diff --git a/Classes/PHPWord/Style/Paragraph.php b/Classes/PHPWord/Style/Paragraph.php index 632ef8b225..70732f86d6 100755 --- a/Classes/PHPWord/Style/Paragraph.php +++ b/Classes/PHPWord/Style/Paragraph.php @@ -94,6 +94,34 @@ class PHPWord_Style_Paragraph */ private $_next; + /** + * Allow first/last line to display on a separate page + * + * @var bool + */ + private $_widowControl; + + /** + * Keep paragraph with next paragraph + * + * @var bool + */ + private $_keepNext; + + /** + * Keep all lines on one page + * + * @var bool + */ + private $_keepLines; + + /** + * Start paragraph on next page + * + * @var bool + */ + private $_pageBreakBefore; + /** * New Paragraph Style */ @@ -108,6 +136,10 @@ public function __construct() $this->_hanging = null; $this->_basedOn = 'Normal'; $this->_next = null; + $this->_widowControl = true; + $this->_keepNext = false; + $this->_keepLines = false; + $this->_pageBreakBefore = false; } /** @@ -323,4 +355,104 @@ public function setNext($pValue = null) return $this; } + /** + * Get allow first/last line to display on a separate page setting + * + * @return bool + */ + public function getWidowControl() + { + return $this->_widowControl; + } + + /** + * Set keep paragraph with next paragraph setting + * + * @param bool $pValue + * @return PHPWord_Style_Paragraph + */ + public function setWidowControl($pValue = true) + { + if (!is_bool($pValue)) { + $pValue = false; + } + $this->_widowControl = $pValue; + return $this; + } + + /** + * Get keep paragraph with next paragraph setting + * + * @return bool + */ + public function getKeepNext() + { + return $this->_keepNext; + } + + /** + * Set keep paragraph with next paragraph setting + * + * @param bool $pValue + * @return PHPWord_Style_Paragraph + */ + public function setKeepNext($pValue = true) + { + if (!is_bool($pValue)) { + $pValue = false; + } + $this->_keepNext = $pValue; + return $this; + } + + /** + * Get keep all lines on one page setting + * + * @return bool + */ + public function getKeepLines() + { + return $this->_keepLines; + } + + /** + * Set keep all lines on one page setting + * + * @param bool $pValue + * @return PHPWord_Style_Paragraph + */ + public function setKeepLines($pValue = true) + { + if (!is_bool($pValue)) { + $pValue = false; + } + $this->_keepLines = $pValue; + return $this; + } + + /** + * Get start paragraph on next page setting + * + * @return bool + */ + public function getPageBreakBefore() + { + return $this->_pageBreakBefore; + } + + /** + * Set start paragraph on next page setting + * + * @param bool $pValue + * @return PHPWord_Style_Paragraph + */ + public function setPageBreakBefore($pValue = true) + { + if (!is_bool($pValue)) { + $pValue = false; + } + $this->_pageBreakBefore = $pValue; + return $this; + } + } \ No newline at end of file diff --git a/Classes/PHPWord/Writer/Word2007/Base.php b/Classes/PHPWord/Writer/Word2007/Base.php index 47c31a81a0..2b99ef452b 100755 --- a/Classes/PHPWord/Writer/Word2007/Base.php +++ b/Classes/PHPWord/Writer/Word2007/Base.php @@ -117,27 +117,47 @@ protected function _writeTextRun(PHPWord_Shared_XMLWriter $objWriter = null, PHP $objWriter->endElement(); } - protected function _writeParagraphStyle(PHPWord_Shared_XMLWriter $objWriter = null, PHPWord_Style_Paragraph $style, $withoutPPR = false) + /** + * Write paragraph style + * + * @param PHPWord_Shared_XMLWriter $objWriter + * @param PHPWord_Style_Paragraph $style + * @param bool $withoutPPR + * @return void + */ + protected function _writeParagraphStyle( + PHPWord_Shared_XMLWriter $objWriter = null, + PHPWord_Style_Paragraph $style, + $withoutPPR = false) { $align = $style->getAlign(); + $spacing = $style->getSpacing(); $spaceBefore = $style->getSpaceBefore(); $spaceAfter = $style->getSpaceAfter(); - $spacing = $style->getSpacing(); $indent = $style->getIndent(); $hanging = $style->getHanging(); $tabs = $style->getTabs(); - - if (!is_null($align) || !is_null($spacing) || !is_null($spaceBefore) || !is_null($spaceAfter) || !is_null($indent) || !is_null($tabs)) { + $widowControl = $style->getWidowControl(); + $keepNext = $style->getKeepNext(); + $keepLines = $style->getKeepLines(); + $pageBreakBefore = $style->getPageBreakBefore(); + + if (!is_null($align) || !is_null($spacing) || !is_null($spaceBefore) || + !is_null($spaceAfter) || !is_null($indent) || !is_null($hanging) || + !is_null($tabs) || !is_null($widowControl) || !is_null($keepNext) || + !is_null($keepLines) || !is_null($pageBreakBefore)) { if (!$withoutPPR) { $objWriter->startElement('w:pPr'); } + // Alignment if (!is_null($align)) { $objWriter->startElement('w:jc'); $objWriter->writeAttribute('w:val', $align); $objWriter->endElement(); } + // Indentation if (!is_null($indent) || !is_null($hanging)) { $objWriter->startElement('w:ind'); $objWriter->writeAttribute('w:firstLine', 0); @@ -150,7 +170,9 @@ protected function _writeParagraphStyle(PHPWord_Shared_XMLWriter $objWriter = nu $objWriter->endElement(); } - if (!is_null($spaceBefore) || !is_null($spaceAfter) || !is_null($spacing)) { + // Spacing + if (!is_null($spaceBefore) || !is_null($spaceAfter) || + !is_null($spacing)) { $objWriter->startElement('w:spacing'); if (!is_null($spaceBefore)) { $objWriter->writeAttribute('w:before', $spaceBefore); @@ -165,6 +187,29 @@ protected function _writeParagraphStyle(PHPWord_Shared_XMLWriter $objWriter = nu $objWriter->endElement(); } + // Pagination + if (!$widowControl) { + $objWriter->startElement('w:widowControl'); + $objWriter->writeAttribute('w:val', '0'); + $objWriter->endElement(); + } + if ($keepNext) { + $objWriter->startElement('w:keepNext'); + $objWriter->writeAttribute('w:val', '1'); + $objWriter->endElement(); + } + if ($keepLines) { + $objWriter->startElement('w:keepLines'); + $objWriter->writeAttribute('w:val', '1'); + $objWriter->endElement(); + } + if ($pageBreakBefore) { + $objWriter->startElement('w:pageBreakBefore'); + $objWriter->writeAttribute('w:val', '1'); + $objWriter->endElement(); + } + + // Tabs if (!is_null($tabs)) { $tabs->toXml($objWriter); } diff --git a/Tests/PHPWord/Writer/Word2007/BaseTest.php b/Tests/PHPWord/Writer/Word2007/BaseTest.php index 8788af8b3e..0179a6a464 100644 --- a/Tests/PHPWord/Writer/Word2007/BaseTest.php +++ b/Tests/PHPWord/Writer/Word2007/BaseTest.php @@ -77,6 +77,35 @@ public function testWriteCellStyle_CellGridSpan() $element = $doc->getElement('/w:document/w:body/w:tbl/w:tr/w:tc/w:tcPr/w:gridSpan'); $this->assertEquals(5, $element->getAttribute('w:val')); + } + + /** + * Test write paragraph pagination + */ + public function testWriteParagraphStyle_Pagination() + { + // Create the doc + $PHPWord = new PHPWord(); + $section = $PHPWord->createSection(); + $attributes = array( + 'widowControl' => 0, + 'keepNext' => 1, + 'keepLines' => 1, + 'pageBreakBefore' => 1, + ); + foreach ($attributes as $attribute => $value) { + $section->addText('Test', null, array($attribute => $value)); + } + $doc = TestHelperDOCX::getDocument($PHPWord); + + // Test the attributes + $i = 0; + foreach ($attributes as $attribute => $value) { + $i++; + $path = "/w:document/w:body/w:p[{$i}]/w:pPr/w:{$attribute}"; + $element = $doc->getElement($path); + $this->assertEquals($value, $element->getAttribute('w:val')); + } } + } - \ No newline at end of file diff --git a/changelog.txt b/changelog.txt index c5c66fc373..4ad31be95d 100755 --- a/changelog.txt +++ b/changelog.txt @@ -44,6 +44,7 @@ Changes in branch for release 0.7.1 : - Feature: (ivanlanin) GH-87 - Paragraph: Ability to define parent style (basedOn) and style for following paragraph (next) - Feature: (jeroenmoors) GH-44 GH-88 - Clone table rows on the fly when using a template document - Feature: (deds) GH-16 - Initial addition of basic footnote support +- Feature: (ivanlanin) GH-91 - Paragraph: Ability to define paragraph pagination: widow control, keep next, keep lines, and page break before - QA: (Progi1984) - UnitTests Changes in branch for release 0.7.0 : diff --git a/samples/Sample_08_ParagraphPagination.php b/samples/Sample_08_ParagraphPagination.php new file mode 100644 index 0000000000..97b43032f1 --- /dev/null +++ b/samples/Sample_08_ParagraphPagination.php @@ -0,0 +1,76 @@ +'); +} + +require_once '../Classes/PHPWord.php'; + +// New Word document +echo date('H:i:s') , " Create new PHPWord object" , EOL; +$PHPWord = new PHPWord(); +$PHPWord->setDefaultParagraphStyle(array( + 'align' => 'both', + 'spaceAfter' => PHPWord_Shared_Font::pointSizeToTwips(12), + 'spacing' => 120, +)); + +// Sample +$section = $PHPWord->createSection(); + +$section->addText('Below are the samples on how to control your paragraph ' . + 'pagination. See "Line and Page Break" tab on paragraph properties ' . + 'window to see the attribute set by these controls.', + array('bold' => true), null); + +$section->addText('Paragraph with widowControl = false (default: true). ' . + 'A "widow" is the last line of a paragraph printed by itself at the top ' . + 'of a page. An "orphan" is the first line of a paragraph printed by ' . + 'itself at the bottom of a page. Set this option to "false" if you want ' . + 'to disable this automatic control.', + null, array('widowControl' => false)); + +$section->addText('Paragraph with keepNext = true (default: false). ' . + '"Keep with next" is used to prevent Word from inserting automatic page ' . + 'breaks between paragraphs. Set this option to "true" if you do not want ' . + 'your paragraph to be separated with the next paragraph.', + null, array('keepNext' => true)); + +$section->addText('Paragraph with keepLines = true (default: false). ' . + '"Keep lines together" will prevent Word from inserting an automatic page ' . + 'break within a paragraph. Set this option to "true" if you do not want ' . + 'all lines of your paragraph to be in the same page.', + null, array('keepLines' => true)); + +$section->addText('Keep scrolling. More below.'); + +$section->addText('Paragraph with pageBreakBefore = true (default: false). ' . + 'Different with all other control above, "page break before" separates ' . + 'your paragraph into the next page. This option is most useful for ' . + 'heading styles.', + null, array('pageBreakBefore' => true)); + +// Save File +echo date('H:i:s') , " Write to Word2007 format" , EOL; +$objWriter = PHPWord_IOFactory::createWriter($PHPWord, 'Word2007'); +$objWriter->save(str_replace('.php', '.docx', __FILE__)); + +// echo date('H:i:s') , " Write to OpenDocumentText format" , EOL; +// $objWriter = PHPWord_IOFactory::createWriter($PHPWord, 'ODText'); +// $objWriter->save(str_replace('.php', '.odt', __FILE__)); + +// echo date('H:i:s') , " Write to RTF format" , EOL; +// $objWriter = PHPWord_IOFactory::createWriter($PHPWord, 'RTF'); +// $objWriter->save(str_replace('.php', '.rtf', __FILE__)); + + +// Echo memory peak usage +echo date('H:i:s') , " Peak memory usage: " , (memory_get_peak_usage(true) / 1024 / 1024) , " MB" , EOL; + +// Echo done +echo date('H:i:s') , " Done writing file" , EOL;