Skip to content

Commit

Permalink
docs(front-matter): improve docs for stabilization (#4789)
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
magurotuna and iuioiua authored May 28, 2024
1 parent 083b63f commit d13ef17
Show file tree
Hide file tree
Showing 15 changed files with 219 additions and 112 deletions.
1 change: 1 addition & 0 deletions _tools/check_docs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
10 changes: 5 additions & 5 deletions front_matter/_test_utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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"));
Expand Down Expand Up @@ -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"));
Expand Down Expand Up @@ -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"));
Expand Down Expand Up @@ -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"));
Expand Down Expand Up @@ -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"));
Expand Down
7 changes: 7 additions & 0 deletions front_matter/_types.ts
Original file line number Diff line number Diff line change
@@ -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";
8 changes: 4 additions & 4 deletions front_matter/any.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 |
Expand All @@ -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,
});
16 changes: 8 additions & 8 deletions front_matter/any_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand All @@ -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 //
Expand All @@ -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 //
Expand All @@ -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);
});
105 changes: 72 additions & 33 deletions front_matter/create_extractor.ts
Original file line number Diff line number Diff line change
@@ -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> = {
Expand Down Expand Up @@ -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) {
Expand All @@ -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");
* ```
*
* @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";
*
* ({ attrs, body, frontMatter } = extractTOML<{ title: string }>("---toml\ntitle = 'Three dashes followed by format marks the spot'\n---\n"));
* 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"}`);
* ```
*
* @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,
* });
*
* ({ attrs, body, frontMatter } = extractYAMLOrJSON<{ title: string }>("---\ntitle: Three dashes marks the spot\n---\nferret"));
* 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[];

Expand Down
54 changes: 27 additions & 27 deletions front_matter/create_extractor_test.ts
Original file line number Diff line number Diff line change
@@ -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({
Expand All @@ -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);
});
Loading

0 comments on commit d13ef17

Please sign in to comment.