mirror of
https://github.com/hanzo-docs/docs.git
synced 2026-10-26 23:49:51 +00:00
MDX: Hotfix Windows EOL being ignored
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'fumadocs-mdx': patch
|
||||
---
|
||||
|
||||
Hotfix Windows EOL being ignored
|
||||
@@ -1,58 +1,29 @@
|
||||
/**
|
||||
* Inspired by https://github.com/jonschlinkert/gray-matter
|
||||
*/
|
||||
import { LRUCache } from 'lru-cache';
|
||||
import { load } from 'js-yaml';
|
||||
|
||||
const cache = new LRUCache<string, Output>({
|
||||
max: 200,
|
||||
});
|
||||
|
||||
interface Output {
|
||||
matter: string;
|
||||
content: string;
|
||||
data: unknown;
|
||||
}
|
||||
|
||||
const regex = /^---\r?\n(.+?)\r?\n---\r?\n/s;
|
||||
|
||||
/**
|
||||
* parse frontmatter, it supports only yaml format
|
||||
*/
|
||||
export function fumaMatter(input: string): Output {
|
||||
if (input === '') {
|
||||
return { data: {}, content: input, matter: '' };
|
||||
}
|
||||
|
||||
const cached = cache.get(input);
|
||||
if (cached) return cached;
|
||||
const result = parseMatter(input);
|
||||
cache.set(input, result);
|
||||
|
||||
// avoid mutation
|
||||
return structuredClone(result);
|
||||
}
|
||||
|
||||
const delimiter = '---';
|
||||
|
||||
function parseMatter(str: string): Output {
|
||||
const output: Output = { matter: '', data: {}, content: str };
|
||||
const open = delimiter + '\n';
|
||||
const close = '\n' + delimiter;
|
||||
|
||||
if (!str.startsWith(open)) {
|
||||
const output: Output = { matter: '', data: {}, content: input };
|
||||
const match = regex.exec(input);
|
||||
if (!match) {
|
||||
return output;
|
||||
}
|
||||
|
||||
str = str.slice(open.length);
|
||||
const len = str.length;
|
||||
|
||||
let closeIdx = str.indexOf(close);
|
||||
if (closeIdx === -1) {
|
||||
closeIdx = len;
|
||||
}
|
||||
|
||||
// get the raw front-matter block
|
||||
output.matter = str.slice(0, closeIdx);
|
||||
output.content = str.slice(closeIdx + close.length);
|
||||
output.matter = match[1];
|
||||
output.content = input.slice(match[0].length);
|
||||
|
||||
const loaded = load(output.matter);
|
||||
output.data = loaded ?? {};
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
// @ts-nocheck -- skip type checking
|
||||
import * as _source from "./config"
|
||||
import { _runtimeAsync, buildConfig } from "fumadocs-mdx/runtime/async"
|
||||
const [err, _sourceConfig] = buildConfig(_source)
|
||||
if (!_sourceConfig) throw new Error(err)
|
||||
import { _runtime } from "fumadocs-mdx"
|
||||
import * as _source from "./config"
|
||||
export const docs = _runtimeAsync.doc<typeof _source.docs>([{"info":{"path":"index.mdx","absolutePath":"$cwd/packages/mdx/test/fixtures/index.mdx"},"data":{},"content":"# Hello World\n"}, {"info":{"path":"folder/test.mdx","absolutePath":"$cwd/packages/mdx/test/fixtures/folder/test.mdx"},"data":{},"content":""}], "docs", _sourceConfig)
|
||||
@@ -2,4 +2,5 @@
|
||||
import * as docs_1 from "./folder/test.mdx?collection=docs&hash=hash"
|
||||
import * as docs_0 from "./index.mdx?collection=docs&hash=hash"
|
||||
import { _runtime } from "fumadocs-mdx"
|
||||
import * as _source from "./config"
|
||||
export const docs = _runtime.doc<typeof _source.docs>([{ info: {"path":"index.mdx","absolutePath":"$cwd/packages/mdx/test/fixtures/index.mdx"}, data: docs_0 }, { info: {"path":"folder/test.mdx","absolutePath":"$cwd/packages/mdx/test/fixtures/folder/test.mdx"}, data: docs_1 }]);
|
||||
@@ -5,6 +5,7 @@ import { z } from 'zod';
|
||||
import { ValidationError } from '@/utils/schema';
|
||||
import { generateJS } from '@/map/generate';
|
||||
import { defineCollections } from '@/config';
|
||||
import { fumaMatter } from '@/utils/fuma-matter';
|
||||
|
||||
test('format errors', async () => {
|
||||
const schema = z.object({
|
||||
@@ -79,3 +80,49 @@ for (const { name, collection } of cases) {
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
test('parse frontmatter', () => {
|
||||
expect(
|
||||
fumaMatter(
|
||||
'---\ntitle: hello world\ndescription: I love Fumadocs\n---\nwow looks cool.',
|
||||
),
|
||||
).toMatchInlineSnapshot(`
|
||||
{
|
||||
"content": "wow looks cool.",
|
||||
"data": {
|
||||
"description": "I love Fumadocs",
|
||||
"title": "hello world",
|
||||
},
|
||||
"matter": "title: hello world
|
||||
description: I love Fumadocs",
|
||||
}
|
||||
`);
|
||||
|
||||
expect(
|
||||
fumaMatter(
|
||||
'---\r\ntitle: hello world\r\ndescription: I love Fumadocs\r\n---\r\nwow looks cool.',
|
||||
),
|
||||
).toMatchInlineSnapshot(`
|
||||
{
|
||||
"content": "wow looks cool.",
|
||||
"data": {
|
||||
"description": "I love Fumadocs",
|
||||
"title": "hello world",
|
||||
},
|
||||
"matter": "title: hello world
|
||||
description: I love Fumadocs",
|
||||
}
|
||||
`);
|
||||
|
||||
expect(fumaMatter('--- \ntitle: hello world\r\n---\r\nwow looks cool.'))
|
||||
.toMatchInlineSnapshot(`
|
||||
{
|
||||
"content": "---
|
||||
title: hello world
|
||||
---
|
||||
wow looks cool.",
|
||||
"data": {},
|
||||
"matter": "",
|
||||
}
|
||||
`);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user