Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .changeset/orange-dogs-pull.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@studiocms/markdown-remark-processor-web": minor
"@studiocms/markdown-remark-processor": minor
---

Update to add support for TOML frontmatter to match Astro's markdown-remark package compat
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,12 @@
"@changesets/cli": "^2.27.11",
"@changesets/config": "^3.0.5",
"@types/node": "^22.10.7",
"@vitest/ui": "3.0.2",
"esbuild": "^0.24.2",
"@vitest/ui": "3.0.5",
"esbuild": "^0.25.0",
"jest-extended": "^4.0.2",
"pkg-pr-new": "^0.0.39",
"run-scripts": "workspace:*",
"typescript": "^5.7.3",
"vitest": "^3.0.2"
"vitest": "^3.0.5"
}
}
1 change: 1 addition & 0 deletions packages/markdown-remark-processor-web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
"remark-rehype": "^11.1.1",
"remark-smartypants": "^3.0.2",
"shiki": "^1.23.1",
"smol-toml": "^1.3.1",
"unified": "^11.0.5",
"unist-util-remove-position": "^5.0.0",
"unist-util-visit": "^5.0.0",
Expand Down
24 changes: 17 additions & 7 deletions packages/markdown-remark-processor-web/src/frontmatter.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import yaml from 'js-yaml';
import * as toml from 'smol-toml';

