docs(front-matter): improve docs for stabilization (#4789)

This commit improves docs of the front-matter module.

Specifically, the following things are done:

- Use `@example` where appropriate to render the examples more beautifully
- Split the big example attached to `createExtractor` function into smaller pieces so that each one has minimal yet meaningful example
- Add `@returns` to the `test` function
- Deduplicate `Format` type definition
- Add a brief description to `Format` type

Towards #3764

---------

Co-authored-by: Asher Gomez <ashersaupingomez@gmail.com>
This commit is contained in:
Yusuke Tanaka 2024-05-27 18:14:52 -07:00 committed by GitHub
parent 083b63f428
commit d13ef17a5d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
15 changed files with 219 additions and 112 deletions

View File

@ -34,6 +34,7 @@ const ENTRY_POINTS = [
"../datetime/mod.ts",
"../encoding/mod.ts",
"../expect/mod.ts",
"../front_matter/mod.ts",
"../http/mod.ts",
"../internal/mod.ts",
"../jsonc/mod.ts",

View File

@ -77,7 +77,7 @@ export function runExtractTypeErrorTests(
});
}
export async function runExtractJSONTests(
export async function runExtractJsonTests(
extractFn: ExtractFn,
) {
const str = await Deno.readTextFile(resolveTestDataPath("json.md"));
@ -110,7 +110,7 @@ export async function runExtractJSONTests(
);
}
export async function runExtractYAMLTests1(
export async function runExtractYamlTests1(
extractFn: ExtractFn,
) {
const str = await Deno.readTextFile(resolveTestDataPath("yaml1.md"));
@ -138,7 +138,7 @@ expanded-description: with some --- crazy stuff in it`,
);
}
export async function runExtractYAMLTests2(
export async function runExtractYamlTests2(
extractFn: ExtractFn,
) {
const str = await Deno.readTextFile(resolveTestDataPath("yaml2.md"));
@ -166,7 +166,7 @@ expanded-description: with some --- crazy stuff in it`,
);
}
export async function runExtractTOMLTests(
export async function runExtractTomlTests(
extractFn: ExtractFn,
) {
const str = await Deno.readTextFile(resolveTestDataPath("toml.md"));
@ -194,7 +194,7 @@ tags = ['toml', 'front-matter']
);
}
export async function runExtractTOMLTests2(
export async function runExtractTomlTests2(
extractFn: ExtractFn,
) {
const str = await Deno.readTextFile(resolveTestDataPath("toml2.md"));

7
front_matter/_types.ts Normal file
View File

@ -0,0 +1,7 @@
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
/**
* Supported format for front matter. `"unknown"` is used when auto format
* detection logic fails.
*/
export type Format = "yaml" | "toml" | "json" | "unknown";

View File

@ -5,8 +5,8 @@ import {
type Extractor,
type Parser,
} from "./create_extractor.ts";
import { parse as parseYAML } from "@std/yaml/parse";
import { parse as parseTOML } from "@std/toml/parse";
import { parse as parseYaml } from "@std/yaml/parse";
import { parse as parseToml } from "@std/toml/parse";
/**
* Extracts and parses {@link https://yaml.org | YAML}, {@link https://toml.io |
@ -31,7 +31,7 @@ import { parse as parseTOML } from "@std/toml/parse";
* ```
*/
export const extract: Extractor = createExtractor({
yaml: parseYAML as Parser,
toml: parseTOML as Parser,
yaml: parseYaml as Parser,
toml: parseToml as Parser,
json: JSON.parse as Parser,
});

View File

@ -3,11 +3,11 @@
import { test } from "./test.ts";
import { extract } from "./any.ts";
import {
runExtractJSONTests,
runExtractTOMLTests,
runExtractJsonTests,
runExtractTomlTests,
runExtractTypeErrorTests,
runExtractYAMLTests1,
runExtractYAMLTests2,
runExtractYamlTests1,
runExtractYamlTests2,
runTestInvalidInputTests,
runTestValidInputTests,
} from "./_test_utils.ts";
@ -27,11 +27,11 @@ Deno.test("extract() extracts type error on invalid input", () => {
});
Deno.test("extract() parses yaml delineate by `---`", async () => {
await runExtractYAMLTests1(extract);
await runExtractYamlTests1(extract);
});
Deno.test("extract() parses yaml delineate by `---yaml`", async () => {
await runExtractYAMLTests2(extract);
await runExtractYamlTests2(extract);
});
// JSON //
@ -49,7 +49,7 @@ Deno.test("extract() extracts type error on invalid json input", () => {
});
Deno.test("extract() parses json delineate by ---json", async () => {
await runExtractJSONTests(extract);
await runExtractJsonTests(extract);
});
// TOML //
@ -67,5 +67,5 @@ Deno.test("extract() extracts type error on invalid toml input", () => {
});
Deno.test("extract() parses toml delineate by ---toml", async () => {
await runExtractTOMLTests(extract);
await runExtractTomlTests(extract);
});

View File

@ -1,8 +1,7 @@
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
import { EXTRACT_REGEXP_MAP, RECOGNIZE_REGEXP_MAP } from "./_formats.ts";
type Format = "yaml" | "toml" | "json" | "unknown";
import type { Format } from "./_types.ts";
/** Return type for {@linkcode Extractor}. */
export type Extract<T> = {
@ -35,21 +34,12 @@ function _extract<T>(
}
/**
* Recognizes the format of the front matter in a string. Supports YAML, TOML and JSON.
* Recognizes the format of the front matter in a string.
* Supports {@link https://yaml.org | YAML}, {@link https://toml.io | TOML} and
* {@link https://www.json.org/ | JSON}.
*
* @param str String to recognize.
* @param formats A list of formats to recognize. Defaults to all supported formats.
*
* ```ts
* import { recognize } from "@std/front-matter";
* import { assertEquals } from "@std/assert/assert-equals";
*
* assertEquals(recognize("---\ntitle: Three dashes marks the spot\n---\n"), "yaml");
* assertEquals(recognize("---toml\ntitle = 'Three dashes followed by format marks the spot'\n---\n"), "toml");
* assertEquals(recognize("---json\n{\"title\": \"Three dashes followed by format marks the spot\"}\n---\n"), "json");
* assertEquals(recognize("---xml\n<title>Three dashes marks the spot</title>\n---\n"), "unknown");
*
* assertEquals(recognize("---json\n<title>Three dashes marks the spot</title>\n---\n", ["yaml"]), "unknown");
*/
function recognize(str: string, formats?: Format[]): Format {
if (!formats) {
@ -72,53 +62,102 @@ function recognize(str: string, formats?: Format[]): Format {
}
/**
* Factory that creates a function that extracts front matter from a string with the given parsers.
* Supports YAML, TOML and JSON.
* Factory that creates a function that extracts front matter from a string with
* the given parsers. Supports {@link https://yaml.org | YAML},
* {@link https://toml.io | TOML} and {@link https://www.json.org/ | JSON}.
*
* For simple use cases where you know which format to parse in advance, use the
* pre-built extractors:
*
* - {@linkcode https://jsr.io/@std/front-matter/doc/yaml/~/extract | extractYaml}
* - {@linkcode https://jsr.io/@std/front-matter/doc/toml/~/extract | extractToml}
* - {@linkcode https://jsr.io/@std/front-matter/doc/json/~/extract | extractJson}
*
* @param formats A descriptor containing Format-parser pairs to use for each format.
* @returns A function that extracts front matter from a string with the given parsers.
*
* @example Extract YAML front matter
* ```ts
* import { createExtractor, Parser } from "@std/front-matter";
* import { assertEquals } from "@std/assert/assert-equals";
* import { parse as parseYAML } from "@std/yaml/parse";
* import { parse as parseTOML } from "@std/toml/parse";
* const extractYAML = createExtractor({ yaml: parseYAML as Parser });
* const extractTOML = createExtractor({ toml: parseTOML as Parser });
* const extractJSON = createExtractor({ json: JSON.parse as Parser });
* const extractYAMLOrJSON = createExtractor({
* yaml: parseYAML as Parser,
* json: JSON.parse as Parser,
* });
* import { parse as parseYaml } from "@std/yaml/parse";
*
* let { attrs, body, frontMatter } = extractYAML<{ title: string }>("---\ntitle: Three dashes marks the spot\n---\nferret");
* const extractYaml = createExtractor({ yaml: parseYaml as Parser });
* const { attrs, body, frontMatter } = extractYaml<{ title: string }>(
* `---
* title: Three dashes marks the spot
* ---
* ferret`);
* assertEquals(attrs.title, "Three dashes marks the spot");
* assertEquals(body, "ferret");
* assertEquals(frontMatter, "title: Three dashes marks the spot");
* ```
*
* ({ attrs, body, frontMatter } = extractTOML<{ title: string }>("---toml\ntitle = 'Three dashes followed by format marks the spot'\n---\n"));
* @example Extract TOML front matter
* ```ts
* import { createExtractor, Parser } from "@std/front-matter";
* import { assertEquals } from "@std/assert/assert-equals";
* import { parse as parseToml } from "@std/toml/parse";
*
* const extractToml = createExtractor({ toml: parseToml as Parser });
* const { attrs, body, frontMatter } = extractToml<{ title: string }>(
* `---toml
* title = 'Three dashes followed by format marks the spot'
* ---
* `);
* assertEquals(attrs.title, "Three dashes followed by format marks the spot");
* assertEquals(body, "");
* assertEquals(frontMatter, "title = 'Three dashes followed by format marks the spot'");
* ```
*
* ({ attrs, body, frontMatter } = extractJSON<{ title: string }>("---json\n{\"title\": \"Three dashes followed by format marks the spot\"}\n---\ngoat"));
* @example Extract JSON front matter
* ```ts
* import { createExtractor, Parser } from "@std/front-matter";
* import { assertEquals } from "@std/assert/assert-equals";
*
* const extractJson = createExtractor({ json: JSON.parse as Parser });
* const { attrs, body, frontMatter } = extractJson<{ title: string }>(
* `---json
* {"title": "Three dashes followed by format marks the spot"}
* ---
* goat`);
* assertEquals(attrs.title, "Three dashes followed by format marks the spot");
* assertEquals(body, "goat");
* assertEquals(frontMatter, "{\"title\": \"Three dashes followed by format marks the spot\"}");
* assertEquals(frontMatter, `{"title": "Three dashes followed by format marks the spot"}`);
* ```
*
* ({ attrs, body, frontMatter } = extractYAMLOrJSON<{ title: string }>("---\ntitle: Three dashes marks the spot\n---\nferret"));
* @example Extract YAML or JSON front matter
* ```ts
* import { createExtractor, Parser } from "@std/front-matter";
* import { assertEquals } from "@std/assert/assert-equals";
* import { parse as parseYaml } from "@std/yaml/parse";
*
* const extractYamlOrJson = createExtractor({
* yaml: parseYaml as Parser,
* json: JSON.parse as Parser,
* });
*
* let { attrs, body, frontMatter } = extractYamlOrJson<{ title: string }>(
* `---
* title: Three dashes marks the spot
* ---
* ferret`);
* assertEquals(attrs.title, "Three dashes marks the spot");
* assertEquals(body, "ferret");
* assertEquals(frontMatter, "title: Three dashes marks the spot");
*
* ({ attrs, body, frontMatter } = extractYAMLOrJSON<{ title: string }>("---json\n{\"title\": \"Three dashes followed by format marks the spot\"}\n---\ngoat"));
* ({ attrs, body, frontMatter } = extractYamlOrJson<{ title: string }>(
* `---json
* {"title": "Three dashes followed by format marks the spot"}
* ---
* goat`));
* assertEquals(attrs.title, "Three dashes followed by format marks the spot");
* assertEquals(body, "goat");
* assertEquals(frontMatter, "{\"title\": \"Three dashes followed by format marks the spot\"}");
* assertEquals(frontMatter, `{"title": "Three dashes followed by format marks the spot"}`);
* ```
*/
export function createExtractor(
formats: Partial<Record<"yaml" | "toml" | "json" | "unknown", Parser>>,
formats: Partial<Record<Format, Parser>>,
): Extractor {
const formatKeys = Object.keys(formats) as Format[];

View File

@ -1,43 +1,43 @@
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
import { assertThrows } from "@std/assert";
import { parse as parseYAML } from "@std/yaml/parse";
import { parse as parseTOML } from "@std/toml/parse";
import { parse as parseYaml } from "@std/yaml/parse";
import { parse as parseToml } from "@std/toml/parse";
import {
resolveTestDataPath,
runExtractJSONTests,
runExtractTOMLTests,
runExtractJsonTests,
runExtractTomlTests,
runExtractTypeErrorTests,
runExtractYAMLTests1,
runExtractYAMLTests2,
runExtractYamlTests1,
runExtractYamlTests2,
} from "./_test_utils.ts";
import { createExtractor, type Parser } from "./create_extractor.ts";
const extractYAML = createExtractor({ "yaml": parseYAML as Parser });
const extractTOML = createExtractor({ "toml": parseTOML as Parser });
const extractJSON = createExtractor({ "json": JSON.parse as Parser });
const extractYAMLOrJSON = createExtractor({
"yaml": parseYAML as Parser,
const extractYaml = createExtractor({ "yaml": parseYaml as Parser });
const extractToml = createExtractor({ "toml": parseToml as Parser });
const extractJson = createExtractor({ "json": JSON.parse as Parser });
const extractYamlOrJson = createExtractor({
"yaml": parseYaml as Parser,
"json": JSON.parse as Parser,
});
const extractAny = createExtractor({
"yaml": parseYAML as Parser,
"yaml": parseYaml as Parser,
"json": JSON.parse as Parser,
"toml": parseTOML as Parser,
"toml": parseToml as Parser,
});
// YAML //
Deno.test("createExtractor() extracts yaml type error on invalid input", () => {
runExtractTypeErrorTests("yaml", extractYAML);
runExtractTypeErrorTests("yaml", extractYaml);
});
Deno.test("createExtractor() parses yaml delineate by `---`", async () => {
await runExtractYAMLTests1(extractYAML);
await runExtractYamlTests1(extractYaml);
});
Deno.test("createExtractor() parses yaml delineate by `---yaml`", async () => {
await runExtractYAMLTests2(extractYAML);
await runExtractYamlTests2(extractYaml);
});
Deno.test({
@ -61,34 +61,34 @@ Deno.test({
// JSON //
Deno.test("createExtractor() extracts json type error on invalid input", () => {
runExtractTypeErrorTests("json", extractJSON);
runExtractTypeErrorTests("json", extractJson);
});
Deno.test("createExtractor() parses json delineate by ---json", async () => {
await runExtractJSONTests(extractJSON);
await runExtractJsonTests(extractJson);
});
// TOML //
Deno.test("createExtractor() extracts toml type error on invalid input", () => {
runExtractTypeErrorTests("toml", extractTOML);
runExtractTypeErrorTests("toml", extractToml);
});
Deno.test("createExtractor() parses toml delineate by ---toml", async () => {
await runExtractTOMLTests(extractTOML);
await runExtractTomlTests(extractToml);
});
// MULTIPLE FORMATS //
Deno.test("createExtractor() parses yaml or json input", async () => {
await runExtractYAMLTests1(extractYAMLOrJSON);
await runExtractYAMLTests2(extractYAMLOrJSON);
await runExtractJSONTests(extractYAMLOrJSON);
await runExtractYamlTests1(extractYamlOrJson);
await runExtractYamlTests2(extractYamlOrJson);
await runExtractJsonTests(extractYamlOrJson);
});
Deno.test("createExtractor() parses any input", async () => {
await runExtractYAMLTests1(extractAny);
await runExtractYAMLTests2(extractAny);
await runExtractJSONTests(extractAny);
await runExtractTOMLTests(extractAny);
await runExtractYamlTests1(extractAny);
await runExtractYamlTests2(extractAny);
await runExtractJsonTests(extractAny);
await runExtractTomlTests(extractAny);
});

View File

@ -10,9 +10,10 @@ import {
* Extracts and parses {@link https://www.json.org/ | JSON } from the metadata
* of front matter content.
*
* @example
* @example Extract JSON front matter
* ```ts
* import { extract } from "@std/front-matter/json";
* import { assertEquals } from "@std/assert/assert-equals";
*
* const output = `---json
* {
@ -22,9 +23,11 @@ import {
* Hello, world!`;
* const result = extract(output);
*
* result.frontMatter; // '{\n "title": "Three dashes marks the spot"\n}'
* result.body; // "Hello, world!"
* result.attrs; // { title: "Three dashes marks the spot" }
* assertEquals(result, {
* frontMatter: '{\n "title": "Three dashes marks the spot"\n}',
* body: "Hello, world!",
* attrs: { title: "Three dashes marks the spot" },
* });
* ```
*/
export const extract: Extractor = createExtractor({

View File

@ -3,7 +3,7 @@
import { test } from "./test.ts";
import { extract } from "./json.ts";
import {
runExtractJSONTests,
runExtractJsonTests,
runExtractTypeErrorTests,
runTestInvalidInputTests,
runTestValidInputTests,
@ -22,5 +22,5 @@ Deno.test("json() extracts type error on invalid input", () => {
});
Deno.test("json() parses json delineate by ---json", async () => {
await runExtractJSONTests(extract);
await runExtractJsonTests(extract);
});

View File

@ -1,4 +1,3 @@
// deno-lint-ignore-file no-unused-vars
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
// Copyright (c) Jason Campbell. MIT license
@ -25,7 +24,8 @@
* result.attrs; // { and: "this" }
* ```
*
* {@linkcode extractJson | extract} and {@linkcode test} support the following delimiters.
* {@linkcode extractJson | extract} and {@linkcode test} support the following
* delimiters.
*
* ```markdown
* ---json
@ -56,7 +56,8 @@
* result.attrs; // { module: "front_matter" }
* ```
*
* {@linkcode extractToml | extract} and {@linkcode test} support the following delimiters.
* {@linkcode extractToml | extract} and {@linkcode test} support the following
* delimiters.
*
* ```markdown
* ---toml
@ -93,7 +94,8 @@
* result.attrs; // { module: "front_matter" }
* ```
*
* {@linkcode extractYaml | extract} and {@linkcode test} support the following delimiters.
* {@linkcode extractYaml | extract} and {@linkcode test} support the following
* delimiters.
*
* ```front_matter
* ---
@ -115,9 +117,11 @@
*
* @module
*/
import type { extract as extractJson } from "./json.ts";
import type { extract as extractToml } from "./toml.ts";
import type { extract as extractYaml } from "./yaml.ts";
import { extract as extractJson } from "./json.ts";
import { extract as extractToml } from "./toml.ts";
import { extract as extractYaml } from "./yaml.ts";
export * from "./create_extractor.ts";
export * from "./test.ts";
export { extractJson, extractToml, extractYaml };

View File

@ -1,22 +1,69 @@
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
import { EXTRACT_REGEXP_MAP } from "./_formats.ts";
import type { Format } from "./_types.ts";
export type Format = "yaml" | "toml" | "json" | "unknown";
export type { Format };
/**
* Tests if a string has valid front matter. Supports YAML, TOML and JSON.
* Tests if a string has valid front matter.
* Supports {@link https://yaml.org | YAML}, {@link https://toml.io | TOML} and
* {@link https://www.json.org/ | JSON}.
*
* @param str String to test.
* @param formats A list of formats to test for. Defaults to all supported formats.
* @returns `true` if the string has valid front matter, otherwise `false`.
*
* @example Test for valid YAML front matter
* ```ts
* import { test } from "@std/front-matter/test";
* import { assert } from "@std/assert/assert";
*
* test("---\ntitle: Three dashes marks the spot\n---\n"); // true
* test("---toml\ntitle = 'Three dashes followed by format marks the spot'\n---\n"); // true
* test("---json\n{\"title\": \"Three dashes followed by format marks the spot\"}\n---\n"); // true
* test("---json\n{\"title\": \"Three dashes followed by format marks the spot\"}\n---\n", ["yaml"]); // false
* const result = test(
* `---
* title: Three dashes marks the spot
* ---
* `);
* assert(result);
* ```
*
* @example Test for valid TOML front matter
* ```ts
* import { test } from "@std/front-matter/test";
* import { assert } from "@std/assert/assert";
*
* const result = test(
* `---toml
* title = 'Three dashes followed by format marks the spot'
* ---
* `);
* assert(result);
* ```
*
* @example Test for valid JSON front matter
* ```ts
* import { test } from "@std/front-matter/test";
* import { assert } from "@std/assert/assert";
*
* const result = test(
* `---json
* {"title": "Three dashes followed by format marks the spot"}
* ---
* `);
* assert(result);
* ```
*
* @example JSON front matter is not valid as YAML
* ```ts
* import { test } from "@std/front-matter/test";
* import { assertFalse } from "@std/assert/assert-false";
*
* const result = test(
* `---json
* {"title": "Three dashes followed by format marks the spot"}
* ---
* `, ["yaml"]);
* assertFalse(result);
* ```
*/
export function test(

View File

@ -11,9 +11,10 @@ import { parse } from "@std/toml/parse";
* Extracts and parses {@link https://toml.io | TOML} from the metadata of
* front matter content.
*
* @example
* @example Extract TOML front matter
* ```ts
* import { extract } from "@std/front-matter/toml";
* import { assertEquals } from "@std/assert/assert-equals";
*
* const output = `---toml
* title = "Three dashes marks the spot"
@ -21,9 +22,11 @@ import { parse } from "@std/toml/parse";
* Hello, world!`;
* const result = extract(output);
*
* result.frontMatter; // 'title = "Three dashes marks the spot"'
* result.body; // "Hello, world!"
* result.attrs; // { title: "Three dashes marks the spot" }
* assertEquals(result, {
* frontMatter: 'title = "Three dashes marks the spot"',
* body: "Hello, world!",
* attrs: { title: "Three dashes marks the spot" },
* });
* ```
*/
export const extract: Extractor = createExtractor({

View File

@ -3,8 +3,8 @@
import { test } from "./test.ts";
import { extract } from "./toml.ts";
import {
runExtractTOMLTests,
runExtractTOMLTests2,
runExtractTomlTests,
runExtractTomlTests2,
runExtractTypeErrorTests,
runTestInvalidInputTests,
runTestValidInputTests,
@ -23,9 +23,9 @@ Deno.test("toml() extracts type error on invalid input", () => {
});
Deno.test("toml() parses toml delineate by ---toml", async () => {
await runExtractTOMLTests(extract);
await runExtractTomlTests(extract);
});
Deno.test("toml() parses toml delineate by +++", async () => {
await runExtractTOMLTests2(extract);
await runExtractTomlTests2(extract);
});

View File

@ -11,9 +11,10 @@ import { parse } from "@std/yaml/parse";
* Extracts and parses {@link https://yaml.org | YAML} from the metadata of
* front matter content.
*
* @example
* @example Extract YAML front matter
* ```ts
* import { extract } from "@std/front-matter/yaml";
* import { assertEquals } from "@std/assert/assert-equals";
*
* const output = `---yaml
* title: Three dashes marks the spot
@ -21,9 +22,11 @@ import { parse } from "@std/yaml/parse";
* Hello, world!`;
* const result = extract(output);
*
* result.frontMatter; // 'title: Three dashes marks the spot'
* result.body; // "Hello, world!"
* result.attrs; // { title: "Three dashes marks the spot" }
* assertEquals(result, {
* frontMatter: "title: Three dashes marks the spot",
* body: "Hello, world!",
* attrs: { title: "Three dashes marks the spot" },
* });
* ```
*/
export const extract: Extractor = createExtractor({

View File

@ -4,8 +4,8 @@ import { test } from "./test.ts";
import { extract } from "./yaml.ts";
import {
runExtractTypeErrorTests,
runExtractYAMLTests1,
runExtractYAMLTests2,
runExtractYamlTests1,
runExtractYamlTests2,
runTestInvalidInputTests,
runTestValidInputTests,
} from "./_test_utils.ts";
@ -23,9 +23,9 @@ Deno.test("yaml() extracts type error on invalid input", () => {
});
Deno.test("yaml() parses yaml delineate by `---`", async () => {
await runExtractYAMLTests1(extract);
await runExtractYamlTests1(extract);
});
Deno.test("yaml() parses yaml delineate by `---yaml`", async () => {
await runExtractYAMLTests2(extract);
await runExtractYamlTests2(extract);
});