From 9bed303d344761b37e7f868218aef78aa3e7aeda Mon Sep 17 00:00:00 2001 From: Dolan Date: Tue, 25 Oct 2022 18:53:00 +0100 Subject: [PATCH] #1529 - Word wrap feature --- demo/72-word-wrap.ts | 22 +++++++++++++++++-- .../paragraph/formatting/word-wrap.spec.ts | 20 +++++++++++++++++ src/file/paragraph/formatting/word-wrap.ts | 14 ++++++++++++ src/file/paragraph/properties.spec.ts | 19 ++++++++++++++++ src/file/paragraph/properties.ts | 6 +++++ src/file/paragraph/run/properties.ts | 2 -- src/file/paragraph/run/run.spec.ts | 17 -------------- src/file/paragraph/run/run.ts | 5 ----- 8 files changed, 79 insertions(+), 26 deletions(-) create mode 100644 src/file/paragraph/formatting/word-wrap.spec.ts create mode 100644 src/file/paragraph/formatting/word-wrap.ts diff --git a/demo/72-word-wrap.ts b/demo/72-word-wrap.ts index 95b8b41d013..74c4b2bebe8 100644 --- a/demo/72-word-wrap.ts +++ b/demo/72-word-wrap.ts @@ -7,12 +7,31 @@ const doc = new Document({ sections: [ { children: [ + new Paragraph({ + wordWrap: true, + children: [ + new TextRun("我今天遛狗去公园"), + new TextRun({ + text: "456435234523456435564745673456345456435234523456435564745673456345456435234523456435564745673456345456435234523456435564745673456345456435234523456435564745673456345", + }), + ], + }), + new Paragraph({ + wordWrap: true, + children: [ + new TextRun( + "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua", + ), + new TextRun({ + text: "456435234523456435564745673456345456435234523456435564745673456345456435234523456435564745673456345456435234523456435564745673456345456435234523456435564745673456345", + }), + ], + }), new Paragraph({ children: [ new TextRun("我今天遛狗去公园"), new TextRun({ text: "456435234523456435564745673456345456435234523456435564745673456345456435234523456435564745673456345456435234523456435564745673456345456435234523456435564745673456345", - space: SpaceType.PRESERVE, }), ], }), @@ -23,7 +42,6 @@ const doc = new Document({ ), new TextRun({ text: "456435234523456435564745673456345456435234523456435564745673456345456435234523456435564745673456345456435234523456435564745673456345456435234523456435564745673456345", - space: SpaceType.PRESERVE, }), ], }), diff --git a/src/file/paragraph/formatting/word-wrap.spec.ts b/src/file/paragraph/formatting/word-wrap.spec.ts new file mode 100644 index 00000000000..acf8b7de1f0 --- /dev/null +++ b/src/file/paragraph/formatting/word-wrap.spec.ts @@ -0,0 +1,20 @@ +import { expect } from "chai"; + +import { Formatter } from "@export/formatter"; + +import { WordWrap } from "./word-wrap"; + +describe("WordWrap", () => { + it("should create", () => { + const wordWrap = new WordWrap(); + const tree = new Formatter().format(wordWrap); + + expect(tree).to.deep.equal({ + "w:wordWrap": { + _attr: { + "w:val": 0, + }, + }, + }); + }); +}); diff --git a/src/file/paragraph/formatting/word-wrap.ts b/src/file/paragraph/formatting/word-wrap.ts new file mode 100644 index 00000000000..3fd6e02775a --- /dev/null +++ b/src/file/paragraph/formatting/word-wrap.ts @@ -0,0 +1,14 @@ +// http://officeopenxml.com/WPalignment.php +// http://officeopenxml.com/WPtableAlignment.php +import { XmlAttributeComponent, XmlComponent } from "@file/xml-components"; + +export class WordWrapAttributes extends XmlAttributeComponent<{ readonly val: 0 }> { + protected readonly xmlKeys = { val: "w:val" }; +} + +export class WordWrap extends XmlComponent { + public constructor() { + super("w:wordWrap"); + this.root.push(new WordWrapAttributes({ val: 0 })); + } +} diff --git a/src/file/paragraph/properties.spec.ts b/src/file/paragraph/properties.spec.ts index 86ecbbf62b9..0890d65f5b1 100644 --- a/src/file/paragraph/properties.spec.ts +++ b/src/file/paragraph/properties.spec.ts @@ -123,5 +123,24 @@ describe("ParagraphProperties", () => { ], }); }); + + it("should create with the wordWrap property", () => { + const properties = new ParagraphProperties({ + wordWrap: true, + }); + const tree = new Formatter().format(properties); + + expect(tree).to.deep.equal({ + "w:pPr": [ + { + "w:wordWrap": { + _attr: { + "w:val": 0, + }, + }, + }, + ], + }); + }); }); }); diff --git a/src/file/paragraph/properties.ts b/src/file/paragraph/properties.ts index 03bdfc4fc19..09886ceec34 100644 --- a/src/file/paragraph/properties.ts +++ b/src/file/paragraph/properties.ts @@ -11,6 +11,7 @@ import { ISpacingProperties, Spacing } from "./formatting/spacing"; import { HeadingLevel, Style } from "./formatting/style"; import { TabStop, TabStopDefinition, TabStopType } from "./formatting/tab-stop"; import { NumberProperties } from "./formatting/unordered-list"; +import { WordWrap } from "./formatting/word-wrap"; import { FrameProperties, IFrameOptions } from "./frame/frame-properties"; import { OutlineLevel } from "./links"; @@ -50,6 +51,7 @@ export interface IParagraphPropertiesOptions extends IParagraphStylePropertiesOp readonly widowControl?: boolean; readonly frame?: IFrameOptions; readonly suppressLineNumbers?: boolean; + readonly wordWrap?: boolean; } export class ParagraphProperties extends IgnoreIfEmptyXmlComponent { @@ -128,6 +130,10 @@ export class ParagraphProperties extends IgnoreIfEmptyXmlComponent { this.push(new Shading(options.shading)); } + if (options.wordWrap) { + this.push(new WordWrap()); + } + /** * FIX: Multitab support for Libre Writer * Ensure there is only one w:tabs tag with multiple w:tab diff --git a/src/file/paragraph/run/properties.ts b/src/file/paragraph/run/properties.ts index e24b8648d17..99435513643 100644 --- a/src/file/paragraph/run/properties.ts +++ b/src/file/paragraph/run/properties.ts @@ -1,6 +1,5 @@ import { BorderElement, IBorderOptions } from "@file/border"; import { IShadingAttributesProperties, Shading } from "@file/shading"; -import { SpaceType } from "@file/space-type"; import { ChangeAttributes, IChangedAttributesProperties } from "@file/track-revision/track-revision"; import { HpsMeasureElement, IgnoreIfEmptyXmlComponent, OnOffElement, StringValueElement, XmlComponent } from "@file/xml-components"; @@ -46,7 +45,6 @@ export interface IRunStylePropertiesOptions { readonly imprint?: boolean; readonly revision?: IRunPropertiesChangeOptions; readonly border?: IBorderOptions; - readonly space?: SpaceType; } export interface IRunPropertiesOptions extends IRunStylePropertiesOptions { diff --git a/src/file/paragraph/run/run.spec.ts b/src/file/paragraph/run/run.spec.ts index 2604d8ffca6..2205461e643 100644 --- a/src/file/paragraph/run/run.spec.ts +++ b/src/file/paragraph/run/run.spec.ts @@ -3,7 +3,6 @@ import { expect } from "chai"; import { Formatter } from "@export/formatter"; import { BorderStyle } from "@file/border"; import { ShadingType } from "@file/shading"; -import { SpaceType } from "@file/space-type"; import { EmphasisMarkType } from "./emphasis-mark"; import { PageNumber, Run } from "./run"; @@ -520,20 +519,4 @@ describe("Run", () => { }); }); }); - - describe("#space", () => { - it("should correctly set the border", () => { - const run = new Run({ - space: SpaceType.PRESERVE, - }); - const tree = new Formatter().format(run); - expect(tree).to.deep.equal({ - "w:r": { - _attr: { - "xml:space": "preserve", - }, - }, - }); - }); - }); }); diff --git a/src/file/paragraph/run/run.ts b/src/file/paragraph/run/run.ts index e5344e0e545..7d2a0f2ced4 100644 --- a/src/file/paragraph/run/run.ts +++ b/src/file/paragraph/run/run.ts @@ -9,7 +9,6 @@ import { Begin, End, Separate } from "./field"; import { NumberOfPages, NumberOfPagesSection, Page } from "./page-number"; import { IRunPropertiesOptions, RunProperties } from "./properties"; import { Text } from "./run-components/text"; -import { TextAttributes } from "./text-attributes"; export interface IRunOptions extends IRunPropertiesOptions { readonly children?: readonly (Begin | FieldInstruction | Separate | End | PageNumber | FootnoteReferenceRun | string)[]; @@ -37,10 +36,6 @@ export class Run extends XmlComponent { } } - if (options.space) { - this.root.push(new TextAttributes({ space: options.space })); - } - if (options.children) { for (const child of options.children) { if (typeof child === "string") {