diff options
-rw-r--r-- | Zotlabs/Module/Wiki.php | 5 | ||||
-rw-r--r-- | include/wiki.php | 77 | ||||
-rw-r--r-- | view/tpl/wiki.tpl | 2 |
3 files changed, 81 insertions, 3 deletions
diff --git a/Zotlabs/Module/Wiki.php b/Zotlabs/Module/Wiki.php index 2f22f0a81..6252f7a1a 100644 --- a/Zotlabs/Module/Wiki.php +++ b/Zotlabs/Module/Wiki.php @@ -138,7 +138,8 @@ class Wiki extends \Zotlabs\Web\Controller { $content = ($p['content'] !== '' ? htmlspecialchars_decode($p['content'],ENT_COMPAT) : '"# New page\n"'); // Render the Markdown-formatted page content in HTML require_once('library/markdown.php'); - $renderedContent = wiki_convert_links(Markdown(json_decode($content)),argv(0).'/'.argv(1).'/'.$wikiUrlName); + $html = wiki_generate_toc(purify_html(Markdown(json_decode($content)))); + $renderedContent = wiki_convert_links($html,argv(0).'/'.argv(1).'/'.$wikiUrlName); $hide_editor = false; $showPageControls = $wiki_editor; $showNewWikiButton = $wiki_owner; @@ -215,7 +216,7 @@ class Wiki extends \Zotlabs\Web\Controller { $content = $_POST['content']; $resource_id = $_POST['resource_id']; require_once('library/markdown.php'); - $html = purify_html(Markdown($content)); + $html = wiki_generate_toc(purify_html(Markdown($content))); $w = wiki_get_wiki($resource_id); $wikiURL = argv(0).'/'.argv(1).'/'.$w['urlName']; $html = wiki_convert_links($html,$wikiURL); diff --git a/include/wiki.php b/include/wiki.php index 63cf70f3c..424b2d9a0 100644 --- a/include/wiki.php +++ b/include/wiki.php @@ -493,4 +493,79 @@ function wiki_convert_links($s, $wikiURL) { } } return $s; -}
\ No newline at end of file +} + +function wiki_generate_toc($s) { + + if (strpos($s,'[toc]') !== false) { + //$toc_md = wiki_toc($s); // Generate Markdown-formatted list prior to HTML render + $toc_md = '<ul id="wiki-toc"></ul>'; // use the available jQuery plugin http://ndabas.github.io/toc/ + $s = preg_replace("/\[toc\]/", $toc_md, $s, -1); + } + return $s; +} + +// This function is derived from +// http://stackoverflow.com/questions/32068537/generate-table-of-contents-from-markdown-in-php +function wiki_toc($content) { + // ensure using only "\n" as line-break + $source = str_replace(["\r\n", "\r"], "\n", $content); + + // look for markdown TOC items + preg_match_all( + '/^(?:=|-|#).*$/m', + $source, + $matches, + PREG_PATTERN_ORDER | PREG_OFFSET_CAPTURE + ); + + // preprocess: iterate matched lines to create an array of items + // where each item is an array(level, text) + $file_size = strlen($source); + foreach ($matches[0] as $item) { + $found_mark = substr($item[0], 0, 1); + if ($found_mark == '#') { + // text is the found item + $item_text = $item[0]; + $item_level = strrpos($item_text, '#') + 1; + $item_text = substr($item_text, $item_level); + } else { + // text is the previous line (empty if <hr>) + $item_offset = $item[1]; + $prev_line_offset = strrpos($source, "\n", -($file_size - $item_offset + 2)); + $item_text = + substr($source, $prev_line_offset, $item_offset - $prev_line_offset - 1); + $item_text = trim($item_text); + $item_level = $found_mark == '=' ? 1 : 2; + } + if (!trim($item_text) OR strpos($item_text, '|') !== FALSE) { + // item is an horizontal separator or a table header, don't mind + continue; + } + $raw_toc[] = ['level' => $item_level, 'text' => trim($item_text)]; + } + $o = ''; + foreach($raw_toc as $t) { + $level = intval($t['level']); + $text = $t['text']; + switch ($level) { + case 1: + $li = '* '; + break; + case 2: + $li = ' * '; + break; + case 3: + $li = ' * '; + break; + case 4: + $li = ' * '; + break; + default: + $li = '* '; + break; + } + $o .= $li . $text . "\n"; + } + return $o; +} diff --git a/view/tpl/wiki.tpl b/view/tpl/wiki.tpl index 1d8570828..7617808f4 100644 --- a/view/tpl/wiki.tpl +++ b/view/tpl/wiki.tpl @@ -190,6 +190,7 @@ $(document).ready(function () { wiki_refresh_page_list(); + $("#wiki-toc").toc({content: "#wiki-preview", headings: "h1,h2,h3,h4"}); // Show Edit tab first. Otherwise the Ace editor does not load. $("#wiki-nav-tabs li:eq(1) a").tab('show'); }); @@ -203,6 +204,7 @@ $.post("wiki/{{$channel}}/preview", {content: editor.getValue(), resource_id: window.wiki_resource_id}, function (data) { if (data.success) { $('#wiki-preview').html(data.html); + $("#wiki-toc").toc({content: "#wiki-preview", headings: "h1,h2,h3,h4"}); } else { window.console.log('Error previewing page.'); } |