remark-docx 0.1.2 → 0.1.4

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) },
@@ -439,13 +419,13 @@ const DEFAULT_NUMBERINGS = [
439
419
  },
440
420
  },
441
421
  ];
442
- const mdastToDocx = (node, { output = "buffer", title, subject, creator, keywords, description, lastModifiedBy, revision, styles, background, }, images) => {
443
- const nodes = convertNodes(node.children, {
422
+ const mdastToDocx = (node, { output = "buffer", title, subject, creator, keywords, description, lastModifiedBy, revision, styles, background, }, images) => tslib.__awaiter(void 0, void 0, void 0, function* () {
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: [
@@ -467,13 +448,18 @@ const mdastToDocx = (node, { output = "buffer", title, subject, creator, keyword
467
448
  });
468
449
  switch (output) {
469
450
  case "buffer":
470
- return docx.Packer.toBuffer(doc);
451
+ const bufOut = yield docx.Packer.toBuffer(doc);
452
+ // feature detection instead of environment detection, but if Buffer exists
453
+ // it's probably Node. If not, return the Uint8Array that JSZip returns
454
+ // when it doesn't detect a Node environment.
455
+ return typeof Buffer === "function" ? Buffer.from(bufOut) : bufOut;
471
456
  case "blob":
472
457
  return docx.Packer.toBlob(doc);
473
458
  }
474
- };
459
+ });
475
460
  const convertNodes = (nodes, ctx) => {
476
461
  const results = [];
462
+ let footnotes = {};
477
463
  for (const node of nodes) {
478
464
  switch (node.type) {
479
465
  case "paragraph":
@@ -516,7 +502,7 @@ const convertNodes = (nodes, ctx) => {
516
502
  // FIXME: unimplemented
517
503
  break;
518
504
  case "footnoteDefinition":
519
- // FIXME: unimplemented
505
+ footnotes[node.identifier] = buildFootnoteDefinition(node, ctx);
520
506
  break;
521
507
  case "text":
522
508
  results.push(buildText(node.value, ctx.deco));
@@ -525,7 +511,8 @@ const convertNodes = (nodes, ctx) => {
525
511
  case "strong":
526
512
  case "delete": {
527
513
  const { type, children } = node;
528
- results.push(...convertNodes(children, Object.assign(Object.assign({}, ctx), { deco: Object.assign(Object.assign({}, ctx.deco), { [type]: true }) })));
514
+ const { nodes } = convertNodes(children, Object.assign(Object.assign({}, ctx), { deco: Object.assign(Object.assign({}, ctx.deco), { [type]: true }) }));
515
+ results.push(...nodes);
529
516
  break;
530
517
  }
531
518
  case "inlineCode":
@@ -551,7 +538,8 @@ const convertNodes = (nodes, ctx) => {
551
538
  results.push(buildFootnote(node, ctx));
552
539
  break;
553
540
  case "footnoteReference":
554
- // FIXME: unimplemented
541
+ // do we need context here?
542
+ results.push(buildFootnoteReference(node));
555
543
  break;
556
544
  case "math":
557
545
  results.push(...buildMath(node));
@@ -564,11 +552,15 @@ const convertNodes = (nodes, ctx) => {
564
552
  break;
565
553
  }
566
554
  }
567
- return results;
555
+ return {
556
+ nodes: results,
557
+ footnotes,
558
+ };
568
559
  };
569
560
  const buildParagraph = ({ children }, ctx) => {
570
561
  const list = ctx.list;
571
- return new docx__namespace.Paragraph(Object.assign({ children: convertNodes(children, ctx), indent: ctx.indent > 0
562
+ const { nodes } = convertNodes(children, ctx);
563
+ return new docx.Paragraph(Object.assign({ children: nodes, indent: ctx.indent > 0
572
564
  ? {
573
565
  start: docx.convertInchesToTwip(INDENT * ctx.indent),
574
566
  }
@@ -590,36 +582,38 @@ const buildHeading = ({ children, depth }, ctx) => {
590
582
  let heading;
591
583
  switch (depth) {
592
584
  case 1:
593
- heading = docx__namespace.HeadingLevel.TITLE;
585
+ heading = docx.HeadingLevel.TITLE;
594
586
  break;
595
587
  case 2:
596
- heading = docx__namespace.HeadingLevel.HEADING_1;
588
+ heading = docx.HeadingLevel.HEADING_1;
597
589
  break;
598
590
  case 3:
599
- heading = docx__namespace.HeadingLevel.HEADING_2;
591
+ heading = docx.HeadingLevel.HEADING_2;
600
592
  break;
601
593
  case 4:
602
- heading = docx__namespace.HeadingLevel.HEADING_3;
594
+ heading = docx.HeadingLevel.HEADING_3;
603
595
  break;
604
596
  case 5:
605
- heading = docx__namespace.HeadingLevel.HEADING_4;
597
+ heading = docx.HeadingLevel.HEADING_4;
606
598
  break;
607
599
  case 6:
608
- heading = docx__namespace.HeadingLevel.HEADING_5;
600
+ heading = docx.HeadingLevel.HEADING_5;
609
601
  break;
610
602
  }
611
- return new docx__namespace.Paragraph({
603
+ const { nodes } = convertNodes(children, ctx);
604
+ return new docx.Paragraph({
612
605
  heading,
613
- children: convertNodes(children, ctx),
606
+ children: nodes,
614
607
  });
615
608
  };
616
609
  const buildThematicBreak = (_) => {
617
- return new docx__namespace.Paragraph({
610
+ return new docx.Paragraph({
618
611
  thematicBreak: true,
619
612
  });
620
613
  };
621
614
  const buildBlockquote = ({ children }, ctx) => {
622
- return convertNodes(children, Object.assign(Object.assign({}, ctx), { indent: ctx.indent + 1 }));
615
+ const { nodes } = convertNodes(children, Object.assign(Object.assign({}, ctx), { indent: ctx.indent + 1 }));
616
+ return nodes;
623
617
  };
624
618
  const buildList = ({ children, ordered, start: _start, spread: _spread }, ctx) => {
625
619
  const list = {
@@ -632,72 +626,74 @@ const buildList = ({ children, ordered, start: _start, spread: _spread }, ctx) =
632
626
  }, []);
633
627
  };
634
628
  const buildListItem = ({ children, checked: _checked, spread: _spread }, ctx) => {
635
- return convertNodes(children, ctx);
629
+ const { nodes } = convertNodes(children, ctx);
630
+ return nodes;
636
631
  };
637
632
  const buildTable = ({ children, align }, ctx) => {
638
633
  const cellAligns = align === null || align === void 0 ? void 0 : align.map((a) => {
639
634
  switch (a) {
640
635
  case "left":
641
- return docx__namespace.AlignmentType.LEFT;
636
+ return docx.AlignmentType.LEFT;
642
637
  case "right":
643
- return docx__namespace.AlignmentType.RIGHT;
638
+ return docx.AlignmentType.RIGHT;
644
639
  case "center":
645
- return docx__namespace.AlignmentType.CENTER;
640
+ return docx.AlignmentType.CENTER;
646
641
  default:
647
- return docx__namespace.AlignmentType.LEFT;
642
+ return docx.AlignmentType.LEFT;
648
643
  }
649
644
  });
650
- return new docx__namespace.Table({
645
+ return new docx.Table({
651
646
  rows: children.map((r) => {
652
647
  return buildTableRow(r, ctx, cellAligns);
653
648
  }),
654
649
  });
655
650
  };
656
651
  const buildTableRow = ({ children }, ctx, cellAligns) => {
657
- return new docx__namespace.TableRow({
652
+ return new docx.TableRow({
658
653
  children: children.map((c, i) => {
659
654
  return buildTableCell(c, ctx, cellAligns === null || cellAligns === void 0 ? void 0 : cellAligns[i]);
660
655
  }),
661
656
  });
662
657
  };
663
658
  const buildTableCell = ({ children }, ctx, align) => {
664
- return new docx__namespace.TableCell({
659
+ const { nodes } = convertNodes(children, ctx);
660
+ return new docx.TableCell({
665
661
  children: [
666
- new docx__namespace.Paragraph({
662
+ new docx.Paragraph({
667
663
  alignment: align,
668
- children: convertNodes(children, ctx),
664
+ children: nodes,
669
665
  }),
670
666
  ],
671
667
  });
672
668
  };
673
669
  const buildHtml = ({ value }) => {
674
670
  // FIXME: transform to text for now
675
- return new docx__namespace.Paragraph({
671
+ return new docx.Paragraph({
676
672
  children: [buildText(value, {})],
677
673
  });
678
674
  };
679
675
  const buildCode = ({ value, lang: _lang, meta: _meta }) => {
680
676
  // FIXME: transform to text for now
681
- return new docx__namespace.Paragraph({
677
+ return new docx.Paragraph({
682
678
  children: [buildText(value, {})],
683
679
  });
684
680
  };
685
681
  const buildMath = ({ value }) => {
686
- return parseLatex(value).map((runs) => new docx__namespace.Paragraph({
682
+ return parseLatex(value).map((runs) => new docx.Paragraph({
687
683
  children: [
688
- new docx__namespace.Math({
684
+ new docx.Math({
689
685
  children: runs,
690
686
  }),
691
687
  ],
692
688
  }));
693
689
  };
694
690
  const buildInlineMath = ({ value }) => {
695
- return new docx__namespace.Math({
691
+ return new docx.Math({
696
692
  children: parseLatex(value).flatMap((runs) => runs),
697
693
  });
698
694
  };
699
695
  const buildText = (text, deco) => {
700
- return new docx__namespace.TextRun({
696
+ return new docx.TextRun({
701
697
  text,
702
698
  bold: deco.strong,
703
699
  italics: deco.emphasis,
@@ -705,19 +701,20 @@ const buildText = (text, deco) => {
705
701
  });
706
702
  };
707
703
  const buildBreak = (_) => {
708
- return new docx__namespace.TextRun({ text: "", break: 1 });
704
+ return new docx.TextRun({ text: "", break: 1 });
709
705
  };
710
706
  const buildLink = ({ children, url, title: _title }, ctx) => {
711
- return new docx__namespace.ExternalHyperlink({
707
+ const { nodes } = convertNodes(children, ctx);
708
+ return new docx.ExternalHyperlink({
712
709
  link: url,
713
- children: convertNodes(children, ctx),
710
+ children: nodes,
714
711
  });
715
712
  };
716
713
  const buildImage = ({ url, title: _title, alt: _alt }, images) => {
717
714
  const img = images[url];
718
715
  invariant(img, `Fetch image was failed: ${url}`);
719
716
  const { image, width, height } = img;
720
- return new docx__namespace.ImageRun({
717
+ return new docx.ImageRun({
721
718
  data: image,
722
719
  transformation: {
723
720
  width,
@@ -727,10 +724,23 @@ const buildImage = ({ url, title: _title, alt: _alt }, images) => {
727
724
  };
728
725
  const buildFootnote = ({ children }, ctx) => {
729
726
  // FIXME: transform to paragraph for now
730
- return new docx__namespace.Paragraph({
731
- children: convertNodes(children, ctx),
727
+ const { nodes } = convertNodes(children, ctx);
728
+ return new docx.Paragraph({
729
+ children: nodes,
732
730
  });
733
731
  };
732
+ const buildFootnoteDefinition = ({ children }, ctx) => {
733
+ return {
734
+ children: children.map((node) => {
735
+ const { nodes } = convertNodes([node], ctx);
736
+ return nodes[0];
737
+ }),
738
+ };
739
+ };
740
+ const buildFootnoteReference = ({ identifier }) => {
741
+ // do we need Context?
742
+ return new docx.FootnoteReferenceRun(parseInt(identifier));
743
+ };
734
744
 
735
745
  const plugin = function (opts = {}) {
736
746
  let images = {};