Text::Hatena::Escaped
というわけで、Text::Hatenaに渡したらHTMLエスケープした上で整形するように継承してみた。
#!/usr/bin/perl use strict; use warnings; { package Text::Hatena::Escaped; use base qw(Text::Hatena); sub text_line { my $class = shift; my $text = shift->{items}->[2]; return $class->escape("$text\n"); } sub cdata { my $class = shift; my $items = shift->{items}; my $data = $items->[1]; $data = $class->escape($data); return "<$data>\n"; } sub pre_line { my $class = shift; my $items = shift->{items}; my $inlines = $class->expand($items->[2]); return $class->escape("$inlines\n"); } sub inline { my $class = shift; my $items = shift->{items}; my $item = $items->[0] or return; $item = $class->escape($item); $item = Text::Hatena::AutoLink->parse($item); return $item; } sub escape { my ($self, $text) = @_; return $text unless $text; for ($text) { s/&/&/g; s/</</g; s/>/>/g; s/"/"/g; } $text; } } warn Text::Hatena::Escaped->parse(<<EOL); >|| sub test { <script>alert('hoge')</script> } ||< * <h1>test</h1> - <h3>foo</h3> - <h3>bar</h3> |*<h1>名前</h1>|*<h1>色</h1>|*<h1>個数</h1>| |<b>りんご</b>|<b>赤</b>|<b>1</b>| <script>alert('hoge')</script [http://www.hatena.ne.jp/:title=Hatena] EOL
結果は
<div class="section"> <pre> sub test { <script>alert('hoge')</script> } </pre> </div> <div class="section"> <h3> <h1>test</h1></h3> <ul> <li> <h3>foo</h3></li> <li> <h3>bar</h3></li> </ul> <table> <tr> <th><h1>名前</h1></th> <th><h1>色</h1></th> <th><h1>個数</h1></th> </tr> <tr> <td><b>りんご</b></td> <td><b>赤</b></td> <td><b>1</b></td> </tr> </table> <p><script>alert('hoge')</script></p> <p><a href="http://www.hatena.ne.jp/">Hatena</a></p> </div>
こんな感じ。