OSDN Git Service

Changed name.($autoalias=>$aliaspage, $autoalias_min_len=>$autoalias)
[pukiwiki/pukiwiki.git] / lib / make_link.php
1 <?php
2 // PukiWiki - Yet another WikiWikiWeb clone.
3 // $Id: make_link.php,v 1.17.2.3 2005/03/21 17:57:41 teanan Exp $
4 //
5 // Hyperlink-related functions
6
7 // Hyperlink decoration
8 function make_link($string, $page = '')
9 {
10         global $vars;
11         static $converter;
12
13         if (! isset($converter)) $converter = new InlineConverter();
14
15         $clone = $converter->get_clone($converter);
16
17         return $clone->convert($string, ($page != '') ? $page : $vars['page']);
18 }
19
20 // Converters of inline element
21 class InlineConverter
22 {
23         var $converters; // as array()
24         var $pattern;
25         var $pos;
26         var $result;
27
28         function get_clone($obj) {
29                 static $clone_func;
30
31                 if (! isset($clone_func)) {
32                         if (version_compare(PHP_VERSION, '5.0.0', '<')) {
33                                 $clone_func = create_function('$a', 'return $a;');
34                         } else {
35                                 $clone_func = create_function('$a', 'return clone $a;');
36                         }
37                 }
38                 return $clone_func($obj);
39         }
40
41         function __clone() {
42                 $converters = array();
43                 foreach ($this->converters as $key=>$converter) {
44                         $converters[$key] = $this->get_clone($converter);
45                 }
46                 $this->converters = $converters;
47         }
48
49         function InlineConverter($converters = NULL, $excludes = NULL)
50         {
51                 if ($converters === NULL) {
52                         $converters = array(
53                                 'plugin',        // Inline plugins
54                                 'note',          // Footnotes
55                                 'url',           // URLs
56                                 'url_interwiki', // URLs (interwiki definition)
57                                 'mailto',        // mailto: URL schemes
58                                 'interwikiname', // InterWikiNames
59                                 'autoalias',     // AutoAlias
60                                 'autolink',      // AutoLinks
61                                 'bracketname',   // BracketNames
62                                 'wikiname',      // WikiNames
63                                 'autoalias_a',   // AutoAlias(alphabet)
64                                 'autolink_a',    // AutoLinks(alphabet)
65                         );
66                 }
67
68                 if ($excludes !== NULL)
69                         $converters = array_diff($converters, $excludes);
70
71                 $this->converters = $patterns = array();
72                 $start = 1;
73
74                 foreach ($converters as $name) {
75                         $classname = 'Link_' . $name;
76                         $converter = new $classname($start);
77                         $pattern   = $converter->get_pattern();
78                         if ($pattern === FALSE) continue;
79
80                         $patterns[] = '(' . "\n" . $pattern . "\n" . ')';
81                         $this->converters[$start] = $converter;
82                         $start += $converter->get_count();
83                         ++$start;
84                 }
85                 $this->pattern = join('|', $patterns);
86         }
87
88         function convert($string, $page)
89         {
90                 $this->page   = $page;
91                 $this->result = array();
92
93                 $string = preg_replace_callback('/' . $this->pattern . '/x',
94                         array(& $this, 'replace'), $string);
95
96                 $arr = explode("\x08", make_line_rules(htmlspecialchars($string)));
97                 $retval = '';
98                 while (! empty($arr)) {
99                         $retval .= array_shift($arr) . array_shift($this->result);
100                 }
101                 return $retval;
102         }
103
104         function replace($arr)
105         {
106                 $obj = $this->get_converter($arr);
107
108                 $this->result[] = ($obj !== NULL && $obj->set($arr, $this->page) !== FALSE) ?
109                         $obj->toString() : make_line_rules(htmlspecialchars($arr[0]));
110
111                 return "\x08"; // Add a mark into latest processed part
112         }
113
114         function get_objects($string, $page)
115         {
116                 $matches = $arr = array();
117                 preg_match_all('/' . $this->pattern . '/x', $string, $matches, PREG_SET_ORDER);
118                 foreach ($matches as $match) {
119                         $obj = $this->get_converter($match);
120                         if ($obj->set($match, $page) !== FALSE) {
121                                 $arr[] = $this->get_clone($obj);
122                                 if ($obj->body != '')
123                                         $arr = array_merge($arr, $this->get_objects($obj->body, $page));
124                         }
125                 }
126                 return $arr;
127         }
128
129         function & get_converter(& $arr)
130         {
131                 foreach (array_keys($this->converters) as $start) {
132                         if ($arr[$start] == $arr[0])
133                                 return $this->converters[$start];
134                 }
135                 return NULL;
136         }
137 }
138
139 // Base class of inline elements
140 class Link
141 {
142         var $start;   // Origin number of parentheses (0 origin)
143         var $text;    // Matched string
144
145         var $type;
146         var $page;
147         var $name;
148         var $body;
149         var $alias;
150
151         // Constructor
152         function Link($start)
153         {
154                 $this->start = $start;
155         }
156
157         // Return a regex pattern to match
158         function get_pattern() {}
159
160         // Return number of parentheses (except (?:...) )
161         function get_count() {}
162
163         // Set pattern that matches
164         function set($arr, $page) {}
165
166         function toString() {}
167
168         // Private: Get needed parts from a matched array()
169         function splice($arr) {
170                 $count = $this->get_count() + 1;
171                 $arr   = array_pad(array_splice($arr, $this->start, $count), $count, '');
172                 $this->text = $arr[0];
173                 return $arr;
174         }
175
176         // Set basic parameters
177         function setParam($page, $name, $body, $type = '', $alias = '')
178         {
179                 static $converter = NULL;
180
181                 $this->page = $page;
182                 $this->name = $name;
183                 $this->body = $body;
184                 $this->type = $type;
185                 if (is_url($alias) && preg_match('/\.(gif|png|jpe?g)$/i', $alias)) {
186                         $alias = htmlspecialchars($alias);
187                         $alias = '<img src="' . $alias . '" alt="' . $name . '" />';
188                 } else if ($alias != '') {
189                         if ($converter === NULL)
190                                 $converter = new InlineConverter(array('plugin'));
191
192                         $alias = make_line_rules($converter->convert($alias, $page));
193
194                         // BugTrack/669: A hack removing anchor tags added by AutoLink
195                         $alias = preg_replace('#</?a[^>]*>#i', '', $alias);
196                 }
197                 $this->alias = $alias;
198
199                 return TRUE;
200         }
201 }
202
203 // Inline plugins
204 class Link_plugin extends Link
205 {
206         var $pattern;
207         var $plain,$param;
208
209         function Link_plugin($start)
210         {
211                 parent::Link($start);
212         }
213
214         function get_pattern()
215         {
216                 $this->pattern = <<<EOD
217 &
218 (      # (1) plain
219  (\w+) # (2) plugin name
220  (?:
221   \(
222    ((?:(?!\)[;{]).)*) # (3) parameter
223   \)
224  )?
225 )
226 EOD;
227                 return <<<EOD
228 {$this->pattern}
229 (?:
230  \{
231   ((?:(?R)|(?!};).)*) # (4) body
232  \}
233 )?
234 ;
235 EOD;
236         }
237
238         function get_count()
239         {
240                 return 4;
241         }
242
243         function set($arr, $page)
244         {
245                 list($all, $this->plain, $name, $this->param, $body) = $this->splice($arr);
246
247                 // Re-get true plugin name and patameters (for PHP 4.1.2)
248                 $matches = array();
249                 if (preg_match('/^' . $this->pattern . '/x', $all, $matches)
250                         && $matches[1] != $this->plain) 
251                         list(, $this->plain, $name, $this->param) = $matches;
252
253                 return parent::setParam($page, $name, $body, 'plugin');
254         }
255
256         function toString()
257         {
258                 $body = ($this->body == '') ? '' : make_link($this->body);
259                 $str = FALSE;
260
261                 // Try to call the plugin
262                 if (exist_plugin_inline($this->name))
263                         $str = do_plugin_inline($this->name, $this->param, $body);
264
265                 if ($str !== FALSE) {
266                         return $str; // Succeed
267                 } else {
268                         // No such plugin, or Failed
269                         $body = (($body == '') ? '' : '{' . $body . '}') . ';';
270                         return make_line_rules(htmlspecialchars('&' . $this->plain) . $body);
271                 }
272         }
273 }
274
275 // Footnotes
276 class Link_note extends Link
277 {
278         function Link_note($start)
279         {
280                 parent::Link($start);
281         }
282
283         function get_pattern()
284         {
285                 return <<<EOD
286 \(\(
287  ((?:(?R)|(?!\)\)).)*) # (1) note body
288 \)\)
289 EOD;
290         }
291
292         function get_count()
293         {
294                 return 1;
295         }
296
297         function set($arr, $page)
298         {
299                 global $foot_explain, $script, $vars;
300                 static $note_id = 0;
301
302                 list(, $body) = $this->splice($arr);
303
304                 $id   = ++$note_id;
305                 $note = make_link($body);
306                 $page = isset($vars['page']) ? rawurlencode($vars['page']) : '';
307
308                 // Footnote
309                 $foot_explain[$id] = '<a id="notefoot_' . $id . '" href="' .
310                         $script . '?' . $page . '#notetext_' . $id .
311                         '" class="note_super">*' . $id . '</a>' . "\n" .
312                         '<span class="small">' . $note . '</span><br />';
313
314                 // A hyperlink, content-body to footnote
315                 $name = '<a id="notetext_' . $id . '" href="' . $script . '?' . $page .
316                         '#notefoot_' . $id . '" class="note_super" title="' .
317                         htmlspecialchars(strip_tags($note)) . '">*' . $id . '</a>';
318
319                 return parent::setParam($page, $name, $body);
320         }
321
322         function toString()
323         {
324                 return $this->name;
325         }
326 }
327
328 // URLs
329 class Link_url extends Link
330 {
331         function Link_url($start)
332         {
333                 parent::Link($start);
334         }
335
336         function get_pattern()
337         {
338                 $s1 = $this->start + 1;
339                 return <<<EOD
340 (\[\[             # (1) open bracket
341  ((?:(?!\]\]).)+) # (2) alias
342  (?:>|:)
343 )?
344 (                 # (3) url
345  (?:(?:https?|ftp|news):\/\/|mailto:)[\w\/\@\$()!?&%#:;.,~'=*+-]+
346 )
347 (?($s1)\]\])      # close bracket
348 EOD;
349         }
350
351         function get_count()
352         {
353                 return 3;
354         }
355
356         function set($arr, $page)
357         {
358                 list(, , $alias, $name) = $this->splice($arr);
359                 return parent::setParam($page, htmlspecialchars($name),
360                         '', 'url', $alias == '' ? $name : $alias);
361         }
362
363         function toString()
364         {
365                 if (FALSE) {
366                         $rel = '';
367                 } else {
368                         $rel = ' rel="nofollow"';
369                 }
370                 return '<a href="' . $this->name . '"' . $rel . '>' . $this->alias . '</a>';
371         }
372 }
373
374 // URLs (InterWiki definition on "InterWikiName")
375 class Link_url_interwiki extends Link
376 {
377         function Link_url_interwiki($start)
378         {
379                 parent::Link($start);
380         }
381
382         function get_pattern()
383         {
384                 return <<<EOD
385 \[       # open bracket
386 (        # (1) url
387  (?:(?:https?|ftp|news):\/\/|\.\.?\/)[!~*'();\/?:\@&=+\$,%#\w.-]*
388 )
389 \s
390 ([^\]]+) # (2) alias
391 \]       # close bracket
392 EOD;
393         }
394
395         function get_count()
396         {
397                 return 2;
398         }
399
400         function set($arr, $page)
401         {
402                 list(, $name, $alias) = $this->splice($arr);
403                 return parent::setParam($page, htmlspecialchars($name), '', 'url', $alias);
404         }
405
406         function toString()
407         {
408                 return '<a href="' . $this->name . '" rel="nofollow">' . $this->alias . '</a>';
409         }
410 }
411
412 // mailto: URL schemes
413 class Link_mailto extends Link
414 {
415         var $is_image, $image;
416
417         function Link_mailto($start)
418         {
419                 parent::Link($start);
420         }
421
422         function get_pattern()
423         {
424                 $s1 = $this->start + 1;
425                 return <<<EOD
426 (?:
427  \[\[
428  ((?:(?!\]\]).)+)(?:>|:)  # (1) alias
429 )?
430 ([\w.-]+@[\w-]+\.[\w.-]+) # (2) mailto
431 (?($s1)\]\])              # close bracket if (1)
432 EOD;
433         }
434
435         function get_count()
436         {
437                 return 2;
438         }
439
440         function set($arr, $page)
441         {
442                 list(, $alias, $name) = $this->splice($arr);
443                 return parent::setParam($page, $name, '', 'mailto', $alias == '' ? $name : $alias);
444         }
445         
446         function toString()
447         {
448                 return '<a href="mailto:' . $this->name . '" rel="nofollow">' . $this->alias . '</a>';
449         }
450 }
451
452 // InterWikiName-rendered URLs
453 class Link_interwikiname extends Link
454 {
455         var $url    = '';
456         var $param  = '';
457         var $anchor = '';
458
459         function Link_interwikiname($start)
460         {
461                 parent::Link($start);
462         }
463
464         function get_pattern()
465         {
466                 $s2 = $this->start + 2;
467                 $s5 = $this->start + 5;
468                 return <<<EOD
469 \[\[                  # open bracket
470 (?:
471  ((?:(?!\]\]).)+)>    # (1) alias
472 )?
473 (\[\[)?               # (2) open bracket
474 ((?:(?!\s|:|\]\]).)+) # (3) InterWiki
475 (?<! > | >\[\[ )      # not '>' or '>[['
476 :                     # separator
477 (                     # (4) param
478  (\[\[)?              # (5) open bracket
479  (?:(?!>|\]\]).)+
480  (?($s5)\]\])         # close bracket if (5)
481 )
482 (?($s2)\]\])          # close bracket if (2)
483 \]\]                  # close bracket
484 EOD;
485         }
486
487         function get_count()
488         {
489                 return 5;
490         }
491
492         function set($arr, $page)
493         {
494                 global $script;
495
496                 list(, $alias, , $name, $this->param) = $this->splice($arr);
497
498                 $matches = array();
499                 if (preg_match('/^([^#]+)(#[A-Za-z][\w-]*)$/', $this->param, $matches))
500                         list(, $this->param, $this->anchor) = $matches;
501
502                 $url = get_interwiki_url($name, $this->param);
503                 $this->url = ($url === FALSE) ?
504                         $script . '?' . rawurlencode('[[' . $name . ':' . $this->param . ']]') :
505                         htmlspecialchars($url);
506
507                 return parent::setParam(
508                         $page,
509                         htmlspecialchars($name . ':' . $this->param),
510                         '',
511                         'InterWikiName',
512                         $alias == '' ? $name . ':' . $this->param : $alias
513                 );
514         }
515
516         function toString()
517         {
518                 return '<a href="' . $this->url . $this->anchor . '" title="' .
519                         $this->name . '" rel="nofollow">' . $this->alias . '</a>';
520         }
521 }
522
523 // BracketNames
524 class Link_bracketname extends Link
525 {
526         var $anchor, $refer;
527
528         function Link_bracketname($start)
529         {
530                 parent::Link($start);
531         }
532
533         function get_pattern()
534         {
535                 global $WikiName, $BracketName;
536
537                 $s2 = $this->start + 2;
538                 return <<<EOD
539 \[\[                     # Open bracket
540 (?:((?:(?!\]\]).)+)>)?   # (1) Alias
541 (\[\[)?                  # (2) Open bracket
542 (                        # (3) PageName
543  (?:$WikiName)
544  |
545  (?:$BracketName)
546 )?
547 (\#(?:[a-zA-Z][\w-]*)?)? # (4) Anchor
548 (?($s2)\]\])             # Close bracket if (2)
549 \]\]                     # Close bracket
550 EOD;
551         }
552
553         function get_count()
554         {
555                 return 4;
556         }
557
558         function set($arr, $page)
559         {
560                 global $WikiName;
561
562                 list(, $alias, , $name, $this->anchor) = $this->splice($arr);
563                 if ($name == '' && $this->anchor == '') return FALSE;
564
565                 if ($name == '' || ! preg_match('/^' . $WikiName . '$/', $name)) {
566                         if ($alias == '') $alias = $name . $this->anchor;
567                         if ($name != '') {
568                                 $name = get_fullname($name, $page);
569                                 if (! is_pagename($name)) return FALSE;
570                         }
571                 }
572
573                 return parent::setParam($page, $name, '', 'pagename', $alias);
574         }
575
576         function toString()
577         {
578                 return make_pagelink(
579                         $this->name,
580                         $this->alias,
581                         $this->anchor,
582                         $this->page
583                 );
584         }
585 }
586
587 // WikiNames
588 class Link_wikiname extends Link
589 {
590         function Link_wikiname($start)
591         {
592                 parent::Link($start);
593         }
594
595         function get_pattern()
596         {
597                 global $WikiName, $nowikiname;
598
599                 return $nowikiname ? FALSE : '(' . $WikiName . ')';
600         }
601
602         function get_count()
603         {
604                 return 1;
605         }
606
607         function set($arr, $page)
608         {
609                 list($name) = $this->splice($arr);
610                 return parent::setParam($page, $name, '', 'pagename', $name);
611         }
612
613         function toString()
614         {
615                 return make_pagelink(
616                         $this->name,
617                         $this->alias,
618                         '',
619                         $this->page
620                 );
621         }
622 }
623
624 // AutoLinks
625 class Link_autolink extends Link
626 {
627         var $forceignorepages = array();
628         var $auto;
629         var $auto_a; // alphabet only
630
631         function Link_autolink($start)
632         {
633                 global $autolink;
634
635                 parent::Link($start);
636
637                 if (! $autolink || ! file_exists(CACHE_DIR . 'autolink.dat'))
638                         return;
639
640                 @list($auto, $auto_a, $forceignorepages) = file(CACHE_DIR . 'autolink.dat');
641                 $this->auto   = $auto;
642                 $this->auto_a = $auto_a;
643                 $this->forceignorepages = explode("\t", trim($forceignorepages));
644         }
645
646         function get_pattern()
647         {
648                 return isset($this->auto) ? '(' . $this->auto . ')' : FALSE;
649         }
650
651         function get_count()
652         {
653                 return 1;
654         }
655
656         function set($arr, $page)
657         {
658                 global $WikiName;
659
660                 list($name) = $this->splice($arr);
661
662                 // Ignore pages listed, or Expire ones not found
663                 if (in_array($name, $this->forceignorepages) || ! is_page($name))
664                         return FALSE;
665
666                 return parent::setParam($page, $name, '', 'pagename', $name);
667         }
668
669         function toString()
670         {
671                 return make_pagelink($this->name, $this->alias, '', $this->page);
672         }
673 }
674
675 class Link_autolink_a extends Link_autolink
676 {
677         function Link_autolink_a($start)
678         {
679                 parent::Link_autolink($start);
680         }
681
682         function get_pattern()
683         {
684                 return isset($this->auto_a) ? '(' . $this->auto_a . ')' : FALSE;
685         }
686 }
687
688 // AutoAlias
689 class Link_autoalias extends Link
690 {
691         var $forceignorepages = array();
692         var $auto;
693         var $auto_a; // alphabet only
694
695         function Link_autoalias($start)
696         {
697                 global $autoalias, $aliaspage;
698
699                 parent::Link($start);
700
701                 if (!$autoalias || !file_exists(CACHE_DIR.'autoalias.dat') || $this->page==$aliaspage)
702                 {
703                         return;
704                 }
705                 @list($auto,$auto_a,$forceignorepages) = file(CACHE_DIR.'autoalias.dat');
706                 $this->auto = $auto;
707                 $this->auto_a = $auto_a;
708                 $this->forceignorepages = explode("\t", trim($forceignorepages));
709         }
710         function get_pattern()
711         {
712                 return isset($this->auto) ? '(' . $this->auto . ')' : FALSE;
713         }
714         function get_count()
715         {
716                 return 1;
717         }
718         function set($arr,$page)
719         {
720                 list($name) = $this->splice($arr);
721                 // Ignore pages listed
722                 if (in_array($name, $this->forceignorepages)) {
723                         return FALSE;
724                 }
725                 return parent::setParam($page,$name,'','pagename',$name);
726         }
727
728         function toString()
729         {
730                 static $aliases;
731
732                 if (!isset($aliases)) {
733                         $aliases = get_autoaliases();
734                 }
735                 if (array_key_exists($this->name,$aliases)) {
736                         return make_link($aliases[$this->name]);
737                 }
738         }
739 }
740
741 class Link_autoalias_a extends Link_autoalias
742 {
743         function Link_autoalias_a($start)
744         {
745                 parent::Link_autoalias($start);
746         }
747         function get_pattern()
748         {
749                 return isset($this->auto_a) ? '(' . $this->auto_a . ')' : FALSE;
750         }
751 }
752
753 // Make hyperlink for the page
754 function make_pagelink($page, $alias = '', $anchor = '', $refer = '')
755 {
756         global $script, $vars, $link_compact, $related, $_symbol_noexists;
757
758         $s_page = htmlspecialchars(strip_bracket($page));
759         $s_alias = ($alias == '') ? $s_page : $alias;
760
761         if ($page == '') return '<a href="' . $anchor . '">' . $s_alias . '</a>';
762
763         $r_page  = rawurlencode($page);
764         $r_refer = ($refer == '') ? '' : '&amp;refer=' . rawurlencode($refer);
765
766         if (! isset($related[$page]) && $page != $vars['page'] && is_page($page))
767                 $related[$page] = get_filetime($page);
768
769         if (is_page($page)) {
770                 // Hyperlinks
771                 $passage = get_pg_passage($page, FALSE);
772                 $title   = $link_compact ? '' : ' title="' . $s_page . $passage . '"';
773                 return '<a href="' . $script . '?' . $r_page . $anchor . '"' . $title . '>' .
774                         $s_alias . '</a>';
775         } else if (PKWK_READONLY) {
776                 // Without hyperlink (= Suppress dangling link)
777                 return $s_alias;
778         } else {
779                 // Dangling links
780                 $retval = $s_alias . '<a href="' .
781                         $script . '?cmd=edit&amp;page=' . $r_page . $r_refer . '">' .
782                         $_symbol_noexists . '</a>';
783                 if (! $link_compact)
784                         $retval = '<span class="noexists">' . $retval . '</span>';
785                 return $retval;
786         }
787 }
788
789 // Resolve relative / (Unix-like)absolute path of the page
790 function get_fullname($name, $refer)
791 {
792         global $defaultpage;
793
794         // 'Here'
795         if ($name == '' || $name == './') return $refer;
796
797         // Absolute path
798         if ($name{0} == '/') {
799                 $name = substr($name, 1);
800                 return ($name == '') ? $defaultpage : $name;
801         }
802
803         // Relative path from 'Here'
804         if (substr($name, 0, 2) == './') {
805                 $arrn    = preg_split('#/#', $name, -1, PREG_SPLIT_NO_EMPTY);
806                 $arrn[0] = $refer;
807                 return join('/', $arrn);
808         }
809
810         // Relative path from dirname()
811         if (substr($name, 0, 3) == '../') {
812                 $arrn = preg_split('#/#', $name,  -1, PREG_SPLIT_NO_EMPTY);
813                 $arrp = preg_split('#/#', $refer, -1, PREG_SPLIT_NO_EMPTY);
814
815                 while (! empty($arrn) && $arrn[0] == '..') {
816                         array_shift($arrn);
817                         array_pop($arrp);
818                 }
819                 $name = ! empty($arrp) ? join('/', array_merge($arrp, $arrn)) :
820                         (! empty($arrn) ? $defaultpage . '/' . join('/', $arrn) : $defaultpage);
821         }
822
823         return $name;
824 }
825
826 // Render an InterWiki into a URL
827 function get_interwiki_url($name, $param)
828 {
829         global $WikiName, $interwiki;
830         static $interwikinames;
831         static $encode_aliases = array('sjis'=>'SJIS', 'euc'=>'EUC-JP', 'utf8'=>'UTF-8');
832
833         if (! isset($interwikinames)) {
834                 $interwikinames = $matches = array();
835                 foreach (get_source($interwiki) as $line)
836                         if (preg_match('/\[(' . '(?:(?:https?|ftp|news):\/\/|\.\.?\/)' .
837                             '[!~*\'();\/?:\@&=+\$,%#\w.-]*)\s([^\]]+)\]\s?([^\s]*)/',
838                             $line, $matches))
839                                 $interwikinames[$matches[2]] = array($matches[1], $matches[3]);
840         }
841
842         if (! isset($interwikinames[$name])) return FALSE;
843
844         list($url, $opt) = $interwikinames[$name];
845
846         // Encoding
847         switch ($opt) {
848
849         case '':
850         case 'std': // As-Is (Internal encoding of this PukiWiki will be used)
851                 $param = rawurlencode($param);
852                 break;
853
854         case 'asis': // As-Is
855         case 'raw':
856                 // $param = htmlspecialchars($param);
857                 break;
858
859         case 'yw': // YukiWiki
860                 if (! preg_match('/' . $WikiName . '/', $param))
861                         $param = '[[' . mb_convert_encoding($param, 'SJIS', SOURCE_ENCODING) . ']]';
862                 // $param = htmlspecialchars($param);
863                 break;
864
865         case 'moin': // MoinMoin
866                 $param = str_replace('%', '_', rawurlencode($param));
867                 break;
868
869         default:
870                 // Alias conversion
871                 if (isset($encode_aliases[$opt])) $opt = $encode_aliases[$opt];
872                 // Encoding conversion into specified encode, and URLencode
873                 $param = rawurlencode(mb_convert_encoding($param, $opt, 'auto'));
874         }
875
876         // Replace parameters
877         if (strpos($url, '$1') !== FALSE) {
878                 $url = str_replace('$1', $param, $url);
879         } else {
880                 $url .= $param;
881         }
882
883         $len = strlen($url);
884         if ($len > 512) die_message('InterWiki URL too long: ' . $len . ' characters');
885
886         return $url;
887 }
888 ?>