FEATURE: Composer HTML pasting support for complex table formats

This commit is contained in:
Vinoth Kannan 2018-01-31 01:39:11 +05:30
parent cc830f7119
commit 10ed4c0078
2 changed files with 42 additions and 16 deletions

View File

@ -2,7 +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.replace(/\\\|/,"").match(/\|/g).length; const countPipes = text => (text.replace(/\\\|/,"").match(/\|/g) || []).length;
class Tag { class Tag {
constructor(name, prefix = "", suffix = "", inline = false) { constructor(name, prefix = "", suffix = "", inline = false) {
@ -189,8 +189,14 @@ class Tag {
toMarkdown() { toMarkdown() {
const text = this.element.innerMarkdown().trim(); const text = this.element.innerMarkdown().trim();
if (text.includes("\n")) { if(text.includes("\n")) { // Unsupported format inside Markdown table cells
throw "Unsupported format inside Markdown table cells"; let e = this.element;
while(e = e.parent) {
if (e.name === "table") {
e.tag().invalid();
break;
}
}
} }
return this.decorate(text); return this.decorate(text);
@ -242,21 +248,38 @@ class Tag {
static table() { static table() {
return class extends Tag.block("table") { return class extends Tag.block("table") {
constructor() {
super();
this.isValid = true;
}
invalid() {
this.isValid = false;
if (this.element.parentNames.includes("table")) {
let e = this.element;
while(e = e.parent) {
if (e.name === "table") {
e.tag().invalid();
break;
}
}
}
}
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 pipeCount = countPipes(rows[0]); const pipeCount = countPipes(rows[0]);
const isValid = rows.length > 1 && this.isValid = this.isValid && rows.length > 1 && pipeCount > 2 && rows.reduce((a, c) => a && countPipes(c) <= pipeCount); // Unsupported table format for Markdown conversion
pipeCount > 2 &&
rows.reduce((a, c) => a && countPipes(c) <= pipeCount);
if (!isValid) { if (this.isValid) {
throw "Unsupported table format for Markdown conversion"; const splitterRow = [...Array(pipeCount-1)].map(() => "| --- ").join("") + "|\n";
text = text.replace("|\n", "|\n" + splitterRow);
} else {
text = text.replace(/\|/g, " ");
this.invalid();
} }
const splitterRow = [...Array(pipeCount-1)].map(() => "| --- ").join("") + "|\n";
text = text.replace("|\n", "|\n" + splitterRow);
return text; return text;
} }
}; };

View File

@ -119,7 +119,7 @@ QUnit.test("converts table tags", assert => {
assert.equal(toMarkdown(html), markdown); assert.equal(toMarkdown(html), markdown);
}); });
QUnit.test("returns empty string if table format not supported", assert => { QUnit.test("replace pipes with spaces if table format not supported", assert => {
let html = `<table> let html = `<table>
<thead> <tr><th>Headi<br><br>ng 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>
@ -127,7 +127,8 @@ QUnit.test("returns empty string if table format not supported", assert => {
<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>
</table> </table>
`; `;
assert.equal(toMarkdown(html), ""); let markdown = `Headi\n\nng 1 Head 2\nLorem ipsum\n[![](http://dolor.com/image.png)](http://example.com) *sit amet*`;
assert.equal(toMarkdown(html), markdown);
html = `<table> html = `<table>
<thead> <tr><th>Heading 1</th></tr> </thead> <thead> <tr><th>Heading 1</th></tr> </thead>
@ -136,10 +137,12 @@ QUnit.test("returns empty string if table format not supported", assert => {
<tr><td><i>sit amet</i></td></tr></tbody> <tr><td><i>sit amet</i></td></tr></tbody>
</table> </table>
`; `;
assert.equal(toMarkdown(html), ""); markdown = `Heading 1\nLorem\n*sit amet*`;
assert.equal(toMarkdown(html), markdown);
html = `<table><tr><td>Lorem</td><td><i>sit amet</i></td></tr></table>`; html = `<table><tr><td>Lorem</td><td><strong>sit amet</strong></td></tr></table>`;
assert.equal(toMarkdown(html), ""); markdown = `Lorem **sit amet**`;
assert.equal(toMarkdown(html), markdown);
}); });
QUnit.test("converts img tag", assert => { QUnit.test("converts img tag", assert => {