@joplin/turndown-plugin-gfm
Advanced tools
Comparing version 1.0.50 to 1.0.51
@@ -45,2 +45,9 @@ 'use strict'; | ||
let isCodeBlock_ = null; | ||
// We need to cache the result of tableShouldBeSkipped() as it is expensive. | ||
// Caching it means we went from about 9000 ms for rendering down to 90 ms. | ||
// Fixes https://github.com/laurent22/joplin/issues/6736 | ||
const tableShouldBeSkippedCache_ = new Map(); | ||
function getAlignment(node) { | ||
@@ -108,6 +115,6 @@ return node ? (node.getAttribute('align') || node.style.textAlign || '').toLowerCase() : ''; | ||
rules.table = { | ||
// Only convert tables with a heading row. | ||
// Tables with no heading row are kept using `keep` (see below). | ||
// Only convert tables that can result in valid Markdown | ||
// Other tables are kept as HTML using `keep` (see below). | ||
filter: function (node) { | ||
return node.nodeName === 'TABLE' | ||
return node.nodeName === 'TABLE' && !tableShouldBeHtml(node); | ||
}, | ||
@@ -198,10 +205,48 @@ | ||
const nodeContains = (node, types) => { | ||
if (!node.childNodes) return false; | ||
for (let i = 0; i < node.childNodes.length; i++) { | ||
const child = node.childNodes[i]; | ||
if (types === 'code' && isCodeBlock_(child)) return true; | ||
if (types.includes(child.nodeName)) return true; | ||
if (nodeContains(child, types)) return true; | ||
} | ||
return false; | ||
}; | ||
const tableShouldBeHtml = (tableNode) => { | ||
return nodeContains(tableNode, 'code') || | ||
nodeContains(tableNode, [ | ||
'UL', | ||
'OL', | ||
'H1', | ||
'H2', | ||
'H3', | ||
'H4', | ||
'H5', | ||
'H6', | ||
'HR', | ||
'BLOCKQUOTE', | ||
]); | ||
}; | ||
// Various conditions under which a table should be skipped - i.e. each cell | ||
// will be rendered one after the other as if they were paragraphs. | ||
function tableShouldBeSkipped(tableNode) { | ||
if (!tableNode) return true; | ||
if (!tableNode.rows) return true; | ||
if (tableNode.rows.length === 1 && tableNode.rows[0].childNodes.length <= 1) return true; // Table with only one cell | ||
if (nodeContainsTable(tableNode)) return true; | ||
return false; | ||
const cached = tableShouldBeSkippedCache_.get(tableNode); | ||
if (cached !== undefined) return cached; | ||
const process = () => { | ||
if (!tableNode) return true; | ||
if (!tableNode.rows) return true; | ||
if (tableNode.rows.length === 1 && tableNode.rows[0].childNodes.length <= 1) return true; // Table with only one cell | ||
if (nodeContainsTable(tableNode)) return true; | ||
return false; | ||
}; | ||
const result = process(); | ||
tableShouldBeSkippedCache_.set(tableNode, result); | ||
return result; | ||
} | ||
@@ -237,4 +282,7 @@ | ||
function tables (turndownService) { | ||
isCodeBlock_ = turndownService.isCodeBlock; | ||
turndownService.keep(function (node) { | ||
return node.nodeName === 'TABLE' | ||
if (node.nodeName === 'TABLE' && tableShouldBeHtml(node)) return true; | ||
return false; | ||
}); | ||
@@ -241,0 +289,0 @@ for (var key in rules) turndownService.addRule(key, rules[key]); |
@@ -7,3 +7,3 @@ { | ||
}, | ||
"version": "1.0.50", | ||
"version": "1.0.51", | ||
"author": "Dom Christie", | ||
@@ -45,3 +45,3 @@ "main": "lib/turndown-plugin-gfm.cjs.js", | ||
}, | ||
"gitHead": "21929157b5184b261264c43cc851e7d17faed2c6" | ||
"gitHead": "05a29b450962bf05a8642bbd39446a1f679a96ba" | ||
} |
13115
266