forked from denoland/deno_std
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
encoding: add front matter module (denoland#2335)
Co-authored-by: Yoshiya Hinosawa <[email protected]>
- Loading branch information
1 parent
a06298b
commit 6dbb212
Showing
2 changed files
with
140 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license. | ||
// Copyright (c) Jason Campbell. MIT license. | ||
// https://github.com/jxson/front-matter/blob/36f139ef797bd9e5196a9ede03ef481d7fbca18e/index.js | ||
|
||
import { parse } from "./yaml.ts"; | ||
|
||
const pattern = "^(" + | ||
"\\ufeff?" + // Maybe byte order mark | ||
"(= yaml =|---)" + | ||
"$([\\s\\S]*?)" + | ||
"^(?:\\2|\\.\\.\\.)\\s*" + | ||
"$" + | ||
(Deno.build.os === "windows" ? "\\r?" : "") + | ||
"(?:\\n)?)"; | ||
const regex = new RegExp(pattern, "m"); | ||
|
||
export type Extract<T> = { | ||
frontMatter: string; | ||
body: string; | ||
attrs: T; | ||
}; | ||
|
||
/** | ||
* Extracts front matter from a string. | ||
* @param str String to extract from. | ||
* | ||
* ```ts | ||
* import { extract } from "https://deno.land/std@$STD_VERSION/encoding/front_matter.ts"; | ||
* import { assertEquals } from "https://deno.land/std@$STD_VERSION/testing/asserts.ts"; | ||
* | ||
* const { attrs, body, frontMatter } = extract<{ title: string }>("---\ntitle: Three dashes marks the spot\n---\n"); | ||
* assertEquals(attrs.title, "Three dashes marks the spot"); | ||
* assertEquals(body, ""); | ||
* assertEquals(frontMatter, "---\ntitle: Three dashes marks the spot\n---\n"); | ||
* ``` | ||
*/ | ||
export function extract<T = unknown>(str: string): Extract<T> { | ||
const lines = str.split(/(\r?\n)/); | ||
if (/= yaml =|---/.test(lines[0])) { | ||
const match = regex.exec(str); | ||
if (!match) throw new TypeError("Unexpected end of input"); | ||
const frontMatter = match.at(-1)?.replace(/^\s+|\s+$/g, "") || ""; | ||
const attrs = parse(frontMatter) as T; | ||
const body = str.replace(match[0], ""); | ||
return { frontMatter, body, attrs }; | ||
} | ||
throw new TypeError("Failed to extract front matter"); | ||
} | ||
|
||
/** | ||
* Tests if a string has valid front matter. | ||
* @param str String to test. | ||
* | ||
* ```ts | ||
* import { test } from "https://deno.land/std@$STD_VERSION/encoding/front_matter.ts"; | ||
* import { assert } from "https://deno.land/std@$STD_VERSION/testing/asserts.ts"; | ||
* | ||
* assert(test("---\ntitle: Three dashes marks the spot\n---\n")); | ||
* ``` | ||
*/ | ||
export function test(str: string): boolean { | ||
return regex.test(str); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license. | ||
|
||
import { extract, test } from "./front_matter.ts"; | ||
import { assert, assertEquals, assertThrows } from "../testing/asserts.ts"; | ||
|
||
Deno.test("test valid input true", () => { | ||
[ | ||
"---\nname: deno\n---\n", | ||
"= yaml =\nname: deno\n= yaml =\n", | ||
"= yaml =\nname: deno\n= yaml =\ndeno is awesome\n", | ||
].forEach((str) => { | ||
assert(test(str)); | ||
}); | ||
}); | ||
|
||
Deno.test("test invalid input false", () => { | ||
[ | ||
"", | ||
"---", | ||
"= yaml =", | ||
"---\n", | ||
"= yaml =\n", | ||
"---\nasdasdasd", | ||
].forEach((str) => { | ||
assert(!test(str)); | ||
}); | ||
}); | ||
|
||
Deno.test("extract type error on invalid input", () => { | ||
[ | ||
"", | ||
"---", | ||
"= yaml =", | ||
"---\n", | ||
"= yaml =\n", | ||
"---\nasdasdasd", | ||
].forEach((str) => { | ||
assertThrows(() => extract(str), TypeError); | ||
}); | ||
}); | ||
|
||
Deno.test("parse yaml delinetead by `---`", () => { | ||
const content = extract< | ||
{ title: string; tags: string[]; "expaned-description": string } | ||
>(`--- | ||
title: Three dashes marks the spot | ||
tags: | ||
- yaml | ||
- front-matter | ||
- dashes | ||
expaned-description: with some --- crazy stuff in it | ||
--- | ||
don't break | ||
--- | ||
Also this shouldn't be a problem | ||
`); | ||
assert(content !== undefined); | ||
assertEquals( | ||
content.frontMatter, | ||
`title: Three dashes marks the spot | ||
tags: | ||
- yaml | ||
- front-matter | ||
- dashes | ||
expaned-description: with some --- crazy stuff in it`, | ||
); | ||
assertEquals( | ||
content.body, | ||
"don't break\n---\nAlso this shouldn't be a problem\n", | ||
); | ||
assertEquals(content.attrs.title, "Three dashes marks the spot"); | ||
assertEquals(content.attrs.tags, ["yaml", "front-matter", "dashes"]); | ||
assertEquals( | ||
content.attrs["expaned-description"], | ||
"with some --- crazy stuff in it", | ||
); | ||
}); |