easy-template-x 5.1.0 → 6.0.0

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.
Files changed (89) hide show
  1. package/README.md +208 -19
  2. package/dist/cjs/easy-template-x.cjs +2978 -1801
  3. package/dist/es/easy-template-x.mjs +2971 -1796
  4. package/dist/types/compilation/delimiterMark.d.ts +3 -1
  5. package/dist/types/compilation/delimiterSearcher.d.ts +2 -5
  6. package/dist/types/compilation/tag.d.ts +2 -2
  7. package/dist/types/compilation/tagParser.d.ts +4 -6
  8. package/dist/types/compilation/templateContext.d.ts +2 -2
  9. package/dist/types/extensions/templateExtension.d.ts +1 -5
  10. package/dist/types/office/contentTypesFile.d.ts +2 -2
  11. package/dist/types/office/docx.d.ts +10 -17
  12. package/dist/types/office/index.d.ts +4 -3
  13. package/dist/types/office/{docxParser.d.ts → officeMarkup.d.ts} +18 -17
  14. package/dist/types/office/omlNode.d.ts +26 -0
  15. package/dist/types/office/openXmlPart.d.ts +21 -0
  16. package/dist/types/office/relationship.d.ts +7 -1
  17. package/dist/types/office/relsFile.d.ts +2 -1
  18. package/dist/types/office/xlsx.d.ts +16 -0
  19. package/dist/types/plugins/chart/chartContent.d.ts +8 -0
  20. package/dist/types/plugins/chart/chartData.d.ts +138 -0
  21. package/dist/types/plugins/chart/chartPlugin.d.ts +6 -0
  22. package/dist/types/plugins/chart/index.d.ts +2 -0
  23. package/dist/types/plugins/chart/updateChart.d.ts +3 -0
  24. package/dist/types/plugins/defaultPlugins.d.ts +1 -1
  25. package/dist/types/plugins/image/imagePlugin.d.ts +2 -2
  26. package/dist/types/plugins/link/linkPlugin.d.ts +2 -2
  27. package/dist/types/plugins/loop/loopPlugin.d.ts +2 -2
  28. package/dist/types/plugins/loop/strategy/iLoopStrategy.d.ts +2 -4
  29. package/dist/types/plugins/loop/strategy/loopListStrategy.d.ts +3 -6
  30. package/dist/types/plugins/loop/strategy/loopParagraphStrategy.d.ts +3 -6
  31. package/dist/types/plugins/loop/strategy/loopTableColumnsStrategy.d.ts +3 -6
  32. package/dist/types/plugins/loop/strategy/loopTableRowsStrategy.d.ts +3 -6
  33. package/dist/types/plugins/pluginContent.d.ts +1 -0
  34. package/dist/types/plugins/rawXml/rawXmlPlugin.d.ts +2 -2
  35. package/dist/types/plugins/templatePlugin.d.ts +1 -5
  36. package/dist/types/plugins/text/textPlugin.d.ts +3 -3
  37. package/dist/types/templateHandler.d.ts +5 -6
  38. package/dist/types/xml/index.d.ts +1 -1
  39. package/dist/types/xml/xml.d.ts +55 -0
  40. package/dist/types/xml/xmlNode.d.ts +1 -29
  41. package/dist/types/zip/zip.d.ts +2 -1
  42. package/dist/types/zip/zipObject.d.ts +3 -2
  43. package/package.json +2 -1
  44. package/src/compilation/delimiterMark.ts +3 -1
  45. package/src/compilation/delimiterSearcher.ts +8 -18
  46. package/src/compilation/tag.ts +2 -2
  47. package/src/compilation/tagParser.ts +13 -21
  48. package/src/compilation/templateContext.ts +2 -2
  49. package/src/extensions/templateExtension.ts +1 -5
  50. package/src/office/contentTypesFile.ts +8 -8
  51. package/src/office/docx.ts +48 -180
  52. package/src/office/index.ts +4 -4
  53. package/src/office/{docxParser.ts → officeMarkup.ts} +253 -217
  54. package/src/office/omlNode.ts +54 -0
  55. package/src/office/openXmlPart.ts +146 -0
  56. package/src/office/relationship.ts +8 -2
  57. package/src/office/relsFile.ts +15 -8
  58. package/src/office/xlsx.ts +103 -0
  59. package/src/plugins/chart/chartContent.ts +9 -0
  60. package/src/plugins/chart/chartData.ts +231 -0
  61. package/src/plugins/chart/chartPlugin.ts +84 -0
  62. package/src/plugins/chart/index.ts +2 -0
  63. package/src/plugins/chart/updateChart.ts +987 -0
  64. package/src/plugins/defaultPlugins.ts +8 -6
  65. package/src/plugins/image/imagePlugin.ts +13 -13
  66. package/src/plugins/link/linkPlugin.ts +23 -24
  67. package/src/plugins/loop/loopPlugin.ts +9 -10
  68. package/src/plugins/loop/strategy/iLoopStrategy.ts +2 -5
  69. package/src/plugins/loop/strategy/loopListStrategy.ts +14 -20
  70. package/src/plugins/loop/strategy/loopParagraphStrategy.ts +15 -21
  71. package/src/plugins/loop/strategy/loopTableColumnsStrategy.ts +27 -33
  72. package/src/plugins/loop/strategy/loopTableRowsStrategy.ts +15 -21
  73. package/src/plugins/pluginContent.ts +1 -0
  74. package/src/plugins/rawXml/rawXmlPlugin.ts +14 -9
  75. package/src/plugins/templatePlugin.ts +1 -5
  76. package/src/plugins/text/textPlugin.ts +36 -25
  77. package/src/templateHandler.ts +58 -65
  78. package/src/utils/path.ts +19 -1
  79. package/src/xml/index.ts +1 -1
  80. package/src/xml/xml.ts +656 -0
  81. package/src/xml/xmlNode.ts +1 -588
  82. package/src/zip/zip.ts +7 -6
  83. package/src/zip/zipObject.ts +5 -3
  84. package/dist/types/office/contentPartType.d.ts +0 -10
  85. package/dist/types/office/xmlPart.d.ts +0 -13
  86. package/dist/types/xml/xmlParser.d.ts +0 -9
  87. package/src/office/contentPartType.ts +0 -11
  88. package/src/office/xmlPart.ts +0 -67
  89. package/src/xml/xmlParser.ts +0 -32
