Skip to content

Commit 8750cc3

Browse files
committed
Use monospace font for timecodes, don't use list icons, fix expando row positioning
1 parent ef63c19 commit 8750cc3

File tree

3 files changed

+89
-1
lines changed

3 files changed

+89
-1
lines changed

src/components/Layout/MarkdownStyles.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,13 +37,16 @@ export const MarkdownStyles = createGlobalStyle`
3737
word-break: break-word;
3838
word-wrap: break-word;
3939
}
40+
ul {
41+
list-style: none;
42+
}
4043
li > details {
4144
display: block;
4245
}
4346
summary {
4447
cursor: pointer;
48+
margin-left: -2rem;
4549
user-select: none;
46-
list-style: none;
4750
display: block;
4851
&::marker,
4952
&::-webkit-details-marker {

src/helpers/rehypeWrapTimecodes.ts

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
import { visit } from "unist-util-visit";
2+
import type { Root, Element, Text, ElementContent } from "hast";
3+
4+
/**
5+
* Rehype plugin that wraps timecode patterns in <code> tags.
6+
* Looks for list items that start with `[<timecode link>]` pattern
7+
* and wraps them in <code> tags for styling.
8+
*
9+
* Input: <li>[<a href="#intro">00:00:00</a>] Intro</li>
10+
* Output: <li><code>[<a href="#intro">00:00:00</a>]</code> Intro</li>
11+
*/
12+
export default function rehypeWrapTimecodes() {
13+
return (tree: Root) => {
14+
visit(tree, "element", (node) => {
15+
// Only process <li> elements
16+
if (node.tagName !== "li") {
17+
return;
18+
}
19+
20+
// Check if first child is a text node starting with "["
21+
if (node.children.length < 3) {
22+
return;
23+
}
24+
25+
const firstChild = node.children[0];
26+
if (firstChild.type !== "text" || !firstChild.value.startsWith("[")) {
27+
return;
28+
}
29+
30+
// Check if second child is a link with a timecode pattern
31+
const secondChild = node.children[1];
32+
if (secondChild.type !== "element" || secondChild.tagName !== "a") {
33+
return;
34+
}
35+
36+
// Check if the link text matches timecode pattern (HH:MM:SS or MM:SS)
37+
const linkText =
38+
secondChild.children[0]?.type === "text"
39+
? secondChild.children[0].value
40+
: "";
41+
const timecodePattern = /^\d{1,2}:\d{2}(:\d{2})?$/;
42+
if (!timecodePattern.test(linkText)) {
43+
return;
44+
}
45+
46+
// Check if third child is a text node starting with "]"
47+
const thirdChild = node.children[2];
48+
if (thirdChild.type !== "text" || !thirdChild.value.startsWith("]")) {
49+
return;
50+
}
51+
52+
// Extract and modify the bracket text nodes
53+
const openingBracket: Text = {
54+
type: "text",
55+
value: "[",
56+
};
57+
58+
const closingBracket: Text = {
59+
type: "text",
60+
value: "]",
61+
};
62+
63+
// Update the original text nodes to remove the brackets
64+
const firstTextNode = firstChild as Text;
65+
firstTextNode.value = firstTextNode.value.slice(1); // Remove leading "["
66+
67+
const thirdTextNode = thirdChild as Text;
68+
thirdTextNode.value = thirdTextNode.value.slice(1); // Remove leading "]"
69+
70+
// Create the <code> wrapper with the timecode content
71+
const codeElement: Element = {
72+
type: "element",
73+
tagName: "code",
74+
properties: {},
75+
children: [openingBracket, secondChild, closingBracket],
76+
};
77+
78+
// Rebuild the children array
79+
const remainingContent = node.children.slice(2);
80+
node.children = [codeElement, ...remainingContent];
81+
});
82+
};
83+
}

src/helpers/retrieveMdPages.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import rehypeSlug from "rehype-slug";
1111
import remarkHeadings, { hasHeadingsData } from "@vcarl/remark-headings";
1212
import { toString } from "mdast-util-to-string";
1313
import rehypeWrapFirstList from "./rehypeWrapFirstList";
14+
import rehypeWrapTimecodes from "./rehypeWrapTimecodes";
1415

1516
const loadMd = async (path: string) => {
1617
const fullPath = join(process.cwd(), `${path}.md`);
@@ -55,6 +56,7 @@ export const processMd = (mdSource: string, options?: ProcessMdOptions) => {
5556
.use(remarkHeadings as ReturnType<ReturnType<typeof unified>["use"]>)
5657
.use(remarkRehype, { allowDangerousHtml: true })
5758
.use(rehypeSlug)
59+
.use(rehypeWrapTimecodes)
5860
.use(rehypeWrapFirstList)
5961
.use(rehypeStringify, { allowDangerousHtml: true });
6062
}

0 commit comments

Comments
 (0)