Nenhuma descrição

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  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. * @link https://github.com/PHPOffice/PHPWord
  14. * @copyright 2010-2014 PHPWord contributors
  15. * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3
  16. */
  17. namespace PhpOffice\PhpWord\Writer\Word2007\Element;
  18. use PhpOffice\PhpWord\Element\TOC as TOCElement;
  19. use PhpOffice\PhpWord\Shared\XMLWriter;
  20. use PhpOffice\PhpWord\Style\Font;
  21. use PhpOffice\PhpWord\Writer\Word2007\Style\Font as FontStyleWriter;
  22. use PhpOffice\PhpWord\Writer\Word2007\Style\Paragraph as ParagraphStyleWriter;
  23. use PhpOffice\PhpWord\Writer\Word2007\Style\Tab as TabStyleWriter;
  24. /**
  25. * TOC element writer
  26. *
  27. * @since 0.10.0
  28. */
  29. class TOC extends AbstractElement
  30. {
  31. /**
  32. * Write element.
  33. *
  34. * @return void
  35. */
  36. public function write()
  37. {
  38. $xmlWriter = $this->getXmlWriter();
  39. $element = $this->getElement();
  40. if (!$element instanceof TOCElement) {
  41. return;
  42. }
  43. $titles = $element->getTitles();
  44. $writeFieldMark = true;
  45. foreach ($titles as $title) {
  46. $this->writeTitle($xmlWriter, $element, $title, $writeFieldMark);
  47. if ($writeFieldMark) {
  48. $writeFieldMark = false;
  49. }
  50. }
  51. $xmlWriter->startElement('w:p');
  52. $xmlWriter->startElement('w:r');
  53. $xmlWriter->startElement('w:fldChar');
  54. $xmlWriter->writeAttribute('w:fldCharType', 'end');
  55. $xmlWriter->endElement();
  56. $xmlWriter->endElement();
  57. $xmlWriter->endElement();
  58. }
  59. /**
  60. * Write title
  61. *
  62. * @param \PhpOffice\PhpWord\Shared\XMLWriter $xmlWriter
  63. * @param \PhpOffice\PhpWord\Element\TOC $element
  64. * @param \PhpOffice\PhpWord\Element\Title $title
  65. * @param bool $writeFieldMark
  66. * @return void
  67. */
  68. private function writeTitle(XMLWriter $xmlWriter, TOCElement $element, $title, $writeFieldMark)
  69. {
  70. $tocStyle = $element->getStyleTOC();
  71. $fontStyle = $element->getStyleFont();
  72. $isObject = ($fontStyle instanceof Font) ? true : false;
  73. $rId = $title->getRelationId();
  74. $indent = ($title->getDepth() - 1) * $tocStyle->getIndent();
  75. $xmlWriter->startElement('w:p');
  76. // Write style and field mark
  77. $this->writeStyle($xmlWriter, $element, $indent);
  78. if ($writeFieldMark) {
  79. $this->writeFieldMark($xmlWriter, $element);
  80. }
  81. // Hyperlink
  82. $xmlWriter->startElement('w:hyperlink');
  83. $xmlWriter->writeAttribute('w:anchor', "_Toc{$rId}");
  84. $xmlWriter->writeAttribute('w:history', '1');
  85. // Title text
  86. $xmlWriter->startElement('w:r');
  87. if ($isObject) {
  88. $styleWriter = new FontStyleWriter($xmlWriter, $fontStyle);
  89. $styleWriter->write();
  90. }
  91. $xmlWriter->startElement('w:t');
  92. $xmlWriter->writeRaw($title->getText());
  93. $xmlWriter->endElement();
  94. $xmlWriter->endElement(); // w:r
  95. $xmlWriter->startElement('w:r');
  96. $xmlWriter->writeElement('w:tab', null);
  97. $xmlWriter->endElement();
  98. $xmlWriter->startElement('w:r');
  99. $xmlWriter->startElement('w:fldChar');
  100. $xmlWriter->writeAttribute('w:fldCharType', 'begin');
  101. $xmlWriter->endElement();
  102. $xmlWriter->endElement();
  103. $xmlWriter->startElement('w:r');
  104. $xmlWriter->startElement('w:instrText');
  105. $xmlWriter->writeAttribute('xml:space', 'preserve');
  106. $xmlWriter->writeRaw("PAGEREF _Toc{$rId} \h");
  107. $xmlWriter->endElement();
  108. $xmlWriter->endElement();
  109. $xmlWriter->startElement('w:r');
  110. $xmlWriter->startElement('w:fldChar');
  111. $xmlWriter->writeAttribute('w:fldCharType', 'end');
  112. $xmlWriter->endElement();
  113. $xmlWriter->endElement();
  114. $xmlWriter->endElement(); // w:hyperlink
  115. $xmlWriter->endElement(); // w:p
  116. }
  117. /**
  118. * Write style
  119. *
  120. * @param \PhpOffice\PhpWord\Shared\XMLWriter $xmlWriter
  121. * @param \PhpOffice\PhpWord\Element\TOC $element
  122. * @param int $indent
  123. * @return void
  124. */
  125. private function writeStyle(XMLWriter $xmlWriter, TOCElement $element, $indent)
  126. {
  127. $tocStyle = $element->getStyleTOC();
  128. $fontStyle = $element->getStyleFont();
  129. $isObject = ($fontStyle instanceof Font) ? true : false;
  130. $xmlWriter->startElement('w:pPr');
  131. // Paragraph
  132. if ($isObject && !is_null($fontStyle->getParagraph())) {
  133. $styleWriter = new ParagraphStyleWriter($xmlWriter, $fontStyle->getParagraph());
  134. $styleWriter->write();
  135. }
  136. // Font
  137. if (!empty($fontStyle) && !$isObject) {
  138. $xmlWriter->startElement('w:rPr');
  139. $xmlWriter->startElement('w:rStyle');
  140. $xmlWriter->writeAttribute('w:val', $fontStyle);
  141. $xmlWriter->endElement();
  142. $xmlWriter->endElement(); // w:rPr
  143. }
  144. // Tab
  145. $xmlWriter->startElement('w:tabs');
  146. $styleWriter = new TabStyleWriter($xmlWriter, $tocStyle);
  147. $styleWriter->write();
  148. $xmlWriter->endElement();
  149. // Indent
  150. if ($indent > 0) {
  151. $xmlWriter->startElement('w:ind');
  152. $xmlWriter->writeAttribute('w:left', $indent);
  153. $xmlWriter->endElement();
  154. }
  155. $xmlWriter->endElement(); // w:pPr
  156. }
  157. /**
  158. * Write TOC Field.
  159. *
  160. * @param \PhpOffice\PhpWord\Shared\XMLWriter $xmlWriter
  161. * @param \PhpOffice\PhpWord\Element\TOC $element
  162. * @return void
  163. */
  164. private function writeFieldMark(XMLWriter $xmlWriter, TOCElement $element)
  165. {
  166. $minDepth = $element->getMinDepth();
  167. $maxDepth = $element->getMaxDepth();
  168. $xmlWriter->startElement('w:r');
  169. $xmlWriter->startElement('w:fldChar');
  170. $xmlWriter->writeAttribute('w:fldCharType', 'begin');
  171. $xmlWriter->endElement();
  172. $xmlWriter->endElement();
  173. $xmlWriter->startElement('w:r');
  174. $xmlWriter->startElement('w:instrText');
  175. $xmlWriter->writeAttribute('xml:space', 'preserve');
  176. $xmlWriter->writeRaw("TOC \o {$minDepth}-{$maxDepth} \h \z \u");
  177. $xmlWriter->endElement();
  178. $xmlWriter->endElement();
  179. $xmlWriter->startElement('w:r');
  180. $xmlWriter->startElement('w:fldChar');
  181. $xmlWriter->writeAttribute('w:fldCharType', 'separate');
  182. $xmlWriter->endElement();
  183. $xmlWriter->endElement();
  184. }
  185. }