chore: added hugo support through frontmatter parsing
c8300a54
1 file(s) · +34 −15
| 6 | 6 | frontmatter: PostFrontmatter; |
|
| 7 | 7 | body: string; |
|
| 8 | 8 | } { |
|
| 9 | - | const frontmatterRegex = /^---\n([\s\S]*?)\n---\n([\s\S]*)$/; |
|
| 9 | + | // Support multiple frontmatter delimiters: |
|
| 10 | + | // --- (YAML) - Jekyll, Astro, most SSGs |
|
| 11 | + | // +++ (TOML) - Hugo |
|
| 12 | + | // *** - Alternative format |
|
| 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 | - | const frontmatterStr = match[1] ?? ""; |
|
| 17 | - | const body = match[2] ?? ""; |
|
| 20 | + | const delimiter = match[1]; |
|
| 21 | + | const frontmatterStr = match[2] ?? ""; |
|
| 22 | + | const body = match[3] ?? ""; |
|
| 23 | + | ||
| 24 | + | // Determine format based on delimiter: |
|
| 25 | + | // +++ uses TOML (key = value) |
|
| 26 | + | // --- and *** use YAML (key: value) |
|
| 27 | + | const isToml = delimiter === "+++"; |
|
| 28 | + | const separator = isToml ? "=" : ":"; |
|
| 18 | 29 | ||
| 19 | - | // Parse YAML-like frontmatter manually |
|
| 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 | - | const colonIndex = line.indexOf(":"); |
|
| 25 | - | if (colonIndex === -1) continue; |
|
| 35 | + | const sepIndex = line.indexOf(separator); |
|
| 36 | + | if (sepIndex === -1) continue; |
|
| 26 | 37 | ||
| 27 | - | const key = line.slice(0, colonIndex).trim(); |
|
| 28 | - | let value = line.slice(colonIndex + 1).trim(); |
|
| 38 | + | const key = line.slice(0, sepIndex).trim(); |
|
| 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 | - | // Check if atUri already exists in frontmatter |
|
| 159 | - | if (rawContent.includes("atUri:")) { |
|
| 160 | - | // Replace existing atUri |
|
| 161 | - | return rawContent.replace(/atUri:\s*["']?[^"'\n]+["']?\n?/, `atUri: "${atUri}"\n`); |
|
| 169 | + | // Detect which delimiter is used (---, +++, or ***) |
|
| 170 | + | const delimiterMatch = rawContent.match(/^(---|\+\+\+|\*\*\*)/); |
|
| 171 | + | const delimiter = delimiterMatch?.[1] ?? "---"; |
|
| 172 | + | const isToml = delimiter === "+++"; |
|
| 173 | + | ||
| 174 | + | // Format the atUri entry based on frontmatter type |
|
| 175 | + | const atUriEntry = isToml ? `atUri = "${atUri}"` : `atUri: "${atUri}"`; |
|
| 176 | + | ||
| 177 | + | // Check if atUri already exists in frontmatter (handle both formats) |
|
| 178 | + | if (rawContent.includes("atUri:") || rawContent.includes("atUri =")) { |
|
| 179 | + | // Replace existing atUri (match both YAML and TOML formats) |
|
| 180 | + | return rawContent.replace(/atUri\s*[=:]\s*["']?[^"'\n]+["']?\n?/, `${atUriEntry}\n`); |
|
| 162 | 181 | } |
|
| 163 | 182 | ||
| 164 | - | // Insert atUri before the closing --- |
|
| 165 | - | const frontmatterEndIndex = rawContent.indexOf("---", 4); |
|
| 183 | + | // Insert atUri before the closing delimiter |
|
| 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 | - | return `${beforeEnd}atUri: "${atUri}"\n${afterEnd}`; |
|
| 192 | + | return `${beforeEnd}${atUriEntry}\n${afterEnd}`; |
|
| 174 | 193 | } |
|
| 175 | 194 | ||
| 176 | 195 | export function stripMarkdownForText(markdown: string): string { |
|