|
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 // override config options for image if specified |
|
105 if (in_array('Image', $this->wiki->disable)) { |
|
106 $this->imageConf['prefix'] = array(); |
|
107 } else { |
|
108 if (isset($this->wiki->parseConf['Image']) && |
|
109 is_array($this->wiki->parseConf['Image'])) { |
|
110 $this->imageConf = array_merge( |
|
111 $this->imageConf, |
|
112 $this->wiki->parseConf['Image'] |
|
113 ); |
|
114 } |
|
115 } |
|
116 |
|
117 // override config options for interwiki if specified |
|
118 if (in_array('Interwiki', $this->wiki->disable)) { |
|
119 $this->interwikiConf['sites'] = array(); |
|
120 $this->interwikiConf['interlangage'] = array(); |
|
121 } else { |
|
122 if (isset($this->wiki->parseConf['Interwiki']) && |
|
123 is_array($this->wiki->parseConf['Interwiki'])) { |
|
124 $this->interwikiConf = array_merge( |
|
125 $this->interwikiConf, |
|
126 $this->wiki->parseConf['Interwiki'] |
|
127 ); |
|
128 } |
|
129 if (empty($this->conf['langage'])) { |
|
130 $this->interwikiConf['interlangage'] = array(); |
|
131 } |
|
132 } |
|
133 // convert the list of recognized schemes to a regex OR, |
|
134 /* $schemes = $this->getConf('schemes', $default['schemes']); |
|
135 $this->url = str_replace( '#delim#', $this->wiki->delim, |
|
136 '#(?:' . (is_array($schemes) ? implode('|', $schemes) : $schemes) . ')://' |
|
137 . $this->getConf('host_regexp', $default['host_regexp']) |
|
138 . $this->getConf('path_regexp', $default['path_regexp']) .'#'); */ |
|
139 } |
|
140 |
|
141 /** |
|
142 * Generates a replacement for the matched text. Token options are: |
|
143 * - 'page' => the name of the target wiki page |
|
144 * -'anchor' => the optional section in it |
|
145 * - 'text' => the optional alternate link text |
|
146 * |
|
147 * @access public |
|
148 * @param array &$matches The array of matches from parse(). |
|
149 * @return string token to be used as replacement |
|
150 */ |
|
151 function process(&$matches) |
|
152 { |
|
153 // Starting colon ? |
|
154 $colon = !empty($matches[1]); |
|
155 $auto = $interlang = $interwiki = $image = $site = ''; |
|
156 // Prefix ? |
|
157 if (!empty($matches[2])) { |
|
158 $prefix = explode(':', substr($matches[2], 0, -1)); |
|
159 $count = count($prefix); |
|
160 $i = -1; |
|
161 // Autolink |
|
162 if (isset($this->conf['project']) && |
|
163 in_array(trim($prefix[0]), $this->conf['project'])) { |
|
164 $auto = trim($prefix[0]); |
|
165 unset($prefix[0]); |
|
166 $i = 0; |
|
167 } |
|
168 while (++$i < $count) { |
|
169 $prefix[$i] = trim($prefix[$i]); |
|
170 // interlangage |
|
171 if (!$interlang && |
|
172 in_array($prefix[$i], $this->interwikiConf['interlangage'])) { |
|
173 $interlang = $prefix[$i]; |
|
174 unset($prefix[$i]); |
|
175 continue; |
|
176 } |
|
177 // image |
|
178 if (!$image && in_array($prefix[$i], $this->imageConf['prefix'])) { |
|
179 $image = $prefix[$i]; |
|
180 unset($prefix[$i]); |
|
181 break; |
|
182 } |
|
183 // interwiki |
|
184 if (isset($this->interwikiConf['sites'][$prefix[$i]])) { |
|
185 $interwiki = $this->interwikiConf['sites'][$prefix[$i]]; |
|
186 $site = $prefix[$i]; |
|
187 unset($prefix[$i]); |
|
188 } |
|
189 break; |
|
190 } |
|
191 if ($prefix) { |
|
192 $matches[3] = implode(':', $prefix) . ':' . $matches[3]; |
|
193 } |
|
194 } |
|
195 $text = empty($matches[5]) ? $matches[3] : $matches[5]; |
|
196 $matches[3] = trim($matches[3]); |
|
197 $matches[4] = empty($matches[4]) ? '' : trim($matches[4]); |
|
198 if ($this->conf['spaceUnderscore']) { |
|
199 $matches[3] = preg_replace('/\s+/', '_', $matches[3]); |
|
200 $matches[4] = preg_replace('/\s+/', '_', $matches[4]); |
|
201 } |
|
202 if ($image) { |
|
203 return $this->image($matches[3] . (empty($matches[4]) ? '' : '#' . $matches[4]), |
|
204 $text, $interlang, $colon); |
|
205 } |
|
206 if (!$interwiki && $interlang && isset($this->conf['url'])) { |
|
207 if ($interlang == $this->conf['langage']) { |
|
208 $interlang = ''; |
|
209 } else { |
|
210 $interwiki = $this->conf['url']; |
|
211 $site = isset($this->conf['project']) ? $this->conf['project'][0] : ''; |
|
212 } |
|
213 } |
|
214 if ($interwiki) { |
|
215 return $this->interwiki($site, $interwiki, |
|
216 $matches[3] . (empty($matches[4]) ? '' : '#' . $matches[4]), |
|
217 $text, $interlang, $colon); |
|
218 } |
|
219 if ($interlang) { |
|
220 $matches[3] = $interlang . ':' . $matches[3]; |
|
221 $text = (empty($matches[5]) ? $interlang . ':' : '') . $text; |
|
222 } |
|
223 // set the options |
|
224 $options = array( |
|
225 'page' => $matches[3], |
|
226 'anchor' => (empty($matches[4]) ? '' : $matches[4]), |
|
227 'text' => $text |
|
228 ); |
|
229 |
|
230 // create and return the replacement token |
|
231 return $this->wiki->addToken($this->rule, $options); |
|
232 } |
|
233 |
|
234 /** |
|
235 * Generates an image token. Token options are: |
|
236 * - 'src' => the name of the image file |
|
237 * - 'attr' => an array of attributes for the image: |
|
238 * | - 'alt' => the optional alternate image text |
|
239 * | - 'align => 'left', 'center' or 'right' |
|
240 * |
|
241 * @access public |
|
242 * @param array &$matches The array of matches from parse(). |
|
243 * @return string token to be used as replacement |
|
244 */ |
|
245 function image($name, $text, $interlang, $colon) |
|
246 { |
|
247 $attr = array('alt' => ''); |
|
248 // scan text for supplementary attibutes |
|
249 if (strpos($text, '|') !== false) { |
|
250 $splits = explode('|', $text); |
|
251 $sep = ''; |
|
252 foreach ($splits as $split) { |
|
253 switch (strtolower($split)) { |
|
254 case 'left': case 'center': case 'right': |
|
255 $attr['align'] = strtolower($split); |
|
256 break; |
|
257 default: |
|
258 $attr['alt'] .= $sep . $split; |
|
259 $sep = '|'; |
|
260 } |
|
261 } |
|
262 } else { |
|
263 $attr['alt'] = $text; |
|
264 } |
|
265 $options = array( |
|
266 'src' => ($interlang ? $interlang . ':' : '') . $name, |
|
267 'attr' => $attr); |
|
268 |
|
269 // create and return the replacement token |
|
270 return $this->wiki->addToken('Image', $options); |
|
271 } |
|
272 |
|
273 /** |
|
274 * Generates an interwiki token. Token options are: |
|
275 * - 'page' => the name of the target wiki page |
|
276 * - 'site' => the key for external site |
|
277 * - 'url' => the full target url |
|
278 * - 'text' => the optional alternate link text |
|
279 * |
|
280 * @access public |
|
281 * @param array &$matches The array of matches from parse(). |
|
282 * @return string token to be used as replacement |
|
283 */ |
|
284 function interwiki($site, $interwiki, $page, $text, $interlang, $colon) |
|
285 { |
|
286 if ($interlang) { |
|
287 $interwiki = preg_replace('/\b' . $this->conf['langage'] . '\b/i', |
|
288 $interlang, $interwiki); |
|
289 } |
|
290 // set the options |
|
291 $options = array( |
|
292 'page' => $page, |
|
293 'site' => $site, |
|
294 'url' => sprintf($interwiki, $page), |
|
295 'text' => $text |
|
296 ); |
|
297 |
|
298 // create and return the replacement token |
|
299 return $this->wiki->addToken('Interwiki', $options); |
|
300 } |
|
301 } |
|
302 ?> |