From a28f677a5d93ec54073eb7e90d858ca8f53845c4 Mon Sep 17 00:00:00 2001 From: Steffen Pegenau Date: Tue, 5 Apr 2016 11:55:04 +0200 Subject: [PATCH] Adds a simple table of contents to each wiki page --- lang/en/ouwiki.php | 2 + renderer.php | 9 +++ tableofcontents.php | 161 ++++++++++++++++++++++++++++++++++++++++++++ version.php | 2 +- 4 files changed, 173 insertions(+), 1 deletion(-) create mode 100644 tableofcontents.php diff --git a/lang/en/ouwiki.php b/lang/en/ouwiki.php index 6a0f4cb..13bc0c2 100644 --- a/lang/en/ouwiki.php +++ b/lang/en/ouwiki.php @@ -588,3 +588,5 @@ $string['event:ouwikipageupdated'] = 'ouwiki page updated'; $string['event:savefailed'] = 'Session fail on page save'; $string['ouwikicrontask'] = 'OU wiki maintenance jobs'; + +$string['tableofcontents'] = 'Table of contents'; diff --git a/renderer.php b/renderer.php index f1b95a6..f91b53a 100644 --- a/renderer.php +++ b/renderer.php @@ -206,8 +206,17 @@ public function get_topheading_section($title, $gewgaws, $pageversion, $annotati $cm = $this->params->cm; $output = html_writer::start_tag('div', array('class' => 'ouw_topheading')); $output .= html_writer::start_tag('div', array('class' => 'ouw_heading')); + $output .= html_writer::tag('h2', format_string($title), array('class' => 'ouw_topheading')); + + // Add table of contents + global $CFG; + require_once($CFG->dirroot.'/mod/ouwiki/tableofcontents.php'); + $toc = new TableOfContents($pageversion->xhtml); + $output .= $toc->toHtml(); + + if ($gewgaws) { $output .= $this->render_heading_bit(1, $pageversion->title, $subwiki, $cm, null, $annotations, $pageversion->locked, $files, diff --git a/tableofcontents.php b/tableofcontents.php new file mode 100644 index 0000000..3bb306e --- /dev/null +++ b/tableofcontents.php @@ -0,0 +1,161 @@ +. + +/** + * Version. + * + * @package mod_ouwiki + * @copyright 2016 The Open University + * @author Steffen Pegenau + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +class TableOfContents { + // The table of contents is saved in a 6xn-Array + // 6:

-

+ // n: the number of headings + private $ToC = array(array(array(array(array(array()))))); + private $html = ""; + + private $lastH1 = 0; + private $lastH2 = 0; + private $lastH3 = 0; + private $lastH4 = 0; + private $lastH5 = 0; + private $lastH6 = 0; + private $lastLvl = 0; + + public function __construct($html) { + $this->html = $html; + $this->parseHtml($html); + } + + /* + * returns the table of contents as printable html + */ + public function toHtml() { + $toc = $this->ToC; + $output = "

" . get_string('tableofcontents', 'ouwiki') . "

"; + $output .= ""; + + return $output; + } + + /* + * Parses the html-Code and generates the table of contents + * + * @param String $html The html-snippet to parse + */ + private function parseHtml($html) { + $reader = new XMLReader(); + $reader->xml($html); + + $headings = []; + $output = ""; + + $lastlevel = 0; + + // traverse the tree + while($reader->read() !== false) { + $tag = $reader->name; + $content = $reader->readString(); + $matches = null; + + // is it a h1-h6 heading? + preg_match('/[hH][1-6]/', $tag, $matches); + if(!empty($content) && count($matches) > 0) { + // example: h1 -> 1 + $lvl = substr($tag, 1); + //

=> ouw_s0_0 + $id = $reader->getAttribute("id"); + $this->addToTree($lvl, $content, $id); + } + } + } + + /** + * Adds an entry with name and level to the table of contents + * + * param int $lvl The level of the heading + * param string $name The title of the heading + * param string $id html attribute id of heading + */ + private function addToTree($lvl, $name, $id) { + if($lvl < $this->lastLvl) { + $lvlToDelete = $lvl + 1; + switch($lvlToDelete) { + case 1: + $this->lastH1 = 0; + case 2: + $this->lastH2 = 0; + case 3: + $this->lastH3 = 0; + case 4: + $this->lastH4 = 0; + case 5: + $this->lastH5 = 0; + case 6: + $this->lastH6 = 0; + break; + } + } + + switch ($lvl) { + case 1: + ++$this->lastH1; + break; + case 2: + ++$this->lastH2; + break; + case 3: + ++$this->lastH3; + break; + case 4: + ++$this->lastH4; + break; + case 5: + ++$this->lastH5; + break; + case 6: + ++$this->lastH6; + break; + } + $element = new stdClass(); + $element->name = $name; + $element->id = $id; + + // Save element in array + $this->ToC[$this->lastH1][$this->lastH2][$this->lastH3][$this->lastH4][$this->lastH5][$this->lastH6] = $element; + + $this->lastLvl = $lvl; + } +} diff --git a/version.php b/version.php index fe0bd84..6cc9db6 100644 --- a/version.php +++ b/version.php @@ -22,7 +22,7 @@ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ -$plugin->version = 2015101501; +$plugin->version = 2016040500; $plugin->requires = 2014051200; $plugin->component = 'mod_ouwiki'; $plugin->maturity = MATURITY_STABLE;