|
1 |
| -/** |
2 |
| - * @typedef {import('mdast').FootnoteReference} FootnoteReference |
3 |
| - * @typedef {import('mdast').FootnoteDefinition} FootnoteDefinition |
4 |
| - * @typedef {import('mdast-util-from-markdown').CompileContext} CompileContext |
5 |
| - * @typedef {import('mdast-util-from-markdown').Extension} FromMarkdownExtension |
6 |
| - * @typedef {import('mdast-util-from-markdown').Handle} FromMarkdownHandle |
7 |
| - * @typedef {import('mdast-util-to-markdown').Options} ToMarkdownExtension |
8 |
| - * @typedef {import('mdast-util-to-markdown').Handle} ToMarkdownHandle |
9 |
| - * @typedef {import('mdast-util-to-markdown').Map} Map |
10 |
| - */ |
11 |
| - |
12 |
| -import {normalizeIdentifier} from 'micromark-util-normalize-identifier' |
13 |
| -import {association} from 'mdast-util-to-markdown/lib/util/association.js' |
14 |
| -import {containerFlow} from 'mdast-util-to-markdown/lib/util/container-flow.js' |
15 |
| -import {indentLines} from 'mdast-util-to-markdown/lib/util/indent-lines.js' |
16 |
| -import {safe} from 'mdast-util-to-markdown/lib/util/safe.js' |
17 |
| -import {track} from 'mdast-util-to-markdown/lib/util/track.js' |
18 |
| - |
19 |
| -/** |
20 |
| - * @returns {FromMarkdownExtension} |
21 |
| - */ |
22 |
| -export function gfmFootnoteFromMarkdown() { |
23 |
| - return { |
24 |
| - enter: { |
25 |
| - gfmFootnoteDefinition: enterFootnoteDefinition, |
26 |
| - gfmFootnoteDefinitionLabelString: enterFootnoteDefinitionLabelString, |
27 |
| - gfmFootnoteCall: enterFootnoteCall, |
28 |
| - gfmFootnoteCallString: enterFootnoteCallString |
29 |
| - }, |
30 |
| - exit: { |
31 |
| - gfmFootnoteDefinition: exitFootnoteDefinition, |
32 |
| - gfmFootnoteDefinitionLabelString: exitFootnoteDefinitionLabelString, |
33 |
| - gfmFootnoteCall: exitFootnoteCall, |
34 |
| - gfmFootnoteCallString: exitFootnoteCallString |
35 |
| - } |
36 |
| - } |
37 |
| - |
38 |
| - /** |
39 |
| - * @this {CompileContext} |
40 |
| - * @type {FromMarkdownHandle} |
41 |
| - */ |
42 |
| - function enterFootnoteDefinition(token) { |
43 |
| - this.enter( |
44 |
| - {type: 'footnoteDefinition', identifier: '', label: '', children: []}, |
45 |
| - token |
46 |
| - ) |
47 |
| - } |
48 |
| - |
49 |
| - /** |
50 |
| - * @this {CompileContext} |
51 |
| - * @type {FromMarkdownHandle} |
52 |
| - */ |
53 |
| - function enterFootnoteDefinitionLabelString() { |
54 |
| - this.buffer() |
55 |
| - } |
56 |
| - |
57 |
| - /** |
58 |
| - * @this {CompileContext} |
59 |
| - * @type {FromMarkdownHandle} |
60 |
| - */ |
61 |
| - function exitFootnoteDefinitionLabelString(token) { |
62 |
| - const label = this.resume() |
63 |
| - const node = /** @type {FootnoteDefinition} */ ( |
64 |
| - this.stack[this.stack.length - 1] |
65 |
| - ) |
66 |
| - node.label = label |
67 |
| - node.identifier = normalizeIdentifier( |
68 |
| - this.sliceSerialize(token) |
69 |
| - ).toLowerCase() |
70 |
| - } |
71 |
| - |
72 |
| - /** |
73 |
| - * @this {CompileContext} |
74 |
| - * @type {FromMarkdownHandle} |
75 |
| - */ |
76 |
| - function exitFootnoteDefinition(token) { |
77 |
| - this.exit(token) |
78 |
| - } |
79 |
| - |
80 |
| - /** |
81 |
| - * @this {CompileContext} |
82 |
| - * @type {FromMarkdownHandle} |
83 |
| - */ |
84 |
| - function enterFootnoteCall(token) { |
85 |
| - this.enter({type: 'footnoteReference', identifier: '', label: ''}, token) |
86 |
| - } |
87 |
| - |
88 |
| - /** |
89 |
| - * @this {CompileContext} |
90 |
| - * @type {FromMarkdownHandle} |
91 |
| - */ |
92 |
| - function enterFootnoteCallString() { |
93 |
| - this.buffer() |
94 |
| - } |
95 |
| - |
96 |
| - /** |
97 |
| - * @this {CompileContext} |
98 |
| - * @type {FromMarkdownHandle} |
99 |
| - */ |
100 |
| - function exitFootnoteCallString(token) { |
101 |
| - const label = this.resume() |
102 |
| - const node = /** @type {FootnoteDefinition} */ ( |
103 |
| - this.stack[this.stack.length - 1] |
104 |
| - ) |
105 |
| - node.label = label |
106 |
| - node.identifier = normalizeIdentifier( |
107 |
| - this.sliceSerialize(token) |
108 |
| - ).toLowerCase() |
109 |
| - } |
110 |
| - |
111 |
| - /** |
112 |
| - * @this {CompileContext} |
113 |
| - * @type {FromMarkdownHandle} |
114 |
| - */ |
115 |
| - function exitFootnoteCall(token) { |
116 |
| - this.exit(token) |
117 |
| - } |
118 |
| -} |
119 |
| - |
120 |
| -/** |
121 |
| - * @returns {ToMarkdownExtension} |
122 |
| - */ |
123 |
| -export function gfmFootnoteToMarkdown() { |
124 |
| - footnoteReference.peek = footnoteReferencePeek |
125 |
| - |
126 |
| - return { |
127 |
| - // This is on by default already. |
128 |
| - unsafe: [{character: '[', inConstruct: ['phrasing', 'label', 'reference']}], |
129 |
| - handlers: {footnoteDefinition, footnoteReference} |
130 |
| - } |
131 |
| - |
132 |
| - /** |
133 |
| - * @type {ToMarkdownHandle} |
134 |
| - * @param {FootnoteReference} node |
135 |
| - */ |
136 |
| - function footnoteReference(node, _, context, safeOptions) { |
137 |
| - const tracker = track(safeOptions) |
138 |
| - let value = tracker.move('[^') |
139 |
| - // @ts-expect-error: use map. |
140 |
| - const exit = context.enter('footnoteReference') |
141 |
| - const subexit = context.enter('reference') |
142 |
| - value += tracker.move( |
143 |
| - safe(context, association(node), { |
144 |
| - ...tracker.current(), |
145 |
| - before: value, |
146 |
| - after: ']' |
147 |
| - }) |
148 |
| - ) |
149 |
| - subexit() |
150 |
| - exit() |
151 |
| - value += tracker.move(']') |
152 |
| - return value |
153 |
| - } |
154 |
| - |
155 |
| - /** @type {ToMarkdownHandle} */ |
156 |
| - function footnoteReferencePeek() { |
157 |
| - return '[' |
158 |
| - } |
159 |
| - |
160 |
| - /** |
161 |
| - * @type {ToMarkdownHandle} |
162 |
| - * @param {FootnoteDefinition} node |
163 |
| - */ |
164 |
| - function footnoteDefinition(node, _, context, safeOptions) { |
165 |
| - const tracker = track(safeOptions) |
166 |
| - let value = tracker.move('[^') |
167 |
| - // @ts-expect-error: use map. |
168 |
| - const exit = context.enter('footnoteDefinition') |
169 |
| - const subexit = context.enter('label') |
170 |
| - value += tracker.move( |
171 |
| - safe(context, association(node), { |
172 |
| - ...tracker.current(), |
173 |
| - before: value, |
174 |
| - after: ']' |
175 |
| - }) |
176 |
| - ) |
177 |
| - subexit() |
178 |
| - value += tracker.move( |
179 |
| - ']:' + (node.children && node.children.length > 0 ? ' ' : '') |
180 |
| - ) |
181 |
| - tracker.shift(4) |
182 |
| - value += tracker.move( |
183 |
| - indentLines(containerFlow(node, context, tracker.current()), map) |
184 |
| - ) |
185 |
| - exit() |
186 |
| - |
187 |
| - return value |
188 |
| - |
189 |
| - /** @type {Map} */ |
190 |
| - function map(line, index, blank) { |
191 |
| - if (index) { |
192 |
| - return (blank ? '' : ' ') + line |
193 |
| - } |
194 |
| - |
195 |
| - return line |
196 |
| - } |
197 |
| - } |
198 |
| -} |
| 1 | +export {gfmFootnoteFromMarkdown, gfmFootnoteToMarkdown} from './lib/index.js' |
0 commit comments