Skip to content

Commit 7a42802

Browse files
committed
RTF reader: Unit tests and some improvements
1 parent 7c2ad59 commit 7a42802

File tree

10 files changed

+126
-60
lines changed

10 files changed

+126
-60
lines changed

CHANGELOG.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ This is the changelog between releases of PHPWord. Releases are listed in revers
44

55
## 0.11.0 - Not yet released
66

7-
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.
7+
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.
88

99
### Features
1010

@@ -30,6 +30,7 @@ This release marked the change of PHPWord license from LGPL 2.1 to LGPL 3. Three
3030
- RTF Writer: Ability to write document properties - @ivanlanin
3131
- RTF Writer: Ability to write image - @ivanlanin
3232
- Element: New `Field` element - @basjan GH-251
33+
- RTF Reader: Basic RTF reader - @ivanlanin GH-72
3334

3435
### Bugfixes
3536

docs/intro.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ Readers
124124
+---------------------------+----------------------+--------+-------+-------+
125125
| | Custom || | |
126126
+---------------------------+----------------------+--------+-------+-------+
127-
| **Element Type** | Text ||| |
127+
| **Element Type** | Text ||| |
128128
+---------------------------+----------------------+--------+-------+-------+
129129
| | Text Run || | |
130130
+---------------------------+----------------------+--------+-------+-------+

docs/src/documentation.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ Below are the supported features for each file formats.
114114
|-------------------------|--------------------|------|-----|-----|
115115
| **Document Properties** | Standard || | |
116116
| | Custom || | |
117-
| **Element Type** | Text ||| |
117+
| **Element Type** | Text ||| |
118118
| | Text Run || | |
119119
| | Title ||| |
120120
| | Link || | |
File renamed without changes.

src/PhpWord/Reader/RTF/Document.php

