From 87f071d1b63183ffaf8801840386c65b4b9978e5 Mon Sep 17 00:00:00 2001 From: Ivan Lanin Date: Tue, 27 May 2014 23:41:15 +0700 Subject: [PATCH 1/4] #72: Basic RTF Reader --- samples/Sample_27_ReadRTF.php | 17 ++ samples/resources/rtf.rtf | 21 ++ src/PhpWord/IOFactory.php | 2 +- src/PhpWord/Reader/AbstractReader.php | 2 +- src/PhpWord/Reader/RTF.php | 50 ++++ src/PhpWord/Reader/RTF/Document.php | 351 +++++++++++++++++++++++++ src/PhpWord/Shared/XMLReader.php | 22 +- src/PhpWord/Writer/RTF/Part/Header.php | 2 +- 8 files changed, 459 insertions(+), 8 deletions(-) create mode 100644 samples/Sample_27_ReadRTF.php create mode 100644 samples/resources/rtf.rtf create mode 100644 src/PhpWord/Reader/RTF.php create mode 100644 src/PhpWord/Reader/RTF/Document.php diff --git a/samples/Sample_27_ReadRTF.php b/samples/Sample_27_ReadRTF.php new file mode 100644 index 00000000..a28ba40b --- /dev/null +++ b/samples/Sample_27_ReadRTF.php @@ -0,0 +1,17 @@ +canRead($docFile)) { + $doc = new Document(); + $doc->rtf = file_get_contents($docFile); + $doc->read($phpWord); + } else { + throw new \Exception("Cannot read {$docFile}."); + } + + return $phpWord; + } +} diff --git a/src/PhpWord/Reader/RTF/Document.php b/src/PhpWord/Reader/RTF/Document.php new file mode 100644 index 00000000..ccb9b595 --- /dev/null +++ b/src/PhpWord/Reader/RTF/Document.php @@ -0,0 +1,351 @@ + 'markOpening', // { + 125 => 'markClosing', // } + 92 => 'markBackslash', // \ + 10 => 'markNewline', // LF + 13 => 'markNewline' // CR + ); + + $this->phpWord = $phpWord; + $this->section = $phpWord->addSection(); + $this->textrun = $this->section->addTextRun(); + $this->length = strlen($this->rtf); + + $this->flags['paragraph'] = true; // Set paragraph flag from the beginning + + // Walk each characters + while ($this->offset < $this->length) { + $char = $this->rtf[$this->offset]; + $ascii = ord($char); + + if (array_key_exists($ascii, $markers)) { // Marker found: {, }, \, LF, or CR + $markerFunction = $markers[$ascii]; + $this->$markerFunction(); + } else { + if ($this->isControl === false) { // Non control word: Push character + $this->pushText($char); + } else { + if (preg_match("/^[a-zA-Z0-9-]?$/", $char)) { // No delimiter: Buffer control + $this->control .= $char; + $this->isFirst = false; + } else { // Delimiter found: Parse buffered control + if ($this->isFirst) { + $this->isFirst = false; + } else { + if ($char == ' ') { // Discard space as a control word delimiter + $this->flushControl(true); + } + } + } + } + } + $this->offset++; + } + $this->flushText(); + } + + /** + * Mark opening braket `{` character + */ + private function markOpening() + { + $this->flush(true); + array_push($this->groups, $this->flags); + } + + /** + * Mark closing braket `}` character + */ + private function markClosing() + { + $this->flush(true); + $this->flags = array_pop($this->groups); + } + + /** + * Mark backslash `\` character + */ + private function markBackslash() + { + if ($this->isFirst) { + $this->setControl(false); + $this->text .= '\\'; + } else { + $this->flush(); + $this->setControl(true); + $this->control = ''; + } + } + + /** + * Mark newline character: Flush control word because it's not possible to span multiline + */ + private function markNewline() + { + if ($this->isControl) { + $this->flushControl(true); + } + } + + /** + * Flush control word or text + * + * @param bool $isControl + */ + private function flush($isControl = false) + { + if ($this->isControl) { + $this->flushControl($isControl); + } else { + $this->flushText(); + } + } + + /** + * Flush control word + * + * @param bool $isControl + */ + private function flushControl($isControl = false) + { + if (preg_match("/^([A-Za-z]+)(-?[0-9]*) ?$/", $this->control, $match) === 1) { + list(, $control, $parameter) = $match; + $this->parseControl($control, $parameter); + } + + if ($isControl === true) { + $this->setControl(false); + } + } + + /* + * Flush text in queue + */ + private function flushText() + { + if ($this->text != '') { + if (isset($this->flags['property'])) { + $this->flags['value'] = $this->text; + var_dump($this->flags); + } else { + if ($this->flags['paragraph'] === true) { + $this->flags['paragraph'] = false; + $this->flags['text'] = $this->text; + } + } + if (!isset($this->flags['skipped'])) { + $this->textrun->addText($this->text); + } + + $this->text = ''; + } + } + + /** + * Reset control word and first char state + * + * @param bool $state + */ + private function setControl($value) + { + $this->isControl = $value; + $this->isFirst = $value; + } + + /** + * Push text into queue + * + * @param string $char + */ + private function pushText($char) + { + if ($char == '<') { + $this->text .= "<"; + } elseif ($char == '>') { + $this->text .= ">"; + } else { + $this->text .= $char; + } + } + + /** + * Parse control + * + * @param string $control + * @param string $parameter + */ + private function parseControl($control, $parameter) + { + $controls = array( + 'par' => array(self::PARA, 'paragraph', true), + 'b' => array(self::STYL, 'bold', true), + 'i' => array(self::STYL, 'italic', true), + 'u' => array(self::STYL, 'underline', true), + 'fonttbl' => array(self::SKIP, 'fonttbl', null), + 'colortbl' => array(self::SKIP, 'colortbl', null), + 'info' => array(self::SKIP, 'info', null), + 'generator' => array(self::SKIP, 'generator', null), + 'title' => array(self::SKIP, 'title', null), + 'subject' => array(self::SKIP, 'subject', null), + 'category' => array(self::SKIP, 'category', null), + 'keywords' => array(self::SKIP, 'keywords', null), + 'comment' => array(self::SKIP, 'comment', null), + 'shppict' => array(self::SKIP, 'pic', null), + 'fldinst' => array(self::SKIP, 'link', null), + ); + + if (array_key_exists($control, $controls)) { + list($mode, $property, $value) = $controls[$control]; + switch ($mode) { + case self::PARA: // Paragraph + $this->textrun = $this->section->addTextRun(); + $this->flags[$property] = $value; + break; + case self::STYL: // Style + $this->flags[$property] = $value; + break; + case self::SKIP: // Destination + $this->flags['property'] = $property; + $this->flags['skipped'] = true; + } + } + } +} diff --git a/src/PhpWord/Shared/XMLReader.php b/src/PhpWord/Shared/XMLReader.php index 60474ce9..153152ee 100644 --- a/src/PhpWord/Shared/XMLReader.php +++ b/src/PhpWord/Shared/XMLReader.php @@ -56,18 +56,30 @@ class XMLReader $zip = new ZipArchive(); $zip->open($zipFile); - $contents = $zip->getFromName($xmlFile); + $content = $zip->getFromName($xmlFile); $zip->close(); - if ($contents === false) { + if ($content === false) { return false; } else { - $this->dom = new \DOMDocument(); - $this->dom->loadXML($contents); - return $this->dom; + return $this->getDomFromString($content); } } + /** + * Get DOMDocument from content string + * + * @param string $content + * @return \DOMDocument + */ + public function getDomFromString($content) + { + $this->dom = new \DOMDocument(); + $this->dom->loadXML($content); + + return $this->dom; + } + /** * Get elements * diff --git a/src/PhpWord/Writer/RTF/Part/Header.php b/src/PhpWord/Writer/RTF/Part/Header.php index c401b500..15a0c303 100644 --- a/src/PhpWord/Writer/RTF/Part/Header.php +++ b/src/PhpWord/Writer/RTF/Part/Header.php @@ -123,7 +123,7 @@ class Header extends AbstractPart $content .= '{'; $content .= '\fonttbl'; foreach ($this->fontTable as $index => $font) { - $content .= "{\\f{$index}\\fnil\\fcharset0{$font};}"; + $content .= "{\\f{$index}\\fnil\\fcharset0 {$font};}"; } $content .= '}'; $content .= PHP_EOL; From 2d88ea22b4f0bd3ea6f62a81ff3fc4b676f3e016 Mon Sep 17 00:00:00 2001 From: Ivan Lanin Date: Thu, 29 May 2014 15:09:02 +0700 Subject: [PATCH 2/4] RTF Reader: Split control parsers into functions --- samples/Sample_11_ReadWord2007.php | 3 +- samples/Sample_24_ReadODText.php | 3 +- samples/Sample_27_ReadRTF.php | 4 +- samples/Sample_Header.php | 4 +- .../{rtf.rtf => Sample_27_ReadRTF.rtf} | 0 src/PhpWord/Reader/RTF.php | 1 + src/PhpWord/Reader/RTF/Document.php | 82 +++++++++++++------ 7 files changed, 64 insertions(+), 33 deletions(-) rename samples/resources/{rtf.rtf => Sample_27_ReadRTF.rtf} (100%) diff --git a/samples/Sample_11_ReadWord2007.php b/samples/Sample_11_ReadWord2007.php index 09d9cab0..c0b54c7a 100644 --- a/samples/Sample_11_ReadWord2007.php +++ b/samples/Sample_11_ReadWord2007.php @@ -3,7 +3,8 @@ include_once 'Sample_Header.php'; // Read contents $name = basename(__FILE__, '.php'); -$source = "resources/{$name}.docx"; +$source = __DIR__ . "/resources/{$name}.docx"; + echo date('H:i:s'), " Reading contents from `{$source}`", EOL; $phpWord = \PhpOffice\PhpWord\IOFactory::load($source); diff --git a/samples/Sample_24_ReadODText.php b/samples/Sample_24_ReadODText.php index bb5332e6..42df23ae 100644 --- a/samples/Sample_24_ReadODText.php +++ b/samples/Sample_24_ReadODText.php @@ -3,7 +3,8 @@ include_once 'Sample_Header.php'; // Read contents $name = basename(__FILE__, '.php'); -$source = "resources/{$name}.odt"; +$source = __DIR__ . "/resources/{$name}.odt"; + echo date('H:i:s'), " Reading contents from `{$source}`", EOL; $phpWord = \PhpOffice\PhpWord\IOFactory::load($source, 'ODText'); diff --git a/samples/Sample_27_ReadRTF.php b/samples/Sample_27_ReadRTF.php index a28ba40b..76ac3d48 100644 --- a/samples/Sample_27_ReadRTF.php +++ b/samples/Sample_27_ReadRTF.php @@ -3,9 +3,7 @@ include_once 'Sample_Header.php'; // Read contents $name = basename(__FILE__, '.php'); -$source = "results/Sample_01_SimpleText.rtf"; -$source = "resources/rtf.rtf"; -$source = "results/Sample_11_ReadWord2007.rtf"; +$source = __DIR__ . "/resources/{$name}.rtf"; echo date('H:i:s'), " Reading contents from `{$source}`", EOL; $phpWord = \PhpOffice\PhpWord\IOFactory::load($source, 'RTF'); diff --git a/samples/Sample_Header.php b/samples/Sample_Header.php index f39bda16..7af23c94 100644 --- a/samples/Sample_Header.php +++ b/samples/Sample_Header.php @@ -63,8 +63,8 @@ function write($phpWord, $filename, $writers) $result .= date('H:i:s') . " Write to {$writer} format"; if (!is_null($extension)) { $xmlWriter = IOFactory::createWriter($phpWord, $writer); - $xmlWriter->save("{$filename}.{$extension}"); - rename("{$filename}.{$extension}", "results/{$filename}.{$extension}"); + $xmlWriter->save(__DIR__ . "/{$filename}.{$extension}"); + rename(__DIR__ . "/{$filename}.{$extension}", __DIR__ . "/results/{$filename}.{$extension}"); } else { $result .= ' ... NOT DONE!'; } diff --git a/samples/resources/rtf.rtf b/samples/resources/Sample_27_ReadRTF.rtf similarity index 100% rename from samples/resources/rtf.rtf rename to samples/resources/Sample_27_ReadRTF.rtf diff --git a/src/PhpWord/Reader/RTF.php b/src/PhpWord/Reader/RTF.php index 1856116c..9d5d813b 100644 --- a/src/PhpWord/Reader/RTF.php +++ b/src/PhpWord/Reader/RTF.php @@ -31,6 +31,7 @@ class RTF extends AbstractReader implements ReaderInterface * Loads PhpWord from file * * @param string $docFile + * @throws \Exception * @return \PhpOffice\PhpWord\PhpWord */ public function load($docFile) diff --git a/src/PhpWord/Reader/RTF/Document.php b/src/PhpWord/Reader/RTF/Document.php index ccb9b595..84e9c1ed 100644 --- a/src/PhpWord/Reader/RTF/Document.php +++ b/src/PhpWord/Reader/RTF/Document.php @@ -18,8 +18,6 @@ namespace PhpOffice\PhpWord\Reader\RTF; use PhpOffice\PhpWord\PhpWord; -use PhpOffice\PhpWord\Element\Section; -use PhpOffice\PhpWord\Element\TextRun; /** * RTF document reader @@ -35,9 +33,9 @@ use PhpOffice\PhpWord\Element\TextRun; class Document { /** @const int */ - const PARA = 0; - const STYL = 1; - const SKIP = 2; + const PARA = 'readParagraph'; + const STYL = 'readStyle'; + const SKIP = 'readSkip'; /** * PhpWord object @@ -247,8 +245,8 @@ class Document private function flushControl($isControl = false) { if (preg_match("/^([A-Za-z]+)(-?[0-9]*) ?$/", $this->control, $match) === 1) { - list(, $control, $parameter) = $match; - $this->parseControl($control, $parameter); + list(, $control) = $match; + $this->parseControl($control); } if ($isControl === true) { @@ -256,23 +254,25 @@ class Document } } - /* + /** * Flush text in queue */ private function flushText() { if ($this->text != '') { - if (isset($this->flags['property'])) { + if (isset($this->flags['property'])) { // Set property $this->flags['value'] = $this->text; - var_dump($this->flags); - } else { + } else { // Set text if ($this->flags['paragraph'] === true) { $this->flags['paragraph'] = false; $this->flags['text'] = $this->text; } } + + // Add text if it's not flagged as skipped if (!isset($this->flags['skipped'])) { - $this->textrun->addText($this->text); + $textrun = $this->textrun->addText($this->text); + $this->flags['element'] = &$textrun; } $this->text = ''; @@ -282,7 +282,7 @@ class Document /** * Reset control word and first char state * - * @param bool $state + * @param bool $value */ private function setControl($value) { @@ -312,7 +312,7 @@ class Document * @param string $control * @param string $parameter */ - private function parseControl($control, $parameter) + private function parseControl($control) { $controls = array( 'par' => array(self::PARA, 'paragraph', true), @@ -333,19 +333,49 @@ class Document ); if (array_key_exists($control, $controls)) { - list($mode, $property, $value) = $controls[$control]; - switch ($mode) { - case self::PARA: // Paragraph - $this->textrun = $this->section->addTextRun(); - $this->flags[$property] = $value; - break; - case self::STYL: // Style - $this->flags[$property] = $value; - break; - case self::SKIP: // Destination - $this->flags['property'] = $property; - $this->flags['skipped'] = true; + list($function) = $controls[$control]; + if (method_exists($this, $function)) { + $this->$function($controls[$control]); } } } + + /** + * Read paragraph + * + * @param array $directives + */ + private function readParagraph($directives) + { + list(, $property, $value) = $directives; + $this->textrun = $this->section->addTextRun(); + $this->flags[$property] = $value; + } + + /** + * Read style + * + * @param array $directives + */ + private function readStyle($directives) + { + list(, $property, $value) = $directives; + $this->flags[$property] = $value; + if (isset($this->flags['element'])) { + $element = &$this->flags['element']; + $element->getFontStyle()->setStyleValue($property, $value); + } + } + + /** + * Read skip + * + * @param array $directives + */ + private function readSkip($directives) + { + list(, $property) = $directives; + $this->flags['property'] = $property; + $this->flags['skipped'] = true; + } } From 7a42802b4882cfe9ecda44b2b0131bb11059c641 Mon Sep 17 00:00:00 2001 From: Ivan Lanin Date: Thu, 29 May 2014 17:37:26 +0700 Subject: [PATCH 3/4] RTF reader: Unit tests and some improvements --- CHANGELOG.md | 3 +- docs/intro.rst | 2 +- docs/src/documentation.md | 2 +- ...e_27_ReadRTF.php => Sample_28_ReadRTF.php} | 0 ...e_27_ReadRTF.rtf => Sample_28_ReadRTF.rtf} | 0 src/PhpWord/Reader/RTF/Document.php | 70 +++++++++++-------- tests/PhpWord/Tests/Reader/ODTextTest.php | 4 +- tests/PhpWord/Tests/Reader/RTFTest.php | 51 ++++++++++++++ tests/PhpWord/Tests/Reader/Word2007Test.php | 33 ++------- .../PhpWord/Tests/_files/documents/reader.rtf | 21 ++++++ 10 files changed, 126 insertions(+), 60 deletions(-) rename samples/{Sample_27_ReadRTF.php => Sample_28_ReadRTF.php} (100%) rename samples/resources/{Sample_27_ReadRTF.rtf => Sample_28_ReadRTF.rtf} (100%) create mode 100644 tests/PhpWord/Tests/Reader/RTFTest.php create mode 100644 tests/PhpWord/Tests/_files/documents/reader.rtf diff --git a/CHANGELOG.md b/CHANGELOG.md index 4584c4a4..0ccba8cc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,7 @@ This is the changelog between releases of PHPWord. Releases are listed in revers ## 0.11.0 - Not yet released -This release marked the change of PHPWord license from LGPL 2.1 to LGPL 3. Three new elements were added: TextBox, ListItemRun, and Field. Relative and absolute positioning for images and textboxes were added. Writer classes were refactored into parts, elements, and styles. ODT and RTF features were enhanced. Ability to add elements to PHPWord object via HTML were implemeted. +This release marked the change of PHPWord license from LGPL 2.1 to LGPL 3. Three new elements were added: TextBox, ListItemRun, and Field. Relative and absolute positioning for images and textboxes were added. Writer classes were refactored into parts, elements, and styles. ODT and RTF features were enhanced. Ability to add elements to PHPWord object via HTML were implemeted. RTF reader were initiated. ### Features @@ -30,6 +30,7 @@ This release marked the change of PHPWord license from LGPL 2.1 to LGPL 3. Three - RTF Writer: Ability to write document properties - @ivanlanin - RTF Writer: Ability to write image - @ivanlanin - Element: New `Field` element - @basjan GH-251 +- RTF Reader: Basic RTF reader - @ivanlanin GH-72 ### Bugfixes diff --git a/docs/intro.rst b/docs/intro.rst index a64fb2ad..3da729e8 100644 --- a/docs/intro.rst +++ b/docs/intro.rst @@ -124,7 +124,7 @@ Readers +---------------------------+----------------------+--------+-------+-------+ | | Custom | ✓ | | | +---------------------------+----------------------+--------+-------+-------+ -| **Element Type** | Text | ✓ | ✓ | | +| **Element Type** | Text | ✓ | ✓ | ✓ | +---------------------------+----------------------+--------+-------+-------+ | | Text Run | ✓ | | | +---------------------------+----------------------+--------+-------+-------+ diff --git a/docs/src/documentation.md b/docs/src/documentation.md index 889842f9..0f4d085b 100644 --- a/docs/src/documentation.md +++ b/docs/src/documentation.md @@ -114,7 +114,7 @@ Below are the supported features for each file formats. |-------------------------|--------------------|------|-----|-----| | **Document Properties** | Standard | ✓ | | | | | Custom | ✓ | | | -| **Element Type** | Text | ✓ | ✓ | | +| **Element Type** | Text | ✓ | ✓ | ✓ | | | Text Run | ✓ | | | | | Title | ✓ | ✓ | | | | Link | ✓ | | | diff --git a/samples/Sample_27_ReadRTF.php b/samples/Sample_28_ReadRTF.php similarity index 100% rename from samples/Sample_27_ReadRTF.php rename to samples/Sample_28_ReadRTF.php diff --git a/samples/resources/Sample_27_ReadRTF.rtf b/samples/resources/Sample_28_ReadRTF.rtf similarity index 100% rename from samples/resources/Sample_27_ReadRTF.rtf rename to samples/resources/Sample_28_ReadRTF.rtf diff --git a/src/PhpWord/Reader/RTF/Document.php b/src/PhpWord/Reader/RTF/Document.php index 84e9c1ed..cb082fdc 100644 --- a/src/PhpWord/Reader/RTF/Document.php +++ b/src/PhpWord/Reader/RTF/Document.php @@ -245,8 +245,8 @@ class Document private function flushControl($isControl = false) { if (preg_match("/^([A-Za-z]+)(-?[0-9]*) ?$/", $this->control, $match) === 1) { - list(, $control) = $match; - $this->parseControl($control); + list(, $control, $parameter) = $match; + $this->parseControl($control, $parameter); } if ($isControl === true) { @@ -271,8 +271,7 @@ class Document // Add text if it's not flagged as skipped if (!isset($this->flags['skipped'])) { - $textrun = $this->textrun->addText($this->text); - $this->flags['element'] = &$textrun; + $this->readText(); } $this->text = ''; @@ -312,30 +311,36 @@ class Document * @param string $control * @param string $parameter */ - private function parseControl($control) + private function parseControl($control, $parameter) { $controls = array( - 'par' => array(self::PARA, 'paragraph', true), - 'b' => array(self::STYL, 'bold', true), - 'i' => array(self::STYL, 'italic', true), - 'u' => array(self::STYL, 'underline', true), - 'fonttbl' => array(self::SKIP, 'fonttbl', null), - 'colortbl' => array(self::SKIP, 'colortbl', null), - 'info' => array(self::SKIP, 'info', null), - 'generator' => array(self::SKIP, 'generator', null), - 'title' => array(self::SKIP, 'title', null), - 'subject' => array(self::SKIP, 'subject', null), - 'category' => array(self::SKIP, 'category', null), - 'keywords' => array(self::SKIP, 'keywords', null), - 'comment' => array(self::SKIP, 'comment', null), - 'shppict' => array(self::SKIP, 'pic', null), - 'fldinst' => array(self::SKIP, 'link', null), + 'par' => array(self::PARA, 'paragraph', true), + 'b' => array(self::STYL, 'font', 'bold', true), + 'i' => array(self::STYL, 'font', 'italic', true), + 'u' => array(self::STYL, 'font', 'underline', true), + 'strike' => array(self::STYL, 'font', 'strikethrough',true), + 'fs' => array(self::STYL, 'font', 'size', $parameter), + 'qc' => array(self::STYL, 'paragraph', 'align', 'center'), + 'sa' => array(self::STYL, 'paragraph', 'spaceAfter', $parameter), + 'fonttbl' => array(self::SKIP, 'fonttbl', null), + 'colortbl' => array(self::SKIP, 'colortbl', null), + 'info' => array(self::SKIP, 'info', null), + 'generator' => array(self::SKIP, 'generator', null), + 'title' => array(self::SKIP, 'title', null), + 'subject' => array(self::SKIP, 'subject', null), + 'category' => array(self::SKIP, 'category', null), + 'keywords' => array(self::SKIP, 'keywords', null), + 'comment' => array(self::SKIP, 'comment', null), + 'shppict' => array(self::SKIP, 'pic', null), + 'fldinst' => array(self::SKIP, 'link', null), ); if (array_key_exists($control, $controls)) { list($function) = $controls[$control]; if (method_exists($this, $function)) { - $this->$function($controls[$control]); + $directives = $controls[$control]; + array_shift($directives); // remove the function variable; we won't need it + $this->$function($directives); } } } @@ -347,7 +352,7 @@ class Document */ private function readParagraph($directives) { - list(, $property, $value) = $directives; + list($property, $value) = $directives; $this->textrun = $this->section->addTextRun(); $this->flags[$property] = $value; } @@ -359,12 +364,8 @@ class Document */ private function readStyle($directives) { - list(, $property, $value) = $directives; - $this->flags[$property] = $value; - if (isset($this->flags['element'])) { - $element = &$this->flags['element']; - $element->getFontStyle()->setStyleValue($property, $value); - } + list($style, $property, $value) = $directives; + $this->flags['styles'][$style][$property] = $value; } /** @@ -374,8 +375,19 @@ class Document */ private function readSkip($directives) { - list(, $property) = $directives; + list($property) = $directives; $this->flags['property'] = $property; $this->flags['skipped'] = true; } + + /** + * Read text + */ + private function readText() + { + $text = $this->textrun->addText($this->text); + if (isset($this->flags['styles']['font'])) { + $text->getFontStyle()->setStyleByArray($this->flags['styles']['font']); + } + } } diff --git a/tests/PhpWord/Tests/Reader/ODTextTest.php b/tests/PhpWord/Tests/Reader/ODTextTest.php index 4120c11e..fc4d2e33 100644 --- a/tests/PhpWord/Tests/Reader/ODTextTest.php +++ b/tests/PhpWord/Tests/Reader/ODTextTest.php @@ -33,7 +33,7 @@ class ODTextTest extends \PHPUnit_Framework_TestCase public function testLoad() { $filename = __DIR__ . '/../_files/documents/reader.odt'; - $object = IOFactory::load($filename, 'ODText'); - $this->assertInstanceOf('PhpOffice\\PhpWord\\PhpWord', $object); + $phpWord = IOFactory::load($filename, 'ODText'); + $this->assertInstanceOf('PhpOffice\\PhpWord\\PhpWord', $phpWord); } } diff --git a/tests/PhpWord/Tests/Reader/RTFTest.php b/tests/PhpWord/Tests/Reader/RTFTest.php new file mode 100644 index 00000000..c495db68 --- /dev/null +++ b/tests/PhpWord/Tests/Reader/RTFTest.php @@ -0,0 +1,51 @@ +assertInstanceOf('PhpOffice\\PhpWord\\PhpWord', $phpWord); + } + + /** + * Test load exception + * + * @expectedException \Exception + * @expectedExceptionMessage Cannot read + */ + public function testLoadException() + { + $filename = __DIR__ . '/../_files/documents/foo.rtf'; + IOFactory::load($filename, 'RTF'); + } +} diff --git a/tests/PhpWord/Tests/Reader/Word2007Test.php b/tests/PhpWord/Tests/Reader/Word2007Test.php index 58890c9a..f2257012 100644 --- a/tests/PhpWord/Tests/Reader/Word2007Test.php +++ b/tests/PhpWord/Tests/Reader/Word2007Test.php @@ -28,40 +28,24 @@ use PhpOffice\PhpWord\Reader\Word2007; */ class Word2007Test extends \PHPUnit_Framework_TestCase { - /** - * Init - */ - public function tearDown() - { - } - /** * Test canRead() method */ public function testCanRead() { $object = new Word2007(); - $fqFilename = join( - DIRECTORY_SEPARATOR, - array(PHPWORD_TESTS_BASE_DIR, 'PhpWord', 'Tests', '_files', 'documents', 'reader.docx') - ); - $this->assertTrue($object->canRead($fqFilename)); + $filename = __DIR__ . '/../_files/documents/reader.docx'; + $this->assertTrue($object->canRead($filename)); } /** * Can read exception - * - * @expectedException \PhpOffice\PhpWord\Exception\Exception */ public function testCanReadFailed() { $object = new Word2007(); - $fqFilename = join( - DIRECTORY_SEPARATOR, - array(PHPWORD_TESTS_BASE_DIR, 'PhpWord', 'Tests', '_files', 'documents', 'foo.docx') - ); - $this->assertFalse($object->canRead($fqFilename)); - $object = IOFactory::load($fqFilename); + $filename = __DIR__ . '/../_files/documents/foo.docx'; + $this->assertFalse($object->canRead($filename)); } /** @@ -69,11 +53,8 @@ class Word2007Test extends \PHPUnit_Framework_TestCase */ public function testLoad() { - $fqFilename = join( - DIRECTORY_SEPARATOR, - array(PHPWORD_TESTS_BASE_DIR, 'PhpWord', 'Tests', '_files', 'documents', 'reader.docx') - ); - $object = IOFactory::load($fqFilename); - $this->assertInstanceOf('PhpOffice\\PhpWord\\PhpWord', $object); + $filename = __DIR__ . '/../_files/documents/reader.docx'; + $phpWord = IOFactory::load($filename); + $this->assertInstanceOf('PhpOffice\\PhpWord\\PhpWord', $phpWord); } } diff --git a/tests/PhpWord/Tests/_files/documents/reader.rtf b/tests/PhpWord/Tests/_files/documents/reader.rtf new file mode 100644 index 00000000..400f43a5 --- /dev/null +++ b/tests/PhpWord/Tests/_files/documents/reader.rtf @@ -0,0 +1,21 @@ +{\rtf1 +\ansi\ansicpg1252 +\deff0 +{\fonttbl{\f0\fnil\fcharset0 Arial;}{\f1\fnil\fcharset0 Times New Roman;}} +{\colortbl;\red255\green0\blue0;\red14\green0\blue0} +{\*\generator PhpWord;} + +{\info{\title }{\subject }{\category }{\keywords }{\comment }{\author }{\operator }{\creatim \yr2014\mo05\dy27\hr23\min36\sec45}{\revtim \yr2014\mo05\dy27\hr23\min36\sec45}{\company }{\manager }} +\deftab720\viewkind1\uc1\pard\nowidctlpar\lang1036\kerning1\fs20 +{Welcome to PhpWord}\par +\pard\nowidctlpar{\cf0\f0 Hello World!}\par +\par +\par +\pard\nowidctlpar{\cf0\f0\fs32\b\i I am styled by a definition.}\par +\pard\nowidctlpar{\cf0\f0 I am styled by a paragraph style definition.}\par +\pard\nowidctlpar\qc\sa100{\cf0\f0\fs32\b\i I am styled by both font and paragraph style.}\par +\pard\nowidctlpar{\cf1\f1\fs40\b\i\ul\strike\super I am inline styled.}\par +\par +{\field {\*\fldinst {HYPERLINK "http://www.google.com"}}{\fldrslt {Google}}}\par +\par +} \ No newline at end of file From 4bb3ffe5bd6cf6752d630393011bb4a381d26520 Mon Sep 17 00:00:00 2001 From: Ivan Lanin Date: Thu, 29 May 2014 18:13:57 +0700 Subject: [PATCH 4/4] Apply #250 fix a minor typo in the text styles example --- docs/elements.rst | 2 +- docs/src/documentation.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/elements.rst b/docs/elements.rst index 7e0c33f6..901832eb 100644 --- a/docs/elements.rst +++ b/docs/elements.rst @@ -88,7 +88,7 @@ Inline style examples: $textrun = $section->addTextRun(); $textrun->addText('I am bold', array('bold' => true)); $textrun->addText('I am italic', array('italic' => true)); - $textrun->addText('I am colored, array('color' => 'AACC00')); + $textrun->addText('I am colored', array('color' => 'AACC00')); Defined style examples: diff --git a/docs/src/documentation.md b/docs/src/documentation.md index 0f4d085b..0259dd8b 100644 --- a/docs/src/documentation.md +++ b/docs/src/documentation.md @@ -495,7 +495,7 @@ $section->addText('I am simple paragraph', $fontStyle, $paragraphStyle); $textrun = $section->addTextRun(); $textrun->addText('I am bold', array('bold' => true)); $textrun->addText('I am italic', array('italic' => true)); -$textrun->addText('I am colored, array('color' => 'AACC00')); +$textrun->addText('I am colored', array('color' => 'AACC00')); ``` Defined style examples: