diff --git a/app/assets/javascripts/discourse/components/quote-button.js.es6 b/app/assets/javascripts/discourse/components/quote-button.js.es6 index 742be7865a2..a703e5e3d76 100644 --- a/app/assets/javascripts/discourse/components/quote-button.js.es6 +++ b/app/assets/javascripts/discourse/components/quote-button.js.es6 @@ -48,23 +48,21 @@ export default Component.extend({ } } - let opts; + let opts = { raw: true }; for ( let element = selectedElement(); element && element.tagName !== "ARTICLE"; element = element.parentElement ) { if (element.tagName === "ASIDE" && element.classList.contains("quote")) { - opts = { - username: - element.dataset.username || - element - .querySelector(".title") - .textContent.trim() - .replace(/:$/, ""), - post: element.dataset.post, - topic: element.dataset.topic - }; + opts.username = + element.dataset.username || + element + .querySelector(".title") + .textContent.trim() + .replace(/:$/, ""); + opts.post = element.dataset.post; + opts.topic = element.dataset.topic; } } diff --git a/app/assets/javascripts/discourse/lib/to-markdown.js.es6 b/app/assets/javascripts/discourse/lib/to-markdown.js.es6 index 163c895f83e..83d7b28d045 100644 --- a/app/assets/javascripts/discourse/lib/to-markdown.js.es6 +++ b/app/assets/javascripts/discourse/lib/to-markdown.js.es6 @@ -44,7 +44,6 @@ export class Tag { return [ "address", "article", - "aside", "dd", "div", "dl", @@ -89,6 +88,7 @@ export class Tag { ...Tag.blocks(), ...Tag.headings(), ...Tag.slices(), + "aside", "li", "td", "th", @@ -126,6 +126,45 @@ export class Tag { }; } + static aside() { + return class extends Tag.block("aside") { + constructor() { + super(); + } + + toMarkdown() { + if (!/\bquote\b/.test(this.element.attributes.class)) { + return super.toMarkdown(); + } + + const blockquote = this.element.children.find( + child => child.name === "blockquote" + ); + + if (!blockquote) { + return super.toMarkdown(); + } + + let text = Element.parse([blockquote], this.element) || ""; + text = text.trim().replace(/^>/g, ""); + if (text.length === 0) { + return ""; + } + + const username = this.element.attributes["data-username"]; + const post = this.element.attributes["data-post"]; + const topic = this.element.attributes["data-topic"]; + + const prefix = + username && post && topic + ? `[quote="${username}, post:${post}, topic:${topic}"]` + : "[quote]"; + + return `\n\n${prefix}\n${text}\n[/quote]\n\n`; + } + }; + } + static heading(name, i) { const prefix = `${[...Array(i)].map(() => "#").join("")} `; return Tag.block(name, prefix, ""); @@ -484,6 +523,7 @@ function tags() { ...Tag.slices().map(s => Tag.slice(s, "\n")), ...Tag.emphases().map(e => Tag.emphasis(e[0], e[1])), ...Tag.whitelists().map(t => Tag.whitelist(t)), + Tag.aside(), Tag.cell("td"), Tag.cell("th"), Tag.replace("br", "\n"), diff --git a/test/javascripts/lib/to-markdown-test.js.es6 b/test/javascripts/lib/to-markdown-test.js.es6 index e6fc113ce79..bcda89c9f23 100644 --- a/test/javascripts/lib/to-markdown-test.js.es6 +++ b/test/javascripts/lib/to-markdown-test.js.es6 @@ -386,3 +386,30 @@ QUnit.test("converts image lightboxes to markdown", assert => { assert.equal(toMarkdown(html), markdown); }); + +QUnit.test("converts quotes to markdown", assert => { + let html = ` +
there is a quote below
+ +there is a quote above
+ `; + + let markdown = ` +there is a quote below + +[quote="foo, post:1, topic:2"] +this is a quote +[/quote] + +there is a quote above +`; + + assert.equal(toMarkdown(html), markdown.trim()); +});