Home > Archives > 2007年03月

2007年03月

Emacs Lisp をいじるの覚書 - プロパティというか face というか

テキストのプロパティは get-text-property で手に入る.face もプロパティなので (get-text-property (point) 'face) でカーソル位置の face がわかる.カーソル位置の face が適当な face だったら処理をするとかを次のように書ける.

(if (let ((prop (get-text-property (point) 'face))) (or (eq 'line-number-face prop) (eq 'over-under-full-face prop)))
 (しょり~))

これの場合 'line-number-face か 'over-under-full-face だったらなにかすると.

face の指定時に mouse-face を付けてあげるとマウスに反応して face を変えられる.font-lock-defaults に渡す font-lock-keywords のなかで,

(cons "\\(.*full ..box.*\\)\\(line.*\\)"
    '((1 over-under-full-face)
      (2 line-number-face)))

とか書くところを

(cons "\\(.*full ..box.*\\)\\(line.*\\)"
  '((1 (progn
        (set-text-properties (match-beginning 1) (match-end 1)
			    '(mouse-face highlight))
         'over-under-full-face))
    (2 (progn
         (set-text-properties (match-beginning 2) (match-end 2)
 			    '(mouse-face highlight))
          'line-number-face))))

のようにプロパティを設定する関数 set-text-properties を呼ぶようにする.よくわからんが 1 とか 2 とかの数字はマッチした subexpression の番号らしい.あとは,マウスが押されたときに関数を呼ぶように mode の設定のとこで

(local-set-key [mouse-1] 'hogehoge-suru-function)

とか設定しとけばいいみたい.

PEAR & Text_Highlighterをインストール

http://faq.sakura.ne.jp/wiki/wiki.cgi?cgi%a4%c8php#i16 を参考にしつつ PEAR のローカルコピーを作る.最大の難点は download_dir の設定が抜けていたためダウンロードできずに嵌ったことだった.つーわけで,ここらを考慮しつつ以下のようなコマンド列を発行してどうにか成功.

pear config-create /home/user/pear .pearrc
pear install -o PEAR
pear config-set download_dir $HOME/pear/temp
pear install -o channel://pear.php.net/Text_Highlighter-0.6.9

ついでに,php.ini にパスを通す記述をしておく.

include_path=".:/home/user/pear/pear/php"

ちょっとディレクトリ名があれかもしれない…

なにはともあれ,これで C++ や Java も使えるようになった.あとは elisp とか sed とかのための設定を作ればよいのかな.

NP_SyntaxHighlighter を試す

http://wakka.xiffy.nl/syntaxhighlighter より入手.

PEARText_Highlighter を使っているらしい.とりあえず pre タグでソースを書いてしまうので div でなく pre にクラスを書いて動くように修正.このプラグイン無しでも普通に表示できるようにHTMLエスケープされた文字列を食うように変更.ついでに,<?php と ?> で囲まれてない php もハイライトするうにあほな修正を入れてみた.

<?php
   function parseString(&$content) {
      $chk = ' class="highlight';
      if (strpos($content['body'],$chk) > 0 ||  strpos($content['more'],$chk) > 0) {
         if ($this->_setupPEAR()) {
            $supportedRules = $this->getOption('highlight_rules');
            $supported_highlighter = explode(',',$supportedRules);
            if (is_array($supported_highlighter)) {
               foreach ($supported_highlighter AS $key=>$syntax) {
                   $supported_highlighter[$key] = trim(strtolower($syntax));
               }
            } else {
               // fallback with default settings
               $supported_highlighter = $this->supported_highlighter;
            }
            $this->counter = 1;
            $highlight_str = '';
            $content_part = array('body','more');
            foreach ($content_part as $key) {
               // now check for all allowed syntax highlighter
               foreach ($supported_highlighter AS $syntax) {
                  $pattern = "/<pre class=\"highlight_".$syntax."\">(.*?)<\/pre>/esi";
                  $replacement = "\$this->highlight_code('\\1','".$syntax."')";
                  $content[$key] = preg_replace($pattern,$replacement,$content[$key]);
               }
            } // end content_part
         } else {
            doError('Check your settings - can not include PEAR::Text_Highlighter');
         }
         // some cleanup code
         ini_restore('include_path');
         unset($this->hl);
      }
   }
   function highlight_code($string, $mode)
   {
      // remove possible br tags from nucleus automatic linebreak convertion
      $string = preg_replace('/<br \/>[\n|\r| ]/', '', $string);
      $string = stripslashes($string);
      $string = str_replace ( array ( '&amp;' , '&quot;', '&apos;' , '&lt;' , '&gt;', '&apos;' ), array ( '&', '"', "'", '<', '>', '?' ), $string );
      $normflag=false;
      $va = strpos($string, "<?");
      if(strcmp($mode, 'php')==0 &&  ($va==FALSE || $va > 5)) {
    $normflag = true;
    $string = "<?php ".$string."?>";
      }
      // check is there a cached object
      if (!isset($this->hl[$mode])) {
         // create new highlighter object
         $options = array('tag' => $this->tag_mode,'numbers'=>$this->line_numbers);
         $this->hl[$mode] = & Text_Highlighter::factory($mode,$options);
      }
      // retrieve highlighted string
      $highlight_str = $this->hl[$mode]->highlight($string);
      // if higlight_mode == save add a dummy id to exclude from further parsing
      $checkid = '';
      if ($this->rendermode == 'save') {
          $checkid = 'id="np_hl_'.$this->counter.'" ';
      }
      // enclose with div container
      //$highlight_str = '<div '.$checkid.'class="highlight_'.$mode.'">'.$highlight_str.'</div>';
      $highlight_str = $highlight_str;
      $this->counter++;
      if($normflag){
    $highlight_str = str_replace("<span class=\"hl-inlinetags\">?&gt;</span>", "", $highlight_str);    
    $highlight_str = preg_replace("/(<span class=\"hl-inlinetags\">)?&lt;\\?php *\n(<\\/span>)?/", "", $highlight_str);    
      }
      return $highlight_str;
   }

追記:

Text_highlighter を新しくしたら <?php の後の空白とかの扱いが変わったらしい.なので最後のほうをちょっと書き換え.

<?php
    $highlight_str = preg_replace("/(<span class=\"hl-inlinetags\">)?<\\?php *(<\\/span>)?(<.*?>) *\n/", "\\3", $highlight_str);

Home > Archives > 2007年03月

Search
Feeds

Page Top