1 <?php |
|
2 // vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: |
|
3 /** |
|
4 * Mediawiki: Parses for links to (inter)wiki pages or images. |
|
5 * |
|
6 * Text_Wiki rule parser to find links, it groups the 3 rules: |
|
7 * # Wikilink: links to internal Wiki pages |
|
8 * # Interwiki: links to external Wiki pages (sister projects, interlangage) |
|
9 * # Image: Images |
|
10 * as defined by text surrounded by double brackets [[]] |
|
11 * Translated are the link itself, the section (anchor) and alternate text |
|
12 * |
|
13 * PHP versions 4 and 5 |
|
14 * |
|
15 * @category Text |
|
16 * @package Text_Wiki |
|
17 * @author Bertrand Gugger <bertrand@toggg.com> |
|
18 * @author Paul M. Jones <pmjones@php.net> |
|
19 * @copyright 2005 bertrand Gugger |
|
20 * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 |
|
21 * @version CVS: $Id: Wikilink.php,v 1.7 2006/02/25 13:34:50 toggg Exp $ |
|
22 * @link http://pear.php.net/package/Text_Wiki |
|
23 */ |
|
24 |
|
25 /** |
|
26 * Wikilink, Interwiki and Image rules parser class for Mediawiki. |
|
27 * This class implements a Text_Wiki_Parse to find links marked |
|
28 * in source by text surrounded by 2 opening/closing brackets as |
|
29 * [[Wiki page name#Section|Alternate text]] |
|
30 * On parsing, the link is replaced with a token. |
|
31 * |
|
32 * @category Text |
|
33 * @package Text_Wiki |
|
34 * @author Bertrand Gugger <bertrand@toggg.com> |
|
35 * @copyright 2005 bertrand Gugger |
|
36 * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 |
|
37 * @version Release: @package_version@ |
|
38 * @link http://pear.php.net/package/Text_Wiki |
|
39 * @see Text_Wiki_Parse::Text_Wiki_Parse() |
|
40 */ |
|
41 class Text_Wiki_Parse_Wikilink extends Text_Wiki_Parse { |
|
42 |
|
43 /** |
|
44 * Configuration for this rule (Wikilink) |
|
45 * |
|
46 * @access public |
|
47 * @var array |
|
48 */ |
|
49 var $conf = array( |
|
50 'spaceUnderscore' => true, |
|
51 'project' => array('demo', 'd'), |
|
52 'url' => 'http://example.com/en/page=%s', |
|
53 'langage' => 'en' |
|
54 ); |
|
55 |
|
56 /** |
|
57 * Configuration for the Image rule |
|
58 * |
|
59 * @access public |
|
60 * @var array |
|
61 */ |
|
62 var $imageConf = array( |
|
63 'prefix' => array('Image', 'image') |
|
64 ); |
|
65 |
|
66 /** |
|
67 * Configuration for the Interwiki rule |
|
68 * |
|
69 * @access public |
|
70 * @var array |
|
71 */ |
|
72 var $interwikiConf = array( |
|
73 'sites' => array( |
|
74 'manual' => 'http://www.php.net/manual/en/%s', |
|
75 'pear' => 'http://pear.php.net/package/%s', |
|
76 'bugs' => 'http://pear.php.net/package/%s/bugs' |
|
77 ), |
|
78 'interlangage' => array('en', 'de', 'fr') |
|
79 ); |
|
80 |
|
81 /** |
|
82 * The regular expression used to parse the source text and find |
|
83 * matches conforming to this rule. Used by the parse() method. |
|
84 * |
|
85 * @access public |
|
86 * @var string |
|
87 * @see Text_Wiki_Parse::parse() |
|
88 */ |
|
89 var $regex = '/(?<!\[)\[\[(?!\[)\s*(:?)((?:[^:]+:)+)?([^:]+)(?:#(.*))?\s*(?:\|(((?R))|.*))?]]/msU'; |
|
90 |
|
91 /** |
|
92 * Constructor. |
|
93 * We override the constructor to get Image and Interwiki config |
|
94 * |
|
95 * @param object &$obj the base conversion handler |
|
96 * @return The parser object |
|
97 * @access public |
|
98 */ |
|
99 function Text_Wiki_Parse_Wikilink(&$obj) |
|
100 { |
|
101 $default = $this->conf; |
|
102 parent::Text_Wiki_Parse($obj); |
|
103 |
|
104 if ( defined('IN_ENANO_INSTALL') ) |
|
105 { |
|
106 // This doesn't really matter in the installer |
|
107 $this->imageConf = array( |
|
108 'prefix' => array(':File:') |
|
109 ); |
|
110 } |
|
111 else |
|
112 { |
|
113 global $paths; |
|
114 $this->imageConf = array( |
|
115 'prefix' => array(':' . $paths->nslist['File']) |
|
116 ); |
|
117 } |
|
118 |
|
119 // override config options for image if specified |
|
120 if (in_array('Image', $this->wiki->disable)) { |
|
121 $this->imageConf['prefix'] = array(); |
|
122 } else { |
|
123 if (isset($this->wiki->parseConf['Image']) && |
|
124 is_array($this->wiki->parseConf['Image'])) { |
|
125 $this->imageConf = array_merge( |
|
126 $this->imageConf, |
|
127 $this->wiki->parseConf['Image'] |
|
128 ); |
|
129 } |
|
130 } |
|
131 |
|
132 // override config options for interwiki if specified |
|
133 if (in_array('Interwiki', $this->wiki->disable)) { |
|
134 $this->interwikiConf['sites'] = array(); |
|
135 $this->interwikiConf['interlangage'] = array(); |
|
136 } else { |
|
137 if (isset($this->wiki->parseConf['Interwiki']) && |
|
138 is_array($this->wiki->parseConf['Interwiki'])) { |
|
139 $this->interwikiConf = array_merge( |
|
140 $this->interwikiConf, |
|
141 $this->wiki->parseConf['Interwiki'] |
|
142 ); |
|
143 } |
|
144 if (empty($this->conf['langage'])) { |
|
145 $this->interwikiConf['interlangage'] = array(); |
|
146 } |
|
147 } |
|
148 // convert the list of recognized schemes to a regex OR, |
|
149 /* $schemes = $this->getConf('schemes', $default['schemes']); |
|
150 $this->url = str_replace( '#delim#', $this->wiki->delim, |
|
151 '#(?:' . (is_array($schemes) ? implode('|', $schemes) : $schemes) . ')://' |
|
152 . $this->getConf('host_regexp', $default['host_regexp']) |
|
153 . $this->getConf('path_regexp', $default['path_regexp']) .'#'); */ |
|
154 } |
|
155 |
|
156 /** |
|
157 * Generates a replacement for the matched text. Token options are: |
|
158 * - 'page' => the name of the target wiki page |
|
159 * -'anchor' => the optional section in it |
|
160 * - 'text' => the optional alternate link text |
|
161 * |
|
162 * @access public |
|
163 * @param array &$matches The array of matches from parse(). |
|
164 * @return string token to be used as replacement |
|
165 */ |
|
166 function process(&$matches) |
|
167 { |
|
168 // Starting colon ? |
|
169 $colon = !empty($matches[1]); |
|
170 $auto = $interlang = $interwiki = $image = $site = ''; |
|
171 // Prefix ? |
|
172 if (!empty($matches[2])) { |
|
173 $prefix = explode(':', substr($matches[2], 0, -1)); |
|
174 $count = count($prefix); |
|
175 $i = -1; |
|
176 // Autolink |
|
177 if (isset($this->conf['project']) && |
|
178 in_array(trim($prefix[0]), $this->conf['project'])) { |
|
179 $auto = trim($prefix[0]); |
|
180 unset($prefix[0]); |
|
181 $i = 0; |
|
182 } |
|
183 while (++$i < $count) { |
|
184 $prefix[$i] = trim($prefix[$i]); |
|
185 // interlangage |
|
186 if (!$interlang && |
|
187 in_array($prefix[$i], $this->interwikiConf['interlangage'])) { |
|
188 $interlang = $prefix[$i]; |
|
189 unset($prefix[$i]); |
|
190 continue; |
|
191 } |
|
192 // image |
|
193 if (!$image && in_array($prefix[$i], $this->imageConf['prefix'])) { |
|
194 $image = $prefix[$i]; |
|
195 unset($prefix[$i]); |
|
196 break; |
|
197 } |
|
198 // interwiki |
|
199 if (isset($this->interwikiConf['sites'][$prefix[$i]])) { |
|
200 $interwiki = $this->interwikiConf['sites'][$prefix[$i]]; |
|
201 $site = $prefix[$i]; |
|
202 unset($prefix[$i]); |
|
203 } |
|
204 break; |
|
205 } |
|
206 if ($prefix) { |
|
207 $matches[3] = implode(':', $prefix) . ':' . $matches[3]; |
|
208 } |
|
209 } |
|
210 $text = empty($matches[5]) ? $matches[3] : $matches[5]; |
|
211 $matches[3] = trim($matches[3]); |
|
212 $matches[4] = empty($matches[4]) ? '' : trim($matches[4]); |
|
213 if ($this->conf['spaceUnderscore']) { |
|
214 $matches[3] = preg_replace('/\s+/', '_', $matches[3]); |
|
215 $matches[4] = preg_replace('/\s+/', '_', $matches[4]); |
|
216 } |
|
217 if ($image) { |
|
218 return $this->image($matches[3] . (empty($matches[4]) ? '' : '#' . $matches[4]), |
|
219 $text, $interlang, $colon); |
|
220 } |
|
221 if (!$interwiki && $interlang && isset($this->conf['url'])) { |
|
222 if ($interlang == $this->conf['langage']) { |
|
223 $interlang = ''; |
|
224 } else { |
|
225 $interwiki = $this->conf['url']; |
|
226 $site = isset($this->conf['project']) ? $this->conf['project'][0] : ''; |
|
227 } |
|
228 } |
|
229 if ($interwiki) { |
|
230 return $this->interwiki($site, $interwiki, |
|
231 $matches[3] . (empty($matches[4]) ? '' : '#' . $matches[4]), |
|
232 $text, $interlang, $colon); |
|
233 } |
|
234 if ($interlang) { |
|
235 $matches[3] = $interlang . ':' . $matches[3]; |
|
236 $text = (empty($matches[5]) ? $interlang . ':' : '') . $text; |
|
237 } |
|
238 // set the options |
|
239 $options = array( |
|
240 'page' => $matches[3], |
|
241 'anchor' => (empty($matches[4]) ? '' : $matches[4]), |
|
242 'text' => $text |
|
243 ); |
|
244 |
|
245 // create and return the replacement token |
|
246 return $this->wiki->addToken($this->rule, $options); |
|
247 } |
|
248 |
|
249 /** |
|
250 * Generates an image token. Token options are: |
|
251 * - 'src' => the name of the image file |
|
252 * - 'attr' => an array of attributes for the image: |
|
253 * | - 'alt' => the optional alternate image text |
|
254 * | - 'align => 'left', 'center' or 'right' |
|
255 * |
|
256 * @access public |
|
257 * @param array &$matches The array of matches from parse(). |
|
258 * @return string token to be used as replacement |
|
259 */ |
|
260 function image($name, $text, $interlang, $colon) |
|
261 { |
|
262 $attr = array('alt' => ''); |
|
263 // scan text for supplementary attibutes |
|
264 if (strpos($text, '|') !== false) { |
|
265 $splits = explode('|', $text); |
|
266 $sep = ''; |
|
267 foreach ($splits as $split) { |
|
268 switch (strtolower($split)) { |
|
269 case 'left': case 'center': case 'right': |
|
270 $attr['align'] = strtolower($split); |
|
271 break; |
|
272 default: |
|
273 $attr['alt'] .= $sep . $split; |
|
274 $sep = '|'; |
|
275 } |
|
276 } |
|
277 } else { |
|
278 $attr['alt'] = $text; |
|
279 } |
|
280 $options = array( |
|
281 'src' => ($interlang ? $interlang . ':' : '') . $name, |
|
282 'attr' => $attr); |
|
283 |
|
284 // create and return the replacement token |
|
285 return $this->wiki->addToken('Image', $options); |
|
286 } |
|
287 |
|
288 /** |
|
289 * Generates an interwiki token. Token options are: |
|
290 * - 'page' => the name of the target wiki page |
|
291 * - 'site' => the key for external site |
|
292 * - 'url' => the full target url |
|
293 * - 'text' => the optional alternate link text |
|
294 * |
|
295 * @access public |
|
296 * @param array &$matches The array of matches from parse(). |
|
297 * @return string token to be used as replacement |
|
298 */ |
|
299 function interwiki($site, $interwiki, $page, $text, $interlang, $colon) |
|
300 { |
|
301 if ($interlang) { |
|
302 $interwiki = preg_replace('/\b' . $this->conf['langage'] . '\b/i', |
|
303 $interlang, $interwiki); |
|
304 } |
|
305 // set the options |
|
306 $options = array( |
|
307 'page' => $page, |
|
308 'site' => $site, |
|
309 'url' => sprintf($interwiki, $page), |
|
310 'text' => $text |
|
311 ); |
|
312 |
|
313 // create and return the replacement token |
|
314 return $this->wiki->addToken('Interwiki', $options); |
|
315 } |
|
316 } |
|
317 ?> |
|