Skip to content

Ability to define paragraph pagination #92

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Mar 8, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
132 changes: 132 additions & 0 deletions Classes/PHPWord/Style/Paragraph.php
Original file line number Diff line number Diff line change
Expand Up @@ -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
*/
Expand All @@ -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;
}

/**
Expand Down Expand Up @@ -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;
}

}
55 changes: 50 additions & 5 deletions Classes/PHPWord/Writer/Word2007/Base.php
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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);
Expand All @@ -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);
}
Expand Down
31 changes: 30 additions & 1 deletion Tests/PHPWord/Writer/Word2007/BaseTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -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'));
}
}

}

1 change: 1 addition & 0 deletions changelog.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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 :
Expand Down
76 changes: 76 additions & 0 deletions samples/Sample_08_ParagraphPagination.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
<?php

error_reporting(E_ALL);

if(php_sapi_name() == 'cli' && empty($_SERVER['REMOTE_ADDR'])) {
define('EOL', PHP_EOL);
}
else {
define('EOL', '<br />');
}

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;