Lines changed: 41 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -245,8 +245,8 @@ private function flush($isControl = false)
245245
private function flushControl($isControl = false)
246246
{
247247
if (preg_match("/^([A-Za-z]+)(-?[0-9]*) ?$/", $this->control, $match) === 1) {
248-
list(, $control) = $match;
249-
$this->parseControl($control);
248+
list(, $control, $parameter) = $match;
249+
$this->parseControl($control, $parameter);
250250
}
251251

252252
if ($isControl === true) {
@@ -271,8 +271,7 @@ private function flushText()
271271

272272
// Add text if it's not flagged as skipped
273273
if (!isset($this->flags['skipped'])) {
274-
$textrun = $this->textrun->addText($this->text);
275-
$this->flags['element'] = &$textrun;
274+
$this->readText();
276275
}
277276

278277
$this->text = '';
@@ -312,30 +311,36 @@ private function pushText($char)
312311
* @param string $control
313312
* @param string $parameter
314313
*/
315-
private function parseControl($control)
314+
private function parseControl($control, $parameter)
316315
{
317316
$controls = array(
318-
'par' => array(self::PARA, 'paragraph', true),
319-
'b' => array(self::STYL, 'bold', true),
320-
'i' => array(self::STYL, 'italic', true),
321-
'u' => array(self::STYL, 'underline', true),
322-
'fonttbl' => array(self::SKIP, 'fonttbl', null),
323-
'colortbl' => array(self::SKIP, 'colortbl', null),
324-
'info' => array(self::SKIP, 'info', null),
325-
'generator' => array(self::SKIP, 'generator', null),
326-
'title' => array(self::SKIP, 'title', null),
327-
'subject' => array(self::SKIP, 'subject', null),
328-
'category' => array(self::SKIP, 'category', null),
329-
'keywords' => array(self::SKIP, 'keywords', null),
330-
'comment' => array(self::SKIP, 'comment', null),
331-
'shppict' => array(self::SKIP, 'pic', null),
332-
'fldinst' => array(self::SKIP, 'link', null),
317+
'par' => array(self::PARA, 'paragraph', true),
318+
'b' => array(self::STYL, 'font', 'bold', true),
319+
'i' => array(self::STYL, 'font', 'italic', true),
320+
'u' => array(self::STYL, 'font', 'underline', true),
321+
'strike' => array(self::STYL, 'font', 'strikethrough',true),
322+
'fs' => array(self::STYL, 'font', 'size', $parameter),
323+
'qc' => array(self::STYL, 'paragraph', 'align', 'center'),
324+
'sa' => array(self::STYL, 'paragraph', 'spaceAfter', $parameter),
325+
'fonttbl' => array(self::SKIP, 'fonttbl', null),
326+
'colortbl' => array(self::SKIP, 'colortbl', null),
327+
'info' => array(self::SKIP, 'info', null),
328+
'generator' => array(self::SKIP, 'generator', null),
329+
'title' => array(self::SKIP, 'title', null),
330+
'subject' => array(self::SKIP, 'subject', null),
331+
'category' => array(self::SKIP, 'category', null),
332+
'keywords' => array(self::SKIP, 'keywords', null),
333+
'comment' => array(self::SKIP, 'comment', null),
334+
'shppict' => array(self::SKIP, 'pic', null),
335+
'fldinst' => array(self::SKIP, 'link', null),
333336
);
334337

335338
if (array_key_exists($control, $controls)) {
336339
list($function) = $controls[$control];
337340
if (method_exists($this, $function)) {
338-
$this->$function($controls[$control]);
341+
$directives = $controls[$control];
342+
array_shift($directives); // remove the function variable; we won't need it
343+
$this->$function($directives);
339344
}
340345
}
341346
}
@@ -347,7 +352,7 @@ private function parseControl($control)
347352
*/
348353
private function readParagraph($directives)
349354
{
350-
list(, $property, $value) = $directives;
355+
list($property, $value) = $directives;
351356
$this->textrun = $this->section->addTextRun();
352357
$this->flags[$property] = $value;
353358
}
@@ -359,12 +364,8 @@ private function readParagraph($directives)
359364
*/
360365
private function readStyle($directives)
361366
{
362-
list(, $property, $value) = $directives;
363-
$this->flags[$property] = $value;
364-
if (isset($this->flags['element'])) {
365-
$element = &$this->flags['element'];
366-
$element->getFontStyle()->setStyleValue($property, $value);
367-
}
367+
list($style, $property, $value) = $directives;
368+
$this->flags['styles'][$style][$property] = $value;
368369
}
369370

370371
/**
@@ -374,8 +375,19 @@ private function readStyle($directives)
374375
*/
375376
private function readSkip($directives)
376377
{
377-
list(, $property) = $directives;
378+
list($property) = $directives;
378379
$this->flags['property'] = $property;
379380
$this->flags['skipped'] = true;
380381
}
382+
383+
/**
384+
* Read text
385+
*/
386+
private function readText()
387+
{
388+
$text = $this->textrun->addText($this->text);
389+
if (isset($this->flags['styles']['font'])) {
390+
$text->getFontStyle()->setStyleByArray($this->flags['styles']['font']);
391+
}
392+
}
381393
}

tests/PhpWord/Tests/Reader/ODTextTest.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ class ODTextTest extends \PHPUnit_Framework_TestCase
3333
public function testLoad()
3434
{
3535
$filename = __DIR__ . '/../_files/documents/reader.odt';
36-
$object = IOFactory::load($filename, 'ODText');
37-
$this->assertInstanceOf('PhpOffice\\PhpWord\\PhpWord', $object);
36+
$phpWord = IOFactory::load($filename, 'ODText');
37+
$this->assertInstanceOf('PhpOffice\\PhpWord\\PhpWord', $phpWord);
3838
}
3939
}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
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+
18+
namespace PhpOffice\PhpWord\Tests\Reader;
19+
20+
use PhpOffice\PhpWord\IOFactory;
21+
22+
/**
23+
* Test class for PhpOffice\PhpWord\Reader\RTF
24+
*
25+
* @coversDefaultClass \PhpOffice\PhpWord\Reader\RTF
26+
* @runTestsInSeparateProcesses
27+
*/
28+
class RTFTest extends \PHPUnit_Framework_TestCase
29+
{
30+
/**
31+
* Test load
32+
*/
33+
public function testLoad()
34+
{
35+
$filename = __DIR__ . '/../_files/documents/reader.rtf';
36+
$phpWord = IOFactory::load($filename, 'RTF');
37+
$this->assertInstanceOf('PhpOffice\\PhpWord\\PhpWord', $phpWord);
38+
}
39+
40+
/**
41+
* Test load exception
42+
*
43+
* @expectedException \Exception
44+
* @expectedExceptionMessage Cannot read
45+
*/
46+
public function testLoadException()
47+
{
48+
$filename = __DIR__ . '/../_files/documents/foo.rtf';
49+
IOFactory::load($filename, 'RTF');
50+
}
51+
}

