平コードの総行数が1つ不足する問題を修正 EditToHeaderToFooter

方針 EditToHeaderToFooter

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

改造 EditToHeaderToFooter

  • plugin/code/codehighlight.phpfunction highlight の前半にて、
      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
    
             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 から開始するように仕様変更 EditToHeaderToFooter

方針 EditToHeaderToFooter

  • 行数は自然数で数える方が自然かと。
  • 次の改造と合わせ、_plugin_code_makeNumber の呼出しが単純で規則的になる。

改造 EditToHeaderToFooter

  • plugin/code/codehighlight.php の #function _plugin_code_makeNumber## にて、
      1
      2
      3
      4
      5
      6
      7
      8
      9
    
    -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 の前半で、平コードの改造の直後にて、
      1
      2
      3
      4
      5
      6
      7
      8
      9
     10
     11
     12
     13
     14
     15
     16
     17
     18
     19
     20
     21
    
             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 の最後にて、
      1
      2
      3
      4
      5
      6
      7
      8
      9
     10
    
             // 最後の余分な改行を削除
             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 の最後にて、
      1
      2
      3
      4
      5
      6
      7
      8
      9
     10
     11
     12
     13
     14
    
             // 最後の余分な改行を削除
             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 モードで空白開始行を表示するように変更/
コメント行の行末に現れる余計な改行の除去 EditToHeaderToFooter

方針 EditToHeaderToFooter

  • diff をコードの変更を示す目的(汎用差分)で使用する場合、無変更行を位置のマーカーとして表示できると便利。
  • この改造により、_plugin_code_makeNumber の3箇所の呼出しから引数の補正が無くなる。
  • plugin/code/line.diff.php にて、
      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
    
        ...
        $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.phpfunction lineToHTML にて、
      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
    
        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 モードで、複数行インライン数式で行番号が狂う問題を修正 EditToHeaderToFooter

現象 EditToHeaderToFooter

次のコードで行番号で、数式中の改行を数え忘れ。

#code(tex){{{{
    関数$
        y = f(x)
    $と置く。
}}}}

改造 EditToHeaderToFooter

  • plugin/code/codehighlight.phpfunction srcToHTML の後半、case PLUGIN_CODE_FORMULA: にて、
      1
      2
      3
      4
      5
      6
      7
      8
      9
     10
     11
     12
     13
     14
     15
     16
     17
     18
     19
     20
     21
     22
     23
     24
    
             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 モードで、字下げ書式対応 EditToHeaderToFooter

方針 EditToHeaderToFooter

  • 字下げ拡張をしたため、コードプラグインの PukiWiki モードにも対応させるべし。

改造 EditToHeaderToFooter

  • plugin/code.inc.php の先頭にて、
      1
      2
      3
      4
      5
      6
      7
      8
      9
    
     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 にて、
      1
      2
      3
      4
      5
      6
      7
      8
      9
     10
     11
     12
     13
     14
     15
     16
    
         $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.phpfunction lineToHTML にて、
      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
     44
     45
     46
     47
     48
     49
     50
     51
     52
     53
     54
     55
     56
     57
     58
     59
     60
     61
     62
     63
     64
     65
     66
     67
     68
     69
     70
     71
     72
     73
     74
     75
     76
     77
     78
     79
     80
    
         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 にて、
      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
    
     <?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,     // 引用
     
       );
     ?>
    

    課題 EditToHeaderToFooter

  • pukiwiki モードではなく、新たに nekowiki モードを作るべきか?

php モードで、勝手に付けられる「<?php 」と「 ?>」の無効化 EditToHeaderToFooter

方針 EditToHeaderToFooter

  • <?php 」と「 ?>」にマーカを付けて、丸ごと削除。
    • タグは残しても無害なので、放置。

