Question

I wrote a script, where i slurp in UTF-8 encoded HTML-file and then parse it to tree with HTML::Tree. Problem is that after parsing the strings are not marked as UTF-8 anymore.

As _utf8_on() is not recommended way to set flag on, i am looking for proper way.

My simplified code-example:

#!/usr/bin/perl

use strict;
use warnings;
use 5.010;
use utf8::all;
use autodie;
use HTML::Tree;
use Encode qw/is_utf8/;

my $file = shift;
my $tree;

if ($file) {
    my $content = slurp_in( 'file' => $file );
    $tree = html_tree('content' => $content);
} else {
    die "no file";
}

my $title = $tree->look_down(_tag => 'title');
$title = $title->as_HTML('');

if ( is_utf8( $title ) ) {
    say "OK: $title";
} else {
    say "NOT OK: $title";
}

## SUBS
##
sub slurp_in {
    my %v = @_;

    open(my $fh, "<:utf8", $v{file}) || die "no $v{file}: $!";
    local $/;
    my $content = (<$fh>);
    close $fh;

    if ($content) {
        return $content;
    } else {
        die "no content in $v{file} !";
    }
}

sub html_tree {
    my %v = @_;
    my $tree = HTML::Tree->new();
    $tree->utf8_mode(1); ## wrong call here, no such method, but no warnings on it!
    $tree->parse( $v{content} );

    if ($tree) {
        return $tree;
    } else {
        die "no tree here";
    }
}
Was it helpful?

Solution

Your code is overcomplicated, and you employ utf8::all and decode manually and call that strange method all at once. Rhetorically asking, what do you expect to achieve that way? I do not have the patience to find out the details what goes wrong and where, especially since you did not post any input with which your program fails to do the expected, so I drastically reduce it to a much simpler one. This works:

#!/usr/bin/env perl
use 5.010;
use strict;
use warnings FATAL => ':all';
use File::Slurp qw(read_file);  # autodies on error
use HTML::Tree qw();

my $file = shift;
die 'no file' unless $file;

my $tree = HTML::Tree->new_from_content(
    read_file($file, binmode => ':encoding(UTF-8)')
);

my $title = $tree->look_down(_tag => 'title');
$title->as_HTML(''); # returns a Perl string
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top