@adobe/helix-md2docx 2.0.2 → 2.0.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/CHANGELOG.md +14 -0
- package/package.json +3 -3
- package/src/mdast2docx/handlers/gridTable.js +85 -0
- package/src/mdast2docx/handlers/gtRow.js +23 -0
- package/src/mdast2docx/handlers/index.js +9 -0
- package/src/mdast2docx/handlers/paragraph.js +2 -1
- package/src/mdast2docx/handlers/tableCell.js +19 -13
- package/src/mdast2docx/handlers/text.js +4 -7
- package/src/mdast2docx/utils.js +15 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,17 @@
|
|
|
1
|
+
## [2.0.4](https://github.com/adobe/helix-md2docx/compare/v2.0.3...v2.0.4) (2022-09-27)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Bug Fixes
|
|
5
|
+
|
|
6
|
+
* add support for gridtables ([#141](https://github.com/adobe/helix-md2docx/issues/141)) ([a5a3952](https://github.com/adobe/helix-md2docx/commit/a5a39527891504f04dafc932d7dd65caf47e8b6a))
|
|
7
|
+
|
|
8
|
+
## [2.0.3](https://github.com/adobe/helix-md2docx/compare/v2.0.2...v2.0.3) (2022-09-27)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Bug Fixes
|
|
12
|
+
|
|
13
|
+
* **deps:** update dependency @adobe/helix-docx2md to v1.1.2 ([#140](https://github.com/adobe/helix-md2docx/issues/140)) ([8a20252](https://github.com/adobe/helix-md2docx/commit/8a20252aad5567488c464c9694e3627f787d359b))
|
|
14
|
+
|
|
1
15
|
## [2.0.2](https://github.com/adobe/helix-md2docx/compare/v2.0.1...v2.0.2) (2022-09-24)
|
|
2
16
|
|
|
3
17
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@adobe/helix-md2docx",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.4",
|
|
4
4
|
"description": "Helix Service that converts markdown to word documents",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
"homepage": "https://github.com/adobe/helix-md2docx#readme",
|
|
29
29
|
"dependencies": {
|
|
30
30
|
"@adobe/fetch": "3.1.4",
|
|
31
|
-
"@adobe/helix-docx2md": "1.1.
|
|
31
|
+
"@adobe/helix-docx2md": "1.1.2",
|
|
32
32
|
"@adobe/helix-markdown-support": "5.0.7",
|
|
33
33
|
"@adobe/helix-shared-process-queue": "1.1.5",
|
|
34
34
|
"docx": "7.5.0",
|
|
@@ -44,7 +44,7 @@
|
|
|
44
44
|
},
|
|
45
45
|
"devDependencies": {
|
|
46
46
|
"@adobe/eslint-config-helix": "1.3.2",
|
|
47
|
-
"@adobe/helix-mediahandler": "1.2.
|
|
47
|
+
"@adobe/helix-mediahandler": "1.2.5",
|
|
48
48
|
"@semantic-release/changelog": "6.0.1",
|
|
49
49
|
"@semantic-release/exec": "6.0.3",
|
|
50
50
|
"@semantic-release/git": "10.0.1",
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2022 Adobe. All rights reserved.
|
|
3
|
+
* This file is licensed to you under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
* you may not use this file except in compliance with the License. You may obtain a copy
|
|
5
|
+
* of the License at http://www.apache.org/licenses/LICENSE-2.0
|
|
6
|
+
*
|
|
7
|
+
* Unless required by applicable law or agreed to in writing, software distributed under
|
|
8
|
+
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
|
|
9
|
+
* OF ANY KIND, either express or implied. See the License for the specific language
|
|
10
|
+
* governing permissions and limitations under the License.
|
|
11
|
+
*/
|
|
12
|
+
import docx from 'docx';
|
|
13
|
+
import all from '../all.js';
|
|
14
|
+
|
|
15
|
+
const { Paragraph, Table, WidthType } = docx;
|
|
16
|
+
|
|
17
|
+
function* rowIter(node) {
|
|
18
|
+
for (const child of node.children) {
|
|
19
|
+
if (child.type === 'gtRow') {
|
|
20
|
+
yield child;
|
|
21
|
+
} else {
|
|
22
|
+
for (const grandChild of child.children) {
|
|
23
|
+
yield grandChild;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// see http://officeopenxml.com/WPtableWidth.php
|
|
30
|
+
// Note: The 2006 version of the OOXML standard specified that the value was to be a decimal.
|
|
31
|
+
// When type="pct", the value was interpreted as fifths of a percent, so 4975=99.5%,
|
|
32
|
+
// and no % symbol was included in the attribute. In the 2011 version the value can be either a
|
|
33
|
+
// decimal or a percent, so a % symbol should be included when type="pct".
|
|
34
|
+
|
|
35
|
+
export default async function gridTable(ctx, node) {
|
|
36
|
+
let maxCols = 1;
|
|
37
|
+
|
|
38
|
+
// need to calculate the number of columns beforehand, for nested tables
|
|
39
|
+
// compute the number of cells in each row, respecting the row and col spans.
|
|
40
|
+
const pendingRowSpans = [];
|
|
41
|
+
for (const row of rowIter(node)) {
|
|
42
|
+
let numCols = pendingRowSpans.shift() || 0;
|
|
43
|
+
for (const cell of row.children) {
|
|
44
|
+
const rowSpan = Number.parseInt(cell.data?.rowSpan || '1', 10);
|
|
45
|
+
const colSpan = Number.parseInt(cell.data?.colSpan || '1', 10);
|
|
46
|
+
numCols += colSpan;
|
|
47
|
+
if (rowSpan > 1) {
|
|
48
|
+
for (let i = 0; i < rowSpan - 1; i += 1) {
|
|
49
|
+
pendingRowSpans[i] = (pendingRowSpans[i] || 0) + colSpan;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
maxCols = Math.max(maxCols, numCols);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
const oldTable = ctx.table;
|
|
57
|
+
ctx.table = {
|
|
58
|
+
// remember the table width
|
|
59
|
+
// default width: Letter Width - Margin = 8.5" - 2" = 6.5". the unit is 1/1440 inches.
|
|
60
|
+
width: oldTable?.columnWidth || 1440 * 6.5,
|
|
61
|
+
align: node.align || [],
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
// use the same width for all columns
|
|
65
|
+
ctx.table.columnWidth = maxCols ? (ctx.table.width / maxCols) : ctx.table.width;
|
|
66
|
+
const columnWidths = new Array(maxCols).fill(Math.round(ctx.table.columnWidth));
|
|
67
|
+
|
|
68
|
+
// process the rows
|
|
69
|
+
const rows = await all(ctx, node);
|
|
70
|
+
|
|
71
|
+
ctx.table = oldTable;
|
|
72
|
+
|
|
73
|
+
const tbl = new Table({
|
|
74
|
+
style: 'PageBlock',
|
|
75
|
+
rows,
|
|
76
|
+
columnWidths,
|
|
77
|
+
width: {
|
|
78
|
+
size: 100,
|
|
79
|
+
type: WidthType.PERCENTAGE,
|
|
80
|
+
},
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
// add empty paragraph for better separation in word
|
|
84
|
+
return [tbl, new Paragraph([])];
|
|
85
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2022 Adobe. All rights reserved.
|
|
3
|
+
* This file is licensed to you under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
* you may not use this file except in compliance with the License. You may obtain a copy
|
|
5
|
+
* of the License at http://www.apache.org/licenses/LICENSE-2.0
|
|
6
|
+
*
|
|
7
|
+
* Unless required by applicable law or agreed to in writing, software distributed under
|
|
8
|
+
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
|
|
9
|
+
* OF ANY KIND, either express or implied. See the License for the specific language
|
|
10
|
+
* governing permissions and limitations under the License.
|
|
11
|
+
*/
|
|
12
|
+
import docx from 'docx';
|
|
13
|
+
import all from '../all.js';
|
|
14
|
+
|
|
15
|
+
const { TableRow } = docx;
|
|
16
|
+
|
|
17
|
+
export default async function gridTableRow(ctx, node, parent) {
|
|
18
|
+
const children = await all(ctx, node);
|
|
19
|
+
return new TableRow({
|
|
20
|
+
children,
|
|
21
|
+
tableHeader: parent.type === 'gtHeader' ? true : undefined,
|
|
22
|
+
});
|
|
23
|
+
}
|
|
@@ -28,6 +28,9 @@ import tableRow from './tableRow.js';
|
|
|
28
28
|
import tableCell from './tableCell.js';
|
|
29
29
|
import text from './text.js';
|
|
30
30
|
import thematicBreak from './thematicBreak.js';
|
|
31
|
+
import gridTable from './gridTable.js';
|
|
32
|
+
import gtRow from './gtRow.js';
|
|
33
|
+
import all from '../all.js';
|
|
31
34
|
|
|
32
35
|
export default {
|
|
33
36
|
blockquote: paragraphStyle('Quote'),
|
|
@@ -53,4 +56,10 @@ export default {
|
|
|
53
56
|
tableCell,
|
|
54
57
|
text,
|
|
55
58
|
thematicBreak,
|
|
59
|
+
gridTable,
|
|
60
|
+
gtRow,
|
|
61
|
+
gtHeader: all,
|
|
62
|
+
gtFooter: all,
|
|
63
|
+
gtBody: all,
|
|
64
|
+
gtCell: tableCell,
|
|
56
65
|
};
|
|
@@ -14,7 +14,7 @@ import all from '../all.js';
|
|
|
14
14
|
|
|
15
15
|
const { Paragraph } = docx;
|
|
16
16
|
|
|
17
|
-
export default async function paragraph(ctx, node) {
|
|
17
|
+
export default async function paragraph(ctx, node, parent) {
|
|
18
18
|
// clear style
|
|
19
19
|
ctx.style = {};
|
|
20
20
|
|
|
@@ -29,6 +29,7 @@ export default async function paragraph(ctx, node) {
|
|
|
29
29
|
const children = await all(ctx, node);
|
|
30
30
|
const opts = {
|
|
31
31
|
children,
|
|
32
|
+
alignment: parent.alignment,
|
|
32
33
|
};
|
|
33
34
|
|
|
34
35
|
if (ctx.listLevel >= 0) {
|
|
@@ -11,20 +11,30 @@
|
|
|
11
11
|
*/
|
|
12
12
|
import docx from 'docx';
|
|
13
13
|
import all from '../all.js';
|
|
14
|
+
import { removeUndefined } from '../utils.js';
|
|
14
15
|
|
|
15
16
|
const {
|
|
16
|
-
AlignmentType, Paragraph, Table, TableCell, ShadingType,
|
|
17
|
+
AlignmentType, Paragraph, Table, TableCell, ShadingType, VerticalAlign,
|
|
17
18
|
} = docx;
|
|
18
19
|
|
|
19
20
|
const ALIGN = {
|
|
20
21
|
left: null,
|
|
21
22
|
right: AlignmentType.RIGHT,
|
|
22
23
|
center: AlignmentType.CENTER,
|
|
24
|
+
justify: AlignmentType.JUSTIFIED,
|
|
25
|
+
distribute: AlignmentType.DISTRIBUTE,
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
const V_ALIGN = {
|
|
29
|
+
top: VerticalAlign.TOP,
|
|
30
|
+
middle: VerticalAlign.CENTER,
|
|
31
|
+
bottom: VerticalAlign.BOTTOM,
|
|
23
32
|
};
|
|
24
33
|
|
|
25
34
|
export default async function tableCell(ctx, node, parent, siblings) {
|
|
35
|
+
// eslint-disable-next-line no-param-reassign
|
|
36
|
+
node.alignment = ALIGN[node.align || ctx.table.align?.[siblings.length]];
|
|
26
37
|
const children = await all(ctx, node);
|
|
27
|
-
const alignment = ALIGN[ctx.table.align[siblings.length]];
|
|
28
38
|
|
|
29
39
|
const content = [];
|
|
30
40
|
let leaves = [];
|
|
@@ -33,7 +43,7 @@ export default async function tableCell(ctx, node, parent, siblings) {
|
|
|
33
43
|
const child = children[i];
|
|
34
44
|
if ((child instanceof Paragraph) || (child instanceof Table)) {
|
|
35
45
|
if (leaves.length) {
|
|
36
|
-
content.push(new Paragraph({ alignment, children: leaves }));
|
|
46
|
+
content.push(new Paragraph({ alignment: node.alignment, children: leaves }));
|
|
37
47
|
}
|
|
38
48
|
content.push(child);
|
|
39
49
|
leaves = [];
|
|
@@ -42,19 +52,15 @@ export default async function tableCell(ctx, node, parent, siblings) {
|
|
|
42
52
|
}
|
|
43
53
|
}
|
|
44
54
|
if (leaves.length) {
|
|
45
|
-
content.push(new Paragraph({ alignment, children: leaves }));
|
|
55
|
+
content.push(new Paragraph({ alignment: node.alignment, children: leaves }));
|
|
46
56
|
}
|
|
47
57
|
|
|
48
|
-
const opts = {
|
|
58
|
+
const opts = removeUndefined({
|
|
49
59
|
children: content,
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
}
|
|
55
|
-
if (node.data?.rowSpan) {
|
|
56
|
-
opts.rowSpan = node.data.rowSpan;
|
|
57
|
-
}
|
|
60
|
+
verticalAlign: V_ALIGN[node.valign],
|
|
61
|
+
columnSpan: node.data?.colSpan ?? node.colSpan,
|
|
62
|
+
rowSpan: node.data?.rowSpan ?? node.rowSpan,
|
|
63
|
+
});
|
|
58
64
|
|
|
59
65
|
if (parent.tableHeader) {
|
|
60
66
|
// shading for header row
|
|
@@ -14,11 +14,8 @@ import docx from 'docx';
|
|
|
14
14
|
const { TextRun } = docx;
|
|
15
15
|
|
|
16
16
|
export default function textNode(ctx, node) {
|
|
17
|
-
return
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
break: idx > 0 ? 1 : 0,
|
|
22
|
-
})
|
|
23
|
-
));
|
|
17
|
+
return new TextRun({
|
|
18
|
+
...ctx.style,
|
|
19
|
+
text: node.value,
|
|
20
|
+
});
|
|
24
21
|
}
|
package/src/mdast2docx/utils.js
CHANGED
|
@@ -27,3 +27,18 @@ export function findXMLComponent(root, path) {
|
|
|
27
27
|
}
|
|
28
28
|
return comp;
|
|
29
29
|
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* removes undefined and null properties from the given object.
|
|
33
|
+
* @param {object} obj
|
|
34
|
+
* @returns {object}
|
|
35
|
+
*/
|
|
36
|
+
export function removeUndefined(obj) {
|
|
37
|
+
for (const key of Object.keys(obj)) {
|
|
38
|
+
if (obj[key] === undefined || obj[key] === null) {
|
|
39
|
+
// eslint-disable-next-line no-param-reassign
|
|
40
|
+
delete obj[key];
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
return obj;
|
|
44
|
+
}
|