HTML::TreeBuilder::no_space_compacting

HTML::TreeBuilder で HTML を parse したとき、文字列中の改行コードは半角スペースに変換される。pre タグの中の改行コードはそのまま残る。正確に言うと、pre タグと textarea タグの中以外のホワイトスペースの連続は、半角スペース一個に変換される。
この動きは、no_space_compacting メソッドで変更できる。デフォルトは off になっているので compacting が行われる。これを 1 にセットすると変換が行われなくなる。

use strict;
use warnings;
use utf8;
use HTML::TreeBuilder;

my $text = "a\t \nb\t \n";
my $html = "<pre>$text</pre><p>$text</p>";
foreach my $switch (0, 1) {
    my $tree = HTML::TreeBuilder->new;
    my $default = $tree->no_space_compacting;
    if ($default != $switch) {
        $tree->no_space_compacting($switch);
        print {*STDERR} "no_space_compacting = $default -> $switch\n";        
    }
    else {
        print {*STDERR} "no_space_compacting = $switch (default)\n";
    }
    $tree->parse($html);
    $tree->eof;
    $tree->dump;
    $tree->delete;
}

実行してみる。

[takeyuki@sunya ~]$ perl space_compacting.pl
no_space_compacting = 0 (default)
<html> @0 (IMPLICIT)
  <head> @0.0 (IMPLICIT)
  <body> @0.1 (IMPLICIT)
    <pre> @0.1.0
      "a\x09 \x0ab\x09 \x0a"
    <p> @0.1.1
      "a b "
no_space_compacting = 0 -> 1
<html> @0 (IMPLICIT)
  <head> @0.0 (IMPLICIT)
  <body> @0.1 (IMPLICIT)
    <pre> @0.1.0
      "a\x09 \x0ab\x09 \x0a"
    <p> @0.1.1
      "a\x09 \x0ab\x09 \x0a"

追記

全角スペースは HTML::TreeBuilder が compacting するホワイトスペースに含まれない。正規表現の \s には全角スペースも含まれる (use utf8 の有無などで変わってくるかもしれない) ので注意。