emdy/src/index.ts
2025-04-02 10:33:29 -04:00

62 lines
1.7 KiB
TypeScript

import YAML from "yaml";
const FRONTMATTER_REGEX = /^---[\s\S]*?---/gm;
/**
* Parse a markdown document with optional YAML frontmatter into an object
* with the markdown content and any frontmatter as keys.
* @param content The raw markdown content
* @param markdownKey The key to use for the markdown content
* @returns The parsed markdown content and frontmatter
*/
function parse(
content: string,
markdownKey = "content",
): Record<string, unknown> {
const markdown = content.trim().replace(FRONTMATTER_REGEX, "").trim();
let frontmatter: Record<string, unknown> = {};
if (FRONTMATTER_REGEX.test(content)) {
const frontmatterString = content.match(FRONTMATTER_REGEX)?.[0] ?? "";
const cleanFrontmatter = frontmatterString.replaceAll("---", "").trim();
frontmatter = YAML.parse(cleanFrontmatter);
}
return {
[markdownKey]: markdown,
...frontmatter,
};
}
/**
* Serialize an object with markdown content and optional frontmatter into a
* Markdown document. Uses the `content` key for the markdown content by default.
* @param data The object to serialize
* @param markdownKey The key to use for the markdown content
* @returns The parsed markdown content and frontmatter
*/
function stringify(
data: Record<string, unknown>,
markdownKey = "content",
): string {
const markdown = String(data[markdownKey] ?? "");
const frontmatter = { ...data };
delete frontmatter[markdownKey];
const remainingKeys = Object.keys(frontmatter).length;
if (remainingKeys === 0) {
return markdown;
}
const stringifiedFrontmatter = YAML.stringify(frontmatter).trim();
return `---\n${stringifiedFrontmatter}\n---\n${markdown}`;
}
const EMDY = {
parse,
stringify,
} as const;
export default EMDY;