mirror of
https://github.com/discourse/discourse.git
synced 2025-04-02 10:02:37 +08:00
FEATURE: Composer HTML pasting ul tag support for MS Word
This commit is contained in:
parent
1e51be923c
commit
91beedd0ca
@ -3,6 +3,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;
|
||||||
|
const msoListClasses = ["MsoListParagraphCxSpFirst", "MsoListParagraphCxSpMiddle", "MsoListParagraphCxSpLast"];
|
||||||
|
|
||||||
class Tag {
|
class Tag {
|
||||||
constructor(name, prefix = "", suffix = "", inline = false) {
|
constructor(name, prefix = "", suffix = "", inline = false) {
|
||||||
@ -207,7 +208,22 @@ class Tag {
|
|||||||
static li() {
|
static li() {
|
||||||
return class extends Tag.slice("li", "\n") {
|
return class extends Tag.slice("li", "\n") {
|
||||||
decorate(text) {
|
decorate(text) {
|
||||||
const indent = this.element.filterParentNames(["ol", "ul"]).slice(1).map(() => "\t").join("");
|
let indent = this.element.filterParentNames(["ol", "ul"]).slice(1).map(() => "\t").join("");
|
||||||
|
const attrs = this.element.attributes;
|
||||||
|
|
||||||
|
if (msoListClasses.includes(attrs.class)) {
|
||||||
|
try {
|
||||||
|
const level = parseInt(attrs.style.match(/level./)[0].replace("level", ""));
|
||||||
|
indent = Array(level).join("\t") + indent;
|
||||||
|
} finally {
|
||||||
|
if (attrs.class === "MsoListParagraphCxSpFirst") {
|
||||||
|
indent = `\n\n${indent}`;
|
||||||
|
} else if (attrs.class === "MsoListParagraphCxSpLast") {
|
||||||
|
text = `${text}\n`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return super.decorate(`${indent}* ${trimLeft(text)}`);
|
return super.decorate(`${indent}* ${trimLeft(text)}`);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -356,6 +372,13 @@ class Element {
|
|||||||
this.parentNames = this.parentNames || [];
|
this.parentNames = this.parentNames || [];
|
||||||
this.previous = previous;
|
this.previous = previous;
|
||||||
this.next = next;
|
this.next = next;
|
||||||
|
|
||||||
|
if (this.name === "p") {
|
||||||
|
if (msoListClasses.includes(this.attributes.class)) {
|
||||||
|
this.name = "li";
|
||||||
|
this.parentNames.push("ul");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
tag() {
|
tag() {
|
||||||
@ -433,7 +456,7 @@ class Element {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function trimUnwantedSpaces(html) {
|
function trimUnwanted(html) {
|
||||||
const body = html.match(/<body[^>]*>([\s\S]*?)<\/body>/);
|
const body = html.match(/<body[^>]*>([\s\S]*?)<\/body>/);
|
||||||
html = body ? body[1] : html;
|
html = body ? body[1] : html;
|
||||||
html = html.replace(/\r|\n| /g, " ");
|
html = html.replace(/\r|\n| /g, " ");
|
||||||
@ -443,6 +466,8 @@ function trimUnwantedSpaces(html) {
|
|||||||
html = html.replace(match[0], match[0].replace(/>\s{2,}</, "> <"));
|
html = html.replace(match[0], match[0].replace(/>\s{2,}</, "> <"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
html = html.replace(/<!\[if !?\S*]>[^!]*<!\[endif]>/g, ""); // to support ms word list tags
|
||||||
|
|
||||||
return html;
|
return html;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -461,7 +486,7 @@ function putPlaceholders(html) {
|
|||||||
match = codeRegEx.exec(origHtml);
|
match = codeRegEx.exec(origHtml);
|
||||||
}
|
}
|
||||||
|
|
||||||
const elements = parseHTML(trimUnwantedSpaces(html));
|
const elements = parseHTML(trimUnwanted(html));
|
||||||
return { elements, placeholders };
|
return { elements, placeholders };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -239,3 +239,50 @@ QUnit.test("converts ol list tag", assert => {
|
|||||||
const markdown = `Testing\n\n1. Item 1\n2. Item 2\n 100. Sub Item 1\n 101. Sub Item 2\n3. Item 3`;
|
const markdown = `Testing\n\n1. Item 1\n2. Item 2\n 100. Sub Item 1\n 101. Sub Item 2\n3. Item 3`;
|
||||||
assert.equal(toMarkdown(html), markdown);
|
assert.equal(toMarkdown(html), markdown);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
QUnit.test("converts list tag from word", assert => {
|
||||||
|
const html = `Sample<!--StartFragment-->
|
||||||
|
<p class=MsoListParagraphCxSpFirst style='text-indent:-.25in;mso-list:l0 level1 lfo1'>
|
||||||
|
<![if !supportLists]>
|
||||||
|
<span style='font-family:Symbol;mso-fareast-font-family:Symbol;mso-bidi-font-family: Symbol;mso-bidi-font-weight:bold'>
|
||||||
|
<span style='mso-list:Ignore'>·
|
||||||
|
<span style='font:7.0pt "Times New Roman"'> </span>
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
<![endif]>
|
||||||
|
<b>Item 1
|
||||||
|
<o:p></o:p>
|
||||||
|
</b>
|
||||||
|
</p>
|
||||||
|
<p class=MsoListParagraphCxSpMiddle style='text-indent:-.25in;mso-list:l0 level2 lfo1'>
|
||||||
|
<![if !supportLists]>
|
||||||
|
<span style='font-family:Symbol;mso-fareast-font-family:Symbol;mso-bidi-font-family: Symbol;mso-bidi-font-style:italic'>
|
||||||
|
<span style='mso-list:Ignore'>·
|
||||||
|
<span style='font:7.0pt "Times New Roman"'> </span>
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
<![endif]>
|
||||||
|
<i>Item 2
|
||||||
|
<o:p></o:p>
|
||||||
|
</i>
|
||||||
|
</p>
|
||||||
|
<p class=MsoListParagraphCxSpMiddle style='text-indent:-.25in;mso-list:l0 level3 lfo1'>
|
||||||
|
<![if !supportLists]>
|
||||||
|
<span style='font-family:Symbol;mso-fareast-font-family:Symbol;mso-bidi-font-family: Symbol'>
|
||||||
|
<span style='mso-list:Ignore'>·
|
||||||
|
<span style='font:7.0pt "Times New Roman"'> </span>
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
<![endif]>Item 3 </p>
|
||||||
|
<p class=MsoListParagraphCxSpLast style='text-indent:-.25in;mso-list:l0 level1 lfo1'>
|
||||||
|
<![if !supportLists]>
|
||||||
|
<span style='font-family:Symbol;mso-fareast-font-family:Symbol;mso-bidi-font-family: Symbol'>
|
||||||
|
<span style='mso-list:Ignore'>·
|
||||||
|
<span style='font:7.0pt "Times New Roman"'> </span>
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
<![endif]>Item 4</p>
|
||||||
|
<!--EndFragment-->List`;
|
||||||
|
const markdown = `Sample\n\n* **Item 1**\n * *Item 2*\n * Item 3\n* Item 4\n\nList`;
|
||||||
|
assert.equal(toMarkdown(html), markdown);
|
||||||
|
});
|
||||||
|
Loading…
x
Reference in New Issue
Block a user