@lowlighter/markdown 2.0.0 → 3.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +31 -33
- package/mod.d.ts +34 -0
- package/mod.js +22 -0
- package/package.json +117 -40
- package/plugins/anchors.d.ts +11 -0
- package/plugins/anchors.js +39 -0
- package/plugins/callouts.d.ts +14 -0
- package/plugins/callouts.js +31 -0
- package/plugins/directives.d.ts +24 -0
- package/plugins/directives.js +76 -0
- package/plugins/emojis.d.ts +11 -0
- package/plugins/emojis.js +15 -0
- package/plugins/frontmatter.d.ts +20 -0
- package/plugins/frontmatter.js +49 -0
- package/plugins/gfm.d.ts +18 -0
- package/plugins/gfm.js +43 -0
- package/plugins/{highlighting.ts → highlighting.d.ts} +2 -11
- package/plugins/highlighting.js +24 -0
- package/plugins/markers.d.ts +15 -0
- package/plugins/markers.js +30 -0
- package/plugins/math.d.ts +21 -0
- package/plugins/math.js +75 -0
- package/plugins/mermaid.d.ts +25 -0
- package/plugins/mermaid.js +32 -0
- package/plugins/mod.d.ts +15 -0
- package/plugins/mod.js +14 -0
- package/plugins/{ruby.ts → ruby.d.ts} +2 -11
- package/plugins/ruby.js +28 -0
- package/plugins/uncomments.d.ts +13 -0
- package/plugins/uncomments.js +28 -0
- package/plugins/wikilinks.d.ts +26 -0
- package/plugins/wikilinks.js +45 -0
- package/presets/default.d.ts +3 -0
- package/presets/default.js +9 -0
- package/presets/svg.d.ts +3 -0
- package/presets/svg.js +11 -0
- package/presets/text.d.ts +3 -0
- package/presets/text.js +11 -0
- package/presets/web.d.ts +3 -0
- package/presets/web.js +12 -0
- package/renderer.d.ts +62 -0
- package/renderer.js +70 -0
- package/types.d.ts +85 -0
- package/types.js +10 -0
- package/deno.jsonc +0 -124
- package/deno.lock +0 -2282
- package/mod.mjs +0 -1
- package/mod.ts +0 -2
- package/mod_test.ts +0 -1
- package/plugins/anchors.mjs +0 -1
- package/plugins/anchors.ts +0 -21
- package/plugins/anchors_test.ts +0 -8
- package/plugins/directives.mjs +0 -1
- package/plugins/directives.ts +0 -112
- package/plugins/directives_test.ts +0 -13
- package/plugins/emojis.mjs +0 -1
- package/plugins/emojis.ts +0 -20
- package/plugins/emojis_test.ts +0 -8
- package/plugins/frontmatter.mjs +0 -1
- package/plugins/frontmatter.ts +0 -43
- package/plugins/frontmatter_test.ts +0 -18
- package/plugins/gfm.mjs +0 -1
- package/plugins/gfm.ts +0 -14
- package/plugins/gfm_test.ts +0 -28
- package/plugins/highlighting.mjs +0 -1
- package/plugins/highlighting_test.ts +0 -8
- package/plugins/linebreaks.mjs +0 -1
- package/plugins/linebreaks.ts +0 -21
- package/plugins/linebreaks_test.ts +0 -8
- package/plugins/markers.mjs +0 -1
- package/plugins/markers.ts +0 -25
- package/plugins/markers_test.ts +0 -13
- package/plugins/math.mjs +0 -1
- package/plugins/math.ts +0 -25
- package/plugins/math_test.ts +0 -8
- package/plugins/mermaid.mjs +0 -1
- package/plugins/mermaid.ts +0 -41
- package/plugins/mermaid_test.ts +0 -8
- package/plugins/mod.mjs +0 -1
- package/plugins/mod.ts +0 -14
- package/plugins/ruby.mjs +0 -1
- package/plugins/ruby_test.ts +0 -8
- package/plugins/sanitize.mjs +0 -1
- package/plugins/sanitize.ts +0 -26
- package/plugins/sanitize_test.ts +0 -15
- package/plugins/uncomments.mjs +0 -1
- package/plugins/uncomments.ts +0 -20
- package/plugins/uncomments_test.ts +0 -8
- package/plugins/wikilinks.mjs +0 -1
- package/plugins/wikilinks.ts +0 -40
- package/plugins/wikilinks_test.ts +0 -14
- package/renderer.mjs +0 -1
- package/renderer.ts +0 -138
- package/renderer_test.ts +0 -19
package/renderer.ts
DELETED
|
@@ -1,138 +0,0 @@
|
|
|
1
|
-
// Imports
|
|
2
|
-
import { type Processor as _Processor, unified } from "unified"
|
|
3
|
-
import remarkRehype from "remark-rehype"
|
|
4
|
-
import remarkParse from "remark-parse"
|
|
5
|
-
import rehypeRaw from "rehype-raw"
|
|
6
|
-
import rehypeStringify from "rehype-stringify"
|
|
7
|
-
import pluginGfm from "./plugins/gfm.ts"
|
|
8
|
-
import pluginSanitize from "./plugins/sanitize.ts"
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* Markdown renderer.
|
|
12
|
-
*/
|
|
13
|
-
export class Renderer {
|
|
14
|
-
/** Constructor. */
|
|
15
|
-
constructor({ plugins = [] } = {} as { plugins: Plugin[] }) {
|
|
16
|
-
this.#processor = unified().use(remarkParse)
|
|
17
|
-
plugins.filter(({ remark }) => remark).forEach(({ remark }) => this.#processor = remark!(this.#processor, this as unknown as FriendlyRenderer))
|
|
18
|
-
this.#processor = this.#processor.use(remarkRehype, { allowDangerousHtml: true }).use(rehypeRaw)
|
|
19
|
-
plugins.filter(({ rehype }) => rehype).forEach(({ rehype }) => this.#processor = rehype!(this.#processor, this as unknown as FriendlyRenderer))
|
|
20
|
-
this.#processor = this.#processor.use(rehypeStringify)
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
/** Renderer processor. */
|
|
24
|
-
#processor: Processor
|
|
25
|
-
|
|
26
|
-
/** Plugins storage by render id. */
|
|
27
|
-
protected storage = {} as Record<PropertyKey, Record<PropertyKey, unknown>>
|
|
28
|
-
|
|
29
|
-
/**
|
|
30
|
-
* Render markdown content into an HTML string.
|
|
31
|
-
*
|
|
32
|
-
* @example
|
|
33
|
-
* ```ts
|
|
34
|
-
* import { Renderer } from "./renderer.ts"
|
|
35
|
-
* await Renderer.render("# Hello, world!")
|
|
36
|
-
* ```
|
|
37
|
-
* @example
|
|
38
|
-
* ```ts
|
|
39
|
-
* import { Renderer } from "./renderer.ts"
|
|
40
|
-
* import { gfm, highlighting, math, markers, wikilinks, sanitize } from "./plugins/mod.ts"
|
|
41
|
-
* const renderer = new Renderer({ plugins: [ gfm, highlighting, math, markers, wikilinks, sanitize ] })
|
|
42
|
-
* await renderer.render("# Hello, world!")
|
|
43
|
-
* ```
|
|
44
|
-
*/
|
|
45
|
-
async render(content: string, options?: { metadata?: false }): Promise<string>
|
|
46
|
-
/**
|
|
47
|
-
* Render markdown content into an HTML string with parsed metadata.
|
|
48
|
-
*
|
|
49
|
-
* @example
|
|
50
|
-
* ```ts
|
|
51
|
-
* import { Renderer } from "./renderer.ts"
|
|
52
|
-
* import pluginGfm from "./plugins/gfm.ts"
|
|
53
|
-
* import pluginFrontmatter from "./plugins/frontmatter.ts"
|
|
54
|
-
*
|
|
55
|
-
* const renderer = new Renderer({ plugins: [ pluginGfm, pluginFrontmatter ] })
|
|
56
|
-
* await renderer.render(`
|
|
57
|
-
* ---
|
|
58
|
-
* title: Hello, world!
|
|
59
|
-
* ---
|
|
60
|
-
* Lorem ipsum dolor sit amet.
|
|
61
|
-
* `.trim())
|
|
62
|
-
* ```
|
|
63
|
-
*/
|
|
64
|
-
async render(content: string, options?: { metadata: true }): Promise<{ value: string; metadata: Record<PropertyKey, unknown> }>
|
|
65
|
-
/**
|
|
66
|
-
* Render markdown content.
|
|
67
|
-
*/
|
|
68
|
-
async render(content: string, { metadata = false } = {} as { metadata?: boolean }): Promise<string | { value: string; metadata: Record<PropertyKey, unknown> }> {
|
|
69
|
-
const id = (this.#id++) % Number.MAX_SAFE_INTEGER
|
|
70
|
-
try {
|
|
71
|
-
if (metadata) {
|
|
72
|
-
this.storage[id] ??= {}
|
|
73
|
-
}
|
|
74
|
-
const value = `${await this.#processor.process({ id, value: content, cwd: "" })}`
|
|
75
|
-
return metadata ? { value, metadata: { ...this.storage[id] } } : value
|
|
76
|
-
} finally {
|
|
77
|
-
delete this.storage[id]
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
/** Render request id counter. */
|
|
82
|
-
#id = 0
|
|
83
|
-
|
|
84
|
-
/** Default renderer instance. */
|
|
85
|
-
static default = new Renderer({ plugins: [pluginGfm, pluginSanitize] }) as Renderer
|
|
86
|
-
|
|
87
|
-
/** See {@link Renderer.render}. */
|
|
88
|
-
static render = this.default.render.bind(this.default) as typeof Renderer.prototype.render
|
|
89
|
-
|
|
90
|
-
/**
|
|
91
|
-
* Instantiate a new renderer with specified plugins.
|
|
92
|
-
*
|
|
93
|
-
* Plugins may be specified as a URL or string path to a module, or as an already import {@link Plugin} object.
|
|
94
|
-
*
|
|
95
|
-
* @example
|
|
96
|
-
* ```ts
|
|
97
|
-
* import { Renderer } from "./renderer.ts"
|
|
98
|
-
* import frontmatter from "./plugins/frontmatter.ts"
|
|
99
|
-
*
|
|
100
|
-
* const renderer = await Renderer.with({
|
|
101
|
-
* plugins: [
|
|
102
|
-
* frontmatter,
|
|
103
|
-
* "./plugins/gfm.ts",
|
|
104
|
-
* new URL("./plugins/sanitize.ts", import.meta.url),
|
|
105
|
-
* ]
|
|
106
|
-
* })
|
|
107
|
-
* await renderer.render("# foo")
|
|
108
|
-
* ```
|
|
109
|
-
*/
|
|
110
|
-
static async with({ plugins = [], throw: throws = true }: { plugins: Array<Plugin | URL | string>; throw?: boolean }): Promise<Renderer> {
|
|
111
|
-
plugins = plugins.map((plugin) => plugin instanceof URL ? plugin.href : plugin)
|
|
112
|
-
const imported = await Promise.allSettled(plugins.map((plugin) => (typeof plugin === "string") ? import(plugin) : { default: plugin }))
|
|
113
|
-
const resolved = imported
|
|
114
|
-
.filter((result): result is PromiseFulfilledResult<{ default: Plugin }> => result.status === "fulfilled")
|
|
115
|
-
.map(({ value }) => value.default)
|
|
116
|
-
if (throws && (imported.some(({ status }) => status === "rejected"))) {
|
|
117
|
-
const errors = imported
|
|
118
|
-
.filter((result): result is PromiseRejectedResult => result.status === "rejected")
|
|
119
|
-
.map(({ reason }) => reason)
|
|
120
|
-
.join(", ")
|
|
121
|
-
throw new ReferenceError(`Failed to import some plugins: ${errors}`)
|
|
122
|
-
}
|
|
123
|
-
return new Renderer({ plugins: resolved })
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
/** {@link Renderer} with exposed protected properties. */
|
|
128
|
-
export type FriendlyRenderer = Renderer & { storage: Record<PropertyKey, Record<PropertyKey, unknown>> }
|
|
129
|
-
|
|
130
|
-
/** Markdown processor. */
|
|
131
|
-
// deno-lint-ignore no-explicit-any
|
|
132
|
-
export type Processor = _Processor<any, any, any, any, any>
|
|
133
|
-
|
|
134
|
-
/** Markdown plugin. */
|
|
135
|
-
export type Plugin = {
|
|
136
|
-
remark?: (processor: Processor, renderer: FriendlyRenderer) => Processor
|
|
137
|
-
rehype?: (processor: Processor, renderer: FriendlyRenderer) => Processor
|
|
138
|
-
}
|
package/renderer_test.ts
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import { expect, test } from "@libs/testing"
|
|
2
|
-
import { Renderer } from "./renderer.ts"
|
|
3
|
-
import pluginGfm from "./plugins/gfm.ts"
|
|
4
|
-
|
|
5
|
-
test("deno")("`Renderer.render()` renders markdown", async () => {
|
|
6
|
-
const markdown = new Renderer()
|
|
7
|
-
await expect(markdown.render("# foo")).resolves.toBe("<h1>foo</h1>")
|
|
8
|
-
await expect(Renderer.render("# foo")).resolves.toBe("<h1>foo</h1>")
|
|
9
|
-
})
|
|
10
|
-
|
|
11
|
-
test("deno")("`Renderer.with()` instantiates a new customized renderer", async () => {
|
|
12
|
-
const markdown = await Renderer.with({ plugins: ["./plugins/gfm.ts", new URL("./plugins/gfm.ts", import.meta.url), pluginGfm] })
|
|
13
|
-
await expect(markdown.render("# foo")).resolves.toBe("<h1>foo</h1>")
|
|
14
|
-
})
|
|
15
|
-
|
|
16
|
-
test("deno")("`Renderer.with()` honors throw option when creating a new customized renderer", async () => {
|
|
17
|
-
await expect(Renderer.with({ plugins: ["unknown"], throw: false })).resolves.toBeInstanceOf(Renderer)
|
|
18
|
-
await expect(Renderer.with({ plugins: ["unknown"], throw: true })).rejects.toThrow(ReferenceError)
|
|
19
|
-
})
|