方針 EditToHeaderToFooter

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

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

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

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

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

  1
   &aname(アンカー名);

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

仕様 EditToHeaderToFooter

アンカープラグイン aname とブラケット書式 [[〜]]の仕様変更 EditToHeaderToFooter

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

アンカーのエンコード方式 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を表示する。

実装 EditToHeaderToFooter

プラグイン aname EditToHeaderToFooter

  • plugin/aname.inc.php の先頭、グローバル領域にて、
      1
      2
      3
    
        // Max length of ID
    -   define('PLUGIN_ANAME_ID_MAX',   40);
    +   define('PLUGIN_ANAME_ID_MAX',   1024);
    
    日本語アンカーのエンコード結果が、半角40文字を容易に超えるために拡張した。HTML としては id の最大長を指定してないようだが、実用的文字数とブラウザの実装限界を考慮して 1024 と決め付けた。
  • plugin/aname.inc.phpfunction lugin_aname_tag の中、id を取得直後に以下を追加。
      1
      2
      3
      4
      5
      6
      7
      8
      9
     10
    
        function plugin_aname_tag($args = array(), $convert = TRUE)
        {
            ...
            
            $id = array_shift($args);
    +       if (! preg_match(PLUGIN_ANAME_ID_REGEX, $id))
    +       {
    +           $id = rawurlencode($id);
    +           $id = 'Anchor' . str_replace('%', '_', $id);
    +       }
    

ブラケット書式 [[〜]] EditToHeaderToFooter

  • lib/make_link.inc.php の先頭、グローバル領域にて、plugin/aname.inc.php で設定されているアンカー名の正規表現を設定する。
      1
      2
    
    +   // Pattern of ID
    +   define('PLUGIN_ANAME_ID_REGEX', '/^[A-Za-z][\w\-]*$/');
    
  • lib/make_link.inc.php の中ほど、class Link_bracketname extends Linkfunction get_pattern にて、return 対象の正規表現を変更。
      1
      2
      3
      4
      5
      6
      7
      8
      9
     10
     11
     12
     13
     14
     15
     16
     17
     18
     19
     20
    
            function get_pattern()
            {
                global $WikiName, $BracketName;
            
                $s2 = $this->start + 2;
                return <<<EOD
        \[\[                     # Open bracket
        (?:((?:(?!\]\]).)+)>)?   # (1) Alias
        (\[\[)?                  # (2) Open bracket
        (                        # (3) PageName
         (?:$WikiName)
         |
         (?:$BracketName)
        )?
    -   (\#(?:[a-zA-Z][\w-]*)?)? # (4) Anchor
    +   (?:\#([^\[\>\#\]]+)?)?   # (4) Anchor
        (?($s2)\]\])             # Close bracket if (2)
        \]\]                     # Close bracket
        EOD;
            }
    
  • lib/make_link.inc.php の中ほど、class Link_bracketname extends Linkfunction toString にて、
      1
      2
      3
      4
      5
      6
      7
      8
      9
     10
     11
     12
    
    +           if (! preg_match(PLUGIN_ANAME_ID_REGEX,$this->anchor))
    +           {
    +               $this->anchor = rawurlencode($this->anchor);
    +               $this->anchor = 'Anchor' . str_replace('%', '_', $this->anchor);
    +           }
    +           $this->anchor = '#'.$this->anchor;
    +           
                return make_pagelink(
                    $this->name,
                    $this->alias,
                    $this->anchor,
                    $this->page
    

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

  • lib/make_link.inc.php の先頭、class InlineConverterfunction InlineConverter にて、'bracketname' を登録直前、
      1
      2
      3
      4
      5
      6
      7
      8
      9
     10
    
            function InlineConverter($converters = NULL, $excludes = NULL)
            {
                if ($converters === NULL) {
                    $converters = array(
                        ...
    +                   'bracketanchor', // BracketAnchor
                        'bracketname',   // BracketName
                        ...
                    );
                }
    
    正規表現として [[[〜]]][[〜]] に包含されるため、'bracketanchor' は必ず 'bracketname' の前に登録する必要がある。
  • lib/make_link.inc.php の中ほど、class Link_bracketname の前にて、以下を挿入*1
      1
      2
      3
      4
      5
      6
      7
      8
      9
     10
     11
     12
     13
     14
    
        // BracketAnchor
        // Native-alias for &aname plugin
        class Link_bracketanchor extends Link_plugin_alias
        {
            var $name    = 'aname';
            var $pattern = '\[\[\[(()(?:([^\[\>\#\]]+)>?)?(?:\#?([^\[\]\>\#]+?))?)\]\]\]';
            
            function set($arr, $page)
            {
                list(, $this->plain, , $body, $this->param) = $this->splice($arr);
                if ($this->param == '') {$this->param = $body;}                         // アンカー省略=エイリアスをアンカーに使用
                return parent::setParam($page, $this->name, $body, 'plugin');
            }
        } 
    *1 継承しているLink_plugin_aliasネイティブエイリアス で実装したクラスである。

課題 EditToHeaderToFooter

  • 見出しのアンカー [#〜] をアンカーのネイティブエイリアス [[[〜]]] に統合すべし。
    • 見出しのハッシュではなく、文字列自体をアンカーにすべし。
      • 今でも **[[[見出し1]]] のようにコーディングすれば一応できるけど。
      • アンカーの禁止文字「[>#]」を何とかすべし。
    • 見出しの階層構造に応じたアンカーの階層化を検討すべし。
      • 例: ページ階層1/ページ階層2/ページ名#見出し1/見出し1-1/見出し1-1-1
      • 例: ページ階層1/ページ階層2/ページ名#見出し1-1-1 ← も衝突しない限り可能にしたい。
リロード   新規 編集 凍結 差分 添付 複製 改名   初基 一覧 検索 最新 バックアップ リンク元   ヘルプ   最終更新のRSS
Last-modified: 2013.0324 (日) 0717.0800 (4049d)