package DocSet::Doc::POD2HTMLPS; use strict; use warnings; use DocSet::Util; use DocSet::RunTime; use vars qw(@ISA); require DocSet::Source::POD; @ISA = qw(DocSet::Source::POD); use DocSet::Doc::Common (); *postprocess = \&DocSet::Doc::Common::postprocess_ps_pdf; require Pod::POM; #require Pod::POM::View::HTML; #my $view_mode = 'Pod::POM::View::HTML'; my $view_mode = 'DocSet::Doc::POD2HTML::View::HTMLPS'; my %split_by = map {"head".$_ => 1} 1..4; sub convert { my ($self) = @_; set_render_obj($self); my $pom = $self->{parsed_tree}; my @sections = $pom->content(); shift @sections; # skip the title # foreach my $node (@sections) { ## my $type = $node->type(); ## print "$type\n"; # push @body, $node->present($view_mode); # } my @body = slice_by_head(@sections); my $vars = { meta => $self->{meta}, toc => $self->{toc}, body => \@body, dir => $self->{dir}, nav => $self->{nav}, last_modified => $self->{timestamp}, }; my $tmpl_file = 'page'; my $mode = $self->{tmpl_mode}; my $tmpl_root = $self->{tmpl_root}; $self->{output} = proc_tmpl($tmpl_root, $tmpl_file, $mode, {doc => $vars} ); unset_render_obj(); } sub slice_by_head { my @sections = @_; my @body = (); for my $node (@sections) { my @next = (); # assumption, after the first 'headX' section, there can only # be other 'headX' sections my $count = scalar $node->content; my $id = -1; for ($node->content) { $id++; next unless exists $split_by{ $_->type }; @next = splice @{$node->content}, $id; last; } push @body, $node->present($view_mode), slice_by_head(@next); } return @body; } 1; package DocSet::Doc::POD2HTML::View::HTMLPS; use DocSet::RunTime; use DocSet::Util; use File::Spec::Functions; use File::Basename; use vars qw(@ISA); require Pod::POM::View::HTML; @ISA = qw( Pod::POM::View::HTML); # we want the PDF to be layouted in a way that the chapter title comes # as h1 and the real h1 sections as h2, h2 as h3, and so on. sub view_head1 { my ($self, $head1) = @_; return "

" . $head1->title->present($self) . "

\n\n" . $head1->content->present($self); } sub view_head2 { my ($self, $head2) = @_; return "

" . $head2->title->present($self) . "

\n\n" . $head2->content->present($self); } sub view_head3 { my ($self, $head3) = @_; return "

" . $head3->title->present($self) . "

\n\n" . $head3->content->present($self); } sub view_head4 { my ($self, $head4) = @_; return "
" . $head4->title->present($self) . "
\n\n" . $head4->content->present($self); } sub view_seq_file { my ($self, $path) = @_; my $doc_obj = get_render_obj(); my $base_dir = dirname catfile $doc_obj->{src_root}, $doc_obj->{src_uri}; my $file = catfile $base_dir, $path; #warn "file: $file"; return qq{$path} unless -e $file; # since we cannot link to the text files which should stay as is # from ps/pdf, we simply include them inlined my $content = ''; read_file($file, \$content); return qq{$path:\n\n
$content
\n\n}; } # the
 section uses class "pre-section", which allows to use a custom
# look-n-feel via the CSS
sub view_verbatim {
    my ($self, $text) = @_;
    for ($text) {
        s/&/&/g;
        s//>/g;
    }

    # if the 
 section is too long ps2pdf fails to generate pdf,
    # so split it into 40 lines chunks.
    my $result = '';
    while ($text =~ /((?:[^\n]*\n?){1,40})/sg) {
        next unless length($1); # skip empty matches
        $result .= qq{
$1
\n}; } return $result; } *anchor = \&DocSet::Doc::Common::pod_pom_html_anchor; *view_seq_link_transform_path = \&DocSet::Doc::Common::pod_pom_html_view_seq_link_transform_path; #*view_seq_link = \&DocSet::Doc::Common::pod_pom_html_view_seq_link; 1; __END__ =head1 NAME C - POD source to PS (intermediate HTML) target converter =head1 SYNOPSIS =head1 DESCRIPTION Implements an C sub-class which converts a source document in POD, into an output document in PS (intermediate in HTML). =head1 METHODS For the rest of the super class methods see C. =over =item * convert =back =head1 Rendering Class documents using this class are rendered via C, which is a subclass of C. Since we want the final PDF document which potentially includes many chapters in it to look more as a book and have a nice Table of Contents, we need to change the default structure of C<=head1> specs, so the C<=head1 NAME> becomes a title of the chapter and removed from the POD source, therefore we need to bump up all the remaining C<=headX> headers by one. i.e. C<=head1> is rendered as C<=head2>, C<=head3> as C<=head3>, etc. Therefore we override the super class's methods C. In addition we put Ea nameE anchors next to the headers so the PDF document can be hyperlinked if the reader supports this feature. view_seq_file() is overriden too. Here we search for the file relative to the location of the document and if we find it we include its contents since the PDFs are created for making dead tree copies and therefore linking is not an option. Notice that it's OK to say FE/etc/passwdE since it won't be found unless you actually put it under the current documents path or put the source document in the I path. view_verbatim() is overriden: renders the EpreE...E/preE html, but defines a CSS class C so the look-n-feel can be adjusted. in addition it splits text into 40 lines chunks. This solves two problems: =over =item * C tries to fit the whole EpreE...E/preE in a single page ending up using a very small unreadable font when the text is long. =item * C fails to convert ps to pdf if the former includes EpreE...E/preE, longer than 40 lines in one chunk. =back The following rendering methods: anchor() and view_seq_link_transform_path() are defined in the C class and documented there. =head1 AUTHORS Stas Bekman Estas (at) stason.orgE =cut