remark-docx 0.1.1 → 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
@@ -13,7 +13,7 @@ If you have some feature requests or improvements, please create a [issue](https
13
13
  - [x] paragraph
14
14
  - [x] heading
15
15
  - [x] thematicBreak
16
- - [ ] blockquote
16
+ - [x] blockquote
17
17
  - [x] list
18
18
  - [x] listItem
19
19
  - [x] table
@@ -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,9 +35,9 @@ 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
40
- - [x] LaTeX support with math and inlineMath ([remark-math](https://www.npmjs.com/package/remark-math) is required)
38
+ - [x] footnote
39
+ - [x] footnoteReference
40
+ - [x] LaTeX support with math and inlineMath ([remark-math](https://github.com/remarkjs/remark-math) is required)
41
41
 
42
42
  ## Demo
43
43
 
@@ -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,11 +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,
426
+ indent: 0,
446
427
  });
447
- const doc = new docx__namespace.Document({
428
+ const doc = new docx.Document({
448
429
  title,
449
430
  subject,
450
431
  creator,
@@ -454,6 +435,7 @@ const mdastToDocx = (node, { output = "buffer", title, subject, creator, keyword
454
435
  revision,
455
436
  styles,
456
437
  background,
438
+ footnotes,
457
439
  sections: [{ children: nodes }],
458
440
  numbering: {
459
441
  config: [
@@ -473,6 +455,7 @@ const mdastToDocx = (node, { output = "buffer", title, subject, creator, keyword
473
455
  };
474
456
  const convertNodes = (nodes, ctx) => {
475
457
  const results = [];
458
+ let footnotes = {};
476
459
  for (const node of nodes) {
477
460
  switch (node.type) {
478
461
  case "paragraph":
@@ -515,7 +498,7 @@ const convertNodes = (nodes, ctx) => {
515
498
  // FIXME: unimplemented
516
499
  break;
517
500
  case "footnoteDefinition":
518
- // FIXME: unimplemented
501
+ footnotes[node.identifier] = buildFootnoteDefinition(node, ctx);
519
502
  break;
520
503
  case "text":
521
504
  results.push(buildText(node.value, ctx.deco));
@@ -524,7 +507,8 @@ const convertNodes = (nodes, ctx) => {
524
507
  case "strong":
525
508
  case "delete": {
526
509
  const { type, children } = node;
527
- 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);
528
512
  break;
529
513
  }
530
514
  case "inlineCode":
@@ -550,7 +534,8 @@ const convertNodes = (nodes, ctx) => {
550
534
  results.push(buildFootnote(node, ctx));
551
535
  break;
552
536
  case "footnoteReference":
553
- // FIXME: unimplemented
537
+ // do we need context here?
538
+ results.push(buildFootnoteReference(node));
554
539
  break;
555
540
  case "math":
556
541
  results.push(...buildMath(node));
@@ -563,11 +548,19 @@ const convertNodes = (nodes, ctx) => {
563
548
  break;
564
549
  }
565
550
  }
566
- return results;
551
+ return {
552
+ nodes: results,
553
+ footnotes,
554
+ };
567
555
  };
568
556
  const buildParagraph = ({ children }, ctx) => {
569
557
  const list = ctx.list;
570
- return new docx__namespace.Paragraph(Object.assign({ children: convertNodes(children, ctx) }, (list &&
558
+ const { nodes } = convertNodes(children, ctx);
559
+ return new docx.Paragraph(Object.assign({ children: nodes, indent: ctx.indent > 0
560
+ ? {
561
+ start: docx.convertInchesToTwip(INDENT * ctx.indent),
562
+ }
563
+ : undefined }, (list &&
571
564
  (list.ordered
572
565
  ? {
573
566
  numbering: {
@@ -585,37 +578,38 @@ const buildHeading = ({ children, depth }, ctx) => {
585
578
  let heading;
586
579
  switch (depth) {
587
580
  case 1:
588
- heading = docx__namespace.HeadingLevel.TITLE;
581
+ heading = docx.HeadingLevel.TITLE;
589
582
  break;
590
583
  case 2:
591
- heading = docx__namespace.HeadingLevel.HEADING_1;
584
+ heading = docx.HeadingLevel.HEADING_1;
592
585
  break;
593
586
  case 3:
594
- heading = docx__namespace.HeadingLevel.HEADING_2;
587
+ heading = docx.HeadingLevel.HEADING_2;
595
588
  break;
596
589
  case 4:
597
- heading = docx__namespace.HeadingLevel.HEADING_3;
590
+ heading = docx.HeadingLevel.HEADING_3;
598
591
  break;
599
592
  case 5:
600
- heading = docx__namespace.HeadingLevel.HEADING_4;
593
+ heading = docx.HeadingLevel.HEADING_4;
601
594
  break;
602
595
  case 6:
603
- heading = docx__namespace.HeadingLevel.HEADING_5;
596
+ heading = docx.HeadingLevel.HEADING_5;
604
597
  break;
605
598
  }
606
- return new docx__namespace.Paragraph({
599
+ const { nodes } = convertNodes(children, ctx);
600
+ return new docx.Paragraph({
607
601
  heading,
608
- children: convertNodes(children, ctx),
602
+ children: nodes,
609
603
  });
610
604
  };
611
605
  const buildThematicBreak = (_) => {
612
- return new docx__namespace.Paragraph({
606
+ return new docx.Paragraph({
613
607
  thematicBreak: true,
614
608
  });
615
609
  };
616
610
  const buildBlockquote = ({ children }, ctx) => {
617
- // FIXME: do nothing for now
618
- return convertNodes(children, ctx);
611
+ const { nodes } = convertNodes(children, Object.assign(Object.assign({}, ctx), { indent: ctx.indent + 1 }));
612
+ return nodes;
619
613
  };
620
614
  const buildList = ({ children, ordered, start: _start, spread: _spread }, ctx) => {
621
615
  const list = {
@@ -628,72 +622,74 @@ const buildList = ({ children, ordered, start: _start, spread: _spread }, ctx) =
628
622
  }, []);
629
623
  };
630
624
  const buildListItem = ({ children, checked: _checked, spread: _spread }, ctx) => {
631
- return convertNodes(children, ctx);
625
+ const { nodes } = convertNodes(children, ctx);
626
+ return nodes;
632
627
  };
633
628
  const buildTable = ({ children, align }, ctx) => {
634
629
  const cellAligns = align === null || align === void 0 ? void 0 : align.map((a) => {
635
630
  switch (a) {
636
631
  case "left":
637
- return docx__namespace.AlignmentType.LEFT;
632
+ return docx.AlignmentType.LEFT;
638
633
  case "right":
639
- return docx__namespace.AlignmentType.RIGHT;
634
+ return docx.AlignmentType.RIGHT;
640
635
  case "center":
641
- return docx__namespace.AlignmentType.CENTER;
636
+ return docx.AlignmentType.CENTER;
642
637
  default:
643
- return docx__namespace.AlignmentType.LEFT;
638
+ return docx.AlignmentType.LEFT;
644
639
  }
645
640
  });
646
- return new docx__namespace.Table({
641
+ return new docx.Table({
647
642
  rows: children.map((r) => {
648
643
  return buildTableRow(r, ctx, cellAligns);
649
644
  }),
650
645
  });
651
646
  };
652
647
  const buildTableRow = ({ children }, ctx, cellAligns) => {
653
- return new docx__namespace.TableRow({
648
+ return new docx.TableRow({
654
649
  children: children.map((c, i) => {
655
650
  return buildTableCell(c, ctx, cellAligns === null || cellAligns === void 0 ? void 0 : cellAligns[i]);
656
651
  }),
657
652
  });
658
653
  };
659
654
  const buildTableCell = ({ children }, ctx, align) => {
660
- return new docx__namespace.TableCell({
655
+ const { nodes } = convertNodes(children, ctx);
656
+ return new docx.TableCell({
661
657
  children: [
662
- new docx__namespace.Paragraph({
658
+ new docx.Paragraph({
663
659
  alignment: align,
664
- children: convertNodes(children, ctx),
660
+ children: nodes,
665
661
  }),
666
662
  ],
667
663
  });
668
664
  };
669
665
  const buildHtml = ({ value }) => {
670
666
  // FIXME: transform to text for now
671
- return new docx__namespace.Paragraph({
667
+ return new docx.Paragraph({
672
668
  children: [buildText(value, {})],
673
669
  });
674
670
  };
675
671
  const buildCode = ({ value, lang: _lang, meta: _meta }) => {
676
672
  // FIXME: transform to text for now
677
- return new docx__namespace.Paragraph({
673
+ return new docx.Paragraph({
678
674
  children: [buildText(value, {})],
679
675
  });
680
676
  };
681
677
  const buildMath = ({ value }) => {
682
- return parseLatex(value).map((runs) => new docx__namespace.Paragraph({
678
+ return parseLatex(value).map((runs) => new docx.Paragraph({
683
679
  children: [
684
- new docx__namespace.Math({
680
+ new docx.Math({
685
681
  children: runs,
686
682
  }),
687
683
  ],
688
684
  }));
689
685
  };
690
686
  const buildInlineMath = ({ value }) => {
691
- return new docx__namespace.Math({
687
+ return new docx.Math({
692
688
  children: parseLatex(value).flatMap((runs) => runs),
693
689
  });
694
690
  };
695
691
  const buildText = (text, deco) => {
696
- return new docx__namespace.TextRun({
692
+ return new docx.TextRun({
697
693
  text,
698
694
  bold: deco.strong,
699
695
  italics: deco.emphasis,
@@ -701,19 +697,20 @@ const buildText = (text, deco) => {
701
697
  });
702
698
  };
703
699
  const buildBreak = (_) => {
704
- return new docx__namespace.TextRun({ text: "", break: 1 });
700
+ return new docx.TextRun({ text: "", break: 1 });
705
701
  };
706
702
  const buildLink = ({ children, url, title: _title }, ctx) => {
707
- return new docx__namespace.ExternalHyperlink({
703
+ const { nodes } = convertNodes(children, ctx);
704
+ return new docx.ExternalHyperlink({
708
705
  link: url,
709
- children: convertNodes(children, ctx),
706
+ children: nodes,
710
707
  });
711
708
  };
712
709
  const buildImage = ({ url, title: _title, alt: _alt }, images) => {
713
710
  const img = images[url];
714
711
  invariant(img, `Fetch image was failed: ${url}`);
715
712
  const { image, width, height } = img;
716
- return new docx__namespace.ImageRun({
713
+ return new docx.ImageRun({
717
714
  data: image,
718
715
  transformation: {
719
716
  width,
@@ -723,10 +720,23 @@ const buildImage = ({ url, title: _title, alt: _alt }, images) => {
723
720
  };
724
721
  const buildFootnote = ({ children }, ctx) => {
725
722
  // FIXME: transform to paragraph for now
726
- return new docx__namespace.Paragraph({
727
- children: convertNodes(children, ctx),
723
+ const { nodes } = convertNodes(children, ctx);
724
+ return new docx.Paragraph({
725
+ children: nodes,
728
726
  });
729
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
+ };
730
740
 
731
741
  const plugin = function (opts = {}) {
732
742
  let images = {};