remark-docx 0.2.1 → 0.3.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.
- package/README.md +46 -23
- package/lib/index.cjs +124 -551
- package/lib/index.cjs.map +1 -1
- package/lib/index.d.ts +1 -0
- package/lib/index.js +125 -552
- package/lib/index.js.map +1 -1
- package/lib/mdast-to-docx.d.ts +6 -19
- package/lib/mdast.d.ts +2 -0
- package/lib/plugin.d.ts +8 -2
- package/lib/plugins/image/index.cjs +96 -0
- package/lib/plugins/image/index.cjs.map +1 -0
- package/lib/plugins/image/index.d.ts +13 -0
- package/lib/plugins/image/index.js +94 -0
- package/lib/plugins/image/index.js.map +1 -0
- package/lib/plugins/math/index.cjs +376 -0
- package/lib/plugins/math/index.cjs.map +1 -0
- package/lib/plugins/math/index.d.ts +5 -0
- package/lib/plugins/math/index.js +374 -0
- package/lib/plugins/math/index.js.map +1 -0
- package/lib/types.d.ts +17 -0
- package/lib/utils-40yKzkXT.js +19 -0
- package/lib/utils-40yKzkXT.js.map +1 -0
- package/lib/utils-EYEfXxbh.js +22 -0
- package/lib/utils-EYEfXxbh.js.map +1 -0
- package/package.json +18 -10
- package/lib/models/mdast.d.ts +0 -21
- /package/lib/{latex.d.ts → plugins/math/parser.d.ts} +0 -0
package/lib/index.js
CHANGED
|
@@ -1,86 +1,25 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import { parseMath } from '@unified-latex/unified-latex-util-parse';
|
|
1
|
+
import { Document, Packer, AlignmentType, LevelFormat, convertInchesToTwip, FootnoteReferenceRun, ExternalHyperlink, TextRun, Paragraph, Table, TableRow, TableCell, HeadingLevel, CheckBox } from 'docx';
|
|
2
|
+
import { definitions } from 'mdast-util-definitions';
|
|
4
3
|
|
|
5
4
|
/**
|
|
6
5
|
* @internal
|
|
7
6
|
*/
|
|
8
|
-
|
|
9
|
-
throw new Error(
|
|
10
|
-
}
|
|
7
|
+
function invariant(cond, message) {
|
|
8
|
+
throw new Error(message);
|
|
9
|
+
}
|
|
10
|
+
const alreadyWarned = {};
|
|
11
11
|
/**
|
|
12
12
|
* @internal
|
|
13
13
|
*/
|
|
14
|
-
function
|
|
15
|
-
if (!cond)
|
|
16
|
-
|
|
14
|
+
function warnOnce(message, cond = false) {
|
|
15
|
+
if (!cond && !alreadyWarned[message]) {
|
|
16
|
+
alreadyWarned[message] = true;
|
|
17
|
+
console.warn(message);
|
|
18
|
+
}
|
|
17
19
|
}
|
|
18
20
|
|
|
19
21
|
const ORDERED_LIST_REF = "ordered";
|
|
20
22
|
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
23
|
const createFootnoteRegistry = () => {
|
|
85
24
|
const idToInternalId = new Map();
|
|
86
25
|
const defs = new Map();
|
|
@@ -109,11 +48,74 @@ const createFootnoteRegistry = () => {
|
|
|
109
48
|
};
|
|
110
49
|
const createNumberingRegistry = () => {
|
|
111
50
|
let counter = 1;
|
|
51
|
+
const DEFAULT_NUMBERINGS = [
|
|
52
|
+
{
|
|
53
|
+
level: 0,
|
|
54
|
+
format: LevelFormat.DECIMAL,
|
|
55
|
+
text: "%1.",
|
|
56
|
+
alignment: AlignmentType.START,
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
level: 1,
|
|
60
|
+
format: LevelFormat.DECIMAL,
|
|
61
|
+
text: "%2.",
|
|
62
|
+
alignment: AlignmentType.START,
|
|
63
|
+
style: {
|
|
64
|
+
paragraph: {
|
|
65
|
+
indent: { start: convertInchesToTwip(INDENT * 1) },
|
|
66
|
+
},
|
|
67
|
+
},
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
level: 2,
|
|
71
|
+
format: LevelFormat.DECIMAL,
|
|
72
|
+
text: "%3.",
|
|
73
|
+
alignment: AlignmentType.START,
|
|
74
|
+
style: {
|
|
75
|
+
paragraph: {
|
|
76
|
+
indent: { start: convertInchesToTwip(INDENT * 2) },
|
|
77
|
+
},
|
|
78
|
+
},
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
level: 3,
|
|
82
|
+
format: LevelFormat.DECIMAL,
|
|
83
|
+
text: "%4.",
|
|
84
|
+
alignment: AlignmentType.START,
|
|
85
|
+
style: {
|
|
86
|
+
paragraph: {
|
|
87
|
+
indent: { start: convertInchesToTwip(INDENT * 3) },
|
|
88
|
+
},
|
|
89
|
+
},
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
level: 4,
|
|
93
|
+
format: LevelFormat.DECIMAL,
|
|
94
|
+
text: "%5.",
|
|
95
|
+
alignment: AlignmentType.START,
|
|
96
|
+
style: {
|
|
97
|
+
paragraph: {
|
|
98
|
+
indent: { start: convertInchesToTwip(INDENT * 4) },
|
|
99
|
+
},
|
|
100
|
+
},
|
|
101
|
+
},
|
|
102
|
+
{
|
|
103
|
+
level: 5,
|
|
104
|
+
format: LevelFormat.DECIMAL,
|
|
105
|
+
text: "%6.",
|
|
106
|
+
alignment: AlignmentType.START,
|
|
107
|
+
style: {
|
|
108
|
+
paragraph: {
|
|
109
|
+
indent: { start: convertInchesToTwip(INDENT * 5) },
|
|
110
|
+
},
|
|
111
|
+
},
|
|
112
|
+
},
|
|
113
|
+
];
|
|
112
114
|
return {
|
|
113
115
|
create: () => {
|
|
114
116
|
return `${ORDERED_LIST_REF}-${counter++}`;
|
|
115
117
|
},
|
|
116
|
-
|
|
118
|
+
numberings: () => {
|
|
117
119
|
return Array.from({ length: counter }, (_, i) => ({
|
|
118
120
|
reference: `${ORDERED_LIST_REF}-${i}`,
|
|
119
121
|
levels: DEFAULT_NUMBERINGS,
|
|
@@ -121,21 +123,18 @@ const createNumberingRegistry = () => {
|
|
|
121
123
|
},
|
|
122
124
|
};
|
|
123
125
|
};
|
|
124
|
-
const mdastToDocx = async (node, {
|
|
125
|
-
const definition =
|
|
126
|
-
visit(node, "definition", (node) => {
|
|
127
|
-
definition[node.identifier] = node.url;
|
|
128
|
-
});
|
|
126
|
+
const mdastToDocx = async (node, { plugins = [], title, subject, creator, keywords, description, lastModifiedBy, revision, styles, background, }) => {
|
|
127
|
+
const definition = definitions(node);
|
|
129
128
|
const footnote = createFootnoteRegistry();
|
|
130
129
|
const numbering = createNumberingRegistry();
|
|
130
|
+
const pluginCtx = { root: node, definition };
|
|
131
131
|
const nodes = convertNodes(node.children, {
|
|
132
|
+
overrides: (await Promise.all(plugins.map((p) => p(pluginCtx)))).reduceRight((acc, p) => ({ acc, ...p }), {}),
|
|
132
133
|
deco: {},
|
|
133
|
-
images,
|
|
134
134
|
indent: 0,
|
|
135
|
-
|
|
135
|
+
definition: definition,
|
|
136
136
|
footnote,
|
|
137
137
|
numbering,
|
|
138
|
-
latex,
|
|
139
138
|
});
|
|
140
139
|
const doc = new Document({
|
|
141
140
|
title,
|
|
@@ -150,21 +149,25 @@ const mdastToDocx = async (node, { output = "buffer", title, subject, creator, k
|
|
|
150
149
|
footnotes: footnote.footnotes(),
|
|
151
150
|
sections: [{ children: nodes }],
|
|
152
151
|
numbering: {
|
|
153
|
-
config: numbering.
|
|
152
|
+
config: numbering.numberings(),
|
|
154
153
|
},
|
|
155
154
|
});
|
|
156
|
-
|
|
157
|
-
case "buffer":
|
|
158
|
-
return Packer.toBuffer(doc);
|
|
159
|
-
case "arrayBuffer":
|
|
160
|
-
return Packer.toArrayBuffer(doc);
|
|
161
|
-
case "blob":
|
|
162
|
-
return Packer.toBlob(doc);
|
|
163
|
-
}
|
|
155
|
+
return Packer.toArrayBuffer(doc);
|
|
164
156
|
};
|
|
165
157
|
const convertNodes = (nodes, ctx) => {
|
|
158
|
+
var _a, _b;
|
|
166
159
|
const results = [];
|
|
167
160
|
for (const node of nodes) {
|
|
161
|
+
const customNodes = (_b = (_a = ctx.overrides)[node.type]) === null || _b === void 0 ? void 0 : _b.call(_a, node, (children) => convertNodes(children, ctx));
|
|
162
|
+
if (customNodes != null) {
|
|
163
|
+
if (Array.isArray(customNodes)) {
|
|
164
|
+
results.push(...customNodes);
|
|
165
|
+
}
|
|
166
|
+
else {
|
|
167
|
+
results.push(customNodes);
|
|
168
|
+
}
|
|
169
|
+
continue;
|
|
170
|
+
}
|
|
168
171
|
switch (node.type) {
|
|
169
172
|
case "paragraph": {
|
|
170
173
|
results.push(buildParagraph(node, ctx));
|
|
@@ -200,12 +203,12 @@ const convertNodes = (nodes, ctx) => {
|
|
|
200
203
|
case "code":
|
|
201
204
|
results.push(buildCode(node));
|
|
202
205
|
break;
|
|
203
|
-
case "yaml":
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
case "toml":
|
|
207
|
-
|
|
208
|
-
|
|
206
|
+
// case "yaml":
|
|
207
|
+
// // unimplemented
|
|
208
|
+
// break;
|
|
209
|
+
// case "toml":
|
|
210
|
+
// // unimplemented
|
|
211
|
+
// break;
|
|
209
212
|
case "definition":
|
|
210
213
|
// noop
|
|
211
214
|
break;
|
|
@@ -238,34 +241,27 @@ const convertNodes = (nodes, ctx) => {
|
|
|
238
241
|
results.push(buildLink(node, ctx));
|
|
239
242
|
break;
|
|
240
243
|
}
|
|
241
|
-
case "image":
|
|
242
|
-
results.push(buildImage(node, ctx.images));
|
|
243
|
-
break;
|
|
244
244
|
case "linkReference":
|
|
245
245
|
results.push(...buildLinkReference(node, ctx));
|
|
246
246
|
break;
|
|
247
|
+
case "image":
|
|
247
248
|
case "imageReference": {
|
|
248
|
-
|
|
249
|
-
if (image) {
|
|
250
|
-
results.push(image);
|
|
251
|
-
}
|
|
252
|
-
break;
|
|
253
|
-
}
|
|
254
|
-
case "footnote": {
|
|
255
|
-
// inline footnote was removed in mdast v5
|
|
249
|
+
warnOnce(`${node.type} node is not rendered since remark-docx/plugins/image is not provided.`);
|
|
256
250
|
break;
|
|
257
251
|
}
|
|
252
|
+
// case "footnote": {
|
|
253
|
+
// // inline footnote was removed in mdast v5
|
|
254
|
+
// break;
|
|
255
|
+
// }
|
|
258
256
|
case "footnoteReference":
|
|
259
257
|
results.push(buildFootnoteReference(node, ctx));
|
|
260
258
|
break;
|
|
261
259
|
case "math":
|
|
262
|
-
results.push(...buildMath(node, ctx));
|
|
263
|
-
break;
|
|
264
260
|
case "inlineMath":
|
|
265
|
-
|
|
261
|
+
warnOnce(`${node.type} node is not rendered since remark-docx/plugins/math is not provided.`);
|
|
266
262
|
break;
|
|
267
263
|
default:
|
|
268
|
-
|
|
264
|
+
warnOnce(`${node.type} node is not officially supported.`);
|
|
269
265
|
break;
|
|
270
266
|
}
|
|
271
267
|
}
|
|
@@ -342,7 +338,7 @@ const buildBlockquote = ({ children }, ctx) => {
|
|
|
342
338
|
indent: ctx.indent + 1,
|
|
343
339
|
});
|
|
344
340
|
};
|
|
345
|
-
const buildList = ({ children, ordered
|
|
341
|
+
const buildList = ({ children, ordered }, ctx) => {
|
|
346
342
|
var _a;
|
|
347
343
|
const isTopLevel = !ctx.list;
|
|
348
344
|
const list = {
|
|
@@ -359,7 +355,7 @@ const buildList = ({ children, ordered, start: _start, spread: _spread }, ctx) =
|
|
|
359
355
|
});
|
|
360
356
|
});
|
|
361
357
|
};
|
|
362
|
-
const buildListItem = ({ children, checked
|
|
358
|
+
const buildListItem = ({ children, checked }, ctx) => {
|
|
363
359
|
return convertNodes(children, {
|
|
364
360
|
...ctx,
|
|
365
361
|
...(ctx.list && { list: { ...ctx.list, checked: checked !== null && checked !== void 0 ? checked : undefined } }),
|
|
@@ -380,28 +376,21 @@ const buildTable = ({ children, align }, ctx) => {
|
|
|
380
376
|
});
|
|
381
377
|
return new Table({
|
|
382
378
|
rows: children.map((r) => {
|
|
383
|
-
return
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
379
|
+
return new TableRow({
|
|
380
|
+
children: r.children.map((c, i) => {
|
|
381
|
+
return new TableCell({
|
|
382
|
+
children: [
|
|
383
|
+
new Paragraph({
|
|
384
|
+
alignment: cellAligns === null || cellAligns === void 0 ? void 0 : cellAligns[i],
|
|
385
|
+
children: convertNodes(c.children, ctx),
|
|
386
|
+
}),
|
|
387
|
+
],
|
|
388
|
+
});
|
|
389
|
+
}),
|
|
390
|
+
});
|
|
391
391
|
}),
|
|
392
392
|
});
|
|
393
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
394
|
const buildHtml = ({ value }) => {
|
|
406
395
|
// FIXME: transform to text for now
|
|
407
396
|
return new Paragraph({
|
|
@@ -414,20 +403,6 @@ const buildCode = ({ value, lang: _lang, meta: _meta, }) => {
|
|
|
414
403
|
children: [buildText(value, {})],
|
|
415
404
|
});
|
|
416
405
|
};
|
|
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
406
|
const buildText = (text, deco) => {
|
|
432
407
|
return new TextRun({
|
|
433
408
|
text,
|
|
@@ -446,32 +421,12 @@ const buildLink = ({ children, url }, ctx) => {
|
|
|
446
421
|
children: nodes,
|
|
447
422
|
});
|
|
448
423
|
};
|
|
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
424
|
const buildLinkReference = ({ children, identifier }, ctx) => {
|
|
463
|
-
const def = ctx.
|
|
425
|
+
const def = ctx.definition(identifier);
|
|
464
426
|
if (def == null) {
|
|
465
427
|
return convertNodes(children, ctx);
|
|
466
428
|
}
|
|
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);
|
|
429
|
+
return [buildLink({ children, url: def.url }, ctx)];
|
|
475
430
|
};
|
|
476
431
|
const registerFootnoteDefinition = ({ children, identifier }, ctx) => {
|
|
477
432
|
const definition = {
|
|
@@ -491,391 +446,9 @@ const buildFootnoteReference = ({ identifier }, ctx) => {
|
|
|
491
446
|
return new FootnoteReferenceRun(ctx.footnote.ref(identifier));
|
|
492
447
|
};
|
|
493
448
|
|
|
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
|
-
});
|
|
758
|
-
}
|
|
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;
|
|
768
|
-
}
|
|
769
|
-
}
|
|
770
|
-
return mapString(n.content);
|
|
771
|
-
};
|
|
772
|
-
const mapGroup = (nodes) => {
|
|
773
|
-
const group = [];
|
|
774
|
-
for (const c of nodes) {
|
|
775
|
-
group.push(...(mapNode(c, group) || []));
|
|
776
|
-
}
|
|
777
|
-
return group;
|
|
778
|
-
};
|
|
779
|
-
const mapNode = (n, runs) => {
|
|
780
|
-
switch (n.type) {
|
|
781
|
-
case "root":
|
|
782
|
-
break;
|
|
783
|
-
case "string":
|
|
784
|
-
return [mapString(n.content)];
|
|
785
|
-
case "whitespace":
|
|
786
|
-
break;
|
|
787
|
-
case "parbreak":
|
|
788
|
-
break;
|
|
789
|
-
case "comment":
|
|
790
|
-
break;
|
|
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":
|
|
802
|
-
break;
|
|
803
|
-
case "verbatim":
|
|
804
|
-
break;
|
|
805
|
-
case "inlinemath":
|
|
806
|
-
break;
|
|
807
|
-
case "displaymath":
|
|
808
|
-
break;
|
|
809
|
-
case "group":
|
|
810
|
-
return mapGroup(n.content);
|
|
811
|
-
case "verb":
|
|
812
|
-
break;
|
|
813
|
-
default:
|
|
814
|
-
unreachable();
|
|
815
|
-
}
|
|
816
|
-
return [];
|
|
817
|
-
};
|
|
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);
|
|
833
|
-
}
|
|
834
|
-
}
|
|
835
|
-
return paragraphs;
|
|
836
|
-
};
|
|
837
|
-
|
|
838
449
|
const plugin = function (opts = {}) {
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
return mdastToDocx(node, opts, images, parseLatex);
|
|
842
|
-
};
|
|
843
|
-
return async (node) => {
|
|
844
|
-
const imageList = [];
|
|
845
|
-
visit(node, "image", (node) => {
|
|
846
|
-
imageList.push(node);
|
|
847
|
-
});
|
|
848
|
-
const defs = new Map();
|
|
849
|
-
visit(node, "definition", (node) => {
|
|
850
|
-
defs.set(node.identifier, node);
|
|
851
|
-
});
|
|
852
|
-
visit(node, "imageReference", (node) => {
|
|
853
|
-
const maybeImage = defs.get(node.identifier);
|
|
854
|
-
if (maybeImage) {
|
|
855
|
-
imageList.push(maybeImage);
|
|
856
|
-
}
|
|
857
|
-
});
|
|
858
|
-
if (imageList.length === 0) {
|
|
859
|
-
return node;
|
|
860
|
-
}
|
|
861
|
-
const imageResolver = opts.imageResolver;
|
|
862
|
-
invariant(imageResolver, "options.imageResolver is not defined.");
|
|
863
|
-
const resolved = new Set();
|
|
864
|
-
const promises = [];
|
|
865
|
-
imageList.forEach(({ url }) => {
|
|
866
|
-
if (!resolved.has(url)) {
|
|
867
|
-
resolved.add(url);
|
|
868
|
-
promises.push((async () => {
|
|
869
|
-
const img = await imageResolver(url);
|
|
870
|
-
return { img, url };
|
|
871
|
-
})());
|
|
872
|
-
}
|
|
873
|
-
});
|
|
874
|
-
images = (await Promise.all(promises)).reduce((acc, { img, url }) => {
|
|
875
|
-
acc[url] = img;
|
|
876
|
-
return acc;
|
|
877
|
-
}, {});
|
|
878
|
-
return node;
|
|
450
|
+
this.compiler = (node) => {
|
|
451
|
+
return mdastToDocx(node, opts);
|
|
879
452
|
};
|
|
880
453
|
};
|
|
881
454
|
|