state = new ODTState();
// Initialize HTML state
$this->htmlStack = new cssdocument();
// Create default styles/styles storage.
$this->styleset = new ODTDefaultStyles();
$this->styleset->import();
// Set standard page format: A4, portrait, 2cm margins
$this->page = new pageFormat();
$this->setStartPageFormat ('A4', 'portrait', 2, 2, 2, 2);
// Create units object and set default values
$this->units = new ODTUnits();
$this->units->setPixelPerEm(16);
$this->units->setTwipsPerPixelX(16);
$this->units->setTwipsPerPixelY(20);
// Setup meta data store/handler
$this->meta = new ODTMeta();
// Setup manifest data
$this->manifest = new ODTManifest();
// Prepare the zipper
// (This instance is only for our to-be-created ODT-ZIP-Archive
// - NOT to be used for extracting any ODT-Templates!)
if (class_exists('\splitbrain\PHPArchive\Zip'))
{
$this->ZIP = new \splitbrain\PHPArchive\Zip();
$this->ZIP->create();
}
$this->params = new ODTInternalParams();
}
/**
* Initialize the document.
*/
public function initialize () {
$this->state->setDocument($this);
$this->params->document = $this;
$this->params->htmlStack = $this->htmlStack;
$this->params->units = $this->units;
$this->params->content = &$this->content;
$this->params->ZIP = $this->ZIP;
$this->params->manifest = $this->manifest;
$this->params->styleset = $this->styleset;
if (!isset($this->ZIP)) {
return false;
}
return true;
}
/**
* Set CSS usage.
*
* @param string $usage
*/
public function setCSSUsage ($usage) {
switch (strtolower($usage)) {
case 'basic':
case 'full':
$this->CSSUsage = $usage;
break;
default:
$this->CSSUsage = 'off';
break;
}
}
protected function setupImport() {
if (!isset($this->importnew)) {
// No CSS imported yet. Create object.
$this->importnew = new cssimportnew();
if (!isset($this->importnew)) {
return;
}
}
$this->params->import = $this->importnew;
}
/**
* Set commom CSS media selector.
*
* @param string $mediaSel
*/
public function setMediaSelector ($mediaSel) {
if (!isset($this->importnew)) {
$this->setupImport();
}
$this->importnew->setMedia ($mediaSel);
}
/**
* Callback function which adjusts all CSS length values to point.
*
* @param $property The name of the current CSS property, e.g. 'border-left'
* @param $value The current value from the original CSS code
* @param $type There are 3 possible values:
* - LengthValueXAxis: the property represents a value on the X axis
* - LengthValueYAxis: the property represents a value on the Y axis
* - CSSValueType::StrokeOrBorderWidth: the property represents a stroke
* or border width
* @return string The new, adjusted value for the property
*/
public function adjustLengthCallback ($property, $value, $type, $rule) {
// Get the digits and unit
$digits = ODTUnits::getDigits($value);
$unit = ODTUnits::stripDigits($value);
if ( $unit == 'px' ) {
// Replace px with pt (px does not seem to be supported by ODT)
switch ($type) {
case CSSValueType::LengthValueXAxis:
$adjusted = $this->toPoints($value, 'x');
break;
case CSSValueType::StrokeOrBorderWidth:
switch ($property) {
case 'border':
case 'border-left':
case 'border-right':
case 'border-top':
case 'border-bottom':
// border in ODT spans does not support 'px' units, so we convert it.
$adjusted = $this->toPoints($value, 'y');
break;
default:
$adjusted = $value;
break;
}
break;
case CSSValueType::LengthValueYAxis:
default:
switch ($property) {
case 'line-height':
$adjusted = $this->toPoints($value, 'y');
break;
default:
$adjusted = $this->toPoints($value, 'y');
break;
}
break;
}
return $adjusted;
} else {
if ($property == 'line-height' && $value != 'normal') {
if ($unit == '%' || empty($unit)) {
// Relative values must be handled later
return $value;
}
$adjusted = $this->toPoints($value, 'y');
return $adjusted;
}
return $value;
}
return $value;
}
public function replaceURLPrefixes ($callback) {
if (isset($this->importnew)) {
$this->importnew->replaceURLPrefixes ($callback);
}
}
public function enableLinks () {
$this->linksEnabled = true;
}
public function disableLinks () {
$this->linksEnabled = false;
}
// Functions generating content for now will have to be passed
// $renderer->doc. Later this will be removed and an internal doc
// variable will be maintained. This will break backwards compatibility
// with plugins writing to $renderer->doc directly (instead of calling cdata).
/**
* Render plain text data
*
* @param string $text
*/
function addPlainText($text) {
// Check if there is some content in the text.
// Only insert bookmark/pagebreak/format change if text is not empty.
// Otherwise a empty paragraph/line would be created!
if ( !empty($text) && !ctype_space($text) ) {
// Insert page bookmark if requested and not done yet.
$this->insertPendingPageBookmark();
// Insert pagebreak or page format change if still pending.
// Attention: NOT if $text is empty. This would lead to empty lines before headings
// right after a pagebreak!
$in_paragraph = $this->state->getInParagraph();
if ( ($this->pagebreakIsPending() || $this->pageFormatChangeIsPending()) ||
!$in_paragraph ) {
$this->paragraphOpen();
}
}
$this->content .= $this->replaceXMLEntities($text);
if ($this->text_empty && !ctype_space($text)) {
$this->text_empty = false;
}
}
/**
* Open a text span.
*
* @param string $styleName The style to use.
* @see ODTSpan::spanOpen for detailed documentation
*/
function spanOpen($styleName, $element=NULL, $attributes=NULL){
$in_paragraph = $this->state->getInParagraph();
if ( !$in_paragraph ) {
$this->paragraphOpen();
}
unset($this->params->elementObj);
ODTSpan::spanOpen($this->params, $styleName, $element, $attributes);
}
/**
* Open a text span using CSS.
*
* @see ODTSpan::spanOpenUseCSS for detailed documentation
*/
function spanOpenUseCSS($element=NULL, $attributes=NULL, cssimportnew $import=NULL){
$in_paragraph = $this->state->getInParagraph();
if ( !$in_paragraph ) {
$this->paragraphOpen();
}
if (!isset($import)) {
$import = $this->importnew;
}
if (!isset($element)) {
$element = 'span';
}
unset($this->params->elementObj);
$this->params->import = $import;
ODTSpan::spanOpenUseCSS($this->params, $element, $attributes);
$this->params->import = $this->importnew;
}
/**
* Open a text span using properties.
*
* @see ODTSpan::spanOpenUseProperties for detailed documentation
*/
function spanOpenUseProperties($properties){
$in_paragraph = $this->state->getInParagraph();
if ( !$in_paragraph ) {
$this->paragraphOpen();
}
ODTUtility::adjustValuesForODT($properties, $this->units);
unset($this->params->elementObj);
ODTSpan::spanOpenUseProperties($this->params, $properties);
}
/**
* Close a text span.
*
* @param string $style_name The style to use.
* @see ODTSpan::spanClose for detailed documentation
*/
function spanClose() {
unset($this->params->elementObj);
ODTSpan::spanClose($this->params);
}
/**
* Automatically generate ODT format for $HTMLCode
* including text spans.
*
* @param string $style_name The style to use.
* @see ODTSpan::generateSpansfromHTMLCode for detailed documentation
*/
function generateSpansfromHTMLCode($HTMLCode){
ODTSpan::generateSpansfromHTMLCode($this->params, $HTMLCode);
}
/**
* Open a paragraph
*
* @param string $styleName The style to use.
* @see ODTParagraph::paragraphOpen for detailed documentation
*/
function paragraphOpen($styleName=NULL, $element=NULL, $attributes=NULL){
unset($this->params->elementObj);
ODTParagraph::paragraphOpen($this->params, $styleName, $element, $attributes);
}
/**
* Close a paragraph
*
* @see ODTParagraph::paragraphClose for detailed documentation
*/
function paragraphClose(){
unset($this->params->elementObj);
ODTParagraph::paragraphClose($this->params);
}
/**
* Open a paragraph using CSS.
*
* @see ODTParagraph::paragraphOpenUseCSS for detailed documentation
*/
function paragraphOpenUseCSS($element=NULL, $attributes=NULL, cssimportnew $import=NULL){
if (!isset($import)) {
$import = $this->importnew;
}
if (!isset($element)) {
$element = 'p';
}
unset($this->params->elementObj);
$this->params->import = $import;
ODTParagraph::paragraphOpenUseCSS($this->params, $element, $attributes);
$this->params->import = $this->importnew;
}
/**
* Open a paragraph using properties.
*
* @see ODTParagraph::paragraphOpenUseProperties for detailed documentation
*/
function paragraphOpenUseProperties($properties){
ODTUtility::adjustValuesForODT($properties, $this->units);
unset($this->params->elementObj);
ODTParagraph::paragraphOpenUseProperties($this->params, $properties);
}
/**
* Insert a horizontal rule
*/
function horizontalRule() {
$this->paragraphClose();
$styleName = $this->getStyleName('horizontal line');
$this->paragraphOpen($styleName);
$this->paragraphClose();
// Save paragraph style name in 'Do not delete array'!
$this->preventDeletetionStyles [] = $styleName;
}
/**
* static call back to replace spaces
*
* @param array $matches
* @return string
*/
function _preserveSpace($matches){
$spaces = $matches[1];
$len = strlen($spaces);
return '';
}
/**
* @param string $text
* @param string $style
* @param bool $notescaped
*/
function addPreformattedText($text, $style=null, $notescaped=true) {
if (empty($style)) {
$style = $this->getStyleName('preformatted');
}
if ($notescaped) {
$text = $this->replaceXMLEntities($text);
}
// Check newline at start
$first_newline = strpos($text, "\n");
if ($first_newline !== FALSE and $first_newline == 0) {
// text starts with a newline, remove it
$text = substr($text,1);
}
// Check newline at end
$length = strlen($text);
if ($text[$length-1] == "\n") {
$text = substr($text, 0, $length-1);
}
$text = str_replace("\n",'',$text);
$text = str_replace("\t",'',$text);
$text = preg_replace_callback('/( +)/',array($this,'_preserveSpace'),$text);
$list_item = $this->state->getCurrentListItem();
if (isset($list_item)) {
// if we're in a list item, we must close the tag
$this->paragraphClose();
$this->paragraphOpen($style);
$this->content .= $text;
$this->paragraphClose();
// FIXME: query previous style before preformatted text was opened and re-use it here
$this->paragraphOpen();
} else {
$this->paragraphClose();
$this->paragraphOpen($style);
$this->content .= $text;
$this->paragraphClose();
}
}
/**
* Add a linebreak
*/
function linebreak() {
$this->content .= '';
}
/**
* Add a pagebreak
*/
function pagebreak() {
// Only set marker to insert a pagebreak on "next occasion".
// The pagebreak will then be inserted in the next call to p_open() or header().
// The style will be a "pagebreak" style with the paragraph or header style as the parent.
// This prevents extra empty lines after the pagebreak.
$this->paragraphClose();
$this->pagebreak = true;
}
/**
* Check if a pagebreak is pending
*
* @return bool
*/
function pagebreakIsPending() {
return $this->pagebreak;
}
/**
* Check if a page format change is pending
*
* @return bool
*/
function pageFormatChangeIsPending() {
if (isset($this->changePageFormat)) {
return true;
}
return false;
}
/**
* Set pagebreak pending.
*
* @return bool
*/
function setPagebreakPending($value) {
return $this->pagebreak = $value;
}
/**
* Check if a header with $title exists.
*
* @return bool
*/
function headerExists($title) {
return in_array($title, $this->headers);
}
/**
* Add $title to headers.
*
* @return bool
*/
function addHeader($title) {
$this->headers[] = $title;
}
/**
* Insert an index into the document using the parameters in $settings.
*
* @see ODTIndex::insertIndex for detailed documentation
*/
function insertIndex($type='toc', array $settings=NULL) {
ODTIndex::insertIndex($this->params, $this->indexesData, $type, $settings);
}
/**
* Creates a reference ID for the TOC
*
* @param string $title The headline/item title
* @return string
*
* @author LarsDW223
*/
public function buildTOCReferenceID($title) {
// FIXME: not DokuWiki dependant function woud be nicer...
$title = str_replace(':','',cleanID($title));
$title = ltrim($title,'0123456789._-');
if(empty($title)) {
$title='NoTitle';
}
$this->refIDCount++;
// The reference ID needs to start with '__RefHeading___'.
// Otherwise LibreOffice will display $ref instead of the heading
// name when moving the mouse over the link in the TOC.
$ref = '__RefHeading___'.$title.'_'.$this->refIDCount;
return $ref;
}
/**
* Add an item to the TOC
*
* @param string $refID the reference ID
* @param string $hid the hash link
* @param string $text the text to display
* @param int $level the nesting level
*/
function tocAddItemInternal($refID, $hid, $text, $level) {
$item = $refID.','.$hid.','.$text.','. $level;
$this->toc[] = $item;
}
/**
* Set bookmark for the start of the page. This just saves the title temporarily.
* It is then to be inserted in the first header or paragraph.
*
* @param string $id ID of the bookmark
*/
function setPageBookmark($id){
$inParagraph = $this->state->getInParagraph();
if ($inParagraph) {
$this->insertBookmarkInternal($id, true);
} else {
$this->pageBookmark = $id;
}
}
/**
* Insert a bookmark. If $now is true then the bookmark will be created
* immediately. This eventually causes a paragraph to be opened.
* If $now is false then the bookmark will be inserted with the next
* cdata text.
*
* @param string $id ID of the bookmark
* @param string $now Insert bookmark immediately?
*/
public function insertBookmark($id, $now) {
if ($now) {
$this->insertBookmarkInternal($id);
} else {
$this->pageBookmark = $id;
}
}
/**
* Insert a bookmark.
*
* @param string $id ID of the bookmark
*/
protected function insertBookmarkInternal($id, $openParagraph=true){
if ($openParagraph) {
$this->paragraphOpen();
}
$this->content .= '';
$this->bookmarks [] = $id;
}
/**
* Insert a pending page bookmark
*
* @param string $text the text to display
* @param int $level header level
* @param int $pos byte position in the original source
*/
function insertPendingPageBookmark(){
// Insert page bookmark if requested and not done yet.
if ( !empty($this->pageBookmark) ) {
$this->insertBookmarkInternal($this->pageBookmark, false);
$this->pageBookmark = NULL;
}
}
/**
* Render a heading.
*
* @param string $text the text to display
* @param int $level header level
* @param int $pos byte position in the original source
* @see ODTHeading::heading for detailed documentation
*/
function heading($text, $level, $element=NULL, $attributes=NULL){
ODTHeading::heading($this->params, $text, $level, $element, $attributes);
}
/**
* Make sure that a user field name only contains valid sings.
* (Code has been adopted from the fields plugin)
*
* @param string $name The name of the field
* @return string The cleaned up $name
* @author Aurelien Bompard
*/
protected function cleanupUserFieldName($name) {
// Keep only allowed chars in the name
return preg_replace('/[^a-zA-Z0-9_.]/', '', $name);
}
/**
* Add a user field.
* (Code has been adopted from the fields plugin)
*
* @param string $name The name of the field
* @param string $value The value of the field
* @author Aurelien Bompard
*/
public function addUserField($name, $value) {
$name = $this->cleanupUserFieldName($name);
$this->fields [$name] = $value;
}
/**
* Insert a user field reference.
* (Code has been adopted from the fields plugin)
*
* @param string $name The name of the field
* @author Aurelien Bompard
*/
public function insertUserField($name) {
$name = $this->cleanupUserFieldName($name);
if (array_key_exists($name, $this->fields)) {
$this->content .= ''.$this->fields [$name].'';
}
}
/**
* This function encodes the section of a
* ODT document.
*
* @return string
*/
protected function getUserFieldDecls() {
$value = '';
foreach ($this->fields as $fname => $fvalue) {
$value .= '';
}
$value .= '';
return $value;
}
/**
* Get ODT file as string (ZIP archive).
*
* @param string $content The content
* @return string String containing ODT ZIP stream
*/
public function getODTFileAsString($ODTtemplate=NULL, $tempDir=NULL) {
// Close any open paragraph if not done yet.
$this->paragraphClose();
// Replace local link placeholders with links to headings or bookmarks
$styleName = $this->getStyleName('local link');
$visitedStyleName = $this->getStyleName('visited local link');
ODTUtility::replaceLocalLinkPlaceholders($this->content, $this->toc, $this->bookmarks, $styleName, $visitedStyleName);
// Build indexes
ODTIndex::replaceIndexesPlaceholders($this->params, $this->indexesData, $this->toc);
// Delete paragraphs which only contain whitespace (but keep pagebreaks!)
ODTUtility::deleteUselessElements($this->content, $this->preventDeletetionStyles);
//$this->trace_dump .= $this->htmlStack->getDump();
//$this->trace_dump .= $this->importnew->rulesToString();
if (!empty($this->trace_dump)) {
$this->paragraphOpen();
$this->linebreak();
$this->content .= 'Tracedump: ';
$this->addPreformattedText($this->trace_dump);
$this->paragraphClose();
}
// Get meta content
$metaContent = $this->meta->getContent();
// Get user field declarations
$userFieldDecls = $this->getUserFieldDecls();
// Build the document
ODTExport::buildZIPFile($this->params,
$metaContent,
$userFieldDecls,
$this->pageStyles,
$ODTtemplate,
$tempDir);
// Return document
return $this->ZIP->getArchive();
}
/**
* Import CSS code for styles from a string.
*
* @param string $cssCode The CSS code to import
* @param string $mediaSel The media selector to use e.g. 'print'
* @param string $mediaPath Local path to media files
*/
public function importCSSFromString($cssCode, $mediaSel=NULL, $URLCallback=NULL, $forceStyles=false, $listAlign='right') {
// Import CSS as styles?
$importStyles = false;
if ($this->CSSUsage == 'basic' || $this->CSSUsage == 'full' || $forceStyles) {
$importStyles = true;
}
ODTImport::importCSSFromString ($this->params, $cssCode, $mediaSel, array($this, 'adjustLengthCallback'), $URLCallback, $this->registrations, $importStyles, $listAlign);
}
/**
* Import CSS code for styles from a file.
*
* @param string $CSSTemplate String containing the path and file name of the CSS file to import
* @param string $mediaSel The media selector to use e.g. 'print'
* @param string $mediaPath Local path to media files
*/
public function importCSSFromFile($CSSTemplate, $mediaSel=NULL, $URLCallback=NULL, $listAlign='right') {
// Import CSS as styles?
$importStyles = false;
if ($this->CSSUsage == 'basic' || $this->CSSUsage == 'full') {
$importStyles = true;
}
ODTImport::importCSSFromFile ($this->params, $CSSTemplate, $mediaSel, array($this, 'adjustLengthCallback'), $URLCallback, $this->registrations, $importStyles, $listAlign);
}
public function importODTStyles($template=NULL, $tempDir=NULL) {
ODTImport::importODTStyles($this->params, $template, $tempDir);
}
/**
* General internal function for closing an element.
* Can always be used to close any open element if no more actions
* are required apart from generating the closing tag and
* removing the element from the state stack.
*/
public function closeCurrentElement() {
$current = $this->state->getCurrent();
if (isset($current)) {
$this->content .= $current->getClosingTag($this->content);
$this->state->leave();
}
}
/**
* This function creates a style for changing the page format if required.
* It returns NULL if no page format change is pending or if the current
* page format is equal to the required page format.
*
* @param string $parent Parent style name.
* @return string Name of the style to be used for changing page format
*
* FIXME: make protected as soon as function header is moved here also!
*/
public function doPageFormatChange ($parent = NULL) {
if ( !isset($this->changePageFormat) ) {
// Error.
return NULL;
}
$data = $this->changePageFormat;
$this->changePageFormat = NULL;
if ( empty($parent) ) {
$parent = 'Standard';
}
// Create page layout style
$format_string = $this->page->formatToString ($data['format'], $data['orientation'], $data['margin-top'], $data['margin-right'], $data['margin-bottom'], $data['margin-left']);
$properties ['style-name'] = 'Style-Page-'.$format_string;
$properties ['width'] = $data ['width'];
$properties ['height'] = $data ['height'];
$properties ['margin-top'] = $data ['margin-top'];
$properties ['margin-bottom'] = $data ['margin-bottom'];
$properties ['margin-left'] = $data ['margin-left'];
$properties ['margin-right'] = $data ['margin-right'];
$style_obj = ODTPageLayoutStyle::createPageLayoutStyle($properties);
$style_name = $style_obj->getProperty('style-name');
// It is iassumed the proper media selector has been set by calling setMediaSelector()
if (($this->CSSUsage == 'basic' || $this->CSSUsage == 'full') && isset($this->importnew)) {
ODTImport::set_page_properties($this->params, $style_obj);
}
// Save style data in page style array, in common styles and set current page format
$master_page_style_name = $format_string;
$this->pageStyles [$master_page_style_name] = $style_name;
$this->addAutomaticStyle($style_obj);
$this->page->setFormat($data ['format'], $data ['orientation'], $data['margin-top'], $data['margin-right'], $data['margin-bottom'], $data['margin-left']);
// Create paragraph style.
$properties = array();
$properties ['style-name'] = 'Style-'.$format_string;
$properties ['style-parent'] = $parent;
$properties ['style-master-page-name'] = $master_page_style_name;
$properties ['page-number'] = 'auto';
$style_obj = ODTParagraphStyle::createParagraphStyle($properties);
$style_name = $style_obj->getProperty('style-name');
$this->addAutomaticStyle($style_obj);
// Save paragraph style name in 'Do not delete array'!
$this->preventDeletetionStyles [] = $style_name;
return $style_name;
}
public function createPagebreakStyle($parent=NULL,$before=true) {
$style_name = 'pagebreak';
if ( !$before ) {
$style_name .= '_after';
}
if ( !empty($parent) ) {
$style_name .= '_'.$parent;
}
if ( !$this->styleExists($style_name) ) {
$style_obj = ODTParagraphStyle::createPagebreakStyle($style_name, $parent, $before);
$this->addAutomaticStyle($style_obj);
// Save paragraph style name in 'Do not delete array'!
$this->preventDeletetionStyles [] = $style_name;
}
return $style_name;
}
/**
* Replace XML entities
*
* @param string $value
* @return string
*/
function replaceXMLEntities($value) {
return str_replace( array('&','"',"'",'<','>'), array('&','"',''','<','>'), $value);
}
/**
* Open/start a footnote.
*
* @author Andreas Gohr
* @see ODTFootnote::footnoteOpen for detailed documentation
*/
function footnoteOpen() {
ODTFootnote::footnoteOpen($this->params);
}
/**
* Close/end a footnote.
*
* @author Andreas Gohr
* @see ODTFootnote::footnoteClose for detailed documentation
*/
function footnoteClose() {
ODTFootnote::footnoteClose($this->params);
}
function quoteOpen() {
// Do not go higher than 5 because only 5 quotation styles are defined.
if ( $this->quote_depth < 5 ) {
$this->quote_depth++;
}
unset($this->params->elementObj);
ODTTable::tableOpen($this->params, 1, 1, 'Table_Quotation'.$this->quote_depth, 'blockquote', NULL);
$this->tableRowOpen();
unset($this->params->elementObj);
ODTTable::tableCellOpen($this->params, 1, 1, 'left', 'Cell_Quotation'.$this->quote_depth, NULL, NULL, NULL);
}
function quoteClose() {
$this->paragraphClose();
$this->tableCellClose();
$this->tableRowClose();
$this->tableClose();
if ( $this->quote_depth > 0 ) {
$this->quote_depth--;
}
}
/**
* Opens a list.
* The list style specifies if the list is an ordered or unordered list.
*
* @param bool $continue Continue numbering?
* @param string $styleName Name of style to use for the list
* @see ODTList::listOpen for detailed documentation
*/
function listOpen($continue=false, $styleName, $element=NULL, $attributes=NULL) {
if (!isset($element)) {
if ($styleName == $this->getStyleName('list')) {
$element = 'ul';
}
if ($styleName == $this->getStyleName('numbering')) {
$element = 'ol';
}
}
ODTList::listOpen($this->params, $continue, $styleName, $element, $attributes);
}
/**
* Close a list.
*
* @see ODTList::listClose for detailed documentation
*/
function listClose() {
ODTList::listClose($this->params);
}
/**
* Open a list item.
*
* @param int $level The nesting level
* @see ODTList::listItemOpen for detailed documentation
*/
function listItemOpen($level, $element=NULL, $attributes=NULL) {
ODTList::listItemOpen($this->params, $level, $element, $attributes);
}
/**
* Close a list item.
*
* @see ODTList::listItemClose for detailed documentation
*/
function listItemClose() {
ODTList::listItemClose($this->params);
}
/**
* Open a list header.
*
* @param int $level The nesting level
* @see ODTList::listHeaderOpen for detailed documentation
*/
function listHeaderOpen($level, $element=NULL, $attributes=NULL) {
ODTList::listHeaderOpen($this->params, $level, $element, $attributes);
}
/**
* Close a list header.
*
* @see ODTList::listHeaderClose for detailed documentation
*/
function listHeaderClose() {
ODTList::listHeaderClose($this->params);
}
/**
* Open list content/a paragraph in a list item.
*
* @see ODTList::listContentOpen for detailed documentation
*/
function listContentOpen($element=NULL, $attributes=NULL) {
ODTList::listContentOpen($this->params, $element, $attributes);
}
/**
* Close list content/a paragraph in a list item.
*
* @see ODTList::listContentClose for detailed documentation
*/
function listContentClose() {
ODTList::listContentClose($this->params);
}
/**
* Open/start a table.
*
* @param int $maxcols maximum number of columns
* @param int $numrows NOT IMPLEMENTED
* @see ODTTable::tableOpen for detailed documentation
*/
function tableOpen($maxcols = NULL, $numrows = NULL, $element=NULL, $attributes=NULL){
unset($this->params->elementObj);
ODTTable::tableOpen($this->params, $maxcols, $numrows, NULL, $element, $attributes);
}
/**
* Close/finish a table.
*
* @param int $maxcols maximum number of columns
* @param int $numrows NOT IMPLEMENTED
* @see ODTTable::tableClose for detailed documentation
*/
function tableClose(){
unset($this->params->elementObj);
ODTTable::tableClose($this->params);
}
/**
* Add a column to a table.
*
* @see ODTTable::tableAddColumn for detailed documentation
*/
function tableAddColumn (){
unset($this->params->elementObj);
ODTTable::tableAddColumn ($this->params);
}
/**
* Open a table row.
*
* @see ODTTable::tableRowOpen for detailed documentation
*/
function tableRowOpen($element=NULL, $attributes=NULL){
unset($this->params->elementObj);
ODTTable::tableRowOpen($this->params, NULL, $element, $attributes);
}
/**
* Close a table row.
*
* @see ODTTable::tableRowClose for detailed documentation
*/
function tableRowClose(){
unset($this->params->elementObj);
ODTTable::tableRowClose($this->params);
}
/**
* Open a table header cell.
*
* @see ODTTable::tableHeaderOpen for detailed documentation
*/
function tableHeaderOpen($colspan = 1, $rowspan = 1, $align, $element=NULL, $attributes=NULL){
unset($this->params->elementObj);
ODTTable::tableHeaderOpen($this->params, $colspan, $rowspan, $align, NULL, NULL, $element, $attributes);
}
/**
* Close a table header cell.
*
* @see ODTTable::tableHeaderClose for detailed documentation
*/
function tableHeaderClose(){
unset($this->params->elementObj);
ODTTable::tableHeaderClose($this->params);
}
/**
* Open a table cell.
*
* @see ODTTable::tableCellOpen for detailed documentation
*/
function tableCellOpen($colspan, $rowspan, $align, $element=NULL, $attributes=NULL){
unset($this->params->elementObj);
ODTTable::tableCellOpen($this->params, $colspan, $rowspan, $align, NULL, NULL, $element, $attributes);
}
/**
* Close a table cell.
*
* @see ODTTable::tableCellClose for detailed documentation
*/
function tableCellClose(){
unset($this->params->elementObj);
ODTTable::tableCellClose($this->params);
}
/**
* Open a table using CSS.
*
* @see ODTTable::tableOpenUseCSS for detailed documentation
*/
function tableOpenUseCSS($maxcols=NULL, $numrows=NULL, $element=NULL, $attributes=NULL, cssimportnew $import=NULL){
if (!isset($import)) {
$import = $this->importnew;
}
if (!isset($element)) {
$element = 'table';
}
unset($this->params->elementObj);
$this->params->import = $import;
ODTTable::tableOpenUseCSS($this->params, $maxcols, $numrows, $element, $attributes);
$this->params->import = $this->importnew;
}
/**
* Open a table using properties.
*
* @see ODTTable::tableOpenUseProperties for detailed documentation
*/
function tableOpenUseProperties ($properties, $maxcols = 0, $numrows = 0){
unset($this->params->elementObj);
ODTTable::tableOpenUseProperties($this->params, $properties, $maxcols, $numrows);
}
/**
* Add a table column using properties.
*
* @see ODTTable::tableAddColumnUseProperties for detailed documentation
*/
function tableAddColumnUseProperties ($properties){
unset($this->params->elementObj);
ODTTable::tableAddColumnUseProperties($this->params, $properties);
}
/**
* Open a table header using CSS.
*
* @see ODTTable::tableHeaderOpenUseCSS for detailed documentation
*/
function tableHeaderOpenUseCSS($colspan = 1, $rowspan = 1, $element=NULL, $attributes=NULL, cssimportnew $import=NULL){
if (!isset($import)) {
$import = $this->importnew;
}
if (!isset($element)) {
$element = 'th';
}
unset($this->params->elementObj);
$this->params->import = $import;
ODTTable::tableHeaderOpenUseCSS($this->params, $colspan, $rowspan, $element, $attributes);
$this->params->import = $this->importnew;
}
/**
* Open a table header using properties.
*
* @see ODTTable::tableHeaderOpenUseProperties for detailed documentation
*/
function tableHeaderOpenUseProperties($properties, $colspan = 1, $rowspan = 1){
unset($this->params->elementObj);
ODTTable::tableHeaderOpenUseProperties($this->params, $properties, $colspan, $rowspan);
}
/**
* Open a table row using CSS.
*
* @see ODTTable::tableRowOpenUseCSS for detailed documentation
*/
function tableRowOpenUseCSS($element=NULL, $attributes=NULL, cssimportnew $import=NULL){
if (!isset($import)) {
$import = $this->importnew;
}
if (!isset($element)) {
$element = 'tr';
}
unset($this->params->elementObj);
$this->params->import = $import;
ODTTable::tableRowOpenUseCSS($this->params, $element, $attributes);
$this->params->import = $this->importnew;
}
/**
* Open a table row using properties.
*
* @see ODTTable::tableRowOpenUseProperties for detailed documentation
*/
function tableRowOpenUseProperties($properties){
unset($this->params->elementObj);
ODTTable::tableRowOpenUseProperties($this->params, $properties);
}
/**
* Open a table cell using CSS.
*
* @see ODTTable::tableCellOpenUseCSS for detailed documentation
*/
function tableCellOpenUseCSS($colspan = 1, $rowspan = 1, $element=NULL, $attributes=NULL, cssimportnew $import=NULL){
if (!isset($import)) {
$import = $this->importnew;
}
if (!isset($element)) {
$element = 'td';
}
unset($this->params->elementObj);
$this->params->import = $import;
ODTTable::tableCellOpenUseCSS($this->params, $element, $attributes, $colspan, $rowspan);
$this->params->import = $this->importnew;
}
/**
* Open a table cell using properties.
*
* @see ODTTable::tableCellOpenUseProperties for detailed documentation
*/
function tableCellOpenUseProperties($properties, $colspan = 1, $rowspan = 1){
unset($this->params->elementObj);
ODTTable::tableCellOpenUseProperties($this->params, $properties, $colspan, $rowspan);
}
/**
* Open a text box in a frame using CSS.
*
* @see ODTFrame::openTextBoxUseCSS for detailed documentation
*/
function openTextBoxUseCSS ($element=NULL, $attributes=NULL, cssimportnew $import=NULL) {
if (!isset($import)) {
$import = $this->importnew;
}
if (!isset($element)) {
$element = 'div';
}
unset($this->params->elementObj);
$this->params->import = $import;
ODTFrame::openTextBoxUseCSS($this->params, $element, $attributes);
$this->params->import = $this->importnew;
}
/**
* Open a text box in a frame using properties.
*
* @see ODTFrame::openTextBoxUseProperties for detailed documentation
*/
function openTextBoxUseProperties ($properties) {
unset($this->params->elementObj);
ODTFrame::openTextBoxUseProperties($this->params, $properties);
}
/**
* This function closes a textbox.
*
* @see ODTFrame::closeTextBox for detailed documentation
*/
function closeTextBox () {
unset($this->params->elementObj);
ODTFrame::closeTextBox($this->params);
}
/**
* Open a frame using properties.
*
* @see ODTFrame::openFrameUseProperties for detailed documentation
*/
function openFrameUseProperties ($properties) {
unset($this->params->elementObj);
ODTFrame::openFrameUseProperties($this->params, $properties);
}
/**
* This function closes a textbox.
*
* @see ODTFrame::closeTextBox for detailed documentation
*/
function closeFrame () {
unset($this->params->elementObj);
ODTFrame::closeFrame($this->params);
}
/**
* Open a multi column text box in a frame using properties.
*
* @see ODTFrame::openMultiColumnTextBoxUseProperties for detailed documentation
*/
function openMultiColumnTextBoxUseProperties ($properties) {
unset($this->params->elementObj);
ODTFrame::openMultiColumnTextBoxUseProperties($this->params, $properties);
}
/**
* This function closes a multi column textbox.
*
* @see ODTFrame::closeTextBox for detailed documentation
*/
function closeMultiColumnTextBox () {
unset($this->params->elementObj);
ODTFrame::closeMultiColumnTextBox($this->params);
}
/**
* Change outline style to given value.
* Currently only 'Numbers' is supported. Any other value will
* not change anything.
*
* @param string $type Type of outline style to set
*/
public function setOutlineStyle ($type) {
$outline_style = $this->getStyle('Outline');
if (!isset($outline_style)) {
// Outline style not found!
return;
}
switch ($type) {
case 'Numbers':
for ($level = 1 ; $level < 11 ; $level++) {
$outline_style->setPropertyForLevel($level, 'num-format', '1');
$outline_style->setPropertyForLevel($level, 'num-suffix', NULL);
$outline_style->setPropertyForLevel($level, 'num-prefix', NULL);
$outline_style->setPropertyForLevel($level, 'display-levels', $level);
}
break;
}
}
/**
* This function creates a text style for spans with the given properties.
* If $common is true it will be added to the common styles otherwise it
* will be dadded to the automatic styles.
*
* Common styles are visible for the user after export e.g. in LibreOffice
* 'Styles and Formatting' view. Therefore they should have
* $properties ['style-display-name'] set to a meaningfull name.
*
* @param $properties The properties to use
* @param $common Add style to common or automatic styles?
* @see ODTTextStyle::createTextStyle for more documentation
*/
public function createTextStyle ($properties, $common=true) {
$style_obj = ODTTextStyle::createTextStyle($properties, NULL, $this);
if ($common == true) {
$this->addStyle($style_obj);
} else {
$this->addAutomaticStyle($style_obj);
}
}
/**
* This function creates a paragraph style for paragraphs with the given properties.
* If $common is true it will be added to the common styles otherwise it
* will be dadded to the automatic styles.
*
* Common styles are visible for the user after export e.g. in LibreOffice
* 'Styles and Formatting' view. Therefore they should have
* $properties ['style-display-name'] set to a meaningfull name.
*
* @param $properties The properties to use
* @param $common Add style to common or automatic styles?
* @see ODTParagraphStyle::createParagraphStyle for more documentation
*/
public function createParagraphStyle ($properties, $common=true) {
$style_obj = ODTParagraphStyle::createParagraphStyle($properties, NULL, $this);
if ($common == true) {
$this->addStyle($style_obj);
} else {
$this->addAutomaticStyle($style_obj);
}
}
/**
* This function creates a table style for tables with the given properties.
* If $common is true it will be added to the common styles otherwise it
* will be dadded to the automatic styles.
*
* Common styles are visible for the user after export e.g. in LibreOffice
* 'Styles and Formatting' view. Therefore they should have
* $properties ['style-display-name'] set to a meaningfull name.
*
* @param $properties The properties to use
* @param $common Add style to common or automatic styles?
* @see ODTTableStyle::createTableTableStyle for more documentation
*/
public function createTableStyle ($properties, $common=true) {
$style_obj = ODTTableStyle::createTableTableStyle($properties);
if ($common == true) {
$this->addStyle($style_obj);
} else {
$this->addAutomaticStyle($style_obj);
}
}
/**
* This function creates a table row style for table rows with the given properties.
* If $common is true it will be added to the common styles otherwise it
* will be dadded to the automatic styles.
*
* Common styles are visible for the user after export e.g. in LibreOffice
* 'Styles and Formatting' view. Therefore they should have
* $properties ['style-display-name'] set to a meaningfull name.
*
* @param $properties The properties to use
* @param $common Add style to common or automatic styles?
* @see ODTTableRowStyle::createTableRowStyle for more documentation
*/
public function createTableRowStyle ($properties, $common=true) {
$style_obj = ODTTableRowStyle::createTableRowStyle($properties);
if ($common == true) {
$this->addStyle($style_obj);
} else {
$this->addAutomaticStyle($style_obj);
}
}
/**
* This function creates a table cell style for table cells with the given properties.
* If $common is true it will be added to the common styles otherwise it
* will be dadded to the automatic styles.
*
* Common styles are visible for the user after export e.g. in LibreOffice
* 'Styles and Formatting' view. Therefore they should have
* $properties ['style-display-name'] set to a meaningfull name.
*
* @param $properties The properties to use
* @param $common Add style to common or automatic styles?
* @see ODTTableCellStyle::createTableCellStyle for more documentation
*/
public function createTableCellStyle ($properties, $common=true) {
$style_obj = ODTTableCellStyle::createTableCellStyle($properties);
if ($common == true) {
$this->addStyle($style_obj);
} else {
$this->addAutomaticStyle($style_obj);
}
}
/**
* This function creates a table column style for table columns with the given properties.
* If $common is true it will be added to the common styles otherwise it
* will be dadded to the automatic styles.
*
* Common styles are visible for the user after export e.g. in LibreOffice
* 'Styles and Formatting' view. Therefore they should have
* $properties ['style-display-name'] set to a meaningfull name.
*
* @param $properties The properties to use
* @param $common Add style to common or automatic styles?
* @see ODTTableColumnStyle::createTableColumnStyle for more documentation
*/
public function createTableColumnStyle ($properties, $common=true) {
$style_obj = ODTTableColumnStyle::createTableColumnStyle($properties);
if ($common == true) {
$this->addStyle($style_obj);
} else {
$this->addAutomaticStyle($style_obj);
}
}
/**
* The function tries to examine the width and height
* of the image stored in file $src.
*
* @see ODTUtility::getImageSize for a detailed description
*/
public function getImageSize($src, $maxwidth=NULL, $maxheight=NULL){
return ODTUtility::getImageSize($src, $maxwidth, $maxheight);
}
/**
* @param string $src
* @param $width
* @param $height
* @return array
*/
public function getImageSizeString($src, $width = NULL, $height = NULL){
return ODTUtility::getImageSizeString($src, $width, $height, false, $this->params->units);
}
/**
* Adds an image $src to the document.
*
* @param string $src The path to the image file
* @param string $width Width of the picture (NULL=original size)
* @param string $height Height of the picture (NULL=original size)
* @param string $align Alignment
* @param string $title Title
* @param string $style Optional "draw:style-name"
* @param boolean $returnonly Only return code
*
* @see ODTImage::addImage for a detailed description
*/
public function addImage($src, $width = NULL, $height = NULL, $align = NULL, $title = NULL, $style = NULL, $returnonly = false){
if ($returnonly) {
return ODTImage::addImage($this->params, $src, $width, $height, $align, $title, $style, $returnonly);
} else {
ODTImage::addImage($this->params, $src, $width, $height, $align, $title, $style, $returnonly);
}
}
/**
* Adds an image $src to the document using the parameters set in $properties.
*
* @param string $src The path to the image file
* @param array $properties Properties (width, height... see ODTImage::addImageUseProperties)
* @param boolean $returnonly Only return code
*
* @see ODTImage::addImageUseProperties for a detailed description
*/
public function addImageUseProperties($src, $properties, $returnonly = false){
if ($returnonly) {
return ODTImage::addImageUseProperties($this->params, $src, $properties, $returnonly);
} else {
ODTImage::addImageUseProperties($this->params, $src, $properties, $returnonly);
}
}
/**
* The function adds $string as an SVG image file.
* It does NOT insert the image in the document.
*
* @see ODTImage::addStringAsSVGImageFile for a detailed description
*/
public function addStringAsSVGImageFile($string) {
return ODTImage::addStringAsSVGImageFile($this, $string);
}
/**
* Adds the content of $string as a SVG picture to the document.
*
* @see ODTImage::addStringAsSVGImage for a detailed description
*/
public function addStringAsSVGImage($string, $width = NULL, $height = NULL, $align = NULL, $title = NULL, $style = NULL) {
return ODTImage::addStringAsSVGImage($this->params, $string, $width, $height, $align, $title, $style);
}
/**
* Get properties defined in a CSS style statement.
*
* @see ODTUtility::getCSSStylePropertiesForODT
*/
public function getCSSStylePropertiesForODT(&$properties, $style, $baseURL = NULL){
ODTUtility::getCSSStylePropertiesForODT($properties, $style, $baseURL, $this->units);
}
/**
* This function sets the page format for the FIRST page.
* The format, orientation and page margins can be changed.
* See function queryFormat() in ODT/page.php for supported formats.
*
* @param string $format e.g. 'A4', 'A3'
* @param string $orientation e.g. 'portrait' or 'landscape'
* @param numeric $margin_top Top-Margin in cm, default 2
* @param numeric $margin_right Right-Margin in cm, default 2
* @param numeric $margin_bottom Bottom-Margin in cm, default 2
* @param numeric $margin_left Left-Margin in cm, default 2
*/
public function setStartPageFormat ($format=NULL, $orientation=NULL, $margin_top=NULL, $margin_right=NULL, $margin_bottom=NULL, $margin_left=NULL) {
// Setup page format.
// Set the page format of the current page for calculation ($this->page)
$this->page->setFormat
($format, $orientation, $margin_top, $margin_right, $margin_bottom, $margin_left);
// Change the standard page layout style
$first_page = $this->getStyleByAlias('first page');
if (isset($first_page)) {
$first_page->setProperty('width', $this->page->getWidth().'cm');
$first_page->setProperty('height', $this->page->getHeight().'cm');
$first_page->setProperty('margin-top', $this->page->getMarginTop().'cm');
$first_page->setProperty('margin-right', $this->page->getMarginRight().'cm');
$first_page->setProperty('margin-bottom', $this->page->getMarginBottom().'cm');
$first_page->setProperty('margin-left', $this->page->getMarginLeft().'cm');
}
}
/**
* This function sets the page format.
* The format, orientation and page margins can be changed.
* See function queryFormat() in ODT/page.php for supported formats.
*
* @param string $format e.g. 'A4', 'A3'
* @param string $orientation e.g. 'portrait' or 'landscape'
* @param numeric $margin_top Top-Margin in cm, default 2
* @param numeric $margin_right Right-Margin in cm, default 2
* @param numeric $margin_bottom Bottom-Margin in cm, default 2
* @param numeric $margin_left Left-Margin in cm, default 2
*/
public function setPageFormat ($format=NULL, $orientation=NULL, $margin_top=NULL, $margin_right=NULL, $margin_bottom=NULL, $margin_left=NULL) {
$data = array ();
// Fill missing values with current settings
if ( empty($format) ) {
$format = $this->page->getFormat();
}
if ( empty($orientation) ) {
$orientation = $this->page->getOrientation();
}
if ( empty($margin_top) ) {
$margin_top = $this->page->getMarginTop();
}
if ( empty($margin_right) ) {
$margin_right = $this->page->getMarginRight();
}
if ( empty($margin_bottom) ) {
$margin_bottom = $this->page->getMarginBottom();
}
if ( empty($margin_left) ) {
$margin_left = $this->page->getMarginLeft();
}
// Adjust given parameters, query resulting format data and get format-string
$this->page->queryFormat ($data, $format, $orientation, $margin_top, $margin_right, $margin_bottom, $margin_left);
$format_string = $this->page->formatToString ($data['format'], $data['orientation'], $data['margin-top'], $data['margin-right'], $data['margin-bottom'], $data['margin-left']);
if ( $format_string == $this->page->toString () ) {
// Current page already uses this format, no need to do anything...
return;
}
if ($this->text_empty) {
// If the text is still empty, then we change the start page format now.
$this->page->setFormat($data ['format'], $data ['orientation'], $data['margin-top'], $data['margin-right'], $data['margin-bottom'], $data['margin-left']);
$first_page = $this->getStyleByAlias('first page');
if (isset($first_page)) {
$first_page->setProperty('width', $this->page->getWidth().'cm');
$first_page->setProperty('height', $this->page->getHeight().'cm');
$first_page->setProperty('margin-top', $this->page->getMarginTop().'cm');
$first_page->setProperty('margin-right', $this->page->getMarginRight().'cm');
$first_page->setProperty('margin-bottom', $this->page->getMarginBottom().'cm');
$first_page->setProperty('margin-left', $this->page->getMarginLeft().'cm');
}
} else {
// Set marker and save data for pending change format.
// The format change istelf will be done on the next call to p_open or header()
// to prevent empty lines after the format change.
$this->changePageFormat = $data;
// Close paragraph if open
$this->paragraphClose();
}
}
/**
* Return total page width in centimeters
* (margins are included)
*
* @author LarsDW223
*/
function getPageWidth(){
return $this->page->getWidth();
}
/**
* Return total page height in centimeters
* (margins are included)
*
* @author LarsDW223
*/
function getPageHeight(){
return $this->page->getHeight();
}
/**
* Return left margin in centimeters
*
* @author LarsDW223
*/
function getLeftMargin(){
return $this->page->getMarginLeft();
}
/**
* Return right margin in centimeters
*
* @author LarsDW223
*/
function getRightMargin(){
return $this->page->getMarginRight();
}
/**
* Return top margin in centimeters
*
* @author LarsDW223
*/
function _getTopMargin(){
return $this->page->getMarginTop();
}
/**
* Return bottom margin in centimeters
*
* @author LarsDW223
*/
function _getBottomMargin(){
return $this->page->getMarginBottom();
}
/**
* Return width percentage value if margins are taken into account.
* Usually "100%" means 21cm in case of A4 format.
* But usually you like to take care of margins. This function
* adjusts the percentage to the value which should be used for margins.
* So 100% == 21cm e.g. becomes 80.9% == 17cm (assuming a margin of 2 cm on both sides).
*
* @author LarsDW223
*
* @param int|string $percentage
* @return int|string
*/
function getRelWidthMindMargins ($percentage = '100'){
return $this->page->getRelWidthMindMargins($percentage);
}
/**
* Like _getRelWidthMindMargins but returns the absulute width
* in centimeters.
*
* @author LarsDW223
* @param string|int|float $percentage
* @return float
*/
function getAbsWidthMindMargins ($percentage = '100'){
return $this->page->getAbsWidthMindMargins($percentage);
}
/**
* Return height percentage value if margins are taken into account.
* Usually "100%" means 29.7cm in case of A4 format.
* But usually you like to take care of margins. This function
* adjusts the percentage to the value which should be used for margins.
* So 100% == 29.7cm e.g. becomes 86.5% == 25.7cm (assuming a margin of 2 cm on top and bottom).
*
* @author LarsDW223
*
* @param string|float|int $percentage
* @return float|string
*/
function getRelHeightMindMargins ($percentage = '100'){
return $this->page->getRelHeightMindMargins($percentage);
}
/**
* Like _getRelHeightMindMargins but returns the absulute width
* in centimeters.
*
* @author LarsDW223
*
* @param string|int|float $percentage
* @return float
*/
function getAbsHeightMindMargins ($percentage = '100'){
return $this->page->getAbsHeightMindMargins($percentage);
}
/**
* Sets the twips per pixel (X axis) used for px to pt conversion.
*
* @param int $value The value to be set.
*/
function setTwipsPerPixelX ($value) {
$this->units->setTwipsPerPixelX ($value);
}
/**
* Sets the twips per pixel (Y axis) unit used for px to pt conversion.
*
* @param int $value The value to be set.
*/
function setTwipsPerPixelY ($value) {
$this->units->setTwipsPerPixelY ($value);
}
/**
* Sets the pixel per em unit used for px to em conversion.
*
* @param int $value The value to be set.
*/
public function setPixelPerEm ($value) {
$this->units->setPixelPerEm ($value);
}
/**
* Convert length value with valid XSL unit to points.
*
* @param string $value String with length value, e.g. '20px', '20cm'...
* @param string $axis Is the value to be converted a value on the X or Y axis? Default is 'y'.
* Only relevant for conversion from 'px' or 'em'.
* @return string The current value.
*/
public function toPoints ($value, $axis = 'y') {
return $this->units->toPoints ($value, $axis);
}
/**
* Convert length value with valid XSL unit to pixel.
*
* @param string $value String with length value, e.g. '20pt', '20cm'...
* @param string $axis Is the value to be converted a value on the X or Y axis? Default is 'y'.
* Only relevant for conversion from 'px' or 'em'.
* @return string The current value.
*/
public function toPixel ($value, $axis = 'y') {
return $this->units->toPixel ($value, $axis);
}
public function setTitle ($title) {
// Set title in meta info.
$this->meta->setTitle($title);
}
/**
* Get closest previous TOC entry with $level.
* The function search backwards (previous) in the TOC entries
* for the next entry with level $level and retunrs it reference ID.
*
* @param int $level the nesting level
* @return string The reference ID or NULL
*/
public function getPreviousToCItem($level) {
$index = count($this->toc);
for (; $index >= 0 ; $index--) {
$item = $this->toc[$index];
$params = explode (',', $item);
if ($params [3] == $level) {
return $params [0];
}
}
return NULL;
}
/**
* Insert cross reference to a "destination" inside of the ODT document.
* To insert a link to an external destination use insertHyperlink().
*
* The function only inserts a placeholder and resolves
* the reference on calling replaceLocalLinkPlaceholders();
*
* @fixme add image handling
*
* @param string $destination The resource to link to (e.g. heading ID)
* @param string $text Text for the link (text inserted instead of $destination)
*/
function insertCrossReference($destination, $text){
$this->content .= ''.$destination.'';
}
function openImageLink ($url, $returnonly = false) {
$encoded = '';
if ($this->linksEnabled) {
$url = ODTUtility::stringToIRI($url);
$encoded = '';
}
if ($returnonly) {
return $encoded;
}
$this->content .= $encoded;
}
function closeImageLink ($returnonly = false) {
$encoded = '';
if ($this->linksEnabled) {
$encoded = '';
}
if ($returnonly) {
return $encoded;
}
$this->content .= $encoded;
}
function openHyperlink ($url, $styleName = NULL, $visitedStyleName = NULL, $returnonly = false) {
$encoded = '';
if ($url && $this->linksEnabled) {
if (empty($styleName)) {
$styleName = $this->getStyleName('internet link');
}
if (empty($visitedStyleName)) {
$visitedStyleName = $this->getStyleName('visited internet link');
}
$url = ODTUtility::stringToIRI($url);
$encoded .= 'content .= $encoded;
}
function closeHyperlink ($returnonly = false) {
$encoded = '';
if ($this->linksEnabled) {
$encoded .= '';
}
if ($returnonly) {
return $encoded;
}
$this->content .= $encoded;
}
function insertHyperlink ($url, $text, $styleName = NULL, $visitedStyleName = NULL, $returnonly = false) {
$encoded = '';
if ($url && $this->linksEnabled) {
if (empty($styleName)) {
$styleName = $this->getStyleName('internet link');
}
if (empty($visitedStyleName)) {
$visitedStyleName = $this->getStyleName('visited internet link');
}
$url = ODTUtility::stringToIRI($url);
$encoded .= 'linksEnabled) {
$encoded .= '';
}
if ($returnonly) {
return $encoded;
}
$this->content .= $encoded;
}
/**
* Get CSS properties for a given element and adjust them for ODT.
*
* @param array $dest Properties found will be written in $dest as key value pairs,
* e.g. $dest ['color'] = 'black';
* @param iElementCSSMatchable $element The element object for which the properties are queried.
* The class of the element needs to implement the interface
* iElementCSSMatchable.
* @param string $media_sel The media selector to use for the query e.g. 'print'. May be empty.
*/
public function getODTProperties (array &$dest, $element, $attributes=NULL, $media_sel=NULL, $inherit=true) {
if (!isset($this->importnew)) {
return;
}
$save = $this->importnew->getMedia();
$this->importnew->setMedia($media_sel);
$maxWidth = $this->getAbsWidthMindMargins().'cm';
ODTUtility::getHTMLElementProperties($this->params, $dest, $element, $attributes, $maxWidth, $inherit);
$this->importnew->setMedia($save);
}
public function getODTPropertiesFromElement (array &$dest, iElementCSSMatchable $element, $media_sel=NULL, $inherit=true) {
if (!isset($this->importnew)) {
return;
}
$save = $this->importnew->getMedia();
$this->importnew->setMedia($media_sel);
// Get properties for our class/element from imported CSS
$this->importnew->getPropertiesForElement($dest, $element, $this->units, $inherit);
// Adjust values for ODT
$maxWidth = $this->getAbsWidthMindMargins().'cm';
ODTUtility::adjustValuesForODT($dest, $this->units, $maxWidth);
$this->importnew->setMedia($save);
}
public function adjustValuesForODT (array &$properties) {
ODTUtility::adjustValuesForODT($properties, $this->units);
}
public function adjustValueForODT ($property, $value) {
return ODTUtility::adjustValueForODT($property, $value, $this->units);
}
/**
* Adds an $element with $attributes to the internal HTML stack for
* CSS matching. HTML elments added from extern using this function
* are supposed to never be closed so only root elements should be
* added like 'html' or 'body' or maybe a 'div' that should always
* be present for proper CSS matching.
*
* @param string $element The element name, e.g. 'body'
* @param string $attributes The elements attributes, e.g. 'lang="en" dir="ltr"'
*/
public function addHTMLElement ($element, $attributes = NULL) {
$this->htmlStack->open($element, $attributes);
$this->htmlStack->saveRootIndex ();
}
public function getHTMLStack () {
return $this->htmlStack;
}
public function dumpHTMLStack () {
$this->trace_dump .= $this->htmlStack->getDump();
}
/**
* Check if a file already exists in the document.
*
* @param string $fileName Full file name in the document
* e.g. 'Pictures/myimage.png'
* @return bool
*/
public function fileExists($name) {
return $this->manifest->exists($name);
}
/**
* Add a file to the document.
*
* @param string $fileName Full file name in the document
* e.g. 'Pictures/myimage.png'
* @param string $mime Mime type
* @param string $content The content of the file
*/
public function addFile($fileName, $mime, $content) {
if(!$this->manifest->exists($fileName)){
$this->manifest->add($fileName, $mime);
$this->ZIP->addData($fileName, $content);
return true;
}
// File with that name already exists!
return false;
}
/**
* Adds the image $fileName as a picture file without adding it to
* the content of the document. The link name which can be used for
* the ODT draw:image xlink:href is returned.
*
* @param string $fileName
* @return string
*/
function addFileAsPicture($fileName){
$name = '';
if (file_exists($fileName)) {
list($ext,$mime) = mimetype($fileName);
$name = 'Pictures/'.md5($fileName).'.'.$ext;
$this->addFile($name, $mime, io_readfile($fileName,false));
}
return $name;
}
/**
* Add style object to the document as a common style.
*
* @param ODTStyle $new Object to add
*/
public function addStyle(ODTStyle $new) {
return $this->styleset->addStyle($new);
}
/**
* Add style object to the document as an automatic style.
*
* @param ODTStyle $new Object to add
*/
public function addAutomaticStyle(ODTStyle $new) {
return $this->styleset->addAutomaticStyle($new);
}
/**
* Check if a style with $styleName already exists.
*
* @param string $styleName The style name ofthe style style.
* @return bool
*/
public function styleExists ($name) {
return $this->styleset->styleExists($name);
}
/**
* Get the style object with style name $styleName.
*
* @param string $styleName The style name ofthe style style.
* @return ODTStyle The style object
*/
public function getStyle ($styleName) {
return $this->styleset->getStyle($styleName);
}
public function getDefaultStyle ($family) {
return $this->styleset->getDefaultStyle($family);
}
/**
* Get the style name for a style alias.
*
* @param string $alias The alias for the style.
* @return string The style name used in the ODT document
*/
public function getStyleName($alias) {
return $this->styleset->getStyleName($alias);
}
/**
* The function returns the style at the given index
*
* @param $element Element of the style e.g. 'office:styles'
* @return ODTStyle or NULL
*/
public function getStyleAtIndex($element, $index) {
return $this->styleset->getStyleAtIndex($element, $index);
}
/**
* Get the style object by $alias.
*
* @param string $alias The alias for the style.
* @return ODTStyle The style object
*/
public function getStyleByAlias($alias) {
return $this->styleset->getStyle($this->styleset->getStyleName($alias));
}
public function registerHTMLElementForCSSImport ($style_type, $element, $attributes=NULL) {
$this->registrations [$style_type]['element'] = $element;
$this->registrations [$style_type]['attributes'] = $attributes;
}
public function addToValue ($value, $add) {
$valueInPt = $this->units->toPoints($value, 'y');
$valueInPt = $this->units->getDigits($valueInPt);
$addInPt = $this->units->toPoints($add, 'y');
$addInPt = $this->units->getDigits($addInPt);
return ($valueInPt + $addInPt).'pt';
}
public function subFromValue ($value, $sub) {
$valueInPt = $this->units->toPoints($value, 'y');
$valueInPt = $this->units->getDigits($valueInPt);
$subInPt = $this->units->toPoints($sub, 'y');
$subInPt = $this->units->getDigits($subInPt);
return ($valueInPt - $subInPt).'pt';
}
/**
* Adjust font sizes of all styles to $newBaseSize.
* The $newBaseSize will be the new default font-size and all
* other font-sizes will be re-calculated.
*
* @param string $newBaseSize The new base size e.g. '16pt'
*/
public function adjustFontSizes($newBaseSize) {
// First get the old base size
$default = $this->styleset->getDefaultStyle('paragraph');
if (!isset($default)) {
// ???
return;
}
$oldBaseSize = $default->getProperty('font-size');
if (!isset($oldBaseSize)) {
return;
}
$oldBaseSizeInPt = trim($this->units->toPoints($oldBaseSize, 'y'), 'pt');
// Convert new base size to pt
$newBaseSizeInPt = trim($this->units->toPoints($newBaseSize, 'y'), 'pt');
$styles_list = array();
$styles_list [] = $this->styleset->getStyles();
$styles_list [] = $this->styleset->getAutomaticStyles();
$styles_list [] = $this->styleset->getMasterStyles();
// Go through the list of style arrays and adjust each one
// having a 'font-size' property
foreach ($styles_list as $styles) {
foreach ($styles as $style) {
$fontSize = $style->getProperty('font-size');
if (isset($fontSize)) {
$fontSizeInPt = trim($this->units->toPoints($fontSize, 'y'), 'pt');
$fontSizeInPt = ($fontSizeInPt/$oldBaseSizeInPt) * $newBaseSizeInPt;
$fontSizeInPt = round($fontSizeInPt, 2);
$style->setProperty('font-size', $fontSizeInPt.'pt');
}
}
}
$this->trace_dump .= 'newBaseSize: '.$newBaseSize."\n";
$this->trace_dump .= 'newBaseSizeInPt: '.$newBaseSizeInPt."\n";
// Also set default font-size to the new base size!
$default->setProperty('font-size', $newBaseSizeInPt.'pt');
}
/**
* The function sets the alignment and indentation for ordered lists.
* This means the alignment of the numbers if front of each list item.
* For each alignment predefined values for the attributes 'list-tab-stop-position',
* 'text-indent' and 'margin-left' is set.
*
* @param string $align Alignment to set ('left'/'start', 'center', 'right'/'end')
* @param integer $paddingLeft Left padding in centimeters, moves the whole list to the right
* @param integer $marginLeft Left margin in centimeters, specifies the indent per level
*/
public function setOrderedListParams($setLevel=NULL, $align, $paddingLeft=0, $marginLeft=1) {
if (empty($align)) {
return;
}
$name = $this->styleset->getStyleName('numbering');
$style = $this->styleset->getStyle($name);
if ( !isset($style) ) {
return;
}
if ( !isset($setLevel) ) {
for ($level = 1 ; $level < 11 ; $level++) {
switch ($align) {
case 'left':
case 'start':
$dist = 1;
$style->setPropertyForLevel($level, 'text-align', 'left');
break;
case 'center':
$dist = 0.5;
$style->setPropertyForLevel($level, 'text-align', 'center');
break;
case 'right':
case 'end':
default:
$dist = 0.25;
$style->setPropertyForLevel($level, 'text-align', 'end');
break;
}
$position = $paddingLeft + ($marginLeft * $level) + $dist;
$style->setPropertyForLevel($level, 'list-level-position-and-space-mode', 'label-alignment');
$style->setPropertyForLevel($level, 'label-followed-by', 'listtab');
$style->setPropertyForLevel($level, 'list-tab-stop-position', $position.'cm');
$style->setPropertyForLevel($level, 'text-indent', ($dist*-1).'cm');
$style->setPropertyForLevel($level, 'margin-left', $position.'cm');
}
} else {
switch ($align) {
case 'left':
case 'start':
$dist = 1;
$style->setPropertyForLevel($setLevel, 'text-align', 'left');
break;
case 'center':
$dist = 0.5;
$style->setPropertyForLevel($setLevel, 'text-align', 'center');
break;
case 'right':
case 'end':
default:
$dist = 0.25;
$style->setPropertyForLevel($setLevel, 'text-align', 'end');
break;
}
$position = $paddingLeft + ($marginLeft * $setLevel) + $dist;
$style->setPropertyForLevel($setLevel, 'list-level-position-and-space-mode', 'label-alignment');
$style->setPropertyForLevel($setLevel, 'label-followed-by', 'listtab');
$style->setPropertyForLevel($setLevel, 'list-tab-stop-position', $position.'cm');
$style->setPropertyForLevel($setLevel, 'text-indent', ($dist*-1).'cm');
$style->setPropertyForLevel($setLevel, 'margin-left', $position.'cm');
}
}
/**
* The function sets the alignment and indentation for unordered lists.
* This means the alignment of the icons/buttons if front of each list item.
* For each alignment predefined values for the attributes 'list-tab-stop-position',
* 'text-indent' and 'margin-left' is set.
*
* @param string $align Alignment to set ('left'/'start', 'center', 'right'/'end')
* @param integer $paddingLeft Left padding in centimeters, moves the whole list to the right
* @param integer $marginLeft Left margin in centimeters, specifies the indent per level
*/
public function setUnorderedListParams($setLevel=NULL, $align, $paddingLeft=0, $marginLeft=1) {
if (empty($align)) {
return;
}
$name = $this->styleset->getStyleName('list');
$style = $this->styleset->getStyle($name);
if ( !isset($style) ) {
return;
}
if ( !isset($setLevel) ) {
for ($level = 1 ; $level < 11 ; $level++) {
switch ($align) {
case 'left':
case 'start':
$dist = 1;
$style->setPropertyForLevel($level, 'text-align', 'left');
break;
case 'center':
$dist = 0.5;
$style->setPropertyForLevel($level, 'text-align', 'center');
break;
case 'right':
case 'end':
default:
$dist = 0.25;
$style->setPropertyForLevel($level, 'text-align', 'end');
break;
}
$position = $paddingLeft + ($marginLeft * $level) + $dist;
$style->setPropertyForLevel($level, 'list-level-position-and-space-mode', 'label-alignment');
$style->setPropertyForLevel($level, 'label-followed-by', 'listtab');
$style->setPropertyForLevel($level, 'list-tab-stop-position', $position.'cm');
$style->setPropertyForLevel($level, 'text-indent', ($dist*-1).'cm');
$style->setPropertyForLevel($level, 'margin-left', $position.'cm');
}
} else {
switch ($align) {
case 'left':
case 'start':
$dist = 1;
$style->setPropertyForLevel($setLevel, 'text-align', 'left');
break;
case 'center':
$dist = 0.5;
$style->setPropertyForLevel($setLevel, 'text-align', 'center');
break;
case 'right':
case 'end':
default:
$dist = 0.25;
$style->setPropertyForLevel($setLevel, 'text-align', 'end');
break;
}
$position = $paddingLeft + ($marginLeft * $setLevel) + $dist;
$style->setPropertyForLevel($setLevel, 'list-level-position-and-space-mode', 'label-alignment');
$style->setPropertyForLevel($setLevel, 'label-followed-by', 'listtab');
$style->setPropertyForLevel($setLevel, 'list-tab-stop-position', $position.'cm');
$style->setPropertyForLevel($setLevel, 'text-indent', ($dist*-1).'cm');
$style->setPropertyForLevel($setLevel, 'margin-left', $position.'cm');
}
}
/**
* Automatically generate ODT format for given $HTMLCode.
*
* @param string $HTMLCode
* @see ODTUtility::generateODTfromHTMLCode for detailed documentation
*/
public function generateODTfromHTMLCode($HTMLCode, array $options){
ODTUtility::generateODTfromHTMLCode($this->params, $HTMLCode, $options);
}
}