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