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:
@ -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 {
|
export class Text extends XmlComponent {
|
||||||
|
|
||||||
constructor(text: string) {
|
constructor(text: string) {
|
||||||
super("w:t");
|
super("w:t");
|
||||||
|
this.root.push(new TextAttributes({space: "preserve"}));
|
||||||
if (text) {
|
if (text) {
|
||||||
this.root.push(text);
|
this.root.push(text);
|
||||||
}
|
}
|
||||||
|
@ -41,7 +41,7 @@ describe("Document", () => {
|
|||||||
expect(body[0]).to.have.property("w:p").which.includes({
|
expect(body[0]).to.have.property("w:p").which.includes({
|
||||||
"w:r": [
|
"w:r": [
|
||||||
{"w:rPr": []},
|
{"w:rPr": []},
|
||||||
{"w:t": ["sample paragraph text"]},
|
{"w:t": [{_attr: {"xml:space": "preserve"}}, "sample paragraph text"]},
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -39,7 +39,7 @@ describe("Paragraph", () => {
|
|||||||
expect(tree).to.be.an("array").which.includes({
|
expect(tree).to.be.an("array").which.includes({
|
||||||
"w:r": [
|
"w:r": [
|
||||||
{"w:rPr": []},
|
{"w:rPr": []},
|
||||||
{"w:t": ["this is a test run"]},
|
{"w:t": [{_attr: {"xml:space": "preserve"}}, "this is a test run"]},
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
22
ts/tests/docx/run/run-components/text.ts
Normal file
22
ts/tests/docx/run/run-components/text.ts
Normal 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",
|
||||||
|
]});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
@ -1,6 +1,6 @@
|
|||||||
import { assert } from "chai";
|
import { expect } from "chai";
|
||||||
import { TextRun } from "../../../docx/run/text-run";
|
import { TextRun } from "../../../docx/run/text-run";
|
||||||
import { Utility } from "../../utility";
|
import { Formatter } from "../../../export/formatter";
|
||||||
|
|
||||||
describe("TextRun", () => {
|
describe("TextRun", () => {
|
||||||
let run: TextRun;
|
let run: TextRun;
|
||||||
@ -9,8 +9,11 @@ describe("TextRun", () => {
|
|||||||
|
|
||||||
it("should add text into run", () => {
|
it("should add text into run", () => {
|
||||||
run = new TextRun("test");
|
run = new TextRun("test");
|
||||||
const newJson = Utility.jsonify(run);
|
const f = new Formatter().format(run);
|
||||||
assert.equal(newJson.root[1].root, "test");
|
expect(f).to.deep.equal({"w:r": [
|
||||||
|
{"w:rPr": []},
|
||||||
|
{"w:t": [{_attr: {"xml:space": "preserve"}}, "test"]},
|
||||||
|
]});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -36,7 +36,7 @@ describe("Table", () => {
|
|||||||
{"w:tcPr": []},
|
{"w:tcPr": []},
|
||||||
{"w:p": [
|
{"w:p": [
|
||||||
{"w:pPr": []},
|
{"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({
|
expect(tree).to.deep.equal({
|
||||||
@ -65,7 +65,7 @@ describe("Table", () => {
|
|||||||
{"w:tcPr": []},
|
{"w:tcPr": []},
|
||||||
{"w:p": [
|
{"w:p": [
|
||||||
{"w:pPr": []},
|
{"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({
|
expect(tree).to.deep.equal({
|
||||||
@ -153,7 +153,7 @@ describe("Table", () => {
|
|||||||
{"w:tcPr": []},
|
{"w:tcPr": []},
|
||||||
{"w:p": [
|
{"w:p": [
|
||||||
{"w:pPr": []},
|
{"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:tcPr": []},
|
||||||
{"w:p": [
|
{"w:p": [
|
||||||
{"w:pPr": []},
|
{"w:pPr": []},
|
||||||
{"w:r": [{"w:rPr": []}, {"w:t": ["Test paragraph"]}]},
|
{"w:r": [
|
||||||
|
{"w:rPr": []},
|
||||||
|
{"w:t": [{_attr: {"xml:space": "preserve"}}, "Test paragraph"]},
|
||||||
|
]},
|
||||||
]},
|
]},
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
Reference in New Issue
Block a user