xref: /plugin/combo/renderer/renderer.php (revision 21913ab3235d516e2fa19c7e3929b555b3a2bda1)
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