// biome-ignore lint/suspicious/noExplicitAny: <explanation>
export function isFrontmatterValid(frontmatter: Record<string, any>): boolean {
Expand All @@ -11,15 +12,20 @@ export function isFrontmatterValid(frontmatter: Record<string, any>): boolean {
return typeof frontmatter === 'object' && frontmatter !== null;
}

// Capture frontmatter wrapped with `---`, including any characters and new lines within it.
// Only capture if `---` exists near the top of the file, including:
// Capture frontmatter wrapped with `---` or `+++`, including any characters and new lines within it.
// Only capture if `---` or `+++` exists near the top of the file, including:
// 1. Start of file (including if has BOM encoding)
// 2. Start of file with any whitespace (but `---` must still start on a new line)
const frontmatterRE = /(?:^\uFEFF?|^\s*\n)---([\s\S]*?\n)---/;
const frontmatterRE = /(?:^\uFEFF?|^\s*\n)(?:---|\+\+\+)([\s\S]*?\n)(?:---|\+\+\+)/;
const frontmatterTypeRE = /(?:^\uFEFF?|^\s*\n)(---|\+\+\+)/;
export function extractFrontmatter(code: string): string | undefined {
return frontmatterRE.exec(code)?.[1];
}

function getFrontmatterParser(code: string): [string, (str: string) => unknown] {
return frontmatterTypeRE.exec(code)?.[1] === '+++' ? ['+++', toml.parse] : ['---', yaml.load];
}

export interface ParseFrontmatterOptions {
/**
* How the frontmatter should be handled in the returned `content` string.
Expand Down Expand Up @@ -69,7 +75,8 @@ export function parseFrontmatter(
return { frontmatter: {}, rawFrontmatter: '', content: code };
}

const parsed = yaml.load(rawFrontmatter);
const [delims, parser] = getFrontmatterParser(code);
const parsed = parser(rawFrontmatter);
// biome-ignore lint/suspicious/noExplicitAny: <explanation>
const frontmatter = (parsed && typeof parsed === 'object' ? parsed : {}) as Record<string, any>;

Expand All @@ -79,16 +86,19 @@ export function parseFrontmatter(
content = code;
break;
case 'remove':
content = code.replace(`---${rawFrontmatter}---`, '');
content = code.replace(`${delims}${rawFrontmatter}${delims}`, '');
break;
case 'empty-with-spaces':
content = code.replace(
`---${rawFrontmatter}---`,
`${delims}${rawFrontmatter}${delims}`,
` ${rawFrontmatter.replace(/[^\r\n]/g, ' ')} `
);
break;
case 'empty-with-lines':
content = code.replace(`---${rawFrontmatter}---`, rawFrontmatter.replace(/[^\r\n]/g, ''));
content = code.replace(
`${delims}${rawFrontmatter}${delims}`,
rawFrontmatter.replace(/[^\r\n]/g, '')
);
break;
}

Expand Down
2 changes: 1 addition & 1 deletion packages/markdown-remark-processor/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -54,14 +54,14 @@
"remark-rehype": "^11.1.1",
"remark-smartypants": "^3.0.2",
"shiki": "^1.23.1",
"smol-toml": "^1.3.1",
"unified": "^11.0.5",
"unist-util-remove-position": "^5.0.0",
"unist-util-visit": "^5.0.0",
"unist-util-visit-parents": "^6.0.1",
"vfile": "^6.0.3"
},
"devDependencies": {
"@inox-tools/astro-tests": "^0.2.2",
"@types/estree": "^1.0.6",
"@types/html-escaper": "^3.0.2",
"@types/hast": "^3.0.4",
Expand Down
24 changes: 17 additions & 7 deletions packages/markdown-remark-processor/src/frontmatter.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import yaml from 'js-yaml';
import * as toml from 'smol-toml';

// biome-ignore lint/suspicious/noExplicitAny: <explanation>
export function isFrontmatterValid(frontmatter: Record<string, any>): boolean {
Expand All @@ -11,15 +12,20 @@ export function isFrontmatterValid(frontmatter: Record<string, any>): boolean {
return typeof frontmatter === 'object' && frontmatter !== null;
}

// Capture frontmatter wrapped with `---`, including any characters and new lines within it.
// Only capture if `---` exists near the top of the file, including:
// Capture frontmatter wrapped with `---` or `+++`, including any characters and new lines within it.
// Only capture if `---` or `+++` exists near the top of the file, including:
// 1. Start of file (including if has BOM encoding)
// 2. Start of file with any whitespace (but `---` must still start on a new line)
const frontmatterRE = /(?:^\uFEFF?|^\s*\n)---([\s\S]*?\n)---/;
const frontmatterRE = /(?:^\uFEFF?|^\s*\n)(?:---|\+\+\+)([\s\S]*?\n)(?:---|\+\+\+)/;
const frontmatterTypeRE = /(?:^\uFEFF?|^\s*\n)(---|\+\+\+)/;
export function extractFrontmatter(code: string): string | undefined {
return frontmatterRE.exec(code)?.[1];
}

function getFrontmatterParser(code: string): [string, (str: string) => unknown] {
return frontmatterTypeRE.exec(code)?.[1] === '+++' ? ['+++', toml.parse] : ['---', yaml.load];
}

export interface ParseFrontmatterOptions {
/**
* How the frontmatter should be handled in the returned `content` string.
Expand Down Expand Up @@ -69,7 +75,8 @@ export function parseFrontmatter(
return { frontmatter: {}, rawFrontmatter: '', content: code };
}

const parsed = yaml.load(rawFrontmatter);
const [delims, parser] = getFrontmatterParser(code);
const parsed = parser(rawFrontmatter);
// biome-ignore lint/suspicious/noExplicitAny: <explanation>
const frontmatter = (parsed && typeof parsed === 'object' ? parsed : {}) as Record<string, any>;

Expand All @@ -79,16 +86,19 @@ export function parseFrontmatter(
content = code;
break;
case 'remove':
content = code.replace(`---${rawFrontmatter}---`, '');
content = code.replace(`${delims}${rawFrontmatter}${delims}`, '');
break;
case 'empty-with-spaces':
content = code.replace(
`---${rawFrontmatter}---`,
`${delims}${rawFrontmatter}${delims}`,
` ${rawFrontmatter.replace(/[^\r\n]/g, ' ')} `
);
break;
case 'empty-with-lines':
content = code.replace(`---${rawFrontmatter}---`, rawFrontmatter.replace(/[^\r\n]/g, ''));
content = code.replace(
`${delims}${rawFrontmatter}${delims}`,
rawFrontmatter.replace(/[^\r\n]/g, '')
);
break;
}

Expand Down
2 changes: 1 addition & 1 deletion packages/markdown-remark/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@
"ultrahtml": "^1.5.3"
},
"devDependencies": {
"@inox-tools/astro-tests": "^0.2.2"
"@inox-tools/astro-tests": "0.2.0"
},
"publishConfig": {
"provenance": true
Expand Down
2 changes: 1 addition & 1 deletion packages/markdown-remark/tests/astro-integration.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { loadFixture } from '@inox-tools/astro-tests/astroFixture';
import { afterAll, beforeAll, describe, expect, test } from 'vitest';

const fixture = await loadFixture({
root: './fixture/astro',
root: './fixture/astro/',
});

describe('Markdown-Remark Astro Integration Tests', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,6 @@
},
"dependencies": {
"@studiocms/markdown-remark": "workspace:*",
"astro": "^5.1.7"
"astro": "^5.2.5"
}
}
Loading