remark-docx 0.1.8 → 0.2.0
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/lib/{index.mjs → index.cjs} +691 -673
- package/lib/index.cjs.map +1 -0
- package/lib/index.js +688 -674
- package/lib/index.js.map +1 -1
- package/lib/mdast-to-docx.d.ts +5 -5
- package/package.json +13 -17
- package/lib/index.mjs.map +0 -1
package/lib/index.js
CHANGED
|
@@ -1,8 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
var docx = require('docx');
|
|
5
|
-
var unifiedLatexUtilParse = require('@unified-latex/unified-latex-util-parse');
|
|
1
|
+
import { visit } from 'unist-util-visit';
|
|
2
|
+
import { AlignmentType, LevelFormat, convertInchesToTwip, Document, Packer, Math, Paragraph, FootnoteReferenceRun, ImageRun, ExternalHyperlink, TextRun, Table, HeadingLevel, CheckBox, TableRow, TableCell, MathRun, MathRadical, MathFraction, MathSum, MathSubScript, MathSuperScript } from 'docx';
|
|
3
|
+
import { parseMath } from '@unified-latex/unified-latex-util-parse';
|
|
6
4
|
|
|
7
5
|
/**
|
|
8
6
|
* @internal
|
|
@@ -18,455 +16,128 @@ function invariant(cond, message) {
|
|
|
18
16
|
throw new Error(message);
|
|
19
17
|
}
|
|
20
18
|
|
|
21
|
-
const
|
|
22
|
-
|
|
19
|
+
const ORDERED_LIST_REF = "ordered";
|
|
20
|
+
const INDENT = 0.5;
|
|
21
|
+
const DEFAULT_NUMBERINGS = [
|
|
22
|
+
{
|
|
23
|
+
level: 0,
|
|
24
|
+
format: LevelFormat.DECIMAL,
|
|
25
|
+
text: "%1.",
|
|
26
|
+
alignment: AlignmentType.START,
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
level: 1,
|
|
30
|
+
format: LevelFormat.DECIMAL,
|
|
31
|
+
text: "%2.",
|
|
32
|
+
alignment: AlignmentType.START,
|
|
33
|
+
style: {
|
|
34
|
+
paragraph: {
|
|
35
|
+
indent: { start: convertInchesToTwip(INDENT * 1) },
|
|
36
|
+
},
|
|
37
|
+
},
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
level: 2,
|
|
41
|
+
format: LevelFormat.DECIMAL,
|
|
42
|
+
text: "%3.",
|
|
43
|
+
alignment: AlignmentType.START,
|
|
44
|
+
style: {
|
|
45
|
+
paragraph: {
|
|
46
|
+
indent: { start: convertInchesToTwip(INDENT * 2) },
|
|
47
|
+
},
|
|
48
|
+
},
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
level: 3,
|
|
52
|
+
format: LevelFormat.DECIMAL,
|
|
53
|
+
text: "%4.",
|
|
54
|
+
alignment: AlignmentType.START,
|
|
55
|
+
style: {
|
|
56
|
+
paragraph: {
|
|
57
|
+
indent: { start: convertInchesToTwip(INDENT * 3) },
|
|
58
|
+
},
|
|
59
|
+
},
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
level: 4,
|
|
63
|
+
format: LevelFormat.DECIMAL,
|
|
64
|
+
text: "%5.",
|
|
65
|
+
alignment: AlignmentType.START,
|
|
66
|
+
style: {
|
|
67
|
+
paragraph: {
|
|
68
|
+
indent: { start: convertInchesToTwip(INDENT * 4) },
|
|
69
|
+
},
|
|
70
|
+
},
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
level: 5,
|
|
74
|
+
format: LevelFormat.DECIMAL,
|
|
75
|
+
text: "%6.",
|
|
76
|
+
alignment: AlignmentType.START,
|
|
77
|
+
style: {
|
|
78
|
+
paragraph: {
|
|
79
|
+
indent: { start: convertInchesToTwip(INDENT * 5) },
|
|
80
|
+
},
|
|
81
|
+
},
|
|
82
|
+
},
|
|
83
|
+
];
|
|
84
|
+
const createFootnoteRegistry = () => {
|
|
85
|
+
const idToInternalId = new Map();
|
|
86
|
+
const defs = new Map();
|
|
87
|
+
const getId = (id) => {
|
|
88
|
+
let internalId = idToInternalId.get(id);
|
|
89
|
+
if (internalId == null) {
|
|
90
|
+
idToInternalId.set(id, (internalId = idToInternalId.size + 1));
|
|
91
|
+
}
|
|
92
|
+
return internalId;
|
|
93
|
+
};
|
|
94
|
+
return {
|
|
95
|
+
ref: (id) => {
|
|
96
|
+
return getId(id);
|
|
97
|
+
},
|
|
98
|
+
def: (id, def) => {
|
|
99
|
+
const internalId = getId(id);
|
|
100
|
+
defs.set(internalId, def);
|
|
101
|
+
},
|
|
102
|
+
footnotes: () => {
|
|
103
|
+
return defs.entries().reduce((acc, [key, def]) => {
|
|
104
|
+
acc[key] = def;
|
|
105
|
+
return acc;
|
|
106
|
+
}, {});
|
|
107
|
+
},
|
|
108
|
+
};
|
|
23
109
|
};
|
|
24
|
-
const
|
|
25
|
-
|
|
110
|
+
const createNumberingRegistry = () => {
|
|
111
|
+
let counter = 1;
|
|
112
|
+
return {
|
|
113
|
+
create: () => {
|
|
114
|
+
return `${ORDERED_LIST_REF}-${counter++}`;
|
|
115
|
+
},
|
|
116
|
+
getAll: () => {
|
|
117
|
+
return Array.from({ length: counter }, (_, i) => ({
|
|
118
|
+
reference: `${ORDERED_LIST_REF}-${i}`,
|
|
119
|
+
levels: DEFAULT_NUMBERINGS,
|
|
120
|
+
}));
|
|
121
|
+
},
|
|
122
|
+
};
|
|
26
123
|
};
|
|
27
|
-
const
|
|
28
|
-
const mapMacro = (n, runs) => {
|
|
29
|
-
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
30
|
-
switch (n.content) {
|
|
31
|
-
case "#":
|
|
32
|
-
return mapString("#");
|
|
33
|
-
case "$":
|
|
34
|
-
return mapString("$");
|
|
35
|
-
case "%":
|
|
36
|
-
return mapString("%");
|
|
37
|
-
case "&":
|
|
38
|
-
return mapString("&");
|
|
39
|
-
case "textasciitilde":
|
|
40
|
-
return mapString("~");
|
|
41
|
-
case "textasciicircum":
|
|
42
|
-
return mapString("^");
|
|
43
|
-
case "textbackslash":
|
|
44
|
-
return mapString("∖");
|
|
45
|
-
case "{":
|
|
46
|
-
return mapString("{");
|
|
47
|
-
case "}":
|
|
48
|
-
return mapString("}");
|
|
49
|
-
case "textbar":
|
|
50
|
-
return mapString("|");
|
|
51
|
-
case "textless":
|
|
52
|
-
return mapString("<");
|
|
53
|
-
case "textgreater":
|
|
54
|
-
return mapString(">");
|
|
55
|
-
case "neq":
|
|
56
|
-
return mapString("≠");
|
|
57
|
-
case "sim":
|
|
58
|
-
return mapString("∼");
|
|
59
|
-
case "simeq":
|
|
60
|
-
return mapString("≃");
|
|
61
|
-
case "approx":
|
|
62
|
-
return mapString("≈");
|
|
63
|
-
case "fallingdotseq":
|
|
64
|
-
return mapString("≒");
|
|
65
|
-
case "risingdotseq":
|
|
66
|
-
return mapString("≓");
|
|
67
|
-
case "equiv":
|
|
68
|
-
return mapString("≡");
|
|
69
|
-
case "geq":
|
|
70
|
-
return mapString("≥");
|
|
71
|
-
case "geqq":
|
|
72
|
-
return mapString("≧");
|
|
73
|
-
case "leq":
|
|
74
|
-
return mapString("≤");
|
|
75
|
-
case "leqq":
|
|
76
|
-
return mapString("≦");
|
|
77
|
-
case "gg":
|
|
78
|
-
return mapString("≫");
|
|
79
|
-
case "ll":
|
|
80
|
-
return mapString("≪");
|
|
81
|
-
case "times":
|
|
82
|
-
return mapString("×");
|
|
83
|
-
case "div":
|
|
84
|
-
return mapString("÷");
|
|
85
|
-
case "pm":
|
|
86
|
-
return mapString("±");
|
|
87
|
-
case "mp":
|
|
88
|
-
return mapString("∓");
|
|
89
|
-
case "oplus":
|
|
90
|
-
return mapString("⊕");
|
|
91
|
-
case "ominus":
|
|
92
|
-
return mapString("⊖");
|
|
93
|
-
case "otimes":
|
|
94
|
-
return mapString("⊗");
|
|
95
|
-
case "oslash":
|
|
96
|
-
return mapString("⊘");
|
|
97
|
-
case "circ":
|
|
98
|
-
return mapString("∘");
|
|
99
|
-
case "cdot":
|
|
100
|
-
return mapString("⋅");
|
|
101
|
-
case "bullet":
|
|
102
|
-
return mapString("∙");
|
|
103
|
-
case "ltimes":
|
|
104
|
-
return mapString("⋉");
|
|
105
|
-
case "rtimes":
|
|
106
|
-
return mapString("⋊");
|
|
107
|
-
case "in":
|
|
108
|
-
return mapString("∈");
|
|
109
|
-
case "ni":
|
|
110
|
-
return mapString("∋");
|
|
111
|
-
case "notin":
|
|
112
|
-
return mapString("∉");
|
|
113
|
-
case "subset":
|
|
114
|
-
return mapString("⊂");
|
|
115
|
-
case "supset":
|
|
116
|
-
return mapString("⊃");
|
|
117
|
-
case "subseteq":
|
|
118
|
-
return mapString("⊆");
|
|
119
|
-
case "supseteq":
|
|
120
|
-
return mapString("⊇");
|
|
121
|
-
case "nsubseteq":
|
|
122
|
-
return mapString("⊈");
|
|
123
|
-
case "nsupseteq":
|
|
124
|
-
return mapString("⊉");
|
|
125
|
-
case "subsetneq":
|
|
126
|
-
return mapString("⊊");
|
|
127
|
-
case "supsetneq":
|
|
128
|
-
return mapString("⊋");
|
|
129
|
-
case "cap":
|
|
130
|
-
return mapString("∩");
|
|
131
|
-
case "cup":
|
|
132
|
-
return mapString("∪");
|
|
133
|
-
case "emptyset":
|
|
134
|
-
return mapString("∅");
|
|
135
|
-
case "infty":
|
|
136
|
-
return mapString("∞");
|
|
137
|
-
case "partial":
|
|
138
|
-
return mapString("∂");
|
|
139
|
-
case "aleph":
|
|
140
|
-
return mapString("ℵ");
|
|
141
|
-
case "hbar":
|
|
142
|
-
return mapString("ℏ");
|
|
143
|
-
case "wp":
|
|
144
|
-
return mapString("℘");
|
|
145
|
-
case "Re":
|
|
146
|
-
return mapString("ℜ");
|
|
147
|
-
case "Im":
|
|
148
|
-
return mapString("ℑ");
|
|
149
|
-
case "alpha":
|
|
150
|
-
return mapString("α");
|
|
151
|
-
case "beta":
|
|
152
|
-
return mapString("β");
|
|
153
|
-
case "gamma":
|
|
154
|
-
return mapString("γ");
|
|
155
|
-
case "delta":
|
|
156
|
-
return mapString("δ");
|
|
157
|
-
case "epsilon":
|
|
158
|
-
return mapString("ϵ");
|
|
159
|
-
case "zeta":
|
|
160
|
-
return mapString("ζ");
|
|
161
|
-
case "eta":
|
|
162
|
-
return mapString("η");
|
|
163
|
-
case "theta":
|
|
164
|
-
return mapString("θ");
|
|
165
|
-
case "iota":
|
|
166
|
-
return mapString("ι");
|
|
167
|
-
case "kappa":
|
|
168
|
-
return mapString("κ");
|
|
169
|
-
case "lambda":
|
|
170
|
-
return mapString("λ");
|
|
171
|
-
case "eta":
|
|
172
|
-
return mapString("η");
|
|
173
|
-
case "mu":
|
|
174
|
-
return mapString("μ");
|
|
175
|
-
case "nu":
|
|
176
|
-
return mapString("ν");
|
|
177
|
-
case "xi":
|
|
178
|
-
return mapString("ξ");
|
|
179
|
-
case "pi":
|
|
180
|
-
return mapString("π");
|
|
181
|
-
case "rho":
|
|
182
|
-
return mapString("ρ");
|
|
183
|
-
case "sigma":
|
|
184
|
-
return mapString("σ");
|
|
185
|
-
case "tau":
|
|
186
|
-
return mapString("τ");
|
|
187
|
-
case "upsilon":
|
|
188
|
-
return mapString("υ");
|
|
189
|
-
case "phi":
|
|
190
|
-
return mapString("ϕ");
|
|
191
|
-
case "chi":
|
|
192
|
-
return mapString("χ");
|
|
193
|
-
case "psi":
|
|
194
|
-
return mapString("ψ");
|
|
195
|
-
case "omega":
|
|
196
|
-
return mapString("ω");
|
|
197
|
-
case "varepsilon":
|
|
198
|
-
return mapString("ε");
|
|
199
|
-
case "vartheta":
|
|
200
|
-
return mapString("ϑ");
|
|
201
|
-
case "varrho":
|
|
202
|
-
return mapString("ϱ");
|
|
203
|
-
case "varsigma":
|
|
204
|
-
return mapString("ς");
|
|
205
|
-
case "varphi":
|
|
206
|
-
return mapString("φ");
|
|
207
|
-
case "Gamma":
|
|
208
|
-
return mapString("Γ");
|
|
209
|
-
case "Delta":
|
|
210
|
-
return mapString("Δ");
|
|
211
|
-
case "Theta":
|
|
212
|
-
return mapString("Θ");
|
|
213
|
-
case "Lambda":
|
|
214
|
-
return mapString("Λ");
|
|
215
|
-
case "Xi":
|
|
216
|
-
return mapString("Ξ");
|
|
217
|
-
case "Pi":
|
|
218
|
-
return mapString("Π");
|
|
219
|
-
case "Sigma":
|
|
220
|
-
return mapString("Σ");
|
|
221
|
-
case "Upsilon":
|
|
222
|
-
return mapString("Υ");
|
|
223
|
-
case "Phi":
|
|
224
|
-
return mapString("Φ");
|
|
225
|
-
case "Psi":
|
|
226
|
-
return mapString("Ψ");
|
|
227
|
-
case "Omega":
|
|
228
|
-
return mapString("Ω");
|
|
229
|
-
case "newline":
|
|
230
|
-
case "\\":
|
|
231
|
-
// line break
|
|
232
|
-
return false;
|
|
233
|
-
case "^": {
|
|
234
|
-
const prev = runs.pop();
|
|
235
|
-
if (!prev)
|
|
236
|
-
break;
|
|
237
|
-
return new docx.MathSuperScript({
|
|
238
|
-
children: [prev],
|
|
239
|
-
superScript: mapGroup((_c = (_b = (_a = n.args) === null || _a === void 0 ? void 0 : _a[0]) === null || _b === void 0 ? void 0 : _b.content) !== null && _c !== void 0 ? _c : []),
|
|
240
|
-
});
|
|
241
|
-
}
|
|
242
|
-
case "_": {
|
|
243
|
-
const prev = runs.pop();
|
|
244
|
-
if (!prev)
|
|
245
|
-
break;
|
|
246
|
-
return new docx.MathSubScript({
|
|
247
|
-
children: [prev],
|
|
248
|
-
subScript: mapGroup((_f = (_e = (_d = n.args) === null || _d === void 0 ? void 0 : _d[0]) === null || _e === void 0 ? void 0 : _e.content) !== null && _f !== void 0 ? _f : []),
|
|
249
|
-
});
|
|
250
|
-
}
|
|
251
|
-
case "hat":
|
|
252
|
-
// TODO: implement
|
|
253
|
-
break;
|
|
254
|
-
case "widehat":
|
|
255
|
-
// TODO: implement
|
|
256
|
-
break;
|
|
257
|
-
case "sum": {
|
|
258
|
-
// TODO: support superscript and subscript
|
|
259
|
-
return new docx.MathSum({
|
|
260
|
-
children: [],
|
|
261
|
-
});
|
|
262
|
-
}
|
|
263
|
-
case "int":
|
|
264
|
-
return mapString("∫");
|
|
265
|
-
case "frac":
|
|
266
|
-
case "tfrac":
|
|
267
|
-
case "dfrac": {
|
|
268
|
-
const args = (_g = n.args) !== null && _g !== void 0 ? _g : [];
|
|
269
|
-
if (args.length === 2 &&
|
|
270
|
-
hasCurlyBrackets(args[0]) &&
|
|
271
|
-
hasCurlyBrackets(args[1])) {
|
|
272
|
-
return new docx.MathFraction({
|
|
273
|
-
numerator: mapGroup(args[0].content),
|
|
274
|
-
denominator: mapGroup(args[1].content),
|
|
275
|
-
});
|
|
276
|
-
}
|
|
277
|
-
break;
|
|
278
|
-
}
|
|
279
|
-
case "sqrt": {
|
|
280
|
-
const args = (_h = n.args) !== null && _h !== void 0 ? _h : [];
|
|
281
|
-
if (args.length === 1 && hasCurlyBrackets(args[0])) {
|
|
282
|
-
return new docx.MathRadical({
|
|
283
|
-
children: mapGroup(args[0].content),
|
|
284
|
-
});
|
|
285
|
-
}
|
|
286
|
-
if (args.length === 2 &&
|
|
287
|
-
hasSquareBrackets(args[0]) &&
|
|
288
|
-
hasCurlyBrackets(args[1])) {
|
|
289
|
-
return new docx.MathRadical({
|
|
290
|
-
children: mapGroup(args[1].content),
|
|
291
|
-
degree: mapGroup(args[0].content),
|
|
292
|
-
});
|
|
293
|
-
}
|
|
294
|
-
break;
|
|
295
|
-
}
|
|
296
|
-
}
|
|
297
|
-
return mapString(n.content);
|
|
298
|
-
};
|
|
299
|
-
const mapGroup = (nodes) => {
|
|
300
|
-
const group = [];
|
|
301
|
-
for (const c of nodes) {
|
|
302
|
-
group.push(...(mapNode(c, group) || []));
|
|
303
|
-
}
|
|
304
|
-
return group;
|
|
305
|
-
};
|
|
306
|
-
const mapNode = (n, runs) => {
|
|
307
|
-
switch (n.type) {
|
|
308
|
-
case "root":
|
|
309
|
-
break;
|
|
310
|
-
case "string":
|
|
311
|
-
return [mapString(n.content)];
|
|
312
|
-
case "whitespace":
|
|
313
|
-
break;
|
|
314
|
-
case "parbreak":
|
|
315
|
-
break;
|
|
316
|
-
case "comment":
|
|
317
|
-
break;
|
|
318
|
-
case "macro":
|
|
319
|
-
const run = mapMacro(n, runs);
|
|
320
|
-
if (!run) {
|
|
321
|
-
// line break
|
|
322
|
-
return false;
|
|
323
|
-
}
|
|
324
|
-
else {
|
|
325
|
-
return [run];
|
|
326
|
-
}
|
|
327
|
-
case "environment":
|
|
328
|
-
case "mathenv":
|
|
329
|
-
break;
|
|
330
|
-
case "verbatim":
|
|
331
|
-
break;
|
|
332
|
-
case "inlinemath":
|
|
333
|
-
break;
|
|
334
|
-
case "displaymath":
|
|
335
|
-
break;
|
|
336
|
-
case "group":
|
|
337
|
-
return mapGroup(n.content);
|
|
338
|
-
case "verb":
|
|
339
|
-
break;
|
|
340
|
-
default:
|
|
341
|
-
unreachable();
|
|
342
|
-
}
|
|
343
|
-
return [];
|
|
344
|
-
};
|
|
345
|
-
/**
|
|
346
|
-
* @internal
|
|
347
|
-
*/
|
|
348
|
-
const parseLatex = (value) => {
|
|
349
|
-
const parsed = unifiedLatexUtilParse.parseMath(value);
|
|
350
|
-
const paragraphs = [[]];
|
|
351
|
-
let runs = paragraphs[0];
|
|
352
|
-
for (const n of parsed) {
|
|
353
|
-
const res = mapNode(n, runs);
|
|
354
|
-
if (!res) {
|
|
355
|
-
// line break
|
|
356
|
-
paragraphs.push((runs = []));
|
|
357
|
-
}
|
|
358
|
-
else {
|
|
359
|
-
runs.push(...res);
|
|
360
|
-
}
|
|
361
|
-
}
|
|
362
|
-
return paragraphs;
|
|
363
|
-
};
|
|
364
|
-
|
|
365
|
-
const ORDERED_LIST_REF = "ordered";
|
|
366
|
-
const INDENT = 0.5;
|
|
367
|
-
const DEFAULT_NUMBERINGS = [
|
|
368
|
-
{
|
|
369
|
-
level: 0,
|
|
370
|
-
format: docx.LevelFormat.DECIMAL,
|
|
371
|
-
text: "%1.",
|
|
372
|
-
alignment: docx.AlignmentType.START,
|
|
373
|
-
},
|
|
374
|
-
{
|
|
375
|
-
level: 1,
|
|
376
|
-
format: docx.LevelFormat.DECIMAL,
|
|
377
|
-
text: "%2.",
|
|
378
|
-
alignment: docx.AlignmentType.START,
|
|
379
|
-
style: {
|
|
380
|
-
paragraph: {
|
|
381
|
-
indent: { start: docx.convertInchesToTwip(INDENT * 1) },
|
|
382
|
-
},
|
|
383
|
-
},
|
|
384
|
-
},
|
|
385
|
-
{
|
|
386
|
-
level: 2,
|
|
387
|
-
format: docx.LevelFormat.DECIMAL,
|
|
388
|
-
text: "%3.",
|
|
389
|
-
alignment: docx.AlignmentType.START,
|
|
390
|
-
style: {
|
|
391
|
-
paragraph: {
|
|
392
|
-
indent: { start: docx.convertInchesToTwip(INDENT * 2) },
|
|
393
|
-
},
|
|
394
|
-
},
|
|
395
|
-
},
|
|
396
|
-
{
|
|
397
|
-
level: 3,
|
|
398
|
-
format: docx.LevelFormat.DECIMAL,
|
|
399
|
-
text: "%4.",
|
|
400
|
-
alignment: docx.AlignmentType.START,
|
|
401
|
-
style: {
|
|
402
|
-
paragraph: {
|
|
403
|
-
indent: { start: docx.convertInchesToTwip(INDENT * 3) },
|
|
404
|
-
},
|
|
405
|
-
},
|
|
406
|
-
},
|
|
407
|
-
{
|
|
408
|
-
level: 4,
|
|
409
|
-
format: docx.LevelFormat.DECIMAL,
|
|
410
|
-
text: "%5.",
|
|
411
|
-
alignment: docx.AlignmentType.START,
|
|
412
|
-
style: {
|
|
413
|
-
paragraph: {
|
|
414
|
-
indent: { start: docx.convertInchesToTwip(INDENT * 4) },
|
|
415
|
-
},
|
|
416
|
-
},
|
|
417
|
-
},
|
|
418
|
-
{
|
|
419
|
-
level: 5,
|
|
420
|
-
format: docx.LevelFormat.DECIMAL,
|
|
421
|
-
text: "%6.",
|
|
422
|
-
alignment: docx.AlignmentType.START,
|
|
423
|
-
style: {
|
|
424
|
-
paragraph: {
|
|
425
|
-
indent: { start: docx.convertInchesToTwip(INDENT * 5) },
|
|
426
|
-
},
|
|
427
|
-
},
|
|
428
|
-
},
|
|
429
|
-
];
|
|
430
|
-
const createFootnoteRegistry = () => {
|
|
431
|
-
const idToInternalId = new Map();
|
|
432
|
-
const defs = new Map();
|
|
433
|
-
const getId = (id) => {
|
|
434
|
-
let internalId = idToInternalId.get(id);
|
|
435
|
-
if (internalId == null) {
|
|
436
|
-
idToInternalId.set(id, (internalId = idToInternalId.size + 1));
|
|
437
|
-
}
|
|
438
|
-
return internalId;
|
|
439
|
-
};
|
|
440
|
-
return {
|
|
441
|
-
ref: (id) => {
|
|
442
|
-
return getId(id);
|
|
443
|
-
},
|
|
444
|
-
def: (id, def) => {
|
|
445
|
-
const internalId = getId(id);
|
|
446
|
-
defs.set(internalId, def);
|
|
447
|
-
},
|
|
448
|
-
footnotes: () => {
|
|
449
|
-
return defs.entries().reduce((acc, [key, def]) => {
|
|
450
|
-
acc[key] = def;
|
|
451
|
-
return acc;
|
|
452
|
-
}, {});
|
|
453
|
-
},
|
|
454
|
-
};
|
|
455
|
-
};
|
|
456
|
-
const mdastToDocx = async (node, { output = "buffer", title, subject, creator, keywords, description, lastModifiedBy, revision, styles, background, }, images) => {
|
|
124
|
+
const mdastToDocx = async (node, { output = "buffer", title, subject, creator, keywords, description, lastModifiedBy, revision, styles, background, }, images, latex) => {
|
|
457
125
|
const definition = {};
|
|
458
|
-
|
|
126
|
+
visit(node, "definition", (node) => {
|
|
459
127
|
definition[node.identifier] = node.url;
|
|
460
128
|
});
|
|
461
129
|
const footnote = createFootnoteRegistry();
|
|
130
|
+
const numbering = createNumberingRegistry();
|
|
462
131
|
const nodes = convertNodes(node.children, {
|
|
463
132
|
deco: {},
|
|
464
133
|
images,
|
|
465
134
|
indent: 0,
|
|
466
135
|
def: definition,
|
|
467
136
|
footnote,
|
|
137
|
+
numbering,
|
|
138
|
+
latex,
|
|
468
139
|
});
|
|
469
|
-
const doc = new
|
|
140
|
+
const doc = new Document({
|
|
470
141
|
title,
|
|
471
142
|
subject,
|
|
472
143
|
creator,
|
|
@@ -479,23 +150,16 @@ const mdastToDocx = async (node, { output = "buffer", title, subject, creator, k
|
|
|
479
150
|
footnotes: footnote.footnotes(),
|
|
480
151
|
sections: [{ children: nodes }],
|
|
481
152
|
numbering: {
|
|
482
|
-
config:
|
|
483
|
-
{
|
|
484
|
-
reference: ORDERED_LIST_REF,
|
|
485
|
-
levels: DEFAULT_NUMBERINGS,
|
|
486
|
-
},
|
|
487
|
-
],
|
|
153
|
+
config: numbering.getAll(),
|
|
488
154
|
},
|
|
489
155
|
});
|
|
490
156
|
switch (output) {
|
|
491
157
|
case "buffer":
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
// when it doesn't detect a Node environment.
|
|
496
|
-
return typeof Buffer === "function" ? Buffer.from(bufOut) : bufOut;
|
|
158
|
+
return Packer.toBuffer(doc);
|
|
159
|
+
case "arrayBuffer":
|
|
160
|
+
return Packer.toArrayBuffer(doc);
|
|
497
161
|
case "blob":
|
|
498
|
-
return
|
|
162
|
+
return Packer.toBlob(doc);
|
|
499
163
|
}
|
|
500
164
|
};
|
|
501
165
|
const convertNodes = (nodes, ctx) => {
|
|
@@ -587,255 +251,605 @@ const convertNodes = (nodes, ctx) => {
|
|
|
587
251
|
}
|
|
588
252
|
break;
|
|
589
253
|
}
|
|
590
|
-
case "footnote": {
|
|
591
|
-
// inline footnote was removed in mdast v5
|
|
592
|
-
break;
|
|
254
|
+
case "footnote": {
|
|
255
|
+
// inline footnote was removed in mdast v5
|
|
256
|
+
break;
|
|
257
|
+
}
|
|
258
|
+
case "footnoteReference":
|
|
259
|
+
results.push(buildFootnoteReference(node, ctx));
|
|
260
|
+
break;
|
|
261
|
+
case "math":
|
|
262
|
+
results.push(...buildMath(node, ctx));
|
|
263
|
+
break;
|
|
264
|
+
case "inlineMath":
|
|
265
|
+
results.push(buildInlineMath(node, ctx));
|
|
266
|
+
break;
|
|
267
|
+
default:
|
|
268
|
+
unreachable();
|
|
269
|
+
break;
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
return results;
|
|
273
|
+
};
|
|
274
|
+
const buildParagraph = ({ children }, ctx) => {
|
|
275
|
+
const list = ctx.list;
|
|
276
|
+
const nodes = convertNodes(children, ctx);
|
|
277
|
+
if (list && list.checked != null) {
|
|
278
|
+
nodes.unshift(new CheckBox({
|
|
279
|
+
checked: list.checked,
|
|
280
|
+
checkedState: { value: "2611" },
|
|
281
|
+
uncheckedState: { value: "2610" },
|
|
282
|
+
}));
|
|
283
|
+
}
|
|
284
|
+
return new Paragraph({
|
|
285
|
+
children: nodes,
|
|
286
|
+
indent: ctx.indent > 0
|
|
287
|
+
? {
|
|
288
|
+
start: convertInchesToTwip(INDENT * ctx.indent),
|
|
289
|
+
}
|
|
290
|
+
: undefined,
|
|
291
|
+
...(list &&
|
|
292
|
+
(list.ordered
|
|
293
|
+
? {
|
|
294
|
+
numbering: {
|
|
295
|
+
reference: list.reference,
|
|
296
|
+
level: list.level,
|
|
297
|
+
},
|
|
298
|
+
}
|
|
299
|
+
: {
|
|
300
|
+
bullet: {
|
|
301
|
+
level: list.level,
|
|
302
|
+
},
|
|
303
|
+
})),
|
|
304
|
+
});
|
|
305
|
+
};
|
|
306
|
+
const buildHeading = ({ children, depth }, ctx) => {
|
|
307
|
+
let headingLevel;
|
|
308
|
+
switch (depth) {
|
|
309
|
+
case 1:
|
|
310
|
+
headingLevel = HeadingLevel.TITLE;
|
|
311
|
+
break;
|
|
312
|
+
case 2:
|
|
313
|
+
headingLevel = HeadingLevel.HEADING_1;
|
|
314
|
+
break;
|
|
315
|
+
case 3:
|
|
316
|
+
headingLevel = HeadingLevel.HEADING_2;
|
|
317
|
+
break;
|
|
318
|
+
case 4:
|
|
319
|
+
headingLevel = HeadingLevel.HEADING_3;
|
|
320
|
+
break;
|
|
321
|
+
case 5:
|
|
322
|
+
headingLevel = HeadingLevel.HEADING_4;
|
|
323
|
+
break;
|
|
324
|
+
case 6:
|
|
325
|
+
headingLevel = HeadingLevel.HEADING_5;
|
|
326
|
+
break;
|
|
327
|
+
}
|
|
328
|
+
const nodes = convertNodes(children, ctx);
|
|
329
|
+
return new Paragraph({
|
|
330
|
+
heading: headingLevel,
|
|
331
|
+
children: nodes,
|
|
332
|
+
});
|
|
333
|
+
};
|
|
334
|
+
const buildThematicBreak = (_) => {
|
|
335
|
+
return new Paragraph({
|
|
336
|
+
thematicBreak: true,
|
|
337
|
+
});
|
|
338
|
+
};
|
|
339
|
+
const buildBlockquote = ({ children }, ctx) => {
|
|
340
|
+
return convertNodes(children, {
|
|
341
|
+
...ctx,
|
|
342
|
+
indent: ctx.indent + 1,
|
|
343
|
+
});
|
|
344
|
+
};
|
|
345
|
+
const buildList = ({ children, ordered, start: _start, spread: _spread }, ctx) => {
|
|
346
|
+
var _a;
|
|
347
|
+
const isTopLevel = !ctx.list;
|
|
348
|
+
const list = {
|
|
349
|
+
level: ctx.list ? ctx.list.level + 1 : 0,
|
|
350
|
+
ordered: !!ordered,
|
|
351
|
+
reference: isTopLevel && ordered
|
|
352
|
+
? ctx.numbering.create()
|
|
353
|
+
: ((_a = ctx.list) === null || _a === void 0 ? void 0 : _a.reference) || ORDERED_LIST_REF,
|
|
354
|
+
};
|
|
355
|
+
return children.flatMap((item) => {
|
|
356
|
+
return buildListItem(item, {
|
|
357
|
+
...ctx,
|
|
358
|
+
list,
|
|
359
|
+
});
|
|
360
|
+
});
|
|
361
|
+
};
|
|
362
|
+
const buildListItem = ({ children, checked, spread: _spread }, ctx) => {
|
|
363
|
+
return convertNodes(children, {
|
|
364
|
+
...ctx,
|
|
365
|
+
...(ctx.list && { list: { ...ctx.list, checked: checked !== null && checked !== void 0 ? checked : undefined } }),
|
|
366
|
+
});
|
|
367
|
+
};
|
|
368
|
+
const buildTable = ({ children, align }, ctx) => {
|
|
369
|
+
const cellAligns = align === null || align === void 0 ? void 0 : align.map((a) => {
|
|
370
|
+
switch (a) {
|
|
371
|
+
case "left":
|
|
372
|
+
return AlignmentType.LEFT;
|
|
373
|
+
case "right":
|
|
374
|
+
return AlignmentType.RIGHT;
|
|
375
|
+
case "center":
|
|
376
|
+
return AlignmentType.CENTER;
|
|
377
|
+
default:
|
|
378
|
+
return AlignmentType.LEFT;
|
|
379
|
+
}
|
|
380
|
+
});
|
|
381
|
+
return new Table({
|
|
382
|
+
rows: children.map((r) => {
|
|
383
|
+
return buildTableRow(r, ctx, cellAligns);
|
|
384
|
+
}),
|
|
385
|
+
});
|
|
386
|
+
};
|
|
387
|
+
const buildTableRow = ({ children }, ctx, cellAligns) => {
|
|
388
|
+
return new TableRow({
|
|
389
|
+
children: children.map((c, i) => {
|
|
390
|
+
return buildTableCell(c, ctx, cellAligns === null || cellAligns === void 0 ? void 0 : cellAligns[i]);
|
|
391
|
+
}),
|
|
392
|
+
});
|
|
393
|
+
};
|
|
394
|
+
const buildTableCell = ({ children }, ctx, align) => {
|
|
395
|
+
const nodes = convertNodes(children, ctx);
|
|
396
|
+
return new TableCell({
|
|
397
|
+
children: [
|
|
398
|
+
new Paragraph({
|
|
399
|
+
alignment: align,
|
|
400
|
+
children: nodes,
|
|
401
|
+
}),
|
|
402
|
+
],
|
|
403
|
+
});
|
|
404
|
+
};
|
|
405
|
+
const buildHtml = ({ value }) => {
|
|
406
|
+
// FIXME: transform to text for now
|
|
407
|
+
return new Paragraph({
|
|
408
|
+
children: [buildText(value, {})],
|
|
409
|
+
});
|
|
410
|
+
};
|
|
411
|
+
const buildCode = ({ value, lang: _lang, meta: _meta, }) => {
|
|
412
|
+
// FIXME: transform to text for now
|
|
413
|
+
return new Paragraph({
|
|
414
|
+
children: [buildText(value, {})],
|
|
415
|
+
});
|
|
416
|
+
};
|
|
417
|
+
const buildMath = ({ value }, ctx) => {
|
|
418
|
+
return ctx.latex(value).map((runs) => new Paragraph({
|
|
419
|
+
children: [
|
|
420
|
+
new Math({
|
|
421
|
+
children: runs,
|
|
422
|
+
}),
|
|
423
|
+
],
|
|
424
|
+
}));
|
|
425
|
+
};
|
|
426
|
+
const buildInlineMath = ({ value }, ctx) => {
|
|
427
|
+
return new Math({
|
|
428
|
+
children: ctx.latex(value).flatMap((runs) => runs),
|
|
429
|
+
});
|
|
430
|
+
};
|
|
431
|
+
const buildText = (text, deco) => {
|
|
432
|
+
return new TextRun({
|
|
433
|
+
text,
|
|
434
|
+
bold: deco.strong,
|
|
435
|
+
italics: deco.emphasis,
|
|
436
|
+
strike: deco.delete,
|
|
437
|
+
});
|
|
438
|
+
};
|
|
439
|
+
const buildBreak = (_) => {
|
|
440
|
+
return new TextRun({ text: "", break: 1 });
|
|
441
|
+
};
|
|
442
|
+
const buildLink = ({ children, url }, ctx) => {
|
|
443
|
+
const nodes = convertNodes(children, ctx);
|
|
444
|
+
return new ExternalHyperlink({
|
|
445
|
+
link: url,
|
|
446
|
+
children: nodes,
|
|
447
|
+
});
|
|
448
|
+
};
|
|
449
|
+
const buildImage = ({ url }, images) => {
|
|
450
|
+
const img = images[url];
|
|
451
|
+
invariant(img, `Fetch image was failed: ${url}`);
|
|
452
|
+
const { image, width, height } = img;
|
|
453
|
+
return new ImageRun({
|
|
454
|
+
type: img.type,
|
|
455
|
+
data: image,
|
|
456
|
+
transformation: {
|
|
457
|
+
width,
|
|
458
|
+
height,
|
|
459
|
+
},
|
|
460
|
+
});
|
|
461
|
+
};
|
|
462
|
+
const buildLinkReference = ({ children, identifier }, ctx) => {
|
|
463
|
+
const def = ctx.def[identifier];
|
|
464
|
+
if (def == null) {
|
|
465
|
+
return convertNodes(children, ctx);
|
|
466
|
+
}
|
|
467
|
+
return [buildLink({ children, url: def }, ctx)];
|
|
468
|
+
};
|
|
469
|
+
const buildImageReference = ({ identifier }, ctx) => {
|
|
470
|
+
const def = ctx.def[identifier];
|
|
471
|
+
if (def == null) {
|
|
472
|
+
return;
|
|
473
|
+
}
|
|
474
|
+
return buildImage({ url: def }, ctx.images);
|
|
475
|
+
};
|
|
476
|
+
const registerFootnoteDefinition = ({ children, identifier }, ctx) => {
|
|
477
|
+
const definition = {
|
|
478
|
+
children: children.map((node) => {
|
|
479
|
+
// Convert each node and extract the first result as a paragraph
|
|
480
|
+
const nodes = convertNodes([node], ctx);
|
|
481
|
+
if (nodes[0] instanceof Paragraph) {
|
|
482
|
+
return nodes[0];
|
|
483
|
+
}
|
|
484
|
+
// For non-paragraph content, wrap in a paragraph
|
|
485
|
+
return new Paragraph({ children: nodes });
|
|
486
|
+
}),
|
|
487
|
+
};
|
|
488
|
+
ctx.footnote.def(identifier, definition);
|
|
489
|
+
};
|
|
490
|
+
const buildFootnoteReference = ({ identifier }, ctx) => {
|
|
491
|
+
return new FootnoteReferenceRun(ctx.footnote.ref(identifier));
|
|
492
|
+
};
|
|
493
|
+
|
|
494
|
+
const hasSquareBrackets = (arg) => {
|
|
495
|
+
return !!arg && arg.openMark === "[" && arg.closeMark === "]";
|
|
496
|
+
};
|
|
497
|
+
const hasCurlyBrackets = (arg) => {
|
|
498
|
+
return !!arg && arg.openMark === "{" && arg.closeMark === "}";
|
|
499
|
+
};
|
|
500
|
+
const mapString = (s) => new MathRun(s);
|
|
501
|
+
const mapMacro = (n, runs) => {
|
|
502
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
503
|
+
switch (n.content) {
|
|
504
|
+
case "#":
|
|
505
|
+
return mapString("#");
|
|
506
|
+
case "$":
|
|
507
|
+
return mapString("$");
|
|
508
|
+
case "%":
|
|
509
|
+
return mapString("%");
|
|
510
|
+
case "&":
|
|
511
|
+
return mapString("&");
|
|
512
|
+
case "textasciitilde":
|
|
513
|
+
return mapString("~");
|
|
514
|
+
case "textasciicircum":
|
|
515
|
+
return mapString("^");
|
|
516
|
+
case "textbackslash":
|
|
517
|
+
return mapString("∖");
|
|
518
|
+
case "{":
|
|
519
|
+
return mapString("{");
|
|
520
|
+
case "}":
|
|
521
|
+
return mapString("}");
|
|
522
|
+
case "textbar":
|
|
523
|
+
return mapString("|");
|
|
524
|
+
case "textless":
|
|
525
|
+
return mapString("<");
|
|
526
|
+
case "textgreater":
|
|
527
|
+
return mapString(">");
|
|
528
|
+
case "neq":
|
|
529
|
+
return mapString("≠");
|
|
530
|
+
case "sim":
|
|
531
|
+
return mapString("∼");
|
|
532
|
+
case "simeq":
|
|
533
|
+
return mapString("≃");
|
|
534
|
+
case "approx":
|
|
535
|
+
return mapString("≈");
|
|
536
|
+
case "fallingdotseq":
|
|
537
|
+
return mapString("≒");
|
|
538
|
+
case "risingdotseq":
|
|
539
|
+
return mapString("≓");
|
|
540
|
+
case "equiv":
|
|
541
|
+
return mapString("≡");
|
|
542
|
+
case "geq":
|
|
543
|
+
return mapString("≥");
|
|
544
|
+
case "geqq":
|
|
545
|
+
return mapString("≧");
|
|
546
|
+
case "leq":
|
|
547
|
+
return mapString("≤");
|
|
548
|
+
case "leqq":
|
|
549
|
+
return mapString("≦");
|
|
550
|
+
case "gg":
|
|
551
|
+
return mapString("≫");
|
|
552
|
+
case "ll":
|
|
553
|
+
return mapString("≪");
|
|
554
|
+
case "times":
|
|
555
|
+
return mapString("×");
|
|
556
|
+
case "div":
|
|
557
|
+
return mapString("÷");
|
|
558
|
+
case "pm":
|
|
559
|
+
return mapString("±");
|
|
560
|
+
case "mp":
|
|
561
|
+
return mapString("∓");
|
|
562
|
+
case "oplus":
|
|
563
|
+
return mapString("⊕");
|
|
564
|
+
case "ominus":
|
|
565
|
+
return mapString("⊖");
|
|
566
|
+
case "otimes":
|
|
567
|
+
return mapString("⊗");
|
|
568
|
+
case "oslash":
|
|
569
|
+
return mapString("⊘");
|
|
570
|
+
case "circ":
|
|
571
|
+
return mapString("∘");
|
|
572
|
+
case "cdot":
|
|
573
|
+
return mapString("⋅");
|
|
574
|
+
case "bullet":
|
|
575
|
+
return mapString("∙");
|
|
576
|
+
case "ltimes":
|
|
577
|
+
return mapString("⋉");
|
|
578
|
+
case "rtimes":
|
|
579
|
+
return mapString("⋊");
|
|
580
|
+
case "in":
|
|
581
|
+
return mapString("∈");
|
|
582
|
+
case "ni":
|
|
583
|
+
return mapString("∋");
|
|
584
|
+
case "notin":
|
|
585
|
+
return mapString("∉");
|
|
586
|
+
case "subset":
|
|
587
|
+
return mapString("⊂");
|
|
588
|
+
case "supset":
|
|
589
|
+
return mapString("⊃");
|
|
590
|
+
case "subseteq":
|
|
591
|
+
return mapString("⊆");
|
|
592
|
+
case "supseteq":
|
|
593
|
+
return mapString("⊇");
|
|
594
|
+
case "nsubseteq":
|
|
595
|
+
return mapString("⊈");
|
|
596
|
+
case "nsupseteq":
|
|
597
|
+
return mapString("⊉");
|
|
598
|
+
case "subsetneq":
|
|
599
|
+
return mapString("⊊");
|
|
600
|
+
case "supsetneq":
|
|
601
|
+
return mapString("⊋");
|
|
602
|
+
case "cap":
|
|
603
|
+
return mapString("∩");
|
|
604
|
+
case "cup":
|
|
605
|
+
return mapString("∪");
|
|
606
|
+
case "emptyset":
|
|
607
|
+
return mapString("∅");
|
|
608
|
+
case "infty":
|
|
609
|
+
return mapString("∞");
|
|
610
|
+
case "partial":
|
|
611
|
+
return mapString("∂");
|
|
612
|
+
case "aleph":
|
|
613
|
+
return mapString("ℵ");
|
|
614
|
+
case "hbar":
|
|
615
|
+
return mapString("ℏ");
|
|
616
|
+
case "wp":
|
|
617
|
+
return mapString("℘");
|
|
618
|
+
case "Re":
|
|
619
|
+
return mapString("ℜ");
|
|
620
|
+
case "Im":
|
|
621
|
+
return mapString("ℑ");
|
|
622
|
+
case "alpha":
|
|
623
|
+
return mapString("α");
|
|
624
|
+
case "beta":
|
|
625
|
+
return mapString("β");
|
|
626
|
+
case "gamma":
|
|
627
|
+
return mapString("γ");
|
|
628
|
+
case "delta":
|
|
629
|
+
return mapString("δ");
|
|
630
|
+
case "epsilon":
|
|
631
|
+
return mapString("ϵ");
|
|
632
|
+
case "zeta":
|
|
633
|
+
return mapString("ζ");
|
|
634
|
+
case "eta":
|
|
635
|
+
return mapString("η");
|
|
636
|
+
case "theta":
|
|
637
|
+
return mapString("θ");
|
|
638
|
+
case "iota":
|
|
639
|
+
return mapString("ι");
|
|
640
|
+
case "kappa":
|
|
641
|
+
return mapString("κ");
|
|
642
|
+
case "lambda":
|
|
643
|
+
return mapString("λ");
|
|
644
|
+
case "eta":
|
|
645
|
+
return mapString("η");
|
|
646
|
+
case "mu":
|
|
647
|
+
return mapString("μ");
|
|
648
|
+
case "nu":
|
|
649
|
+
return mapString("ν");
|
|
650
|
+
case "xi":
|
|
651
|
+
return mapString("ξ");
|
|
652
|
+
case "pi":
|
|
653
|
+
return mapString("π");
|
|
654
|
+
case "rho":
|
|
655
|
+
return mapString("ρ");
|
|
656
|
+
case "sigma":
|
|
657
|
+
return mapString("σ");
|
|
658
|
+
case "tau":
|
|
659
|
+
return mapString("τ");
|
|
660
|
+
case "upsilon":
|
|
661
|
+
return mapString("υ");
|
|
662
|
+
case "phi":
|
|
663
|
+
return mapString("ϕ");
|
|
664
|
+
case "chi":
|
|
665
|
+
return mapString("χ");
|
|
666
|
+
case "psi":
|
|
667
|
+
return mapString("ψ");
|
|
668
|
+
case "omega":
|
|
669
|
+
return mapString("ω");
|
|
670
|
+
case "varepsilon":
|
|
671
|
+
return mapString("ε");
|
|
672
|
+
case "vartheta":
|
|
673
|
+
return mapString("ϑ");
|
|
674
|
+
case "varrho":
|
|
675
|
+
return mapString("ϱ");
|
|
676
|
+
case "varsigma":
|
|
677
|
+
return mapString("ς");
|
|
678
|
+
case "varphi":
|
|
679
|
+
return mapString("φ");
|
|
680
|
+
case "Gamma":
|
|
681
|
+
return mapString("Γ");
|
|
682
|
+
case "Delta":
|
|
683
|
+
return mapString("Δ");
|
|
684
|
+
case "Theta":
|
|
685
|
+
return mapString("Θ");
|
|
686
|
+
case "Lambda":
|
|
687
|
+
return mapString("Λ");
|
|
688
|
+
case "Xi":
|
|
689
|
+
return mapString("Ξ");
|
|
690
|
+
case "Pi":
|
|
691
|
+
return mapString("Π");
|
|
692
|
+
case "Sigma":
|
|
693
|
+
return mapString("Σ");
|
|
694
|
+
case "Upsilon":
|
|
695
|
+
return mapString("Υ");
|
|
696
|
+
case "Phi":
|
|
697
|
+
return mapString("Φ");
|
|
698
|
+
case "Psi":
|
|
699
|
+
return mapString("Ψ");
|
|
700
|
+
case "Omega":
|
|
701
|
+
return mapString("Ω");
|
|
702
|
+
case "newline":
|
|
703
|
+
case "\\":
|
|
704
|
+
// line break
|
|
705
|
+
return false;
|
|
706
|
+
case "^": {
|
|
707
|
+
const prev = runs.pop();
|
|
708
|
+
if (!prev)
|
|
709
|
+
break;
|
|
710
|
+
return new MathSuperScript({
|
|
711
|
+
children: [prev],
|
|
712
|
+
superScript: mapGroup((_c = (_b = (_a = n.args) === null || _a === void 0 ? void 0 : _a[0]) === null || _b === void 0 ? void 0 : _b.content) !== null && _c !== void 0 ? _c : []),
|
|
713
|
+
});
|
|
714
|
+
}
|
|
715
|
+
case "_": {
|
|
716
|
+
const prev = runs.pop();
|
|
717
|
+
if (!prev)
|
|
718
|
+
break;
|
|
719
|
+
return new MathSubScript({
|
|
720
|
+
children: [prev],
|
|
721
|
+
subScript: mapGroup((_f = (_e = (_d = n.args) === null || _d === void 0 ? void 0 : _d[0]) === null || _e === void 0 ? void 0 : _e.content) !== null && _f !== void 0 ? _f : []),
|
|
722
|
+
});
|
|
723
|
+
}
|
|
724
|
+
case "hat":
|
|
725
|
+
// TODO: implement
|
|
726
|
+
break;
|
|
727
|
+
case "widehat":
|
|
728
|
+
// TODO: implement
|
|
729
|
+
break;
|
|
730
|
+
case "sum": {
|
|
731
|
+
// TODO: support superscript and subscript
|
|
732
|
+
return new MathSum({
|
|
733
|
+
children: [],
|
|
734
|
+
});
|
|
735
|
+
}
|
|
736
|
+
case "int":
|
|
737
|
+
return mapString("∫");
|
|
738
|
+
case "frac":
|
|
739
|
+
case "tfrac":
|
|
740
|
+
case "dfrac": {
|
|
741
|
+
const args = (_g = n.args) !== null && _g !== void 0 ? _g : [];
|
|
742
|
+
if (args.length === 2 &&
|
|
743
|
+
hasCurlyBrackets(args[0]) &&
|
|
744
|
+
hasCurlyBrackets(args[1])) {
|
|
745
|
+
return new MathFraction({
|
|
746
|
+
numerator: mapGroup(args[0].content),
|
|
747
|
+
denominator: mapGroup(args[1].content),
|
|
748
|
+
});
|
|
749
|
+
}
|
|
750
|
+
break;
|
|
751
|
+
}
|
|
752
|
+
case "sqrt": {
|
|
753
|
+
const args = (_h = n.args) !== null && _h !== void 0 ? _h : [];
|
|
754
|
+
if (args.length === 1 && hasCurlyBrackets(args[0])) {
|
|
755
|
+
return new MathRadical({
|
|
756
|
+
children: mapGroup(args[0].content),
|
|
757
|
+
});
|
|
593
758
|
}
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
default:
|
|
604
|
-
unreachable();
|
|
605
|
-
break;
|
|
759
|
+
if (args.length === 2 &&
|
|
760
|
+
hasSquareBrackets(args[0]) &&
|
|
761
|
+
hasCurlyBrackets(args[1])) {
|
|
762
|
+
return new MathRadical({
|
|
763
|
+
children: mapGroup(args[1].content),
|
|
764
|
+
degree: mapGroup(args[0].content),
|
|
765
|
+
});
|
|
766
|
+
}
|
|
767
|
+
break;
|
|
606
768
|
}
|
|
607
769
|
}
|
|
608
|
-
return
|
|
770
|
+
return mapString(n.content);
|
|
609
771
|
};
|
|
610
|
-
const
|
|
611
|
-
const
|
|
612
|
-
const
|
|
613
|
-
|
|
614
|
-
nodes.unshift(new docx.CheckBox({
|
|
615
|
-
checked: list.checked,
|
|
616
|
-
checkedState: { value: "2611" },
|
|
617
|
-
uncheckedState: { value: "2610" },
|
|
618
|
-
}));
|
|
772
|
+
const mapGroup = (nodes) => {
|
|
773
|
+
const group = [];
|
|
774
|
+
for (const c of nodes) {
|
|
775
|
+
group.push(...(mapNode(c, group) || []));
|
|
619
776
|
}
|
|
620
|
-
return
|
|
621
|
-
children: nodes,
|
|
622
|
-
indent: ctx.indent > 0
|
|
623
|
-
? {
|
|
624
|
-
start: docx.convertInchesToTwip(INDENT * ctx.indent),
|
|
625
|
-
}
|
|
626
|
-
: undefined,
|
|
627
|
-
...(list &&
|
|
628
|
-
(list.ordered
|
|
629
|
-
? {
|
|
630
|
-
numbering: {
|
|
631
|
-
reference: ORDERED_LIST_REF,
|
|
632
|
-
level: list.level,
|
|
633
|
-
},
|
|
634
|
-
}
|
|
635
|
-
: {
|
|
636
|
-
bullet: {
|
|
637
|
-
level: list.level,
|
|
638
|
-
},
|
|
639
|
-
})),
|
|
640
|
-
});
|
|
777
|
+
return group;
|
|
641
778
|
};
|
|
642
|
-
const
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
case 1:
|
|
646
|
-
headingLevel = docx.HeadingLevel.TITLE;
|
|
779
|
+
const mapNode = (n, runs) => {
|
|
780
|
+
switch (n.type) {
|
|
781
|
+
case "root":
|
|
647
782
|
break;
|
|
648
|
-
case
|
|
649
|
-
|
|
783
|
+
case "string":
|
|
784
|
+
return [mapString(n.content)];
|
|
785
|
+
case "whitespace":
|
|
650
786
|
break;
|
|
651
|
-
case
|
|
652
|
-
headingLevel = docx.HeadingLevel.HEADING_2;
|
|
787
|
+
case "parbreak":
|
|
653
788
|
break;
|
|
654
|
-
case
|
|
655
|
-
headingLevel = docx.HeadingLevel.HEADING_3;
|
|
789
|
+
case "comment":
|
|
656
790
|
break;
|
|
657
|
-
case
|
|
658
|
-
|
|
791
|
+
case "macro":
|
|
792
|
+
const run = mapMacro(n, runs);
|
|
793
|
+
if (!run) {
|
|
794
|
+
// line break
|
|
795
|
+
return false;
|
|
796
|
+
}
|
|
797
|
+
else {
|
|
798
|
+
return [run];
|
|
799
|
+
}
|
|
800
|
+
case "environment":
|
|
801
|
+
case "mathenv":
|
|
659
802
|
break;
|
|
660
|
-
case
|
|
661
|
-
|
|
803
|
+
case "verbatim":
|
|
804
|
+
break;
|
|
805
|
+
case "inlinemath":
|
|
806
|
+
break;
|
|
807
|
+
case "displaymath":
|
|
662
808
|
break;
|
|
809
|
+
case "group":
|
|
810
|
+
return mapGroup(n.content);
|
|
811
|
+
case "verb":
|
|
812
|
+
break;
|
|
813
|
+
default:
|
|
814
|
+
unreachable();
|
|
663
815
|
}
|
|
664
|
-
|
|
665
|
-
return new docx.Paragraph({
|
|
666
|
-
heading: headingLevel,
|
|
667
|
-
children: nodes,
|
|
668
|
-
});
|
|
669
|
-
};
|
|
670
|
-
const buildThematicBreak = (_) => {
|
|
671
|
-
return new docx.Paragraph({
|
|
672
|
-
thematicBreak: true,
|
|
673
|
-
});
|
|
674
|
-
};
|
|
675
|
-
const buildBlockquote = ({ children }, ctx) => {
|
|
676
|
-
return convertNodes(children, {
|
|
677
|
-
...ctx,
|
|
678
|
-
indent: ctx.indent + 1,
|
|
679
|
-
});
|
|
680
|
-
};
|
|
681
|
-
const buildList = ({ children, ordered, start: _start, spread: _spread }, ctx) => {
|
|
682
|
-
const list = {
|
|
683
|
-
level: ctx.list ? ctx.list.level + 1 : 0,
|
|
684
|
-
ordered: !!ordered,
|
|
685
|
-
};
|
|
686
|
-
return children.flatMap((item) => {
|
|
687
|
-
return buildListItem(item, {
|
|
688
|
-
...ctx,
|
|
689
|
-
list,
|
|
690
|
-
});
|
|
691
|
-
});
|
|
692
|
-
};
|
|
693
|
-
const buildListItem = ({ children, checked, spread: _spread }, ctx) => {
|
|
694
|
-
return convertNodes(children, {
|
|
695
|
-
...ctx,
|
|
696
|
-
...(ctx.list && { list: { ...ctx.list, checked: checked !== null && checked !== void 0 ? checked : undefined } }),
|
|
697
|
-
});
|
|
816
|
+
return [];
|
|
698
817
|
};
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
818
|
+
/**
|
|
819
|
+
* @internal
|
|
820
|
+
*/
|
|
821
|
+
const parseLatex = (value) => {
|
|
822
|
+
const parsed = parseMath(value);
|
|
823
|
+
const paragraphs = [[]];
|
|
824
|
+
let runs = paragraphs[0];
|
|
825
|
+
for (const n of parsed) {
|
|
826
|
+
const res = mapNode(n, runs);
|
|
827
|
+
if (!res) {
|
|
828
|
+
// line break
|
|
829
|
+
paragraphs.push((runs = []));
|
|
830
|
+
}
|
|
831
|
+
else {
|
|
832
|
+
runs.push(...res);
|
|
710
833
|
}
|
|
711
|
-
});
|
|
712
|
-
return new docx.Table({
|
|
713
|
-
rows: children.map((r) => {
|
|
714
|
-
return buildTableRow(r, ctx, cellAligns);
|
|
715
|
-
}),
|
|
716
|
-
});
|
|
717
|
-
};
|
|
718
|
-
const buildTableRow = ({ children }, ctx, cellAligns) => {
|
|
719
|
-
return new docx.TableRow({
|
|
720
|
-
children: children.map((c, i) => {
|
|
721
|
-
return buildTableCell(c, ctx, cellAligns === null || cellAligns === void 0 ? void 0 : cellAligns[i]);
|
|
722
|
-
}),
|
|
723
|
-
});
|
|
724
|
-
};
|
|
725
|
-
const buildTableCell = ({ children }, ctx, align) => {
|
|
726
|
-
const nodes = convertNodes(children, ctx);
|
|
727
|
-
return new docx.TableCell({
|
|
728
|
-
children: [
|
|
729
|
-
new docx.Paragraph({
|
|
730
|
-
alignment: align,
|
|
731
|
-
children: nodes,
|
|
732
|
-
}),
|
|
733
|
-
],
|
|
734
|
-
});
|
|
735
|
-
};
|
|
736
|
-
const buildHtml = ({ value }) => {
|
|
737
|
-
// FIXME: transform to text for now
|
|
738
|
-
return new docx.Paragraph({
|
|
739
|
-
children: [buildText(value, {})],
|
|
740
|
-
});
|
|
741
|
-
};
|
|
742
|
-
const buildCode = ({ value, lang: _lang, meta: _meta, }) => {
|
|
743
|
-
// FIXME: transform to text for now
|
|
744
|
-
return new docx.Paragraph({
|
|
745
|
-
children: [buildText(value, {})],
|
|
746
|
-
});
|
|
747
|
-
};
|
|
748
|
-
const buildMath = ({ value }) => {
|
|
749
|
-
return parseLatex(value).map((runs) => new docx.Paragraph({
|
|
750
|
-
children: [
|
|
751
|
-
new docx.Math({
|
|
752
|
-
children: runs,
|
|
753
|
-
}),
|
|
754
|
-
],
|
|
755
|
-
}));
|
|
756
|
-
};
|
|
757
|
-
const buildInlineMath = ({ value }) => {
|
|
758
|
-
return new docx.Math({
|
|
759
|
-
children: parseLatex(value).flatMap((runs) => runs),
|
|
760
|
-
});
|
|
761
|
-
};
|
|
762
|
-
const buildText = (text, deco) => {
|
|
763
|
-
return new docx.TextRun({
|
|
764
|
-
text,
|
|
765
|
-
bold: deco.strong,
|
|
766
|
-
italics: deco.emphasis,
|
|
767
|
-
strike: deco.delete,
|
|
768
|
-
});
|
|
769
|
-
};
|
|
770
|
-
const buildBreak = (_) => {
|
|
771
|
-
return new docx.TextRun({ text: "", break: 1 });
|
|
772
|
-
};
|
|
773
|
-
const buildLink = ({ children, url }, ctx) => {
|
|
774
|
-
const nodes = convertNodes(children, ctx);
|
|
775
|
-
return new docx.ExternalHyperlink({
|
|
776
|
-
link: url,
|
|
777
|
-
children: nodes,
|
|
778
|
-
});
|
|
779
|
-
};
|
|
780
|
-
const buildImage = ({ url }, images) => {
|
|
781
|
-
const img = images[url];
|
|
782
|
-
invariant(img, `Fetch image was failed: ${url}`);
|
|
783
|
-
const { image, width, height } = img;
|
|
784
|
-
return new docx.ImageRun({
|
|
785
|
-
data: image,
|
|
786
|
-
transformation: {
|
|
787
|
-
width,
|
|
788
|
-
height,
|
|
789
|
-
},
|
|
790
|
-
});
|
|
791
|
-
};
|
|
792
|
-
const buildLinkReference = ({ children, identifier }, ctx) => {
|
|
793
|
-
const def = ctx.def[identifier];
|
|
794
|
-
if (def == null) {
|
|
795
|
-
return convertNodes(children, ctx);
|
|
796
|
-
}
|
|
797
|
-
return [buildLink({ children, url: def }, ctx)];
|
|
798
|
-
};
|
|
799
|
-
const buildImageReference = ({ identifier }, ctx) => {
|
|
800
|
-
const def = ctx.def[identifier];
|
|
801
|
-
if (def == null) {
|
|
802
|
-
return;
|
|
803
834
|
}
|
|
804
|
-
return
|
|
805
|
-
};
|
|
806
|
-
const registerFootnoteDefinition = ({ children, identifier }, ctx) => {
|
|
807
|
-
const definition = {
|
|
808
|
-
children: children.map((node) => {
|
|
809
|
-
// Convert each node and extract the first result as a paragraph
|
|
810
|
-
const nodes = convertNodes([node], ctx);
|
|
811
|
-
if (nodes[0] instanceof docx.Paragraph) {
|
|
812
|
-
return nodes[0];
|
|
813
|
-
}
|
|
814
|
-
// For non-paragraph content, wrap in a paragraph
|
|
815
|
-
return new docx.Paragraph({ children: nodes });
|
|
816
|
-
}),
|
|
817
|
-
};
|
|
818
|
-
ctx.footnote.def(identifier, definition);
|
|
819
|
-
};
|
|
820
|
-
const buildFootnoteReference = ({ identifier }, ctx) => {
|
|
821
|
-
return new docx.FootnoteReferenceRun(ctx.footnote.ref(identifier));
|
|
835
|
+
return paragraphs;
|
|
822
836
|
};
|
|
823
837
|
|
|
824
838
|
const plugin = function (opts = {}) {
|
|
825
839
|
let images = {};
|
|
826
840
|
this.Compiler = (node) => {
|
|
827
|
-
return mdastToDocx(node, opts, images);
|
|
841
|
+
return mdastToDocx(node, opts, images, parseLatex);
|
|
828
842
|
};
|
|
829
843
|
return async (node) => {
|
|
830
844
|
const imageList = [];
|
|
831
|
-
|
|
845
|
+
visit(node, "image", (node) => {
|
|
832
846
|
imageList.push(node);
|
|
833
847
|
});
|
|
834
848
|
const defs = new Map();
|
|
835
|
-
|
|
849
|
+
visit(node, "definition", (node) => {
|
|
836
850
|
defs.set(node.identifier, node);
|
|
837
851
|
});
|
|
838
|
-
|
|
852
|
+
visit(node, "imageReference", (node) => {
|
|
839
853
|
const maybeImage = defs.get(node.identifier);
|
|
840
854
|
if (maybeImage) {
|
|
841
855
|
imageList.push(maybeImage);
|
|
@@ -865,5 +879,5 @@ const plugin = function (opts = {}) {
|
|
|
865
879
|
};
|
|
866
880
|
};
|
|
867
881
|
|
|
868
|
-
|
|
882
|
+
export { plugin as default };
|
|
869
883
|
//# sourceMappingURL=index.js.map
|