@link-assistant/web-capture 1.7.18 → 1.7.19
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 +6 -0
- package/package.json +1 -1
- package/src/gdocs-preprocess.js +1 -1
- package/src/lib.js +24 -0
- package/tests/unit/gdocs-preprocess.test.js +36 -0
package/CHANGELOG.md
CHANGED
package/package.json
CHANGED
package/src/gdocs-preprocess.js
CHANGED
package/src/lib.js
CHANGED
|
@@ -166,11 +166,34 @@ export function convertHtmlToMarkdown(html, baseUrl) {
|
|
|
166
166
|
style: false,
|
|
167
167
|
});
|
|
168
168
|
turndown.use(turndownPluginGfm.gfm);
|
|
169
|
+
preserveTableCellLineBreaks(turndown);
|
|
169
170
|
// Decode HTML entities to unicode after markdown conversion
|
|
170
171
|
// Preserve non-breaking spaces as entities for clear marking
|
|
171
172
|
return he.decode(turndown.turndown($.html())).replace(/\u00A0/g, ' ');
|
|
172
173
|
}
|
|
173
174
|
|
|
175
|
+
function preserveTableCellLineBreaks(turndown) {
|
|
176
|
+
turndown.addRule('tableCellLineBreak', {
|
|
177
|
+
filter(node) {
|
|
178
|
+
return node.nodeName === 'BR' && hasAncestorNode(node, ['TD', 'TH']);
|
|
179
|
+
},
|
|
180
|
+
replacement() {
|
|
181
|
+
return '<br>';
|
|
182
|
+
},
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
function hasAncestorNode(node, nodeNames) {
|
|
187
|
+
let current = node.parentNode;
|
|
188
|
+
while (current) {
|
|
189
|
+
if (nodeNames.includes(current.nodeName)) {
|
|
190
|
+
return true;
|
|
191
|
+
}
|
|
192
|
+
current = current.parentNode;
|
|
193
|
+
}
|
|
194
|
+
return false;
|
|
195
|
+
}
|
|
196
|
+
|
|
174
197
|
function selectedHtml($, selector) {
|
|
175
198
|
if (!selector) {
|
|
176
199
|
return null;
|
|
@@ -531,6 +554,7 @@ export function convertHtmlToMarkdownEnhanced(html, baseUrl, options = {}) {
|
|
|
531
554
|
style: false,
|
|
532
555
|
});
|
|
533
556
|
turndown.use(turndownPluginGfm.gfm);
|
|
557
|
+
preserveTableCellLineBreaks(turndown);
|
|
534
558
|
|
|
535
559
|
// Decode HTML entities to unicode after markdown conversion
|
|
536
560
|
// Normalize non-breaking spaces to regular spaces in Markdown text
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import {
|
|
2
|
+
normalizeGoogleDocsExportMarkdown,
|
|
3
|
+
preprocessGoogleDocsExportHtml,
|
|
4
|
+
} from '../../src/gdocs.js';
|
|
5
|
+
import { convertHtmlToMarkdown } from '../../src/lib.js';
|
|
6
|
+
|
|
7
|
+
describe('preprocessGoogleDocsExportHtml', () => {
|
|
8
|
+
it('keeps multi-paragraph table cells on one GFM row (issue #110)', () => {
|
|
9
|
+
const html = `
|
|
10
|
+
<table>
|
|
11
|
+
<tr><td><p>Feature</p></td><td><p>Notes</p></td></tr>
|
|
12
|
+
<tr>
|
|
13
|
+
<td>
|
|
14
|
+
<p>First paragraph.</p>
|
|
15
|
+
<p>Second paragraph.</p>
|
|
16
|
+
<p>Third paragraph.</p>
|
|
17
|
+
</td>
|
|
18
|
+
<td><p>x</p></td>
|
|
19
|
+
</tr>
|
|
20
|
+
</table>
|
|
21
|
+
`;
|
|
22
|
+
|
|
23
|
+
const preprocessed = preprocessGoogleDocsExportHtml(html);
|
|
24
|
+
const markdown = normalizeGoogleDocsExportMarkdown(
|
|
25
|
+
convertHtmlToMarkdown(preprocessed.html)
|
|
26
|
+
);
|
|
27
|
+
|
|
28
|
+
expect(preprocessed.html).toContain(
|
|
29
|
+
'<td>First paragraph.<br><br>Second paragraph.<br><br>Third paragraph.</td>'
|
|
30
|
+
);
|
|
31
|
+
expect(markdown).toContain(
|
|
32
|
+
'| First paragraph.<br><br>Second paragraph.<br><br>Third paragraph. | x |'
|
|
33
|
+
);
|
|
34
|
+
expect(markdown).not.toContain('First paragraph. \n');
|
|
35
|
+
});
|
|
36
|
+
});
|