@adobe/helix-md2docx 2.1.77 → 2.1.79

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/CHANGELOG.md CHANGED
@@ -1,3 +1,17 @@
1
+ ## [2.1.79](https://github.com/adobe/helix-md2docx/compare/v2.1.78...v2.1.79) (2024-10-16)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * **deps:** update dependency docx to v9 ([#495](https://github.com/adobe/helix-md2docx/issues/495)) ([88808e0](https://github.com/adobe/helix-md2docx/commit/88808e0f7a1b1aafb2f8a6a5d39607f1a3315398))
7
+
8
+ ## [2.1.78](https://github.com/adobe/helix-md2docx/compare/v2.1.77...v2.1.78) (2024-10-15)
9
+
10
+
11
+ ### Bug Fixes
12
+
13
+ * don't create bookmarks if heading is not referenced ([656e792](https://github.com/adobe/helix-md2docx/commit/656e792d3f31a0731c72fac9583d370cbf3a2a5d)), closes [#492](https://github.com/adobe/helix-md2docx/issues/492)
14
+
1
15
  ## [2.1.77](https://github.com/adobe/helix-md2docx/compare/v2.1.76...v2.1.77) (2024-09-30)
2
16
 
3
17
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adobe/helix-md2docx",
3
- "version": "2.1.77",
3
+ "version": "2.1.79",
4
4
  "description": "Helix Service that converts markdown to word documents",
5
5
  "main": "src/index.js",
6
6
  "type": "module",
@@ -9,7 +9,7 @@
9
9
  "lint": "eslint .",
10
10
  "semantic-release": "semantic-release",
11
11
  "semantic-release-dry": "semantic-release --dry-run --branches $CI_BRANCH",
12
- "prepare": "husky install"
12
+ "prepare": "husky"
13
13
  },
14
14
  "mocha": {
15
15
  "spec": "test/*.test.js",
@@ -33,7 +33,7 @@
33
33
  "@adobe/helix-markdown-support": "7.1.6",
34
34
  "@adobe/helix-shared-process-queue": "3.0.4",
35
35
  "@adobe/remark-gridtables": "3.0.6",
36
- "docx": "8.5.0",
36
+ "docx": "9.0.2",
37
37
  "github-slugger": "2.0.0",
38
38
  "hast-util-is-element": "3.0.0",
39
39
  "hast-util-to-mdast": "10.1.0",
@@ -47,8 +47,8 @@
47
47
  "unist-util-visit": "5.0.0"
48
48
  },
