OSDN Git Service

BugTrack/2367 CSS reformat
[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 $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="' . get_base_uri() . '?' . 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                         $read_pages = array(); // read pages per page
116                         plugin_ls2_get_headings($page, $params, 1, false, $read_pages);
117                 }
118                 return join("\n", $params['result']) . join("\n", $params['saved']);
119         }
120 }
121
122 function plugin_ls2_get_headings($page, & $params, $level, $include = FALSE,
123         &$read_pages)
124 {
125         static $_ls2_anchor = 0;
126
127         if (is_null($read_pages)) {
128                 $read_pages = array();
129         }
130         // ページが未表示のとき
131         $is_done = isset($read_pages[$page]);
132         if (! $is_done) $params["page_$page"] = ++$_ls2_anchor;
133
134         $s_page = htmlsc($page);
135         $attrs = get_page_link_a_attrs($page);
136         $href   = get_page_uri($page);
137
138         plugin_ls2_list_push($params, $level);
139         $ret = $include ? '<li>include ' : '<li>';
140
141         if ($is_done) {
142                 $ret .= '<a href="' . $href . '" class="' .
143                         $attrs['class'] . '" data-mtime="' . $attrs['data_mtime'] .
144                         '">' . $s_page . '</a> ';
145                 $ret .= '<a href="#list_' . $params["page_$page"] . '"><sup>&uarr;</sup></a>';
146                 array_push($params['result'], $ret);
147                 return;
148         }
149
150         $ret .= '<a id="list_' . $params["page_$page"] . '" href="' . $href .
151                 '" class="' . $attrs['class'] . '" data-mtime="' .
152                 $attrs['data_mtime'] . '">' . $s_page . '</a>';
153         array_push($params['result'], $ret);
154
155         $anchor = PLUGIN_LS2_ANCHOR_ORIGIN;
156         $matches = array();
157         $is_title = $params['title'];
158         $is_include = $params['include'];
159         if (!$is_title && !$is_include) {
160                 return;
161         }
162         foreach (get_source($page) as $line) {
163                 if ($is_title && preg_match('/^(\*{1,3})/', $line, $matches)) {
164                         $id    = make_heading($line);
165                         $heading_level = strlen($matches[1]);
166                         $id    = PLUGIN_LS2_ANCHOR_PREFIX . $anchor++;
167                         plugin_ls2_list_push($params, $level + $heading_level);
168                         array_push($params['result'],
169                                 '<li><a href="' . $href . $id . '">' . $line . '</a>');
170                 } else if ($is_include &&
171                         preg_match('/^#include\((.+)\)/', $line, $matches)) {
172                         $include_args = $matches[1];
173                         $page2 = $include_args;
174                         $m2 = null;
175                         if (preg_match('#^(("([^"]+)")|([^",]+))#', $include_args, $m2)) {
176                                 if ($m2[3]) {
177                                         $page2 = $m2[3];
178                                 } else if ($m2[4]) {
179                                         $page2 = $m2[4];
180                                 }
181                         }
182                         $sub_page = get_fullname($page2, $page);
183                         if (is_page($sub_page)) {
184                                 $read_pages[$page] = 1;
185                                 if (!isset($read_pages[$sub_page])) {
186                                         plugin_ls2_get_headings($sub_page, $params,
187                                                 $level + 1, TRUE, $read_pages);
188                                 }
189                         }
190                 }
191         }
192 }
193
194 //リスト構造を構築する
195 function plugin_ls2_list_push(& $params, $level)
196 {
197         $result = & $params['result'];
198         $saved  = & $params['saved'];
199         $cont   = TRUE;
200         $open   = '<ul%s>';
201         $close  = '</li></ul>';
202
203         while (count($saved) > $level || (! empty($saved) && $saved[0] != $close))
204                 array_push($result, array_shift($saved));
205
206         $margin = $level - count($saved);
207
208         // count($saved)を増やす
209         while (count($saved) < ($level - 1)) array_unshift($saved, '');
210
211         if (count($saved) < $level) {
212                 $cont = FALSE;
213                 array_unshift($saved, $close);
214
215                 $left = 0;
216                 if ($params['compact']) {
217                         $left = 1;   // マージンを固定
218                         $level -= ($margin - 1); // レベルを修正
219                 } else {
220                         $left = $margin;
221                 }
222                 $str = sprintf(pkwk_list_attrs_template(), $level, $left);
223                 array_push($result, sprintf($open, $str));
224         }
225
226         if ($cont) array_push($result, '</li>');
227 }
228
229 // オプションを解析する
230 function plugin_ls2_check_arg($value, & $params)
231 {
232         if ($value == '') {
233                 $params['_done'] = TRUE;
234                 return;
235         }
236
237         if (! $params['_done']) {
238                 foreach (array_keys($params) as $param) {
239                         if (strtolower($value)  == $param &&
240                             preg_match('/^[a-z]/', $param)) {
241                                 $params[$param] = TRUE;
242                                 return;
243                         }
244                 }
245                 $params['_done'] = TRUE;
246         }
247
248         $params['_args'][] = htmlsc($value); // Link title
249 }