改造 EditToHeaderToFooter

  • plugin/code/codehightlight.phpclass CodeHighlight の後半、function highlightPHP にて、
      1
      2
      3
      4
      5
      6
      7
      8
      9
     10
     11
     12
     13
     14
     15
     16
     17
     18
     19
    
         function highlightPHP($src) {
             // phpタグが存在するか?
             $phptagf = false;
             if(! strstr($src,'<?php')) {
                 $phptagf = true;
    -            $src='<'.'?php '.$src.' ?'.'>';
    +            $src='<?php __dammy__head__ '.$src.' __dammy__tail__ ?>';
             }
             ……
             
             // phpタグを取り除く。
             if ($phptagf) {
    -            $html = preg_replace('/&lt;\?php (.*)?(<font[^>]*>\?&gt;<\/font>|\?&gt;)/m','$1',$html);
    +            $html = preg_replace('/&lt;\?php&nbsp;__dammy__head__&nbsp;/','',$html);
    +            $html = preg_replace('/(&nbsp;)*__dammy__tail__&nbsp;\?&gt;/','',$html);
                 // Debug:: http://pukiwiki.sourceforge.jp/?%E8%87%AA%E4%BD%9C%E3%83%97%E3%83%A9%E3%82%B0%E3%82%A4%E3%83%B3%2Fcodehighlight.inc.php
                 // Comment -- 2007-12-08 (土) 13:56:18
             }
             ……
    

インラインコード EditToHeaderToFooter

方針 EditToHeaderToFooter

  • とりあえず等幅フォントで出力
  • 色付けは codehightlight.php を理解してから

実装 EditToHeaderToFooter

  • plugin/code.inc.php の前半、function plugin_code_convertの前にて、
      1
      2
      3
      4
    
    function plugin_code_inline()
    {
        return '<span class="code_inline">'.rtrim(rtrim(join(func_get_args(), ','), ','), "\r").'</span>'; 
    } 
  • code タグを使わないのは、コードが小さく表示されるのを避けるため。CSSで無効化ができたら使う予定。

code.php / 2012.0817.0046 EditToHeaderToFooter

  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
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
<?php
/**
 * コードハイライト機能をPukiWikiに追加する
 * @author sky
 * Time-stamp: <05/07/30 20:00:55 sasaki>
 * 
 * GPL
 *
 * Ver. 0.5.0
 */
 
define('PLUGIN_CODE_LANGUAGE', 'pre');  // 標準言語 全て小文字で指定
// 標準設定
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);  // 字下げ拡張
 
 
// URLで指定したファイルを読み込むか否か
define('PLUGIN_CODE_READ_URL',  false);
 
// テーブルを使うか否か(falseはCSSのdivによる分割)
define('PLUGIN_CODE_TABLE',     true);
 
// TAB幅
define('PLUGIN_CODE_WIDTHOFTAB', '    ');
// 画像ファイルの設定
define('PLUGIN_CODE_IMAGE_FILE', IMAGE_DIR.'code_dot.png');
 
define('PLUGIN_CODE_OUTLINE_OPEN_FILE',  IMAGE_DIR.'code_outline_open.png');
define('PLUGIN_CODE_OUTLINE_CLOSE_FILE', IMAGE_DIR.'code_outline_close.png');
 
if (! defined('FILE_ICON')) {
    define('FILE_ICON',
    '<img src="' . IMAGE_DIR . 'file.png" width="20" height="20"' .
    ' alt="file" style="border-width:0px; vertical-align:middle;" />');
}
 
 
define('PLUGIN_CODE_USAGE', 
       '<p class="error">Plugin code: Usage:<br />#code[(Lang)]{{<br />src<br />}}</p>');
 
 
function pluing_code_init()
{
    global $javascript; $javascript = true;
}
function plugin_code_action()
{
    global $vars;
    global $_source_messages;
    
    if (PKWK_SAFE_MODE) die_message('PKWK_SAFE_MODE prohibits this');
 
    $vars['refer'] = $vars['page'];
 
    if (! is_page($vars['page']) || ! check_readable($vars['page'],false,false)) {
        return array( 'msg' => $_source_messages['msg_notfound'],
                      'body' => $_source_messages['err_notfound'] );
    }
    return array( 'msg' => $_source_messages['msg_title'],
                  'body' => plugin_code_convert('pukiwiki',
                                                join('',get_source($vars['page']))."\n"));
}
 
function plugin_code_inline()
{
//    return '<span class="code_inline">'.rtrim(rtrim(join(func_get_args(), ','), ','), "\r").'</span>'; 
    return '<span class="code_inline">'.rtrim(join(func_get_args(), ','), "\r").'</span>';
    // Debug: ##;,##で「,」が表示されないバグを直すため
    // 他で「,」が余計に現れないかは未確認
}
 
