Movable Type 備忘録

 MTPrecodeプラグイン

こんにちわ^^

今日は目の調子がいいので、がんばってプラグイン作ってみました ( ̄∇ ̄)/

先日、こちらのdp.SyntaxHighlighterで、各種コードを整形してくれるJavaScriptを紹介しました。
でも、わたしのところでは他のJavaScriptと競合!? しちゃうようで、あんまりよろしくないなぁ・・・と思って、コードを解析したら何となく作れそうだったので、似たようなものをプラグインとして作ってみたんです (●´∀`●)

- 2008.01.21 追記 -

行の先頭の空白文字(スペース、タブ)を実体参照文字に変換するよう対応しました。また、行末の空白文字を削除するよう対応しました。

- 2007.04.17 追記 -

すいません、MTPrecodeプラグインはエントリ内で使用するプラグインです。
ですので、こちらのエントリでMovableTypeのタグを使用するで紹介している、EvalTemplateプラグインと併用する必要があります。

EvalTemplateプラグインはエントリ内でもMovableType(ムーバブルタイプ)のテンプレート・タグを使用可能にしてくれるプラグインです。

- 2007.04.17 Ver1.01 -

行番号を任意の番号から開始できるよう対応しました。

- 2007.04.17 Ver.1.02 -

最初の1行目に改行が入ってしまう不具合を対応しました。

- 2007.04.17 Ver.1.03 -

タイトルを付けられるように対応しました。それに伴って、多少 CSS の変更が入ります。

- 2007.07.13 Ver.1.04 -

任意の行数を超える場合、縦スクロールバーを表示するように対応してみました。
多少 CSS を変更しました。

あと、MovableType 4でも問題なく表示できることを確認しました。

まずはサンプルですね。

  1. package MT::Plugin::Precode;
  2.  
  3. use strict;
  4. use MT::Template::Context;
  5. use base qw(MT::Plugin);
  6.  
  7. my $plugin = __PACKAGE__->new({
  8.     name => 'Precode',
  9.     version => '1.04',
  10.     author_name => 'bzbell',
  11.     description => 'Preformatted Code.',
  12.     author_link => 'http://bizcaz.com/',
  13.     doc_link => 'http://bizcaz.com/archives/2007/02/10-015235.php',
  14. });
  15. MT->add_plugin($plugin);
  16.  
  17. MT::Template::Context->add_container_tag (Precode => \&precode_main);
  18.  
  19. sub precode_main
  20. {
  21.     my ($ctx, $args, $cond) = @_;
  22.  
  23.     my $builder = $ctx->stash('builder');
  24.     my $tokens = $ctx->stash('tokens');
  25.  
  26.     my $start = 1;
  27.     my $title = '';
  28.     my $over = 30;
  29.     my $html = '';
  30.  
  31.     if ($args->{'start'}) {
  32.         $start = $args->{'start'};
  33.     }
  34.  
  35.     if ($args->{'title'}) {
  36.         $title = $args->{'title'};
  37.     }
  38.  
  39.     if ($args->{'overline'}) {
  40.         $over = $args->{'overline'};
  41.     }
  42.  
  43.     my $out = $builder->build ($ctx, $tokens, $cond);
  44.  
  45.     $out = precode_sub($out, $start, $title, $over);
  46.     $html .= $out;
  47.  
  48.     $html;
  49. }
  50.  
  51.  
  52. sub precode_sub
  53. {
  54.     my ($str, $start, $title, $over) = @_;
  55.  
  56.     my @result = ();
  57.     my @clname = ("\"precode-odd\"", "\"precode-eve\"");
  58.     my $out = "<div class=\"precode-block\">\n";
  59.     my $index = 0;
  60.  
  61.     if ('' ne $title) {
  62.         $out .= "<p class=\"precode-title\">$title</p>\n";
  63.     }
  64.  
  65.     @result = split(/\x0D\x0A|[\x0D\x0A]|\<br \/\>$/, $str);
  66.  
  67.     if ('' eq $result[0]) {
  68.         shift(@result);
  69.     }
  70.  
  71.     my $scroll = '';
  72.  
  73.     if ($over < @result) {
  74.         $scroll = 'scroll';
  75.     }
  76.  
  77.     if (1 < $start) {
  78.         $out .= "<div class=\"precode-wrapper ".$scroll."\">\n<ol start=\"$start\">\n";
  79.     } else {
  80.         $out .= "<div class=\"precode-wrapper ".$scroll."\">\n<ol>\n";
  81.     }
  82.  
  83.     foreach my $line (@result) {
  84.         if ('' eq $line) {
  85.             $line = ' ';
  86.         }
  87.  
  88.         $out .= '<li class='.$clname[$index].'><code>'.$line."</code></li>\n";
  89.         $index ^= 1;
  90.     }
  91.  
  92.     $out .= "</ol>\n</div>\n</div>";
  93.     return $out;
  94. }
  95.  
  96. 1;

上記はMTPrecodeプラグインのコードになります。
そのコードをMTPrecodeプラグインを使って整形したものです。

dp.SyntaxHighlighterと違って強調表示はされません。
でも、とりあえず目的の機能は満たしてると思います。

MTPrecodeプラグインの使い方

使い方はカンタンです。
整形したいテキストを<MTPrecode>コンテナタグで囲うだけです。
たとえば、以下のようなかんじで使います。

  1. <MTPrecode>
  2.     &lt;div&gt;
  3.         &lt;ul&gt;
  4.         &lt;li&gt;xxxxx&lt;/li&gt;
  5.         &lt;/ul&gt;
  6.     &lt;/div&gt;
  7. </MTPrecode>

そうすると、以下のように整形されます。

  1. <div class="precode-block">
  2.   <p class="precode-title">タイトル</p>
  3.   <div class="precode-wrapper">
  4.     <ol>
  5.     <li class="precode-odd"><span class="code"> &lt;div&gt;</li>
  6.     <li class="precode-eve"><span class="code"> &lt;ul&gt;</li>
  7.     <li class="precode-odd"><span class="code"> &lt;li&gt;xxxxx&lt;/li&gt;</li>
  8.     <li class="precode-eve"><span class="code"> &lt;/ul&gt;</li>
  9.     <li class="precode-odd"><span class="code"> &lt;/div&gt;</li>
  10.     </ol>
  11.   </div>
  12. </div>

あとは、上記で出力されるClassルールをCSSで各自の好みで変更するだけです ( ̄∇ ̄)b
ちなみに、例で示したスタイルは以下の通りです。

  1. div.precode-block {
  2.     margin: 1em 0;
  3.  
  4.     border: 5px solid #31313b;
  5.     background-color: #fefefe;
  6. }
  7.  
  8. div.precode-block p.precode-title {
  9.     margin: 0;
  10.     padding: 0;
  11.     padding-bottom: 5px;
  12.  
  13.     color: #d3d9f0;
  14.     background-color: #31313b;
  15. }
  16.  
  17. div.precode-block div.precode-wrapper {
  18.     overflow: auto;
  19. }
  20.  
  21. /*
  22.  * 縦スクロールバー表示用スタイル
  23.  */
  24. div.precode-block div.scroll {
  25.     height: 43em; /* 1.4 × 任意の表示行数(デフォルト:30行) + 1em */
  26. }
  27.  
  28. div.precode-block ol {
  29.     margin: .5em 0 .5em 55px;
  30.     padding: 0;
  31.  
  32.     color: #2b91af;
  33.     background-color: #fefefe;
  34. }
  35.  
  36. div.precode-block ol li {
  37.     padding: 0 .5em;
  38.  
  39.     line-height: 1.4;
  40.     border-left: 2px solid #303;
  41. }
  42.  
  43. div.precode-block ol li code {
  44.     font-family: monospace, 'Courier New', Courier, Fixed !important;
  45.     white-space: pre;
  46.     /*
  47.      * 横スクロールを表示せずに、折り返して表示させる場合
  48.      */
  49.     white-space: -moz-pre-wrap; /* Mozilla */
  50.     white-space: -pre-wrap; /* Opera 4-6 */
  51.     white-space: -o-pre-wrap; /* Opera 7 */
  52.     white-space: pre-wrap; /* CSS3 */
  53.     word-wrap: break-word; /* IE 5.5+ */
  54.  
  55.     color: #303;
  56. }
  57.  
  58. div.precode-block ol li.precode-odd {
  59.     background-color:#e7e7e7;
  60. }
  61. div.precode-block ol li.precode-eve {
  62. }

オプション

<MTPrecode>コンテナタグに以下のオプションを対応しました。

  • start
    指定した行番号から採番できます。デフォルトは1番から採番されます。

    1. <MTPrecode start="400">
    2.     &lt;div&gt;
    3.         &lt;ul&gt;
    4.         &lt;li&gt;xxxxx&lt;/li&gt;
    5.         &lt;/ul&gt;
    6.     &lt;/div&gt;
    7. </MTPrecode>

    青い字の部分で開始番号(=400)を指定しています。
    結果、以下のように表示されます。

    1.     &lt;div&gt;
    2.         &lt;ul&gt;
    3.         &lt;li&gt;xxxxx&lt;/li&gt;
    4.         &lt;/ul&gt;
    5.     &lt;/div&gt;

    - 補足 -

    このオプションでは、<ol>タグにstartオプションをつけることで任意の番号を表示させてます。
    でも、W3Cではstartオプションは推奨されていません。何でだろぅね (´・д・`)

    CSSだけでカウンタの設定は可能なんです...可能だけど、IEが未対応なんです。

  • title
    任意のタイトル名を付加することができます。日本語も表示可です。
    このオプションが指定されない限りタイトル表示はされません。

    1. <MTPrecode start="400" title="タイトル表示">
    2.     &lt;div&gt;
    3.         &lt;ul&gt;
    4.         &lt;li&gt;xxxxx&lt;/li&gt;
    5.         &lt;/ul&gt;
    6.     &lt;/div&gt;
    7. </MTPrecode>

    青い字の部分でタイトル表示の指定をしています。
    結果、以下のように表示されます。

    タイトル表示

    1. <MTPrecode start="400" title="タイトル表示">
    2.     &lt;div&gt;
    3.         &lt;ul&gt;
    4.         &lt;li&gt;xxxxx&lt;/li&gt;
    5.         &lt;/ul&gt;
    6.     &lt;/div&gt;
    7. </MTPrecode>
  • overline
    任意の行数以上になった場合、縦スクロールバーを表示することができます。デフォルトは 30行となっています。

    1. <MTPrecode overline="30">
    2.     &lt;div&gt;
    3.         &lt;ul&gt;
    4.         &lt;li&gt;xxxxx&lt;/li&gt;
    5.         &lt;/ul&gt;
    6.     &lt;/div&gt;
    7. </MTPrecode>

    青い字の部分で任意の行数を指定しています。
    結果、以下のように表示されます。

    1. package MT::Plugin::Precode;
    2.  
    3. use strict;
    4. use MT::Template::Context;
    5. use base qw(MT::Plugin);
    6.  
    7. my $plugin = __PACKAGE__->new({
    8.     name => 'Precode',
    9.     version => '1.04',
    10.     author_name => 'bzbell',
    11.     description => 'Preformatted Code.',
    12.     author_link => 'http://bizcaz.com/',
    13.     doc_link => 'http://bizcaz.com/archives/2007/02/10-015235.php',
    14. });
    15. MT->add_plugin($plugin);
    16.  
    17. MT::Template::Context->add_container_tag (Precode => \&precode_main);
    18.  
    19. sub precode_main
    20. {
    21.     my ($ctx, $args, $cond) = @_;
    22.  
    23.     my $builder = $ctx->stash('builder');
    24.     my $tokens = $ctx->stash('tokens');
    25.  
    26.     my $start = 1;
    27.     my $title = '';
    28.     my $over = 30;
    29.     my $html = '';
    30.  
    31.     if ($args->{'start'}) {
    32.         $start = $args->{'start'};
    33.     }
    34.  
    35.     if ($args->{'title'}) {
    36.         $title = $args->{'title'};
    37.     }
    38.  
    39.     if ($args->{'overline'}) {
    40.         $over = $args->{'overline'};
    41.     }
    42.  
    43.     my $out = $builder->build ($ctx, $tokens, $cond);
    44.  
    45.     $out = precode_sub($out, $start, $title, $over);
    46.     $html .= $out;
    47.  
    48.     $html;
    49. }
    50.  
    51. sub precode_sub
    52. {
    53.     my ($str, $start, $title, $over) = @_;
    54.  
    55.     my @result = ();
    56.     my @clname = ("\"precode-odd\"", "\"precode-eve\"");
    57.     my $out = "<div class=\"precode-block\">\n";
    58.     my $index = 0;
    59.  
    60.     if ('' ne $title) {
    61.         $out .= "<p class=\"precode-title\">$title</p>\n";
    62.     }
    63.  
    64.     @result = split(/\x0D\x0A|[\x0D\x0A]|\<br \/\>$/, $str);
    65.  
    66.     if ('' eq $result[0]) {
    67.         shift(@result);
    68.     }
    69.  
    70.     my $scroll = '';
    71.  
    72.     if ($over < @result) {
    73.         $scroll = 'scroll';
    74.     }
    75.  
    76.     if (1 < $start) {
    77.         $out .= "<div class=\"precode-wrapper ".$scroll."\">\n<ol start=\"$start\">\n";
    78.     } else {
    79.         $out .= "<div class=\"precode-wrapper ".$scroll."\">\n<ol>\n";
    80.     }
    81.  
    82.     foreach my $line (@result) {
    83.         if ('' eq $line) {
    84.             $line = ' ';
    85.         }
    86.  
    87.         $out .= '<li class='.$clname[$index].'><code>'.$line."</code></li>\n";
    88.         $index ^= 1;
    89.     }
    90.  
    91.     $out .= "</ol>\n</div>\n</div>";
    92.     return $out;
    93. }
    94.  
    95. 1;

    任意の行数に合わせて CSS の方も変更します。

    スタイルシート

    1. /*
    2.  * 縦スクロールバー表示用スタイル
    3.  */
    4. div.precode-block div.scroll {
    5.     height: 43em; /* 1.4 × 任意の表示行数(デフォルト:30行) + 1em */
    6. }

