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/lib/index.js CHANGED
@@ -1,86 +1,25 @@
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';
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
- const unreachable = (_) => {
9
- throw new Error("unreachable");
10
- };
7
+ function invariant(cond, message) {
8
+ throw new Error(message);
9
+ }
10
+ const alreadyWarned = {};
11
11
  /**
12
12
  * @internal
13
13
  */
14
- function invariant(cond, message) {
15
- if (!cond)
16
- throw new Error(message);
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
- getAll: () => {
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, { output = "buffer", title, subject, creator, keywords, description, lastModifiedBy, revision, styles, background, }, images, latex) => {
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
- def: definition,
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.getAll(),
152
+ config: numbering.numberings(),
154
153
  },
155
154
  });
156
- switch (output) {
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
- // FIXME: unimplemented
205
- break;
206
- case "toml":
207
- // FIXME: unimplemented
208
- break;
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
- const image = buildImageReference(node, ctx);
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
- results.push(buildInlineMath(node, ctx));
261
+ warnOnce(`${node.type} node is not rendered since remark-docx/plugins/math is not provided.`);
266
262
  break;
267
263
  default:
268
- unreachable();
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, start: _start, spread: _spread }, ctx) => {
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, spread: _spread }, ctx) => {
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 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]);
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.def[identifier];
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
- let images = {};
840
- this.Compiler = (node) => {
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