Merge pull request #445 from anaqreon/wiki

Table of contents with links is generated if [toc] is found in Markdown text
This commit is contained in:
hubzilla 2016-07-01 11:57:48 +10:00 committed by GitHub
commit eef8f3b417
3 changed files with 81 additions and 3 deletions

View File

@ -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);

View File

@ -493,4 +493,79 @@ function wiki_convert_links($s, $wikiURL) {
}
}
return $s;
}
}
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;
}

View File

@ -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.');
}