convert($string, ($page != '') ? $page : $vars['page']);
}
//インライン要素を置換する
class InlineConverter
{
var $converters; // as array()
var $pattern;
var $pos;
var $result;
function InlineConverter($converters=NULL,$excludes=NULL)
{
if ($converters === NULL)
{
$converters = array(
'plugin', // インラインプラグイン
'note', // 注釈
'url', // URL
'url_interwiki', // URL (interwiki definition)
'mailto', // mailto:
'interwikiname', // InterWikiName
'autolink', // AutoLink
'bracketname', // BracketName
'wikiname', // WikiName
'autolink_a', // AutoLink(アルファベット)
);
}
if ($excludes !== NULL)
{
$converters = array_diff($converters,$excludes);
}
$this->converters = array();
$patterns = array();
$start = 1;
foreach ($converters as $name)
{
$classname = "Link_$name";
$converter = new $classname($start);
$pattern = $converter->get_pattern();
if ($pattern === FALSE)
{
continue;
}
$patterns[] = "(\n$pattern\n)";
$this->converters[$start] = $converter;
$start += $converter->get_count();
$start++;
}
$this->pattern = join('|',$patterns);
}
function convert($string,$page)
{
$this->page = $page;
$this->result = array();
$string = preg_replace_callback("/{$this->pattern}/x",array(&$this,'replace'),$string);
$arr = explode("\x08",make_line_rules(htmlspecialchars($string)));
$retval = '';
while (count($arr))
{
$retval .= array_shift($arr).array_shift($this->result);
}
return $retval;
}
function replace($arr)
{
$obj = $this->get_converter($arr);
$this->result[] = ($obj !== NULL and $obj->set($arr,$this->page) !== FALSE) ?
$obj->toString() : make_line_rules(htmlspecialchars($arr[0]));
return "\x08"; //処理済みの部分にマークを入れる
}
function get_objects($string,$page)
{
preg_match_all("/{$this->pattern}/x",$string,$matches,PREG_SET_ORDER);
$arr = array();
foreach ($matches as $match)
{
$obj = $this->get_converter($match);
if ($obj->set($match,$page) !== FALSE)
{
$arr[] = $obj; // copy
if ($obj->body != '')
{
$arr = array_merge($arr,$this->get_objects($obj->body,$page));
}
}
}
return $arr;
}
function &get_converter(&$arr)
{
foreach (array_keys($this->converters) as $start)
{
if ($arr[$start] == $arr[0])
{
return $this->converters[$start];
}
}
return NULL;
}
}
//インライン要素集合のベースクラス
class Link
{
var $start; // 括弧の先頭番号(0オリジン)
var $text; // マッチした文字列全体
var $type;
var $page;
var $name;
var $body;
var $alias;
// constructor
function Link($start)
{
$this->start = $start;
}
// マッチに使用するパターンを返す
function get_pattern()
{
}
// 使用している括弧の数を返す ((?:...)を除く)
function get_count()
{
}
// マッチしたパターンを設定する
function set($arr,$page)
{
}
// 文字列に変換する
function toString()
{
}
//private
// マッチした配列から、自分に必要な部分だけを取り出す
function splice($arr)
{
$count = $this->get_count() + 1;
$arr = array_pad(array_splice($arr,$this->start,$count),$count,'');
$this->text = $arr[0];
return $arr;
}
// 基本パラメータを設定する
function setParam($page,$name,$body,$type='',$alias='')
{
static $converter = NULL;
$this->page = $page;
$this->name = $name;
$this->body = $body;
$this->type = $type;
if ($type != 'InterWikiName' and preg_match('/\.(gif|png|jpe?g)$/i',$alias))
{
$alias = htmlspecialchars($alias);
$alias = "";
}
else if ($alias != '')
{
if ($converter === NULL)
{
$converter = new InlineConverter(array('plugin'));
}
$alias = make_line_rules($converter->convert($alias,$page));
}
$this->alias = $alias;
return TRUE;
}
}
// インラインプラグイン
class Link_plugin extends Link
{
var $pattern;
var $plain,$param;
function Link_plugin($start)
{
parent::Link($start);
}
function get_pattern()
{
$this->pattern = <<pattern}
(?:
\{
((?:(?R)|(?!};).)*) # (4) body
\}
)?
;
EOD;
}
function get_count()
{
return 4;
}
function set($arr,$page)
{
list($all,$this->plain,$name,$this->param,$body) = $this->splice($arr);
// 本来のプラグイン名およびパラメータを取得しなおす PHP4.1.2 (?R)対策
if (preg_match("/^{$this->pattern}/x",$all,$matches)
and $matches[1] != $this->plain)
{
list(,$this->plain,$name,$this->param) = $matches;
}
return parent::setParam($page,$name,$body,'plugin');
}
function toString()
{
$body = ($this->body == '') ? '' : make_link($this->body);
// プラグイン呼び出し
if (exist_plugin_inline($this->name))
{
$str = do_plugin_inline($this->name,$this->param,$body);
if ($str !== FALSE) //成功
{
return $str;
}
}
// プラグインが存在しないか、変換に失敗
$body = ($body == '') ? ';' : "\{$body};";
return make_line_rules(htmlspecialchars('&'.$this->plain).$body);
}
}
// 注釈
class Link_note extends Link
{
function Link_note($start)
{
parent::Link($start);
}
function get_pattern()
{
return <<splice($arr);
$id = ++$note_id;
$note = make_link($body);
$foot_explain[$id] = <<