以上です。
MTPrecodeプラグイン

 Trackback Pings(3)

from 笑むなAikoの『お玉杓子は飲み物です』

1日悩んで、原因は「それ!?」ってコトってよく有りますよね?。 え…大ぼけはAikoだけ?。 ...

from blog.mystorage.jp

ソースコードをきれいに見せたかったので、方法を探してたらMTPrecodeなるM...

from まったり(。・・。)

記事投稿内容でソースコードを記入する時、今まではSyntaxHighlighter 2.1.364を利用していたのですが 機能が多すぎて使いきれてなかった...

 Comments(17)

#1: Posted by kazuking @ April 23, 2007 [REPLY]
user-pic

勝手にこのようなプラグイン待ってました!JavaScriptのOFF時の事考えると最近は使うスクリプトも色々と選んでしまう今日この頃です。使わせて頂きます。ありがとう御座います!

#2: Posted by bzbell @ April 24, 2007 [REPLY]
user-pic

>>1 kazuking さん

はじめまして^^

使っていただいてありがとうございます (m;_ _)mペコ

> …JavaScriptのOFF時の事考えると最近は使うスクリプトも色々と選んでしまう今日この頃です。

そうですね。
わたしはkazuking さんのようにJavaScript Offのことは考慮してませんが (; ̄∇ ̄A、本来なら考慮すべきですよね。

実際にわたしも各エントリで使ってますが、何か不都合などありましたらご連絡ください。

#3: Posted by Author Profile Page sagasan [livedoor.com] @ January 19, 2008 [REPLY]
user-pic

初めまして。ありがたく使わせていただいてます。

ところで、Windows XP、IE7で表示させた場合、
スペースが無視されてしまうようです。
oPERA9では問題ありませんでした。

何らかの回避方法をご存じでしたら、ご教授くださいませんか?

#4: Posted by Author Profile Page bzbell @ January 19, 2008 [REPLY]
user-pic

>>3 sagasan [livedoor.com] さん

こんばんわ^^

> ところで、Windows XP、IE7で表示させた場合、
> スペースが無視されてしまうようです。
> oPERA9では問題ありませんでした。

えっ あせあせ
確認してみます。

#5: Posted by Author Profile Page bzbell @ January 21, 2008 [REPLY]
user-pic

>>3 sagasan [livedoor.com] さん

こんばんわ^^

> ところで、Windows XP、IE7で表示させた場合、
> スペースが無視されてしまうようです。
> oPERA9では問題ありませんでした。

上記の件ですが、改善したと思いますあせあせ
お手数ですが再度ダウンロードしてご確認していただけますか。

#6: Posted by Author Profile Page sagasan [livedoor.com] @ January 21, 2008 [REPLY]
user-pic

>>5 bzbell さん
改良ありがとうございました。
でも・・・
ちょっとだけ、問題が残っているようです。
複数スペースが単一スペースとして
認識されてしまっています。

IE7独自の問題なんでしょうか?

#7: Posted by Author Profile Page sagasan [livedoor.com] @ January 21, 2008 [REPLY]
user-pic

>>5 bzbell さん
自分なりに検証してみたので、ご報告致します。
問題はCSSにある模様

div.precode-block ol li code の
whitespace: pre;を最後に指定するようにすると
うまくいきました。

div.precode-block ol li code {  font-family: monospace, 'Courier New', Courier, Fixed !important; /*  * 横スクロールを表示せずに、折り返して表示させる場合  */ white-space: -moz-pre-wrap; /* Mozilla */ white-space: -pre-wrap; /* Opera 4-6 */  white-space: -o-pre-wrap; /* Opera 7 */  white-space: pre-wrap; /* CSS3 */  word-wrap: break-word; /* IE 5.5+ */  white-space: pre; color: #303;}
preが上書きされて設定されてしまうのでしょうか?

#8: Posted by Author Profile Page bzbell @ January 21, 2008 [REPLY]
user-pic

>>6 sagasan [livedoor.com] さん
>>7 sagasan [livedoor.com] さん

> 複数スペースが単一スペースとして
> 認識されてしまっています。

えっあせあせ
それは未検証でした。
そうなんですか。IE7 はそのよな振る舞いをするんですね。

> preが上書きされて設定されてしまうのでしょうか?

はい。
そのようにスタイルを設定してます。

でも、IE7 で Mozilla や Opera の設定しても無視されると思ってたんですけどあせあせ
そっかぁ、IE7 だと white-space に無効な設定したことで、white-space 自体が無効になっちゃうのかなぁ。

でも、white-space: pre を最後にもってきてしまうと、Opera などにも影響でませんか!?
今のバージョンは問題ないのかなぁ。

いずれにしても勉強になりました。
ありがとうございましたもじもじ

#9: Posted by yutaka @ June 13, 2008 [REPLY]
user-pic

こんばんわ〜、今度はこれに挑戦してます。
1)MTPrecodeプラグインをダウンロードしてmt/pluginディレクトリーにアップ
2)エントリー中の、例で示したスタイルは以下の通りですの部分のコードをテンプレートのスタイルシートテーマに記述
3)コードを各部分を
<MTPrecode>