function plugin_code_convert()
{
    if (file_exists(PLUGIN_DIR.'code/codehighlight.php'))
        require_once(PLUGIN_DIR.'code/codehighlight.php');
    else
        die_message('file '.PLUGIN_DIR.'code/codehighlight.php not exist or not readable.');
 
    static $plugin_code_jscript_flag = true;
    
    $title = '';
    $lang = null;
    $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,  // 字下げ 無効
                    );
    
    $num_of_arg = func_num_args();
    $args = func_get_args();
    if ($num_of_arg < 1) {
        return PLUGIN_CODE_USAGE;
    }
 
    $arg = $args[$num_of_arg-1];
    if (strlen($arg) == 0) {
        return PLUGIN_CODE_USAGE;
    }
 
    if ($num_of_arg != 1 && ! _plugin_code_check_argment($args[0], $option)) {
        $is_setlang = true;
        $lang = htmlspecialchars(strtolower($args[0])); // 言語名かオプションの判定
    } else
        $lang = PLUGIN_CODE_LANGUAGE; // default
 
    $begin = 0;
    $end = null;
    // オプションを調べる
    for ($i = 1;$i < $num_of_arg-1; ++$i) {
        if (! _plugin_code_check_argment($args[$i], $option))
            _plugin_code_get_region($args[$i], $begin, $end);
    }
    $multiline = _plugin_code_multiline_argment($arg, $data, $option, $begin, $end);
    
    if (PLUGIN_CODE_CACHE && ! $multiline) { 
        $html = _plugin_code_read_cache($arg);
        if ($html != '' or $html != null)
            return $html;
    }        
    
    if (isset($data['_error']) && $data['_error'] != '') {
        return $data['_error'];
    }
    $lines = $data['data'];
    $title = $data['title'];
    
    $highlight = new CodeHighlight;
    $lines = $highlight->highlight($lang, $lines, $option);
    $lines = '<div class="'.$lang.'">'.$lines.'</div>';
    
    if ($plugin_code_jscript_flag && ($option['outline'] || $option['comment'])) {
        $plugin_code_jscript_flag = false;
        $title .= '<script type="text/javascript" src="'.SKIN_DIR.'code.js"></script>'."\n";
    }
    $html = $title.$lines;
    if (PLUGIN_CODE_CACHE && ! $multiline) {
        _plugin_code_write_cache($arg, $html);
    }
    return $html;
}
 
/**
 *  キャッシュに書き込む
 * 引数は添付ファイル名, HTML変換後のファイル
 */
function _plugin_code_write_cache($fname, $html)
{
    global $vars;
    // 添付ファイルのあるページ: defaultは現在のページ名
    $page = isset($vars['page']) ? $vars['page'] : '';
    
    // ファイル名にページ名(ページ参照パス)が合成されているか
    //   (Page_name/maybe-separated-with/slashes/ATTACHED_FILENAME)
    if (preg_match('#^(.+)/([^/]+)$#', $fname, $matches)) {
        if ($matches[1] == '.' || $matches[1] == '..')
            $matches[1] .= '/'; // Restore relative paths
            $fname = $matches[2];
            $page = get_fullname(strip_bracket($matches[1]), $page); // strip is a compat
            $file = encode($page) . '_' . encode($fname);
    } else {
        // Simple single argument
        $file =  encode($page) . '_' . encode($fname);
    }
    $fp = fopen(CACHE_DIR.'code/'.$file.'.html', 'w') or
        die_message('Cannot write cache file ' .
                    CACHE_DIR.'code/'. $file .'.html'.
                    '<br />Maybe permission is not writable or filename is too long');
    
    set_file_buffer($fp, 0);
    flock($fp, LOCK_EX);
    rewind($fp);
    fputs($fp, $html);
    flock($fp, LOCK_UN);
    fclose($fp);
}
 
/**
 * キャッシュを読み出す
 * 引数は添付ファイル名
 * 変換されたファイルデータを返す
 */
function _plugin_code_read_cache($fname)
{
    global $vars;
    // 添付ファイルのあるページ: defaultは現在のページ名
    $page = isset($vars['page']) ? $vars['page'] : '';
    
    // ファイル名にページ名(ページ参照パス)が合成されているか
    //   (Page_name/maybe-separated-with/slashes/ATTACHED_FILENAME)
    if (preg_match('#^(.+)/([^/]+)$#', $fname, $matches)) {
        if ($matches[1] == '.' || $matches[1] == '..')
            $matches[1] .= '/'; // Restore relative paths
        $fname = $matches[2];
        $page = get_fullname(strip_bracket($matches[1]), $page); // strip is a compat
        $file = encode($page) . '_' . encode($fname);
    } else {
        // Simple single argument
        $file =  encode($page) . '_' . encode($fname);
    }
    
    /* Read file data */
    $fdata = '';
    $filelines = file(CACHE_DIR.'code/'.$file.'.html');
    
    foreach ($filelines as $line)
        $fdata .= $line;
    
    return $fdata;
}
?>
 
リロード   新規 編集 凍結 差分 添付 複製 改名   初基 一覧 検索 最新 バックアップ リンク元   ヘルプ   最終更新のRSS
Last-modified: 2012.0817 (金) 0052.5900 (4269d)