49
49
  "devDependencies": {
50
- "@adobe/eslint-config-helix": "2.0.7",
51
- "@adobe/helix-mediahandler": "2.5.23",
50
+ "@adobe/eslint-config-helix": "2.0.8",
51
+ "@adobe/helix-mediahandler": "2.5.26",
52
52
  "@semantic-release/changelog": "6.0.3",
53
53
  "@semantic-release/exec": "6.0.3",
54
54
  "@semantic-release/git": "10.0.1",
@@ -57,7 +57,7 @@
57
57
  "eslint": "8.57.1",
58
58
  "eslint-import-resolver-exports": "1.0.0-beta.5",
59
59
  "eslint-plugin-header": "3.1.1",
60
- "eslint-plugin-import": "2.30.0",
60
+ "eslint-plugin-import": "2.31.0",
61
61
  "husky": "9.1.6",
62
62
  "junit-report-builder": "5.1.1",
63
63
  "lint-staged": "15.2.10",
@@ -9,10 +9,7 @@
9
9
  * OF ANY KIND, either express or implied. See the License for the specific language
10
10
  * governing permissions and limitations under the License.
11
11
  */
12
- import {
13
- Drawing, ImageRun, XmlComponent, XmlAttributeComponent,
14
- } from 'docx';
15
- import { findXMLComponent } from '../utils.js';
12
+ import { ImageRun } from 'docx';
16
13
 
17
14
  // max image width (6.5") and height (2")
18
15
  const LIMITS = {
@@ -31,6 +28,7 @@ export default async function image(ctx, node) {
31
28
  if (!data) {
32
29
  return undefined;
33
30
  }
31
+
34
32
  let x = data.dimensions.width * 9525;
35
33
  let y = data.dimensions.height * 9525;
36
34
  const limits = ctx.tableAlign ? LIMITS_TABLE : LIMITS;
@@ -43,127 +41,28 @@ export default async function image(ctx, node) {
43
41
  y = limits.height;
44
42
  }
45
43
 
46
- const imageData = {
47
- stream: data.buffer,
48
- fileName: data.key,
44
+ const options = {
45
+ type: data.dimensions.type || 'png',
46
+ data: data.buffer,
49
47
  transformation: {
50
- pixels: {
51
- x: Math.round(data.dimensions.width),
52
- y: Math.round(data.dimensions.height),
53
- },
54
- emus: {
55
- x,
56
- y,
57
- },
48
+ width: Math.max(x / 9525, 32),
49
+ height: Math.max(y / 9525, 32),
58
50
  },
59
- };
60
-
61
- const drawing = new Drawing(imageData, {
62
- floating: false,
63
- docProperties: {
51
+ altText: {
64
52
  title: node.title || '',
65
53
  description: node.alt || '',
66
54
  name: node.title || node.alt || '',
67
55
  },
68
- });
69
-
70
- // create picture
71
- const pic = new ImageRun({
72
- data: data.buffer,
73
- transformation: data.dimensions,
74
- });
75
- // replace drawing
76
- const oldDrawing = findXMLComponent(pic, 'w:drawing');
77
- const idx = pic.root.indexOf(oldDrawing);
78
- if (idx >= 0) {
79
- pic.root.splice(idx, 1);
80
- }
81
- pic.root.push(drawing);
82
- pic.key = data.key;
83
- pic.imageData = imageData;
84
-
85
- // for SVGs, we need to generate a proper svgBlip
86
- /*
87
- <pic:blipFill>
88
- <a:blip r:embed="rId4">
89
- <a:extLst>
90
- <a:ext uri="{28A0092B-C50C-407E-A947-70E740481C1C}">
91
- <a14:useLocalDpi val="0" xmlns:a14="http://schemas.microsoft.com/office/drawing/2010/main"/>
92
- </a:ext>
93
- <a:ext uri="{96DAC541-7B7A-43D3-8B79-37D633B846F1}">
94
- <asvg:svgBlip r:embed="rId5" xmlns:asvg="http://schemas.microsoft.com/office/drawing/2016/SVG/main"/>
95
- </a:ext>
96
- </a:extLst>
97
- </a:blip>
98
- <a:stretch>
99
- <a:fillRect/>
100
- </a:stretch>
101
- </pic:blipFill>
102
- */
103
-
104
- class SvgBlip extends XmlComponent {
105
- constructor(imgData) {
106
- super('asvg:svgBlip');
107
- this.imageData = imgData;
108
- this.addChildElement(new XmlAttributeComponent({
109
- 'xmlns:asvg': 'http://schemas.microsoft.com/office/drawing/2016/SVG/main',
110
- 'r:embed': `rId{${imgData.fileName}}`,
111
- }));
112
- }
113
-
114
- prepForXml(context) {
115
- // add the svg data if it has a stream
116
- if (this.imageData.stream) {
117
- context.file.Media.addImage(this.imageData.fileName, this.imageData);
118
- }
56
+ };
119
57
 
120
- // add svg content type if missing
121
- if (!context.file.contentTypes.root.find((entry) => entry.rootKey === 'Default'
122
- && (entry.root[0].root.extension === 'svg' || entry.root[0].root.Extension === 'svg'))) {
123
- context.file.contentTypes.root.push(new XmlComponent('Default').addChildElement(new XmlAttributeComponent({
124
- ContentType: 'image/svg+xml',
125
- Extension: 'svg',
126
- })));
127
- }
128
- return super.prepForXml(context);
129
- }
58
+ if (data.originalType === 'image/svg' || data.originalType === 'image/svg+xml') {
59
+ options.type = 'svg';
60
+ options.data = data.originalBuffer;
61
+ options.fallback = {
62
+ type: data.ext,
63
+ data: data.buffer,
64
+ };
130
65
  }
131
66
 
132
- if (data.originalType === 'image/svg') {
133
- // create a fake image run for the svg image
134
- const ir = new ImageRun({
135
- data: data.originalBuffer,
136
- transformation: data.dimensions,
137
- });
138
- ir.imageData.fileName = data.svgKey;
139
-
140
- const blipFill = findXMLComponent(drawing, 'wp:inline/a:graphic/a:graphicData/pic:pic/pic:blipFill');
141
- const blip = findXMLComponent(blipFill, 'a:blip');
142
-
143
- // const blipAttrs = findXMLComponent(oldBlip, '_attr');
144
- // blipAttrs.root.embed = `rId{${ir.imageData.fileName}}`;
145
-
146
- // add svg stuff
147
- // const newBlip = new XmlComponent('a:blip')
148
- blip
149
- .addChildElement(new XmlComponent('a:extLst')
150
- .addChildElement(new XmlComponent('a:ext')
151
- .addChildElement(new XmlAttributeComponent({
152
- uri: '{28A0092B-C50C-407E-A947-70E740481C1C}',
153
- }))
154
- .addChildElement(new XmlComponent('a14:useLocalDpi')
155
- .addChildElement(new XmlAttributeComponent({
156
- 'xmlns:a14': 'http://schemas.microsoft.com/office/drawing/2010/main',
157
- val: '0',
158
- }))))
159
- .addChildElement(new XmlComponent('a:ext')
160
- .addChildElement(new XmlAttributeComponent({
161
- uri: '{96DAC541-7B7A-43D3-8B79-37D633B846F1}',
162
- }))
163
- .addChildElement(new SvgBlip(ir.imageData))));
164
-
165
- // replace blip
166
- // blipFill.root.splice(blipFill.root.indexOf(oldBlip), 1, newBlip);
167
- }
168
- return pic;
67
+ return new ImageRun(options);
169
68
  }
@@ -46,7 +46,20 @@ export function buildAnchors(tree) {
46
46
  const track = (url) => {
47
47
  let ref = tracking[url];
48
48
  if (!ref) {
49
- ref = { links: [], heading: null, bookmark: null };
49
+ ref = {
50
+ /**
51
+ * links that use this `url`
52
+ */
53
+ links: [],
54
+ /**
55
+ * heading that is anchored at this `url`
56
+ */
57
+ heading: null,
58
+ /**
59
+ * bookmark that is anchored at this `url`
60
+ */
61
+ bookmark: null,
62
+ };
50
63
  tracking[url] = ref;
51
64
  }
52
65
  return ref;
@@ -75,7 +88,7 @@ export function buildAnchors(tree) {
75
88
  const anchors = {};
76
89
  Object.keys(tracking).forEach((k) => {
77
90
  const ref = tracking[k];
78
- if (ref.heading) {
91
+ if (ref.heading && ref.links.length) {
79
92
  // ms-word heading bookmark algorithm
80
93
  const words = toString(ref.heading).split(/\s+/).slice(0, 3);
81
94
  let anchor = `_${words.join('_')}`.substring(0, 36);
@@ -88,8 +101,10 @@ export function buildAnchors(tree) {
88
101
  }
89
102
  anchors[anchor] = 0;
90
103
 
104
+ // remember word-specific anchor for heading
91
105
  ref.heading.anchor = anchor;
92
106
  for (const link of ref.links) {
107
+ // change links to reference word-specific anchor
93
108
  link.anchor = anchor;
94
109
  }
95
110
  } else if (ref.bookmark) {