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