TITLE:コードプラグイン
#indent
#contents

////////////////////////////////////////////////////////////////
//** インラインコードの追加
//* 方針
//-- make_link L59 L285

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

* 平コードの総行数が1つ不足する問題を修正 [#w14469c7]
// codehighlight L83

** 方針 [#v5647617]
- 謎な帳尻合わせがあるが、とりあえず削除。
-- 対症療法。そもそも、どっかで必要のために帳尻合わせしてるハズなので要調査。

** 改造 [#zf38b7b9]
-##plugin/code/codehighlight.php## の ##function highlight## の前半にて、
    #code(diff){{{{
             if (file_exists(PLUGIN_DIR.'code/keyword.'.$lang.'.php')) {
                 // 言語定義ファイルが有る言語
                 ……
             } else if (file_exists(PLUGIN_DIR.'code/line.'.$lang.'.php')) {
                 // 行指向解析設定ファイルが有る言語
                 ……
             } else {
                 // PHP と 未定義言語
                 $option['outline'] = false;
                 $option['comment'] = false;
                 
    -            // 最後の余分な改行を削除
    -            if ($src[strlen($src)-2] == ' ')
    -                $src = substr($src, 0, -2);
    -            else
    -                $src= substr($src, 0, -1);
                 
                 if ($option['number']) {
                     // 行数を得る
                     $num_of_line = substr_count($src, "\n");
                     if($src[strlen($src)-1]=="\n")
                     $src=substr($src,0,-1);
                     $data = array('number' => '');
                     $data['number'] = _plugin_code_makeNumber($num_of_line-1);
                 }
                 ……
    }}}}
//
* 行番号がデフォルトで 1 から開始するように仕様変更 [#a7894906]
** 方針 [#w2e07613]
- 行数は自然数で数える方が自然かと。
- 次の改造と合わせ、##_plugin_code_makeNumber## の呼出しが単純で規則的になる。

** 改造 [#fe784726]
- ##plugin/code/codehighlight.php## の #function _plugin_code_makeNumber## にて、
    #code(diff){{{{
    -function _plugin_code_makeNumber($end, $begin=0)
    +function _plugin_code_makeNumber($end, $begin=1){
         $number='';
         $str_len=max(3,strlen(''.$end));
         for($i=$begin; $i<=$end; ++$i) {
             $number.= sprintf('%'.$str_len.'d',($i))."\n";
         }
         return $number;
     }
    }}}}

- 同ファイル、##function highlight## の前半で、平コードの改造の直後にて、
    #code(diff){{{{
             if (file_exists(PLUGIN_DIR.'code/keyword.'.$lang.'.php')) {
                 // 言語定義ファイルが有る言語
                 ……
             } else if (file_exists(PLUGIN_DIR.'code/line.'.$lang.'.php')) {
                 // 行指向解析設定ファイルが有る言語
                 ……
             } else {
                 // PHP と 未定義言語
                 $option['outline'] = false;
                 $option['comment'] = false;
                 
                 if ($option['number']) {
                     // 行数を得る
                     $num_of_line = substr_count($src, "\n");
                     if($src[strlen($src)-1]=="\n")
                     $src=substr($src,0,-1);
                     $data = array('number' => '');
    -                $data['number'] = _plugin_code_makeNumber($num_of_line-1);
    +                $data['number'] = _plugin_code_makeNumber($num_of_line);
                 }
                 ……
    }}}}
- 同ファイル、##function lineToHTML## の最後にて、
    #code(diff){{{{
             // 最後の余分な改行を削除
             if ($html[strlen($html)-2] == ' ')
                 $html = substr($html, 0, -2);
             else
                 $html = substr($html, 0, -1);
             
             $html = array( 'src' => $html,  'number' => '', 'outline' => '', 'commentnum' => $commentnum,);
    -        if($mknumber) $html['number'] = _plugin_code_makeNumber($num_of_line-2); // 最後に改行を削除したため -2
    +        if($mknumber) $html['number'] = _plugin_code_makeNumber($num_of_line-1); // 最後に改行を削除したため -1
             return $html;
    }}}}
    
- 同ファイル、##function srcToHTML## の最後にて、
    #code(diff){{{{
             // 最後の余分な改行を削除
             if ($html[strlen($html)-2] == ' ')
                 $html = substr($html, 0, -2);
             else
                 $html = substr($html, 0, -1);
             
             $html = array( 'src' => $html,  'number' => '', 'outline' => '', 
                            'blocknum' => $blockno, 'commentnum' => $commentno, );
             
             if($mkoutline) 
                 return $this->makeOutline($html,$line-1,$nest,$mknumber,$outline,$blockno,$id_number);
    -        if($mknumber) $html['number'] = _plugin_code_makeNumber($line-1);
    +        if($mknumber) $html['number'] = _plugin_code_makeNumber($line);
             return $html;
    }}}}

