diff --git a/app/assets/javascripts/discourse/lib/to-markdown.js.es6 b/app/assets/javascripts/discourse/lib/to-markdown.js.es6 index 2fd90c59e01..3a4ff590dc6 100644 --- a/app/assets/javascripts/discourse/lib/to-markdown.js.es6 +++ b/app/assets/javascripts/discourse/lib/to-markdown.js.es6 @@ -2,7 +2,7 @@ import parseHTML from 'discourse/helpers/parse-html'; const trimLeft = 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 { constructor(name, prefix = "", suffix = "", inline = false) { @@ -189,8 +189,14 @@ class Tag { toMarkdown() { const text = this.element.innerMarkdown().trim(); - if (text.includes("\n")) { - throw "Unsupported format inside Markdown table cells"; + if(text.includes("\n")) { // 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); @@ -242,21 +248,38 @@ class Tag { static 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) { text = super.decorate(text).replace(/\|\n{2,}\|/g, "|\n|"); const rows = text.trim().split("\n"); const pipeCount = countPipes(rows[0]); - const isValid = rows.length > 1 && - pipeCount > 2 && - rows.reduce((a, c) => a && countPipes(c) <= pipeCount); + this.isValid = this.isValid && rows.length > 1 && pipeCount > 2 && rows.reduce((a, c) => a && countPipes(c) <= pipeCount); // Unsupported table format for Markdown conversion - if (!isValid) { - throw "Unsupported table format for Markdown conversion"; + if (this.isValid) { + 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; } }; diff --git a/test/javascripts/lib/to-markdown-test.js.es6 b/test/javascripts/lib/to-markdown-test.js.es6 index 3c2f04566b8..12e136ec264 100644 --- a/test/javascripts/lib/to-markdown-test.js.es6 +++ b/test/javascripts/lib/to-markdown-test.js.es6 @@ -119,7 +119,7 @@ QUnit.test("converts table tags", assert => { 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 = ` @@ -127,7 +127,8 @@ QUnit.test("returns empty string if table format not supported", assert => {
Headi

ng 1
Head 2
sit amet
`; - 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 = ` @@ -136,10 +137,12 @@ QUnit.test("returns empty string if table format not supported", assert => {
Heading 1
sit amet
`; - assert.equal(toMarkdown(html), ""); + markdown = `Heading 1\nLorem\n*sit amet*`; + assert.equal(toMarkdown(html), markdown); - html = `
Loremsit amet
`; - assert.equal(toMarkdown(html), ""); + html = `
Loremsit amet
`; + markdown = `Lorem **sit amet**`; + assert.equal(toMarkdown(html), markdown); }); QUnit.test("converts img tag", assert => {