</MTPrecode>
で囲んでテストしてみましたが、これだけでは駄目なようです。あとどんな作業が要りますか?よろしくお願いします。

#10: Posted by Author Profile Page bzbell @ June 13, 2008 [REPLY]
user-pic

>>9 yutaka さん

記事内にも記載してますが MTPrecode プラグインは EvalTemplate プラグインと併用する必要があります。
そちらがインストールされてないのではないでしょうかあせあせ

#11: Posted by yutaka @ June 14, 2008 [REPLY]
user-pic

>>10 bzbell さん
>EvalTemplate プラグインと併用する必要があります。
済みません見逃してましたべ~
エントリーを読みながら控えたメモに
修正前
<div class="entry-body"><$MTEntryBody$></div>
修正後
<div class="entry-body"><$MTEntryBody eval="1"$></div>
この部分を控えておいたのですが、今エントリーを探しているのですが、どのエントリーだったのか?分からないのですが
上の部分ってこのカスタマイズの必要項目ですよね?

#12: Posted by Author Profile Page bzbell @ June 14, 2008 [REPLY]
user-pic

>>11 yutaka さん

こちらの記事になります。
http://bizcaz.com/archives/2006/05/14-142231.php

ちなみに、MT4.2 から上記記事で使用する EvalTemplate プラグインと同等の機能が追加されてます。
ですので、MT4.2 を使う場合には不要になりますので、覚えておいてくださいねふつう

