RTF reader: Unit tests and some improvements

This commit is contained in:
Ivan Lanin 2014-05-29 17:37:26 +07:00
parent 7c2ad59530
commit 7a42802b48
10 changed files with 126 additions and 60 deletions

View File

@ -4,7 +4,7 @@ This is the changelog between releases of PHPWord. Releases are listed in revers
## 0.11.0 - Not yet released ## 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 ### 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 document properties - @ivanlanin
- RTF Writer: Ability to write image - @ivanlanin - RTF Writer: Ability to write image - @ivanlanin
- Element: New `Field` element - @basjan GH-251 - Element: New `Field` element - @basjan GH-251
- RTF Reader: Basic RTF reader - @ivanlanin GH-72
### Bugfixes ### Bugfixes

View File

@ -124,7 +124,7 @@ Readers
+---------------------------+----------------------+--------+-------+-------+ +---------------------------+----------------------+--------+-------+-------+
| | Custom | ✓ | | | | | Custom | ✓ | | |
+---------------------------+----------------------+--------+-------+-------+ +---------------------------+----------------------+--------+-------+-------+
| **Element Type** | Text | ✓ | ✓ | | | **Element Type** | Text | ✓ | ✓ | |
+---------------------------+----------------------+--------+-------+-------+ +---------------------------+----------------------+--------+-------+-------+
| | Text Run | ✓ | | | | | Text Run | ✓ | | |
+---------------------------+----------------------+--------+-------+-------+ +---------------------------+----------------------+--------+-------+-------+

View File

@ -114,7 +114,7 @@ Below are the supported features for each file formats.
|-------------------------|--------------------|------|-----|-----| |-------------------------|--------------------|------|-----|-----|
| **Document Properties** | Standard | ✓ | | | | **Document Properties** | Standard | ✓ | | |
| | Custom | ✓ | | | | | Custom | ✓ | | |
| **Element Type** | Text | ✓ | ✓ | | | **Element Type** | Text | ✓ | ✓ | |
| | Text Run | ✓ | | | | | Text Run | ✓ | | |
| | Title | ✓ | ✓ | | | | Title | ✓ | ✓ | |
| | Link | ✓ | | | | | Link | ✓ | | |

View File