tests/PhpWord/Tests/Reader/Word2007Test.php

Lines changed: 7 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -28,52 +28,33 @@
2828
*/
2929
class Word2007Test extends \PHPUnit_Framework_TestCase
3030
{
31-
/**
32-
* Init
33-
*/
34-
public function tearDown()
35-
{
36-
}
37-
3831
/**
3932
* Test canRead() method
4033
*/
4134
public function testCanRead()
4235
{
4336
$object = new Word2007();
44-
$fqFilename = join(
45-
DIRECTORY_SEPARATOR,
46-
array(PHPWORD_TESTS_BASE_DIR, 'PhpWord', 'Tests', '_files', 'documents', 'reader.docx')
47-
);
48-
$this->assertTrue($object->canRead($fqFilename));
37+
$filename = __DIR__ . '/../_files/documents/reader.docx';
38+
$this->assertTrue($object->canRead($filename));
4939
}
5040

5141
/**
5242
* Can read exception
53-
*
54-
* @expectedException \PhpOffice\PhpWord\Exception\Exception
5543
*/
5644
public function testCanReadFailed()
5745
{
5846
$object = new Word2007();
59-
$fqFilename = join(
60-
DIRECTORY_SEPARATOR,
61-
array(PHPWORD_TESTS_BASE_DIR, 'PhpWord', 'Tests', '_files', 'documents', 'foo.docx')
62-
);
63-
$this->assertFalse($object->canRead($fqFilename));
64-
$object = IOFactory::load($fqFilename);
47+
$filename = __DIR__ . '/../_files/documents/foo.docx';
48+
$this->assertFalse($object->canRead($filename));
6549
}
6650

6751
/**
6852
* Load
6953
*/
7054
public function testLoad()
7155
{
72-
$fqFilename = join(
73-
DIRECTORY_SEPARATOR,
74-
array(PHPWORD_TESTS_BASE_DIR, 'PhpWord', 'Tests', '_files', 'documents', 'reader.docx')
75-
);
76-
$object = IOFactory::load($fqFilename);
77-
$this->assertInstanceOf('PhpOffice\\PhpWord\\PhpWord', $object);
56+
$filename = __DIR__ . '/../_files/documents/reader.docx';
57+
$phpWord = IOFactory::load($filename);
58+
$this->assertInstanceOf('PhpOffice\\PhpWord\\PhpWord', $phpWord);
7859
}
7960
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
{\rtf1
2+
\ansi\ansicpg1252
3+
\deff0
4+
{\fonttbl{\f0\fnil\fcharset0 Arial;}{\f1\fnil\fcharset0 Times New Roman;}}
5+
{\colortbl;\red255\green0\blue0;\red14\green0\blue0}
6+
{\*\generator PhpWord;}
7+
8+
{\info{\title }{\subject }{\category }{\keywords }{\comment }{\author }{\operator }{\creatim \yr2014\mo05\dy27\hr23\min36\sec45}{\revtim \yr2014\mo05\dy27\hr23\min36\sec45}{\company }{\manager }}
9+
\deftab720\viewkind1\uc1\pard\nowidctlpar\lang1036\kerning1\fs20
10+
{Welcome to PhpWord}\par
11+
\pard\nowidctlpar{\cf0\f0 Hello World!}\par
12+
\par
13+
\par
14+
\pard\nowidctlpar{\cf0\f0\fs32\b\i I am styled by a <font style> definition.}\par
15+
\pard\nowidctlpar{\cf0\f0 I am styled by a paragraph style definition.}\par
16+
\pard\nowidctlpar\qc\sa100{\cf0\f0\fs32\b\i I am styled by both font and paragraph style.}\par
17+
\pard\nowidctlpar{\cf1\f1\fs40\b\i\ul\strike\super I am inline styled.}\par
18+
\par
19+
{\field {\*\fldinst {HYPERLINK "http://www.google.com"}}{\fldrslt {Google}}}\par
20+
\par
21+
}

0 commit comments

Comments
 (0)