#13: Posted by yutaka @ June 14, 2008 [REPLY]
user-pic

>>12 bzbell さん
>MT4.2 を使う場合には不要になりますので、覚えておいてください
了解ですバイバイ

#12:のコメントのエントリーで説明されている修正箇所なんですが、修正するテンプレート名が違うので探したのですが修正するコードがあるテンプレートは「ブログ記事の概要」「ブログ記事の詳細」この二つのテンプレートしか見つけられなく
「個別アーカイブ」「カテゴリアーカイブ」「日付アーカイブ」と書いてあるテンプレートはどのテンプレートでしょうか?エントリーを書いてみたのですが、取りあえず表示されているようですがガーン

#14: Posted by Author Profile Page bzbell @ June 14, 2008 [REPLY]
user-pic

>>13 yutaka さん

はい。
「ブログ記事の概要」、「ブログ記事の詳細」でいいですようぅ~ん
というのは、この記事は MT4 以前のバージョンの時のものなので、テンプレートの構造が異なります。

以前にも言ったかもしれませんが、カスタマイズ記事内容によっては必ずしも MT4 を元にした説明となってません。
そこら辺は臨機応変に対応していただく必要がありますもじもじ

#15: Posted by Author Profile Page Kei @ September 7, 2008 [REPLY]
user-pic

