-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpico_toc.php
80 lines (74 loc) · 2.24 KB
/
pico_toc.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
<?php
/**
* Pico Insert TOC Plugin
* 記事のヘッダより見出しリストを自動生成するプラグイン
*
* @author TakamiChie
* @link https://onpu-tamago.net/
* @license http://opensource.org/licenses/MIT
* @version 1.1
*/
class Pico_TOC extends AbstractPicoPlugin {
const API_VERSION = 2;
protected $enabled = false;
public function onConfigLoaded(&$config)
{
$this->headinglevel = isset($config["headerlv"]["level"]) ?
$config["headerlv"]["level"] : 3;
}
public function onPageRendering(&$templateName, array &$twigVariables)
{
$content = $twigVariables["content"];
$twigVariables["TOC"] = $this->createTOC($content);
$twigVariables["content"] = $content;
}
/**
* TOCを生成する(テストのため、別メソッドに分離)
* @ref: http://1bit.mobi/20110106215505.html
*/
private function createTOC(&$content)
{
$toc = "";
$idcount = 1;
$currentLevel = 0;
$minlevel = 9;
$check = function(&$currentLevel, $level, &$toc){
$prevLevel = $currentLevel;
if($level > 0 && $prevLevel == $level) $toc .= '</li>';
while($currentLevel < $level)
{
$toc .= '<ol><li>';
$currentLevel++;
}
while($currentLevel > $level)
{
$toc .= '</li></ol>';
$currentLevel--;
}
if($level > 0 && $prevLevel > $level) $toc .= '</li>';
if($level > 0 && $prevLevel >= $level) $toc .= '<li>';
};
$content = preg_replace_callback('|<h([1-6])([^>]*)>(.*)</h\1>|',
function($matches) use (&$currentLevel, &$minlevel, &$idcount, &$toc, $check){
// id払い出し
$id = "toc_" . $idcount++;
// TOC処理
$minlevel = min($minlevel, $matches[1]);
$check($currentLevel, $matches[1], $toc);
$toc .= "<a href=\"#$id\">${matches[3]}</a>";
// return
return "<h${matches[1]} id=\"$id\"${matches[2]}>${matches[3]}</h${matches[1]}>";
},
$content);
$check($currentLevel, 0, $toc);
if($minlevel > 1)
{
// TOCの余計なolを削除
$toc = preg_replace(
'|(</li></ol>){' . $minlevel . '}$|', '\1',
preg_replace('|^(<ol><li>){' . $minlevel . '}|', '\1', $toc));
}
return $toc;
}
}
?>