This commit is contained in:
Barrett Ruth 2025-10-07 22:58:07 -04:00
parent 17d52f5b07
commit 5af8e1373e
9 changed files with 175 additions and 162 deletions

View file

@ -1,18 +1,15 @@
---
const path = Astro.url.pathname;
const isHome = path === "/" || path === "/index.html";
const is404 = path === "/404.html" || path === "/404";
function getTopic() {
if (path.startsWith("/about")) {
return "/about";
}
const pathname = path.split("/");
if (pathname.length === 2 && pathname[1].endsWith(".html")) {
return "/" + pathname[1].replace(".html", "");
} else if (pathname.length >= 3) {
return "/" + pathname.slice(2, -1).join("/").replace(".html", "");
if (is404) return "/not-found";
if (path.startsWith("/about")) return "/about";
if (path === "/git" || path.startsWith("/git/")) return "/git";
if (path.startsWith("/posts/")) {
const parts = path.replace(/\/+$/, "").split("/");
if (parts.length >= 3) return "/" + parts[2];
}
return "";
}
@ -110,7 +107,8 @@ const promptText = topic ? `barrett@ruth:~$ ${topic}` : "barrett@ruth:~$";
topic.classList.remove("active");
topic.style.color = "";
});
document.getElementById("posts").innerHTML = "";
const posts = document.getElementById("posts");
if (posts) posts.innerHTML = "";
clearPrompt(500);
});
} else {
@ -155,3 +153,4 @@ const promptText = topic ? `barrett@ruth:~$ ${topic}` : "barrett@ruth:~$";
}
}
</style>

View file

@ -12,6 +12,17 @@ const postsCollection = defineCollection({
}),
});
const gistsCollection = defineCollection({
type: "content",
schema: z.object({
title: z.string(),
description: z.string().optional(),
date: z.string().optional(),
}),
});
export const collections = {
posts: postsCollection,
gists: gistsCollection,
};

View file

@ -0,0 +1,24 @@
---
title: "countGoodNumbers.cpp"
date: "07/10/2025"
---
```cpp
class Solution {
public:
static constexpr long long MOD = 1e9 + 7;
long long mpow(long long a, long long b, long long mod=MOD) {
long long ans = 1;
while (b > 0) {
if (b & 1) ans = (ans * a) % MOD;
a = (a * a) % MOD;
b >>= 1;
}
return ans;
}
int countGoodNumbers(long long n) {
long long even = (n + 1) / 2, odd = n / 2;
return (mpow(5, even) * mpow(4, odd)) % MOD;
}
};
```

View file

@ -9,24 +9,29 @@ import BaseLayout from "../layouts/BaseLayout.astro";
</BaseLayout>
<script>
if (!location.pathname.endsWith("/404.html")) {
document.addEventListener("DOMContentLoaded", function () {
const terminalText = " /not-found";
const terminalPrompt = document.querySelector(".terminal-prompt");
const delay = 250;
if (!terminalPrompt) return;
document.addEventListener("DOMContentLoaded", function () {
const base = (window && window.TERMINAL_PROMPT) || "barrett@ruth:~$ ";
const el = document.querySelector(".terminal-prompt");
if (!el) return;
const type = () => {
const target = "/not-found";
let i = 0;
function typechar() {
if (i < terminalText.length) {
terminalPrompt.innerHTML += terminalText.charAt(i++);
setTimeout(typechar, delay / terminalText.length);
el.textContent = base;
(function step() {
if (i < target.length) {
el.textContent += target.charAt(i++);
setTimeout(step, 250 / target.length);
}
}
typechar();
});
}
})();
};
if (window && typeof window.clearPrompt === "function") {
window.clearPrompt(250, type);
} else {
type();
}
});
</script>
<style>
@ -45,3 +50,4 @@ import BaseLayout from "../layouts/BaseLayout.astro";
}
</style>
</BaseLayout>

View file

