@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.14",
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.1",
55
- "@adobe/helix-mediahandler": "2.0.5",
56
- "@semantic-release/changelog": "6.0.2",
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.12.0",
59
+ "c8": "7.13.0",
60
60
  "dotenv": "16.0.3",
61
- "eslint": "8.32.0",
61
+ "eslint": "8.36.0",
62
62
  "husky": "8.0.3",
63
63
  "junit-report-builder": "3.0.1",
64
- "lint-staged": "13.1.0",
64
+ "lint-staged": "13.2.0",
65
65
  "mocha": "10.2.0",
66
66
  "mocha-multi-reporters": "1.5.1",
67
- "semantic-release": "19.0.5",
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
- // eslint-disable-next-line no-continue
108
- continue;
109
- }
110
- // if heading, create an ID from its text
111
- if (bm.target.type === 'heading') {
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 (siblings.length > 0 && siblings[siblings.length - 1].type === 'code') {
288
+ if (prev.type === 'code') {
191
289
  // eslint-disable-next-line no-param-reassign
192
- siblings[siblings.length - 1].value += `\n${text}`;
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
- if (prev.type === 'inlineCode' || prev.type === 'code') {
57
- if (isBreak) {
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 h('inlineCode', { value: text });
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;