|
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