2
0
Fork 0
mirror of https://github.com/discourse/discourse.git synced 2025-09-07 12:02:53 +08:00

Allow linked images inside table cells in HTML to Markdown conversion

This commit is contained in:
Vinoth Kannan 2017-12-23 22:48:39 +05:30
parent ef4c6c67ba
commit 035f96d25f
2 changed files with 18 additions and 9 deletions

View file

@ -2,6 +2,7 @@ import parseHTML from 'discourse/helpers/parse-html';
const trimLeft = text => text.replace(/^\s+/,""); const trimLeft = text => text.replace(/^\s+/,"");
const trimRight = text => text.replace(/\s+$/,""); const trimRight = text => text.replace(/\s+$/,"");
const countPipes = text => text.match(/(?<!\\)\|/g).length;
class Tag { class Tag {
constructor(name, prefix = "", suffix = "", inline = false) { constructor(name, prefix = "", suffix = "", inline = false) {
@ -152,7 +153,8 @@ class Tag {
const height = attr.height || pAttr.height; const height = attr.height || pAttr.height;
if (width && height) { if (width && height) {
alt = `${alt}|${width}x${height}`; const pipe = this.element.parentNames.includes("table") ? "\\|" : "|";
alt = `${alt}${pipe}${width}x${height}`;
} }
return "![" + alt + "](" + src + ")"; return "![" + alt + "](" + src + ")";
@ -187,7 +189,7 @@ class Tag {
toMarkdown() { toMarkdown() {
const text = this.element.innerMarkdown().trim(); const text = this.element.innerMarkdown().trim();
if (text.includes("\n") || text.includes("[![")) { if (text.includes("\n")) {
throw "Unsupported format inside Markdown table cells"; throw "Unsupported format inside Markdown table cells";
} }
@ -243,16 +245,16 @@ class Tag {
decorate(text) { decorate(text) {
text = super.decorate(text).replace(/\|\n{2,}\|/g, "|\n|"); text = super.decorate(text).replace(/\|\n{2,}\|/g, "|\n|");
const rows = text.trim().split("\n"); const rows = text.trim().split("\n");
const pipes = rows[0].match(/\|/g); const pipeCount = countPipes(rows[0]);
const isValid = rows.length > 1 && const isValid = rows.length > 1 &&
pipes.length > 2 && pipeCount > 2 &&
rows.reduce((a, c) => a && c.match(/\|/g).length <= pipes.length); rows.reduce((a, c) => a && countPipes(c) <= pipeCount);
if (!isValid) { if (!isValid) {
throw "Unsupported table format for Markdown conversion"; throw "Unsupported table format for Markdown conversion";
} }
const splitterRow = pipes.slice(1).map(() => "| --- ").join("") + "|\n"; const splitterRow = [...Array(pipeCount-1)].map(() => "| --- ").join("") + "|\n";
text = text.replace("|\n", "|\n" + splitterRow); text = text.replace("|\n", "|\n" + splitterRow);
return text; return text;

View file

@ -98,7 +98,7 @@ QUnit.test("stripes unwanted inline tags", assert => {
}); });
QUnit.test("converts table tags", assert => { QUnit.test("converts table tags", assert => {
const html = `<address>Discourse Avenue</address><b>laboris</b> let html = `<address>Discourse Avenue</address><b>laboris</b>
<table> <table>
<thead> <tr><th>Heading 1</th><th>Head 2</th></tr> </thead> <thead> <tr><th>Heading 1</th><th>Head 2</th></tr> </thead>
<tbody> <tbody>
@ -108,13 +108,20 @@ QUnit.test("converts table tags", assert => {
</tbody> </tbody>
</table> </table>
`; `;
const markdown = `Discourse Avenue\n\n**laboris**\n\n|Heading 1|Head 2|\n| --- | --- |\n|Lorem|ipsum|\n|**dolor**|*sit amet*|`; let markdown = `Discourse Avenue\n\n**laboris**\n\n|Heading 1|Head 2|\n| --- | --- |\n|Lorem|ipsum|\n|**dolor**|*sit amet*|`;
assert.equal(toMarkdown(html), markdown);
html = `<table>
<tr><th>Heading 1</th><th>Head 2</th></tr>
<tr><td><a href="http://example.com"><img src="http://example.com/image.png" alt="Lorem" width="45" height="45"></a></td><td>ipsum</td></tr>
</table>`;
markdown = `|Heading 1|Head 2|\n| --- | --- |\n|[![Lorem\\|45x45](http://example.com/image.png)](http://example.com)|ipsum|`;
assert.equal(toMarkdown(html), markdown); assert.equal(toMarkdown(html), markdown);
}); });
QUnit.test("returns empty string if table format not supported", assert => { QUnit.test("returns empty string if table format not supported", assert => {
let html = `<table> let html = `<table>
<thead> <tr><th>Headi\n\nng 1</th><th>Head 2</th></tr> </thead> <thead> <tr><th>Headi<br><br>ng 1</th><th>Head 2</th></tr> </thead>
<tbody> <tbody>
<tr><td>Lorem</td><td>ipsum</td></tr> <tr><td>Lorem</td><td>ipsum</td></tr>
<tr><td><a href="http://example.com"><img src="http://dolor.com/image.png" /></a></td> <td><i>sit amet</i></td></tr></tbody> <tr><td><a href="http://example.com"><img src="http://dolor.com/image.png" /></a></td> <td><i>sit amet</i></td></tr></tbody>