remark-docx 0.1.2 → 0.1.3

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 CHANGED
@@ -24,7 +24,7 @@ If you have some feature requests or improvements, please create a [issue](https
24
24
  - [ ] yaml
25
25
  - [ ] toml
26
26
  - [ ] definition
27
- - [ ] footnoteDefinition
27
+ - [x] footnoteDefinition
28
28
  - [x] text
29
29
  - [x] emphasis
30
30
  - [x] strong
@@ -35,8 +35,8 @@ If you have some feature requests or improvements, please create a [issue](https
35
35
  - [x] image
36
36
  - [ ] linkReference
37
37
  - [ ] imageReference
38
- - [ ] footnote
39
- - [ ] footnoteReference
38
+ - [x] footnote
39
+ - [x] footnoteReference
40
40
  - [x] LaTeX support with math and inlineMath ([remark-math](https://github.com/remarkjs/remark-math) is required)
41
41
 
42
42
  ## Demo
@@ -89,21 +89,21 @@ const text = "# hello world";
89
89
  })();
90
90
  ```
91
91
 
92
- ## Options
93
-
94
- | Key | Default | Type | Description |
95
- | -------------- | --------- | --------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
96
- | output | "buffer" | `"buffer"` `"blob"` | Set output type of `VFile.result`. `buffer` is `Promise<Buffer>`. `blob` is `Promise<Blob>`. |
97
- | imageResolver | undefined | ImageResolver? | **You must set** if your markdown includes images. See example for [browser](https://github.com/inokawa/remark-docx/blob/main/stories/playground.stories.tsx) and [Node.js](https://github.com/inokawa/remark-docx/blob/main/src/index.spec.ts). |
98
- | title | undefined | string? | |
99
- | subject | undefined | string? | |
100
- | creator | undefined | string? | |
101
- | keywords | undefined | string? | |
102
- | description | undefined | string? | |
103
- | lastModifiedBy | undefined | string? | |
104
- | revision | undefined | number? | |
105
- | styles | undefined | IStylesOptions? | |
106
- | background | undefined | IDocumentBackgroundOptions? | |
92
+ ## Documentation
93
+
94
+ - [API reference](./docs/API.md)
95
+
96
+ ## Contribute
97
+
98
+ All contributions are welcome.
99
+ If you find a problem, feel free to create an [issue](https://github.com/inokawa/remark-docx/issues) or a [PR](https://github.com/inokawa/remark-docx/pulls).
100
+
101
+ ### Making a Pull Request
102
+
103
+ 1. Clone this repo.
104
+ 2. Run `npm install`.
105
+ 3. Commit your fix.
106
+ 4. Make a PR and confirm all the CI checks passed.
107
107
 
108
108
  ## Related projects
109
109
 
package/lib/index.d.ts CHANGED
@@ -1,2 +1,2 @@
1
1
  export { default } from "./plugin";
2
- export type { Options as DocxOptions } from "./plugin";
2
+ export type { DocxOptions } from "./plugin";
package/lib/index.js CHANGED
@@ -5,26 +5,6 @@ var unistUtilVisit = require('unist-util-visit');
5
5
  var docx = require('docx');
6
6
  var unifiedLatexUtilParse = require('@unified-latex/unified-latex-util-parse');
7
7
 
8
- function _interopNamespace(e) {
9
- if (e && e.__esModule) return e;
10
- var n = Object.create(null);
11
- if (e) {
12
- Object.keys(e).forEach(function (k) {
13
- if (k !== 'default') {
14
- var d = Object.getOwnPropertyDescriptor(e, k);
15
- Object.defineProperty(n, k, d.get ? d : {
16
- enumerable: true,
17
- get: function () { return e[k]; }
18
- });
19
- }
20
- });
21
- }
22
- n["default"] = e;
23
- return Object.freeze(n);
24
- }
25
-
26
- var docx__namespace = /*#__PURE__*/_interopNamespace(docx);
27
-
28
8
  const unreachable = (_) => {
29
9
  throw new Error("unreachable");
30
10
  };
@@ -39,7 +19,7 @@ const hasSquareBrackets = (arg) => {
39
19
  const hasCurlyBrackets = (arg) => {
40
20
  return !!arg && arg.openMark === "{" && arg.closeMark === "}";
41
21
  };
42
- const mapString = (s) => new docx__namespace.MathRun(s);
22
+ const mapString = (s) => new docx.MathRun(s);
43
23
  const mapMacro = (n, runs) => {
44
24
  var _a, _b, _c, _d, _e, _f, _g, _h;
45
25
  switch (n.content) {
@@ -249,7 +229,7 @@ const mapMacro = (n, runs) => {
249
229
  const prev = runs.pop();
250
230
  if (!prev)
251
231
  break;
252
- return new docx__namespace.MathSuperScript({
232
+ return new docx.MathSuperScript({
253
233
  children: [prev],
254
234
  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 : []),
255
235
  });
@@ -258,7 +238,7 @@ const mapMacro = (n, runs) => {
258
238
  const prev = runs.pop();
259
239
  if (!prev)
260
240
  break;
261
- return new docx__namespace.MathSubScript({
241
+ return new docx.MathSubScript({
262
242
  children: [prev],
263
243
  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 : []),
264
244
  });
@@ -271,7 +251,7 @@ const mapMacro = (n, runs) => {
271
251
  break;
272
252
  case "sum": {
273
253
  // TODO: support superscript and subscript
274
- return new docx__namespace.MathSum({
254
+ return new docx.MathSum({
275
255
  children: [],
276
256
  });
277
257
  }
@@ -284,7 +264,7 @@ const mapMacro = (n, runs) => {
284
264
  if (args.length === 2 &&
285
265
  hasCurlyBrackets(args[0]) &&
286
266
  hasCurlyBrackets(args[1])) {
287
- return new docx__namespace.MathFraction({
267
+ return new docx.MathFraction({
288
268
  numerator: mapGroup(args[0].content),
289
269
  denominator: mapGroup(args[1].content),
290
270
  });
@@ -294,14 +274,14 @@ const mapMacro = (n, runs) => {
294
274
  case "sqrt": {
295
275
  const args = (_h = n.args) !== null && _h !== void 0 ? _h : [];
296
276
  if (args.length === 1 && hasCurlyBrackets(args[0])) {
297
- return new docx__namespace.MathRadical({
277
+ return new docx.MathRadical({
298
278
  children: mapGroup(args[0].content),
299
279
  });
300
280
  }
301
281
  if (args.length === 2 &&
302
282
  hasSquareBrackets(args[0]) &&
303
283
  hasCurlyBrackets(args[1])) {
304
- return new docx__namespace.MathRadical({
284
+ return new docx.MathRadical({
305
285
  children: mapGroup(args[1].content),
306
286
  degree: mapGroup(args[0].content),
307
287
  });
@@ -379,15 +359,15 @@ const INDENT = 0.5;
379
359
  const DEFAULT_NUMBERINGS = [
380
360
  {
381
361
  level: 0,
382
- format: docx__namespace.LevelFormat.DECIMAL,
362
+ format: docx.LevelFormat.DECIMAL,
383
363
  text: "%1.",
384
- alignment: docx__namespace.AlignmentType.START,
364
+ alignment: docx.AlignmentType.START,
385
365
  },
386
366
  {
387
367
  level: 1,
388
- format: docx__namespace.LevelFormat.DECIMAL,
368
+ format: docx.LevelFormat.DECIMAL,
389
369
  text: "%2.",
390
- alignment: docx__namespace.AlignmentType.START,
370
+ alignment: docx.AlignmentType.START,
391
371
  style: {
392
372
  paragraph: {
393
373
  indent: { start: docx.convertInchesToTwip(INDENT * 1) },
@@ -396,9 +376,9 @@ const DEFAULT_NUMBERINGS = [
396
376
  },
397
377
  {
398
378
  level: 2,
399
- format: docx__namespace.LevelFormat.DECIMAL,
379
+ format: docx.LevelFormat.DECIMAL,
400
380
  text: "%3.",
401
- alignment: docx__namespace.AlignmentType.START,
381
+ alignment: docx.AlignmentType.START,
402
382
  style: {
403
383
  paragraph: {
404
384
  indent: { start: docx.convertInchesToTwip(INDENT * 2) },
@@ -407,9 +387,9 @@ const DEFAULT_NUMBERINGS = [
407
387
  },
408
388
  {
409
389
  level: 3,
410
- format: docx__namespace.LevelFormat.DECIMAL,
390
+ format: docx.LevelFormat.DECIMAL,
411
391
  text: "%4.",
412
- alignment: docx__namespace.AlignmentType.START,
392
+ alignment: docx.AlignmentType.START,
413
393
  style: {
414
394
  paragraph: {
415
395
  indent: { start: docx.convertInchesToTwip(INDENT * 3) },
@@ -418,9 +398,9 @@ const DEFAULT_NUMBERINGS = [
418
398
  },
419
399
  {
420
400
  level: 4,
421
- format: docx__namespace.LevelFormat.DECIMAL,
401
+ format: docx.LevelFormat.DECIMAL,
422
402
  text: "%5.",
423
- alignment: docx__namespace.AlignmentType.START,
403
+ alignment: docx.AlignmentType.START,
424
404
  style: {
425
405
  paragraph: {
426
406
  indent: { start: docx.convertInchesToTwip(INDENT * 4) },
@@ -429,9 +409,9 @@ const DEFAULT_NUMBERINGS = [
429
409
  },
430
410
  {
431
411
  level: 5,
432
- format: docx__namespace.LevelFormat.DECIMAL,
412
+ format: docx.LevelFormat.DECIMAL,
433
413
  text: "%6.",
434
- alignment: docx__namespace.AlignmentType.START,
414
+ alignment: docx.AlignmentType.START,
435
415
  style: {
436
416
  paragraph: {
437
417
  indent: { start: docx.convertInchesToTwip(INDENT * 5) },
@@ -440,12 +420,12 @@ const DEFAULT_NUMBERINGS = [
440
420
  },
441
421
  ];
442
422
  const mdastToDocx = (node, { output = "buffer", title, subject, creator, keywords, description, lastModifiedBy, revision, styles, background, }, images) => {
443
- const nodes = convertNodes(node.children, {
423
+ const { nodes, footnotes } = convertNodes(node.children, {
444
424
  deco: {},
445
425
  images,
446
426
  indent: 0,
447
427
  });
448
- const doc = new docx__namespace.Document({
428
+ const doc = new docx.Document({
449
429
  title,
450
430
  subject,
451
431
  creator,
@@ -455,6 +435,7 @@ const mdastToDocx = (node, { output = "buffer", title, subject, creator, keyword
455
435
  revision,
456
436
  styles,
457
437
  background,
438
+ footnotes,
458
439
  sections: [{ children: nodes }],
459
440
  numbering: {
460
441
  config: [
@@ -474,6 +455,7 @@ const mdastToDocx = (node, { output = "buffer", title, subject, creator, keyword
474
455
  };
475
456
  const convertNodes = (nodes, ctx) => {
476
457
  const results = [];
458
+ let footnotes = {};
477
459
  for (const node of nodes) {
478
460
  switch (node.type) {
479
461
  case "paragraph":
@@ -516,7 +498,7 @@ const convertNodes = (nodes, ctx) => {
516
498
  // FIXME: unimplemented
517
499
  break;
518
500
  case "footnoteDefinition":
519
- // FIXME: unimplemented
501
+ footnotes[node.identifier] = buildFootnoteDefinition(node, ctx);
520
502
  break;
521
503
  case "text":
522
504
  results.push(buildText(node.value, ctx.deco));
@@ -525,7 +507,8 @@ const convertNodes = (nodes, ctx) => {
525
507
  case "strong":
526
508
  case "delete": {
527
509
  const { type, children } = node;
528
- results.push(...convertNodes(children, Object.assign(Object.assign({}, ctx), { deco: Object.assign(Object.assign({}, ctx.deco), { [type]: true }) })));
510
+ const { nodes } = convertNodes(children, Object.assign(Object.assign({}, ctx), { deco: Object.assign(Object.assign({}, ctx.deco), { [type]: true }) }));
511
+ results.push(...nodes);
529
512
  break;
530
513
  }
531
514
  case "inlineCode":
@@ -551,7 +534,8 @@ const convertNodes = (nodes, ctx) => {
551
534
  results.push(buildFootnote(node, ctx));
552
535
  break;
553
536
  case "footnoteReference":
554
- // FIXME: unimplemented
537
+ // do we need context here?
538
+ results.push(buildFootnoteReference(node));
555
539
  break;
556
540
  case "math":
557
541
  results.push(...buildMath(node));
@@ -564,11 +548,15 @@ const convertNodes = (nodes, ctx) => {
564
548
  break;
565
549
  }
566
550
  }
567
- return results;
551
+ return {
552
+ nodes: results,
553
+ footnotes,
554
+ };
568
555
  };
569
556
  const buildParagraph = ({ children }, ctx) => {
570
557
  const list = ctx.list;
571
- return new docx__namespace.Paragraph(Object.assign({ children: convertNodes(children, ctx), indent: ctx.indent > 0
558
+ const { nodes } = convertNodes(children, ctx);
559
+ return new docx.Paragraph(Object.assign({ children: nodes, indent: ctx.indent > 0
572
560
  ? {
573
561
  start: docx.convertInchesToTwip(INDENT * ctx.indent),
574
562
  }
@@ -590,36 +578,38 @@ const buildHeading = ({ children, depth }, ctx) => {
590
578
  let heading;
591
579
  switch (depth) {
592
580
  case 1:
593
- heading = docx__namespace.HeadingLevel.TITLE;
581
+ heading = docx.HeadingLevel.TITLE;
594
582
  break;
595
583
  case 2:
596
- heading = docx__namespace.HeadingLevel.HEADING_1;
584
+ heading = docx.HeadingLevel.HEADING_1;
597
585
  break;
598
586
  case 3:
599
- heading = docx__namespace.HeadingLevel.HEADING_2;
587
+ heading = docx.HeadingLevel.HEADING_2;
600
588
  break;
601
589
  case 4:
602
- heading = docx__namespace.HeadingLevel.HEADING_3;
590
+ heading = docx.HeadingLevel.HEADING_3;
603
591
  break;
604
592
  case 5:
605
- heading = docx__namespace.HeadingLevel.HEADING_4;
593
+ heading = docx.HeadingLevel.HEADING_4;
606
594
  break;
607
595
  case 6:
608
- heading = docx__namespace.HeadingLevel.HEADING_5;
596
+ heading = docx.HeadingLevel.HEADING_5;
609
597
  break;
610
598
  }
611
- return new docx__namespace.Paragraph({
599
+ const { nodes } = convertNodes(children, ctx);
600
+ return new docx.Paragraph({
612
601
  heading,
613
- children: convertNodes(children, ctx),
602
+ children: nodes,
614
603
  });
615
604
  };
616
605
  const buildThematicBreak = (_) => {
617
- return new docx__namespace.Paragraph({
606
+ return new docx.Paragraph({
618
607
  thematicBreak: true,
619
608
  });
620
609
  };
621
610
  const buildBlockquote = ({ children }, ctx) => {
622
- return convertNodes(children, Object.assign(Object.assign({}, ctx), { indent: ctx.indent + 1 }));
611
+ const { nodes } = convertNodes(children, Object.assign(Object.assign({}, ctx), { indent: ctx.indent + 1 }));
612
+ return nodes;
623
613
  };
624
614
  const buildList = ({ children, ordered, start: _start, spread: _spread }, ctx) => {
625
615
  const list = {
@@ -632,72 +622,74 @@ const buildList = ({ children, ordered, start: _start, spread: _spread }, ctx) =
632
622
  }, []);
633
623
  };
634
624
  const buildListItem = ({ children, checked: _checked, spread: _spread }, ctx) => {
635
- return convertNodes(children, ctx);
625
+ const { nodes } = convertNodes(children, ctx);
626
+ return nodes;
636
627
  };
637
628
  const buildTable = ({ children, align }, ctx) => {
638
629
  const cellAligns = align === null || align === void 0 ? void 0 : align.map((a) => {
639
630
  switch (a) {
640
631
  case "left":
641
- return docx__namespace.AlignmentType.LEFT;
632
+ return docx.AlignmentType.LEFT;
642
633
  case "right":
643
- return docx__namespace.AlignmentType.RIGHT;
634
+ return docx.AlignmentType.RIGHT;
644
635
  case "center":
645
- return docx__namespace.AlignmentType.CENTER;
636
+ return docx.AlignmentType.CENTER;
646
637
  default:
647
- return docx__namespace.AlignmentType.LEFT;
638
+ return docx.AlignmentType.LEFT;
648
639
  }
649
640
  });
650
- return new docx__namespace.Table({
641
+ return new docx.Table({
651
642
  rows: children.map((r) => {
652
643
  return buildTableRow(r, ctx, cellAligns);
653
644
  }),
654
645
  });
655
646
  };
656
647
  const buildTableRow = ({ children }, ctx, cellAligns) => {
657
- return new docx__namespace.TableRow({
648
+ return new docx.TableRow({
658
649
  children: children.map((c, i) => {
659
650
  return buildTableCell(c, ctx, cellAligns === null || cellAligns === void 0 ? void 0 : cellAligns[i]);
660
651
  }),
661
652
  });
662
653
  };
663
654
  const buildTableCell = ({ children }, ctx, align) => {
664
- return new docx__namespace.TableCell({
655
+ const { nodes } = convertNodes(children, ctx);
656
+ return new docx.TableCell({
665
657
  children: [
666
- new docx__namespace.Paragraph({
658
+ new docx.Paragraph({
667
659
  alignment: align,
668
- children: convertNodes(children, ctx),
660
+ children: nodes,
669
661
  }),
670
662
  ],
671
663
  });
672
664
  };
673
665
  const buildHtml = ({ value }) => {
674
666
  // FIXME: transform to text for now
675
- return new docx__namespace.Paragraph({
667
+ return new docx.Paragraph({
676
668
  children: [buildText(value, {})],
677
669
  });
678
670
  };
679
671
  const buildCode = ({ value, lang: _lang, meta: _meta }) => {
680
672
  // FIXME: transform to text for now
681
- return new docx__namespace.Paragraph({
673
+ return new docx.Paragraph({
682
674
  children: [buildText(value, {})],
683
675
  });
684
676
  };
685
677
  const buildMath = ({ value }) => {
686
- return parseLatex(value).map((runs) => new docx__namespace.Paragraph({
678
+ return parseLatex(value).map((runs) => new docx.Paragraph({
687
679
  children: [
688
- new docx__namespace.Math({
680
+ new docx.Math({
689
681
  children: runs,
690
682
  }),
691
683
  ],
692
684
  }));
693
685
  };
694
686
  const buildInlineMath = ({ value }) => {
695
- return new docx__namespace.Math({
687
+ return new docx.Math({
696
688
  children: parseLatex(value).flatMap((runs) => runs),
697
689
  });
698
690
  };
699
691
  const buildText = (text, deco) => {
700
- return new docx__namespace.TextRun({
692
+ return new docx.TextRun({
701
693
  text,
702
694
  bold: deco.strong,
703
695
  italics: deco.emphasis,
@@ -705,19 +697,20 @@ const buildText = (text, deco) => {
705
697
  });
706
698
  };
707
699
  const buildBreak = (_) => {
708
- return new docx__namespace.TextRun({ text: "", break: 1 });
700
+ return new docx.TextRun({ text: "", break: 1 });
709
701
  };
710
702
  const buildLink = ({ children, url, title: _title }, ctx) => {
711
- return new docx__namespace.ExternalHyperlink({
703
+ const { nodes } = convertNodes(children, ctx);
704
+ return new docx.ExternalHyperlink({
712
705
  link: url,
713
- children: convertNodes(children, ctx),
706
+ children: nodes,
714
707
  });
715
708
  };
716
709
  const buildImage = ({ url, title: _title, alt: _alt }, images) => {
717
710
  const img = images[url];
718
711
  invariant(img, `Fetch image was failed: ${url}`);
719
712
  const { image, width, height } = img;
720
- return new docx__namespace.ImageRun({
713
+ return new docx.ImageRun({
721
714
  data: image,
722
715
  transformation: {
723
716
  width,
@@ -727,10 +720,23 @@ const buildImage = ({ url, title: _title, alt: _alt }, images) => {
727
720
  };
728
721
  const buildFootnote = ({ children }, ctx) => {
729
722
  // FIXME: transform to paragraph for now
730
- return new docx__namespace.Paragraph({
731
- children: convertNodes(children, ctx),
723
+ const { nodes } = convertNodes(children, ctx);
724
+ return new docx.Paragraph({
725
+ children: nodes,
732
726
  });
733
727
  };
728
+ const buildFootnoteDefinition = ({ children }, ctx) => {
729
+ return {
730
+ children: children.map((node) => {
731
+ const { nodes } = convertNodes([node], ctx);
732
+ return nodes[0];
733
+ }),
734
+ };
735
+ };
736
+ const buildFootnoteReference = ({ identifier }) => {
737
+ // do we need Context?
738
+ return new docx.FootnoteReferenceRun(parseInt(identifier));
739
+ };
734
740
 
735
741
  const plugin = function (opts = {}) {
736
742
  let images = {};