OSDN Git Service

BugTrack/2361 Simple Pagename URL for ls2 plugin
[pukiwiki/pukiwiki.git] / plugin / ls2.inc.php
1 <?php
2 // PukiWiki - Yet another WikiWikiWeb clone.
3 // ls2.inc.php
4 // Copyright
5 //   2002-2017  PukiWiki Development Team
6 //   2002       panda  http://home.arino.jp/?ls2.inc.php 
7 //   2002       Y.MASUI GPL2 http://masui.net/pukiwiki/ masui@masui.net (ls.inc.php)
8 // License: GPL version 2
9 //
10 // List plugin 2
11
12 /*
13  * 配下のページや、その見出し(*,**,***)の一覧を表示する
14  * Usage
15  *  #ls2(pattern[,title|include|link|reverse|compact, ...],heading title)
16  *
17  * pattern  : 省略するときもカンマが必要
18  * 'title'  : 見出しの一覧を表示する
19  * 'include': インクルードしているページの見出しを再帰的に列挙する
20  * 'link   ': actionプラグインを呼び出すリンクを表示
21  * 'reverse': ページの並び順を反転し、降順にする
22  * 'compact': 見出しレベルを調整する
23  *     PLUGIN_LS2_LIST_COMPACTがTRUEの時は無効(変化しない)
24  * heading title: 見出しのタイトルを指定する (linkを指定した時のみ)
25  */
26
27 // 見出しアンカーの書式
28 define('PLUGIN_LS2_ANCHOR_PREFIX', '#content_1_');
29
30 // 見出しアンカーの開始番号
31 define('PLUGIN_LS2_ANCHOR_ORIGIN', 0);
32
33 // 見出しレベルを調整する(デフォルト値)
34 define('PLUGIN_LS2_LIST_COMPACT', FALSE);
35
36 function plugin_ls2_action()
37 {
38         global $vars, $_ls2_msg_title;
39
40         $params = array();
41         $keys   = array('title', 'include', 'reverse');
42         foreach ($keys as $key)
43                 $params[$key] = isset($vars[$key]);
44
45         $prefix = isset($vars['prefix']) ? $vars['prefix'] : '';
46         $body = plugin_ls2_show_lists($prefix, $params);
47
48         return array('body'=>$body,
49                 'msg'=>str_replace('$1', htmlsc($prefix), $_ls2_msg_title));
50 }
51
52 function plugin_ls2_convert()
53 {
54         global $script, $vars, $_ls2_msg_title;
55
56         $params = array(
57                 'link'    => FALSE,
58                 'title'   => FALSE,
59                 'include' => FALSE,
60                 'reverse' => FALSE,
61                 'compact' => PLUGIN_LS2_LIST_COMPACT,
62                 '_args'   => array(),
63                 '_done'   => FALSE
64         );
65
66         $args = array();
67         $prefix = '';
68         if (func_num_args()) {
69                 $args   = func_get_args();
70                 $prefix = array_shift($args);
71         }
72         if ($prefix == '') $prefix = strip_bracket($vars['page']) . '/';
73
74         foreach ($args as $arg)
75                 plugin_ls2_check_arg($arg, $params);
76
77         $title = (! empty($params['_args'])) ? join(',', $params['_args']) :   // Manual
78                 str_replace('$1', htmlsc($prefix), $_ls2_msg_title); // Auto
79
80         if (! $params['link'])
81                 return plugin_ls2_show_lists($prefix, $params);
82
83         $tmp = array();
84         $tmp[] = 'plugin=ls2&amp;prefix=' . rawurlencode($prefix);
85         if (isset($params['title']))   $tmp[] = 'title=1';
86         if (isset($params['include'])) $tmp[] = 'include=1';
87
88         return '<p><a href="' . $script . '?' . join('&amp;', $tmp) . '">' .
89                 $title . '</a></p>' . "\n";
90 }
91
92 function plugin_ls2_show_lists($prefix, & $params)
93 {
94         global $_ls2_err_nopages;
95
96         $pages = array();
97         if ($prefix != '') {
98                 foreach (get_existpages() as $_page)
99                         if (strpos($_page, $prefix) === 0)
100                                 $pages[] = $_page;
101         } else {
102                 $pages = get_existpages();
103         }
104
105         natcasesort($pages);
106         if ($params['reverse']) $pages = array_reverse($pages);
107
108         foreach ($pages as $page) $params['page_ ' . $page] = 0;
109
110         if (empty($pages)) {
111                 return str_replace('$1', htmlsc($prefix), $_ls2_err_nopages);
112         } else {
113                 $params['result'] = $params['saved'] = array();
114                 foreach ($pages as $page)
115                         plugin_ls2_get_headings($page, $params, 1);
116                 return join("\n", $params['result']) . join("\n", $params['saved']);
117         }
118 }
119
120 function plugin_ls2_get_headings($page, & $params, $level, $include = FALSE)
121 {
122         global $script;
123         static $_ls2_anchor = 0;
124
125         // ページが未表示のとき
126         $is_done = (isset($params["page_$page"]) && $params["page_$page"] > 0);
127         if (! $is_done) $params["page_$page"] = ++$_ls2_anchor;
128
129         $s_page = htmlsc($page);
130         $title  = $s_page . ' ' . get_pg_passage($page, FALSE);
131         $href   = $script . '?' . pagename_urlencode($page);
132
133         plugin_ls2_list_push($params, $level);
134         $ret = $include ? '<li>include ' : '<li>';
135
136         if ($params['title'] && $is_done) {
137                 $ret .= '<a href="' . $href . '" title="' . $title . '">' . $s_page . '</a> ';
138                 $ret .= '<a href="#list_' . $params["page_$page"] . '"><sup>&uarr;</sup></a>';
139                 array_push($params['result'], $ret);
140                 return;
141         }
142
143         $ret .= '<a id="list_' . $params["page_$page"] . '" href="' . $href .
144                 '" title="' . $title . '">' . $s_page . '</a>';
145         array_push($params['result'], $ret);
146
147         $anchor = PLUGIN_LS2_ANCHOR_ORIGIN;
148         $matches = array();
149         foreach (get_source($page) as $line) {
150                 if ($params['title'] && preg_match('/^(\*{1,3})/', $line, $matches)) {
151                         $id    = make_heading($line);
152                         $level = strlen($matches[1]);
153                         $id    = PLUGIN_LS2_ANCHOR_PREFIX . $anchor++;
154                         plugin_ls2_list_push($params, $level + strlen($level));
155                         array_push($params['result'],
156                                 '<li><a href="' . $href . $id . '">' . $line . '</a>');
157                 } else if ($params['include'] &&
158                         preg_match('/^#include\((.+)\)/', $line, $matches) &&
159                         is_page($matches[1]))
160                 {
161                         plugin_ls2_get_headings($matches[1], $params, $level + 1, TRUE);
162                 }
163         }
164 }
165
166 //リスト構造を構築する
167 function plugin_ls2_list_push(& $params, $level)
168 {
169         $result = & $params['result'];
170         $saved  = & $params['saved'];
171         $cont   = TRUE;
172         $open   = '<ul%s>';
173         $close  = '</li></ul>';
174
175         while (count($saved) > $level || (! empty($saved) && $saved[0] != $close))
176                 array_push($result, array_shift($saved));
177
178         $margin = $level - count($saved);
179
180         // count($saved)を増やす
181         while (count($saved) < ($level - 1)) array_unshift($saved, '');
182
183         if (count($saved) < $level) {
184                 $cont = FALSE;
185                 array_unshift($saved, $close);
186
187                 $left = 0;
188                 if ($params['compact']) {
189                         $left = 1;   // マージンを固定
190                         $level -= ($margin - 1); // レベルを修正
191                 } else {
192                         $left = $margin;
193                 }
194                 $str = sprintf(pkwk_list_attrs_template(), $level, $left);
195                 array_push($result, sprintf($open, $str));
196         }
197
198         if ($cont) array_push($result, '</li>');
199 }
200
201 // オプションを解析する
202 function plugin_ls2_check_arg($value, & $params)
203 {
204         if ($value == '') {
205                 $params['_done'] = TRUE;
206                 return;
207         }
208
209         if (! $params['_done']) {
210                 foreach (array_keys($params) as $param) {
211                         if (strtolower($value)  == $param &&
212                             preg_match('/^[a-z]/', $param)) {
213                                 $params[$param] = TRUE;
214                                 return;
215                         }
216                 }
217                 $params['_done'] = TRUE;
218         }
219
220         $params['_args'][] = htmlsc($value); // Link title
221 }