2 /////////////////////////////////////////////////
3 // PukiWiki - Yet another WikiWikiWeb clone.
5 // $Id: make_link.php,v 1.37 2003/05/13 07:56:12 arino Exp $
9 function make_link($string,$page = '')
14 if (!isset($converter))
16 $converter = new InlineConverter();
18 $_converter = $converter; // copy
19 return $_converter->convert($string, ($page != '') ? $page : $vars['page']);
21 //¥¤¥ó¥é¥¤¥óÍ×ÁǤòÃÖ´¹¤¹¤ë
24 var $converters; // as array()
29 function InlineConverter($converters=NULL,$excludes=NULL)
31 if ($converters === NULL)
34 'plugin', // ¥¤¥ó¥é¥¤¥ó¥×¥é¥°¥¤¥ó
37 'url_interwiki', // URL (interwiki definition)
39 'interwikiname', // InterWikiName
40 'autolink', // AutoLink
41 'bracketname', // BracketName
42 'wikiname', // WikiName
45 if ($excludes !== NULL)
47 $converters = array_diff($converters,$excludes);
49 $this->converters = array();
51 $start = 3; // $this->pattern¤Î¥µ¥Ö¥Ñ¥¿¡¼¥ó2¸Ä¤ò´Þ¤à
53 foreach ($converters as $name)
55 $classname = "Link_$name";
56 $converter = new $classname($start);
57 $pattern = $converter->get_pattern();
58 if ($pattern === FALSE)
62 $patterns[] = "(\n$pattern\n)";
63 $this->converters[$start] = $converter;
64 $start += $converter->get_count();
67 $this->pattern = '(.*?)('.join('|',$patterns).')'; // $start += 2
69 function convert($string,$page)
74 $string = preg_replace_callback("/{$this->pattern}/x",array(&$this,'replace'),$string);
76 return $this->result.htmlspecialchars($string);
78 function replace($arr)
80 $obj = $this->get_converter($arr);
82 $this->result .= ($obj !== NULL and $obj->set($arr,$this->page) !== FALSE) ?
83 htmlspecialchars($arr[1]).$obj->toString() : htmlspecialchars($arr[0]);
85 return ''; //½èÍýºÑ¤ß¤ÎÉôʬ¤òʸ»úÎ󤫤éºï½ü¤¹¤ë
87 function get_objects($string,$page)
89 preg_match_all("/{$this->pattern}/x",$string,$matches,PREG_SET_ORDER);
92 foreach ($matches as $match)
94 $obj = $this->get_converter($match);
95 if ($obj->set($match,$page) !== FALSE)
97 $arr[] = $obj; // copy
102 function &get_converter(&$arr)
104 foreach (array_keys($this->converters) as $start)
106 if ($arr[$start] != '')
108 return $this->converters[$start];
114 //¥¤¥ó¥é¥¤¥óÍ×Áǽ¸¹ç¤Î¥Ù¡¼¥¹¥¯¥é¥¹
117 var $start; // ³ç¸Ì¤ÎÀèƬÈÖ¹æ(0¥ª¥ê¥¸¥ó)
118 var $text; // ¥Þ¥Ã¥Á¤·¤¿Ê¸»úÎóÁ´ÂÎ
126 function Link($start)
128 $this->start = $start;
130 // ¥Þ¥Ã¥Á¤Ë»ÈÍѤ¹¤ë¥Ñ¥¿¡¼¥ó¤òÊÖ¤¹
131 function get_pattern()
134 // »ÈÍѤ·¤Æ¤¤¤ë³ç¸Ì¤Î¿ô¤òÊÖ¤¹ ((?:...)¤ò½ü¤¯)
138 // ¥Þ¥Ã¥Á¤·¤¿¥Ñ¥¿¡¼¥ó¤òÀßÄꤹ¤ë
139 function set($arr,$page)
148 // ¥Þ¥Ã¥Á¤·¤¿ÇÛÎ󤫤顢¼«Ê¬¤ËɬÍפÊÉôʬ¤À¤±¤ò¼è¤ê½Ð¤¹
149 function splice($arr)
151 $count = $this->get_count() + 1;
152 $arr = array_splice($arr,$this->start,$count);
153 while (count($arr) < $count)
157 $this->text = $arr[0];
160 // ´ðËܥѥé¥á¡¼¥¿¤òÀßÄꤹ¤ë
161 function setParam($page,$name,$type='',$alias='')
163 static $converter = NULL;
168 if ($type != 'InterWikiName' and preg_match('/\.(gif|png|jpe?g)$/i',$alias))
170 $alias = "<img src=\"$alias\" alt=\"$name\" />";
172 else if ($alias != '')
174 if ($converter === NULL)
176 $converter = new InlineConverter(array('plugin'));
178 $alias = make_line_rules($converter->convert($alias,$page));
180 $this->alias = $alias;
185 // ¥¤¥ó¥é¥¤¥ó¥×¥é¥°¥¤¥ó
186 class Link_plugin extends Link
190 function Link_plugin($start)
192 parent::Link($start);
194 function get_pattern()
197 &(\w+) # (1) plugin name
200 ([^)]*) # (2) parameter
215 function set($arr,$page)
217 $arr = $this->splice($arr);
220 $this->param = $arr[2];
221 $this->body = ($arr[3] == '') ? '' : make_link($arr[3]);
223 if (!exist_plugin_inline($name))
228 return parent::setParam($page,$name,'plugin');
232 return $this->make_inline($this->name,$this->param,$this->body);
234 function make_inline($func,$param,$body)
236 //&hoge(){...}; &fuga(){...}; ¤Îbody¤¬'...}; &fuga(){...'¤È¤Ê¤ë¤Î¤Ç¡¢Á°¸å¤Ëʬ¤±¤ë
238 if (preg_match("/^ ((?!};).*?) }; (.*?) & (\w+) (?: \( ([^()]*) \) )? { (.+)$/x",$body,$matches))
241 $after = $matches[2].$this->make_inline($matches[3],$matches[4],$matches[5]);
244 // ¥×¥é¥°¥¤¥ó¸Æ¤Ó½Ð¤·
245 if (exist_plugin_inline($func))
247 $str = do_plugin_inline($func,$param,$body);
248 if ($str !== FALSE) //À®¸ù
254 // ¥×¥é¥°¥¤¥ó¤¬Â¸ºß¤·¤Ê¤¤¤«¡¢ÊÑ´¹¤Ë¼ºÇÔ
255 return htmlspecialchars($this->text);
259 class Link_note extends Link
261 function Link_note($start)
263 parent::Link($start);
265 function get_pattern()
273 (?!\(\()(?!\)\)(?:[^\)]|$)).
277 (?R) # or recursive of me
287 function set($arr,$page)
289 global $foot_explain;
292 $arr = $this->splice($arr);
295 $note = make_line_rules(make_link($arr[1]));
297 $foot_explain[$id] = <<<EOD
298 <a id="notefoot_$id" href="#notetext_$id" class="note_super">*$id</a>
299 <span class="small">$note</span>
302 $name = "<a id=\"notetext_$id\" href=\"#notefoot_$id\" class=\"note_super\">*$id</a>";
304 return parent::setParam($page,$name);
312 class Link_url extends Link
314 function Link_url($start)
316 parent::Link($start);
318 function get_pattern()
320 $s1 = $this->start + 1;
322 (\[\[ # (1) open bracket
324 (?:>|>|:) # '>' or '>' or ':'
327 (?:https?|ftp|news):\/\/[!~*'();\/?:\@&=+\$,%#\w.-]+
329 (?($s1)\]\]) # close bracket
336 function set($arr,$page)
338 $arr = $this->splice($arr);
341 $alias = ($arr[2] == '') ? $arr[3] : $arr[2];
342 return parent::setParam($page,$name,'url',$alias);
347 return "<a href=\"{$this->name}\">{$this->alias}</a>";
350 // url (InterWiki definition type)
351 class Link_url_interwiki extends Link
353 function Link_url_interwiki($start)
355 parent::Link($start);
357 function get_pattern()
362 (?:(?:https?|ftp|news):\/\/|\.\.?\/)[!~*'();\/?:\@&=+\$,%#\w.-]*
373 function set($arr,$page)
375 $arr = $this->splice($arr);
380 return parent::setParam($page,$name,'url',$alias);
384 return "<a href=\"{$this->name}\">{$this->alias}</a>";
388 class Link_mailto extends Link
390 var $is_image,$image;
392 function Link_mailto($start)
394 parent::Link($start);
396 function get_pattern()
398 $s1 = $this->start + 1;
400 (?:\[\[([^\]]+)(?:>|>|:))? # (1) alias
401 ([\w.-]+@[\w-]+\.[\w.-]+) # (2) mailto
402 (?($s1)\]\]) # close bracket if (1)
409 function set($arr,$page)
411 $arr = $this->splice($arr);
414 $alias = ($arr[1] == '') ? $arr[2] : $arr[1];
416 return parent::setParam($page,$name,'mailto',$alias);
420 return "<a href=\"mailto:{$this->name}\">{$this->alias}</a>";
424 class Link_interwikiname extends Link
428 function Link_interwikiname($start)
430 parent::Link($start);
432 function get_pattern()
434 $s1 = $this->start + 1;
435 $s3 = $this->start + 3;
436 $s5 = $this->start + 5;
440 (\[\[)? # (1) open bracket
441 ([^\[\]]+) # (2) alias
442 (?:>|>) # '>' or '>'
445 (\[\[)? # (3) open bracket
446 (\[*?[^\s\]]+?\]*?) # (4) InterWiki
448 (?($s1)\]\] # close bracket if (1)
449 |(?($s3)\]\]) # or (3)
453 (\:(?:(?<!>|>).)*?) # (6) param
455 (?($s1)\]\] # close bracket if (1)
456 |(?($s3)\]\]) # or (3)
467 function set($arr,$page)
469 $arr = $this->splice($arr);
472 if (preg_match('/^([^#]+)(#[A-Za-z][\w-]*)$/',$param,$matches))
474 $this->anchor = $matches[2];
475 $param = $matches[1];
477 $name = rawurlencode('[['.$arr[4].$param.']]');
478 $alias = ($arr[2] != '') ? $arr[2] : $arr[4].$arr[6];
480 return parent::setParam($page,$name,'InterWikiName',$alias);
484 global $script; //,$interwiki_target;
486 return "<a href=\"$script?{$this->name}{$this->anchor}\">{$this->alias}</a>";
490 class Link_bracketname extends Link
494 function Link_bracketname($start)
496 parent::Link($start);
498 function get_pattern()
500 global $WikiName,$BracketName;
502 $s1 = $this->start + 1;
503 $s3 = $this->start + 3;
504 $s7 = $this->start + 7;
508 (\[\[)? # (1) open bracket
509 ([^\[\]]+) # (2) alias
510 (?:>|>) # '>' or '>'
512 (\[\[)? # (3) open bracket
514 ($WikiName) # (5) WikiName
516 ($BracketName) # (6) BracketName
519 (?($s1)\]\] # close bracket if (1)
520 |(?($s3)\]\]) # or (3)
523 (\#(?:[a-zA-Z][\w-]*)?)? # (8) anchor
525 (?($s1)\]\] # close bracket if (1)
526 |(?($s3)\]\]) # or (3)
536 function set($arr,$page)
538 global $WikiName,$BracketName;
540 $arr = $this->splice($arr);
544 $this->anchor = $arr[8];
546 if ($name == '' and $this->anchor == '')
550 if ($name != '' and preg_match("/^$WikiName$/",$name))
552 return parent::setParam($page,$name,'pagename',$alias);
556 $alias = $name.$this->anchor;
558 if ($name == '' and $this->anchor == '')
563 $name = get_fullname($name,$page);
565 if ($name != '' and !preg_match("/^($WikiName)|($BracketName)$/",$name))
569 return parent::setParam($page,$name,'pagename',$alias);
573 return make_pagelink(
582 class Link_wikiname extends Link
584 function Link_wikiname($start)
586 parent::Link($start);
588 function get_pattern()
590 global $WikiName,$nowikiname;
592 return $nowikiname ? FALSE : "($WikiName)";
598 function set($arr,$page)
600 $arr = $this->splice($arr);
601 $name = $alias = $arr[0];
602 return parent::setParam($page,$name,'pagename',$alias);
606 return make_pagelink(
615 class Link_autolink extends Link
617 var $forceignorepages = array();
619 function Link_autolink($start)
621 parent::Link($start);
623 function get_pattern()
626 static $auto,$forceignorepages;
628 if (!$autolink or !file_exists(CACHE_DIR.'autolink.dat'))
632 if (!isset($auto)) // and/or !isset($forceignorepages)
634 @list($auto,$forceignorepages) = file(CACHE_DIR.'autolink.dat');
635 $forceignorepages = explode("\t",$forceignorepages);
637 $this->forceignorepages = $forceignorepages;
644 function set($arr,$page)
648 $arr = $this->splice($arr);
649 $name = $alias = $arr[0];
650 // ̵»ë¥ê¥¹¥È¤Ë´Þ¤Þ¤ì¤Æ¤¤¤ë¡¢¤¢¤ë¤¤¤Ï¸ºß¤·¤Ê¤¤¥Ú¡¼¥¸¤ò¼Î¤Æ¤ë
651 if (in_array($name,$this->forceignorepages) or !is_page($name))
655 return parent::setParam($page,$name,'pagename',$alias);
659 return make_pagelink(
667 // ¥Ú¡¼¥¸Ì¾¤Î¥ê¥ó¥¯¤òºîÀ®
668 function make_pagelink($page,$alias='',$anchor='',$refer='')
670 global $script,$vars,$show_title,$show_passage,$link_compact,$related;
672 $s_page = htmlspecialchars(strip_bracket($page));
673 $s_alias = ($alias == '') ? $s_page : $alias;
677 return "<a href=\"$anchor\">$s_alias</a>";
680 $r_page = rawurlencode($page);
681 $r_refer = ($refer == '') ? '' : '&refer='.rawurlencode($refer);
683 if (!array_key_exists($page,$related) and $page != $vars['page'] and is_page($page))
685 $related[$page] = get_filetime($page);
690 $passage = get_pg_passage($page,FALSE);
691 $title = $link_compact ? '' : " title=\"$s_page$passage\"";
692 return "<a href=\"$script?$r_page$anchor\"$title>$s_alias</a>";
696 return $link_compact ?
697 "$s_alias<a href=\"$script?cmd=edit&page=$r_page$r_refer\">?</a>" :
698 "<span class=\"noexists\">$s_alias<a href=\"$script?cmd=edit&page=$r_page$r_refer\">?</a></span>";
702 function get_fullname($name,$refer)
711 if (substr($name,0,2) == './')
713 $arrn = preg_split('/\//',$name,-1,PREG_SPLIT_NO_EMPTY);
715 return join('/',$arrn);
718 if (substr($name,0,3) == '../')
720 $arrn = preg_split('/\//',$name,-1,PREG_SPLIT_NO_EMPTY);
721 $arrp = preg_split('/\//',$refer,-1,PREG_SPLIT_NO_EMPTY);
723 while (count($arrn) > 0 and $arrn[0] == '..')
728 $name = count($arrp) ? join('/',array_merge($arrp,$arrn)) :
729 (count($arrn) ? "$defaultpage/".join('/',$arrn) : $defaultpage);