方針 EditToHeaderToFooter

ページ名を日本語に設定できることが PukiWiki 派閥の売りの一つ。しかし、アンカー名は HTML の制約を受けて英字限定である。

Wiki は HTML ではないから、Wiki は HTML のできないことをできても良い。そして、日本語のページが必要とされるように、日本語のアンカー名も必要とされている。

また、日本語のページ名に対応するため、PukiWiki では「ブラケット名」と呼ばれる以下の構文を導入した。

  1
   [[ページ名#アンカー名]]

これに対し、アンカーを下ろすには aname プラグインを使う必要がある。

  1
   &aname(アンカー名);

この非対称を無くすため、そして、アンカーを目立たせるため、aname に対応した Wiki 構文 = ネイティブエイリアスを設ける。

仕様 EditToHeaderToFooter

aname の仕様変更 EditToHeaderToFooter

アンカープラグイン aname のアンカーに日本語を許す。ただし、半角記号「[>#]」は書式に使用するため、アンカー文字に使用不可とする。

アンカーのエンコード方式 EditToHeaderToFooter

アンカーのエンコードは PukiWiki に使われる URL のエンコード方式を流用する。ただし、HTML の id の仕様を満たすため、以下の変換とする。

変換規則

例:アンカー名

目的

1. rawurlencode で URL 文字列に変換

%A5;%A2%A5%F3%A5%AB%A1%BC%CC%BE

PukiWiki の URL エンコード方式

2. 「%」を「_」に置換

_A5_A2_A5_F3_A5_AB_A1_BC_CC_BE

HTML の id では「%」を使用不能。

3. 「Anchor」を先頭に付加

Anchor_A5_A2_A5_F3_A5_AB_A1_BC_CC_BE

HTML の id は「_」を先頭に配置不能。Anchorであることを明示。

ネイティブエイリアス [[[〜]]] EditToHeaderToFooter

リンクのネイティブ書式が [[〜]] に因み、アンカーを [[[〜]]] とする。これは、似た目的のインライン書式に同じ記号を割り当てる Wiki の方針に則っている。

太字''〜'' ⇔ 斜体'''〜'''
削除%%〜%% ⇔ 更新%%%〜%%%
リンク[[〜]] ⇔ アンカー[[[〜]]]

[[〜]] 自体の拡張も検討したが、[[〜]] の仕様の複雑さを考慮し、別書式とした。

  • 例: アンカー [[##〜]]  ⇔  リンク [[#〜]]

ネイティブエイリアス[[[〜]]]の書式を以下の3つのモードとする。

アンカーのみ [[[# Anchor ]]]
  • Anchor をアンカーに設定する。
  • アンカー位置には何も表示しない。
エイリアス指定 [[[ Alias ]]]
  • Aliasをアンカーに設定する。
  • アンカー位置にAliasを表示する。
エイリアスとアンカーの同時指定 [[[ Alias ># Anchor ]]]
  • Anchor をアンカーに設定する。
  • アンカー位置にAliasを表示する。

数式プラグインの場合、書式文字は「$」、プラグイン名は「eq」。書式文字は TeX のインライン数式モード「$〜$」に由来。用例は書式/数式を参照。

コードプラグインの場合、書式文字は「#」、プラグイン名は「code」。書式文字は、「#」の形が等幅表示のための桝目からの連想。また、C言語で、別言語であるプリプロセッサのコードを埋め込むときに用いられることからの連想。用例は書式/コードを参照。

実装 EditToHeaderToFooter

単一行インラインプラグイン EditToHeaderToFooter

  • lib/make_link.phpclass InlineConverterfunction InlineConverter にて、
      1
      2
      3
      4
      5
      6
      7
      8
      9
     10
    
         function InlineConverter($converters = NULL, $excludes = NULL)
         {
             if ($converters === NULL) {
                 $converters = array(
                     'plugin',        // Inline plugins
        +            'eq',            // eq plugin
        +            'code',          // code plugin
                     'escape',        // Escapes
                     'note',          // Footnotes
                     ……
    
  • lib/make_link.phpclass Link_plugin の後に以下を追加。
      1
      2
      3
      4
      5
      6
      7
      8
      9
     10
     11
     12
     13
     14
     15
     16
     17
     18
     19
     20
     21
     22
     23
     24
     25
     26
     27
     28
     29
     30
     31
     32
     33
     34
     35
     36
     37
     38
     39
     40
     41
     42
     43
    
        // Native-alias Plugin
        class Link_plugin_alias extends Link_plugin
        {
            var $name    = 'echo';  // プラグイン名
            var $pattern = '';      // 正規表現 Link_plugin に対応させるため、
                                    // $matches[1] = plain 
                                    // $matches[2] = plugin name
                                    // $matches[3] = parameter
                                    // $matches[4] = body // 独自拡張 // 引数展開
            
            function Link_eq($start)
            {
                parent::Link_plugin($start);
            }
            
            function get_pattern()
            {
                return $this->pattern;
            }
            
            function get_count()
            {
                return 4;
            }
            
            function set($arr, $page)
            {
                list(, $this->plain, , $this->param, $body) = $this->splice($arr);
                return parent::setParam($page, $this->name, $body, 'plugin');
            }
        }
        // Native-alias for &eq plugin
        class Link_eq extends Link_plugin_alias
        {
            var $name    = 'eq';
            var $pattern = '\$\$(()(.+?)())\$\$';   // no name, no body
        }
        // Native-alias for &code plugin
        class Link_code extends Link_plugin_alias
        {
            var $name    = 'code';
            var $pattern = '\#\#(()()(.+?))\#\#';   // no name, no parameter
        } 
    • Link_plugin_alias は基底クラス。直接生成されることはない。
    • eq は引数保持、code は引数展開。

複数行インラインプラグイン EditToHeaderToFooter

  • lib/convert_html.phpclass Bodyfunction parse にて、 複数行プラグインの後あたり。
      1
      2
      3
      4
      5
      6
      7
      8
      9
     10
     11
     12
     13
     14
     15
     16
     17
     18
     19
     20
     21
    
            // Native-alias for $eq-Plugin
            $pattern = '/^\s*\$\$\s*$/';
            if (preg_match($pattern, $line)) {
                $delimiter = "\r";
                $line = '&eq{{{{{{{{{{{{{{{{'.$delimiter;
                while (! empty($lines)) {
                    $next_line = rtrim(array_shift($lines), "\r\n");
                    if ($indent_format)
                    {
                        preg_match('/^(\s{'.$indent.'}?)?(.*)$/', $next_line, $matches);
                        $next_line = $matches[2];
                    }
                    
                    if (preg_match($pattern, $next_line)) {
                        $line .= ltrim('}}}}}}}}}}}}}}}};');
                        break;
                    } else {
                        $line .= $next_line . $delimiter;
                    }
                }
            } 
      1
      2
      3
      4
      5
      6
      7
      8
      9
     10
     11
     12
     13
     14
     15
     16
     17
     18
     19
     20
     21
    
    !        // Native-alias for $code-Plugin
    !        $pattern = '/^\s*##\s*$/';
             if (preg_match($pattern, $line)) {
                 $delimiter = "\r";
    !            $line = '$code{{{{{{{{{{{{{{{{'.$delimiter;
                 while (! empty($lines)) {
                     $next_line = rtrim(array_shift($lines), "\r\n");
                     if ($indent_format)
                     {
                         preg_match('/^(\s{'.$indent.'}?)?(.*)$/', $next_line, $matches);
                         $next_line = $matches[2];
                     }
                     
                     if (preg_match($pattern, $next_line)) {
                         $line .= ltrim('}}}}}}}}}}}}}}}};');
                         break;
                     } else {
                         $line .= $next_line . $delimiter;
                     }
                 }
             }
    
    • !」に行は、eqプラグイン に対する code プラグインの差分。

複数行ブロックプラグイン EditToHeaderToFooter

  • lib/convert_html.phpclass Bodyfunction parse にて、 複数行プラグインの後あたり。
      1
      2
      3
      4
      5
      6
      7
      8
      9
     10
     11
     12
     13
     14
     15
     16
     17
     18
     19
     20
     21
    
    !            // Native-alias for #eq-Plugin
    !            $pattern = '/^\s*\$\$\$\s*$/';
                 if (preg_match($pattern, $line)) {
                     $delimiter = "\r";
    !                $line = '#eq{{{{{{{{{{{{{{{{'.$delimiter;
                     while (! empty($lines)) {
                         $next_line = rtrim(array_shift($lines), "\r\n");
                         if ($indent_format)
                         {
                             preg_match('/^(\s{'.$indent.'}?)?(.*)$/', $next_line, $matches);
                             $next_line = $matches[2];
                         }
                         
                         if (preg_match($pattern, $next_line)) {
                             $line .= ltrim('}}}}}}}}}}}}}}}}');
                             break;
                         } else {
                             $line .= $next_line . $delimiter;
                         }
                     }
                 }
    
      1
      2
      3
      4
      5
      6
      7
      8
      9
     10
     11
     12
     13
     14
     15
     16
     17
     18
     19
     20
     21
    
    !            // Native-alias for #code-Plugin
    !            $pattern = '/^\s*###\s*(\w*)\s*$/';
    !            if (preg_match($pattern, $line, $matches)) {
                     $delimiter = "\r";
    !                $line = '#code('.$matches[1].'){{{{{{{{{{{{{{{{'.$delimiter;
                     while (! empty($lines)) {
                         $next_line = rtrim(array_shift($lines), "\r\n");
                         if ($indent_format)
                         {
                             preg_match('/^(\s{'.$indent.'}?)?(.*)$/', $next_line, $matches);
                             $next_line = $matches[2];
                         }
                         
                         if (preg_match($pattern, $next_line)) {
                             $line .= ltrim('}}}}}}}}}}}}}}}}');
                             break;
                         } else {
                             $line .= $next_line . $delimiter;
                         }
                     }
                 }
    
    • !」に行は、それぞれの複数行インラインプラグインに対する差分。
    初基 一覧 検索 最新 バックアップ リンク元   ヘルプ   最終更新のRSS