@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.
Files changed (94) hide show
  1. package/README.md +31 -33
  2. package/mod.d.ts +34 -0
  3. package/mod.js +22 -0
  4. package/package.json +117 -40
  5. package/plugins/anchors.d.ts +11 -0
  6. package/plugins/anchors.js +39 -0
  7. package/plugins/callouts.d.ts +14 -0
  8. package/plugins/callouts.js +31 -0
  9. package/plugins/directives.d.ts +24 -0
  10. package/plugins/directives.js +76 -0
  11. package/plugins/emojis.d.ts +11 -0
  12. package/plugins/emojis.js +15 -0
  13. package/plugins/frontmatter.d.ts +20 -0
  14. package/plugins/frontmatter.js +49 -0
  15. package/plugins/gfm.d.ts +18 -0
  16. package/plugins/gfm.js +43 -0
  17. package/plugins/{highlighting.ts → highlighting.d.ts} +2 -11
  18. package/plugins/highlighting.js +24 -0
  19. package/plugins/markers.d.ts +15 -0
  20. package/plugins/markers.js +30 -0
  21. package/plugins/math.d.ts +21 -0
  22. package/plugins/math.js +75 -0
  23. package/plugins/mermaid.d.ts +25 -0
  24. package/plugins/mermaid.js +32 -0
  25. package/plugins/mod.d.ts +15 -0
  26. package/plugins/mod.js +14 -0
  27. package/plugins/{ruby.ts → ruby.d.ts} +2 -11
  28. package/plugins/ruby.js +28 -0
  29. package/plugins/uncomments.d.ts +13 -0
  30. package/plugins/uncomments.js +28 -0
  31. package/plugins/wikilinks.d.ts +26 -0
  32. package/plugins/wikilinks.js +45 -0
  33. package/presets/default.d.ts +3 -0
  34. package/presets/default.js +9 -0
  35. package/presets/svg.d.ts +3 -0
  36. package/presets/svg.js +11 -0
  37. package/presets/text.d.ts +3 -0
  38. package/presets/text.js +11 -0
  39. package/presets/web.d.ts +3 -0
  40. package/presets/web.js +12 -0
  41. package/renderer.d.ts +62 -0
  42. package/renderer.js +70 -0
  43. package/types.d.ts +85 -0
  44. package/types.js +10 -0
  45. package/deno.jsonc +0 -124
  46. package/deno.lock +0 -2282
  47. package/mod.mjs +0 -1
  48. package/mod.ts +0 -2
  49. package/mod_test.ts +0 -1
  50. package/plugins/anchors.mjs +0 -1
  51. package/plugins/anchors.ts +0 -21
  52. package/plugins/anchors_test.ts +0 -8
  53. package/plugins/directives.mjs +0 -1
  54. package/plugins/directives.ts +0 -112
  55. package/plugins/directives_test.ts +0 -13
  56. package/plugins/emojis.mjs +0 -1
  57. package/plugins/emojis.ts +0 -20
  58. package/plugins/emojis_test.ts +0 -8
  59. package/plugins/frontmatter.mjs +0 -1
  60. package/plugins/frontmatter.ts +0 -43
  61. package/plugins/frontmatter_test.ts +0 -18
  62. package/plugins/gfm.mjs +0 -1
  63. package/plugins/gfm.ts +0 -14
  64. package/plugins/gfm_test.ts +0 -28
  65. package/plugins/highlighting.mjs +0 -1
  66. package/plugins/highlighting_test.ts +0 -8
  67. package/plugins/linebreaks.mjs +0 -1
  68. package/plugins/linebreaks.ts +0 -21
  69. package/plugins/linebreaks_test.ts +0 -8
  70. package/plugins/markers.mjs +0 -1
  71. package/plugins/markers.ts +0 -25
  72. package/plugins/markers_test.ts +0 -13
  73. package/plugins/math.mjs +0 -1
  74. package/plugins/math.ts +0 -25
  75. package/plugins/math_test.ts +0 -8
  76. package/plugins/mermaid.mjs +0 -1
  77. package/plugins/mermaid.ts +0 -41
  78. package/plugins/mermaid_test.ts +0 -8
  79. package/plugins/mod.mjs +0 -1
  80. package/plugins/mod.ts +0 -14
  81. package/plugins/ruby.mjs +0 -1
  82. package/plugins/ruby_test.ts +0 -8
  83. package/plugins/sanitize.mjs +0 -1
  84. package/plugins/sanitize.ts +0 -26
  85. package/plugins/sanitize_test.ts +0 -15
  86. package/plugins/uncomments.mjs +0 -1
  87. package/plugins/uncomments.ts +0 -20
  88. package/plugins/uncomments_test.ts +0 -8
  89. package/plugins/wikilinks.mjs +0 -1
  90. package/plugins/wikilinks.ts +0 -40
  91. package/plugins/wikilinks_test.ts +0 -14
  92. package/renderer.mjs +0 -1
  93. package/renderer.ts +0 -138
  94. 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
- })