Perl日記

日々の知ったことのメモなどです。Perlは最近やってないです。

Text::Hamlでできること、できないこと

RubyHamlのつもりでPerlのText::Hamlを使うとつまづいてしまうメモ。
http://search.cpan.org/~vti/Text-Haml-0.990104/lib/Text/Haml.pm

インデントは半角スペースのみ

インデントにタブは使用できず、常に半角スペースでインデントしないとだめ。
いきなりこれでつまづいてたから困った。

日本語を含むときはencodingをundefで指定しないといけない

Text::HamlのデフォルトであるUTF-8文字コードのファイルでも。

my $haml = Text::Haml->new(encoding => undef);

こうしなければいけないみたい。
内部的にはこうなっていた。

binmode $file, ':utf8';
...
$tmpl = decode($self->encoding, $tmpl) if $self->encoding;

$self->encodingにはデフォルトで'utf-8'が入っているので、2回も文字列フラグをつけようとして(Encodeの)エラーになる。
ただこのままだと文字列フラグがついたまま返ってくるので、返ってきた段階でencode_utf8しないといけない。(もちろんUTF-8の場合)

use utf8;
my $haml = Text::Haml->new(encoding => undef);
my $output = $haml->render_file('./tmpl.haml', bar => 'ばず');
print encode_utf8($output);

変数は$をつける

%div= "うー!".$nya
my $output = $haml->render_file('var.haml',
    nya => 'にゃー!',
);
<div>うー!にゃー!</div>

$をつけたくないときは、vars_as_subsオプションを有効にする。

%div= "うー!".nya
my $haml = Text::Haml->new(encoding => undef, vars_as_subs => 1);
my $output = $haml->render_file('var.haml', 
    nya => 'にゃー!',
);
<div>うー!にゃー!</div>

Symbolが見た目使える

%div{ :class => "header" } タイトル
<div class='header'>タイトル</div>

Ruby風文字列挿入#{}が見た目使える

使えるのだけれど、本家のHamlと違い「=」をつけてはいけないので注意!
あとクオートで周りを括ってもだめだよ!

/ 「%div=」ではない
%div いつもニコニコ這い寄る混沌、#{$name}です!
my $output = $haml->render_file('interpolate.haml',
    name => 'ニャルラトホテプ',
);
<div>いつもニコニコ這い寄る混沌、ニャルラトホテプです!</div>

()と{}は同時に使用できない

%div(id="header")
    %div{:id=>"title"}
        PAGE TITLE
<div id='header'>
    <div id='title'>
        PAGE TITLE
    </div>
</div>

%要素に()か{}の片方だけなら問題ないが、両方同時はできない。

%div(id="header"){:class=>"title"}
    %div(class="header"){:id=>"title"}
        PAGE TITLE
$haml->error;
#=> Tag attributes parsing error

ヘルパ関数登録

ヘルパというよりサブルーチンをHaml内で使うとき。

%div
    %p
        = commify($money).""
my $haml = Text::Haml->new(
    helpers => {
        commify => sub {
            my $num = $_[1]; # First argument passed to the helper (Text::Haml instance by default).
            1 while $num =~ s/(.*\d)(\d\d\d)/$1,$2/;
            return $num;
        },
    },
);
# or
$haml->add_helper(
    commify => sub {
        my $num = $_[1]; # First argument passed to the helper (Text::Haml instance by default).
        1 while $num =~ s/(.*\d)(\d\d\d)/$1,$2/;
        return $num;
    },
);
<div>
    <p>
        1,000,000円
    </p>
</div>

if else end

本家のHamlはendが不要だが、Text::Hamlはifの評価にかっこも要るし、ブレースも要る。

%div
  - if (1) {
    OK
  - } else {
    NG
  - }
<div>
  OK
  
</div>

空白の行が出力されてしまうが、直後に何かある場合はなぜかつまる。

%div
  - if (1) {
    OK
  - } else {
    NG
  - }
  %p paragraph
<div>
  OK
  <p>paragraph</p>
</div>

タグ内の改行は調整できない

%div
  %div<
    %div OK
<div>
  <div>
    <div>OK</div>
  </div>
</div>
<div><div><div>OK</div></div></div>

とはならない。



Text::Hamlの実装が面白いのであとでよむ。