From 6c2cd1c66af64d8866b8eb2e16d560e9437d3060 Mon Sep 17 00:00:00 2001 From: rasamassen Date: Sat, 30 Aug 2025 17:09:48 -0500 Subject: [PATCH 1/8] Update Tab.php - add TAB_LEADER --- src/PhpWord/Writer/RTF/Style/Tab.php | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/PhpWord/Writer/RTF/Style/Tab.php b/src/PhpWord/Writer/RTF/Style/Tab.php index 95e1f10a5c..f448401c50 100644 --- a/src/PhpWord/Writer/RTF/Style/Tab.php +++ b/src/PhpWord/Writer/RTF/Style/Tab.php @@ -38,11 +38,19 @@ public function write() \PhpOffice\PhpWord\Style\Tab::TAB_STOP_RIGHT => '\tqr', \PhpOffice\PhpWord\Style\Tab::TAB_STOP_CENTER => '\tqc', \PhpOffice\PhpWord\Style\Tab::TAB_STOP_DECIMAL => '\tqdec', + \PhpOffice\PhpWord\Style\Tab::TAB_LEADER_DOT => '\tldot', + \PhpOffice\PhpWord\Style\Tab::TAB_LEADER_HYPHEN => '\tlhyph', + \PhpOffice\PhpWord\Style\Tab::TAB_LEADER_UNDERSCORE => '\tlul', + \PhpOffice\PhpWord\Style\Tab::TAB_LEADER_HEAVY => '\tlth', + \PhpOffice\PhpWord\Style\Tab::TAB_LEADER_MIDDLEDOT => '\tleq', ]; $content = ''; if (isset($tabs[$style->getType()])) { $content .= $tabs[$style->getType()]; } + if (isset($tabs[$style->getLeader()])) { + $content .= $tabs[$style->getLeader()]; + } $content .= '\tx' . round($style->getPosition()); return $content; From a96b3c9d7c8a345ce0d96b3e003d19d3bff16747 Mon Sep 17 00:00:00 2001 From: rasamassen Date: Sat, 30 Aug 2025 17:18:12 -0500 Subject: [PATCH 2/8] Update Tab.php Fix Mdot --- src/PhpWord/Writer/RTF/Style/Tab.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/PhpWord/Writer/RTF/Style/Tab.php b/src/PhpWord/Writer/RTF/Style/Tab.php index f448401c50..a6b26ded7f 100644 --- a/src/PhpWord/Writer/RTF/Style/Tab.php +++ b/src/PhpWord/Writer/RTF/Style/Tab.php @@ -42,7 +42,7 @@ public function write() \PhpOffice\PhpWord\Style\Tab::TAB_LEADER_HYPHEN => '\tlhyph', \PhpOffice\PhpWord\Style\Tab::TAB_LEADER_UNDERSCORE => '\tlul', \PhpOffice\PhpWord\Style\Tab::TAB_LEADER_HEAVY => '\tlth', - \PhpOffice\PhpWord\Style\Tab::TAB_LEADER_MIDDLEDOT => '\tleq', + \PhpOffice\PhpWord\Style\Tab::TAB_LEADER_MIDDLEDOT => '\tlmdot', ]; $content = ''; if (isset($tabs[$style->getType()])) { From 7f02c9c3355887a708b3ceb8679e0ca003aef6c3 Mon Sep 17 00:00:00 2001 From: rasamassen Date: Sat, 30 Aug 2025 20:05:39 -0500 Subject: [PATCH 3/8] Update TextBreak.php FIXES no new paragraph in TextRun. --- src/PhpWord/Writer/RTF/Element/TextBreak.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/PhpWord/Writer/RTF/Element/TextBreak.php b/src/PhpWord/Writer/RTF/Element/TextBreak.php index d74bf23dcb..c7924b0f8d 100644 --- a/src/PhpWord/Writer/RTF/Element/TextBreak.php +++ b/src/PhpWord/Writer/RTF/Element/TextBreak.php @@ -36,6 +36,10 @@ public function write() $parentWriter = $this->parentWriter; $parentWriter->setLastParagraphStyle(); - return '\pard\par' . PHP_EOL; + if ($this->withoutP) { + return '\line' . PHP_EOL; + } else { + return '\pard\par' . PHP_EOL; + } } } From 195674551e9bd439702e80a6741061577f87cfd8 Mon Sep 17 00:00:00 2001 From: rasamassen Date: Sun, 31 Aug 2025 13:44:51 -0500 Subject: [PATCH 4/8] Update Font.php - Implement most features for RTF Adds a lot of features. Font name, color, lang, and shading still not working. --- src/PhpWord/Writer/RTF/Style/Font.php | 70 +++++++++++++++++++++++++-- 1 file changed, 65 insertions(+), 5 deletions(-) diff --git a/src/PhpWord/Writer/RTF/Style/Font.php b/src/PhpWord/Writer/RTF/Style/Font.php index f343c0502f..332dfc70c2 100644 --- a/src/PhpWord/Writer/RTF/Style/Font.php +++ b/src/PhpWord/Writer/RTF/Style/Font.php @@ -37,6 +37,11 @@ class Font extends AbstractStyle */ private $colorIndex = 0; + /** + * @var int Font lang index + */ + private $langIndex = 0; + /** * Write style. * @@ -50,20 +55,66 @@ public function write() } $content = ''; - $content .= $this->getValueIf($style->isRTL(), '\rtlch'); - $content .= '\cf' . $this->colorIndex; + + // Font Name $content .= '\f' . $this->nameIndex; - $size = $style->getSize(); - $content .= $this->getValueIf(is_numeric($size), '\fs' . round($size * 2)); + // Basic - same order as array found in PhpOffice\PhpWord\Style\Font\getStyleValues + $content .= $this->getValueIf($style->getName() !== null, '\f' . $this->nameIndex); // Doesn't work; fonts not implemented. + $content .= $this->getValueIf($style->getSize() !== null, '\fs' . round($style->getSize() * 2)); + $content .= $this->getValueIf($style->getColor() !== null, '\cf' . $this->colorIndex); // Doesn't work; coloring not implemented. + // Hint (font content type) not implemented. + + // Underline Keywords + $underlines = [ + \PhpOffice\PhpWord\Style\Font::UNDERLINE_DASH => '\uldash', + \PhpOffice\PhpWord\Style\Font::UNDERLINE_DASHHEAVY => '\ulth', + \PhpOffice\PhpWord\Style\Font::UNDERLINE_DASHLONG => '\ulldash', + \PhpOffice\PhpWord\Style\Font::UNDERLINE_DASHLONGHEAVY => '\ulthldash', + \PhpOffice\PhpWord\Style\Font::UNDERLINE_DOUBLE => '\uldb', + \PhpOffice\PhpWord\Style\Font::UNDERLINE_DOTDASH => '\uldashd', + \PhpOffice\PhpWord\Style\Font::UNDERLINE_DOTDASHHEAVY => '\ulthdashd', + \PhpOffice\PhpWord\Style\Font::UNDERLINE_DOTDOTDASH => '\uldashdd', + \PhpOffice\PhpWord\Style\Font::UNDERLINE_DOTDOTDASHHEAVY => '\ulthdashdd', + \PhpOffice\PhpWord\Style\Font::UNDERLINE_DOTTED => '\uld', + \PhpOffice\PhpWord\Style\Font::UNDERLINE_DOTTEDHEAVY => '\ulthd', + \PhpOffice\PhpWord\Style\Font::UNDERLINE_HEAVY => '\ulth', + \PhpOffice\PhpWord\Style\Font::UNDERLINE_SINGLE => '\ul', + \PhpOffice\PhpWord\Style\Font::UNDERLINE_WAVY => '\ulwave', + \PhpOffice\PhpWord\Style\Font::UNDERLINE_WAVYDOUBLE => '\ululdbwave', + \PhpOffice\PhpWord\Style\Font::UNDERLINE_WAVYHEAVY => '\ulhwave', + \PhpOffice\PhpWord\Style\Font::UNDERLINE_WORDS => '\ulw', + ]; + // Style - same order as array found in PhpOffice\PhpWord\Style\Font\getStyleValues $content .= $this->getValueIf($style->isBold(), '\b'); $content .= $this->getValueIf($style->isItalic(), '\i'); - $content .= $this->getValueIf($style->getUnderline() != FontStyle::UNDERLINE_NONE, '\ul'); + if (isset($underlines[$style->getUnderline()])) { $content .= $underlines[$style->getUnderline()]; } $content .= $this->getValueIf($style->isStrikethrough(), '\strike'); + $content .= $this->getValueIf($style->isDoubleStrikethrough(), '\striked1'); $content .= $this->getValueIf($style->isSuperScript(), '\super'); $content .= $this->getValueIf($style->isSubScript(), '\sub'); + $content .= $this->getValueIf($style->isSmallCaps(), '\scaps'); + $content .= $this->getValueIf($style->isAllCaps(), '\caps'); + $content .= $this->getValueIf($style->getFgColor() !== null, '\highlight' . $this->colorIndex); // Doesn't work; coloring not implemented. + $content .= $this->getValueIf($style->isHidden(), '\v'); + + // Spacing - same order as array found in PhpOffice\PhpWord\Style\Font\getStyleValues + $content .= $this->getValueIf($style->getScale() !== null, '\charscalex' . $style->getScale()); + $content .= $this->getValueIf($style->getSpacing() !== null, '\expnd' . $style->getSpacing()); + $content .= $this->getValueIf($style->getKerning() !== null, '\kerning' . $style->getKerning() * 2); + $content .= $this->getValueIf($style->getPosition() !== null, '\up' . $style->getPosition()); + // General - same order as array found in PhpOffice\PhpWord\Style\Font\getStyleValues + // Paragraph not implemented. + $content .= $this->getValueIf($style->isRTL(), '\rtlch'); + $content .= $this->getValueIf($style->getShading() !== null, '\chcfpat' . $this->colorIndex); // Doesn't work; coloring not implemented. + $content .= $this->getValueIf($style->getColor() !== null, '\lnag' . $this->langIndex); // Doesn't work; language not implemented. + // Whitespace and fallbackFont are HTML specific + + // Other items not in included in array found in PhpOffice\PhpWord\Style\Font\getStyleValues + $content .= $this->getValueIf($style->isNoProof(), '\noproof'); + $content .= $this->getValueIf($style->getBgColor() !== null, '\cb' . $this->colorIndex); // Doesn't work; coloring not implemented. return $content . ' '; } @@ -86,4 +137,13 @@ public function setColorIndex($value = 0): void { $this->colorIndex = $value; } + /** + * Set font lang index. + * + * @param int $value + */ + public function setLangIndex($value = 0): void + { + $this->langIndex = $value; + } } From 193e3b2c90207cf8b498e502f5f0cd90d7174c39 Mon Sep 17 00:00:00 2001 From: rasamassen Date: Sun, 31 Aug 2025 13:45:44 -0500 Subject: [PATCH 5/8] Update Font.php Missing return --- src/PhpWord/Writer/RTF/Style/Font.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/PhpWord/Writer/RTF/Style/Font.php b/src/PhpWord/Writer/RTF/Style/Font.php index 332dfc70c2..79bcf596f3 100644 --- a/src/PhpWord/Writer/RTF/Style/Font.php +++ b/src/PhpWord/Writer/RTF/Style/Font.php @@ -115,6 +115,7 @@ public function write() // Other items not in included in array found in PhpOffice\PhpWord\Style\Font\getStyleValues $content .= $this->getValueIf($style->isNoProof(), '\noproof'); $content .= $this->getValueIf($style->getBgColor() !== null, '\cb' . $this->colorIndex); // Doesn't work; coloring not implemented. + return $content . ' '; } From e97f35b05eef05251a0c3482c5b554c1e45d41fa Mon Sep 17 00:00:00 2001 From: rasamassen Date: Sun, 31 Aug 2025 14:28:21 -0500 Subject: [PATCH 6/8] Update Section.php - Add Vertical Align --- src/PhpWord/Writer/RTF/Style/Section.php | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/PhpWord/Writer/RTF/Style/Section.php b/src/PhpWord/Writer/RTF/Style/Section.php index 598015ed4d..fe236febf4 100644 --- a/src/PhpWord/Writer/RTF/Style/Section.php +++ b/src/PhpWord/Writer/RTF/Style/Section.php @@ -55,6 +55,15 @@ public function write() $content .= $this->getValueIf($style->getFooterHeight() !== null, '\footery' . round($style->getFooterHeight())); $content .= $this->getValueIf($style->getGutter() !== null, '\guttersxn' . round($style->getGutter())); $content .= $this->getValueIf($style->getPageNumberingStart() !== null, '\pgnstarts' . $style->getPageNumberingStart() . '\pgnrestart'); + + // Vertical Align + $verticalAlign = [ + \PhpOffice\PhpWord\SimpleType\VerticalJc::TOP => '\vertalt', + \PhpOffice\PhpWord\SimpleType\VerticalJc::CENTER => '\vertalc', + \PhpOffice\PhpWord\SimpleType\VerticalJc::BOTH => '\vertalj', + \PhpOffice\PhpWord\SimpleType\VerticalJc::BOTTOM => '\vertalb', + ]; + if (isset($verticalAlign[$style->getVAlign()])) { $content .= $verticalAlign[$style->getVAlign()]; } $content .= ' '; // Borders From edb77529005e16c36539af3e50af0d0c08c5786b Mon Sep 17 00:00:00 2001 From: rasamassen Date: Sun, 31 Aug 2025 14:52:35 -0500 Subject: [PATCH 7/8] Update Tab.php Add Bar --- src/PhpWord/Writer/RTF/Style/Tab.php | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/PhpWord/Writer/RTF/Style/Tab.php b/src/PhpWord/Writer/RTF/Style/Tab.php index a6b26ded7f..5c2a31475f 100644 --- a/src/PhpWord/Writer/RTF/Style/Tab.php +++ b/src/PhpWord/Writer/RTF/Style/Tab.php @@ -51,8 +51,11 @@ public function write() if (isset($tabs[$style->getLeader()])) { $content .= $tabs[$style->getLeader()]; } - $content .= '\tx' . round($style->getPosition()); - + if ($style->getType() == \PhpOffice\PhpWord\Style\Tab::TAB_STOP_BAR) { + $content .= '\tb' . round($style->getPosition()); + } else { + $content .= '\tx' . round($style->getPosition()); + } return $content; } } From 715790014c1b80e8f35b7f38f58716b3855ec025 Mon Sep 17 00:00:00 2001 From: rasamassen Date: Sun, 31 Aug 2025 14:58:13 -0500 Subject: [PATCH 8/8] Update Font.php - Typeos in lang --- src/PhpWord/Writer/RTF/Style/Font.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/PhpWord/Writer/RTF/Style/Font.php b/src/PhpWord/Writer/RTF/Style/Font.php index 79bcf596f3..171e9fe8c0 100644 --- a/src/PhpWord/Writer/RTF/Style/Font.php +++ b/src/PhpWord/Writer/RTF/Style/Font.php @@ -109,7 +109,7 @@ public function write() // Paragraph not implemented. $content .= $this->getValueIf($style->isRTL(), '\rtlch'); $content .= $this->getValueIf($style->getShading() !== null, '\chcfpat' . $this->colorIndex); // Doesn't work; coloring not implemented. - $content .= $this->getValueIf($style->getColor() !== null, '\lnag' . $this->langIndex); // Doesn't work; language not implemented. + $content .= $this->getValueIf($style->getLang() !== null, '\lang' . $this->langIndex); // Doesn't work; language not implemented. // Whitespace and fallbackFont are HTML specific // Other items not in included in array found in PhpOffice\PhpWord\Style\Font\getStyleValues