xref: /plugin/siteexport/syntax/toc.php (revision 5c17558972eca0c7ff1a5d3f69d6f06de8ebee6e)
17d101cc1SGerry Weißbach<?php
27d101cc1SGerry Weißbach/**
37d101cc1SGerry Weißbach * Search with Scopes
47d101cc1SGerry Weißbach *
57d101cc1SGerry Weißbach * @license    GPL 2 (http://www.gnu.org/licenses/gpl.html)
67d101cc1SGerry Weißbach * @author     i-net software <tools@inetsoftware.de>
77d101cc1SGerry Weißbach * @author     Gerry Weissbach <gweissbach@inetsoftware.de>
87d101cc1SGerry Weißbach */
97d101cc1SGerry Weißbach
107d101cc1SGerry Weißbach// must be run within Dokuwiki
117d101cc1SGerry Weißbachif (!defined('DOKU_INC')) die();
127d101cc1SGerry Weißbachif (!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN', DOKU_INC . 'lib/plugins/');
137d101cc1SGerry Weißbach
148be94324SGerry Weißbachuse dokuwiki\File\PageResolver;
157d101cc1SGerry Weißbach
167d101cc1SGerry Weißbachclass syntax_plugin_siteexport_toc extends DokuWiki_Syntax_Plugin {
177d101cc1SGerry Weißbach
18d98cce67SGerry Weißbach    private $insideToc = false;
19d98cce67SGerry Weißbach    private $savedToc = array();
20d98cce67SGerry Weißbach    private $options = array();
217d101cc1SGerry Weißbach
22d98cce67SGerry Weißbach    private $mergedPages = array();
23d98cce67SGerry Weißbach    private $includedPages = array();
24300ce4a2SGerry Weißbach    private $merghintIds = array();
25d3a16081SGerry Weißbach    private $mergeHints = array();
267d101cc1SGerry Weißbach
27a8c17ab5Si-net /// software    public function getType() { return 'protected'; }
28a8c17ab5Si-net /// software    public function getPType() { return 'block'; }
29a8c17ab5Si-net /// software    public function getAllowedTypes() { return array('container'); }
30a8c17ab5Si-net /// software    public function getSort() { return 100; }
317d101cc1SGerry Weißbach
327d101cc1SGerry Weißbach    /**
337d101cc1SGerry Weißbach     * Connect pattern to lexer
347d101cc1SGerry Weißbach     */
35a8c17ab5Si-net /// software    public function connectTo($mode) {
367d101cc1SGerry Weißbach        $this->Lexer->addEntryPattern('<toc>(?=.*?</toc>)', $mode, 'plugin_siteexport_toc');
377d101cc1SGerry Weißbach        $this->Lexer->addEntryPattern('<toc .+?>(?=.*?</toc>)', $mode, 'plugin_siteexport_toc');
387d101cc1SGerry Weißbach        $this->Lexer->addSpecialPattern("\[\[.+?\]\]", $mode, 'plugin_siteexport_toc');
397d101cc1SGerry Weißbach    }
407d101cc1SGerry Weißbach
41a8c17ab5Si-net /// software    public function postConnect() {
427d101cc1SGerry Weißbach        $this->Lexer->addExitPattern('</toc.*?>', 'plugin_siteexport_toc');
437d101cc1SGerry Weißbach    }
447d101cc1SGerry Weißbach
45a8c17ab5Si-net /// software    public function handle($match, $state, $pos, Doku_Handler $handler) {
467d101cc1SGerry Weißbach        global $ID, $INFO;
477d101cc1SGerry Weißbach
487d101cc1SGerry Weißbach        switch ($state) {
497d101cc1SGerry Weißbach            case DOKU_LEXER_ENTER:
507d101cc1SGerry Weißbach
517d101cc1SGerry Weißbach                $this->insideToc = true;
52a8c17ab5Si-net /// software                $this->options = explode(' ', substr($match, 5, -1)?:"");
535321bc23SGerry Weißbach                return array('start' => true, 'pos' => $pos, 'options' => $this->options);
547d101cc1SGerry Weißbach
557d101cc1SGerry Weißbach            case DOKU_LEXER_SPECIAL:
567d101cc1SGerry Weißbach
577d101cc1SGerry Weißbach                if ($this->insideToc) {
587d101cc1SGerry Weißbach
597d101cc1SGerry Weißbach                    $link = preg_replace(array('/^\[\[/', '/\]\]$/u'), '', $match);
607d101cc1SGerry Weißbach                    // Split title from URL
617d101cc1SGerry Weißbach                    $link = explode('|', $link, 2);
627d101cc1SGerry Weißbach                    if (!isset($link[1])) {
637d101cc1SGerry Weißbach                        $link[1] = NULL;
647d101cc1SGerry Weißbach                    } else if (preg_match('/^\{\{[^\}]+\}\}$/', $link[1])) {
657d101cc1SGerry Weißbach                        // If the title is an image, convert it to an array containing the image details
667d101cc1SGerry Weißbach                        $link[1] = Doku_Handler_Parse_Media($link[1]);
677d101cc1SGerry Weißbach                    }
687d101cc1SGerry Weißbach                    $link[0] = trim($link[0]);
697d101cc1SGerry Weißbach
707d101cc1SGerry Weißbach                    if (!(preg_match('/^[a-zA-Z0-9\.]+>{1}.*$/u', $link[0]) ||
717d101cc1SGerry Weißbach                    preg_match('/^\\\\\\\\[\w.:?\-;,]+?\\\\/u', $link[0]) ||
727d101cc1SGerry Weißbach                    preg_match('#^([a-z0-9\-\.+]+?)://#i', $link[0]) ||
737d101cc1SGerry Weißbach                    preg_match('<' . PREG_PATTERN_VALID_EMAIL . '>', $link[0]) ||
747d101cc1SGerry Weißbach                    preg_match('!^#.+!', $link[0]))
757d101cc1SGerry Weißbach                    ) {
767d101cc1SGerry Weißbach
777d101cc1SGerry Weißbach                        // Get current depth from call stack
787d101cc1SGerry Weißbach                        $depth = 1;
797e363a4eSGerry Weißbach                        if ( isset( $handler->CallWriter ) && $handler->CallWriter instanceof Doku_Handler_List ) {
807d101cc1SGerry Weißbach
817d101cc1SGerry Weißbach                            $calls = array_reverse($handler->CallWriter->calls);
827d101cc1SGerry Weißbach                            $call = $calls[0];
837d101cc1SGerry Weißbach                            foreach ($calls as $item) {
847d101cc1SGerry Weißbach                                if (in_array($item[0], array('list_item', 'list_open'))) { $call = $item; break; }
857d101cc1SGerry Weißbach                            }
867d101cc1SGerry Weißbach
871c5b71a7Si-net /// software                            $listType = null;
881c5b71a7Si-net /// software                            $depth = $handler->CallWriter->interpretSyntax($call[1][0], $listType)-1; // Minus one because of plus one inside the interpret function
897d101cc1SGerry Weißbach                        }
907d101cc1SGerry Weißbach
917d101cc1SGerry Weißbach                        if (empty($link[0])) { break; } // No empty elements. This would lead to problems
927d101cc1SGerry Weißbach                        return array($link[0], $link[1], $depth);
937d101cc1SGerry Weißbach                    } else {
947d101cc1SGerry Weißbach                        // use parser! - but with another p
957d101cc1SGerry Weißbach                        $handler->internallink($match, $state, $pos);
967d101cc1SGerry Weißbach                    }
977d101cc1SGerry Weißbach                } else {
987d101cc1SGerry Weißbach                    // use parser!
997d101cc1SGerry Weißbach                    $handler->internallink($match, $state, $pos);
1007d101cc1SGerry Weißbach                }
1017d101cc1SGerry Weißbach
1027d101cc1SGerry Weißbach                return false;
1037d101cc1SGerry Weißbach            case DOKU_LEXER_UNMATCHED:
1047d101cc1SGerry Weißbach
1058be94324SGerry Weißbach                $handler->addCall('cdata', array($match), $pos);
1065321bc23SGerry Weißbach
1077d101cc1SGerry Weißbach                return false;
1087d101cc1SGerry Weißbach            case DOKU_LEXER_EXIT:
1097d101cc1SGerry Weißbach
1107d101cc1SGerry Weißbach                $this->insideToc = false;
1117d101cc1SGerry Weißbach                return 'save__meta';
1127d101cc1SGerry Weißbach        }
1137d101cc1SGerry Weißbach        return false;
1147d101cc1SGerry Weißbach    }
1157d101cc1SGerry Weißbach
116a8c17ab5Si-net /// software    public function render($mode, Doku_Renderer $renderer, $data) {
1177d101cc1SGerry Weißbach        global $ID, $lang, $INFO;
1187d101cc1SGerry Weißbach
1197d101cc1SGerry Weißbach        list($SID, $NAME, $DEPTH) = $data;
1207d101cc1SGerry Weißbach
1213354083fSGerry Weißbach        $exists = page_exists( (new PageResolver( $ID ))->resolveId($SID) );
1228be94324SGerry Weißbach
1234d9989ecSGerry Weißbach//        $SID = cleanID($SID); // hier kein cleanID, da sonst moeglicherweise der anker verloren geht
1247d101cc1SGerry Weißbach
1257d101cc1SGerry Weißbach        //    Render XHTML and ODT
1261508dbfeSGerry Weißbach        if ($mode != 'metadata' ) {
1277d101cc1SGerry Weißbach
1287d101cc1SGerry Weißbach            // TOC Title
129d04831eaSGerry Weißbach            if (is_array($data) && $data['start'] == true) {
1307d101cc1SGerry Weißbach
1317d101cc1SGerry Weißbach                if (is_Array($data['options'])) {
1327d101cc1SGerry Weißbach                    foreach ($data['options'] as $opt) {
1337d101cc1SGerry Weißbach                        switch ($opt) {
1347d101cc1SGerry Weißbach                            case 'description' : $renderer->meta['sitetoc']['showDescription'] = true; break;
1357d101cc1SGerry Weißbach                            case 'notoc' : $renderer->meta['sitetoc']['noTOC'] = true; break;
1367d101cc1SGerry Weißbach                            case 'merge' : $renderer->meta['sitetoc']['mergeDoc'] = true; break;
1377d101cc1SGerry Weißbach                            case 'nohead' : $renderer->meta['sitetoc']['noTocHeader'] = true; break;
1385321bc23SGerry Weißbach                            case 'mergeheader' : $renderer->meta['sitetoc']['mergeHeader'] = true; break;
13922a479aeSGerry Weißbach                            case 'pagebreak' : $renderer->meta['sitetoc']['pagebreak'] = true; break;
140a310139eSGerry Weißbach                            case 'mergehint' : $renderer->meta['sitetoc']['mergehint'] = true; break;
1417d101cc1SGerry Weißbach                        }
1427d101cc1SGerry Weißbach                    }
1437d101cc1SGerry Weißbach                }
1447d101cc1SGerry Weißbach
1457d101cc1SGerry Weißbach                $renderer->section_open("1 sitetoc");
1467d101cc1SGerry Weißbach                if ($renderer->meta['sitetoc']['noTocHeader'] === false) {
1477d101cc1SGerry Weißbach                    $renderer->header($lang['toc'], 1, $data['pos']);
1487d101cc1SGerry Weißbach                }
1497d101cc1SGerry Weißbach
1507d101cc1SGerry Weißbach                return true;
151d04831eaSGerry Weißbach            } else
1527d101cc1SGerry Weißbach
1537d101cc1SGerry Weißbach            // All Output has been done
1547d101cc1SGerry Weißbach            if (!is_array($data) && $data == 'save__meta') {
1557d101cc1SGerry Weißbach
1567d101cc1SGerry Weißbach                // Close TOC
1577d101cc1SGerry Weißbach                $renderer->section_close();
1587d101cc1SGerry Weißbach
1597d101cc1SGerry Weißbach                if ($renderer->meta['sitetoc']['noTOC'] === true) {
1607d101cc1SGerry Weißbach                    $renderer->doc = preg_replace("/<div.*?sitetoc.*?$/si", "", $renderer->doc);
1617d101cc1SGerry Weißbach                }
1627d101cc1SGerry Weißbach
1637d101cc1SGerry Weißbach                // If this is not set, we may have it as Metadata
164ee579aefSGerry Weißbach                if (empty($this->mergedPages) && $renderer->meta['sitetoc']['mergeDoc']) {
1657d101cc1SGerry Weißbach                    $toc = $renderer->meta['sitetoc']['siteexportTOC'];
166a99d6deeSGerry Weißbach
1677d101cc1SGerry Weißbach                    if (is_array($toc)) {
1687d101cc1SGerry Weißbach                        foreach ($toc as $tocItem) {
169a99d6deeSGerry Weißbach                            $this->mergedPages[] = array($tocItem['id'], $tocItem['depth']);
1707d101cc1SGerry Weißbach                        }
1717d101cc1SGerry Weißbach                    }
172a99d6deeSGerry Weißbach
1737d101cc1SGerry Weißbach                }
1747d101cc1SGerry Weißbach
1757d101cc1SGerry Weißbach                // If there is some data to be merged
1767d101cc1SGerry Weißbach                if (count($this->mergedPages) > 0) {
1777d101cc1SGerry Weißbach
1785321bc23SGerry Weißbach                    $renderer->doc = ''; // Start fresh!
1795321bc23SGerry Weißbach
1809c27c641SGerry Weißbach                    $renderer->section_open("1 mergedsite" . ($renderer->meta['sitetoc']['mergehint'] && count($this->mergedPages) > 1 ? ' mergehint' : ''));
1817d101cc1SGerry Weißbach
1827d101cc1SGerry Weißbach                    // Prepare lookup Array
1837d101cc1SGerry Weißbach                    foreach ($this->mergedPages as $tocItem) {
184ee579aefSGerry Weißbach                        list($this->includedPages[]) = explode('#', $tocItem[0]);
1857d101cc1SGerry Weißbach                    }
1867d101cc1SGerry Weißbach
1875321bc23SGerry Weißbach                    // Load the instructions
1885321bc23SGerry Weißbach                    $instr = array();
189a99d6deeSGerry Weißbach                    foreach ($this->mergedPages as $tocElement) {
190a99d6deeSGerry Weißbach
191a99d6deeSGerry Weißbach                        list($tocItem, $depth) = $tocElement;
1925321bc23SGerry Weißbach                        $file = wikiFN($tocItem);
1936792d0cfSGerry Weißbach
1946792d0cfSGerry Weißbach                        if (@file_exists($file)) {
1956792d0cfSGerry Weißbach                            $instructions = p_cached_instructions($file, false, $tocItem);
1966792d0cfSGerry Weißbach                        } else {
1976792d0cfSGerry Weißbach                            $instructions = p_get_instructions(io_readWikiPage($file, $tocItem));
1986792d0cfSGerry Weißbach                        }
1995321bc23SGerry Weißbach
200a99d6deeSGerry Weißbach                        // Convert Link and header instructions
201ee579aefSGerry Weißbach                        $instructions = $this->_convertInstructions($instructions, $addID = null, $renderer, $depth);
2025321bc23SGerry Weißbach
203f6a2ffb8SGerry Weißbach                        if ($renderer->meta['sitetoc']['mergeHeader'] && count($this->mergedPages) > 1) {
204300ce4a2SGerry Weißbach                            // get a hint for merged pages
205f6a2ffb8SGerry Weißbach                            if ($renderer->meta['sitetoc']['mergehint']) {
206300ce4a2SGerry Weißbach                                // only if the first section is already there
207300ce4a2SGerry Weißbach                                $mergeHint = p_get_metadata($tocItem, 'mergehint', METADATA_RENDER_USING_SIMPLE_CACHE);
208300ce4a2SGerry Weißbach                                if (empty($mergeHint)) { $mergeHint = p_get_metadata($tocItem, 'thema', METADATA_RENDER_USING_SIMPLE_CACHE); }
209300ce4a2SGerry Weißbach                                if (empty($mergeHint)) { $mergeHint = tpl_pagetitle($tocItem, true); }
210f6a2ffb8SGerry Weißbach                                $instructions = $this->_mergeWithHeaders($this->_initialHeaderStructure($instructions), $instructions, 1, $mergeHint);
211300ce4a2SGerry Weißbach                            }
2125321bc23SGerry Weißbach                            // Merge
213f6a2ffb8SGerry Weißbach                            $instr = $this->_mergeWithHeaders($instr, $instructions, 1);
2145b8c78c4SGerry Weißbach
21522a479aeSGerry Weißbach                        } else
21622a479aeSGerry Weißbach                        if ($renderer->meta['sitetoc']['pagebreak']) {
217300ce4a2SGerry Weißbach                            $sitepagebreak = array(array(
218300ce4a2SGerry Weißbach                                'plugin',
219300ce4a2SGerry Weißbach                                array(
220300ce4a2SGerry Weißbach                                    'siteexport_toctools',
221300ce4a2SGerry Weißbach                                    array(
222300ce4a2SGerry Weißbach                                        'pagebreak',
223300ce4a2SGerry Weißbach                                        null,
224300ce4a2SGerry Weißbach                                        null
225300ce4a2SGerry Weißbach                                    )
226300ce4a2SGerry Weißbach                                )
227300ce4a2SGerry Weißbach                            ));
228300ce4a2SGerry Weißbach                            $instr = array_merge($instr, $instructions, $sitepagebreak);
2295321bc23SGerry Weißbach                        } else {
2305321bc23SGerry Weißbach                            // Concat
2315321bc23SGerry Weißbach                            $instr = array_merge($instr, $instructions);
2327d101cc1SGerry Weißbach                        }
2335321bc23SGerry Weißbach                    }
2345321bc23SGerry Weißbach
235d04831eaSGerry Weißbach                    if (!empty($instr)) {
236cfed89d7SGerry Weißbach                        if ( $this->_cleanAllInstructions($instr, true) ) {
237cfed89d7SGerry Weißbach                            // There are no toc elements, remove the mergesite mergehint
238cfed89d7SGerry Weißbach                            $renderer->doc = preg_replace( '/(class=".*?\s)mergedsite/', '\1', $renderer->doc );
239cfed89d7SGerry Weißbach                            $renderer->doc = preg_replace( '/(class=".*?\s)mergehint/', '\1', $renderer->doc );
240cfed89d7SGerry Weißbach                        }
24122a479aeSGerry Weißbach
242300ce4a2SGerry Weißbach                        // print "<pre>"; print_r($instr); print "</pre>";
2435321bc23SGerry Weißbach                        $this->_render_output($renderer, $mode, $instr);
244d04831eaSGerry Weißbach                    }
245d04831eaSGerry Weißbach
2467d101cc1SGerry Weißbach                    $renderer->section_close();
2477d101cc1SGerry Weißbach                }
2487d101cc1SGerry Weißbach                return true;
2497d101cc1SGerry Weißbach            }
2507d101cc1SGerry Weißbach
2517d101cc1SGerry Weißbach            // Save the current ID
2527d101cc1SGerry Weißbach            $LNID = $SID;
2537d101cc1SGerry Weißbach
2547d101cc1SGerry Weißbach            // Add ID to flags['mergeDoc']
2557d101cc1SGerry Weißbach            if ($renderer->meta['sitetoc']['mergeDoc'] === true) { // || (count($renderer->meta['sitetoc']['siteexportTOC']) > 0 && $renderer->meta['sitetoc']['siteexportMergeDoc'] === true) ) {
256a99d6deeSGerry Weißbach                $this->mergedPages[] = array($SID, $DEPTH);
2573354083fSGerry Weißbach                $SID = (new PageResolver( $ID ))->resolveId($SID);
2588be94324SGerry Weißbach                $exists = page_exists( $SID );
2595321bc23SGerry Weißbach            } else {
2605321bc23SGerry Weißbach                // // print normal internal link (XHTML odt)
2617d101cc1SGerry Weißbach                $renderer->internallink($LNID, $NAME, null);
2627d101cc1SGerry Weißbach
2637d101cc1SGerry Weißbach                // Display Description underneath
2647d101cc1SGerry Weißbach                if ($renderer->meta['sitetoc']['showDescription'] === true) {
2657d101cc1SGerry Weißbach                    $renderer->cdata(p_get_metadata($SID, 'description abstract', true));
2667d101cc1SGerry Weißbach                }
2675321bc23SGerry Weißbach            }
2687d101cc1SGerry Weißbach
2697d101cc1SGerry Weißbach            // Render Metadata
2707d101cc1SGerry Weißbach        } else if ($mode == 'metadata') {
2717d101cc1SGerry Weißbach            if (!is_array($data) && $data == 'save__meta') {
2727d101cc1SGerry Weißbach                $renderer->meta['sitetoc']['siteexportTOC'] = $this->savedToc;
2737d101cc1SGerry Weißbach
2747d101cc1SGerry Weißbach                foreach ($this->savedToc as $page) {
2757d101cc1SGerry Weißbach                    $renderer->meta['relation']['references'][$page['id']] = $page['exists'];
2767d101cc1SGerry Weißbach                }
2777d101cc1SGerry Weißbach
2787d101cc1SGerry Weißbach                $this->savedToc = array();
2797d101cc1SGerry Weißbach            } else if (!isset($data['start']) && !isset($data['pos'])) {
2807d101cc1SGerry Weißbach                $this->savedToc[] = $this->__addTocItem($SID, $NAME, $DEPTH, $renderer);
2817d101cc1SGerry Weißbach            }
2827d101cc1SGerry Weißbach        }
2837d101cc1SGerry Weißbach
2847d101cc1SGerry Weißbach        return true;
2857d101cc1SGerry Weißbach    }
2867d101cc1SGerry Weißbach
2877d101cc1SGerry Weißbach    /*
2887d101cc1SGerry Weißbach     * pull apart the ID and create an Entry for the TOC
2897d101cc1SGerry Weißbach     */
29086da2b6bSGerry Weißbach    private function __addTocItem($id, $name, $depth, $renderer) {
2917d101cc1SGerry Weißbach        global $conf;
2927d101cc1SGerry Weißbach        global $ID;
2937d101cc1SGerry Weißbach
2943354083fSGerry Weißbach        $exists = false; $isImage = false; $linktype = null;
2953354083fSGerry Weißbach        $id = (new PageResolver( $ID ) )->resolveId($id);
2963354083fSGerry Weißbach        $exists = page_exists( $id );
297*5c175589SGerry Weißbach        // Keep explicit link title (e.g. [[.:configuration|configuration]]) so tocitem target stays lowercased
2987d101cc1SGerry Weißbach        $default = $renderer->_simpleTitle($id);
299*5c175589SGerry Weißbach        if ($name === null || $name === '') {
300*5c175589SGerry Weißbach            $name = $renderer->_getLinkTitle($name, $default, $isImage, $id, $linktype);
301*5c175589SGerry Weißbach        }
3027d101cc1SGerry Weißbach
3037d101cc1SGerry Weißbach        //keep hash anchor
3047d101cc1SGerry Weißbach        list($id, $hash) = explode('#', $id, 2);
3057d101cc1SGerry Weißbach        if (!empty($hash)) $hash = $renderer->_headerToLink($hash);
3067d101cc1SGerry Weißbach
3077d101cc1SGerry Weißbach        // Build Sitetoc Item
3087d101cc1SGerry Weißbach        $item = array();
3097d101cc1SGerry Weißbach        $item['id'] = $id;
3107d101cc1SGerry Weißbach        $item['name'] = $name;
3117d101cc1SGerry Weißbach        $item['anchor'] = $hash;
3127d101cc1SGerry Weißbach        $item['depth'] = $depth;
3137d101cc1SGerry Weißbach        $item['exists'] = $exists;
3147d101cc1SGerry Weißbach        if (!$conf['skipacl'] && auth_quickaclcheck($item['id']) < AUTH_READ) {
3157d101cc1SGerry Weißbach            return false;
3167d101cc1SGerry Weißbach        }
3177d101cc1SGerry Weißbach
3187d101cc1SGerry Weißbach        return $item;
3197d101cc1SGerry Weißbach    }
3207d101cc1SGerry Weißbach
3217d101cc1SGerry Weißbach    /*
3227d101cc1SGerry Weißbach     * Render the output of one page
3237d101cc1SGerry Weißbach     */
32486da2b6bSGerry Weißbach    private function _render_output($renderer, $mode, $instr) {
3257d101cc1SGerry Weißbach        global $ID;
3267d101cc1SGerry Weißbach
3277d101cc1SGerry Weißbach        // Section IDs
3285321bc23SGerry Weißbach        // $addID = sectionID($addID, $check);    //not possible to use a:b:c for id
3297d101cc1SGerry Weißbach
3307d101cc1SGerry Weißbach        if ($mode == 'xhtml') {
3315321bc23SGerry Weißbach
3327d101cc1SGerry Weißbach            //--------RENDER
3337d101cc1SGerry Weißbach            //renderer information(TOC build / Cache used)
3347d101cc1SGerry Weißbach            $info = array();
3357d101cc1SGerry Weißbach            $content = p_render($mode, $instr, $info);
3367d101cc1SGerry Weißbach
3377d101cc1SGerry Weißbach            //Remove TOC`s, section edit buttons and tags
3387d101cc1SGerry Weißbach            $content = $this->_cleanXHTML($content);
3397d101cc1SGerry Weißbach
3407d101cc1SGerry Weißbach            // embed the included page
3416792d0cfSGerry Weißbach            // $renderer->doc .= '<div class="include">';
3427d101cc1SGerry Weißbach            //add an anchor to find start of a inserted page
3435321bc23SGerry Weißbach            // $renderer->doc .= "<a name='$addID' id='$addID'>";
3447d101cc1SGerry Weißbach            $renderer->doc .= $content;
3456792d0cfSGerry Weißbach            // $renderer->doc .= '</div>';
3461508dbfeSGerry Weißbach        } else {
3477d101cc1SGerry Weißbach
3487d101cc1SGerry Weißbach            // Loop through the instructions
3497d101cc1SGerry Weißbach            foreach ($instr as $instruction) {
3507d101cc1SGerry Weißbach                // Execute the callback against the Renderer
3517d101cc1SGerry Weißbach                call_user_func_array(array($renderer, $instruction[0]), $instruction[1]);
3527d101cc1SGerry Weißbach            }
3537d101cc1SGerry Weißbach        }
3547d101cc1SGerry Weißbach    }
3557d101cc1SGerry Weißbach
3567d101cc1SGerry Weißbach    /*
3577d101cc1SGerry Weißbach     * Corrects relative internal links and media and
3587d101cc1SGerry Weißbach     * converts headers of included pages to subheaders of the current page
3597d101cc1SGerry Weißbach     */
36086da2b6bSGerry Weißbach    private function _convertInstructions($instr, $id, &$renderer, $depth = 1) {
3617d101cc1SGerry Weißbach        global $ID;
3627d101cc1SGerry Weißbach        global $conf;
3637d101cc1SGerry Weißbach
3647d101cc1SGerry Weißbach        $n = count($instr);
3657d101cc1SGerry Weißbach
3667d101cc1SGerry Weißbach        for ($i = 0; $i < $n; $i++) {
3677d101cc1SGerry Weißbach            //internal links(links inside this wiki) an relative links
3687d101cc1SGerry Weißbach            if ((substr($instr[$i][0], 0, 12) == 'internallink')) {
3697d101cc1SGerry Weißbach                $this->_convert_link($renderer, $instr[$i], $id);
3707d101cc1SGerry Weißbach            }
3717d101cc1SGerry Weißbach            else if ((substr($instr[$i][0], 0, 13) == 'internalmedia')) {
3727d101cc1SGerry Weißbach                $this->_convert_media($renderer, $instr[$i], $id);
3737d101cc1SGerry Weißbach            }
374a99d6deeSGerry Weißbach            else if ((substr($instr[$i][0], 0, 6) == 'header')) {
375a99d6deeSGerry Weißbach                $this->_convert_header($renderer, $instr[$i], $depth-1); // -1 because the depth starts at 1
376a99d6deeSGerry Weißbach            }
377a99d6deeSGerry Weißbach            else if ((substr($instr[$i][0], 0, 12) == 'section_open')) {
378a99d6deeSGerry Weißbach                $this->_convert_section($renderer, $instr[$i], $depth-1); // -1 because the depth starts at 1
379a99d6deeSGerry Weißbach            }
3807d101cc1SGerry Weißbach        }
3817d101cc1SGerry Weißbach
3827d101cc1SGerry Weißbach        //if its the document start, cut off the first element(document information)
3837d101cc1SGerry Weißbach        if ($instr[0][0] == 'document_start')
3847d101cc1SGerry Weißbach        return array_slice($instr, 1, -1);
3857d101cc1SGerry Weißbach        else
3867d101cc1SGerry Weißbach        return $instr;
3877d101cc1SGerry Weißbach    }
3887d101cc1SGerry Weißbach
3897d101cc1SGerry Weißbach    /*
3907d101cc1SGerry Weißbach     * Convert link of given instruction
3917d101cc1SGerry Weißbach     */
39286da2b6bSGerry Weißbach    private function _convert_link(&$renderer, &$instr, $id) {
3937d101cc1SGerry Weißbach        global $ID;
3947d101cc1SGerry Weißbach
3957d101cc1SGerry Weißbach        $exists = false;
3967d101cc1SGerry Weißbach
3973354083fSGerry Weißbach        resolve_pageid(getNS($id), $instr[1][0], $exists);
3987d101cc1SGerry Weißbach        list($pageID, $pageReference) = explode("#", $instr[1][0], 2);
3997d101cc1SGerry Weißbach
4007d101cc1SGerry Weißbach        if (in_array($pageID, $this->includedPages)) {
4017d101cc1SGerry Weißbach            // Crate new internal Links
4027d101cc1SGerry Weißbach            $check = null;
4037d101cc1SGerry Weißbach
4047d101cc1SGerry Weißbach            // Either get existing reference or create from first heading. If still not there take the alternate ID
4057d101cc1SGerry Weißbach            $pageNameLink = empty($pageReference) ? sectionID($pageID, $check) : $pageReference;
4067d101cc1SGerry Weißbach
4077d101cc1SGerry Weißbach            $instr[1][0] = $ID . "#" . $pageNameLink;
4087d101cc1SGerry Weißbach
4097d101cc1SGerry Weißbach        } else {
4107d101cc1SGerry Weißbach            // Convert external Links to plain Text
4117d101cc1SGerry Weißbach
4127d101cc1SGerry Weißbach            $instr = array(
4137d101cc1SGerry Weißbach                        "cdata",
4147d101cc1SGerry Weißbach            array($instr[1][1]),
4157d101cc1SGerry Weißbach            $instr[2]
4167d101cc1SGerry Weißbach            );
4177d101cc1SGerry Weißbach        }
4187d101cc1SGerry Weißbach    }
4197d101cc1SGerry Weißbach
4207d101cc1SGerry Weißbach    /*
4217d101cc1SGerry Weißbach     * Convert internalmedia of given instruction
4227d101cc1SGerry Weißbach     */
42386da2b6bSGerry Weißbach    private function _convert_media(&$renderer, &$instr, $id) {
4247d101cc1SGerry Weißbach        global $ID;
4257d101cc1SGerry Weißbach
4267d101cc1SGerry Weißbach        // Resolvemedia returns the absolute path to media by reference
4277d101cc1SGerry Weißbach        $exists = false;
4287d101cc1SGerry Weißbach        resolve_mediaid(getNS($id), $instr[1][0], $exists);
4297d101cc1SGerry Weißbach    }
4307d101cc1SGerry Weißbach
4310571ece2SScrutinizer Auto-Fixer    /**
4320571ece2SScrutinizer Auto-Fixer     * @param integer $depth
4330571ece2SScrutinizer Auto-Fixer     */
43486da2b6bSGerry Weißbach    private function _convert_header(&$renderer, &$instr, $depth) {
435a99d6deeSGerry Weißbach        // More Depth!
436a99d6deeSGerry Weißbach        $instr[1][1] += $depth;
437a99d6deeSGerry Weißbach    }
438a99d6deeSGerry Weißbach
4390571ece2SScrutinizer Auto-Fixer    /**
4400571ece2SScrutinizer Auto-Fixer     * @param integer $depth
4410571ece2SScrutinizer Auto-Fixer     */
44286da2b6bSGerry Weißbach    private function _convert_section(&$renderer, &$instr, $depth) {
443a99d6deeSGerry Weißbach        // More Depth!
444a99d6deeSGerry Weißbach        $instr[1][0] += $depth;
445a99d6deeSGerry Weißbach    }
446a99d6deeSGerry Weißbach
44786da2b6bSGerry Weißbach    private function _mergeWithHeaders($existing, $newInstructions, $level = 1, $mergeHint = array()) {
4485321bc23SGerry Weißbach
4495321bc23SGerry Weißbach        $returnInstructions = array();
4505321bc23SGerry Weißbach        $preparedInstructions = array();
4515321bc23SGerry Weißbach        $existingStart = $existingEnd = 0;
4525321bc23SGerry Weißbach        $firstRun = true;
4535321bc23SGerry Weißbach
4545321bc23SGerry Weißbach        while ($this->_findNextHeaderSection($existing, $level, $existingStart, $existingEnd)) {
4555321bc23SGerry Weißbach
4565321bc23SGerry Weißbach            if ($firstRun) {
4575321bc23SGerry Weißbach                $returnInstructions = array_merge($returnInstructions, array_slice($existing, 0, $existingStart));
4585321bc23SGerry Weißbach                $firstRun = false;
4595321bc23SGerry Weißbach            }
4605321bc23SGerry Weißbach
4615321bc23SGerry Weißbach            $currentSlice = array_slice($existing, $existingStart, $existingEnd-$existingStart);
4625321bc23SGerry Weißbach
4635321bc23SGerry Weißbach            // Find matching part with headername
4645321bc23SGerry Weißbach            $newStart = $newEnd = 0;
4655321bc23SGerry Weißbach            if ($this->_findNextHeaderSection($newInstructions, $level, $newStart, $newEnd, $currentSlice[0][1][0])) {
4665321bc23SGerry Weißbach
4675321bc23SGerry Weißbach                $newSlice = array_slice($newInstructions, $newStart, $newEnd-$newStart);
4685321bc23SGerry Weißbach                if ($newSlice[0][0] == 'header')
4695321bc23SGerry Weißbach                    array_shift($newSlice); // Remove Heading
4705321bc23SGerry Weißbach
4715321bc23SGerry Weißbach                // merge found parts on next level.
472300ce4a2SGerry Weißbach                $returnedInstructions = $this->_mergeWithHeaders($currentSlice, $newSlice, $level+1, $mergeHint);
4735321bc23SGerry Weißbach
4745321bc23SGerry Weißbach                // Put them at the end!
4755321bc23SGerry Weißbach                $preparedInstructions = array_merge($preparedInstructions, $returnedInstructions);
4765321bc23SGerry Weißbach
4775321bc23SGerry Weißbach                // Remove from input
4785321bc23SGerry Weißbach                array_splice($newInstructions, $newStart, $newEnd-$newStart);
4795321bc23SGerry Weißbach            } else {
480300ce4a2SGerry Weißbach                // Nothing else found
4815321bc23SGerry Weißbach                $preparedInstructions = array_merge($preparedInstructions, $currentSlice);
4825321bc23SGerry Weißbach            }
4835321bc23SGerry Weißbach
4845321bc23SGerry Weißbach            $existingStart = $existingEnd;
4855321bc23SGerry Weißbach        }
4865321bc23SGerry Weißbach
4875321bc23SGerry Weißbach        // Append the rest
4885321bc23SGerry Weißbach        $returnInstructions = array_merge($returnInstructions, array_slice($existing, $existingStart));
4895321bc23SGerry Weißbach
4905321bc23SGerry Weißbach        // Check for section close inconsistencies and put one at the very end ...
4915321bc23SGerry Weißbach        $section_postpend = array();
4929490aa3bSAlain        if (
4939490aa3bSAlain            (
494ee579aefSGerry Weißbach                ($tmp1 = array_slice($newInstructions, -1))
495ee579aefSGerry Weißbach                && ($tmp1[0][0] == 'section_close')
4969490aa3bSAlain            )
4979490aa3bSAlain            &&
4989490aa3bSAlain            (
499ee579aefSGerry Weißbach                ($tmp2 = array_slice($newInstructions, -2))
500ee579aefSGerry Weißbach                && ($tmp2[0][0] == 'section_close')
5019490aa3bSAlain            )
5029490aa3bSAlain        ) {
5035321bc23SGerry Weißbach            $section_postpend = array_splice($newInstructions, -1);
5045321bc23SGerry Weißbach        }
5059490aa3bSAlain        if (
5069490aa3bSAlain            (
507ee579aefSGerry Weißbach                ($tmp3 = array_slice($returnInstructions, -1))
508ee579aefSGerry Weißbach                && ($tmp3[0][0] == 'section_close')
5099490aa3bSAlain            )
5109490aa3bSAlain            &&
5119490aa3bSAlain            (
512ee579aefSGerry Weißbach                ($tmp4 = array_slice($returnInstructions, -2))
513ee579aefSGerry Weißbach                && ($tmp4[0][0] == 'section_close')
5149490aa3bSAlain            )
5159490aa3bSAlain        ) {
5165321bc23SGerry Weißbach            $section_postpend = array_merge($section_postpend, array_splice($returnInstructions, -1));
5175321bc23SGerry Weißbach        }
5185321bc23SGerry Weißbach
5195321bc23SGerry Weißbach        // What if there are headings left inside the $newInstructions?????
5205321bc23SGerry Weißbach        // Find matching part with headername
5215321bc23SGerry Weißbach        $newStart = $newEnd = 0;
5225321bc23SGerry Weißbach        $section_prepend = array();
5235321bc23SGerry Weißbach        if ($this->_findNextHeaderSection($newInstructions, $level, $newStart, $newEnd)) {
5245321bc23SGerry Weißbach            // If there are header in here, build a prepend and have the rest at the end
5255321bc23SGerry Weißbach            $section_prepend = array_splice($newInstructions, 0, $newStart);
5265321bc23SGerry Weißbach        } else {
5275321bc23SGerry Weißbach            // If not, prepend all of it.
5285321bc23SGerry Weißbach            $section_prepend = $newInstructions;
5295321bc23SGerry Weißbach            $newInstructions = array();
5305321bc23SGerry Weißbach        }
5315321bc23SGerry Weißbach
532300ce4a2SGerry Weißbach        $this->_insertMergeHint($section_prepend, $mergeHint);
533300ce4a2SGerry Weißbach
5345321bc23SGerry Weißbach        $returnInstructions = array_merge($returnInstructions, $section_prepend, $preparedInstructions, $newInstructions, $section_postpend);
5355321bc23SGerry Weißbach
5365321bc23SGerry Weißbach        return $returnInstructions;
5375321bc23SGerry Weißbach    }
5385321bc23SGerry Weißbach
5390571ece2SScrutinizer Auto-Fixer    /**
5400571ece2SScrutinizer Auto-Fixer     * @param integer $level
5410571ece2SScrutinizer Auto-Fixer     */
54286da2b6bSGerry Weißbach    private function _findNextHeaderSection($section, $level, &$start, &$end, $headerName = null) {
5435321bc23SGerry Weißbach
5445321bc23SGerry Weißbach        $inCount = count($section);
5455321bc23SGerry Weißbach        $currentSlice = -1;
5465321bc23SGerry Weißbach
5475321bc23SGerry Weißbach        // Find Level 1 Header that matches.
5485321bc23SGerry Weißbach        for ($i = $start; $i < $inCount; $i++) {
5495321bc23SGerry Weißbach
5505321bc23SGerry Weißbach            $instruction = $section[$i];
5515321bc23SGerry Weißbach            $end = $i; // Or it will be lost and a section close will be missing.
5525321bc23SGerry Weißbach
5535321bc23SGerry Weißbach            // First Level Header
5545321bc23SGerry Weißbach            if ($instruction[0] == 'header' && $instruction[1][1] == $level) {
5555321bc23SGerry Weißbach
5565321bc23SGerry Weißbach                if ($currentSlice > 0) {
5575321bc23SGerry Weißbach                    return true;
5585321bc23SGerry Weißbach                }
5595321bc23SGerry Weißbach
5605321bc23SGerry Weißbach                if ($headerName == null || ($headerName == $instruction[1][0])) {
5615321bc23SGerry Weißbach                    // Begin of new slice ...
5625321bc23SGerry Weißbach                    $start = $currentSlice = $i;
5635321bc23SGerry Weißbach                }
5645321bc23SGerry Weißbach            }
5655321bc23SGerry Weißbach        }
5665321bc23SGerry Weißbach
5675321bc23SGerry Weißbach        // Nothing found
5685321bc23SGerry Weißbach        $end = $i; // Or it will be lost and a section close will be missing.
5695321bc23SGerry Weißbach        return $currentSlice > 0;
5705321bc23SGerry Weißbach    }
5715321bc23SGerry Weißbach
5724f36f720SGerry Weißbach    private function _cleanAllInstructions(&$instr, $advanced=false) {
5734f36f720SGerry Weißbach        $this->_cleanInstructions($instr, '/p_(close|open)/');
57493734debSGerry Weißbach        $this->_cleanInstructions($instr, '/section_(close|open)/');
57593734debSGerry Weißbach        $this->_cleanInstructions($instr, '/listu_(close|open)/');
57693734debSGerry Weißbach        $this->_cleanInstructions($instr, '/listo_(close|open)/');
5774f36f720SGerry Weißbach
5784f36f720SGerry Weißbach        if ( !$advanced ) {
579cfed89d7SGerry Weißbach            return false;
5804f36f720SGerry Weißbach        }
5814f36f720SGerry Weißbach
5824f36f720SGerry Weißbach        $currentMergeHint = null;
583cfed89d7SGerry Weißbach        $listOfMergeHintNames= [];
584d3a16081SGerry Weißbach
5854f36f720SGerry Weißbach        for( $i=0; $i<count($instr); $i++ ) {
5864f36f720SGerry Weißbach
5874f36f720SGerry Weißbach            $hasMoreEntries = count($instr)-1 > $i;
5884f36f720SGerry Weißbach
5894f36f720SGerry Weißbach            if ( $instr[$i][0] == 'header' ) {
590cfed89d7SGerry Weißbach                // reset after header
591cfed89d7SGerry Weißbach                $currentMergeHint = null;
5924f36f720SGerry Weißbach            }
5934f36f720SGerry Weißbach
594cfed89d7SGerry Weißbach            if ( $instr[$i][1][0] == 'siteexport_toctools' && $instr[$i][1][0][0] != 'pagebreak' ) {
5954f36f720SGerry Weißbach                if ( $currentMergeHint != null && $instr[$i][1][1][2] == $currentMergeHint[1][1][2] ) {
596d3a16081SGerry Weißbach
597d3a16081SGerry Weißbach                    if ( $instr[$i][1][1][1] == 'end' ) {
598d3a16081SGerry Weißbach                        // look ahead, if the next hint is also the same ID, if so: remove this ending hint.
599d3a16081SGerry Weißbach                        $shouldSpliceAway = false;
600d3a16081SGerry Weißbach                        for( $ii=$i+1; $ii<count($instr); $ii++ ) {
601d3a16081SGerry Weißbach                            if ( $instr[$ii][0] == 'header' ) {
602d3a16081SGerry Weißbach                                // Jumping over a section now ... we have to leave the last entry
603d3a16081SGerry Weißbach                                break;
604d3a16081SGerry Weißbach                            } else if ( $instr[$ii][1][0] == 'siteexport_toctools' && $instr[$ii][1][0][0] != 'pagebreak' ) {
605d3a16081SGerry Weißbach                                if ( $instr[$ii][1][1][2] == $currentMergeHint[1][1][2] && $instr[$ii][1][1][1] == 'start' ) {
606d3a16081SGerry Weißbach                                    // Found another one, that is identicall - so this will be removed.
607d3a16081SGerry Weißbach                                    // also remove the current ending element
608d3a16081SGerry Weißbach                                    $shouldSpliceAway = true;
609d3a16081SGerry Weißbach                                }
610d3a16081SGerry Weißbach
611d3a16081SGerry Weißbach                                // Okay, this was a toctools whatever ... but maybe not a start of the same type.
612d3a16081SGerry Weißbach                                // we're done.
613d3a16081SGerry Weißbach                                break;
614d3a16081SGerry Weißbach                            }
615d3a16081SGerry Weißbach                        }
616d3a16081SGerry Weißbach
617d3a16081SGerry Weißbach                        if ( !$shouldSpliceAway ) {
618d3a16081SGerry Weißbach                            // print "<pre>NOT Splicing away ". print_r($instr[$i], true) . "</pre>";
619d3a16081SGerry Weißbach                            continue;
620d3a16081SGerry Weißbach                        }
621d3a16081SGerry Weißbach                        // print "<pre>Splicing away ". print_r($instr[$i], true) . "</pre>";
622d3a16081SGerry Weißbach                    }
623d3a16081SGerry Weißbach
624d3a16081SGerry Weißbach                    // print "<p>Removing 'mergehint' in between  </p>";
6254f36f720SGerry Weißbach                    array_splice($instr, $i--, 1);
6264f36f720SGerry Weißbach                } else {
6274f36f720SGerry Weißbach                    // print "<p>Resetting Mergehint '" . $instr[$i][1][1][2] . "' == '" . $currentMergeHint[1][1][2] . "'</p>";
6284f36f720SGerry Weißbach                    $currentMergeHint = $instr[$i];
629cfed89d7SGerry Weißbach                    $listOfMergeHintNames[] = $instr[$i][1][1][2];
6304f36f720SGerry Weißbach                }
6314f36f720SGerry Weißbach            }
6324f36f720SGerry Weißbach        }
633cfed89d7SGerry Weißbach
634d3a16081SGerry Weißbach/*
635d3a16081SGerry Weißbach        print "<pre>" . print_r($instr, 1) . "</pre>";
636d3a16081SGerry Weißbach
637d3a16081SGerry Weißbach//*/
638d3a16081SGerry Weißbach
639cfed89d7SGerry Weißbach        // There is only ONE distinct mergehint -> remove all
640cfed89d7SGerry Weißbach        $listOfMergeHintNames = array_unique($listOfMergeHintNames);
641cfed89d7SGerry Weißbach        if ( count($listOfMergeHintNames) == 1 ) {
642cfed89d7SGerry Weißbach            for( $i=0; $i<count($instr); $i++ ) {
643cfed89d7SGerry Weißbach                if ( $instr[$i][1][0] == 'siteexport_toctools' && $instr[$i][1][0][0] != 'pagebreak' ) {
644cfed89d7SGerry Weißbach                    array_splice($instr, $i--, 1);
645cfed89d7SGerry Weißbach                }
646cfed89d7SGerry Weißbach            }
647cfed89d7SGerry Weißbach        }
648cfed89d7SGerry Weißbach
649cfed89d7SGerry Weißbach        return count($listOfMergeHintNames) == 1;
65093734debSGerry Weißbach    }
65193734debSGerry Weißbach
6520571ece2SScrutinizer Auto-Fixer    /**
6530571ece2SScrutinizer Auto-Fixer     * @param string $tag
6540571ece2SScrutinizer Auto-Fixer     */
65586da2b6bSGerry Weißbach    private function _cleanInstructions(&$instructions, $tag) {
6565321bc23SGerry Weißbach
6575b8c78c4SGerry Weißbach
6585b8c78c4SGerry Weißbach/*
6595b8c78c4SGerry Weißbach        print "<pre>";
6605b8c78c4SGerry Weißbach        print "$tag ->\n";
6615b8c78c4SGerry Weißbach        print_r($instructions);
6625b8c78c4SGerry Weißbach        print "</pre>";
6635b8c78c4SGerry Weißbach//*/
6645321bc23SGerry Weißbach        $inCount = count($instructions);
6655321bc23SGerry Weißbach        for ($i = 0; $i < $inCount; $i++) {
6665321bc23SGerry Weißbach
6675321bc23SGerry Weißbach            // Last instruction
6685321bc23SGerry Weißbach            if ($i == $inCount-1) {
6695321bc23SGerry Weißbach                break;
6705321bc23SGerry Weißbach            }
6715321bc23SGerry Weißbach
6725321bc23SGerry Weißbach            if (preg_match($tag, $instructions[$i][0]) && preg_match($tag, $instructions[$i+1][0]) && $instructions[$i][0] != $instructions[$i+1][0]) {
6735b8c78c4SGerry Weißbach/*
6745b8c78c4SGerry Weißbach        print "<pre>";
6755b8c78c4SGerry Weißbach        print "Removed ->\n";
6765b8c78c4SGerry Weißbach        print_r($instructions[$i-1]);
6775b8c78c4SGerry Weißbach        print "---\n";
6785b8c78c4SGerry Weißbach        print_r($instructions[$i]);
6795b8c78c4SGerry Weißbach        print_r($instructions[$i+1]);
6805b8c78c4SGerry Weißbach        print "---\n";
6815b8c78c4SGerry Weißbach        print_r($instructions[$i+2]);
6825b8c78c4SGerry Weißbach        print "</pre>";
6835b8c78c4SGerry Weißbach//*/
6845321bc23SGerry Weißbach
6855321bc23SGerry Weißbach                // found different tags, but both match the expression and follow each other - so they can be elliminated
6865321bc23SGerry Weißbach                array_splice($instructions, $i, 2);
6875321bc23SGerry Weißbach                $inCount -= 2;
6885321bc23SGerry Weißbach                $i--;
6895321bc23SGerry Weißbach            }
6905321bc23SGerry Weißbach        }
6915b8c78c4SGerry Weißbach/*
6925b8c78c4SGerry Weißbach        print "<pre>";
6935b8c78c4SGerry Weißbach        print "$tag ->\n";
6945b8c78c4SGerry Weißbach        print_r($instructions);
6955b8c78c4SGerry Weißbach        print "</pre>";
6965b8c78c4SGerry Weißbach//*/
6975321bc23SGerry Weißbach    }
6985321bc23SGerry Weißbach
699f6a2ffb8SGerry Weißbach    /**
700f6a2ffb8SGerry Weißbach     * Strip everything except for the headers
701f6a2ffb8SGerry Weißbach     */
70286da2b6bSGerry Weißbach    private function _initialHeaderStructure($instructions) {
703f6a2ffb8SGerry Weißbach        $inCount = count($instructions);
704f6a2ffb8SGerry Weißbach        for ($i = 0; $i < $inCount; $i++) {
705f6a2ffb8SGerry Weißbach
706f6a2ffb8SGerry Weißbach            // Last instruction
707f6a2ffb8SGerry Weißbach            if ($i == $inCount-1) {
708f6a2ffb8SGerry Weißbach                break;
709f6a2ffb8SGerry Weißbach            }
710f6a2ffb8SGerry Weißbach
711f6a2ffb8SGerry Weißbach            if (!in_array($instructions[$i][0], array('header', 'section_open', 'section_close', 'p_open', 'p_close'))) {
712f6a2ffb8SGerry Weißbach                // found non-matching
713f6a2ffb8SGerry Weißbach                array_splice($instructions, $i, 1);
714f6a2ffb8SGerry Weißbach                $inCount--;
715f6a2ffb8SGerry Weißbach                $i--;
716f6a2ffb8SGerry Weißbach            }
717f6a2ffb8SGerry Weißbach        }
718f6a2ffb8SGerry Weißbach        return $instructions;
719f6a2ffb8SGerry Weißbach    }
720f6a2ffb8SGerry Weißbach
72186da2b6bSGerry Weißbach    private function _insertMergeHint(&$instructions, $mergeHint) {
722300ce4a2SGerry Weißbach
723300ce4a2SGerry Weißbach        // Surround new slice with a mergehint
724300ce4a2SGerry Weißbach        if (empty($mergeHint)) { return; }
725300ce4a2SGerry Weißbach
72693734debSGerry Weißbach        // No emtpy insruction sets.
72793734debSGerry Weißbach        $this->_cleanAllInstructions($instructions);
72874627711SGerry Weißbach
72993734debSGerry Weißbach        if (empty($instructions)) { return; }
73093734debSGerry Weißbach
731f7eda97fSGerry Weißbach        $mergeHintPrepend = $this->_toctoolPrepends( $instructions );
732f7eda97fSGerry Weißbach
733f7eda97fSGerry Weißbach        // only section content should be surrounded.
734f7eda97fSGerry Weißbach        if ($instructions[0][0] != 'section_open') { return; }
735f7eda97fSGerry Weißbach
736f7eda97fSGerry Weißbach        // save for later use
737d3a16081SGerry Weißbach        $mergeHintId = sectionid($mergeHint, $this->mergeHints);
738f7eda97fSGerry Weißbach        $this->merghintIds[$mergeHintId] = $mergeHint;
739f7eda97fSGerry Weißbach
740f7eda97fSGerry Weißbach        // Insert section information
741f7eda97fSGerry Weißbach        array_push( $mergeHintPrepend, array(
742300ce4a2SGerry Weißbach            'plugin',
743300ce4a2SGerry Weißbach            array(
744300ce4a2SGerry Weißbach                'siteexport_toctools',
745300ce4a2SGerry Weißbach                array(
746300ce4a2SGerry Weißbach                    'mergehint',
747300ce4a2SGerry Weißbach                    'start',
748300ce4a2SGerry Weißbach                    $mergeHint,
749300ce4a2SGerry Weißbach                    $mergeHintId
750300ce4a2SGerry Weißbach                )
751300ce4a2SGerry Weißbach            )
752300ce4a2SGerry Weißbach        ) );
753300ce4a2SGerry Weißbach
754300ce4a2SGerry Weißbach        $mergeHintPostpend = array(array(
755300ce4a2SGerry Weißbach            'plugin',
756300ce4a2SGerry Weißbach            array(
757300ce4a2SGerry Weißbach                'siteexport_toctools',
758300ce4a2SGerry Weißbach                array(
759300ce4a2SGerry Weißbach                    'mergehint',
760300ce4a2SGerry Weißbach                    'end',
761300ce4a2SGerry Weißbach                    $mergeHint
762300ce4a2SGerry Weißbach                )
763300ce4a2SGerry Weißbach            )
764300ce4a2SGerry Weißbach        ));
765300ce4a2SGerry Weißbach
766d3a16081SGerry Weißbach        $instructions = array_merge($mergeHintPrepend, $instructions, $mergeHintPostpend);
767300ce4a2SGerry Weißbach/*
76874627711SGerry Weißbach        print "<pre>"; print_r($instructions); print "</pre>";
76974627711SGerry Weißbach//*/
770f7eda97fSGerry Weißbach    }
771f7eda97fSGerry Weißbach
772f7eda97fSGerry Weißbach    private function _toctoolPrepends( &$instructions ) {
773f7eda97fSGerry Weißbach
77474627711SGerry Weißbach        $mergeHintPrependPrepend = array();
7755b8c78c4SGerry Weißbach
7765b8c78c4SGerry Weißbach        // 2021-01-14 This did no good - if a merged page had two mergehints, the first was stripped.
7775b8c78c4SGerry Weißbach/*
778f7eda97fSGerry Weißbach        if ( $instructions[0][0] == 'plugin' && $instructions[0][1][0] == 'siteexport_toctools' && $instructions[0][1][1][1] == 'start' ) {
779f7eda97fSGerry Weißbach
780f7eda97fSGerry Weißbach            // This is already section merge hint ... but it will have a section at its end ... hopefully
78174627711SGerry Weißbach            do {
782268cf88bSGerry Weißbach                $_instructions = array_shift( $instructions );
783268cf88bSGerry Weißbach                array_push( $mergeHintPrependPrepend, $_instructions);
784268cf88bSGerry Weißbach            } while( !($_instructions[0] == 'plugin' && $_instructions[1][0] == 'siteexport_toctools' && $_instructions[1][1][1] == 'end' ) ) ;
78574627711SGerry Weißbach            array_splice($mergeHintPrepend, 0, 0, $mergeHintPrependPrepend);
78674627711SGerry Weißbach        }
7875b8c78c4SGerry Weißbach//*/
78874627711SGerry Weißbach/*
78974627711SGerry Weißbach        print "<pre>"; print_r($instructions); print "</pre>";
79074627711SGerry Weißbach//*/
791f7eda97fSGerry Weißbach        return $mergeHintPrependPrepend;
792300ce4a2SGerry Weißbach    }
793300ce4a2SGerry Weißbach
7947d101cc1SGerry Weißbach    /**
7957d101cc1SGerry Weißbach     * Remove TOC, section edit buttons and tags
7967d101cc1SGerry Weißbach     */
797a8c17ab5Si-net /// software    private function _cleanXHTML($xhtml) {
7987d101cc1SGerry Weißbach        $replace = array(
7997d101cc1SGerry Weißbach            '!<div class="toc">.*?(</div>\n</div>)!s' => '', // remove TOCs
8003dfe6d90SGerry Weißbach            '#<!-- SECTION \[(\d*-\d*)\] -->#s'       => '', // remove section edit buttons
8017d101cc1SGerry Weißbach            '!<div id="tags">.*?(</div>)!s'           => ''  // remove category tags
8027d101cc1SGerry Weißbach        );
8037d101cc1SGerry Weißbach        $xhtml = preg_replace(array_keys($replace), array_values($replace), $xhtml);
8047d101cc1SGerry Weißbach        return $xhtml;
8057d101cc1SGerry Weißbach    }
8067d101cc1SGerry Weißbach
8077d101cc1SGerry Weißbach    /**
8087d101cc1SGerry Weißbach     * Allow the plugin to prevent DokuWiki creating a second instance of itself
8097d101cc1SGerry Weißbach     *
8107d101cc1SGerry Weißbach     * @return bool   true if the plugin can not be instantiated more than once
8117d101cc1SGerry Weißbach     */
812a8c17ab5Si-net /// software    public function isSingleton() {
8137d101cc1SGerry Weißbach        return true;
8147d101cc1SGerry Weißbach    }
8157d101cc1SGerry Weißbach}
8167d101cc1SGerry Weißbach// vim:ts=4:sw=4:et:enc=utf-8:
817