Friday, January 07, 2011

Pod::Simple::XHTML und Pod in UTF-8

Ich bin fast fertig mit der ersten Runde beim Versuch $foo auch als epub zu generieren. Die Ergebnisse sehen auch schon einigermaßen gut aus. Innerhalb des Umwandlungsprozesses benutze ich Pod::Simple::XHTML und die Artikel liegen in Pod vor - gespeichert als UTF-8.

Der Parser wurde bisher so benutzt:

my $parser = Pod::Simple::XHTML->new;
$parser->parse_file( 'article.pod' );

So kam dann aber "Müll" bei den Umlauten raus. Der Doctype und die charset-Angabe im Metatag waren korrekterweise auf UTF-8 gestellt.

Ein Blick in den Code von Pod::Simple::XHTML hat gezeigt, dass der Text durch HTML::Entities::encode_entities läuft. Also musste hier etwas schieflaufen.

In der Doku von HTML::Entities nichts bezüglich UTF-8 gefunden. Also schnell ein Testskript geschrieben und folgendes festgestellt:

use HTML::Entities;
my $text;
{
local $/;
open my $fh, '<', 'article.pod'; $text = <$fh>;
close $fh;
}

print encode_entities( $text );

bringt falsch Entities. Ein

use HTML::Entities;
my $text;
{
local $/;
open my $fh, '<', 'article.pod'; binmode ":encoding(utf-8)"; $text = <$fh>;
close $fh;
}

print encode_entities( $text );

funktioniert. Ich muss also den IO-Layer nehmen, damit die Perl die Datei gleich als UTF-8 einliest (über IO-Layer habe ich hier mal was Kurzes geschrieben).

Also liegt das Problem nicht bei HTML::Entities. Aber wie kann ich Pod::Simple::XHTML sagen, dass die Text UTF-8 sind? In der Doku nichts gefunden. Nachgeschaut, wie die Datei beim parse_file geöffnet wird. Heraus kam

{
local *PODSOURCE;
open(PODSOURCE, "<$source") || Carp::croak("Can't open $source: $!"); $self->{'source_filename'} = $source;
$source = *PODSOURCE{IO};
}

Also nix mit IO-Layern und auch die 2-arg-Form von open (siehe auch diesen Blogpost).

Bei Pod::Simple ist es so, dass auch neuere Releases rückwärtskompatibel gehalten werden bis pre-5.8. Da funktioniert das mit den IO-Layern nicht. So geht das also nicht.

Was aber Pod::Simple unterstützt ist parse_file( *FILEHANDLE ). Also setze ich das jetzt so ein:

open my $pod_fh, '<:encoding(utf-8)', 'article.pod' or die $!; my $parser = Pod::Simple::XHTML->new;
$parser->parse_file( $pod_fh );

5 comments:

Aristotle said...

Versteht Pod::Simple::XHTML die =encoding UTF-8-Anweisung nicht?

ReneeB said...

Hi Aristotle,

ich war mir eigentlich ganz sicher, dass ich das ausprobiert habe. Ich habe es gerade nochmal getestet und es funktioniert.

Wer weiß was ich vorher bei den Tests falsch gemacht habe...

Danke für den Hinweis.

- Renée

Rolf said...

Hallo,
wo kann ich Pod::Simple::XHTML die =encoding UTF-8- Anweisung mitgeben ? Finde da in der Doku und im Source nichts.
Habe gerade ein ähnliches Problem mit Pod::Site welches Pod::Simple::HTMLBatch auruft, welches Pod::Simle::XHTML usw....

Rolf

ReneeB said...

Die "=encoding utf-8" Anweisung übergibt man nicht an Pod::Simple::XHTML, sondern schreibt sie ganz an den Anfang der Dokumentation.

Das sieht dann so aus:

=encoding utf-8

=head1 NAME

...

bo said...

Hallo Renée,

mit "Pod::Parser" scheint der Trick mit dem "=encoding utf-8" im Pod nicht zu klappen.
Mit der Angabe beim Filehandle klappt es aber...

Gruß
Boris