tangled
alpha
login
or
join now
apoena.dev
/
sequoia
forked from
stevedylan.dev/sequoia
A CLI for publishing standard.site documents to ATProto
0
fork
atom
overview
issues
pulls
pipelines
chore: added hugo support through frontmatter parsing
stevedylan.dev
1 week ago
c8300a54
40e08e37
+34
-15
1 changed file
expand all
collapse all
unified
split
packages
cli
src
lib
markdown.ts
+34
-15
packages/cli/src/lib/markdown.ts
···
6
6
frontmatter: PostFrontmatter;
7
7
body: string;
8
8
} {
9
9
-
const frontmatterRegex = /^---\n([\s\S]*?)\n---\n([\s\S]*)$/;
9
9
+
// Support multiple frontmatter delimiters:
10
10
+
// --- (YAML) - Jekyll, Astro, most SSGs
11
11
+
// +++ (TOML) - Hugo
12
12
+
// *** - Alternative format
13
13
+
const frontmatterRegex = /^(---|\+\+\+|\*\*\*)\n([\s\S]*?)\n\1\n([\s\S]*)$/;
10
14
const match = content.match(frontmatterRegex);
11
15
12
16
if (!match) {
13
17
throw new Error("Could not parse frontmatter");
14
18
}
15
19
16
16
-
const frontmatterStr = match[1] ?? "";
17
17
-
const body = match[2] ?? "";
20
20
+
const delimiter = match[1];
21
21
+
const frontmatterStr = match[2] ?? "";
22
22
+
const body = match[3] ?? "";
23
23
+
24
24
+
// Determine format based on delimiter:
25
25
+
// +++ uses TOML (key = value)
26
26
+
// --- and *** use YAML (key: value)
27
27
+
const isToml = delimiter === "+++";
28
28
+
const separator = isToml ? "=" : ":";
18
29
19
19
-
// Parse YAML-like frontmatter manually
30
30
+
// Parse frontmatter manually
20
31
const raw: Record<string, unknown> = {};
21
32
const lines = frontmatterStr.split("\n");
22
33
23
34
for (const line of lines) {
24
24
-
const colonIndex = line.indexOf(":");
25
25
-
if (colonIndex === -1) continue;
35
35
+
const sepIndex = line.indexOf(separator);
36
36
+
if (sepIndex === -1) continue;
26
37
27
27
-
const key = line.slice(0, colonIndex).trim();
28
28
-
let value = line.slice(colonIndex + 1).trim();
38
38
+
const key = line.slice(0, sepIndex).trim();
39
39
+
let value = line.slice(sepIndex + 1).trim();
29
40
30
41
// Handle quoted strings
31
42
if (
···
155
166
}
156
167
157
168
export function updateFrontmatterWithAtUri(rawContent: string, atUri: string): string {
158
158
-
// Check if atUri already exists in frontmatter
159
159
-
if (rawContent.includes("atUri:")) {
160
160
-
// Replace existing atUri
161
161
-
return rawContent.replace(/atUri:\s*["']?[^"'\n]+["']?\n?/, `atUri: "${atUri}"\n`);
169
169
+
// Detect which delimiter is used (---, +++, or ***)
170
170
+
const delimiterMatch = rawContent.match(/^(---|\+\+\+|\*\*\*)/);
171
171
+
const delimiter = delimiterMatch?.[1] ?? "---";
172
172
+
const isToml = delimiter === "+++";
173
173
+
174
174
+
// Format the atUri entry based on frontmatter type
175
175
+
const atUriEntry = isToml ? `atUri = "${atUri}"` : `atUri: "${atUri}"`;
176
176
+
177
177
+
// Check if atUri already exists in frontmatter (handle both formats)
178
178
+
if (rawContent.includes("atUri:") || rawContent.includes("atUri =")) {
179
179
+
// Replace existing atUri (match both YAML and TOML formats)
180
180
+
return rawContent.replace(/atUri\s*[=:]\s*["']?[^"'\n]+["']?\n?/, `${atUriEntry}\n`);
162
181
}
163
182
164
164
-
// Insert atUri before the closing ---
165
165
-
const frontmatterEndIndex = rawContent.indexOf("---", 4);
183
183
+
// Insert atUri before the closing delimiter
184
184
+
const frontmatterEndIndex = rawContent.indexOf(delimiter, 4);
166
185
if (frontmatterEndIndex === -1) {
167
186
throw new Error("Could not find frontmatter end");
168
187
}
···
170
189
const beforeEnd = rawContent.slice(0, frontmatterEndIndex);
171
190
const afterEnd = rawContent.slice(frontmatterEndIndex);
172
191
173
173
-
return `${beforeEnd}atUri: "${atUri}"\n${afterEnd}`;
192
192
+
return `${beforeEnd}${atUriEntry}\n${afterEnd}`;
174
193
}
175
194
176
195
export function stripMarkdownForText(markdown: string): string {