TITLE:エスケープシーケンス
%indent
#contents
//-- make_link L59 L285

////////////////////////////////////////////////////////////////
* 方針 [#jc465a12]
- ウィキには書式をエスケープする手段はない。
-- 書式ごとに手段があったりもするが、ケースバイケースで覚えにくい。
-- 実体参照というエスケープが既にあるが、スペルは覚えにくい上、未対応の記号がある。
-- 文字参照というエスケープも既にあるが、ASCIIコードは覚えにくい。
- プラグイン形式でエスケープを導入。
-- 将来の拡張を想定し、キーボードにある記号類を全対応。
--- 「エスケープ必要か?」の事態を回避。エスケープすれば必ず通ることを保障。

////////////////////////////////////////////////////////////////
* 仕様 [#w0dac652]
- エスケープする記号を ##&## と ##;## で挟む。
- エスケープされた記号は文字参照に変換
- 例:
-- ##&&;&@;&;;## → ##&@;##
-- ##&&;&&;&;;## → ##&&;##
-- ##&&;&;;&;;## → ##&;;##
-- ##&&;& ;&;;## → ##& ;##

////////////////////////////////////////////////////////////////
* 実装 [#a928306f]

- ファイル ##lib/make_link.php## の ##class InlineConverter## の ##function InlineConverter## にて、新しいインライン書式を登録。
    #code(diff){{{{
         function InlineConverter($converters = NULL, $excludes = NULL)
         {
             if ($converters === NULL) {
                 $converters = array(
                     'plugin',        // Inline plugins
    +                'escape',        // Escapes
                     'note',          // Footnotes
                     'url',           // URLs
    }}}}
//
- 同ファイル、##class Link_plugin## を''コピー''し、##class Link_escape## に改造。
-- 「##!##」で始まる行は##class Link_plugin## に対する差分。
-
    #code(diff){{{{
    !// Escapes
    !class Link_escape extends Link
     {
         var $pattern;
         var $plain,$param;
         
         function Link_escape($start)
         {
             parent::Link($start);
         }
         
         function get_pattern()
         {
             $this->pattern = <<<EOD
     &
     (      # (1) plain
    - (\w+) # (2) plugin name
    - (?:
    -  \(
    -   ((?:(?!\)[;{]).)*) # (3) parameter
    -  \)
    - )?
    +    ([-!"#$%&'()=~|\\`@+*;:<>?_,.\/}{\][ ^])       # (2) plugin name
     )
     EOD;
             return <<<EOD
     {$this->pattern}
    -(?:
    - \{
    -  ((?:(?R)|(?!};).)*) # (4) body
    - \}
    -)?
     ;
     EOD;
         }
         
         function get_count()
         {
    -        return 4;
    +        return 2;
         }
         
         function set($arr, $page)
         {
    -        list($all, $this->plain, $name, $this->param, $body) = $this->splice($arr);
    +        list($all, $this->plain, $name) = $this->splice($arr);
         
             // Re-get true plugin name and patameters (for PHP 4.1.2)
             $matches = array();
             if (preg_match('/^' . $this->pattern . '/x', $all, $matches)
                 && $matches[1] != $this->plain) 
                 list(, $this->plain, $name) = $matches;
    +        $body = '';
    -        return parent::setParam($page, $name, $body, 'plugin');
    +        return parent::setParam($page, $name, $body, 'escape');
         }
         
         function toString()
         {
    !        return htmlspecialchars($this->name);
         }
     }
    }}}}
////////////////////////////////////////////////////////////////
* コメント
#pcomment

////////////////////////////////////////////////////////////////

    初基 一覧 検索 最新 バックアップ リンク元   ヘルプ   最終更新のRSS