@adobe/helix-docx2md 1.3.14 → 1.4.1
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
|
+
## [1.4.1](https://github.com/adobe/helix-docx2md/compare/v1.4.0...v1.4.1) (2023-03-27)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Bug Fixes
|
|
5
|
+
|
|
6
|
+
* convert multi line inline code to code block ([#213](https://github.com/adobe/helix-docx2md/issues/213)) ([9c7d34f](https://github.com/adobe/helix-docx2md/commit/9c7d34fae02377eef39ee865f89924698a6e867f)), closes [#210](https://github.com/adobe/helix-docx2md/issues/210)
|
|
7
|
+
|
|
8
|
+
# [1.4.0](https://github.com/adobe/helix-docx2md/compare/v1.3.14...v1.4.0) (2023-02-16)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Features
|
|
12
|
+
|
|
13
|
+
* detect _top bookmark ([#197](https://github.com/adobe/helix-docx2md/issues/197)) ([029df1e](https://github.com/adobe/helix-docx2md/commit/029df1eafe74f918ca39b1a06fe6cc119e742a32))
|
|
14
|
+
|
|
1
15
|
## [1.3.14](https://github.com/adobe/helix-docx2md/compare/v1.3.13...v1.3.14) (2023-02-01)
|
|
2
16
|
|
|
3
17
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@adobe/helix-docx2md",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.4.1",
|
|
4
4
|
"description": "Helix library that converts word documents to markdown",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./src/index.js",
|
|
@@ -51,20 +51,20 @@
|
|
|
51
51
|
"yauzl": "2.10.0"
|
|
52
52
|
},
|
|
53
53
|
"devDependencies": {
|
|
54
|
-
"@adobe/eslint-config-helix": "2.0.
|
|
55
|
-
"@adobe/helix-mediahandler": "2.0.
|
|
56
|
-
"@semantic-release/changelog": "6.0.
|
|
54
|
+
"@adobe/eslint-config-helix": "2.0.2",
|
|
55
|
+
"@adobe/helix-mediahandler": "2.0.17",
|
|
56
|
+
"@semantic-release/changelog": "6.0.3",
|
|
57
57
|
"@semantic-release/exec": "6.0.3",
|
|
58
58
|
"@semantic-release/git": "10.0.1",
|
|
59
|
-
"c8": "7.
|
|
59
|
+
"c8": "7.13.0",
|
|
60
60
|
"dotenv": "16.0.3",
|
|
61
|
-
"eslint": "8.
|
|
61
|
+
"eslint": "8.36.0",
|
|
62
62
|
"husky": "8.0.3",
|
|
63
63
|
"junit-report-builder": "3.0.1",
|
|
64
|
-
"lint-staged": "13.
|
|
64
|
+
"lint-staged": "13.2.0",
|
|
65
65
|
"mocha": "10.2.0",
|
|
66
66
|
"mocha-multi-reporters": "1.5.1",
|
|
67
|
-
"semantic-release": "
|
|
67
|
+
"semantic-release": "20.1.3",
|
|
68
68
|
"unist-util-inspect": "7.0.2"
|
|
69
69
|
},
|
|
70
70
|
"lint-staged": {
|
|
@@ -104,11 +104,13 @@ export default async function dast2mdast(tree, opts = {}) {
|
|
|
104
104
|
const slugger = new IDSlugger();
|
|
105
105
|
for (const bm of bookmarks) {
|
|
106
106
|
if (!bm.target) {
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
107
|
+
if (bm.name !== '_top') {
|
|
108
|
+
// eslint-disable-next-line no-continue
|
|
109
|
+
continue;
|
|
110
|
+
}
|
|
111
|
+
bm.id = '';
|
|
112
|
+
} else if (bm.target.type === 'heading') {
|
|
113
|
+
// if heading, create an ID from its text
|
|
112
114
|
const text = toString(bm.target).trim();
|
|
113
115
|
bm.id = slugger.slug(text || 'heading');
|
|
114
116
|
bm.target.id = bm.id;
|
|
@@ -73,6 +73,103 @@ function isBlockquote(node) {
|
|
|
73
73
|
return styleName && styleName.toLowerCase() === 'quote';
|
|
74
74
|
}
|
|
75
75
|
|
|
76
|
+
function findFrom(nodes, start, pred) {
|
|
77
|
+
let idx = start;
|
|
78
|
+
while (idx < nodes.length) {
|
|
79
|
+
if (pred(nodes[idx])) {
|
|
80
|
+
return idx;
|
|
81
|
+
}
|
|
82
|
+
idx += 1;
|
|
83
|
+
}
|
|
84
|
+
return -1;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* For each paragraph, check if there is an (inlinecode br+ inlincode) sequence and promote them
|
|
89
|
+
* to codeblocks at the container level.
|
|
90
|
+
* @param ret
|
|
91
|
+
*/
|
|
92
|
+
function collapseInlineCode(ret, prev) {
|
|
93
|
+
for (let p = 0; p < ret.length; p += 1) {
|
|
94
|
+
const { type, children } = ret[p];
|
|
95
|
+
if (type === 'paragraph') {
|
|
96
|
+
for (let i = 0; i < children.length; i += 1) {
|
|
97
|
+
const next = findFrom(children, i, (n) => n.type === 'inlineCode');
|
|
98
|
+
if (next < 0) {
|
|
99
|
+
break;
|
|
100
|
+
}
|
|
101
|
+
// there should be at least 3 nodes remaining, otherwise we keep the inline code
|
|
102
|
+
if (children.length - next < 3) {
|
|
103
|
+
break;
|
|
104
|
+
}
|
|
105
|
+
// if previous node is a break, this is might be the start of a code block
|
|
106
|
+
if (next === 0 || children[next - 1].type === 'break') {
|
|
107
|
+
// find first non codeish
|
|
108
|
+
const last = findFrom(children, next + 1, (n) => n.type !== 'inlineCode' && n.type !== 'break');
|
|
109
|
+
if (last < 0 || children[last - 1].type === 'break') {
|
|
110
|
+
// detected a codeblock... split the paragraph
|
|
111
|
+
if (next > 0) {
|
|
112
|
+
// move first chunk to new paragraph
|
|
113
|
+
const kids = children.splice(0, next);
|
|
114
|
+
while (kids[kids.length - 1].type === 'break') {
|
|
115
|
+
kids.pop();
|
|
116
|
+
}
|
|
117
|
+
ret.splice(p, 0, {
|
|
118
|
+
type: 'paragraph',
|
|
119
|
+
children: kids,
|
|
120
|
+
});
|
|
121
|
+
p += 1;
|
|
122
|
+
}
|
|
123
|
+
if (last < 0) {
|
|
124
|
+
// entire paragraph is code block
|
|
125
|
+
ret.splice(p, 1, {
|
|
126
|
+
type: 'code',
|
|
127
|
+
value: toString(ret[p]).trimEnd(),
|
|
128
|
+
});
|
|
129
|
+
break;
|
|
130
|
+
}
|
|
131
|
+
// create code block
|
|
132
|
+
const codeblock = last < 0 ? children : children.splice(0, last - next);
|
|
133
|
+
ret.splice(p, 0, {
|
|
134
|
+
type: 'code',
|
|
135
|
+
value: toString({ children: codeblock }).trimEnd(),
|
|
136
|
+
});
|
|
137
|
+
p += 1;
|
|
138
|
+
i = -1;
|
|
139
|
+
} else {
|
|
140
|
+
// look for more
|
|
141
|
+
i = last;
|
|
142
|
+
}
|
|
143
|
+
} else {
|
|
144
|
+
// otherwise look for more
|
|
145
|
+
i = next;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
// merge with previous if needed
|
|
150
|
+
if (children.length && children.findIndex((n) => n.type !== 'inlineCode' && n.type !== 'break') < 0) {
|
|
151
|
+
// eslint-disable-next-line no-param-reassign
|
|
152
|
+
ret[p].singleLineCode = true;
|
|
153
|
+
if (p === 0 && prev.singleLineCode) {
|
|
154
|
+
if (prev.type === 'paragraph') {
|
|
155
|
+
// eslint-disable-next-line no-param-reassign
|
|
156
|
+
prev.type = 'code';
|
|
157
|
+
// eslint-disable-next-line no-param-reassign
|
|
158
|
+
prev.value = `${toString(prev)}\n${toString(ret[p])}`;
|
|
159
|
+
// eslint-disable-next-line no-param-reassign
|
|
160
|
+
delete prev.children;
|
|
161
|
+
} else {
|
|
162
|
+
// eslint-disable-next-line no-param-reassign
|
|
163
|
+
prev.value += `\n${toString(ret[p])}`;
|
|
164
|
+
}
|
|
165
|
+
ret.splice(p, 1);
|
|
166
|
+
p -= 1;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
|
|
76
173
|
export default function paragraph(h, node, parent, siblings) {
|
|
77
174
|
const { children } = node;
|
|
78
175
|
const nodes = all(h, node);
|
|
@@ -184,12 +281,13 @@ export default function paragraph(h, node, parent, siblings) {
|
|
|
184
281
|
}
|
|
185
282
|
|
|
186
283
|
// check for codeblock
|
|
284
|
+
const prev = siblings.length > 0 ? siblings[siblings.length - 1] : {};
|
|
187
285
|
if (isCodeBlock(node)) {
|
|
188
286
|
const text = toString({ children: nodes });
|
|
189
287
|
// check if previous sibling was code block
|
|
190
|
-
if (
|
|
288
|
+
if (prev.type === 'code') {
|
|
191
289
|
// eslint-disable-next-line no-param-reassign
|
|
192
|
-
|
|
290
|
+
prev.value += `\n${text}`;
|
|
193
291
|
return undefined;
|
|
194
292
|
}
|
|
195
293
|
return h('code', text);
|
|
@@ -257,6 +355,9 @@ export default function paragraph(h, node, parent, siblings) {
|
|
|
257
355
|
ret.push(h('paragraph', nodes));
|
|
258
356
|
}
|
|
259
357
|
|
|
358
|
+
// for each paragraph, find groups of inline code that could form a code block
|
|
359
|
+
collapseInlineCode(ret, prev);
|
|
360
|
+
|
|
260
361
|
// check for block quote
|
|
261
362
|
if (isBlockquote(node)) {
|
|
262
363
|
return h('blockquote', ret);
|
|
@@ -50,17 +50,15 @@ export default function run(h, node, parent, siblings) {
|
|
|
50
50
|
}
|
|
51
51
|
|
|
52
52
|
if (isInlineCode(node)) {
|
|
53
|
-
const isBreak = nodes.find((n) => n.type === 'break');
|
|
54
53
|
const text = toString({ children: nodes });
|
|
54
|
+
const lines = text.split(/(\n)/);
|
|
55
55
|
const prev = siblings.length > 0 ? siblings[siblings.length - 1] : {};
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
prev.type = 'code';
|
|
59
|
-
}
|
|
60
|
-
prev.value += text;
|
|
61
|
-
return undefined;
|
|
56
|
+
while (lines.length > 0 && lines[0] !== '\n' && prev.type === 'inlineCode') {
|
|
57
|
+
prev.value += lines.shift();
|
|
62
58
|
}
|
|
63
|
-
return
|
|
59
|
+
return lines
|
|
60
|
+
.filter((value) => !!value)
|
|
61
|
+
.map((value) => ({ type: value === '\n' ? 'break' : 'inlineCode', value }));
|
|
64
62
|
}
|
|
65
63
|
|
|
66
64
|
let result = nodes;
|