1007225e5Sgerardnico<?php 2007225e5Sgerardnico 3007225e5Sgerardnicouse ComboStrap\AdsUtility; 4007225e5Sgerardnicouse ComboStrap\BreadcrumbHierarchical; 5007225e5Sgerardnicouse ComboStrap\HtmlUtility; 6007225e5Sgerardnicouse ComboStrap\FsWikiUtility; 7007225e5Sgerardnicouse ComboStrap\TableUtility; 8007225e5Sgerardnicouse ComboStrap\TocUtility; 9007225e5Sgerardnico 10007225e5Sgerardnico 11007225e5Sgerardnicorequire_once(__DIR__ . '/../class/FsWikiUtility.php'); 12007225e5Sgerardnicorequire_once(__DIR__ . '/../class/TableUtility.php'); 13007225e5Sgerardnicorequire_once(__DIR__ . '/../class/TocUtility.php'); 14007225e5Sgerardnicorequire_once(__DIR__ . '/../class/AdsUtility.php'); 15007225e5Sgerardnicorequire_once(__DIR__ . '/../class/HtmlUtility.php'); 16007225e5Sgerardnicorequire_once(__DIR__ . '/../class/BreadcrumbHierarchical.php'); 17007225e5Sgerardnico 18007225e5Sgerardnico/** 19007225e5Sgerardnico * Class renderer_plugin_combo_renderer 20007225e5Sgerardnico * The last two parts ie `combo_renderer` is the id for dokuwiki 21007225e5Sgerardnico * The last part should also be equal to the name 22007225e5Sgerardnico */ 23007225e5Sgerardnicoclass renderer_plugin_combo_renderer extends Doku_Renderer_xhtml 24007225e5Sgerardnico{ 25007225e5Sgerardnico const COMBO_RENDERER_NAME = 'combo_renderer'; 26007225e5Sgerardnico 27007225e5Sgerardnico /** 28007225e5Sgerardnico * @var array that hold the position of the parent 29007225e5Sgerardnico */ 30007225e5Sgerardnico protected $nodeParentPosition = []; 31007225e5Sgerardnico 32007225e5Sgerardnico /** 33007225e5Sgerardnico * @var array that hold the current position of an header for a level 34007225e5Sgerardnico * $headerNum[level]=position 35007225e5Sgerardnico */ 36007225e5Sgerardnico protected $header = []; 37007225e5Sgerardnico 38007225e5Sgerardnico /** 39007225e5Sgerardnico * @var array that will contains the whole doc but by section 40007225e5Sgerardnico */ 41007225e5Sgerardnico protected $sections = []; 42007225e5Sgerardnico 43007225e5Sgerardnico /** 44007225e5Sgerardnico * @var int the section number 45007225e5Sgerardnico */ 46007225e5Sgerardnico protected $sectionNumber = 0; 47007225e5Sgerardnico 48007225e5Sgerardnico /** 49007225e5Sgerardnico * @var string variable that permits to carry the header text of a previous section 50007225e5Sgerardnico */ 51007225e5Sgerardnico protected $previousSectionTextHeader = ''; 52007225e5Sgerardnico 53007225e5Sgerardnico 54007225e5Sgerardnico /** 55007225e5Sgerardnico * @var int variable that permits to carry the position of a previous section 56007225e5Sgerardnico */ 57007225e5Sgerardnico protected $previousNodePosition = 0; 58007225e5Sgerardnico 59007225e5Sgerardnico /** 60007225e5Sgerardnico * @var int variable that permits to carry the position of a previous section 61007225e5Sgerardnico */ 62007225e5Sgerardnico protected $previousNodeLevel = 0; 63007225e5Sgerardnico 64007225e5Sgerardnico /** 65007225e5Sgerardnico * @var int variable that permits to carry the number of words 66007225e5Sgerardnico */ 67007225e5Sgerardnico protected $lineCounter = 0; 68007225e5Sgerardnico 69007225e5Sgerardnico 70007225e5Sgerardnico function getFormat() 71007225e5Sgerardnico { 72007225e5Sgerardnico return 'xhtml'; 73007225e5Sgerardnico } 74007225e5Sgerardnico 75007225e5Sgerardnico /* 76007225e5Sgerardnico * Function that enable to list the plugin in the options for config:renderer_xhtml 77007225e5Sgerardnico * http://www.dokuwiki.org/config:renderer_xhtml 78007225e5Sgerardnico * setting in its Configuration Manager. 79007225e5Sgerardnico */ 80007225e5Sgerardnico public function canRender($format) 81007225e5Sgerardnico { 82007225e5Sgerardnico return ($format == 'xhtml'); 83007225e5Sgerardnico } 84007225e5Sgerardnico 85007225e5Sgerardnico 86007225e5Sgerardnico /** 87007225e5Sgerardnico * Render a heading 88007225e5Sgerardnico * 89007225e5Sgerardnico * The rendering of the heading is done through the parent 90007225e5Sgerardnico * The function just: 91007225e5Sgerardnico * - save the rendering between each header in the class variable $this->sections 92007225e5Sgerardnico * This variblae is used in the function document_end to recreate the whole doc. 93007225e5Sgerardnico * - add the numbering to the header text 94007225e5Sgerardnico * 95007225e5Sgerardnico * @param string $text the text to display 96007225e5Sgerardnico * @param int $level header level 97007225e5Sgerardnico * @param int $pos byte position in the original source 98007225e5Sgerardnico */ 99007225e5Sgerardnico function header($text, $level, $pos) 100007225e5Sgerardnico { 101007225e5Sgerardnico 102e06795b8Sgerardnico /** 103e06795b8Sgerardnico * Capture the h1 104e06795b8Sgerardnico */ 105e06795b8Sgerardnico if ($level == 1) { 1061c5862d3Sgerardnico /** 1071c5862d3Sgerardnico * $ACT == 'show' 1081c5862d3Sgerardnico * Otherwise we get the title of the admin page ... 1091c5862d3Sgerardnico */ 1101c5862d3Sgerardnico global $ACT; 1111c5862d3Sgerardnico if ($ACT == 'show') { 112e06795b8Sgerardnico global $ID; 113e06795b8Sgerardnico p_set_metadata($ID, array("h1" => $text)); 114e06795b8Sgerardnico } 1151c5862d3Sgerardnico } 116007225e5Sgerardnico 117007225e5Sgerardnico // We are going from 2 to 3 118007225e5Sgerardnico // The parent is 2 119007225e5Sgerardnico if ($level > $this->previousNodeLevel) { 120007225e5Sgerardnico $nodePosition = 1; 121007225e5Sgerardnico // Keep the position of the parent 122007225e5Sgerardnico $this->nodeParentPosition[$this->previousNodeLevel] = $this->previousNodePosition; 123007225e5Sgerardnico } elseif 124007225e5Sgerardnico // We are going from 3 to 2 125007225e5Sgerardnico // The parent is 1 126007225e5Sgerardnico ($level < $this->previousNodeLevel 127007225e5Sgerardnico ) { 128007225e5Sgerardnico $nodePosition = $this->nodeParentPosition[$level] + 1; 129007225e5Sgerardnico } else { 130007225e5Sgerardnico $nodePosition = $this->previousNodePosition + 1; 131007225e5Sgerardnico } 132007225e5Sgerardnico 133007225e5Sgerardnico // Grab the doc from the previous section 134007225e5Sgerardnico $this->sections[$this->sectionNumber] = array( 135007225e5Sgerardnico 'level' => $this->previousNodeLevel, 136007225e5Sgerardnico 'position' => $this->previousNodePosition, 137007225e5Sgerardnico 'content' => $this->doc, 138007225e5Sgerardnico 'text' => $this->previousSectionTextHeader); 139007225e5Sgerardnico 140007225e5Sgerardnico // And reset it 141007225e5Sgerardnico $this->doc = ''; 142007225e5Sgerardnico // Set the looping variable 143007225e5Sgerardnico $this->sectionNumber = $this->sectionNumber + 1; 144007225e5Sgerardnico $this->previousNodeLevel = $level; 145007225e5Sgerardnico $this->previousNodePosition = $nodePosition; 146007225e5Sgerardnico $this->previousSectionTextHeader = $text; 147007225e5Sgerardnico 148*21913ab3SNickeau /** 149*21913ab3SNickeau * TODO: replace with CSS styling 150*21913ab3SNickeau * https://datacadamia.com/web/css/content#heading_numbering 151*21913ab3SNickeau */ 152007225e5Sgerardnico $numbering = ""; 153007225e5Sgerardnico if ($level == 2) { 154007225e5Sgerardnico $numbering = $nodePosition; 155007225e5Sgerardnico } 156007225e5Sgerardnico if ($level == 3) { 157007225e5Sgerardnico $numbering = $this->nodeParentPosition[$level - 1] . "." . $nodePosition; 158007225e5Sgerardnico } 159007225e5Sgerardnico if ($level == 4) { 160007225e5Sgerardnico $numbering = $this->nodeParentPosition[$level - 2] . "." . $this->nodeParentPosition[$level - 1] . "." . $nodePosition; 161007225e5Sgerardnico } 162007225e5Sgerardnico if ($level == 5) { 163007225e5Sgerardnico $numbering = $this->nodeParentPosition[$level - 3] . "." . $this->nodeParentPosition[$level - 2] . "." . $this->nodeParentPosition[$level - 1] . "." . $nodePosition; 164007225e5Sgerardnico } 165007225e5Sgerardnico if ($numbering <> "") { 166007225e5Sgerardnico $textWithLocalization = $numbering . " - " . $text; 167007225e5Sgerardnico } else { 168007225e5Sgerardnico $textWithLocalization = $text; 169007225e5Sgerardnico } 170007225e5Sgerardnico 171007225e5Sgerardnico // Rendering is done by the parent 172007225e5Sgerardnico parent::header($textWithLocalization, $level, $pos); 173007225e5Sgerardnico 174007225e5Sgerardnico 175007225e5Sgerardnico // Add the page detail after the first header 176007225e5Sgerardnico if ($level == 1 and $nodePosition == 1) { 177007225e5Sgerardnico 178007225e5Sgerardnico $this->doc .= BreadcrumbHierarchical::render(); 179007225e5Sgerardnico 180007225e5Sgerardnico } 181007225e5Sgerardnico 182007225e5Sgerardnico 183007225e5Sgerardnico } 184007225e5Sgerardnico 185007225e5Sgerardnico 186007225e5Sgerardnico function document_end() 187007225e5Sgerardnico { 188007225e5Sgerardnico 189007225e5Sgerardnico global $ID; 190007225e5Sgerardnico // The id of the page (not of the sidebar) 191007225e5Sgerardnico $id = $ID; 192007225e5Sgerardnico $isSidebar = FsWikiUtility::isSideBar(); 193007225e5Sgerardnico 194007225e5Sgerardnico 195007225e5Sgerardnico // Pump the last doc 196007225e5Sgerardnico $this->sections[$this->sectionNumber] = array('level' => $this->previousNodeLevel, 'position' => $this->previousNodePosition, 'content' => $this->doc, 'text' => $this->previousSectionTextHeader); 197007225e5Sgerardnico 198007225e5Sgerardnico // Recreate the doc 199007225e5Sgerardnico $this->doc = ''; 200007225e5Sgerardnico $rollingLineCount = 0; 201007225e5Sgerardnico $currentLineCountSinceLastAd = 0; 202007225e5Sgerardnico $adsCounter = 0; 203007225e5Sgerardnico foreach ($this->sections as $sectionNumber => $section) { 204007225e5Sgerardnico 205007225e5Sgerardnico $sectionContent = $section['content']; 206007225e5Sgerardnico 207007225e5Sgerardnico 208007225e5Sgerardnico if ($section['level'] == 1 and $section['position'] == 1) { 209007225e5Sgerardnico 210007225e5Sgerardnico if (TocUtility::showToc($this)) { 211007225e5Sgerardnico $sectionContent .= TocUtility::renderToc($this); 212007225e5Sgerardnico } 213007225e5Sgerardnico 214007225e5Sgerardnico } 215007225e5Sgerardnico 216007225e5Sgerardnico # Split by element line 217007225e5Sgerardnico # element p, h, br, tr, li, pre (one line for pre) 218007225e5Sgerardnico $sectionLineCount = HtmlUtility::countLines($sectionContent); 219007225e5Sgerardnico $currentLineCountSinceLastAd += $sectionLineCount; 220007225e5Sgerardnico $rollingLineCount += $sectionLineCount; 221007225e5Sgerardnico 222007225e5Sgerardnico // The content 223007225e5Sgerardnico if ($this->getConf('ShowCount') == 1 && $isSidebar == FALSE) { 224007225e5Sgerardnico $this->doc .= "<p>Section " . $sectionNumber . ": (" . $sectionLineCount . "|" . $currentLineCountSinceLastAd . "|" . $rollingLineCount . ")</p>"; 225007225e5Sgerardnico } 226007225e5Sgerardnico $this->doc .= $sectionContent; 227007225e5Sgerardnico 228007225e5Sgerardnico // No ads on private page 229007225e5Sgerardnico 230007225e5Sgerardnico 231007225e5Sgerardnico $isLastSection = $sectionNumber === count($this->sections) - 1; 232007225e5Sgerardnico if (AdsUtility::showAds( 233007225e5Sgerardnico $sectionLineCount, 234007225e5Sgerardnico $currentLineCountSinceLastAd, 235007225e5Sgerardnico $sectionNumber, 236007225e5Sgerardnico $adsCounter, 237007225e5Sgerardnico $isLastSection 238007225e5Sgerardnico )) { 239007225e5Sgerardnico 240007225e5Sgerardnico 241007225e5Sgerardnico // Counter 242007225e5Sgerardnico $adsCounter += 1; 243007225e5Sgerardnico $currentLineCountSinceLastAd = 0; 244007225e5Sgerardnico 245007225e5Sgerardnico $attributes = array("name" => AdsUtility::PREFIX_IN_ARTICLE_ADS . $adsCounter); 246007225e5Sgerardnico $this->doc .= AdsUtility::render($attributes); 247007225e5Sgerardnico 248007225e5Sgerardnico 249007225e5Sgerardnico } 250007225e5Sgerardnico 251007225e5Sgerardnico 252007225e5Sgerardnico } 253007225e5Sgerardnico 254007225e5Sgerardnico parent::document_end(); 255007225e5Sgerardnico 256007225e5Sgerardnico } 257007225e5Sgerardnico 258007225e5Sgerardnico /** 259007225e5Sgerardnico * Start a table 260007225e5Sgerardnico * 261007225e5Sgerardnico * @param int $maxcols maximum number of columns 262007225e5Sgerardnico * @param int $numrows NOT IMPLEMENTED 263007225e5Sgerardnico * @param int $pos byte position in the original source 264007225e5Sgerardnico * @param string|string[] classes - have to be valid, do not pass unfiltered user input 265007225e5Sgerardnico */ 266007225e5Sgerardnico function table_open($maxcols = null, $numrows = null, $pos = null, $classes = NULL) 267007225e5Sgerardnico { 268007225e5Sgerardnico // initialize the row counter used for classes 269007225e5Sgerardnico $this->_counter['row_counter'] = 0; 270007225e5Sgerardnico TableUtility::tableOpen($this, $pos); 271007225e5Sgerardnico } 272007225e5Sgerardnico 273007225e5Sgerardnico /** 274007225e5Sgerardnico * https://getbootstrap.com/docs/4.4/content/typography/#inline-text-elements 275007225e5Sgerardnico */ 276007225e5Sgerardnico public 277007225e5Sgerardnico function monospace_open() 278007225e5Sgerardnico { 279007225e5Sgerardnico $this->doc .= '<mark>'; 280007225e5Sgerardnico } 281007225e5Sgerardnico 282007225e5Sgerardnico public 283007225e5Sgerardnico function monospace_close() 284007225e5Sgerardnico { 285007225e5Sgerardnico $this->doc .= '</mark>'; 286007225e5Sgerardnico } 287007225e5Sgerardnico 288007225e5Sgerardnico 289007225e5Sgerardnico} 290