From 50ef633d50e6b671322f6ef345a7adde1cd6066f Mon Sep 17 00:00:00 2001 From: rasamassen Date: Mon, 8 Sep 2025 20:35:56 -0500 Subject: [PATCH 01/53] Update Paragraph.php - Add Pagination Also fixes hasPageBreakBefore() triggering wrong RTF tag. --- src/PhpWord/Writer/RTF/Style/Paragraph.php | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/PhpWord/Writer/RTF/Style/Paragraph.php b/src/PhpWord/Writer/RTF/Style/Paragraph.php index 040c60b5aa..1346144126 100644 --- a/src/PhpWord/Writer/RTF/Style/Paragraph.php +++ b/src/PhpWord/Writer/RTF/Style/Paragraph.php @@ -94,9 +94,12 @@ public function write() $lineHeightAdjusted = (int) ($lineHeight * 240); $content .= "\\sl$lineHeightAdjusted\\slmult1"; } - if ($style->hasPageBreakBefore()) { - $content .= '\\page'; - } + + // Pagination + $content .= $this->getValueIf($style->hasWidowControl(), '\widctlpar'); + $content .= $this->getValueIf($style->isKeepNext(), '\keepn'); + $content .= $this->getValueIf($style->isKeepLines(), '\keep'); + $content .= $this->getValueIf($style->hasPageBreakBefore(), '\pagebb'); $styles = $style->getStyleValues(); $content .= $this->writeTabs($styles['tabs']); From 5e9976ed4b0f2318ab262836adb7e238b1e2a2d7 Mon Sep 17 00:00:00 2001 From: rasamassen Date: Mon, 8 Sep 2025 20:52:38 -0500 Subject: [PATCH 02/53] Update Paragraph.php - Fix widow/orphan control --- src/PhpWord/Writer/RTF/Style/Paragraph.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/PhpWord/Writer/RTF/Style/Paragraph.php b/src/PhpWord/Writer/RTF/Style/Paragraph.php index 1346144126..b1e3383a0a 100644 --- a/src/PhpWord/Writer/RTF/Style/Paragraph.php +++ b/src/PhpWord/Writer/RTF/Style/Paragraph.php @@ -76,7 +76,7 @@ public function write() $content = ''; if ($this->nestedLevel == 0) { - $content .= '\pard\nowidctlpar '; + $content .= '\pard '; } $alignment = $style->getAlignment(); $bidi = $style->isBidi(); @@ -97,6 +97,7 @@ public function write() // Pagination $content .= $this->getValueIf($style->hasWidowControl(), '\widctlpar'); + $content .= $this->getValueIf(!$style->hasWidowControl(), '\nowidctlpar'); $content .= $this->getValueIf($style->isKeepNext(), '\keepn'); $content .= $this->getValueIf($style->isKeepLines(), '\keep'); $content .= $this->getValueIf($style->hasPageBreakBefore(), '\pagebb'); From 0c66a6515018c3d3cb391b23ced7279974ced61a Mon Sep 17 00:00:00 2001 From: rasamassen Date: Mon, 8 Sep 2025 20:54:51 -0500 Subject: [PATCH 03/53] Update 1.5.0.md - Changelog for Pull 2824 --- docs/changes/1.x/1.5.0.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/changes/1.x/1.5.0.md b/docs/changes/1.x/1.5.0.md index b96865bada..8454d7b74e 100644 --- a/docs/changes/1.x/1.5.0.md +++ b/docs/changes/1.x/1.5.0.md @@ -7,6 +7,7 @@ ### Bug fixes - Set writeAttribute return type by [@radarhere](https://github.com/radarhere) fixing [#2204](https://github.com/PHPOffice/PHPWord/issues/2204) in [#2776](https://github.com/PHPOffice/PHPWord/pull/2776) +- Writer RTF: Add/Fix pagination in Paragraph by [@rasamassen](https://github.com/rasamassen) in [#2824](https://github.com/PHPOffice/PHPWord/pull/2824) ### Miscellaneous @@ -16,4 +17,4 @@ ### BC Breaks -### Notes \ No newline at end of file +### Notes From e61dfd6d068357026c0d5a4fe78e5a5eed7fee8b Mon Sep 17 00:00:00 2001 From: rasamassen Date: Mon, 8 Sep 2025 20:57:25 -0500 Subject: [PATCH 04/53] Update Paragraph.php - Just making the spacing look nice. --- src/PhpWord/Writer/RTF/Style/Paragraph.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/PhpWord/Writer/RTF/Style/Paragraph.php b/src/PhpWord/Writer/RTF/Style/Paragraph.php index b1e3383a0a..88df6c27de 100644 --- a/src/PhpWord/Writer/RTF/Style/Paragraph.php +++ b/src/PhpWord/Writer/RTF/Style/Paragraph.php @@ -76,7 +76,7 @@ public function write() $content = ''; if ($this->nestedLevel == 0) { - $content .= '\pard '; + $content .= '\pard'; } $alignment = $style->getAlignment(); $bidi = $style->isBidi(); @@ -105,7 +105,7 @@ public function write() $styles = $style->getStyleValues(); $content .= $this->writeTabs($styles['tabs']); - return $content; + return $content . ' '; } /** From 33ba3bc2e0faff68a8a6e8e00f7a43c74c904dd5 Mon Sep 17 00:00:00 2001 From: rasamassen Date: Mon, 8 Sep 2025 20:59:08 -0500 Subject: [PATCH 05/53] Update RtfEscaper2Test.php - Replace nowidctlpar with widctlpar - Widow/Orphan controls is default true. --- tests/PhpWordTests/Escaper/RtfEscaper2Test.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/PhpWordTests/Escaper/RtfEscaper2Test.php b/tests/PhpWordTests/Escaper/RtfEscaper2Test.php index d65b543f21..79e564ecc8 100644 --- a/tests/PhpWordTests/Escaper/RtfEscaper2Test.php +++ b/tests/PhpWordTests/Escaper/RtfEscaper2Test.php @@ -23,7 +23,7 @@ */ class RtfEscaper2Test extends \PHPUnit\Framework\TestCase { - const HEADER = '\\pard\\nowidctlpar {\\cf0\\f0 '; + const HEADER = '\\pard\\widctlpar {\\cf0\\f0 '; const TRAILER = '}\\par'; public function escapestring($str) From a547f04b7dd2a247603d3556f0b0185d1a636275 Mon Sep 17 00:00:00 2001 From: rasamassen Date: Mon, 8 Sep 2025 20:59:46 -0500 Subject: [PATCH 06/53] Update RtfEscaper3Test.php - Replace nowidctlpar with widctlpar - Widow/Orphan controls is default true. --- tests/PhpWordTests/Escaper/RtfEscaper3Test.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/PhpWordTests/Escaper/RtfEscaper3Test.php b/tests/PhpWordTests/Escaper/RtfEscaper3Test.php index 1aebea52f0..93032e06cb 100644 --- a/tests/PhpWordTests/Escaper/RtfEscaper3Test.php +++ b/tests/PhpWordTests/Escaper/RtfEscaper3Test.php @@ -25,8 +25,8 @@ */ class RtfEscaper3Test extends \PHPUnit\Framework\TestCase { - const HEADER = '\\pard\\nowidctlpar \ql{\\cf0\\f0 '; - const HEADER_RTL = '\\pard\\nowidctlpar \qr{\\rtlch\\cf0\\f0 '; + const HEADER = '\\pard\\widctlpar \ql{\\cf0\\f0 '; + const HEADER_RTL = '\\pard\\widctlpar \qr{\\rtlch\\cf0\\f0 '; const TRAILER = '}\\par'; protected function tearDown(): void From 6a4ba01508396dfd5b70835af8e25223041cf462 Mon Sep 17 00:00:00 2001 From: rasamassen Date: Mon, 8 Sep 2025 21:01:29 -0500 Subject: [PATCH 07/53] Update Element2Test.php - Replace nowidctlpar with widctlpar - Widow/Orphan controls is default true. --- tests/PhpWordTests/Writer/RTF/Element2Test.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/PhpWordTests/Writer/RTF/Element2Test.php b/tests/PhpWordTests/Writer/RTF/Element2Test.php index 2220d93b68..d2798dda1d 100644 --- a/tests/PhpWordTests/Writer/RTF/Element2Test.php +++ b/tests/PhpWordTests/Writer/RTF/Element2Test.php @@ -47,7 +47,7 @@ public function testTextRun(): void $element->addText('Hello '); $element->addText('there.'); $textrun = new WriterTextRun($parentWriter, $element); - $expect = "\\pard\\nowidctlpar \\ql{{\\cf0\\f0 Hello }{\\cf0\\f0 there.}}\\par\n"; + $expect = "\\pard\\widctlpar \\ql{{\\cf0\\f0 Hello }{\\cf0\\f0 there.}}\\par\n"; self::assertEquals($expect, $this->removeCr($textrun)); } @@ -59,7 +59,7 @@ public function testTextRunParagraphStyle(): void $element->addText('Hello '); $element->addText('there.'); $textrun = new WriterTextRun($parentWriter, $element); - $expect = "\\pard\\nowidctlpar \\ql\\sb0\\sa0{{\\cf0\\f0 Hello }{\\cf0\\f0 there.}}\\par\n"; + $expect = "\\pard\\widctlpar \\ql\\sb0\\sa0{{\\cf0\\f0 Hello }{\\cf0\\f0 there.}}\\par\n"; self::assertEquals($expect, $this->removeCr($textrun)); } @@ -72,7 +72,7 @@ public function testTitle(): void $section = $phpWord->addSection(); $element = $section->addTitle('First Heading', 1); $elwrite = new WriterTitle($parentWriter, $element); - $expect = "\\pard\\nowidctlpar \\ql\\sb0\\sa0{\\outlinelevel0{\\cf0\\f0 First Heading}\\par\n}"; + $expect = "\\pard\\widctlpar \\ql\\sb0\\sa0{\\outlinelevel0{\\cf0\\f0 First Heading}\\par\n}"; self::assertEquals($expect, $this->removeCr($elwrite)); Settings::setDefaultRtl(null); } From 97ddc80673d4b9e4593c997d81c2da278479e47e Mon Sep 17 00:00:00 2001 From: rasamassen Date: Mon, 8 Sep 2025 21:01:46 -0500 Subject: [PATCH 08/53] Update ElementTest.php - Replace nowidctlpar with widctlpar - Widow/Orphan controls is default true. --- tests/PhpWordTests/Writer/RTF/ElementTest.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/PhpWordTests/Writer/RTF/ElementTest.php b/tests/PhpWordTests/Writer/RTF/ElementTest.php index 36504a18f8..5983b4c34e 100644 --- a/tests/PhpWordTests/Writer/RTF/ElementTest.php +++ b/tests/PhpWordTests/Writer/RTF/ElementTest.php @@ -149,7 +149,7 @@ public function testTextRun(): void $element->addText('Hello '); $element->addText('there.'); $textrun = new RTF\Element\TextRun($parentWriter, $element); - $expect = "\\pard\\nowidctlpar {{\\cf0\\f0 Hello }{\\cf0\\f0 there.}}\\par\n"; + $expect = "\\pard\\widctlpar {{\\cf0\\f0 Hello }{\\cf0\\f0 there.}}\\par\n"; self::assertEquals($expect, $this->removeCr($textrun)); } @@ -160,7 +160,7 @@ public function testTextRunParagraphStyle(): void $element->addText('Hello '); $element->addText('there.'); $textrun = new RTF\Element\TextRun($parentWriter, $element); - $expect = "\\pard\\nowidctlpar \\sb0\\sa0{{\\cf0\\f0 Hello }{\\cf0\\f0 there.}}\\par\n"; + $expect = "\\pard\\widctlpar \\sb0\\sa0{{\\cf0\\f0 Hello }{\\cf0\\f0 there.}}\\par\n"; self::assertEquals($expect, $this->removeCr($textrun)); } @@ -172,7 +172,7 @@ public function testTitle(): void $section = $phpWord->addSection(); $element = $section->addTitle('First Heading', 1); $elwrite = new RTF\Element\Title($parentWriter, $element); - $expect = "\\pard\\nowidctlpar \\sb0\\sa0{\\outlinelevel0{\\cf0\\f0 First Heading}\\par\n}"; + $expect = "\\pard\\widctlpar \\sb0\\sa0{\\outlinelevel0{\\cf0\\f0 First Heading}\\par\n}"; self::assertEquals($expect, $this->removeCr($elwrite)); } @@ -188,7 +188,7 @@ public function testRuby(): void $element->addRuby($baseTextRun, $rubyTextRun, $properties); $textrun = new RTF\Element\TextRun($parentWriter, $element); - $expect = "\\pard\\nowidctlpar {{base text (ruby)}}\\par\n"; + $expect = "\\pard\\widctlpar {{base text (ruby)}}\\par\n"; self::assertEquals($expect, $this->removeCr($textrun)); } @@ -213,7 +213,7 @@ public function testRubyTitle(): void $element = $section->addTitle($textRun, 1); $elwrite = new RTF\Element\Title($parentWriter, $element); - $expect = "\\pard\\nowidctlpar \\sb0\\sa2{\\outlinelevel0{\\cf0\\f0\\fs48\\b base text (ruby)}\\par\n}"; + $expect = "\\pard\\widctlpar \\sb0\\sa2{\\outlinelevel0{\\cf0\\f0\\fs48\\b base text (ruby)}\\par\n}"; self::assertEquals($expect, $this->removeCr($elwrite)); } } From bf7f10b1f0a93c7f6b30ba6829483e7a5c1daefa Mon Sep 17 00:00:00 2001 From: rasamassen Date: Mon, 8 Sep 2025 21:02:17 -0500 Subject: [PATCH 09/53] Update StyleTest.php - Replace nowidctlpar with widctlpar - Widow/Orphan controls is default true. --- tests/PhpWordTests/Writer/RTF/StyleTest.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/PhpWordTests/Writer/RTF/StyleTest.php b/tests/PhpWordTests/Writer/RTF/StyleTest.php index 8ba2bcb9c9..e03e68aa7e 100644 --- a/tests/PhpWordTests/Writer/RTF/StyleTest.php +++ b/tests/PhpWordTests/Writer/RTF/StyleTest.php @@ -126,7 +126,7 @@ public function testRTL(): void $parentWriter = new RTF(); $element = new \PhpOffice\PhpWord\Element\Text('אב גד', ['RTL' => true]); $text = new RTF\Element\Text($parentWriter, $element); - $expect = "\\pard\\nowidctlpar {\\rtlch\\cf0\\f0 \\uc0{\\u1488}\\uc0{\\u1489} \\uc0{\\u1490}\\uc0{\\u1491}}\\par\n"; + $expect = "\\pard\\widctlpar {\\rtlch\\cf0\\f0 \\uc0{\\u1488}\\uc0{\\u1489} \\uc0{\\u1490}\\uc0{\\u1491}}\\par\n"; self::assertEquals($expect, $this->removeCr($text)); } @@ -136,7 +136,7 @@ public function testRTL2(): void $parentWriter = new RTF(); $element = new \PhpOffice\PhpWord\Element\Text('אב גד'); $text = new RTF\Element\Text($parentWriter, $element); - $expect = "\\pard\\nowidctlpar \\qr{\\rtlch\\cf0\\f0 \\uc0{\\u1488}\\uc0{\\u1489} \\uc0{\\u1490}\\uc0{\\u1491}}\\par\n"; + $expect = "\\pard\\widctlpar \\qr{\\rtlch\\cf0\\f0 \\uc0{\\u1488}\\uc0{\\u1489} \\uc0{\\u1490}\\uc0{\\u1491}}\\par\n"; self::assertEquals($expect, $this->removeCr($text)); } @@ -145,7 +145,7 @@ public function testPageBreakLineHeight(): void $parentWriter = new RTF(); $element = new \PhpOffice\PhpWord\Element\Text('New page', null, ['lineHeight' => 1.08, 'pageBreakBefore' => true]); $text = new RTF\Element\Text($parentWriter, $element); - $expect = "\\pard\\nowidctlpar \\sl259\\slmult1\\page{\\cf0\\f0 New page}\\par\n"; + $expect = "\\pard\\widctlpar \\sl259\\slmult1\\page{\\cf0\\f0 New page}\\par\n"; self::assertEquals($expect, $this->removeCr($text)); } @@ -155,7 +155,7 @@ public function testPageBreakLineHeight2(): void $parentWriter = new RTF(); $element = new \PhpOffice\PhpWord\Element\Text('New page', null, ['lineHeight' => 1.08, 'pageBreakBefore' => true]); $text = new RTF\Element\Text($parentWriter, $element); - $expect = "\\pard\\nowidctlpar \\ql\\sl259\\slmult1\\page{\\cf0\\f0 New page}\\par\n"; + $expect = "\\pard\\widctlpar \\ql\\sl259\\slmult1\\page{\\cf0\\f0 New page}\\par\n"; self::assertEquals($expect, $this->removeCr($text)); } From 097c050093a5654b6192177da83b3f8c568fbfc2 Mon Sep 17 00:00:00 2001 From: rasamassen Date: Mon, 8 Sep 2025 22:45:15 -0500 Subject: [PATCH 10/53] Update RtfEscaper3Test.php - Fix Test --- tests/PhpWordTests/Escaper/RtfEscaper3Test.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/PhpWordTests/Escaper/RtfEscaper3Test.php b/tests/PhpWordTests/Escaper/RtfEscaper3Test.php index 93032e06cb..5af39f6e63 100644 --- a/tests/PhpWordTests/Escaper/RtfEscaper3Test.php +++ b/tests/PhpWordTests/Escaper/RtfEscaper3Test.php @@ -25,8 +25,8 @@ */ class RtfEscaper3Test extends \PHPUnit\Framework\TestCase { - const HEADER = '\\pard\\widctlpar \ql{\\cf0\\f0 '; - const HEADER_RTL = '\\pard\\widctlpar \qr{\\rtlch\\cf0\\f0 '; + const HEADER = '\\pard\\ql\\widctlpar {\\cf0\\f0 '; + const HEADER_RTL = '\\pard\\qr\\widctlpar {\\rtlch\\cf0\\f0 '; const TRAILER = '}\\par'; protected function tearDown(): void From fcf45f29b209b85daad9b8453583185a55a2afeb Mon Sep 17 00:00:00 2001 From: rasamassen Date: Mon, 8 Sep 2025 22:46:29 -0500 Subject: [PATCH 11/53] Update TableTest.php - Fix test --- tests/PhpWordTests/Writer/RTF/Element/TableTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/PhpWordTests/Writer/RTF/Element/TableTest.php b/tests/PhpWordTests/Writer/RTF/Element/TableTest.php index 7c1ceac68e..8f930c8773 100644 --- a/tests/PhpWordTests/Writer/RTF/Element/TableTest.php +++ b/tests/PhpWordTests/Writer/RTF/Element/TableTest.php @@ -67,7 +67,7 @@ public function testTable(): void '\\row', "\\trowd \\cellx$width \\cellx$width2 ", '\\intbl', - '\\ql{\\cf0\\f0 3}\\par', + '\\ql\\widctlpar {\\cf0\\f0 3}\\par', '\\cell', '\\intbl', '{\\cf0\\f0 4}\par', From 7e30fd61e60a0f23de711410cde95ceae37277b9 Mon Sep 17 00:00:00 2001 From: rasamassen Date: Mon, 8 Sep 2025 22:47:14 -0500 Subject: [PATCH 12/53] Update Element2Test.php - Fix Test --- tests/PhpWordTests/Writer/RTF/Element2Test.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/PhpWordTests/Writer/RTF/Element2Test.php b/tests/PhpWordTests/Writer/RTF/Element2Test.php index d2798dda1d..ed33b92e21 100644 --- a/tests/PhpWordTests/Writer/RTF/Element2Test.php +++ b/tests/PhpWordTests/Writer/RTF/Element2Test.php @@ -47,7 +47,7 @@ public function testTextRun(): void $element->addText('Hello '); $element->addText('there.'); $textrun = new WriterTextRun($parentWriter, $element); - $expect = "\\pard\\widctlpar \\ql{{\\cf0\\f0 Hello }{\\cf0\\f0 there.}}\\par\n"; + $expect = "\\pard\\ql\\widctlpar {{\\cf0\\f0 Hello }{\\cf0\\f0 there.}}\\par\n"; self::assertEquals($expect, $this->removeCr($textrun)); } @@ -59,7 +59,7 @@ public function testTextRunParagraphStyle(): void $element->addText('Hello '); $element->addText('there.'); $textrun = new WriterTextRun($parentWriter, $element); - $expect = "\\pard\\widctlpar \\ql\\sb0\\sa0{{\\cf0\\f0 Hello }{\\cf0\\f0 there.}}\\par\n"; + $expect = "\\pard\\ql\\sb0\\sa0\\widctlpar {{\\cf0\\f0 Hello }{\\cf0\\f0 there.}}\\par\n"; self::assertEquals($expect, $this->removeCr($textrun)); } @@ -72,7 +72,7 @@ public function testTitle(): void $section = $phpWord->addSection(); $element = $section->addTitle('First Heading', 1); $elwrite = new WriterTitle($parentWriter, $element); - $expect = "\\pard\\widctlpar \\ql\\sb0\\sa0{\\outlinelevel0{\\cf0\\f0 First Heading}\\par\n}"; + $expect = "\\pard\\ql\\sb0\\sa0\\widctlpar {\\outlinelevel0{\\cf0\\f0 First Heading}\\par\n}"; self::assertEquals($expect, $this->removeCr($elwrite)); Settings::setDefaultRtl(null); } From 63559b56a3620594ff1a693abc0e712b7ce69546 Mon Sep 17 00:00:00 2001 From: rasamassen Date: Mon, 8 Sep 2025 22:48:14 -0500 Subject: [PATCH 13/53] Update ElementTest.php - Fix Test --- tests/PhpWordTests/Writer/RTF/ElementTest.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/PhpWordTests/Writer/RTF/ElementTest.php b/tests/PhpWordTests/Writer/RTF/ElementTest.php index 5983b4c34e..8cd04996e0 100644 --- a/tests/PhpWordTests/Writer/RTF/ElementTest.php +++ b/tests/PhpWordTests/Writer/RTF/ElementTest.php @@ -160,7 +160,7 @@ public function testTextRunParagraphStyle(): void $element->addText('Hello '); $element->addText('there.'); $textrun = new RTF\Element\TextRun($parentWriter, $element); - $expect = "\\pard\\widctlpar \\sb0\\sa0{{\\cf0\\f0 Hello }{\\cf0\\f0 there.}}\\par\n"; + $expect = "\\pard\\sb0\\sa0\\widctlpar {{\\cf0\\f0 Hello }{\\cf0\\f0 there.}}\\par\n"; self::assertEquals($expect, $this->removeCr($textrun)); } @@ -172,7 +172,7 @@ public function testTitle(): void $section = $phpWord->addSection(); $element = $section->addTitle('First Heading', 1); $elwrite = new RTF\Element\Title($parentWriter, $element); - $expect = "\\pard\\widctlpar \\sb0\\sa0{\\outlinelevel0{\\cf0\\f0 First Heading}\\par\n}"; + $expect = "\\pard\\sb0\\sa0\\widctlpar {\\outlinelevel0{\\cf0\\f0 First Heading}\\par\n}"; self::assertEquals($expect, $this->removeCr($elwrite)); } @@ -213,7 +213,7 @@ public function testRubyTitle(): void $element = $section->addTitle($textRun, 1); $elwrite = new RTF\Element\Title($parentWriter, $element); - $expect = "\\pard\\widctlpar \\sb0\\sa2{\\outlinelevel0{\\cf0\\f0\\fs48\\b base text (ruby)}\\par\n}"; + $expect = "\\pard\\sb0\\sa2\\widctlpar {\\outlinelevel0{\\cf0\\f0\\fs48\\b base text (ruby)}\\par\n}"; self::assertEquals($expect, $this->removeCr($elwrite)); } } From 1e333b6695128d40fa4fe14a6a2b4c0322025d20 Mon Sep 17 00:00:00 2001 From: rasamassen Date: Mon, 8 Sep 2025 22:49:36 -0500 Subject: [PATCH 14/53] Update StyleTest.php - Fix test --- tests/PhpWordTests/Writer/RTF/StyleTest.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/PhpWordTests/Writer/RTF/StyleTest.php b/tests/PhpWordTests/Writer/RTF/StyleTest.php index e03e68aa7e..789d0e4821 100644 --- a/tests/PhpWordTests/Writer/RTF/StyleTest.php +++ b/tests/PhpWordTests/Writer/RTF/StyleTest.php @@ -136,7 +136,7 @@ public function testRTL2(): void $parentWriter = new RTF(); $element = new \PhpOffice\PhpWord\Element\Text('אב גד'); $text = new RTF\Element\Text($parentWriter, $element); - $expect = "\\pard\\widctlpar \\qr{\\rtlch\\cf0\\f0 \\uc0{\\u1488}\\uc0{\\u1489} \\uc0{\\u1490}\\uc0{\\u1491}}\\par\n"; + $expect = "\\pard\\qr\\widctlpar {\\rtlch\\cf0\\f0 \\uc0{\\u1488}\\uc0{\\u1489} \\uc0{\\u1490}\\uc0{\\u1491}}\\par\n"; self::assertEquals($expect, $this->removeCr($text)); } @@ -145,7 +145,7 @@ public function testPageBreakLineHeight(): void $parentWriter = new RTF(); $element = new \PhpOffice\PhpWord\Element\Text('New page', null, ['lineHeight' => 1.08, 'pageBreakBefore' => true]); $text = new RTF\Element\Text($parentWriter, $element); - $expect = "\\pard\\widctlpar \\sl259\\slmult1\\page{\\cf0\\f0 New page}\\par\n"; + $expect = "\\pard\\sl259\\slmult1\\widctlpar\\pagebb {\\cf0\\f0 New page}\\par\n"; self::assertEquals($expect, $this->removeCr($text)); } @@ -155,7 +155,7 @@ public function testPageBreakLineHeight2(): void $parentWriter = new RTF(); $element = new \PhpOffice\PhpWord\Element\Text('New page', null, ['lineHeight' => 1.08, 'pageBreakBefore' => true]); $text = new RTF\Element\Text($parentWriter, $element); - $expect = "\\pard\\widctlpar \\ql\\sl259\\slmult1\\page{\\cf0\\f0 New page}\\par\n"; + $expect = "\\pard\\ql\\sl259\\slmult1\\widctlpar\\pagebb {\\cf0\\f0 New page}\\par\n"; self::assertEquals($expect, $this->removeCr($text)); } From b8aac4856726fd1d9b255a647e3adab694be1e58 Mon Sep 17 00:00:00 2001 From: rasamassen Date: Mon, 8 Sep 2025 22:56:39 -0500 Subject: [PATCH 15/53] Update TableTest.php - Fix test --- tests/PhpWordTests/Writer/RTF/Element/TableTest.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/PhpWordTests/Writer/RTF/Element/TableTest.php b/tests/PhpWordTests/Writer/RTF/Element/TableTest.php index 8f930c8773..182d0e7199 100644 --- a/tests/PhpWordTests/Writer/RTF/Element/TableTest.php +++ b/tests/PhpWordTests/Writer/RTF/Element/TableTest.php @@ -59,7 +59,7 @@ public function testTable(): void '\\pard', "\\trowd \\cellx$width \\cellx$width2 ", '\\intbl', - '\\ql{\\cf0\\f0 1}\\par', + '\\ql\\widctlpar {\\cf0\\f0 1}\\par', '\\cell', '\\intbl', '{\\cf0\\f0 2}\\par', @@ -70,7 +70,7 @@ public function testTable(): void '\\ql\\widctlpar {\\cf0\\f0 3}\\par', '\\cell', '\\intbl', - '{\\cf0\\f0 4}\par', + '\\widctlpar {\\cf0\\f0 4}\par', '\\cell', '\\row', '\\pard', @@ -102,7 +102,7 @@ public function testTableStyle(): void '\\clbrdrr\\brdrs\\brdrw2\\brdrcf0', "\\cellx$width ", '\\intbl', - '\\ql{\\cf0\\f0 1}\\par', + '\\ql\\widctlpar {\\cf0\\f0 1}\\par', '\\cell', '\\row', '\\pard', @@ -128,7 +128,7 @@ public function testTableStyleNotExisting(): void '\\pard', "\\trowd \\cellx$width ", '\\intbl', - '\\ql{\\cf0\\f0 1}\\par', + '\\ql\\widctlpar {\\cf0\\f0 1}\\par', '\\cell', '\\row', '\\pard', @@ -158,7 +158,7 @@ public function testTableCellStyle(): void '\\clbrdrr\\brdrdot\\brdrw2\\brdrcf0', "\\cellx$width ", '\\intbl', - '\\ql{\\cf0\\f0 1}\\par', + '\\ql\\widctlpar {\\cf0\\f0 1}\\par', '\\cell', '\\row', '\\pard', From 5c22beb8b24de03a47f891241dbdf616e8733a2a Mon Sep 17 00:00:00 2001 From: rasamassen Date: Mon, 8 Sep 2025 23:01:38 -0500 Subject: [PATCH 16/53] Update TableTest.php - Hopefully final Fix test --- tests/PhpWordTests/Writer/RTF/Element/TableTest.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/PhpWordTests/Writer/RTF/Element/TableTest.php b/tests/PhpWordTests/Writer/RTF/Element/TableTest.php index 182d0e7199..0158e21260 100644 --- a/tests/PhpWordTests/Writer/RTF/Element/TableTest.php +++ b/tests/PhpWordTests/Writer/RTF/Element/TableTest.php @@ -59,7 +59,7 @@ public function testTable(): void '\\pard', "\\trowd \\cellx$width \\cellx$width2 ", '\\intbl', - '\\ql\\widctlpar {\\cf0\\f0 1}\\par', + '\\widctlpar {\\cf0\\f0 1}\\par', '\\cell', '\\intbl', '{\\cf0\\f0 2}\\par', @@ -67,10 +67,10 @@ public function testTable(): void '\\row', "\\trowd \\cellx$width \\cellx$width2 ", '\\intbl', - '\\ql\\widctlpar {\\cf0\\f0 3}\\par', + '\\widctlpar {\\cf0\\f0 3}\\par', '\\cell', '\\intbl', - '\\widctlpar {\\cf0\\f0 4}\par', + '{\\cf0\\f0 4}\par', '\\cell', '\\row', '\\pard', From d7045a212320d65c5622bc5f0a00b69e2d888ea0 Mon Sep 17 00:00:00 2001 From: rasamassen Date: Mon, 8 Sep 2025 23:04:14 -0500 Subject: [PATCH 17/53] Update TableTest.php - Fix test --- tests/PhpWordTests/Writer/RTF/Element/TableTest.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/PhpWordTests/Writer/RTF/Element/TableTest.php b/tests/PhpWordTests/Writer/RTF/Element/TableTest.php index 0158e21260..df8c0e6258 100644 --- a/tests/PhpWordTests/Writer/RTF/Element/TableTest.php +++ b/tests/PhpWordTests/Writer/RTF/Element/TableTest.php @@ -59,7 +59,7 @@ public function testTable(): void '\\pard', "\\trowd \\cellx$width \\cellx$width2 ", '\\intbl', - '\\widctlpar {\\cf0\\f0 1}\\par', + '\\ql\\widctlpar {\\cf0\\f0 1}\\par', '\\cell', '\\intbl', '{\\cf0\\f0 2}\\par', @@ -67,7 +67,7 @@ public function testTable(): void '\\row', "\\trowd \\cellx$width \\cellx$width2 ", '\\intbl', - '\\widctlpar {\\cf0\\f0 3}\\par', + '\\ql\\widctlpar {\\cf0\\f0 3}\\par', '\\cell', '\\intbl', '{\\cf0\\f0 4}\par', From 3d63e9614c47d973cf82bfba077dc401e1386208 Mon Sep 17 00:00:00 2001 From: rasamassen Date: Mon, 8 Sep 2025 23:05:02 -0500 Subject: [PATCH 18/53] Update ElementTest.php - Fix tests --- tests/PhpWordTests/Writer/RTF/ElementTest.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/PhpWordTests/Writer/RTF/ElementTest.php b/tests/PhpWordTests/Writer/RTF/ElementTest.php index 8cd04996e0..1c2de17ca7 100644 --- a/tests/PhpWordTests/Writer/RTF/ElementTest.php +++ b/tests/PhpWordTests/Writer/RTF/ElementTest.php @@ -121,7 +121,7 @@ public function testTable(): void '\\pard', "\\trowd \\cellx$width \\cellx$width2 ", '\\intbl', - '{\\cf0\\f0 1}\\par', + '\\widctlpar {\\cf0\\f0 1}\\par', '\\cell', '\\intbl', '{\\cf0\\f0 2}\\par', @@ -129,7 +129,7 @@ public function testTable(): void '\\row', "\\trowd \\cellx$width \\cellx$width2 ", '\\intbl', - '{\\cf0\\f0 3}\\par', + '\\widctlpar {\\cf0\\f0 3}\\par', '\\cell', '\\intbl', '{\\cf0\\f0 4}\par', From 06c7c8598e28f2264ff1509c12a05d56f282aee0 Mon Sep 17 00:00:00 2001 From: rasamassen Date: Fri, 3 Oct 2025 17:50:37 -0500 Subject: [PATCH 19/53] Update Paragraph.php - Fix deprecated features --- src/PhpWord/Writer/RTF/Style/Paragraph.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/PhpWord/Writer/RTF/Style/Paragraph.php b/src/PhpWord/Writer/RTF/Style/Paragraph.php index 88df6c27de..88e599ea5d 100644 --- a/src/PhpWord/Writer/RTF/Style/Paragraph.php +++ b/src/PhpWord/Writer/RTF/Style/Paragraph.php @@ -36,9 +36,9 @@ class Paragraph extends AbstractStyle */ private $nestedLevel = 0; - private const LEFT = Jc::LEFT; - private const RIGHT = Jc::RIGHT; - private const JUSTIFY = Jc::JUSTIFY; + private const LEFT = Jc::START; + private const RIGHT = Jc::END; + private const JUSTIFY = Jc::BOTH; /** * Write style. From 66de8748c7ad242d46e0b6264d319ded91edc2d7 Mon Sep 17 00:00:00 2001 From: rasamassen Date: Fri, 3 Oct 2025 18:08:54 -0500 Subject: [PATCH 20/53] Update Paragraph.php - Fix justification, add missing options. --- src/PhpWord/Writer/RTF/Style/Paragraph.php | 26 +++++++++++++--------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/src/PhpWord/Writer/RTF/Style/Paragraph.php b/src/PhpWord/Writer/RTF/Style/Paragraph.php index 88e599ea5d..3148d882fb 100644 --- a/src/PhpWord/Writer/RTF/Style/Paragraph.php +++ b/src/PhpWord/Writer/RTF/Style/Paragraph.php @@ -36,10 +36,6 @@ class Paragraph extends AbstractStyle */ private $nestedLevel = 0; - private const LEFT = Jc::START; - private const RIGHT = Jc::END; - private const JUSTIFY = Jc::BOTH; - /** * Write style. * @@ -57,18 +53,28 @@ public function write() Jc::END => '\qr', Jc::CENTER => '\qc', Jc::BOTH => '\qj', - self::LEFT => '\ql', - self::RIGHT => '\qr', - self::JUSTIFY => '\qj', + Jc::LEFT => '\ql', + Jc::RIGHT => '\qr', + Jc::JUSTIFY => '\qj', + Jc::DISTRIBUTE => '\qd', + Jc::THAI_DISTRIBUTE => '\qt', + Jc::HIGH_KASHIDA => '\qk20', + Jc::MEDIUM_KASHIDA => '\qk10', + Jc::LOW_KASHIDA => '\qk0', ]; $bidiAlignments = [ Jc::START => '\qr', Jc::END => '\ql', Jc::CENTER => '\qc', Jc::BOTH => '\qj', - self::LEFT => '\ql', - self::RIGHT => '\qr', - self::JUSTIFY => '\qj', + Jc::LEFT => '\ql', + Jc::RIGHT => '\qr', + Jc::JUSTIFY => '\qj', + Jc::DISTRIBUTE => '\qd', + Jc::THAI_DISTRIBUTE => '\qt', + Jc::HIGH_KASHIDA => '\qk20', + Jc::MEDIUM_KASHIDA => '\qk10', + Jc::LOW_KASHIDA => '\qk0', ]; $spaceAfter = $style->getSpaceAfter(); From 0c7f3b252ee1ac56670485e2b664d220f41e198b Mon Sep 17 00:00:00 2001 From: rasamassen Date: Fri, 3 Oct 2025 18:10:42 -0500 Subject: [PATCH 21/53] Create ParagraphTest.php - Initial build --- .../Writer/RTF/Style/ParagraphTest.php | 55 +++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 tests/PhpWordTests/Writer/RTF/Style/ParagraphTest.php diff --git a/tests/PhpWordTests/Writer/RTF/Style/ParagraphTest.php b/tests/PhpWordTests/Writer/RTF/Style/ParagraphTest.php new file mode 100644 index 0000000000..e7bd22859e --- /dev/null +++ b/tests/PhpWordTests/Writer/RTF/Style/ParagraphTest.php @@ -0,0 +1,55 @@ +write()); + } + + /** + * Test alignment. + * See page 79 of RTF Specification 1.9.1. + */ + public function testParagraphAlign(): void + { + $parentWriter = new RTF(); + $style = new ParagraphStyle()->setAlignment(Jc::START); + $writer = new ParagraphWriter($parentWriter, $style); + $expect = "\\pard\\ql "; + self::assertEquals($expect, $this->removeCr($writer)); + } +} From 1a8897fb01a7283ddd85781f18a1a75ff16a00f9 Mon Sep 17 00:00:00 2001 From: rasamassen Date: Fri, 3 Oct 2025 18:14:26 -0500 Subject: [PATCH 22/53] Update ParagraphTest.php --- tests/PhpWordTests/Writer/RTF/Style/ParagraphTest.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/PhpWordTests/Writer/RTF/Style/ParagraphTest.php b/tests/PhpWordTests/Writer/RTF/Style/ParagraphTest.php index e7bd22859e..567667f74b 100644 --- a/tests/PhpWordTests/Writer/RTF/Style/ParagraphTest.php +++ b/tests/PhpWordTests/Writer/RTF/Style/ParagraphTest.php @@ -47,7 +47,8 @@ public function removeCr($field): string public function testParagraphAlign(): void { $parentWriter = new RTF(); - $style = new ParagraphStyle()->setAlignment(Jc::START); + $style = new ParagraphStyle(); + $style->setAlignment(Jc::START); $writer = new ParagraphWriter($parentWriter, $style); $expect = "\\pard\\ql "; self::assertEquals($expect, $this->removeCr($writer)); From 953cc31adb961ec73bb1e26fa28198a8ee51d651 Mon Sep 17 00:00:00 2001 From: rasamassen Date: Fri, 3 Oct 2025 18:21:38 -0500 Subject: [PATCH 23/53] Update ParagraphTest.php --- tests/PhpWordTests/Writer/RTF/Style/ParagraphTest.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/PhpWordTests/Writer/RTF/Style/ParagraphTest.php b/tests/PhpWordTests/Writer/RTF/Style/ParagraphTest.php index 567667f74b..ca5573dc3b 100644 --- a/tests/PhpWordTests/Writer/RTF/Style/ParagraphTest.php +++ b/tests/PhpWordTests/Writer/RTF/Style/ParagraphTest.php @@ -16,7 +16,7 @@ * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 */ -namespace PhpOffice\PhpWordTests\Writer\RTF\Styke; +namespace PhpOffice\PhpWordTests\Writer\RTF\Style; use PhpOffice\PhpWord\SimpleType\Jc; use PhpOffice\PhpWord\Style\Paragraph as ParagraphStyle; @@ -49,7 +49,8 @@ public function testParagraphAlign(): void $parentWriter = new RTF(); $style = new ParagraphStyle(); $style->setAlignment(Jc::START); - $writer = new ParagraphWriter($parentWriter, $style); + $writer = new ParagraphWriter($style); + $writer->setParentWriter($parentWriter); $expect = "\\pard\\ql "; self::assertEquals($expect, $this->removeCr($writer)); } From 6eb482a29eb9d608e55cbcc1805a8f66da342c3c Mon Sep 17 00:00:00 2001 From: rasamassen Date: Fri, 3 Oct 2025 18:25:43 -0500 Subject: [PATCH 24/53] Update ParagraphTest.php --- tests/PhpWordTests/Writer/RTF/Style/ParagraphTest.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tests/PhpWordTests/Writer/RTF/Style/ParagraphTest.php b/tests/PhpWordTests/Writer/RTF/Style/ParagraphTest.php index ca5573dc3b..b314767390 100644 --- a/tests/PhpWordTests/Writer/RTF/Style/ParagraphTest.php +++ b/tests/PhpWordTests/Writer/RTF/Style/ParagraphTest.php @@ -51,7 +51,11 @@ public function testParagraphAlign(): void $style->setAlignment(Jc::START); $writer = new ParagraphWriter($style); $writer->setParentWriter($parentWriter); - $expect = "\\pard\\ql "; + $expect = '\\pard\\ql\\widctlpar '; + self::assertEquals($expect, $this->removeCr($writer)); + + $style->setAlignment(Jc::CENTER); + $expect = '\\pard\\qc\\widctlpar '; self::assertEquals($expect, $this->removeCr($writer)); } } From 5aa739649973ef7d18dccd0f6f397e68aab160d0 Mon Sep 17 00:00:00 2001 From: rasamassen Date: Fri, 3 Oct 2025 19:02:49 -0500 Subject: [PATCH 25/53] Update ParagraphTest.php - Add tests --- .../Writer/RTF/Style/ParagraphTest.php | 110 +++++++++++++++++- 1 file changed, 108 insertions(+), 2 deletions(-) diff --git a/tests/PhpWordTests/Writer/RTF/Style/ParagraphTest.php b/tests/PhpWordTests/Writer/RTF/Style/ParagraphTest.php index b314767390..e1b49f14ed 100644 --- a/tests/PhpWordTests/Writer/RTF/Style/ParagraphTest.php +++ b/tests/PhpWordTests/Writer/RTF/Style/ParagraphTest.php @@ -18,9 +18,10 @@ namespace PhpOffice\PhpWordTests\Writer\RTF\Style; +use PhpOffice\PhpWord\Settings; use PhpOffice\PhpWord\SimpleType\Jc; +use PhpOffice\PhpWord\SimpleType\LineSpacingRule; use PhpOffice\PhpWord\Style\Paragraph as ParagraphStyle; -use PhpOffice\PhpWord\Settings; use PhpOffice\PhpWord\Writer\RTF; use PhpOffice\PhpWord\Writer\RTF\Style\Paragraph as ParagraphWriter; use PHPUnit\Framework\TestCase; @@ -57,5 +58,110 @@ public function testParagraphAlign(): void $style->setAlignment(Jc::CENTER); $expect = '\\pard\\qc\\widctlpar '; self::assertEquals($expect, $this->removeCr($writer)); - } + + $style->setAlignment(Jc::END); + $expect = '\\pard\\qr\\widctlpar '; + self::assertEquals($expect, $this->removeCr($writer)); + + $style->setAlignment(Jc::BOTH); + $expect = '\\pard\\qj\\widctlpar '; + self::assertEquals($expect, $this->removeCr($writer)); + + $style->setAlignment(Jc::DISTRIBUTE); + $expect = '\\pard\\qd\\widctlpar '; + self::assertEquals($expect, $this->removeCr($writer)); + + $style->setAlignment(Jc::THAI_DISTRIBUTE); + $expect = '\\pard\\qt\\widctlpar '; + self::assertEquals($expect, $this->removeCr($writer)); + + $style->setAlignment(Jc::HIGH_KASHIDA); + $expect = '\\pard\\qk20\\widctlpar '; + self::assertEquals($expect, $this->removeCr($writer)); + + $style->setAlignment(Jc::MEDIUM_KASHIDA); + $expect = '\\pard\\qk10\\widctlpar '; + self::assertEquals($expect, $this->removeCr($writer)); + + $style->setAlignment(Jc::LOW_KASHIDA); + $expect = '\\pard\\qk0\\widctlpar '; + self::assertEquals($expect, $this->removeCr($writer)); + + $style->setAlignment(Jc::START); + $style->setBidi(true); + $expect = '\\pard\\qr\\widctlpar '; + self::assertEquals($expect, $this->removeCr($writer)); + + $style->setAlignment(Jc::END); + $style->setBidi(true); + $expect = '\\pard\\ql\\widctlpar '; + self::assertEquals($expect, $this->removeCr($writer)); + } + + /** + * Test indentation. + * See PHPOFfice\Tests\Writer\RTF\Style\IndentationTest + */ + + /** + * Test formatting. + * See page 79 of RTF Specification 1.9.1. + */ + public function testParagraphFormatting(): void + { + $parentWriter = new RTF(); + $style = new ParagraphStyle(); + $style->setSuppressAutoHyphens(true); + $style->setKeepLines(true); + $style->setKeepNext(true); + $style->setWidowControl(true); + $style->setPageBreakBefore(true); + $writer = new ParagraphWriter($style); + $writer->setParentWriter($parentWriter); + $expect = '\\pard\\widctlpar\\keepn\\keep\\pagebb\\hyphpar '; + self::assertEquals($expect, $this->removeCr($writer)); + + $style->setSuppressAutoHyphens(false); + $style->setKeepLines(false); + $style->setKeepNext(false); + $style->setWidowControl(false); + $style->setPageBreakBefore(false); + $expect = '\\pard\\nowidctlpar '; + self::assertEquals($expect, $this->removeCr($writer)); + } + + /** + * Test spacing. + * See page 80 of RTF Specification 1.9.1. + */ + public function testParagraphSpacing(): void + { + $parentWriter = new RTF(); + $style = new ParagraphStyle(); + $style->setSpaceBefore(240); + $style->setSpaceAfter(120); + $style->setLineHeight(1.5); + $style->setContextualSpacing(false); + $writer = new ParagraphWriter($style); + $writer->setParentWriter($parentWriter); + $expect = '\\pard\\sb240\\sa120\\sl360\\simult1\\widctlpar '; + self::assertEquals($expect, $this->removeCr($writer)); + + $style->setSpaceBefore(480); + $style->setSpaceAfter(360); + $style->setSpacing(30); + $style->setSpacingLineRule(LineSpacingRule::EXACT); + $style->setContextualSpacing(true); + $expect = '\\pard\\sb480\\sa360\\sl30\\simult0\\contextualspace\\widctlpar '; + self::assertEquals($expect, $this->removeCr($writer)); + } + + /** + * Test tabs. + * See PHPOFfice\Tests\Writer\RTF\Style\TabTest + */ + + /** + * Not Done: basedOn, next, numLevel, numStyle, shading, textAlignment. + */ } From eecc70d455b37032b5258e89557d7882b93b023e Mon Sep 17 00:00:00 2001 From: rasamassen Date: Fri, 3 Oct 2025 19:16:42 -0500 Subject: [PATCH 26/53] Update Paragraph.php - add missing features --- src/PhpWord/Writer/RTF/Style/Paragraph.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/PhpWord/Writer/RTF/Style/Paragraph.php b/src/PhpWord/Writer/RTF/Style/Paragraph.php index 3148d882fb..08e624c949 100644 --- a/src/PhpWord/Writer/RTF/Style/Paragraph.php +++ b/src/PhpWord/Writer/RTF/Style/Paragraph.php @@ -100,6 +100,7 @@ public function write() $lineHeightAdjusted = (int) ($lineHeight * 240); $content .= "\\sl$lineHeightAdjusted\\slmult1"; } + $content .= $this->getValueIf($style->hasContextualSpacing(), '\contextualspace'); // Pagination $content .= $this->getValueIf($style->hasWidowControl(), '\widctlpar'); @@ -107,6 +108,7 @@ public function write() $content .= $this->getValueIf($style->isKeepNext(), '\keepn'); $content .= $this->getValueIf($style->isKeepLines(), '\keep'); $content .= $this->getValueIf($style->hasPageBreakBefore(), '\pagebb'); + $content .= $this->getValueIf($style->hasSuppressAutoHyphens(), '\hyphpar0'); $styles = $style->getStyleValues(); $content .= $this->writeTabs($styles['tabs']); From f43e923c3df6d722382521ed761b396d5211b173 Mon Sep 17 00:00:00 2001 From: rasamassen Date: Fri, 3 Oct 2025 19:16:46 -0500 Subject: [PATCH 27/53] Update ParagraphTest.php --- .../Writer/RTF/Style/ParagraphTest.php | 31 ++++++++++--------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/tests/PhpWordTests/Writer/RTF/Style/ParagraphTest.php b/tests/PhpWordTests/Writer/RTF/Style/ParagraphTest.php index e1b49f14ed..d1defe1dd1 100644 --- a/tests/PhpWordTests/Writer/RTF/Style/ParagraphTest.php +++ b/tests/PhpWordTests/Writer/RTF/Style/ParagraphTest.php @@ -49,9 +49,10 @@ public function testParagraphAlign(): void { $parentWriter = new RTF(); $style = new ParagraphStyle(); - $style->setAlignment(Jc::START); $writer = new ParagraphWriter($style); $writer->setParentWriter($parentWriter); + + $style->setAlignment(Jc::START); $expect = '\\pard\\ql\\widctlpar '; self::assertEquals($expect, $this->removeCr($writer)); @@ -62,7 +63,7 @@ public function testParagraphAlign(): void $style->setAlignment(Jc::END); $expect = '\\pard\\qr\\widctlpar '; self::assertEquals($expect, $this->removeCr($writer)); - + $style->setAlignment(Jc::BOTH); $expect = '\\pard\\qj\\widctlpar '; self::assertEquals($expect, $this->removeCr($writer)); @@ -96,11 +97,11 @@ public function testParagraphAlign(): void $style->setBidi(true); $expect = '\\pard\\ql\\widctlpar '; self::assertEquals($expect, $this->removeCr($writer)); - } + } /** * Test indentation. - * See PHPOFfice\Tests\Writer\RTF\Style\IndentationTest + * See PHPOFfice\Tests\Writer\RTF\Style\IndentationTest. */ /** @@ -111,14 +112,15 @@ public function testParagraphFormatting(): void { $parentWriter = new RTF(); $style = new ParagraphStyle(); + $writer = new ParagraphWriter($style); + $writer->setParentWriter($parentWriter); + $style->setSuppressAutoHyphens(true); $style->setKeepLines(true); $style->setKeepNext(true); $style->setWidowControl(true); $style->setPageBreakBefore(true); - $writer = new ParagraphWriter($style); - $writer->setParentWriter($parentWriter); - $expect = '\\pard\\widctlpar\\keepn\\keep\\pagebb\\hyphpar '; + $expect = '\\pard\\widctlpar\\keepn\\keep\\pagebb\\hyphpar0 '; self::assertEquals($expect, $this->removeCr($writer)); $style->setSuppressAutoHyphens(false); @@ -128,7 +130,7 @@ public function testParagraphFormatting(): void $style->setPageBreakBefore(false); $expect = '\\pard\\nowidctlpar '; self::assertEquals($expect, $this->removeCr($writer)); - } + } /** * Test spacing. @@ -138,13 +140,14 @@ public function testParagraphSpacing(): void { $parentWriter = new RTF(); $style = new ParagraphStyle(); + $writer = new ParagraphWriter($style); + $writer->setParentWriter($parentWriter); + $style->setSpaceBefore(240); $style->setSpaceAfter(120); $style->setLineHeight(1.5); $style->setContextualSpacing(false); - $writer = new ParagraphWriter($style); - $writer->setParentWriter($parentWriter); - $expect = '\\pard\\sb240\\sa120\\sl360\\simult1\\widctlpar '; + $expect = '\\pard\\sb240\\sa120\\sl360\\slmult1\\widctlpar '; self::assertEquals($expect, $this->removeCr($writer)); $style->setSpaceBefore(480); @@ -152,13 +155,13 @@ public function testParagraphSpacing(): void $style->setSpacing(30); $style->setSpacingLineRule(LineSpacingRule::EXACT); $style->setContextualSpacing(true); - $expect = '\\pard\\sb480\\sa360\\sl30\\simult0\\contextualspace\\widctlpar '; + $expect = '\\pard\\sb480\\sa360\\sl30\\slmult0\\contextualspace\\widctlpar '; self::assertEquals($expect, $this->removeCr($writer)); - } + } /** * Test tabs. - * See PHPOFfice\Tests\Writer\RTF\Style\TabTest + * See PHPOFfice\Tests\Writer\RTF\Style\TabTest. */ /** From d238a7ea695bd46c1414bd130a0c159cefd271b4 Mon Sep 17 00:00:00 2001 From: rasamassen Date: Fri, 3 Oct 2025 19:28:14 -0500 Subject: [PATCH 28/53] Update Paragraph.php - add spacing and spacingLineRule --- src/PhpWord/Writer/RTF/Style/Paragraph.php | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/PhpWord/Writer/RTF/Style/Paragraph.php b/src/PhpWord/Writer/RTF/Style/Paragraph.php index 08e624c949..a4fff1bc70 100644 --- a/src/PhpWord/Writer/RTF/Style/Paragraph.php +++ b/src/PhpWord/Writer/RTF/Style/Paragraph.php @@ -19,6 +19,7 @@ namespace PhpOffice\PhpWord\Writer\RTF\Style; use PhpOffice\PhpWord\SimpleType\Jc; +use PhpOffice\PhpWord\SimpleType\LineSpacingRule; /** * RTF paragraph style writer. @@ -76,6 +77,11 @@ public function write() Jc::MEDIUM_KASHIDA => '\qk10', Jc::LOW_KASHIDA => '\qk0', ]; + $spacingRules = [ + LineSpacingRule::AUTO => '\slmult1', + LineSpacingRule::EXACT => '\slmult0', + LineSpacingRule::AT_LEAST => '\slmult0', + ]; $spaceAfter = $style->getSpaceAfter(); $spaceBefore = $style->getSpaceBefore(); @@ -98,8 +104,15 @@ public function write() $lineHeight = $style->getLineHeight(); if ($lineHeight) { $lineHeightAdjusted = (int) ($lineHeight * 240); - $content .= "\\sl$lineHeightAdjusted\\slmult1"; + $content .= "\\sl$lineHeightAdjusted"; + } else { + $content .= $this->getValueIf($style->getSpacing() !== null, '\sl' . round($style->getSpacing() ?? 0)); + $spacingRule = $style->getSpacingLineRule(); + if (isset($spacingRules[$spacingRule])) { + $content .= $spacingRules[$spacingRule]; + } } + $content .= $this->getValueIf($style->hasContextualSpacing(), '\contextualspace'); // Pagination From 995692f209b4f2a2fc0c29f39d45b3a3ab7a0c8c Mon Sep 17 00:00:00 2001 From: rasamassen Date: Fri, 3 Oct 2025 19:28:17 -0500 Subject: [PATCH 29/53] Update ParagraphTest.php --- tests/PhpWordTests/Writer/RTF/Style/ParagraphTest.php | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/PhpWordTests/Writer/RTF/Style/ParagraphTest.php b/tests/PhpWordTests/Writer/RTF/Style/ParagraphTest.php index d1defe1dd1..6d1e904e48 100644 --- a/tests/PhpWordTests/Writer/RTF/Style/ParagraphTest.php +++ b/tests/PhpWordTests/Writer/RTF/Style/ParagraphTest.php @@ -150,6 +150,7 @@ public function testParagraphSpacing(): void $expect = '\\pard\\sb240\\sa120\\sl360\\slmult1\\widctlpar '; self::assertEquals($expect, $this->removeCr($writer)); + $style = new ParagraphStyle(); $style->setSpaceBefore(480); $style->setSpaceAfter(360); $style->setSpacing(30); From 0b08710359b7b03b888315d8012b17d6025603e8 Mon Sep 17 00:00:00 2001 From: rasamassen Date: Fri, 3 Oct 2025 19:31:50 -0500 Subject: [PATCH 30/53] Update Paragraph.php --- src/PhpWord/Writer/RTF/Style/Paragraph.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/PhpWord/Writer/RTF/Style/Paragraph.php b/src/PhpWord/Writer/RTF/Style/Paragraph.php index a4fff1bc70..a8a023eb76 100644 --- a/src/PhpWord/Writer/RTF/Style/Paragraph.php +++ b/src/PhpWord/Writer/RTF/Style/Paragraph.php @@ -109,10 +109,10 @@ public function write() $content .= $this->getValueIf($style->getSpacing() !== null, '\sl' . round($style->getSpacing() ?? 0)); $spacingRule = $style->getSpacingLineRule(); if (isset($spacingRules[$spacingRule])) { - $content .= $spacingRules[$spacingRule]; + $content .= $this->getValueIf($style->getSpacing() !== null$spacingRules[$spacingRule]); } } - + $content .= $this->getValueIf($style->hasContextualSpacing(), '\contextualspace'); // Pagination From 7d4ce32bf658dfad7297a327692ddd5287ac88cc Mon Sep 17 00:00:00 2001 From: rasamassen Date: Fri, 3 Oct 2025 19:33:01 -0500 Subject: [PATCH 31/53] Update Paragraph.php --- src/PhpWord/Writer/RTF/Style/Paragraph.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/PhpWord/Writer/RTF/Style/Paragraph.php b/src/PhpWord/Writer/RTF/Style/Paragraph.php index a8a023eb76..42cd8fb3ea 100644 --- a/src/PhpWord/Writer/RTF/Style/Paragraph.php +++ b/src/PhpWord/Writer/RTF/Style/Paragraph.php @@ -108,9 +108,9 @@ public function write() } else { $content .= $this->getValueIf($style->getSpacing() !== null, '\sl' . round($style->getSpacing() ?? 0)); $spacingRule = $style->getSpacingLineRule(); - if (isset($spacingRules[$spacingRule])) { - $content .= $this->getValueIf($style->getSpacing() !== null$spacingRules[$spacingRule]); - } + } + if (isset($spacingRules[$spacingRule])) { + $content .= $this->getValueIf($style->getSpacing() !== null$spacingRules[$spacingRule]); } $content .= $this->getValueIf($style->hasContextualSpacing(), '\contextualspace'); From ff94ce8a578e6d0422ccc6fabb554d1d9ac53388 Mon Sep 17 00:00:00 2001 From: rasamassen Date: Fri, 3 Oct 2025 19:35:47 -0500 Subject: [PATCH 32/53] Update Paragraph.php --- src/PhpWord/Writer/RTF/Style/Paragraph.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/PhpWord/Writer/RTF/Style/Paragraph.php b/src/PhpWord/Writer/RTF/Style/Paragraph.php index 42cd8fb3ea..d043488be2 100644 --- a/src/PhpWord/Writer/RTF/Style/Paragraph.php +++ b/src/PhpWord/Writer/RTF/Style/Paragraph.php @@ -110,7 +110,7 @@ public function write() $spacingRule = $style->getSpacingLineRule(); } if (isset($spacingRules[$spacingRule])) { - $content .= $this->getValueIf($style->getSpacing() !== null$spacingRules[$spacingRule]); + $content .= $this->getValueIf($style->getSpacing() !== null, $spacingRules[$spacingRule]); } $content .= $this->getValueIf($style->hasContextualSpacing(), '\contextualspace'); From 9143d56065c4010c88bbc90eae9116a46f4a7cbf Mon Sep 17 00:00:00 2001 From: rasamassen Date: Fri, 3 Oct 2025 19:40:11 -0500 Subject: [PATCH 33/53] Update Paragraph.php --- src/PhpWord/Writer/RTF/Style/Paragraph.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/PhpWord/Writer/RTF/Style/Paragraph.php b/src/PhpWord/Writer/RTF/Style/Paragraph.php index d043488be2..92711097b8 100644 --- a/src/PhpWord/Writer/RTF/Style/Paragraph.php +++ b/src/PhpWord/Writer/RTF/Style/Paragraph.php @@ -98,6 +98,7 @@ public function write() if (isset($alignments[$alignment])) { $content .= $bidi ? $bidiAlignments[$alignment] : $alignments[$alignment]; } + $content .= $this->getValueIf($style->isBidi(), '\rtlpar'); $content .= $this->writeIndentation($style->getIndentation()); $content .= $this->getValueIf($spaceBefore !== null, '\sb' . round($spaceBefore ?? 0)); $content .= $this->getValueIf($spaceAfter !== null, '\sa' . round($spaceAfter ?? 0)); @@ -107,8 +108,8 @@ public function write() $content .= "\\sl$lineHeightAdjusted"; } else { $content .= $this->getValueIf($style->getSpacing() !== null, '\sl' . round($style->getSpacing() ?? 0)); - $spacingRule = $style->getSpacingLineRule(); } + $spacingRule = $style->getSpacingLineRule(); if (isset($spacingRules[$spacingRule])) { $content .= $this->getValueIf($style->getSpacing() !== null, $spacingRules[$spacingRule]); } From fcba983fac5915638f6f965e832e8bb2eef9aa3e Mon Sep 17 00:00:00 2001 From: rasamassen Date: Fri, 3 Oct 2025 19:51:37 -0500 Subject: [PATCH 34/53] Update ParagraphTest.php --- .../Writer/RTF/Style/ParagraphTest.php | 40 ++++++++++--------- 1 file changed, 22 insertions(+), 18 deletions(-) diff --git a/tests/PhpWordTests/Writer/RTF/Style/ParagraphTest.php b/tests/PhpWordTests/Writer/RTF/Style/ParagraphTest.php index 6d1e904e48..c8ab8a9499 100644 --- a/tests/PhpWordTests/Writer/RTF/Style/ParagraphTest.php +++ b/tests/PhpWordTests/Writer/RTF/Style/ParagraphTest.php @@ -43,7 +43,8 @@ public function removeCr($field): string /** * Test alignment. - * See page 79 of RTF Specification 1.9.1. + * See page 79 of RTF Specification 1.9.1 for Alignment. + * See page 81 of RTF Specification 1.9.1 for Bidirectional Controls. */ public function testParagraphAlign(): void { @@ -53,49 +54,49 @@ public function testParagraphAlign(): void $writer->setParentWriter($parentWriter); $style->setAlignment(Jc::START); - $expect = '\\pard\\ql\\widctlpar '; + $expect = '\pard\ql\widctlpar '; self::assertEquals($expect, $this->removeCr($writer)); $style->setAlignment(Jc::CENTER); - $expect = '\\pard\\qc\\widctlpar '; + $expect = '\pard\qc\widctlpar '; self::assertEquals($expect, $this->removeCr($writer)); $style->setAlignment(Jc::END); - $expect = '\\pard\\qr\\widctlpar '; + $expect = '\pard\qr\widctlpar '; self::assertEquals($expect, $this->removeCr($writer)); $style->setAlignment(Jc::BOTH); - $expect = '\\pard\\qj\\widctlpar '; + $expect = '\pard\qj\widctlpar '; self::assertEquals($expect, $this->removeCr($writer)); $style->setAlignment(Jc::DISTRIBUTE); - $expect = '\\pard\\qd\\widctlpar '; + $expect = '\pard\qd\widctlpar '; self::assertEquals($expect, $this->removeCr($writer)); $style->setAlignment(Jc::THAI_DISTRIBUTE); - $expect = '\\pard\\qt\\widctlpar '; + $expect = '\pard\qt\widctlpar '; self::assertEquals($expect, $this->removeCr($writer)); $style->setAlignment(Jc::HIGH_KASHIDA); - $expect = '\\pard\\qk20\\widctlpar '; + $expect = '\pard\qk20\widctlpar '; self::assertEquals($expect, $this->removeCr($writer)); $style->setAlignment(Jc::MEDIUM_KASHIDA); - $expect = '\\pard\\qk10\\widctlpar '; + $expect = '\pard\qk10\widctlpar '; self::assertEquals($expect, $this->removeCr($writer)); $style->setAlignment(Jc::LOW_KASHIDA); - $expect = '\\pard\\qk0\\widctlpar '; + $expect = '\pard\qk0\widctlpar '; self::assertEquals($expect, $this->removeCr($writer)); $style->setAlignment(Jc::START); $style->setBidi(true); - $expect = '\\pard\\qr\\widctlpar '; + $expect = '\pard\qr\rtlpar\widctlpar '; self::assertEquals($expect, $this->removeCr($writer)); $style->setAlignment(Jc::END); $style->setBidi(true); - $expect = '\\pard\\ql\\widctlpar '; + $expect = '\pard\ql\rtlpar\widctlpar '; self::assertEquals($expect, $this->removeCr($writer)); } @@ -106,7 +107,7 @@ public function testParagraphAlign(): void /** * Test formatting. - * See page 79 of RTF Specification 1.9.1. + * See page 78 of RTF Specification 1.9.1 for Formatting. */ public function testParagraphFormatting(): void { @@ -120,7 +121,7 @@ public function testParagraphFormatting(): void $style->setKeepNext(true); $style->setWidowControl(true); $style->setPageBreakBefore(true); - $expect = '\\pard\\widctlpar\\keepn\\keep\\pagebb\\hyphpar0 '; + $expect = '\pard\widctlpar\keepn\keep\pagebb\hyphpar0 '; self::assertEquals($expect, $this->removeCr($writer)); $style->setSuppressAutoHyphens(false); @@ -128,13 +129,13 @@ public function testParagraphFormatting(): void $style->setKeepNext(false); $style->setWidowControl(false); $style->setPageBreakBefore(false); - $expect = '\\pard\\nowidctlpar '; + $expect = '\pard\nowidctlpar '; self::assertEquals($expect, $this->removeCr($writer)); } /** * Test spacing. - * See page 80 of RTF Specification 1.9.1. + * See page 80 of RTF Specification 1.9.1 for Spacing. */ public function testParagraphSpacing(): void { @@ -147,16 +148,19 @@ public function testParagraphSpacing(): void $style->setSpaceAfter(120); $style->setLineHeight(1.5); $style->setContextualSpacing(false); - $expect = '\\pard\\sb240\\sa120\\sl360\\slmult1\\widctlpar '; + $expect = '\pard\sb240\sa120\sl360\slmult1\widctlpar '; self::assertEquals($expect, $this->removeCr($writer)); $style = new ParagraphStyle(); + $writer = new ParagraphWriter($style); + $writer->setParentWriter($parentWriter); + $style->setSpaceBefore(480); $style->setSpaceAfter(360); $style->setSpacing(30); $style->setSpacingLineRule(LineSpacingRule::EXACT); $style->setContextualSpacing(true); - $expect = '\\pard\\sb480\\sa360\\sl30\\slmult0\\contextualspace\\widctlpar '; + $expect = '\pard\sb480\sa360\sl30\slmult0\contextualspace\widctlpar '; self::assertEquals($expect, $this->removeCr($writer)); } From cbb2cbd57699fc308695d765242df3bd041512dd Mon Sep 17 00:00:00 2001 From: rasamassen Date: Fri, 3 Oct 2025 19:55:47 -0500 Subject: [PATCH 35/53] Update StyleTest.php --- tests/PhpWordTests/Writer/RTF/StyleTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/PhpWordTests/Writer/RTF/StyleTest.php b/tests/PhpWordTests/Writer/RTF/StyleTest.php index 789d0e4821..bd0e452476 100644 --- a/tests/PhpWordTests/Writer/RTF/StyleTest.php +++ b/tests/PhpWordTests/Writer/RTF/StyleTest.php @@ -136,7 +136,7 @@ public function testRTL2(): void $parentWriter = new RTF(); $element = new \PhpOffice\PhpWord\Element\Text('אב גד'); $text = new RTF\Element\Text($parentWriter, $element); - $expect = "\\pard\\qr\\widctlpar {\\rtlch\\cf0\\f0 \\uc0{\\u1488}\\uc0{\\u1489} \\uc0{\\u1490}\\uc0{\\u1491}}\\par\n"; + $expect = "\\pard\\qr\\rtlpar\\widctlpar {\\rtlch\\cf0\\f0 \\uc0{\\u1488}\\uc0{\\u1489} \\uc0{\\u1490}\\uc0{\\u1491}}\\par\n"; self::assertEquals($expect, $this->removeCr($text)); } From 2c4c25d9b9a2bfc3fb8d86d0761837454c5c9d10 Mon Sep 17 00:00:00 2001 From: rasamassen Date: Fri, 3 Oct 2025 19:56:24 -0500 Subject: [PATCH 36/53] Update RtfEscaper3Test.php --- tests/PhpWordTests/Escaper/RtfEscaper3Test.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/PhpWordTests/Escaper/RtfEscaper3Test.php b/tests/PhpWordTests/Escaper/RtfEscaper3Test.php index 5af39f6e63..1460db0e0f 100644 --- a/tests/PhpWordTests/Escaper/RtfEscaper3Test.php +++ b/tests/PhpWordTests/Escaper/RtfEscaper3Test.php @@ -26,7 +26,7 @@ class RtfEscaper3Test extends \PHPUnit\Framework\TestCase { const HEADER = '\\pard\\ql\\widctlpar {\\cf0\\f0 '; - const HEADER_RTL = '\\pard\\qr\\widctlpar {\\rtlch\\cf0\\f0 '; + const HEADER_RTL = '\\pard\\qr\\rtlpar\\widctlpar {\\rtlch\\cf0\\f0 '; const TRAILER = '}\\par'; protected function tearDown(): void From 0516d307f654324321f2d75b38c4609ccc28812d Mon Sep 17 00:00:00 2001 From: rasamassen Date: Fri, 3 Oct 2025 19:58:35 -0500 Subject: [PATCH 37/53] Update ParagraphTest.php --- tests/PhpWordTests/Writer/RTF/Style/ParagraphTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/PhpWordTests/Writer/RTF/Style/ParagraphTest.php b/tests/PhpWordTests/Writer/RTF/Style/ParagraphTest.php index c8ab8a9499..007a6d8373 100644 --- a/tests/PhpWordTests/Writer/RTF/Style/ParagraphTest.php +++ b/tests/PhpWordTests/Writer/RTF/Style/ParagraphTest.php @@ -154,7 +154,7 @@ public function testParagraphSpacing(): void $style = new ParagraphStyle(); $writer = new ParagraphWriter($style); $writer->setParentWriter($parentWriter); - + $style->setSpaceBefore(480); $style->setSpaceAfter(360); $style->setSpacing(30); From b394c75c3c8e34307f0e20fcbb8a940976497007 Mon Sep 17 00:00:00 2001 From: rasamassen Date: Fri, 3 Oct 2025 20:03:16 -0500 Subject: [PATCH 38/53] Update 1.5.0.md --- docs/changes/1.x/1.5.0.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/changes/1.x/1.5.0.md b/docs/changes/1.x/1.5.0.md index 8454d7b74e..c5ede40ead 100644 --- a/docs/changes/1.x/1.5.0.md +++ b/docs/changes/1.x/1.5.0.md @@ -7,7 +7,7 @@ ### Bug fixes - Set writeAttribute return type by [@radarhere](https://github.com/radarhere) fixing [#2204](https://github.com/PHPOffice/PHPWord/issues/2204) in [#2776](https://github.com/PHPOffice/PHPWord/pull/2776) -- Writer RTF: Add/Fix pagination in Paragraph by [@rasamassen](https://github.com/rasamassen) in [#2824](https://github.com/PHPOffice/PHPWord/pull/2824) +- Writer RTF: Add multiple missing controls and fix existing controls in Paragraph by [@rasamassen](https://github.com/rasamassen) in [#2824](https://github.com/PHPOffice/PHPWord/pull/2824) ### Miscellaneous From 1c356caaaf65033e0b90365c6f55ae86d64921e1 Mon Sep 17 00:00:00 2001 From: rasamassen Date: Thu, 9 Oct 2025 23:15:06 -0500 Subject: [PATCH 39/53] Update Paragraph.php --- src/PhpWord/Writer/RTF/Style/Paragraph.php | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/src/PhpWord/Writer/RTF/Style/Paragraph.php b/src/PhpWord/Writer/RTF/Style/Paragraph.php index 92711097b8..5df4fe28a8 100644 --- a/src/PhpWord/Writer/RTF/Style/Paragraph.php +++ b/src/PhpWord/Writer/RTF/Style/Paragraph.php @@ -83,25 +83,31 @@ public function write() LineSpacingRule::AT_LEAST => '\slmult0', ]; - $spaceAfter = $style->getSpaceAfter(); - $spaceBefore = $style->getSpaceBefore(); - $content = ''; if ($this->nestedLevel == 0) { $content .= '\pard'; } + + // Alignment $alignment = $style->getAlignment(); $bidi = $style->isBidi(); if ($alignment === '' && $bidi !== null) { $alignment = Jc::START; } + + // Right to left if (isset($alignments[$alignment])) { $content .= $bidi ? $bidiAlignments[$alignment] : $alignments[$alignment]; } $content .= $this->getValueIf($style->isBidi(), '\rtlpar'); + + // Indentation - Future: Create writeChildStyle in AbstractStyle $content .= $this->writeIndentation($style->getIndentation()); - $content .= $this->getValueIf($spaceBefore !== null, '\sb' . round($spaceBefore ?? 0)); - $content .= $this->getValueIf($spaceAfter !== null, '\sa' . round($spaceAfter ?? 0)); + // Future: Add Shading + + // Spacing - Future: Replace with Spacing writer when built + $content .= $this->getValueIf($style->getSpaceBefore() !== null, '\sb' . round($style->getSpaceBefore() ?? 0)); + $content .= $this->getValueIf($style->getSpaceAfter() !== null, '\sa' . round($style->getSpaceAfter() ?? 0)); $lineHeight = $style->getLineHeight(); if ($lineHeight) { $lineHeightAdjusted = (int) ($lineHeight * 240); @@ -114,7 +120,9 @@ public function write() $content .= $this->getValueIf($style->getSpacing() !== null, $spacingRules[$spacingRule]); } + // Contextual Spacing $content .= $this->getValueIf($style->hasContextualSpacing(), '\contextualspace'); + // Future: Add Text Alignment // Pagination $content .= $this->getValueIf($style->hasWidowControl(), '\widctlpar'); @@ -122,8 +130,11 @@ public function write() $content .= $this->getValueIf($style->isKeepNext(), '\keepn'); $content .= $this->getValueIf($style->isKeepLines(), '\keep'); $content .= $this->getValueIf($style->hasPageBreakBefore(), '\pagebb'); + + // Hyphenation $content .= $this->getValueIf($style->hasSuppressAutoHyphens(), '\hyphpar0'); + // Tabs $styles = $style->getStyleValues(); $content .= $this->writeTabs($styles['tabs']); From 6bf16a352e49b372091fde09f14ccb7480596148 Mon Sep 17 00:00:00 2001 From: rasamassen Date: Fri, 10 Oct 2025 13:41:54 -0500 Subject: [PATCH 40/53] Update AbstractStyle.php - create writeChildStyle function --- .../Writer/RTF/Style/AbstractStyle.php | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/PhpWord/Writer/RTF/Style/AbstractStyle.php b/src/PhpWord/Writer/RTF/Style/AbstractStyle.php index 00e148dfe9..78451dc887 100644 --- a/src/PhpWord/Writer/RTF/Style/AbstractStyle.php +++ b/src/PhpWord/Writer/RTF/Style/AbstractStyle.php @@ -105,4 +105,25 @@ protected function getValueIf($condition, $value) { return $condition == true ? $value : ''; } + + /** + * Write child style. + * + * @param string $name + * @param null|\PhpOffice\PhpWord\Style\AbstractStyle + * + * @return string + */ + protected function writeChildStyle($name, $style = null) + { + $stylePath = "\\PhpOffice\\PhpWord\\Style\\" . ucfirst($name); + if (isset($style) && $style instanceof $stylePath) { + $writerPath = "\\PhpOffice\\PhpWord\\Writer\\RTF\\Style\\" . ucfirst($name); + $writer = new $writerPath($style); + + return $writer->write(); + } + + return ''; + } } From 07b4001621a5fa161bc754baad1032756cfc1e1d Mon Sep 17 00:00:00 2001 From: rasamassen Date: Mon, 13 Oct 2025 20:10:29 -0500 Subject: [PATCH 41/53] Update AbstractStyle.php --- src/PhpWord/Writer/RTF/Style/AbstractStyle.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/PhpWord/Writer/RTF/Style/AbstractStyle.php b/src/PhpWord/Writer/RTF/Style/AbstractStyle.php index 78451dc887..3a6c704696 100644 --- a/src/PhpWord/Writer/RTF/Style/AbstractStyle.php +++ b/src/PhpWord/Writer/RTF/Style/AbstractStyle.php @@ -110,15 +110,15 @@ protected function getValueIf($condition, $value) * Write child style. * * @param string $name - * @param null|\PhpOffice\PhpWord\Style\AbstractStyle + * @param null|\PhpOffice\PhpWord\Style\AbstractStyle $style * * @return string */ protected function writeChildStyle($name, $style = null) { - $stylePath = "\\PhpOffice\\PhpWord\\Style\\" . ucfirst($name); + $stylePath = '\\PhpOffice\\PhpWord\\Style\\'. ucfirst($name); if (isset($style) && $style instanceof $stylePath) { - $writerPath = "\\PhpOffice\\PhpWord\\Writer\\RTF\\Style\\" . ucfirst($name); + $writerPath = '\\PhpOffice\\PhpWord\\Writer\\RTF\\Style\\' . ucfirst($name); $writer = new $writerPath($style); return $writer->write(); From 61ec5ea90a3e67fe188aead840f5443fa38235a0 Mon Sep 17 00:00:00 2001 From: rasamassen Date: Mon, 13 Oct 2025 20:14:27 -0500 Subject: [PATCH 42/53] Update AbstractStyle.php --- src/PhpWord/Writer/RTF/Style/AbstractStyle.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/PhpWord/Writer/RTF/Style/AbstractStyle.php b/src/PhpWord/Writer/RTF/Style/AbstractStyle.php index 3a6c704696..e7f5886636 100644 --- a/src/PhpWord/Writer/RTF/Style/AbstractStyle.php +++ b/src/PhpWord/Writer/RTF/Style/AbstractStyle.php @@ -110,15 +110,15 @@ protected function getValueIf($condition, $value) * Write child style. * * @param string $name - * @param null|\PhpOffice\PhpWord\Style\AbstractStyle $style + * @param null|AbstractStyle $style * * @return string */ protected function writeChildStyle($name, $style = null) { - $stylePath = '\\PhpOffice\\PhpWord\\Style\\'. ucfirst($name); + $stylePath = 'PhpOffice\\PhpWord\\Style\\' . ucfirst($name); if (isset($style) && $style instanceof $stylePath) { - $writerPath = '\\PhpOffice\\PhpWord\\Writer\\RTF\\Style\\' . ucfirst($name); + $writerPath = 'PhpOffice\\PhpWord\\Writer\\RTF\\Style\\' . ucfirst($name); $writer = new $writerPath($style); return $writer->write(); From 6f91bc42a44b8a34cfc5e05033bbeec3c51985a3 Mon Sep 17 00:00:00 2001 From: rasamassen Date: Mon, 13 Oct 2025 20:17:49 -0500 Subject: [PATCH 43/53] Update AbstractStyle.php --- src/PhpWord/Writer/RTF/Style/AbstractStyle.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/PhpWord/Writer/RTF/Style/AbstractStyle.php b/src/PhpWord/Writer/RTF/Style/AbstractStyle.php index e7f5886636..e99f5a7c0d 100644 --- a/src/PhpWord/Writer/RTF/Style/AbstractStyle.php +++ b/src/PhpWord/Writer/RTF/Style/AbstractStyle.php @@ -121,7 +121,9 @@ protected function writeChildStyle($name, $style = null) $writerPath = 'PhpOffice\\PhpWord\\Writer\\RTF\\Style\\' . ucfirst($name); $writer = new $writerPath($style); - return $writer->write(); + if (method_exists($writer, 'write')) { + return $writer->write(); + } } return ''; From 0e180e2fc2133fd2d0dd34dfbe81ab04045548ca Mon Sep 17 00:00:00 2001 From: rasamassen Date: Mon, 13 Oct 2025 20:57:40 -0500 Subject: [PATCH 44/53] Create Spacing.php --- src/PhpWord/Writer/RTF/Style/Spacing.php | 68 ++++++++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 src/PhpWord/Writer/RTF/Style/Spacing.php diff --git a/src/PhpWord/Writer/RTF/Style/Spacing.php b/src/PhpWord/Writer/RTF/Style/Spacing.php new file mode 100644 index 0000000000..1a6ce49061 --- /dev/null +++ b/src/PhpWord/Writer/RTF/Style/Spacing.php @@ -0,0 +1,68 @@ +getStyle(); + if (!$style instanceof \PhpOffice\PhpWord\Style\Spacing) { + return ''; + } + + $spacingRules = [ + LineSpacingRule::AUTO => '\slmult1', + LineSpacingRule::EXACT => '\slmult0', + LineSpacingRule::AT_LEAST => '\slmult0', + ]; + + // Space Before and After + $content .= $this->getValueIf($style->getBefore() !== null, '\sb' . round($style->getBefore() ?? 0)); + $content .= $this->getValueIf($style->getAfter() !== null, '\sa' . round($style->getAfter() ?? 0)); + + // Space Between Lines + $line = $style->getLine(); + if (null !== $line && $style->getLineRule() === LineSpacingRule::AUTO) { + $line += \PhpOffice\PhpWord\Style\Paragraph::LINE_HEIGHT; + } + // Exact is specified by using negative numbers + if ($style->getLineRule() === LineSpacingRule::EXACT && $line > 0) { + $line = $line * -1; + } + $content .= $this->getValueIf($line !== null, '\sl' . round($line ?? 0)); + + // Spacing Multiple + $content .= $this->getValueIf($spacingRules[$style->getLineRule()] !== null, $spacingRules[$style->getLineRule()]); + + return $content . ' '; + } +} From 38630c727c66077effac34faadd058cc149c35c2 Mon Sep 17 00:00:00 2001 From: rasamassen Date: Mon, 13 Oct 2025 21:00:15 -0500 Subject: [PATCH 45/53] Update Paragraph.php --- src/PhpWord/Writer/RTF/Style/Paragraph.php | 42 ++-------------------- 1 file changed, 2 insertions(+), 40 deletions(-) diff --git a/src/PhpWord/Writer/RTF/Style/Paragraph.php b/src/PhpWord/Writer/RTF/Style/Paragraph.php index 5df4fe28a8..365364be0f 100644 --- a/src/PhpWord/Writer/RTF/Style/Paragraph.php +++ b/src/PhpWord/Writer/RTF/Style/Paragraph.php @@ -19,7 +19,6 @@ namespace PhpOffice\PhpWord\Writer\RTF\Style; use PhpOffice\PhpWord\SimpleType\Jc; -use PhpOffice\PhpWord\SimpleType\LineSpacingRule; /** * RTF paragraph style writer. @@ -77,11 +76,6 @@ public function write() Jc::MEDIUM_KASHIDA => '\qk10', Jc::LOW_KASHIDA => '\qk0', ]; - $spacingRules = [ - LineSpacingRule::AUTO => '\slmult1', - LineSpacingRule::EXACT => '\slmult0', - LineSpacingRule::AT_LEAST => '\slmult0', - ]; $content = ''; if ($this->nestedLevel == 0) { @@ -102,24 +96,10 @@ public function write() $content .= $this->getValueIf($style->isBidi(), '\rtlpar'); // Indentation - Future: Create writeChildStyle in AbstractStyle - $content .= $this->writeIndentation($style->getIndentation()); + $content .= $this->writeChildStyle('Indentation', $style->getIndentation()); + $content .= $this->writeChildStyle('Spacing', $style->getSpace()); // Future: Add Shading - // Spacing - Future: Replace with Spacing writer when built - $content .= $this->getValueIf($style->getSpaceBefore() !== null, '\sb' . round($style->getSpaceBefore() ?? 0)); - $content .= $this->getValueIf($style->getSpaceAfter() !== null, '\sa' . round($style->getSpaceAfter() ?? 0)); - $lineHeight = $style->getLineHeight(); - if ($lineHeight) { - $lineHeightAdjusted = (int) ($lineHeight * 240); - $content .= "\\sl$lineHeightAdjusted"; - } else { - $content .= $this->getValueIf($style->getSpacing() !== null, '\sl' . round($style->getSpacing() ?? 0)); - } - $spacingRule = $style->getSpacingLineRule(); - if (isset($spacingRules[$spacingRule])) { - $content .= $this->getValueIf($style->getSpacing() !== null, $spacingRules[$spacingRule]); - } - // Contextual Spacing $content .= $this->getValueIf($style->hasContextualSpacing(), '\contextualspace'); // Future: Add Text Alignment @@ -141,24 +121,6 @@ public function write() return $content . ' '; } - /** - * Writes an \PhpOffice\PhpWord\Style\Indentation. - * - * @param null|\PhpOffice\PhpWord\Style\Indentation $indent - * - * @return string - */ - private function writeIndentation($indent = null) - { - if (isset($indent) && $indent instanceof \PhpOffice\PhpWord\Style\Indentation) { - $writer = new Indentation($indent); - - return $writer->write(); - } - - return ''; - } - /** * Writes tabs. * From 738541412e5af06558f6368b67c6468ee06891a4 Mon Sep 17 00:00:00 2001 From: rasamassen Date: Mon, 13 Oct 2025 21:08:36 -0500 Subject: [PATCH 46/53] Update AbstractStyle.php --- src/PhpWord/Writer/RTF/Style/AbstractStyle.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/PhpWord/Writer/RTF/Style/AbstractStyle.php b/src/PhpWord/Writer/RTF/Style/AbstractStyle.php index e99f5a7c0d..22e19b255f 100644 --- a/src/PhpWord/Writer/RTF/Style/AbstractStyle.php +++ b/src/PhpWord/Writer/RTF/Style/AbstractStyle.php @@ -110,7 +110,7 @@ protected function getValueIf($condition, $value) * Write child style. * * @param string $name - * @param null|AbstractStyle $style + * @param null|PhpOffice\PhpWord\Style\AbstractStyle $style * * @return string */ From e1701e8d59dc8897100d4412f689b425b76f1895 Mon Sep 17 00:00:00 2001 From: rasamassen Date: Mon, 13 Oct 2025 21:11:28 -0500 Subject: [PATCH 47/53] Update AbstractStyle.php --- src/PhpWord/Writer/RTF/Style/AbstractStyle.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/PhpWord/Writer/RTF/Style/AbstractStyle.php b/src/PhpWord/Writer/RTF/Style/AbstractStyle.php index 22e19b255f..9017f2bce7 100644 --- a/src/PhpWord/Writer/RTF/Style/AbstractStyle.php +++ b/src/PhpWord/Writer/RTF/Style/AbstractStyle.php @@ -110,7 +110,7 @@ protected function getValueIf($condition, $value) * Write child style. * * @param string $name - * @param null|PhpOffice\PhpWord\Style\AbstractStyle $style + * @param mixed $style * * @return string */ From acda6416b623c9f73763198cd161520ca14559be Mon Sep 17 00:00:00 2001 From: rasamassen Date: Mon, 13 Oct 2025 21:13:55 -0500 Subject: [PATCH 48/53] Update Spacing.php --- src/PhpWord/Writer/RTF/Style/Spacing.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/PhpWord/Writer/RTF/Style/Spacing.php b/src/PhpWord/Writer/RTF/Style/Spacing.php index 1a6ce49061..3c57fac1d3 100644 --- a/src/PhpWord/Writer/RTF/Style/Spacing.php +++ b/src/PhpWord/Writer/RTF/Style/Spacing.php @@ -45,6 +45,8 @@ public function write() LineSpacingRule::AT_LEAST => '\slmult0', ]; + $content = ''; + // Space Before and After $content .= $this->getValueIf($style->getBefore() !== null, '\sb' . round($style->getBefore() ?? 0)); $content .= $this->getValueIf($style->getAfter() !== null, '\sa' . round($style->getAfter() ?? 0)); @@ -61,7 +63,7 @@ public function write() $content .= $this->getValueIf($line !== null, '\sl' . round($line ?? 0)); // Spacing Multiple - $content .= $this->getValueIf($spacingRules[$style->getLineRule()] !== null, $spacingRules[$style->getLineRule()]); + $content .= $this->getValueIf(isset($spacingRules[$style->getLineRule()]), $spacingRules[$style->getLineRule()]); return $content . ' '; } From 02da3726338cd47f3de0d21670de343fd07e645d Mon Sep 17 00:00:00 2001 From: rasamassen Date: Mon, 13 Oct 2025 21:21:50 -0500 Subject: [PATCH 49/53] Update Spacing.php --- src/PhpWord/Writer/RTF/Style/Spacing.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/PhpWord/Writer/RTF/Style/Spacing.php b/src/PhpWord/Writer/RTF/Style/Spacing.php index 3c57fac1d3..b85cbe4e9f 100644 --- a/src/PhpWord/Writer/RTF/Style/Spacing.php +++ b/src/PhpWord/Writer/RTF/Style/Spacing.php @@ -63,8 +63,10 @@ public function write() $content .= $this->getValueIf($line !== null, '\sl' . round($line ?? 0)); // Spacing Multiple - $content .= $this->getValueIf(isset($spacingRules[$style->getLineRule()]), $spacingRules[$style->getLineRule()]); + if ($line !== null) { + $content .= $this->getValueIf(isset($spacingRules[$style->getLineRule()]), $spacingRules[$style->getLineRule()]); + } - return $content . ' '; + return $content; } } From 9ac06cc594a2e5fd6f76ef1f03a7386aebb26ab4 Mon Sep 17 00:00:00 2001 From: rasamassen Date: Mon, 13 Oct 2025 21:29:19 -0500 Subject: [PATCH 50/53] Update ParagraphTest.php --- tests/PhpWordTests/Writer/RTF/Style/ParagraphTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/PhpWordTests/Writer/RTF/Style/ParagraphTest.php b/tests/PhpWordTests/Writer/RTF/Style/ParagraphTest.php index 007a6d8373..f75b549ab2 100644 --- a/tests/PhpWordTests/Writer/RTF/Style/ParagraphTest.php +++ b/tests/PhpWordTests/Writer/RTF/Style/ParagraphTest.php @@ -160,7 +160,7 @@ public function testParagraphSpacing(): void $style->setSpacing(30); $style->setSpacingLineRule(LineSpacingRule::EXACT); $style->setContextualSpacing(true); - $expect = '\pard\sb480\sa360\sl30\slmult0\contextualspace\widctlpar '; + $expect = '\pard\sb480\sa360\sl-30\slmult0\contextualspace\widctlpar '; self::assertEquals($expect, $this->removeCr($writer)); } From dc794a0a14f1f74c180cdb96ef60b8d0687db9d5 Mon Sep 17 00:00:00 2001 From: rasamassen Date: Fri, 17 Oct 2025 09:46:56 -0500 Subject: [PATCH 51/53] Update StyleTest.php - Add emptyStyle test for spacing --- tests/PhpWordTests/Writer/RTF/StyleTest.php | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/tests/PhpWordTests/Writer/RTF/StyleTest.php b/tests/PhpWordTests/Writer/RTF/StyleTest.php index bd0e452476..1ecd946c3e 100644 --- a/tests/PhpWordTests/Writer/RTF/StyleTest.php +++ b/tests/PhpWordTests/Writer/RTF/StyleTest.php @@ -43,7 +43,7 @@ public function removeCr($field) */ public function testEmptyStyles(): void { - $styles = ['Font', 'Paragraph', 'Section', 'Tab', 'Indentation']; + $styles = ['Font', 'Indentation', 'Paragraph', 'Section', 'Spacing', 'Tab']; foreach ($styles as $style) { $objectClass = 'PhpOffice\\PhpWord\\Writer\\RTF\\Style\\' . $style; $object = new $objectClass(); @@ -52,6 +52,23 @@ public function testEmptyStyles(): void } } + /** + * Test unmatched styles. + */ + public function testUnmatchedStyles(): void + { + $elements = ['Font', 'Indentation', 'Paragraph', 'Section', 'Spacing', 'Tab']; + foreach ($elements as $element) { + $parentWriter = new RTF(); + $writerClass = 'PhpOffice\\PhpWord\\Writer\\RTF\\Style\\' . $element; + $style = new \PhpOffice\PhpWord\Style\Border(); + $writer = new $writerClass($style); + $writer->setParentWriter($parentWriter); + + self::assertEquals('', $object->write()); + } + } + public function testBorderWithNonRegisteredColors(): void { $border = new Border(); From 5511f079e616ccfa32aae8b2739daff317fb6cdc Mon Sep 17 00:00:00 2001 From: rasamassen Date: Fri, 17 Oct 2025 09:55:01 -0500 Subject: [PATCH 52/53] Update StyleTest.php --- tests/PhpWordTests/Writer/RTF/StyleTest.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/PhpWordTests/Writer/RTF/StyleTest.php b/tests/PhpWordTests/Writer/RTF/StyleTest.php index 1ecd946c3e..0d0cc21fa1 100644 --- a/tests/PhpWordTests/Writer/RTF/StyleTest.php +++ b/tests/PhpWordTests/Writer/RTF/StyleTest.php @@ -57,15 +57,15 @@ public function testEmptyStyles(): void */ public function testUnmatchedStyles(): void { - $elements = ['Font', 'Indentation', 'Paragraph', 'Section', 'Spacing', 'Tab']; - foreach ($elements as $element) { + $styles = ['Font', 'Indentation', 'Paragraph', 'Section', 'Spacing', 'Tab']; + foreach ($styles as $style) { $parentWriter = new RTF(); - $writerClass = 'PhpOffice\\PhpWord\\Writer\\RTF\\Style\\' . $element; - $style = new \PhpOffice\PhpWord\Style\Border(); - $writer = new $writerClass($style); + $writerClass = 'PhpOffice\\PhpWord\\Writer\\RTF\\Style\\' . $style; + $newStyle = new \PhpOffice\PhpWord\Style\Border(); + $writer = new $writerClass($newStyle); $writer->setParentWriter($parentWriter); - self::assertEquals('', $object->write()); + self::assertEquals('', $writer->write()); } } From 6839c02688e0b5140afe0711c1bbd87f5484e759 Mon Sep 17 00:00:00 2001 From: rasamassen Date: Fri, 17 Oct 2025 23:21:40 -0500 Subject: [PATCH 53/53] Update 1.5.0.md --- docs/changes/1.x/1.5.0.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/changes/1.x/1.5.0.md b/docs/changes/1.x/1.5.0.md index c5ede40ead..894a124873 100644 --- a/docs/changes/1.x/1.5.0.md +++ b/docs/changes/1.x/1.5.0.md @@ -7,7 +7,7 @@ ### Bug fixes - Set writeAttribute return type by [@radarhere](https://github.com/radarhere) fixing [#2204](https://github.com/PHPOffice/PHPWord/issues/2204) in [#2776](https://github.com/PHPOffice/PHPWord/pull/2776) -- Writer RTF: Add multiple missing controls and fix existing controls in Paragraph by [@rasamassen](https://github.com/rasamassen) in [#2824](https://github.com/PHPOffice/PHPWord/pull/2824) +- Writer RTF: Add multiple missing controls and fix existing controls in Paragraph by [@rasamassen](https://github.com/rasamassen) in [#2824](https://github.com/PHPOffice/PHPWord/pull/2824), also fixing [#334](https://github.com/PHPOffice/PHPWord/issues/334) ### Miscellaneous