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