package/README.md CHANGED
@@ -33,6 +33,7 @@ Generate docx documents from templates, in Node or in the browser.
33
33
  - [Controlling loop behavior](#controlling-loop-behavior)
34
34
  - [Image plugin](#image-plugin)
35
35
  - [Link plugin](#link-plugin)
36
+ - [Chart plugin](#chart-plugin)
36
37
  - [Raw xml plugin](#raw-xml-plugin)
37
38
  - [Writing custom plugins](#writing-your-own-plugins)
38
39
  - [Listing tags](#listing-tags)
@@ -145,11 +146,12 @@ Checkout this [live demo](https://codesandbox.io/p/sandbox/easy-template-x-demo-
145
146
 
146
147
  These are the plugins that comes bundled with `easy-template-x`:
147
148
 
148
- - [Simple text replacement plugin.](#text-plugin)
149
- - [Loop plugin for iterating text, table rows and list rows and for simple conditions.](#loop-plugin)
150
- - [Image plugin for embedding images.](#image-plugin)
151
- - [Link plugin for hyperlinks creation.](#link-plugin)
152
- - [Raw xml plugin for custom xml insertion.](#raw-xml-plugin)
149
+ - [Text plugin](#text-plugin) - For simple text replacement.
150
+ - [Loop plugin](#loop-plugin) - For iterating text, table rows, table columns and list rows and for simple conditions.
151
+ - [Image plugin](#image-plugin) - For embedding images.
152
+ - [Link plugin](#link-plugin) - For hyperlinks creation.
153
+ - [Chart plugin](#chart-plugin) - For handling charts.
154
+ - [Raw xml plugin](#raw-xml-plugin) - For custom xml insertion.
153
155
 
154
156
  ### Text plugin
155
157
 
@@ -282,7 +284,7 @@ The default heuristics are as follows:
282
284
  1. If both loop tags are inside the same table cell - the plugin assumes you want to repeat the **cell content**, not the row or column.
283
285
  2. If both loop tags are in the same column - the plugin will repeat the **column**.
284
286
  3. If both loop tags are inside a table - the plugin will repeat the relevant table **rows**.
285
- 4. If both loop tags are in list - the plugin will repeat the relevant **list items**.
287
+ 4. If both loop tags are in a list - the plugin will repeat the relevant **list items**.
286
288
  5. Otherwise - the plugin will use a naive approach for repeating the **content** in between the loop tags.
287
289
 
288
290
  ##### Changing the default
@@ -380,6 +382,192 @@ Output document:
380
382
 
381
383
  ![output document](./docs/assets/link-plugin-out.png?raw=true)
382
384
 
385
+ ### Chart plugin
386
+
387
+ To use charts in templates, put a placeholder chart and place a tag in its title, like so:
388
+
389
+ ![chart placeholder](./docs/assets/chart-placeholder.png?raw=true)
390
+
391
+ Generally speaking, the charts preserve their original settings and style with
392
+ some configurations also available through the input json data.
393
+
394
+ `easy-template-x` try to keep the same terminology used by MS Word. Therefore,
395
+ while the exact input data schema depends on the chart type, the main terms
396
+ are common to most:
397
+
398
+ - **Categories** are the values of the X axis.
399
+ - **Series** are the values of the Y axis.
400
+
401
+ Take a look at the examples below to get a better understanding of how chart
402
+ tags behave.
403
+
404
+ #### Line, bar & column charts
405
+
406
+ Line, bar & column charts all uses the same input data format.
407
+
408
+ The example below shows 4 charts in the same template: Line chart, Column chart, Bar chart and Stacked Column chart. In this example all of the charts use the same input data (the `MyChart` tag data) but you can of course use a different tag for each chart.
409
+
410
+ Notice how the end result ignores the placeholder data and matches our input data instead.
411
+
412
+ Note that you are not limited to use the same number of categories or series as the placeholder chart. This specific example uses less series than the placeholder (2 instead of 3) but you can just as easily add more series or change the number of categories.
413
+
414
+ Input template:
415
+
416
+ ![input template](./docs/assets/chart-plugin-line-in.png?raw=true)
417
+
418
+ Input data:
419
+
420
+ ```javascript
421
+ {
422
+ MyChart: {
423
+ _type: "chart",
424
+ title: "Easy Chart", // Optional
425
+ categories: {
426
+ names: ["Q1", "Q2", "Q3", "Q4"]
427
+ },
428
+ series: [
429
+ {
430
+ name: "Earnings", // Optional
431
+ color: "#34d399", // Optional
432
+ values: [100, 210, 150, 170]
433
+ },
434
+ {
435
+ name: "Expenses",
436
+ color: "#f87171",
437
+ values: [170, 165, 169, 155]
438
+ },
439
+ ],
440
+ }
441
+ }
442
+ ```
443
+
444
+ Output document:
445
+
446
+ ![output document](./docs/assets/chart-plugin-line-out.png?raw=true)
447
+
448
+ #### Pie & doughnut charts
449
+
450
+ Pie & doughnut uses the same input data format as line, bar and column chart,
451
+ except they expect a single series.
452
+
453
+ The example below shows 4 charts in the same template: 2 pie charts and 2 doughnut charts, each with a different style.
454
+
455
+ Input template:
456
+
457
+ ![input template](./docs/assets/chart-plugin-pie-in.png?raw=true)
458
+
459
+ Input data:
460
+
461
+ ```javascript
462
+ {
463
+ Chart1: {
464
+ _type: "chart",
465
+ title: "Easy Chart", // Optional
466
+ categories: {
467
+ names: ["Q1", "Q2", "Q3", "Q4"]
468
+ },
469
+ series: [
470
+ { values: [100, 210, 150, 170] },
471
+ ],
472
+ }
473
+ }
474
+ ```
475
+
476
+ Output document:
477
+
478
+ ![output document](./docs/assets/chart-plugin-pie-out.png?raw=true)
479
+
480
+ #### Scatter chart
481
+
482
+ Scatter chart do not have a `categories` property. Instead, each of their values requires an `x` and a `y` properties.
483
+
484
+ Input template:
485
+
486
+ ![input template](./docs/assets/chart-plugin-scatter-in.png?raw=true)
487
+
488
+ Input data:
489
+
490
+ ```javascript
491
+ {
492
+ scatter: {
493
+ _type: "chart",
494
+ title: "Easy Scatter Chart", // Optional
495
+ series: [
496
+ {
497
+ name: "Earnings", // Optional
498
+ color: "#34d399", // Optional
499
+ values: [
500
+ { x: 1, y: 310 },
501
+ { x: 3, y: 450 },
502
+ { x: 4, y: 200 },
503
+ { x: 6, y: 200 },
504
+ ],
505
+ },
506
+ {
507
+ name: "Expenses",
508
+ color: "#f87171",
509
+ values: [
510
+ { x: 1, y: 410 },
511
+ { x: 2, y: 450 },
512
+ { x: 3, y: 200 },
513
+ { x: 5, y: 350 },
514
+ ],
515
+ },
516
+ ],
517
+ }
518
+ }
519
+ ```
520
+
521
+ Output document:
522
+
523
+ ![output document](./docs/assets/chart-plugin-scatter-out.png?raw=true)
524
+
525
+ #### Bubble chart
526
+
527
+ Bubble charts are very similar to scatter charts but they have an additional
528
+ `size` property (notice the placeholder chart should be a bubble chart, not a
529
+ scatter chart).
530
+
531
+ Input template:
532
+
533
+ ![input template](./docs/assets/chart-plugin-bubble-in.png?raw=true)
534
+
535
+ Input data:
536
+
537
+ ```javascript
538
+ {
539
+ bubble: {
540
+ _type: "chart",
541
+ title: "Bubble Chart", // Optional
542
+ series: [
543
+ {
544
+ name: "Earnings", // Optional
545
+ color: "#34d399", // Optional
546
+ values: [
547
+ { x: 1, y: 10, size: 10 },
548
+ { x: 2, y: 10, size: 20 },
549
+ { x: 3, y: 8, size: 40 },
550
+ { x: 4, y: 8, size: 30 },
551
+ ],
552
+ },
553
+ {
554
+ name: "Expenses",
555
+ color: "#f87171",
556
+ values: [
557
+ { x: 1, y: 4, size: 40 },
558
+ { x: 2, y: 4, size: 20 },
559
+ { x: 3, y: 3, size: 30 },
560
+ ],
561
+ },
562
+ ],
563
+ }
564
+ }
565
+ ```
566
+
567
+ Output document:
568
+
569
+ ![output document](./docs/assets/chart-plugin-bubble-out.png?raw=true)
570
+
383
571
  ### Raw xml plugin
384
572
 
385
573
  Add custom xml into the document to be interpreted by Word.
@@ -419,6 +607,8 @@ _To better understand the internal structure of Word documents check out [this e
419
607
  Example plugin implementation ([source](./src/plugins/rawXml/rawXmlPlugin.ts)):
420
608
 
421
609
  ```typescript
610
+ import { officeMarkup, xml } from "easy-template-x";
611
+
422
612
  /**
423
613
  * A plugin that inserts raw xml to the document.
424
614
  */
@@ -429,24 +619,23 @@ export class RawXmlPlugin extends TemplatePlugin {
429
619
 
430
620
  // Plugin logic goes here:
431
621
  public simpleTagReplacements(tag: Tag, data: ScopeData): void {
432
-
433
- // Tag.xmlTextNode always reference the actual xml text node.
434
- // In MS Word each text node is wrapped by a <w:t> node so we retrieve that.
435
- const wordTextNode = this.utilities.docxParser.containingTextNode(tag.xmlTextNode);
436
-
622
+
437
623
  // Get the value to use from the input data.
438
- const value = data.getScopeData() as RawXmlContent;
624
+ const value = data.getScopeData<RawXmlContent>();
439
625
  if (value && typeof value.xml === 'string') {
440
626
 
441
- // If it contains a "xml" string property parse it and insert.
442
- const newNode = this.utilities.xmlParser.parse(value.xml);
443
- XmlNode.insertBefore(newNode, wordTextNode);
627
+ // Tag.xmlTextNode always reference the actual xml text node.
628
+ // In MS Word each text node is wrapped by a <w:t> node so we retrieve that.
629
+ const wordTextNode = officeMarkup.query.containingTextNode(tag.xmlTextNode);
630
+
631
+ // If the input data contains an "xml" string property, parse it and insert
632
+ // the content next to the placeholder tag.
633
+ const newNode = xml.parser.parse(value.xml);
634
+ xml.modify.insertBefore(newNode, wordTextNode);
444
635
  }
445
636
 
446
- // Remove the placeholder node.
447
- // We can be sure that only the placeholder is removed since easy-template-x
448
- // makes sure that each tag is isolated into it's own separate <w:t> node.
449
- XmlNode.remove(wordTextNode);
637
+ // Remove the placeholder tag.
638
+ officeMarkup.modify.removeTag(tag.xmlTextNode);
450
639
  }
451
640
  }
452
641
  ```