Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
100.00% |
96 / 96 |
|
100.00% |
1 / 1 |
CRAP | |
100.00% |
1 / 1 |
Paragraph | |
100.00% |
96 / 96 |
|
100.00% |
1 / 1 |
31 | |
100.00% |
1 / 1 |
write | |
100.00% |
96 / 96 |
|
100.00% |
1 / 1 |
31 |
1 | <?php |
2 | /** |
3 | * This file is part of PHPWord - A pure PHP library for reading and writing |
4 | * word processing documents. |
5 | * |
6 | * PHPWord is free software distributed under the terms of the GNU Lesser |
7 | * General Public License version 3 as published by the Free Software Foundation. |
8 | * |
9 | * For the full copyright and license information, please read the LICENSE |
10 | * file that was distributed with this source code. For the full list of |
11 | * contributors, visit https://github.com/PHPOffice/PHPWord/contributors. |
12 | * |
13 | * @see https://github.com/PHPOffice/PHPWord |
14 | * |
15 | * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3 |
16 | */ |
17 | |
18 | namespace PhpOffice\PhpWord\Writer\ODText\Style; |
19 | |
20 | use PhpOffice\PhpWord\Settings; |
21 | use PhpOffice\PhpWord\Shared\Converter; |
22 | use PhpOffice\PhpWord\SimpleType\Jc; |
23 | use PhpOffice\PhpWord\Style; |
24 | |
25 | /** |
26 | * Font style writer. |
27 | * |
28 | * @since 0.10.0 |
29 | */ |
30 | class Paragraph extends AbstractStyle |
31 | { |
32 | private const BIDI_MAP = [ |
33 | Jc::END => Jc::LEFT, |
34 | Jc::START => Jc::RIGHT, |
35 | ]; |
36 | |
37 | private const NON_BIDI_MAP = [ |
38 | Jc::START => Jc::LEFT, |
39 | Jc::END => Jc::RIGHT, |
40 | ]; |
41 | |
42 | /** |
43 | * Write style. |
44 | */ |
45 | public function write(): void |
46 | { |
47 | $style = $this->getStyle(); |
48 | if (!$style instanceof \PhpOffice\PhpWord\Style\Paragraph) { |
49 | return; |
50 | } |
51 | $xmlWriter = $this->getXmlWriter(); |
52 | |
53 | $marginTop = $style->getSpaceBefore(); |
54 | $marginBottom = $style->getSpaceAfter(); |
55 | |
56 | $xmlWriter->startElement('style:style'); |
57 | |
58 | $styleName = (string) $style->getStyleName(); |
59 | $styleAuto = false; |
60 | $mpm = ''; |
61 | $psm = ''; |
62 | $pagestart = -1; |
63 | $breakafter = $breakbefore = $breakauto = false; |
64 | if ($style->isAuto()) { |
65 | if (substr($styleName, 0, 2) === 'PB') { |
66 | $styleAuto = true; |
67 | $breakafter = true; |
68 | } elseif (substr($styleName, 0, 2) === 'SB') { |
69 | $styleAuto = true; |
70 | $mpm = 'Standard' . substr($styleName, 2); |
71 | $psn = $style->getNumLevel(); |
72 | $pagestart = $psn; |
73 | } elseif (substr($styleName, 0, 2) === 'HD') { |
74 | $styleAuto = true; |
75 | $psm = 'Heading_' . substr($styleName, 2); |
76 | $stylep = \PhpOffice\PhpWord\Style::getStyle($psm); |
77 | if ($stylep instanceof \PhpOffice\PhpWord\Style\Font) { |
78 | if (method_exists($stylep, 'getParagraph')) { |
79 | $stylep = $stylep->getParagraph(); |
80 | } |
81 | } |
82 | if ($stylep instanceof \PhpOffice\PhpWord\Style\Paragraph) { |
83 | if ($stylep->hasPageBreakBefore()) { |
84 | $breakbefore = true; |
85 | } |
86 | } |
87 | } elseif (substr($styleName, 0, 2) === 'HE') { |
88 | $styleAuto = true; |
89 | $psm = 'Heading_' . substr($styleName, 2); |
90 | $breakauto = true; |
91 | } else { |
92 | $styleAuto = true; |
93 | $psm = 'Normal'; |
94 | if (preg_match('/^P\\d+_(\\w+)$/', $styleName, $matches)) { |
95 | $psm = $matches[1]; |
96 | } |
97 | } |
98 | } |
99 | |
100 | $xmlWriter->writeAttribute('style:name', $style->getStyleName()); |
101 | $xmlWriter->writeAttribute('style:family', 'paragraph'); |
102 | if ($styleAuto) { |
103 | $xmlWriter->writeAttributeIf($psm !== '', 'style:parent-style-name', $psm); |
104 | $xmlWriter->writeAttributeIf($mpm !== '', 'style:master-page-name', $mpm); |
105 | } |
106 | |
107 | $xmlWriter->startElement('style:paragraph-properties'); |
108 | if ($styleAuto) { |
109 | if ($breakafter) { |
110 | $xmlWriter->writeAttribute('fo:break-after', 'page'); |
111 | $xmlWriter->writeAttribute('fo:margin-top', '0cm'); |
112 | $xmlWriter->writeAttribute('fo:margin-bottom', '0cm'); |
113 | } elseif ($breakbefore) { |
114 | $xmlWriter->writeAttribute('fo:break-before', 'page'); |
115 | } elseif ($breakauto) { |
116 | $xmlWriter->writeAttribute('fo:break-before', 'auto'); |
117 | } |
118 | if ($pagestart > 0) { |
119 | $xmlWriter->writeAttribute('style:page-number', $pagestart); |
120 | } |
121 | } |
122 | if (!$breakafter && !$breakbefore && !$breakauto) { |
123 | $twipToPoint = Converter::INCH_TO_TWIP / Converter::INCH_TO_POINT; // 20 |
124 | $xmlWriter->writeAttributeIf($marginTop !== null, 'fo:margin-top', ($marginTop / $twipToPoint) . 'pt'); |
125 | $xmlWriter->writeAttributeIf($marginBottom !== null, 'fo:margin-bottom', ($marginBottom / $twipToPoint) . 'pt'); |
126 | } |
127 | $alignment = $style->getAlignment(); |
128 | $bidi = $style->isBidi(); |
129 | $defaultRtl = Settings::isDefaultRtl(); |
130 | if ($alignment === '' && $bidi !== null) { |
131 | $alignment = Jc::START; |
132 | } |
133 | if ($bidi) { |
134 | $alignment = self::BIDI_MAP[$alignment] ?? $alignment; |
135 | } elseif ($defaultRtl !== null) { |
136 | $alignment = self::NON_BIDI_MAP[$alignment] ?? $alignment; |
137 | } |
138 | $xmlWriter->writeAttributeIf($alignment !== '', 'fo:text-align', $alignment); |
139 | $temp = $style->getLineHeight(); |
140 | $xmlWriter->writeAttributeIf($temp !== null, 'fo:line-height', ((string) ($temp * 100) . '%')); |
141 | $xmlWriter->writeAttributeIf($style->hasPageBreakBefore() === true, 'fo:break-before', 'page'); |
142 | |
143 | $tabs = $style->getTabs(); |
144 | if ($tabs !== null && count($tabs) > 0) { |
145 | $xmlWriter->startElement('style:tab-stops'); |
146 | foreach ($tabs as $tab) { |
147 | $xmlWriter->startElement('style:tab-stop'); |
148 | $xmlWriter->writeAttribute('style:type', $tab->getType()); |
149 | $xmlWriter->writeAttribute('style:position', (string) ($tab->getPosition() / Converter::INCH_TO_TWIP) . 'in'); |
150 | $xmlWriter->endElement(); |
151 | } |
152 | $xmlWriter->endElement(); |
153 | } |
154 | |
155 | //Right to left |
156 | $xmlWriter->writeAttributeIf($style->isBidi(), 'style:writing-mode', 'rl-tb'); |
157 | |
158 | //Indentation |
159 | $indent = $style->getIndentation(); |
160 | //if ($indent instanceof \PhpOffice\PhpWord\Style\Indentation) { |
161 | if (!empty($indent)) { |
162 | $marg = $indent->getLeft(); |
163 | $xmlWriter->writeAttributeIf($marg !== null, 'fo:margin-left', (string) ($marg / Converter::INCH_TO_TWIP) . 'in'); |
164 | $marg = $indent->getRight(); |
165 | $xmlWriter->writeAttributeIf($marg !== null, 'fo:margin-right', (string) ($marg / Converter::INCH_TO_TWIP) . 'in'); |
166 | } |
167 | |
168 | $xmlWriter->endElement(); //style:paragraph-properties |
169 | |
170 | if ($styleAuto && substr($styleName, 0, 2) === 'SB') { |
171 | $xmlWriter->startElement('style:text-properties'); |
172 | $xmlWriter->writeAttribute('text:display', 'none'); |
173 | $xmlWriter->endElement(); |
174 | } |
175 | |
176 | $xmlWriter->endElement(); //style:style |
177 | } |
178 | } |