@ -245,8 +245,8 @@ class Document
private function flushControl($isControl = false) private function flushControl($isControl = false)
{ {
if (preg_match("/^([A-Za-z]+)(-?[0-9]*) ?$/", $this->control, $match) === 1) { if (preg_match("/^([A-Za-z]+)(-?[0-9]*) ?$/", $this->control, $match) === 1) {
list(, $control) = $match; list(, $control, $parameter) = $match;
$this->parseControl($control); $this->parseControl($control, $parameter);
} }
if ($isControl === true) { if ($isControl === true) {
@ -271,8 +271,7 @@ class Document
// Add text if it's not flagged as skipped // Add text if it's not flagged as skipped
if (!isset($this->flags['skipped'])) { if (!isset($this->flags['skipped'])) {
$textrun = $this->textrun->addText($this->text); $this->readText();
$this->flags['element'] = &$textrun;
} }
$this->text = ''; $this->text = '';
@ -312,13 +311,17 @@ class Document
* @param string $control * @param string $control
* @param string $parameter * @param string $parameter
*/ */
private function parseControl($control) private function parseControl($control, $parameter)
{ {
$controls = array( $controls = array(
'par' => array(self::PARA, 'paragraph', true), 'par' => array(self::PARA, 'paragraph', true),
'b' => array(self::STYL, 'bold', true), 'b' => array(self::STYL, 'font', 'bold', true),
'i' => array(self::STYL, 'italic', true), 'i' => array(self::STYL, 'font', 'italic', true),
'u' => array(self::STYL, 'underline', 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), 'fonttbl' => array(self::SKIP, 'fonttbl', null),
'colortbl' => array(self::SKIP, 'colortbl', null), 'colortbl' => array(self::SKIP, 'colortbl', null),
'info' => array(self::SKIP, 'info', null), 'info' => array(self::SKIP, 'info', null),
@ -335,7 +338,9 @@ class Document
if (array_key_exists($control, $controls)) { if (array_key_exists($control, $controls)) {
list($function) = $controls[$control]; list($function) = $controls[$control];
if (method_exists($this, $function)) { 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) private function readParagraph($directives)
{ {
list(, $property, $value) = $directives; list($property, $value) = $directives;
$this->textrun = $this->section->addTextRun(); $this->textrun = $this->section->addTextRun();
$this->flags[$property] = $value; $this->flags[$property] = $value;
} }
@ -359,12 +364,8 @@ class Document
*/ */
private function readStyle($directives) private function readStyle($directives)
{ {
list(, $property, $value) = $directives; list($style, $property, $value) = $directives;
$this->flags[$property] = $value; $this->flags['styles'][$style][$property] = $value;
if (isset($this->flags['element'])) {
$element = &$this->flags['element'];
$element->getFontStyle()->setStyleValue($property, $value);
}
} }
/** /**
@ -374,8 +375,19 @@ class Document
*/ */
private function readSkip($directives) private function readSkip($directives)
{ {
list(, $property) = $directives; list($property) = $directives;
$this->flags['property'] = $property; $this->flags['property'] = $property;
$this->flags['skipped'] = true; $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']);
}
}
} }

View File

@ -33,7 +33,7 @@ class ODTextTest extends \PHPUnit_Framework_TestCase
public function testLoad() public function testLoad()
{ {
$filename = __DIR__ . '/../_files/documents/reader.odt'; $filename = __DIR__ . '/../_files/documents/reader.odt';
$object = IOFactory::load($filename, 'ODText'); $phpWord = IOFactory::load($filename, 'ODText');
$this->assertInstanceOf('PhpOffice\\PhpWord\\PhpWord', $object); $this->assertInstanceOf('PhpOffice\\PhpWord\\PhpWord', $phpWord);
} }
} }

View File

@ -0,0 +1,51 @@
<?php
/**
* This file is part of PHPWord - A pure PHP library for reading and writing
* word processing documents.
*
* PHPWord is free software distributed under the terms of the GNU Lesser
* General Public License version 3 as published by the Free Software Foundation.
*
* For the full copyright and license information, please read the LICENSE
* file that was distributed with this source code. For the full list of
* contributors, visit https://github.com/PHPOffice/PHPWord/contributors.
*
* @link https://github.com/PHPOffice/PHPWord
* @copyright 2010-2014 PHPWord contributors
* @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3
*/
namespace PhpOffice\PhpWord\Tests\Reader;
use PhpOffice\PhpWord\IOFactory;
/**
* Test class for PhpOffice\PhpWord\Reader\RTF
*
* @coversDefaultClass \PhpOffice\PhpWord\Reader\RTF
* @runTestsInSeparateProcesses
*/
class RTFTest extends \PHPUnit_Framework_TestCase
{
/**
* Test load
*/
public function testLoad()
{
$filename = __DIR__ . '/../_files/documents/reader.rtf';
$phpWord = IOFactory::load($filename, 'RTF');
$this->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');
}
}

View File

@ -28,40 +28,24 @@ use PhpOffice\PhpWord\Reader\Word2007;
*/ */
class Word2007Test extends \PHPUnit_Framework_TestCase class Word2007Test extends \PHPUnit_Framework_TestCase
{ {
/**
* Init
*/
public function tearDown()
{
}
/** /**
* Test canRead() method * Test canRead() method
*/ */
public function testCanRead() public function testCanRead()
{ {
$object = new Word2007(); $object = new Word2007();
$fqFilename = join( $filename = __DIR__ . '/../_files/documents/reader.docx';
DIRECTORY_SEPARATOR, $this->assertTrue($object->canRead($filename));
array(PHPWORD_TESTS_BASE_DIR, 'PhpWord', 'Tests', '_files', 'documents', 'reader.docx')
);
$this->assertTrue($object->canRead($fqFilename));
} }
/** /**
* Can read exception * Can read exception
*
* @expectedException \PhpOffice\PhpWord\Exception\Exception
*/ */
public function testCanReadFailed() public function testCanReadFailed()
{ {
$object = new Word2007(); $object = new Word2007();
$fqFilename = join( $filename = __DIR__ . '/../_files/documents/foo.docx';
DIRECTORY_SEPARATOR, $this->assertFalse($object->canRead($filename));
array(PHPWORD_TESTS_BASE_DIR, 'PhpWord', 'Tests', '_files', 'documents', 'foo.docx')
);
$this->assertFalse($object->canRead($fqFilename));
$object = IOFactory::load($fqFilename);
} }
/** /**
@ -69,11 +53,8 @@ class Word2007Test extends \PHPUnit_Framework_TestCase
*/ */
public function testLoad() public function testLoad()
{ {
$fqFilename = join( $filename = __DIR__ . '/../_files/documents/reader.docx';
DIRECTORY_SEPARATOR, $phpWord = IOFactory::load($filename);
array(PHPWORD_TESTS_BASE_DIR, 'PhpWord', 'Tests', '_files', 'documents', 'reader.docx') $this->assertInstanceOf('PhpOffice\\PhpWord\\PhpWord', $phpWord);
);
$object = IOFactory::load($fqFilename);
$this->assertInstanceOf('PhpOffice\\PhpWord\\PhpWord', $object);
} }
} }

View File

@ -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 <font style> 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
}