@ -1,99 +0,0 @@
---
import { getCollection } from "astro:content";
import BaseLayout from "../layouts/BaseLayout.astro";
export async function getStaticPaths() {
const categories = ["algorithms", "software", "meditations"];
return categories.map((category) => {
return {
params: { category },
props: { category },
};
});
}
const { category } = Astro.props;
const posts = await getCollection(
"posts",
(post) => post.data.category === category,
);
posts.sort((a, b) => {
const dateA = a.data.date ? new Date(a.data.date) : new Date(0);
const dateB = b.data.date ? new Date(b.data.date) : new Date(0);
return dateB.getTime() - dateA.getTime();
});
const capitalizedCategory =
category.charAt(0).toUpperCase() + category.slice(1);
---
<BaseLayout title={capitalizedCategory}>
<div class="content">
<h1>{capitalizedCategory}</h1>
<div class="posts">
{
posts.map((post) => (
<div class="post">
<a href={`/posts/${category}/${post.slug}`}>{post.data.title}</a>
{post.data.date && (
<time datetime={post.data.date}>
{new Date(post.data.date).toLocaleDateString("en-US", {
year: "numeric",
month: "long",
day: "numeric",
})}
</time>
)}
</div>
))
}
</div>
</div>
</BaseLayout>
<style>
.content {
max-width: 800px;
margin: 0 auto;
padding: 20px;
}
h1 {
margin-bottom: 30px;
}
.posts {
padding: 0;
}
.post {
margin-bottom: 20px;
padding-bottom: 15px;
border-bottom: 1px solid #eee;
}
.post a {
display: block;
font-size: 1.2em;
text-decoration: underline;
color: var(--topic-color, inherit);
}
time {
display: block;
font-size: 0.9em;
color: #555;
margin-top: 5px;
}
</style>
<script define:vars={{ category }}>
document.addEventListener("DOMContentLoaded", function () {
document.documentElement.style.setProperty(
"--topic-color",
window.getTopicColor(category),
);
});
</script>

View file

@ -0,0 +1,23 @@
---
import { getCollection } from "astro:content";
import PostLayout from "../../layouts/PostLayout.astro";
export async function getStaticPaths() {
const gists = await getCollection("gists");
console.log(gists)
return gists.map((gist) => ({
params: { slug: gist.slug },
props: { gist },
}));
}
const { gist } = Astro.props;
const { Content } = await gist.render();
---
<PostLayout frontmatter={gist.data}>
<Content />
</PostLayout>

52
src/pages/git.astro Normal file
View file

@ -0,0 +1,52 @@
---
import BaseLayout from "../layouts/BaseLayout.astro";
const title = "Git Repositories";
---
<BaseLayout title={title}>
<slot name="head" slot="head">
<link rel="stylesheet" href="/styles/index.css" />
</slot>
<div class="content">
<ul class="topics" id="repo-list">
<li class="topic"></li>
</ul>
<div class="posts" id="posts"></div>
</div>
<script slot="scripts" type="module">
const listEl = document.getElementById("repo-list");
async function loadRepos() {
try {
const res = await fetch("https://git.barrettruth.com/api/repositories", { mode: "cors" });
if (!res.ok) throw new Error("HTTP " + res.status);
const data = await res.json();
const repos = Array.isArray(data?.repositories) ? data.repositories : [];
listEl.innerHTML = "";
repos.sort((a, b) => a.localeCompare(b));
for (const name of repos) {
const cls = `repo-${name}`;
const li = document.createElement("li");
li.className = `topic ${cls}`;
const a = document.createElement("a");
// a.href = `https://git.barrettruth.com/${name}`;
a.textContent = name;
a.setAttribute("data-topic", name);
li.appendChild(a);
listEl.appendChild(li);
}
} catch (_) {}
}
loadRepos();
</script>
</BaseLayout>

View file

@ -39,9 +39,6 @@ Object.keys(postsByCategory).forEach((category) => {
<li class="topic software">
<a href="#software" data-topic="software">software</a>
</li>
<li class="topic autonomous-racing">
<a href="#autonomous-racing" data-topic="autonomous-racing">autonomous racing</a>
</li>
<li class="topic meditations">
<a href="#meditations" data-topic="meditations">meditations</a>
</li>