|
1 | 1 | /**
|
2 |
| - * @typedef {import('mdast').Literal} Literal |
3 |
| - * @typedef {import('mdast-util-from-markdown').Extension} FromMarkdownExtension |
4 |
| - * @typedef {import('mdast-util-from-markdown').CompileContext} CompileContext |
5 |
| - * @typedef {import('mdast-util-from-markdown').Handle} FromMarkdownHandle |
6 |
| - * @typedef {import('mdast-util-to-markdown').Options} ToMarkdownExtension |
7 |
| - * |
8 |
| - * @typedef {import('micromark-extension-frontmatter/matters.js').Options} Options |
9 |
| - * @typedef {import('micromark-extension-frontmatter/matters.js').Matter} Matter |
10 |
| - * @typedef {import('micromark-extension-frontmatter/matters.js').Info} Info |
| 2 | + * @typedef {import('./lib/index.js').Info} Info |
| 3 | + * @typedef {import('./lib/index.js').Matter} Matter |
| 4 | + * @typedef {import('./lib/index.js').Options} Options |
11 | 5 | */
|
12 | 6 |
|
13 |
| -import {matters} from 'micromark-extension-frontmatter/matters.js' |
14 |
| - |
15 |
| -/** |
16 |
| - * Create an extension for `mdast-util-from-markdown`. |
17 |
| - * |
18 |
| - * @param {Options | null | undefined} [options] |
19 |
| - * Configuration. |
20 |
| - * @returns {FromMarkdownExtension} |
21 |
| - * Extension for `mdast-util-from-markdown`. |
22 |
| - */ |
23 |
| -export function frontmatterFromMarkdown(options) { |
24 |
| - // @ts-expect-error: `micromark-extension-frontmatter` should fix types to |
25 |
| - // accept `null` as options. |
26 |
| - const settings = matters(options) |
27 |
| - /** @type {FromMarkdownExtension['enter']} */ |
28 |
| - const enter = {} |
29 |
| - /** @type {FromMarkdownExtension['exit']} */ |
30 |
| - const exit = {} |
31 |
| - let index = -1 |
32 |
| - |
33 |
| - while (++index < settings.length) { |
34 |
| - const matter = settings[index] |
35 |
| - enter[matter.type] = opener(matter) |
36 |
| - exit[matter.type] = close |
37 |
| - exit[matter.type + 'Value'] = value |
38 |
| - } |
39 |
| - |
40 |
| - return {enter, exit} |
41 |
| -} |
42 |
| - |
43 |
| -/** |
44 |
| - * @param {Matter} matter |
45 |
| - * @returns {FromMarkdownHandle} enter |
46 |
| - */ |
47 |
| -function opener(matter) { |
48 |
| - return open |
49 |
| - |
50 |
| - /** |
51 |
| - * @this {CompileContext} |
52 |
| - * @type {FromMarkdownHandle} |
53 |
| - */ |
54 |
| - function open(token) { |
55 |
| - // @ts-expect-error: custom. |
56 |
| - this.enter({type: matter.type, value: ''}, token) |
57 |
| - this.buffer() |
58 |
| - } |
59 |
| -} |
60 |
| - |
61 |
| -/** |
62 |
| - * @this {CompileContext} |
63 |
| - * @type {FromMarkdownHandle} |
64 |
| - */ |
65 |
| -function close(token) { |
66 |
| - const data = this.resume() |
67 |
| - const node = /** @type {Literal} */ (this.exit(token)) |
68 |
| - // Remove the initial and final eol. |
69 |
| - node.value = data.replace(/^(\r?\n|\r)|(\r?\n|\r)$/g, '') |
70 |
| -} |
71 |
| - |
72 |
| -/** |
73 |
| - * @this {CompileContext} |
74 |
| - * @type {FromMarkdownHandle} |
75 |
| - */ |
76 |
| -function value(token) { |
77 |
| - this.config.enter.data.call(this, token) |
78 |
| - this.config.exit.data.call(this, token) |
79 |
| -} |
80 |
| - |
81 |
| -/** |
82 |
| - * Create an extension for `mdast-util-to-markdown`. |
83 |
| - * |
84 |
| - * @param {Options | null | undefined} [options] |
85 |
| - * Configuration. |
86 |
| - * @returns {ToMarkdownExtension} |
87 |
| - * Extension for `mdast-util-to-markdown`. |
88 |
| - */ |
89 |
| -export function frontmatterToMarkdown(options) { |
90 |
| - // To do: use an extension object with `satisfies` later. |
91 |
| - /** @type {ToMarkdownExtension['unsafe']} */ |
92 |
| - const unsafe = [] |
93 |
| - /** @type {ToMarkdownExtension['handlers']} */ |
94 |
| - const handlers = {} |
95 |
| - // @ts-expect-error: `micromark-extension-frontmatter` should fix types to |
96 |
| - // accept `null` as options. |
97 |
| - const settings = matters(options) |
98 |
| - let index = -1 |
99 |
| - |
100 |
| - while (++index < settings.length) { |
101 |
| - const matter = settings[index] |
102 |
| - |
103 |
| - // @ts-expect-error: this can add custom frontmatter nodes. |
104 |
| - // Typing those is the responsibility of the end user. |
105 |
| - handlers[matter.type] = handler(matter) |
106 |
| - |
107 |
| - // To do: idea: perhaps make this smarter, with an `after` of the second char? |
108 |
| - unsafe.push({atBreak: true, character: fence(matter, 'open').charAt(0)}) |
109 |
| - } |
110 |
| - |
111 |
| - return {unsafe, handlers} |
112 |
| -} |
113 |
| - |
114 |
| -/** |
115 |
| - * Create a handle that can serialize a frontmatter node as markdown. |
116 |
| - * |
117 |
| - * @param {Matter} matter |
118 |
| - * Structure. |
119 |
| - * @returns {(node: Literal) => string} enter |
120 |
| - * Handler. |
121 |
| - */ |
122 |
| -function handler(matter) { |
123 |
| - const open = fence(matter, 'open') |
124 |
| - const close = fence(matter, 'close') |
125 |
| - |
126 |
| - return handle |
127 |
| - |
128 |
| - /** |
129 |
| - * Serialize a frontmatter node as markdown. |
130 |
| - * |
131 |
| - * @param {Literal} node |
132 |
| - * Node to serialize. |
133 |
| - * @returns {string} |
134 |
| - * Serialized node. |
135 |
| - */ |
136 |
| - function handle(node) { |
137 |
| - return open + (node.value ? '\n' + node.value : '') + '\n' + close |
138 |
| - } |
139 |
| -} |
140 |
| - |
141 |
| -/** |
142 |
| - * Get an `open` or `close` fence. |
143 |
| - * |
144 |
| - * @param {Matter} matter |
145 |
| - * Structure. |
146 |
| - * @param {'open' | 'close'} prop |
147 |
| - * Field to get. |
148 |
| - * @returns {string} |
149 |
| - * Fence. |
150 |
| - */ |
151 |
| -function fence(matter, prop) { |
152 |
| - return matter.marker |
153 |
| - ? pick(matter.marker, prop).repeat(3) |
154 |
| - : // @ts-expect-error: They’re mutually exclusive. |
155 |
| - pick(matter.fence, prop) |
156 |
| -} |
157 |
| - |
158 |
| -/** |
159 |
| - * Take `open` or `close` fields when schema is an info object, or use the |
160 |
| - * given value when it is a string. |
161 |
| - * |
162 |
| - * @param {Info | string} schema |
163 |
| - * Info object or value. |
164 |
| - * @param {'open' | 'close'} prop |
165 |
| - * Field to get. |
166 |
| - * @returns {string} |
167 |
| - * Thing to use for the opening or closing. |
168 |
| - */ |
169 |
| -function pick(schema, prop) { |
170 |
| - return typeof schema === 'string' ? schema : schema[prop] |
171 |
| -} |
| 7 | +export {frontmatterFromMarkdown, frontmatterToMarkdown} from './lib/index.js' |
0 commit comments