////////////////////////////////////////////////////////////////
* diff モードで空白開始行を表示するように変更/&br;コメント行の行末に現れる余計な改行の除去 [#pe86fcf0]
** 方針 [#z8437af7]
- diff をコードの変更を示す目的(汎用差分)で使用する場合、無変更行を位置のマーカーとして表示できると便利。
- この改造により、##_plugin_code_makeNumber## の3箇所の呼出しから引数の補正が無くなる。
//
- ##plugin/code/line.diff.php## にて、
    #code(diff){{{{
        ...
        $switchHash['\\']= PLUGIN_CODE_IDENTIFIRE_CHAR;   // control
        $switchHash['@'] = PLUGIN_CODE_IDENTIFIRE_CHAR;   // control
    +   $switchHash[' '] = PLUGIN_CODE_IDENTIFIRE_CHAR;   // nochange
        
        ...
        
        // コメント定義
    -   $switchHash['#'] = PLUGIN_CODE_COMMENT;	// コメントは # から改行まで
    +   $switchHash['#'] = PLUGIN_CODE_COMMENT_CHAR;	// コメントは # から改行まで
     
        $code_css = Array(
            'changed', //
            'added',   //
            'removed', //
            
            'system',  //
    +       'nochange',//
        );
        
        $code_keyword = Array(
            ...
            '*' => 4,
            '\\' => 4,
            '@' => 4,
            '---' => 4,
            '+++' => 4,
    +        
    +       ' ' => 5,
        );
    }}}}
//
- ##plugin/code/codehighlight.php## の ##function lineToHTML## にて、
    #code(diff){{{{
        function lineToHTML(& $string, & $lang, $id_number, & $option) {
            ...
            while($line !== false) {
                ...
                switch ($switchHash[$line[0]]) {
                
                case PLUGIN_CODE_CHAR_COMMENT:
                case PLUGIN_CODE_HEAD_COMMENT:
                case PLUGIN_CODE_COMMENT_CHAR:
                    // 行頭の1文字でコメントと判断できるもの
                    ...
                    
    -               $line = htmlspecialchars(substr($line,0,-1), ENT_QUOTES);
    +               $line = htmlspecialchars($line, ENT_QUOTES);
                    ...
                    
                    $html .= '<span class="'.PLUGIN_CODE_HEADER.'comment" id="'.PLUGIN_CODE_HEADER.$id_number.'_cmt_'.$commentnum.'">'
    -                   .$line.'</span>'."\n";
    +                   .$line.'</span>';
                    ...
                
                case PLUGIN_CODE_HEADW_COMMENT:
                case PLUGIN_CODE_COMMENT_WORD:
                    // 2文字以上のパターンから始まるコメント
                    if (strncmp($line, $commentpattern, strlen($commentpattern)) == 0) {
                        ...
                        
    -                   $line = htmlspecialchars(substr($line,0,-1), ENT_QUOTES);
    +                   $line = htmlspecialchars($line, ENT_QUOTES);
                        ...
                    
                    if ($option['link']) 
                        $html .= '<span class="'.PLUGIN_CODE_HEADER.'comment" id="'.PLUGIN_CODE_HEADER.$id_number.'_cmt_'.$commentnum.'">'
    -                       .$line.'</span>'."\n";
    +                       .$line.'</span>';
                        ...
                
    -           if($mknumber) $html['number'] = _plugin_code_makeNumber($num_of_line-1); // 最後に空行は削除するため -1
    +           if($mknumber) $html['number'] = _plugin_code_makeNumber($num_of_line);
    }}}}

////////////////////////////////////////////////////////////////
* tex モードで、複数行インライン数式で行番号が狂う問題を修正 [#m75e3d76]
** 現象 [#p12a5bd3]
    次のコードで行番号で、数式中の改行を数え忘れ。
    ^#code(tex){{{{
    ^    関数$
    ^        y = f(x)
    ^    $と置く。
    ^}}}}
** 改造 [#l409241a]
- ##plugin/code/codehighlight.php## の ##function srcToHTML## の後半、##case PLUGIN_CODE_FORMULA:## にて、
    #code(diff){{{{
             case PLUGIN_CODE_FORMULA:
                 // TeXの数式に使用 将来的には汎用性を持たせる 
                 
                 $pos = $str_pos;
                 $result = substr($string, $str_pos);
                 $pos1 = strpos($result, $code); // 文字列終了文字検索
                 if ($pos1 === false) { // 文字列が終わらなかったので全部文字列とする
                     $str_pos = $str_len-1;
                 } else {
                     $str_pos += $pos1 + 1;
                 }
                 $result = $code.substr($string, $pos, $str_pos - $pos);
    +            $line+=substr_count($result,"\n");      // ライン数カウント
                 
                 // htmlに追加
                 $result = htmlspecialchars($result, ENT_QUOTES);
                 if ($option['link']) 
                     $result = preg_replace('/(s?https?:\/\/|ftp:\/\/|mailto:)([-_.!~*()a-zA-Z0-9;\/:@?=+$,%#]|&amp;)+/',
                                            '<a href="$0">$0</a>',$result);
                 $html .= '<span class="'.PLUGIN_CODE_HEADER.'formula">'.$result.'</span>';
                 
                 // 次の検索用に読み込み
                 if ($str_len == $str_pos) $code = false; else $code = $string[$str_pos++]; // getc
                 continue 2;
    }}}}

