add xml:space="preserve" to text runs

In MS Word 2015 (and possibly others), leading and trailing spaces are
ignored in text runs. This means that calling TextRun with
leading/trailing space would result in a document that didn't include
those spaces. The fix here (per http://officeopenxml.com/WPtext.php)
is to include an extra attribute on the "w:t" element that forces word
to recognize those spaces.
This commit is contained in:
felipe
2017-04-14 11:01:47 +02:00
parent a706455a7c
commit b1c8b2beb8
6 changed files with 44 additions and 12 deletions

View File

@ -1,9 +1,13 @@
import { XmlComponent } from "../../xml-components";
import { XmlAttributeComponent, XmlComponent } from "../../xml-components";
class TextAttributes extends XmlAttributeComponent<{space: "default" | "preserve"}> {
protected xmlKeys = {space: "xml:space"};
}
export class Text extends XmlComponent {
constructor(text: string) {
super("w:t");
this.root.push(new TextAttributes({space: "preserve"}));
if (text) {
this.root.push(text);
}

View File

@ -41,7 +41,7 @@ describe("Document", () => {
expect(body[0]).to.have.property("w:p").which.includes({
"w:r": [
{"w:rPr": []},
{"w:t": ["sample paragraph text"]},
{"w:t": [{_attr: {"xml:space": "preserve"}}, "sample paragraph text"]},
],
});
});

View File

@ -39,7 +39,7 @@ describe("Paragraph", () => {
expect(tree).to.be.an("array").which.includes({
"w:r": [
{"w:rPr": []},
{"w:t": ["this is a test run"]},
{"w:t": [{_attr: {"xml:space": "preserve"}}, "this is a test run"]},
],
});
});

View File

@ -0,0 +1,22 @@
import { expect } from "chai";
import { Text } from "../../../../docx/run/run-components/text";
import { Formatter } from "../../../../export/formatter";
describe("Text", () => {
describe("#constructor", () => {
it("creates an empty text run if no text is given", () => {
const t = new Text("");
const f = new Formatter().format(t);
expect(f).to.deep.equal({"w:t": [{_attr: {"xml:space": "preserve"}}]});
});
it("adds the passed in text to the component", () => {
const t = new Text(" this is\n text");
const f = new Formatter().format(t);
expect(f).to.deep.equal({"w:t": [
{_attr: {"xml:space": "preserve"}},
" this is\n text",
]});
});
});
});

View File

@ -1,6 +1,6 @@
import { assert } from "chai";
import { expect } from "chai";
import { TextRun } from "../../../docx/run/text-run";
import { Utility } from "../../utility";
import { Formatter } from "../../../export/formatter";
describe("TextRun", () => {
let run: TextRun;
@ -9,8 +9,11 @@ describe("TextRun", () => {
it("should add text into run", () => {
run = new TextRun("test");
const newJson = Utility.jsonify(run);
assert.equal(newJson.root[1].root, "test");
const f = new Formatter().format(run);
expect(f).to.deep.equal({"w:r": [
{"w:rPr": []},
{"w:t": [{_attr: {"xml:space": "preserve"}}, "test"]},
]});
});
});
});

View File

@ -36,7 +36,7 @@ describe("Table", () => {
{"w:tcPr": []},
{"w:p": [
{"w:pPr": []},
{"w:r": [{"w:rPr": []}, {"w:t": [c]}]},
{"w:r": [{"w:rPr": []}, {"w:t": [{_attr: {"xml:space": "preserve"}}, c]}]},
]},
]});
expect(tree).to.deep.equal({
@ -65,7 +65,7 @@ describe("Table", () => {
{"w:tcPr": []},
{"w:p": [
{"w:pPr": []},
{"w:r": [{"w:rPr": []}, {"w:t": [c]}]},
{"w:r": [{"w:rPr": []}, {"w:t": [{_attr: {"xml:space": "preserve"}}, c]}]},
]},
]});
expect(tree).to.deep.equal({
@ -153,7 +153,7 @@ describe("Table", () => {
{"w:tcPr": []},
{"w:p": [
{"w:pPr": []},
{"w:r": [{"w:rPr": []}, {"w:t": ["Hello"]}]},
{"w:r": [{"w:rPr": []}, {"w:t": [{_attr: {"xml:space": "preserve"}}, "Hello"]}]},
]},
],
});
@ -175,7 +175,10 @@ describe("Table", () => {
{"w:tcPr": []},
{"w:p": [
{"w:pPr": []},
{"w:r": [{"w:rPr": []}, {"w:t": ["Test paragraph"]}]},
{"w:r": [
{"w:rPr": []},
{"w:t": [{_attr: {"xml:space": "preserve"}}, "Test paragraph"]},
]},
]},
],
});