#!/usr/bin/perl package Mail::Summary::Tools::CLI::ToHTML; use base qw/Mail::Summary::Tools::CLI::Command/; use strict; use warnings; use Class::Autouse (<<'#\'END_USE' =~ m!(\w+::[\w:]+)!g); #\ use Mail::Summary::Tools::Summary; use Mail::Summary::Tools::Output::HTML; #'END_USE use constant options => ( [ 'verbose|v!' => "Output verbose information" ], [ 'input|i=s' => 'The summary YAML file to emit' ], [ 'output|o=s' => 'A file to output to (defaults to STDOUT)' ], [ 'archive|a=s' => 'On-line archive to use', { default => "google" } ], [ 'compact|c!' => 'Emit compact HTML (no
tags, etc)' ], [ 'body_only|b!' => 'Emit body fragment only (as opposed to a full, valid document)' ], [ 'xml|x!' => "use HTML::Element's as_XML method instead of the indented as_HTML" ], [ 'xhtml!' => "hackishly use startag_XML in as_HTML mode to emit valid xhtml (defaults to true)", { default => 1 }], [ 'h1=s@' => 'Tags to use instead of h1 (e.g. --h1 p,b emits

heading

)', { default => ["h1"] } ], [ 'h2=s@' => 'see h1', { default => ["h2"] } ], [ 'h3=s@' => 'see h1', { default => ["h3"] } ], [ 'lang=s' => 'sets the lang or xml:lang attribute of the element', { default => "en" } ], ); sub output { my $self = shift; my $opt = $self->{opt}; if ( !$opt->{output} or $opt->{output} eq '-' ) { binmode STDOUT, ":utf8"; return \*STDOUT; } elsif ( my $file = $opt->{output} ) { open my $fh, ">:utf8", $file or die "Couldn't open output (open($file): $!)\n"; return $fh; } } sub validate { my ( $self, $opt, $args ) = @_; @$args and $opt->{$_} ||= shift @$args for qw/input output/; unless ( $opt->{input} ) { $self->usage_error("Please specify an input summary YAML file."); } if ( @$args ) { $self->usage_error("Unknown arguments: @$args."); } foreach my $tag ( qw/h1 h2 h3/ ) { @{ $opt->{$tag} } = map { split ',' } @{ $opt->{$tag} }; } $self->{opt} = $opt; } sub run { my ( $self, $opt, $args ) = @_; my $summary = Mail::Summary::Tools::Summary->load( $opt->{input}, thread => { default_archive => $opt->{archive} || "google", archive_link_params => { cache => $self->app->context->cache }, }, ); my $o = Mail::Summary::Tools::Output::HTML->new( summary => $summary, body_only => $opt->{body_only}, strip_divs => $opt->{compact}, lang => $opt->{lang}, map { $_ . "_tag" => $opt->{$_} } qw/h1 h2 h3/, ); my @tree = $o->process; $self->print_tree($self->doctype, @tree); } sub pi_xhtml { HTML::Element->new('~literal' => text => ''); } sub pi_xml { HTML::Element->new('~pi' => text => 'xml version="1.0" encoding="UTF-8"'); } sub doctype_xhtml_11 { HTML::Element->new('~declaration' => text => 'DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"' . "\n" . ' "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"' ); } sub doctype_html_401 { HTML::Element->new('~declaration' => text => 'DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"' . "\n" . ' "http://www.w3.org/TR/html4/loose.dtd"' ); } sub doctype { my $self = shift; return if $self->{opt}{body_only}; if ( $self->{opt}{xml} ) { return ( $self->pi_xml, $self->doctype_xhtml_11 ); } elsif ( $self->{opt}{xhtml} ) { return ( $self->pi_xhtml, $self->doctype_xhtml_11 ); } else { return ( $self->doctype_html_401 ); } } sub print_tree { my ( $self, @tree ) = @_; my $out = $self->output; print $out $self->tree_to_text(@tree); } sub tree_to_text { my ( $self, @tree ) = @_; if ( $self->{opt}{xml} ) { return join("", map { $_->as_XML } @tree); } else { # emit valid XHTML no warnings 'redefine'; local *HTML::Element::starttag = sub { my ( $elem, $p ) = @_; my $empty = $elem->_empty_element_map->{$elem->tag}; $elem->starttag_XML($p, $empty ? 1 : () ); } if $self->{opt}{xhtml}; # FIXME should this be moved down to Output::HTML? unless ( $self->{opt}{xhtml} ) { foreach my $subtree ( @tree ) { if ( $subtree->tag eq "html" ) { $subtree->attr( xmlns => undef ); $subtree->attr( lang => $subtree->attr( 'xml:lang' => undef ) ); } } } # no optional end tags, two space indent, default entity escaping return join("", map { $_->as_HTML(undef, ' ', {}) } @tree); } } __PACKAGE__; __END__ =pod =head1 NAME Mail::Summary::Tools::CLI::ToHTML - Emit a formatted HTML summary =head1 SYNOPSIS # see command line usage =head1 DESCRIPTION