1<?php 2 3use ComboStrap\AdsUtility; 4use ComboStrap\FsWikiUtility; 5use ComboStrap\XhtmlUtility; 6use ComboStrap\PluginUtility; 7use ComboStrap\TableUtility; 8use ComboStrap\TocUtility; 9 10 11require_once(__DIR__ . '/../ComboStrap/PluginUtility.php'); 12 13 14/** 15 * Class renderer_plugin_combo_renderer 16 * The last two parts ie `combo_renderer` is the id for dokuwiki 17 * The last part should also be equal to the name 18 */ 19class renderer_plugin_combo_renderer extends Doku_Renderer_xhtml 20{ 21 const COMBO_RENDERER_NAME = 'combo_renderer'; 22 23 /** 24 * @var array that hold the position of the parent 25 */ 26 protected $nodeParentPosition = []; 27 28 /** 29 * @var array that hold the current position of an header for a level 30 * $headerNum[level]=position 31 */ 32 protected $header = []; 33 34 /** 35 * @var array that will contains the whole doc but by section 36 */ 37 protected $sections = []; 38 39 /** 40 * @var int the section number 41 */ 42 protected $sectionNumber = 0; 43 44 /** 45 * @var string variable that permits to carry the header text of a previous section 46 */ 47 protected $previousSectionTextHeader = ''; 48 49 50 /** 51 * @var int variable that permits to carry the position of a previous section 52 */ 53 protected $previousNodePosition = 0; 54 55 /** 56 * @var int variable that permits to carry the position of a previous section 57 */ 58 protected $previousNodeLevel = 0; 59 60 /** 61 * @var int variable that permits to carry the number of words 62 */ 63 protected $lineCounter = 0; 64 65 66 function getFormat() 67 { 68 return 'xhtml'; 69 } 70 71 /* 72 * Function that enable to list the plugin in the options for config:renderer_xhtml 73 * http://www.dokuwiki.org/config:renderer_xhtml 74 * setting in its Configuration Manager. 75 */ 76 public function canRender($format) 77 { 78 return ($format == 'xhtml'); 79 } 80 81 82 /** 83 * Render a heading 84 * 85 * The rendering of the heading is done through the parent 86 * The function just: 87 * - save the rendering between each header in the class variable $this->sections 88 * This variblae is used in the function document_end to recreate the whole doc. 89 * - add the numbering to the header text 90 * 91 * @param string $text the text to display 92 * @param int $level header level 93 * @param int $pos byte position in the original source 94 */ 95 function header($text, $level, $pos) 96 { 97 98 /** 99 * Save the H1 even if the heading dokuwiki is not enable 100 */ 101 if (!PluginUtility::getConfValue(syntax_plugin_combo_headingwiki::CONF_WIKI_HEADING_ENABLE)) { 102 /** 103 * $ACT == 'show' 104 * Otherwise we may capture the title of the admin page ... 105 */ 106 global $ACT; 107 if ($ACT == 'show') { 108 syntax_plugin_combo_heading::processHeadingMetadataH1($level, $text); 109 } 110 } 111 112 // We are going from 2 to 3 113 // The parent is 2 114 if ($level > $this->previousNodeLevel) { 115 $nodePosition = 1; 116 // Keep the position of the parent 117 $this->nodeParentPosition[$this->previousNodeLevel] = $this->previousNodePosition; 118 } elseif 119 // We are going from 3 to 2 120 // The parent is 1 121 ($level < $this->previousNodeLevel 122 ) { 123 $nodePosition = $this->nodeParentPosition[$level] + 1; 124 } else { 125 $nodePosition = $this->previousNodePosition + 1; 126 } 127 128 // Grab the doc from the previous section 129 $this->sections[$this->sectionNumber] = array( 130 'level' => $this->previousNodeLevel, 131 'position' => $this->previousNodePosition, 132 'content' => $this->doc, 133 'text' => $this->previousSectionTextHeader); 134 135 // And reset it 136 $this->doc = ''; 137 // Set the looping variable 138 $this->sectionNumber = $this->sectionNumber + 1; 139 $this->previousNodeLevel = $level; 140 $this->previousNodePosition = $nodePosition; 141 $this->previousSectionTextHeader = $text; 142 143 144 /** 145 * Rendering is done by the parent 146 * And should be the last one 147 * Because we delete the heading 148 * with {@link syntax_plugin_combo_heading::reduceToFirstOpeningTagAndReturnAttributes()} 149 * in order to be able to add the toc and section 150 * 151 */ 152 parent::header($text, $level, $pos); 153 154 155 } 156 157 158 function document_end() 159 { 160 161 global $ID; 162 // The id of the page (not of the sidebar) 163 $id = $ID; 164 $isSidebar = FsWikiUtility::isSideBar(); 165 166 167 // Pump the last doc 168 $this->sections[$this->sectionNumber] = array('level' => $this->previousNodeLevel, 'position' => $this->previousNodePosition, 'content' => $this->doc, 'text' => $this->previousSectionTextHeader); 169 170 // Recreate the doc 171 $this->doc = ''; 172 $rollingLineCount = 0; 173 $currentLineCountSinceLastAd = 0; 174 $adsCounter = 0; 175 foreach ($this->sections as $sectionNumber => $section) { 176 177 $sectionContent = $section['content']; 178 179 180 if ($section['level'] == 1 and $section['position'] == 1) { 181 182 // Add the hierarchical breadcrumb detail after the first header 183 global $conf; 184 185 // Deprecated 186 // As the main slot is read before the main header and footer 187 // there is no way to known at the end if it was used 188 // 189 // 190 // if ($conf['youarehere']) { 191 // $sectionContent .= syntax_plugin_combo_breadcrumb::toBreadCrumbHtml(); 192 // } 193 194 if (TocUtility::showToc($this)) { 195 $sectionContent .= TocUtility::renderToc($this); 196 } 197 198 } 199 200 # Split by element line 201 # element p, h, br, tr, li, pre (one line for pre) 202 $sectionLineCount = XhtmlUtility::countLines($sectionContent); 203 $currentLineCountSinceLastAd += $sectionLineCount; 204 $rollingLineCount += $sectionLineCount; 205 206 // The content 207 if ($this->getConf('ShowCount') == 1 && $isSidebar == FALSE) { 208 $this->doc .= "<p>Section " . $sectionNumber . ": (" . $sectionLineCount . "|" . $currentLineCountSinceLastAd . "|" . $rollingLineCount . ")</p>"; 209 } 210 $this->doc .= $sectionContent; 211 212 // No ads on private page 213 214 215 $isLastSection = $sectionNumber === count($this->sections) - 1; 216 if (AdsUtility::showAds( 217 $sectionLineCount, 218 $currentLineCountSinceLastAd, 219 $sectionNumber, 220 $adsCounter, 221 $isLastSection 222 )) { 223 224 225 // Counter 226 $adsCounter += 1; 227 $currentLineCountSinceLastAd = 0; 228 229 $attributes = array("name" => AdsUtility::PREFIX_IN_ARTICLE_ADS . $adsCounter); 230 $this->doc .= AdsUtility::render($attributes); 231 232 233 } 234 235 236 } 237 238 parent::document_end(); 239 240 } 241 242 /** 243 * Start a table 244 * 245 * @param int $maxcols maximum number of columns 246 * @param int $numrows NOT IMPLEMENTED 247 * @param int $pos byte position in the original source 248 * @param string|string[] classes - have to be valid, do not pass unfiltered user input 249 */ 250 function table_open($maxcols = null, $numrows = null, $pos = null, $classes = NULL) 251 { 252 // initialize the row counter used for classes 253 $this->_counter['row_counter'] = 0; 254 TableUtility::tableOpen($this, $pos); 255 } 256 257 258} 259