Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
100.00% |
142 / 142 |
|
100.00% |
5 / 5 |
CRAP | |
100.00% |
1 / 1 |
Styles | |
100.00% |
142 / 142 |
|
100.00% |
5 / 5 |
26 | |
100.00% |
1 / 1 |
write | |
100.00% |
17 / 17 |
|
100.00% |
1 / 1 |
5 | |||
writeDefaultStyles | |
100.00% |
62 / 62 |
|
100.00% |
1 / 1 |
9 | |||
writeFontStyle | |
100.00% |
36 / 36 |
|
100.00% |
1 / 1 |
10 | |||
writeParagraphStyle | |
100.00% |
14 / 14 |
|
100.00% |
1 / 1 |
1 | |||
writeTableStyle | |
100.00% |
13 / 13 |
|
100.00% |
1 / 1 |
1 |
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\Word2007\Part; |
19 | |
20 | use PhpOffice\PhpWord\Shared\XMLWriter; |
21 | use PhpOffice\PhpWord\Style; |
22 | use PhpOffice\PhpWord\Style\Font as FontStyle; |
23 | use PhpOffice\PhpWord\Style\Paragraph as ParagraphStyle; |
24 | use PhpOffice\PhpWord\Style\Table as TableStyle; |
25 | use PhpOffice\PhpWord\Writer\Word2007\Style\Font as FontStyleWriter; |
26 | use PhpOffice\PhpWord\Writer\Word2007\Style\Paragraph as ParagraphStyleWriter; |
27 | use PhpOffice\PhpWord\Writer\Word2007\Style\Table as TableStyleWriter; |
28 | |
29 | /** |
30 | * Word2007 styles part writer: word/styles.xml. |
31 | * |
32 | * @todo Do something with the numbering style introduced in 0.10.0 |
33 | * |
34 | * @SuppressWarnings(PHPMD.UnusedPrivateMethod) For writeFontStyle, writeParagraphStyle, and writeTableStyle |
35 | */ |
36 | class Styles extends AbstractPart |
37 | { |
38 | /** |
39 | * Write part. |
40 | * |
41 | * @return string |
42 | */ |
43 | public function write() |
44 | { |
45 | $xmlWriter = $this->getXmlWriter(); |
46 | |
47 | $xmlWriter->startDocument('1.0', 'UTF-8', 'yes'); |
48 | $xmlWriter->startElement('w:styles'); |
49 | $xmlWriter->writeAttribute('xmlns:r', 'http://schemas.openxmlformats.org/officeDocument/2006/relationships'); |
50 | $xmlWriter->writeAttribute('xmlns:w', 'http://schemas.openxmlformats.org/wordprocessingml/2006/main'); |
51 | |
52 | // Write default styles |
53 | $styles = Style::getStyles(); |
54 | $this->writeDefaultStyles($xmlWriter, $styles); |
55 | |
56 | // Write styles |
57 | if (count($styles) > 0) { |
58 | foreach ($styles as $styleName => $style) { |
59 | if ($styleName == 'Normal') { |
60 | continue; |
61 | } |
62 | |
63 | // Get style class and execute if the private method exists |
64 | $styleClass = substr(get_class($style), strrpos(get_class($style), '\\') + 1); |
65 | $method = "write{$styleClass}Style"; |
66 | if (method_exists($this, $method)) { |
67 | $this->$method($xmlWriter, $styleName, $style); |
68 | } |
69 | } |
70 | } |
71 | |
72 | $xmlWriter->endElement(); // w:styles |
73 | |
74 | return $xmlWriter->getData(); |
75 | } |
76 | |
77 | /** |
78 | * Write default font and other default styles. |
79 | * |
80 | * @param \PhpOffice\PhpWord\Style\AbstractStyle[] $styles |
81 | */ |
82 | private function writeDefaultStyles(XMLWriter $xmlWriter, $styles): void |
83 | { |
84 | $phpWord = $this->getParentWriter()->getPhpWord(); |
85 | $fontName = $phpWord->getDefaultFontName(); |
86 | $fontSize = $phpWord->getDefaultFontSize(); |
87 | $language = $phpWord->getSettings()->getThemeFontLang(); |
88 | $latinLanguage = ($language == null || $language->getLatin() === null) ? 'en-US' : $language->getLatin(); |
89 | |
90 | // Default font |
91 | $xmlWriter->startElement('w:docDefaults'); |
92 | $xmlWriter->startElement('w:rPrDefault'); |
93 | $xmlWriter->startElement('w:rPr'); |
94 | $xmlWriter->startElement('w:rFonts'); |
95 | $xmlWriter->writeAttribute('w:ascii', $fontName); |
96 | $xmlWriter->writeAttribute('w:hAnsi', $fontName); |
97 | $xmlWriter->writeAttribute('w:eastAsia', $fontName); |
98 | $xmlWriter->writeAttribute('w:cs', $fontName); |
99 | $xmlWriter->endElement(); // w:rFonts |
100 | $xmlWriter->startElement('w:sz'); |
101 | $xmlWriter->writeAttribute('w:val', $fontSize * 2); |
102 | $xmlWriter->endElement(); // w:sz |
103 | $xmlWriter->startElement('w:szCs'); |
104 | $xmlWriter->writeAttribute('w:val', $fontSize * 2); |
105 | $xmlWriter->endElement(); // w:szCs |
106 | $xmlWriter->startElement('w:lang'); |
107 | $xmlWriter->writeAttribute('w:val', $latinLanguage); |
108 | if ($language != null) { |
109 | $xmlWriter->writeAttributeIf($language->getEastAsia() !== null, 'w:eastAsia', $language->getEastAsia()); |
110 | $xmlWriter->writeAttributeIf($language->getBidirectional() !== null, 'w:bidi', $language->getBidirectional()); |
111 | } |
112 | $xmlWriter->endElement(); // w:lang |
113 | $xmlWriter->endElement(); // w:rPr |
114 | $xmlWriter->endElement(); // w:rPrDefault |
115 | $xmlWriter->endElement(); // w:docDefaults |
116 | |
117 | // Normal style |
118 | $xmlWriter->startElement('w:style'); |
119 | $xmlWriter->writeAttribute('w:type', 'paragraph'); |
120 | $xmlWriter->writeAttribute('w:default', '1'); |
121 | $xmlWriter->writeAttribute('w:styleId', 'Normal'); |
122 | $xmlWriter->startElement('w:name'); |
123 | $xmlWriter->writeAttribute('w:val', 'Normal'); |
124 | $xmlWriter->endElement(); // w:name |
125 | if (isset($styles['Normal'])) { |
126 | $normalStyle = $styles['Normal']; |
127 | // w:pPr |
128 | if ($normalStyle instanceof Fontstyle && $normalStyle->getParagraph() != null) { |
129 | $styleWriter = new ParagraphStyleWriter($xmlWriter, $normalStyle->getParagraph()); |
130 | $styleWriter->write(); |
131 | } elseif ($normalStyle instanceof ParagraphStyle) { |
132 | $styleWriter = new ParagraphStyleWriter($xmlWriter, $normalStyle); |
133 | $styleWriter->write(); |
134 | } |
135 | |
136 | // w:rPr |
137 | $styleWriter = new FontStyleWriter($xmlWriter, $normalStyle); |
138 | $styleWriter->write(); |
139 | } |
140 | $xmlWriter->endElement(); // w:style |
141 | |
142 | // FootnoteReference style |
143 | if (!isset($styles['FootnoteReference'])) { |
144 | $xmlWriter->startElement('w:style'); |
145 | $xmlWriter->writeAttribute('w:type', 'character'); |
146 | $xmlWriter->writeAttribute('w:styleId', 'FootnoteReference'); |
147 | $xmlWriter->startElement('w:name'); |
148 | $xmlWriter->writeAttribute('w:val', 'Footnote Reference'); |
149 | $xmlWriter->endElement(); // w:name |
150 | $xmlWriter->writeElement('w:semiHidden'); |
151 | $xmlWriter->writeElement('w:unhideWhenUsed'); |
152 | $xmlWriter->startElement('w:rPr'); |
153 | $xmlWriter->startElement('w:vertAlign'); |
154 | $xmlWriter->writeAttribute('w:val', 'superscript'); |
155 | $xmlWriter->endElement(); // w:vertAlign |
156 | $xmlWriter->endElement(); // w:rPr |
157 | $xmlWriter->endElement(); // w:style |
158 | } |
159 | } |
160 | |
161 | /** |
162 | * Write font style. |
163 | * |
164 | * @param string $styleName |
165 | */ |
166 | private function writeFontStyle(XMLWriter $xmlWriter, $styleName, FontStyle $style): void |
167 | { |
168 | $paragraphStyle = $style->getParagraph(); |
169 | $styleType = $style->getStyleType(); |
170 | $type = ($styleType == 'title') ? 'paragraph' : 'character'; |
171 | if (null !== $paragraphStyle) { |
172 | $type = 'paragraph'; |
173 | } |
174 | |
175 | $xmlWriter->startElement('w:style'); |
176 | $xmlWriter->writeAttribute('w:type', $type); |
177 | |
178 | // Heading style |
179 | if ($styleType == 'title') { |
180 | $arrStyle = explode('_', $styleName); |
181 | if (count($arrStyle) > 1) { |
182 | $styleId = 'Heading' . $arrStyle[1]; |
183 | $styleName = 'heading ' . $arrStyle[1]; |
184 | $styleLink = 'Heading' . $arrStyle[1] . 'Char'; |
185 | } else { |
186 | $styleId = $styleName; |
187 | $styleName = strtolower($styleName); |
188 | $styleLink = $styleName . 'Char'; |
189 | } |
190 | $xmlWriter->writeAttribute('w:styleId', $styleId); |
191 | |
192 | $xmlWriter->startElement('w:link'); |
193 | $xmlWriter->writeAttribute('w:val', $styleLink); |
194 | $xmlWriter->endElement(); |
195 | } elseif (null !== $paragraphStyle) { |
196 | // if type is 'paragraph' it should have a styleId |
197 | $xmlWriter->writeAttribute('w:styleId', $styleName); |
198 | } |
199 | |
200 | // Style name |
201 | $xmlWriter->startElement('w:name'); |
202 | $xmlWriter->writeAttribute('w:val', $styleName); |
203 | $xmlWriter->endElement(); |
204 | |
205 | // Parent style |
206 | if (null !== $paragraphStyle) { |
207 | if ($paragraphStyle->getStyleName() != null) { |
208 | $xmlWriter->writeElementBlock('w:basedOn', 'w:val', $paragraphStyle->getStyleName()); |
209 | } elseif ($paragraphStyle->getBasedOn() != null) { |
210 | $xmlWriter->writeElementBlock('w:basedOn', 'w:val', $paragraphStyle->getBasedOn()); |
211 | } |
212 | } |
213 | |
214 | // w:pPr |
215 | if (null !== $paragraphStyle) { |
216 | $styleWriter = new ParagraphStyleWriter($xmlWriter, $paragraphStyle); |
217 | $styleWriter->write(); |
218 | } |
219 | |
220 | // w:rPr |
221 | $styleWriter = new FontStyleWriter($xmlWriter, $style); |
222 | $styleWriter->write(); |
223 | |
224 | $xmlWriter->endElement(); |
225 | } |
226 | |
227 | /** |
228 | * Write paragraph style. |
229 | * |
230 | * @param string $styleName |
231 | */ |
232 | private function writeParagraphStyle(XMLWriter $xmlWriter, $styleName, ParagraphStyle $style): void |
233 | { |
234 | $xmlWriter->startElement('w:style'); |
235 | $xmlWriter->writeAttribute('w:type', 'paragraph'); |
236 | $xmlWriter->writeAttribute('w:customStyle', '1'); |
237 | $xmlWriter->writeAttribute('w:styleId', $styleName); |
238 | $xmlWriter->startElement('w:name'); |
239 | $xmlWriter->writeAttribute('w:val', $styleName); |
240 | $xmlWriter->endElement(); |
241 | |
242 | // Parent style |
243 | $basedOn = $style->getBasedOn(); |
244 | $xmlWriter->writeElementIf(null !== $basedOn, 'w:basedOn', 'w:val', $basedOn); |
245 | |
246 | // Next paragraph style |
247 | $next = $style->getNext(); |
248 | $xmlWriter->writeElementIf(null !== $next, 'w:next', 'w:val', $next); |
249 | |
250 | // w:pPr |
251 | $styleWriter = new ParagraphStyleWriter($xmlWriter, $style); |
252 | $styleWriter->write(); |
253 | |
254 | $xmlWriter->endElement(); |
255 | } |
256 | |
257 | /** |
258 | * Write table style. |
259 | * |
260 | * @param string $styleName |
261 | */ |
262 | private function writeTableStyle(XMLWriter $xmlWriter, $styleName, TableStyle $style): void |
263 | { |
264 | $xmlWriter->startElement('w:style'); |
265 | $xmlWriter->writeAttribute('w:type', 'table'); |
266 | $xmlWriter->writeAttribute('w:customStyle', '1'); |
267 | $xmlWriter->writeAttribute('w:styleId', $styleName); |
268 | $xmlWriter->startElement('w:name'); |
269 | $xmlWriter->writeAttribute('w:val', $styleName); |
270 | $xmlWriter->endElement(); |
271 | $xmlWriter->startElement('w:uiPriority'); |
272 | $xmlWriter->writeAttribute('w:val', '99'); |
273 | $xmlWriter->endElement(); |
274 | |
275 | $styleWriter = new TableStyleWriter($xmlWriter, $style); |
276 | $styleWriter->write(); |
277 | |
278 | $xmlWriter->endElement(); // w:style |
279 | } |
280 | } |