Text.php 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  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. * @copyright 2010-2018 PHPWord contributors
  15. * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3
  16. */
  17. namespace PhpOffice\PhpWord\Writer\ODText\Element;
  18. use PhpOffice\PhpWord\Element\TrackChange;
  19. use PhpOffice\PhpWord\Exception\Exception;
  20. /**
  21. * Text element writer
  22. *
  23. * @since 0.10.0
  24. */
  25. class Text extends AbstractElement
  26. {
  27. /**
  28. * Write element
  29. */
  30. public function write()
  31. {
  32. $xmlWriter = $this->getXmlWriter();
  33. $element = $this->getElement();
  34. if (!$element instanceof \PhpOffice\PhpWord\Element\Text) {
  35. return;
  36. }
  37. $fontStyle = $element->getFontStyle();
  38. $paragraphStyle = $element->getParagraphStyle();
  39. // @todo Commented for TextRun. Should really checkout this value
  40. // $fStyleIsObject = ($fontStyle instanceof Font) ? true : false;
  41. //$fStyleIsObject = false;
  42. //if ($fStyleIsObject) {
  43. // Don't never be the case, because I browse all sections for cleaning all styles not declared
  44. // throw new Exception('PhpWord : $fStyleIsObject wouldn\'t be an object');
  45. //}
  46. if (!$this->withoutP) {
  47. $xmlWriter->startElement('text:p'); // text:p
  48. }
  49. if ($element->getTrackChange() != null && $element->getTrackChange()->getChangeType() == TrackChange::DELETED) {
  50. $xmlWriter->startElement('text:change');
  51. $xmlWriter->writeAttribute('text:change-id', $element->getTrackChange()->getElementId());
  52. $xmlWriter->endElement();
  53. } else {
  54. if (empty($fontStyle)) {
  55. if (empty($paragraphStyle)) {
  56. if (!$this->withoutP) {
  57. $xmlWriter->writeAttribute('text:style-name', 'Normal');
  58. }
  59. } elseif (is_string($paragraphStyle)) {
  60. if (!$this->withoutP) {
  61. $xmlWriter->writeAttribute('text:style-name', $paragraphStyle);
  62. }
  63. }
  64. $this->writeChangeInsertion(true, $element->getTrackChange());
  65. $this->replaceTabs($element->getText(), $xmlWriter);
  66. $this->writeChangeInsertion(false, $element->getTrackChange());
  67. } else {
  68. if (empty($paragraphStyle)) {
  69. if (!$this->withoutP) {
  70. $xmlWriter->writeAttribute('text:style-name', 'Normal');
  71. }
  72. } elseif (is_string($paragraphStyle)) {
  73. if (!$this->withoutP) {
  74. $xmlWriter->writeAttribute('text:style-name', $paragraphStyle);
  75. }
  76. }
  77. // text:span
  78. $xmlWriter->startElement('text:span');
  79. if (is_string($fontStyle)) {
  80. $xmlWriter->writeAttribute('text:style-name', $fontStyle);
  81. }
  82. $this->writeChangeInsertion(true, $element->getTrackChange());
  83. $this->replaceTabs($element->getText(), $xmlWriter);
  84. $this->writeChangeInsertion(false, $element->getTrackChange());
  85. $xmlWriter->endElement();
  86. }
  87. }
  88. if (!$this->withoutP) {
  89. $xmlWriter->endElement(); // text:p
  90. }
  91. }
  92. private function replacetabs($text, $xmlWriter)
  93. {
  94. if (preg_match('/^ +/', $text, $matches)) {
  95. $num = strlen($matches[0]);
  96. $xmlWriter->startElement('text:s');
  97. $xmlWriter->writeAttributeIf($num > 1, 'text:c', "$num");
  98. $xmlWriter->endElement();
  99. $text = preg_replace('/^ +/', '', $text);
  100. }
  101. preg_match_all('/([\\s\\S]*?)(\\t| +| ?$)/', $text, $matches, PREG_SET_ORDER);
  102. foreach ($matches as $match) {
  103. $this->writeText($match[1]);
  104. if ($match[2] === '') {
  105. break;
  106. } elseif ($match[2] === "\t") {
  107. $xmlWriter->writeElement('text:tab');
  108. } elseif ($match[2] === ' ') {
  109. $xmlWriter->writeElement('text:s');
  110. break;
  111. } else {
  112. $num = strlen($match[2]);
  113. $xmlWriter->startElement('text:s');
  114. $xmlWriter->writeAttributeIf($num > 1, 'text:c', "$num");
  115. $xmlWriter->endElement();
  116. }
  117. }
  118. }
  119. private function writeChangeInsertion($start = true, TrackChange $trackChange = null)
  120. {
  121. if ($trackChange == null || $trackChange->getChangeType() != TrackChange::INSERTED) {
  122. return;
  123. }
  124. $xmlWriter = $this->getXmlWriter();
  125. $xmlWriter->startElement('text:change-' . ($start ? 'start' : 'end'));
  126. $xmlWriter->writeAttribute('text:change-id', $trackChange->getElementId());
  127. $xmlWriter->endElement();
  128. }
  129. }