1<?php 2/** 3 * ODT Paragraph handling. 4 * 5 * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) 6 * @author LarsDW223 7 * @package ODT\Paragraph 8 */ 9 10/** Include ODTDocument */ 11require_once DOKU_PLUGIN . 'odt/ODT/ODTDocument.php'; 12 13/** 14 * ODTParagraph: 15 * Class containing static code for handling paragraphs. 16 * 17 * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) 18 */ 19class ODTParagraph 20{ 21 /** 22 * Open a paragraph 23 * 24 * @param ODTInternalParams $params Commom params. 25 * @param string|null $styleName The style to use. 26 * @param string $element The element name, e.g. "div" 27 * @param string $attributes The attributes belonging o the element, e.g. 'class="example"' 28 */ 29 public static function paragraphOpen(ODTInternalParams $params, $styleName=NULL, $element=NULL, $attributes=NULL){ 30 if (!isset($element)) { 31 $element = 'p'; 32 } 33 if ( empty($styleName) ) { 34 $styleName = $params->document->getStyleName('body'); 35 } 36 37 $list = NULL; 38 $listItem = $params->document->state->getCurrentListItem(); 39 if (isset($listItem)) { 40 // We are in a list item. Is this the list start? 41 $list = $listItem->getList(); 42 if (isset($list)) { 43 // Get list count and Flag if this is the first paragraph in the list 44 $listCount = $params->document->state->countClass('list'); 45 $isFirst = $list->getListFirstParagraph(); 46 $list->setListFirstParagraph(false); 47 48 // Create a style for putting a top margin for this first paragraph of the list 49 // (if not done yet, the name must be unique!) 50 if ($listCount == 1 && $isFirst) { 51 // If we have a standard list content paragraph style then we use the 52 // corresponding always existing first and last default styles 53 if ($styleName == $params->document->getStyleName('list content')) { 54 $styleName = $params->document->getStyleName('list first'); 55 } else if ($styleName == $params->document->getStyleName('numbering content')) { 56 $styleName = $params->document->getStyleName('numbering first'); 57 } else { 58 // No standard list paragraph style. 59 // Has a clone for the first paragraph's style already been created... 60 $styleNameFirst = 'FirstListParagraph_'.$styleName; 61 if (!$params->document->styleExists($styleNameFirst)) { 62 63 // ...no, create style as copy of style 'list first' or 'numbering first' 64 if ($list->getStyleName() == $params->document->getStyleName('list')) { 65 $styleFirstTemplate = $params->document->getStyleByAlias('list first'); 66 } else { 67 $styleFirstTemplate = $params->document->getStyleByAlias('numbering first'); 68 } 69 if (isset($styleFirstTemplate)) { 70 $styleBody = $params->document->getStyle($styleName); 71 $styleDisplayName = 'First '.$styleBody->getProperty('style-display-name'); 72 $styleObj = clone $styleFirstTemplate; 73 if (isset($styleObj)) { 74 $styleObj->setProperty('style-name', $styleNameFirst); 75 $styleObj->setProperty('style-parent', $styleName); 76 $styleObj->setProperty('style-display-name', $styleDisplayName); 77 $bottom = $styleFirstTemplate->getProperty('margin-bottom'); 78 if (!isset($bottom)) { 79 $styleObj->setProperty('margin-bottom', $styleBody->getProperty('margin-bottom')); 80 } 81 $params->document->addStyle($styleObj); 82 $styleName = $styleNameFirst; 83 } 84 } 85 } else { 86 // ...yes, just use the name 87 $styleName = $styleNameFirst; 88 } 89 } 90 } 91 } 92 } 93 94 // Opening a paragraph inside another paragraph is illegal 95 $inParagraph = $params->document->state->getInParagraph(); 96 if (!$inParagraph) { 97 if ( $params->document->pageFormatChangeIsPending() ) { 98 $pageStyle = $params->document->doPageFormatChange($styleName); 99 if ( isset($pageStyle) ) { 100 $styleName = $pageStyle; 101 // Delete pagebreak, the format change will also introduce a pagebreak. 102 $params->document->setPagebreakPending(false); 103 } 104 } 105 if ( $params->document->pagebreakIsPending() ) { 106 $styleName = $params->document->createPagebreakStyle ($styleName); 107 $params->document->setPagebreakPending(false); 108 } 109 110 // If we are in a list remember paragraph position 111 if (isset($list)) { 112 $list->setListLastParagraphPosition(strlen($params->content)); 113 } 114 115 if (!isset($params->elementObj)) { 116 $properties = array(); 117 ODTUtility::openHTMLElement ($params, $properties, $element, $attributes); 118 } 119 120 $paragraph = new ODTElementParagraph($styleName); 121 $params->document->state->enter($paragraph); 122 $params->content .= $paragraph->getOpeningTag(); 123 $paragraph->setHTMLElement ($element); 124 } 125 } 126 127 /** 128 * Close a paragraph. 129 * 130 * @param ODTInternalParams $params Commom params. 131 */ 132 public static function paragraphClose(ODTInternalParams $params){ 133 $paragraph = $params->document->state->getCurrentParagraph(); 134 if (isset($paragraph)) { 135 ODTUtility::closeHTMLElement ($params, $paragraph->getHTMLElement()); 136 $params->content .= $paragraph->getClosingTag(); 137 $params->document->state->leave(); 138 } 139 } 140 141 /** 142 * This function opens a new paragraph using the style as set in the imported CSS $import. 143 * So, the function requires the helper class 'helper_plugin_odt_cssimport'. 144 * The CSS style is selected by the element type 'p' and the specified classes in $classes. 145 * The property 'background-image' is emulated by inserting an image manually in the paragraph. 146 * If the url from the CSS should be converted to a local path, then the caller can specify a $baseURL. 147 * The full path will then be $baseURL/background-image. 148 * 149 * This function calls _odtParagraphOpenUseProperties. See the function description for supported properties. 150 * 151 * The span should be closed by calling '_odtParagraphClose'. 152 * 153 * @author LarsDW223 154 * @param ODTInternalParams $params Commom params. 155 * @param string $element The element name, e.g. "div" 156 * @param string $attributes The attributes belonging o the element, e.g. 'class="example"' 157 */ 158 public static function paragraphOpenUseCSS(ODTInternalParams $params, $element=NULL, $attributes=NULL){ 159 $inParagraph = $params->document->state->getInParagraph(); 160 if ($inParagraph) { 161 return; 162 } 163 164 $properties = array(); 165 ODTUtility::openHTMLElement ($params, $properties, $element, $attributes); 166 $params->elementObj = $params->htmlStack->getCurrentElement(); 167 168 self::paragraphOpenUseProperties($params, $properties); 169 } 170 171 /** 172 * This function opens a new paragraph using the style as set in the assoziative array $properties. 173 * The parameters in the array should be named as the CSS property names e.g. 'color' or 'background-color'. 174 * The property 'background-image' is emulated by inserting an image manually in the paragraph. 175 * 176 * The currently supported properties are: 177 * background-color, color, font-style, font-weight, font-size, border, font-family, font-variant, letter-spacing, 178 * vertical-align, line-height, background-image (emulated) 179 * 180 * The paragraph must be closed by calling 'p_close'. 181 * 182 * @author LarsDW223 183 * 184 * @param ODTInternalParams $params Commom params. 185 * @param array $properties Properties to use. 186 */ 187 public static function paragraphOpenUseProperties(ODTInternalParams $params, $properties){ 188 $inParagraph = $params->document->state->getInParagraph(); 189 if ($inParagraph) { 190 return; 191 } 192 $disabled = array (); 193 194 $in_paragraph = $params->document->state->getInParagraph(); 195 if ($in_paragraph) { 196 // opening a paragraph inside another paragraph is illegal 197 return; 198 } 199 200 $odt_bg = $properties ['background-color']; 201 $picture = $properties ['background-image']; 202 203 if ( !empty ($picture) ) { 204 // If a picture/background-image is set, than we insert it manually here. 205 // This is a workaround because ODT background-image works different than in CSS. 206 207 // Define graphic style for picture 208 $style_name = ODTStyle::getNewStylename('span_graphic'); 209 $image_style = '<style:style style:name="'.$style_name.'" style:family="graphic" style:parent-style-name="'.$params->document->getStyleName('graphics').'"><style:graphic-properties style:vertical-pos="middle" style:vertical-rel="text" style:horizontal-pos="from-left" style:horizontal-rel="paragraph" fo:background-color="'.$odt_bg.'" style:flow-with-text="true"></style:graphic-properties></style:style>'; 210 211 // Add style and image to our document 212 // (as unknown style because style-family graphic is not supported) 213 $style_obj = ODTUnknownStyle::importODTStyle($image_style); 214 $params->document->addAutomaticStyle($style_obj); 215 ODTImage::addImage ($params, $picture, NULL, NULL, NULL, NULL, $style_name); 216 } 217 218 // Create the style for the paragraph. 219 //$disabled ['background-image'] = 1; 220 //FIXME: pass $disabled 221 $style_obj = ODTParagraphStyle::createParagraphStyle ($properties); 222 $params->document->addAutomaticStyle($style_obj); 223 $style_name = $style_obj->getProperty('style-name'); 224 225 // Open a paragraph 226 self::paragraphOpen($params, $style_name); 227 } 228} 229