////////////////////////////////////////////////////////////////
* pukiwiki モードで、字下げ書式対応 [#va70f92d]
** 方針 [#bc20a5cd]
- 字下げ拡張をしたため、コードプラグインの PukiWiki モードにも対応させるべし。
//
** 改造 [#t1f6d0c7]
- ##plugin/code.inc.php## の先頭にて、
    #code(diff){{{{
    // 標準設定
     define('PLUGIN_CODE_NUMBER',    ture );  // 行番号
     define('PLUGIN_CODE_OUTLINE',   false);  // アウトライン;
     define('PLUGIN_CODE_COMMENT',   false);  // コメント表示/非表示 // 0.5.0 では非推奨
     define('PLUGIN_CODE_MENU',      false);  // メニューの表示/非表示;
     define('PLUGIN_CODE_FILE_ICON', false);  // 添付ファイルにダウンロードアイコンを付ける
     define('PLUGIN_CODE_LINK',      false);  // オートリンク
     define('PLUGIN_CODE_CACHE',     false);  // キャッシュを使う
    +define('PLUGIN_CODE_INDENT',    false);  // 字下げ拡張
    }}}}
-- 天突きモードがデフォルト。
//
- 同ファイル、##function plugin_code_convert## にて、
    #code(diff){{{{
         $option = array(
                         'number'      => false,  // 行番号を表示する
                         'nonumber'    => false,  // 行番号を表示しない
                         'outline'     => false,  // アウトライン モード
                         'nooutline'   => false,  // アウトライン 無効
                         'comment'     => false,  // コメント開閉する
                         'nocomment'   => false,  // コメント開閉しない
                         'menu'        => false,  // メニューを表示する
                         'nomenu'      => false,  // メニューを表示しない
                         'icon'        => false,  // アイコンを表示する
                         'noicon'      => false,  // アイコンを表示しない
                         'link'        => false,  // オートリンク 有効
                         'nolink'      => false,  // オートリンク 無効
    +                    'indent'      => false,  // 字下げ 有効
    +                    'noindent'    => false,  // 字下げ 無効
                         );
    }}}}