こんにちわぁにこっ!
MTPrecode使わせていただいております

私的に以前から思っていた事なんですが。。
MTPrecodeを使って書かれているコードをコピペして張り付けると
行番号まで付いてきてしまう。。
内容のみをコピペできる方法あればと、、質問?にきましたあせあせ

#16: Posted by Author Profile Page bzbellからKeiへの返信 @ September 7, 2008 [REPLY]
user-pic

>>15 Kei さん

こんにちわ^^

> MTPrecodeを使って書かれているコードをコピペして張り付けると
> 行番号まで付いてきてしまう。。
はい。それは以前から言われてたことなのですが、実はそれってブラウザによるんですしくしく
たとえば、Safari とか先日公開された Chrome、IE では行番号は付加されないのですが、Firefox では行番号が付加されちゃうんですあせあせたぶん Firefox では ol タグの内容をコピーしても同様に行番号が付加されるんだと思います。

で、対策としては JavaScript を利用すれば可能です。
でも、JavaScript を使うなら最初っから dp.SyntaxHighlighter 使えばいいよね!? っという結論になりましたのガーン

#17: Posted by Author Profile Page Kei @ September 7, 2008 [REPLY]
user-pic

なるほどぉあせあせ
了解しました!

 Post a Comment

 

コメント用フィード