123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148 |
- <?php
- /**
- *
- * @package Pico
- * @subpackage mcb_TableOfContent
- * @version 0.3.1
- * @author mcbSolutions.at <dev@mcbsolutions.at>
- * @author notabug.org/ohnonot
- *
- * ## Changelog
- *
- * + 2016-11-17 Upgrade to AbstractPicoPlugin for Pico 1.0
- * + 2016-11-19
- * + Removed some parameters
- * + Added the test page
- * + 2019-11-24 Much hacked to be included in my (ohnonot) tagblog theme
- *
- *
- */
- class TableOfContent extends AbstractPicoPlugin {
- // only act if this var is set to "true"
- private $yeah = "false";
- // default settings
- private $depth = 3;
- private $min_headers = 3;
- private $top_txt = 'Top';
- private $caption = "Table of contents";
- private $template = "all"; // config to valid twig template to only act on that template - defaults to all templates.
- // internal
- private $toc = '';
- private $xpQuery;
- private $content;
- public function onConfigLoaded(&$config)
- {
- if(isset($config['TableOfContent']['depth'])) $this->depth = &$config['TableOfContent']['depth'];
- if(isset($config['TableOfContent']['min_headers'])) $this->min_headers = &$config['TableOfContent']['min_headers'];
- if(isset($config['TableOfContent']['top_txt' ])) $this->top_txt = &$config['TableOfContent']['top_txt'];
- if(isset($config['TableOfContent']['caption' ])) $this->caption = &$config['TableOfContent']['caption'];
- if(isset($config['TableOfContent']['template' ])) $this->template = &$config['TableOfContent']['template'];
- for ($i=1; $i <= $this->depth; $i++) {
- $this->xpQuery[] = "//h$i";
- }
- $this->xpQuery = join("|", $this->xpQuery);
- }
- public function onMetaParsed(array $meta)
- {
- if($meta['template'] === $this->template || $this->template === "all" ) $this->yeah = "true";
- }
- private function makeToc(&$content)
- {
- //get the headings
- if(preg_match_all('/<h[1-'.$this->depth.']{1,1}[^>]*>.*?<\/h[1-'.$this->depth.']>/s',$content,$headers) === false)
- return "";
- //create the toc
- $this->headers = $headers;
- $heads = implode("\n",$headers[0]);
- $heads = preg_replace('/<a.+?\/a>/','',$heads);
- $heads = preg_replace('/<h([1-6]).+?id="?/','<li class="toc$1"><a href="#',$heads);
- $heads = preg_replace('/<\/h[1-6]>/','</a></li>',$heads);
- $cap = $this->caption =='' ? "" : '<p id="toc-header">'.$this->caption.'</p>';
- return '<div id="toc">'.$cap.'<ul>'.$heads.'</ul></div>';
- }
- public function onContentParsed(&$content)
- {
- if($this->yeah != "true") return;
- if(trim($content)=="")
- return;
-
- // enable user error handling
- // libxml_use_internal_errors(true);
- // Workaround from cbuckley:
- // "... an alternative is to prepend the HTML with an XML encoding declaration, provided that the
- // document doesn't already contain one:
- //
- // http://stackoverflow.com/questions/8218230/php-domdocument-loadhtml-not-encoding-utf-8-correctly
- $dom = new DOMDocument('1.0', 'utf-8');
- $html = $dom->loadHTML('<?xml encoding="utf-8" ?>' . $content);
- if(!$html)
- {
- foreach (libxml_get_errors() as $error) {
- // handle errors here
- $this->content['err'][] = $error;
- }
- libxml_clear_errors();
- return;
- }
- $xp = new DOMXPath($dom);
- $nodes =$xp->query($this->xpQuery);
- if($nodes->length < $this->min_headers)
- return;
- // add missing id's to the h tags
- $id = 0;
- foreach($nodes as $i => $sort)
- {
- if (isset($sort->tagName) && $sort->tagName !== '')
- {
- if($sort->getAttribute('id') === "")
- {
- ++$id;
- $sort->setAttribute('id', "c$id");
- $a = $dom->createElement('a', $this->top_txt);
- $a->setAttribute('href', '#');
- $a->setAttribute('class', 'toc-nav');
- $sort->appendChild($a);
- }
- }
- }
- $content = preg_replace(array("/<(!DOCTYPE|\?xml).+?>/", "/<\/?(html|body)>/"),
- array( "", ""),
- $dom->saveHTML());
- $this->toc = $this->makeToc($content);
- }
- public function onPageRendering(&$twig, &$twigVariables, &$templateName)
- {
- if($this->yeah != "true") return;
- $twigVariables['tableofcontent'] = $this->toc;
- }
- /* debug
- public function onPageRendered(&$output)
- {
- $output = $output . "<pre style=\"background-color:white;\">".htmlentities(print_r($this,1))."</pre>";
- }*/
- }
|