//
- ##plugin/code/codehighlight.php## の ##function lineToHTML## にて、
    #code(diff){{{{
         function lineToHTML(& $string, & $lang, $id_number, & $option) {
             
             // テーブルジャンプ用ハッシュ
             $switchHash = Array();
             $capital = false; // 大文字小文字を区別しない
             
             $option['outline'] = false; // outlineを使わない
             $mknumber  = $option['number'];
    +        $indent_switch_reg   = '/$^/';    //   indentに切り替えるキーワード // PukiWikiの字下げ拡張 
    +        $noindent_switch_reg = '/$^/';    // noindentに切り替えるキーワード // PukiWikiの字下げ拡張 
             
             ……
             
             while($line !== false) {
                 ++$num_of_line;
                 while ($line[strlen($line)-2] == '\\') {
                     // 行末がエスケープ文字なら次の行も切り出す
                     ++$num_of_line;
                     $line .= $this->getline($string);
                 }
                 // 行頭文字の判定
                 
    +            $line_head = ($option['indent']) ? ltrim($line) : $line;    // PukiWikiの字下げ拡張
    +            if (  $option['indent'] && preg_match($noindent_switch_reg, $line_head)) $option['indent'] = false;
    +            if (! $option['indent'] && preg_match($indent_switch_reg  , $line_head)) $option['indent'] = true;
                 
    -            switch ($switchHash[$line[0]]) {
    +            switch ($switchHash[$line_head[0]])                         // PukiWikiの字下げ拡張
    +            {
                 case PLUGIN_CODE_CHAR_COMMENT:
                 case PLUGIN_CODE_HEAD_COMMENT:
                 case PLUGIN_CODE_COMMENT_CHAR:
                     // 行頭の1文字でコメントと判断できるもの
                     
                     // htmlに追加
                     ++$commentnum;
    -                $line = htmlspecialchars(substr($line,0,-1), ENT_QUOTES);
    +                $line = htmlspecialchars($line, ENT_QUOTES);
                     ……
                 
                 case PLUGIN_CODE_HEADW_COMMENT:
                 case PLUGIN_CODE_COMMENT_WORD:
                     // 2文字以上のパターンから始まるコメント
    -                if (strncmp($line, $commentpattern, strlen($commentpattern)) == 0) {
    +                if (strncmp($line_head, $commentpattern, strlen($commentpattern)) == 0) {
                         // htmlに追加
                         ++$commentnum;
    -                    $line = htmlspecialchars(substr($line,0,-1), ENT_QUOTES);
    +                    $line = htmlspecialchars($line, ENT_QUOTES);
                     ……
                 
                 case PLUGIN_CODE_IDENTIFIRE_CHAR:
                     // 行頭の1文字が意味を持つもの
    -                $index = $code_keyword[$line[0]];
    +                $index = $code_keyword[$line_head[0]];
                     $line = htmlspecialchars($line, ENT_QUOTES);
                     ……
                 
                 case PLUGIN_CODE_IDENTIFIRE_WORD:
                     if (strlen($line) < 2 && $line[0] == ' ') break; // 空行判定
                     // 行頭のパターンを調べる
    -                foreach ($code_identifire[$line[0]] as $pattern) {
    +                foreach ($code_identifire[$line_head[0]] as $pattern) {
    -                    if (strncmp($line, $pattern, strlen($pattern)) == 0) {
    +                    if (strncmp($line_head, $pattern, strlen($pattern)) == 0) {
                     ……
                     }
                     // 行頭の1文字が意味を持つものか判定
    -                $index = $code_keyword[$line[0]];
    +                $index = $code_keyword[$line_head[0]];
                     
                 case PLUGIN_CODE_MULTILINE:
                     // 複数行に渡って効果を持つ指定
    -                $index = $code_keyword[$line[0]];
    +                $index = $code_keyword[$line_head[0]];
                     $src = $line;
                     $line = $this->getline($string);
    -                while (in_array($line_head[0], $multilineEOL) === false && $line !== false) {
    +                while (in_array($line[0], $multilineEOL) === false && $line !== false) {
                     ……
    }}}}
-- モード切替スイッチは pukiwiki モード側で実装。
--- 9行目、##$indent_switch_reg## は字下げモードへのスイッチ。
--- 10行目、##$noindent_switch_reg## は天突きモードへのスイッチ。
-- 23行目、##$line_head## は字下げ処理後の行。
--- 以降、書式の判定は全て ##$line_head## を使う。
--- ただし、字下げも出力するため、コードの出力は ##$line##  のまま。
-- 24、25行目はモードの切り替えの検出と操作。
//
-
- ##plugin/code/line.pukiwiki.php## にて、
    #code(diff){{{{
     <?php
     
    +$indent_switch_reg   = '/^#indent$/';
    +$noindent_switch_reg = '/^#noindent$/';
     
     /**
      *キーワード定義ファイル
      */
     
     $switchHash['#'] = PLUGIN_CODE_SPECIAL_IDENTIFIRE;  // # から始まる予約語あり
     $switchHash['&'] = PLUGIN_CODE_SPECIAL_IDENTIFIRE;  // & から始まる予約語あり
     $switchHash['*'] = PLUGIN_CODE_IDENTIFIRE_CHAR;  // 見出し
     $switchHash[','] = PLUGIN_CODE_IDENTIFIRE_CHAR;  // 表
     $switchHash['|'] = PLUGIN_CODE_IDENTIFIRE_CHAR;  // 表
    +$switchHash['^'] = PLUGIN_CODE_IDENTIFIRE_CHAR;  // 整形済出力
     $switchHash[' '] = PLUGIN_CODE_IDENTIFIRE_WORD;  // 整形済出力
     $switchHash['-'] = PLUGIN_CODE_MULTILINE;        // 箇条書
     $switchHash['+'] = PLUGIN_CODE_MULTILINE;        // 箇条書
     $switchHash[':'] = PLUGIN_CODE_MULTILINE;        // 箇条書
     $switchHash['<'] = PLUGIN_CODE_MULTILINE;        // 引用
     $switchHash['>'] = PLUGIN_CODE_MULTILINE;        // 引用
     
     ……
     
     $code_keyword = Array(
      ……
      '*' => 5,     // 見出し
      ',' => 6,     // 表
      '|' => 6,     // 表
      '-' => 7,     // 箇条書
      '+' => 7,     // 箇条書
      ':' => 7,     // 箇条書
    + '^' => 8,     // 整形済出力
      ' ' => 8,     // 整形済出力
      " \n" => 0,   // ハイライト無効
      '<' => 9,     // 引用
      '>' => 9,     // 引用
     
       );
     ?>
    }}}}
//
** 課題 [#se24fbd2]
- pukiwiki モードではなく、新たに nekowiki モードを作るべきか?
////////////////////////////////////////////////////////////////
* コメント [#rc83778e]
#pcomment

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