From a6894dd68934d5889c1da24b20e6306650c6952f Mon Sep 17 00:00:00 2001 From: Maksim Tiugaev Date: Tue, 13 Feb 2024 16:33:53 +0300 Subject: [PATCH] Respect indents from readed file --- docs/changes/2.x/2.0.0.md | 2 +- src/PhpWord/Reader/Word2007/AbstractPart.php | 6 +- src/PhpWord/Style/Paragraph.php | 77 ++++++++++++++++++- .../Reader/Word2007/StyleTest.php | 49 ++++++++++++ 4 files changed, 129 insertions(+), 5 deletions(-) diff --git a/docs/changes/2.x/2.0.0.md b/docs/changes/2.x/2.0.0.md index 8214ded041..965adee7ea 100644 --- a/docs/changes/2.x/2.0.0.md +++ b/docs/changes/2.x/2.0.0.md @@ -11,8 +11,8 @@ - MsDoc Reader : Correct Font Size Calculation by [@oleibman](https://github.com/oleibman) fixing [#2526](https://github.com/PHPOffice/PHPWord/issues/2526) in [#2531](https://github.com/PHPOffice/PHPWord/pull/2531) - TemplateProcessor Persist File After Destruct [@oleibman](https://github.com/oleibman) fixing [#2539](https://github.com/PHPOffice/PHPWord/issues/2539) in [#2545](https://github.com/PHPOffice/PHPWord/pull/2545) - bug: TemplateProcessor fix multiline values [@gimler](https://github.com/gimler) fixing [#268](https://github.com/PHPOffice/PHPWord/issues/268), [#2323](https://github.com/PHPOffice/PHPWord/issues/2323) and [#2486](https://github.com/PHPOffice/PHPWord/issues/2486) in [#2522](https://github.com/PHPOffice/PHPWord/pull/2522) - - 32-bit Problem in PasswordEncoder [@oleibman](https://github.com/oleibman) fixing [#2550](https://github.com/PHPOffice/PHPWord/issues/2550) in [#2551](https://github.com/PHPOffice/PHPWord/pull/2551) +- Respect paragraph indent units when reading file by [@tugmaks](https://github.com/tugmaks) fixing [#507](https://github.com/PHPOffice/PHPWord/issues/507) ### Miscellaneous diff --git a/src/PhpWord/Reader/Word2007/AbstractPart.php b/src/PhpWord/Reader/Word2007/AbstractPart.php index 95799387ed..265976a499 100644 --- a/src/PhpWord/Reader/Word2007/AbstractPart.php +++ b/src/PhpWord/Reader/Word2007/AbstractPart.php @@ -518,8 +518,10 @@ protected function readParagraphStyle(XMLReader $xmlReader, DOMElement $domNode) 'alignment' => [self::READ_VALUE, 'w:jc'], 'basedOn' => [self::READ_VALUE, 'w:basedOn'], 'next' => [self::READ_VALUE, 'w:next'], - 'indent' => [self::READ_VALUE, 'w:ind', 'w:left'], - 'hanging' => [self::READ_VALUE, 'w:ind', 'w:hanging'], + 'indentLeft' => [self::READ_VALUE, 'w:ind', 'w:left'], + 'indentRight' => [self::READ_VALUE, 'w:ind', 'w:right'], + 'indentHanging' => [self::READ_VALUE, 'w:ind', 'w:hanging'], + 'indentFirstLine' => [self::READ_VALUE, 'w:ind', 'w:firstLine'], 'spaceAfter' => [self::READ_VALUE, 'w:spacing', 'w:after'], 'spaceBefore' => [self::READ_VALUE, 'w:spacing', 'w:before'], 'widowControl' => [self::READ_FALSE, 'w:widowControl'], diff --git a/src/PhpWord/Style/Paragraph.php b/src/PhpWord/Style/Paragraph.php index c77617403d..554aee83cd 100644 --- a/src/PhpWord/Style/Paragraph.php +++ b/src/PhpWord/Style/Paragraph.php @@ -17,6 +17,9 @@ namespace PhpOffice\PhpWord\Style; +use function array_map; +use function is_numeric; +use function is_string; use PhpOffice\PhpWord\Exception\InvalidStyleException; use PhpOffice\PhpWord\Settings; use PhpOffice\PhpWord\Shared\Text; @@ -332,14 +335,26 @@ public function getIndentation() } /** - * Set shading. + * Set indentation. * - * @param mixed $value + * @param array{ + * left?:null|float|int|numeric-string, + * right?:null|float|int|numeric-string, + * hanging?:null|float|int|numeric-string, + * firstLine?:null|float|int|numeric-string + * } $value * * @return self */ public function setIndentation($value = null) { + $value = array_map(function ($indent) { + if (is_string($indent) && is_numeric($indent)) { + $indent = $this->setFloatVal($indent); + } + + return $indent; + }, $value); $this->setObjectVal($value, 'Indentation', $this->indentation); return $this; @@ -367,6 +382,54 @@ public function setIndent($value = null) return $this->setIndentation(['left' => $value]); } + /** + * Set left indentation. + * + * @param float|int|numeric-string $value + * + * @return self + */ + public function setIndentLeft($value = null) + { + return $this->setIndentation(['left' => $value]); + } + + /** + * Set right indentation. + * + * @param float|int|numeric-string $value + * + * @return self + */ + public function setIndentRight($value = null) + { + return $this->setIndentation(['right' => $value]); + } + + /** + * Set right indentation. + * + * @param float|int|numeric-string $value + * + * @return self + */ + public function setIndentHanging($value = null) + { + return $this->setIndentation(['hanging' => $value]); + } + + /** + * Set right indentation. + * + * @param float|int|numeric-string $value + * + * @return self + */ + public function setIndentFirstLine($value = null) + { + return $this->setIndentation(['firstLine' => $value]); + } + /** * Get hanging. * @@ -377,6 +440,16 @@ public function getHanging() return $this->getChildStyleValue($this->indentation, 'hanging'); } + /** + * Get firstLine. + * + * @return int + */ + public function getFirstLine() + { + return $this->getChildStyleValue($this->indentation, 'firstLine'); + } + /** * Set hanging. * diff --git a/tests/PhpWordTests/Reader/Word2007/StyleTest.php b/tests/PhpWordTests/Reader/Word2007/StyleTest.php index 015a3cfcb7..69b4e389a2 100644 --- a/tests/PhpWordTests/Reader/Word2007/StyleTest.php +++ b/tests/PhpWordTests/Reader/Word2007/StyleTest.php @@ -17,6 +17,8 @@ namespace PhpOffice\PhpWordTests\Reader\Word2007; +use Generator; +use PhpOffice\PhpWord\Element\TextRun; use PhpOffice\PhpWord\SimpleType\Border; use PhpOffice\PhpWord\SimpleType\TblWidth; use PhpOffice\PhpWord\SimpleType\VerticalJc; @@ -289,4 +291,51 @@ public function testPageVerticalAlign(): void $sectionStyle = $phpWord->getSection(0)->getStyle(); self::assertEquals(VerticalJc::CENTER, $sectionStyle->getVAlign()); } + + /** + * @dataProvider providerIndentation + * + * @param string $indent + * @param float $left + * @param float $right + * @param null|float $hanging + * @param float $firstLine + */ + public function testIndentation($indent, $left, $right, $hanging, $firstLine): void + { + $documentXml = " + + $indent + + + 1. + + "; + + $phpWord = $this->getDocumentFromString(['document' => $documentXml]); + + $section = $phpWord->getSection(0); + $textRun = $section->getElements()[0]; + self::assertInstanceOf(TextRun::class, $textRun); + + $paragraphStyle = $textRun->getParagraphStyle(); + self::assertInstanceOf(Style\Paragraph::class, $paragraphStyle); + + $indentation = $paragraphStyle->getIndentation(); + self::assertSame($left, $indentation->getLeft()); + self::assertSame($right, $indentation->getRight()); + self::assertSame($hanging, $indentation->getHanging()); + self::assertSame($firstLine, $indentation->getFirstLine()); + } + + /** + * @return Generator + */ + public static function providerIndentation() + { + yield ['', 709.00, 488.00, 10.0, 490.00]; + yield ['', 0, 0, 10.0, 490.00]; + yield ['', 709.00, 0, null, 0]; + yield ['', 0, 488.00, null, 0]; + } }