home *** CD-ROM | disk | FTP | other *** search
/ PC Professionell 2004 December / PCpro_2004_12.ISO / files / webserver / tsw / TSW_3.4.0.exe / Apache2 / perl / POD2HTMLPS.pm < prev    next >
Encoding:
Perl POD Document  |  2002-06-13  |  6.4 KB  |  252 lines

  1. package DocSet::Doc::POD2HTMLPS;
  2.  
  3. use strict;
  4. use warnings;
  5.  
  6. use DocSet::Util;
  7. use DocSet::RunTime;
  8.  
  9. use vars qw(@ISA);
  10. require DocSet::Source::POD;
  11. @ISA = qw(DocSet::Source::POD);
  12.  
  13. use DocSet::Doc::Common ();
  14. *postprocess = \&DocSet::Doc::Common::postprocess_ps_pdf;
  15.  
  16. require Pod::POM;
  17. #require Pod::POM::View::HTML;
  18. #my $view_mode = 'Pod::POM::View::HTML';
  19. my $view_mode = 'DocSet::Doc::POD2HTML::View::HTMLPS';
  20.  
  21. my %split_by = map {"head".$_ => 1} 1..4;
  22.  
  23. sub convert {
  24.     my($self) = @_;
  25.  
  26.     set_render_obj($self);
  27.  
  28.     my $pom = $self->{parsed_tree};
  29.  
  30.     my @sections = $pom->content();
  31.     shift @sections; # skip the title
  32.  
  33. #    foreach my $node (@sections) {
  34. ##    my $type = $node->type();
  35. ##        print "$type\n";
  36. #    push @body, $node->present($view_mode);
  37. #    }
  38.  
  39.     my @body = slice_by_head(@sections);
  40.  
  41.     my $vars = {
  42.                 meta => $self->{meta},
  43.                 toc  => $self->{toc},
  44.                 body => \@body,
  45.                 dir  => $self->{dir},
  46.                 nav  => $self->{nav},
  47.                 last_modified => $self->{timestamp},
  48.                };
  49.  
  50.     my $tmpl_file = 'page';
  51.     my $mode = $self->{tmpl_mode};
  52.     my $tmpl_root = $self->{tmpl_root};
  53.     $self->{output} = proc_tmpl($tmpl_root, $tmpl_file, $mode, {doc => $vars} );
  54.  
  55.     unset_render_obj();
  56.  
  57. }
  58.  
  59.  
  60. sub slice_by_head {
  61.     my @sections = @_;
  62.     my @body = ();
  63.     for my $node (@sections) {
  64.         my @next = ();
  65.         # assumption, after the first 'headX' section, there can only
  66.         # be other 'headX' sections
  67.         my $count = scalar $node->content;
  68.         my $id = -1;
  69.         for ($node->content) {
  70.             $id++;
  71.             next unless exists $split_by{ $_->type };
  72.             @next = splice @{$node->content}, $id;
  73.             last;
  74.         }
  75.         push @body, $node->present($view_mode), slice_by_head(@next);
  76.     }
  77.     return @body;
  78. }
  79.  
  80. 1;
  81.  
  82.  
  83. package DocSet::Doc::POD2HTML::View::HTMLPS;
  84.  
  85. use DocSet::RunTime;
  86. use DocSet::Util;
  87.  
  88. use File::Spec::Functions;
  89. use File::Basename;
  90.  
  91. use vars qw(@ISA);
  92. require Pod::POM::View::HTML;
  93. @ISA = qw( Pod::POM::View::HTML);
  94.  
  95. # we want the PDF to be layouted in a way that the chapter title comes
  96. # as h1 and the real h1 sections as h2, h2 as h3, and so on.
  97.  
  98. sub view_head1 {
  99.     my ($self, $head1) = @_;
  100.     return "<h2>" . $self->anchor($head1->title) . "</h2>\n\n" .
  101.         $head1->content->present($self);
  102. }
  103.  
  104. sub view_head2 {
  105.     my ($self, $head2) = @_;
  106.     return "<h3>" . $self->anchor($head2->title) . "</h3>\n\n" .
  107.         $head2->content->present($self);
  108. }
  109.  
  110. sub view_head3 {
  111.     my ($self, $head3) = @_;
  112.     return "<h4>" . $self->anchor($head3->title) . "</h4>\n\n" .
  113.         $head3->content->present($self);
  114. }
  115.  
  116. sub view_head4 {
  117.     my ($self, $head4) = @_;
  118.     return "<h5>" . $self->anchor($head4->title) . "</h5>\n\n" .
  119.         $head4->content->present($self);
  120. }
  121.  
  122. sub view_seq_file {
  123.     my ($self, $path) = @_;
  124.     my $doc_obj = get_render_obj();
  125.     my $base_dir = dirname catfile $doc_obj->{src_root}, $doc_obj->{src_uri};
  126.     my $file = catfile $base_dir, $path;
  127.     #warn "file: $file";
  128.  
  129.     return qq{<i>$path</i>} unless -e $file;
  130.  
  131.     # since we cannot link to the text files which should stay as is
  132.     # from ps/pdf, we simply include them inlined
  133.     my $content = '';
  134.     read_file($file, \$content);
  135.  
  136.     return qq{<i>$path</i>:\n\n<pre>$content</pre>\n\n};
  137. }
  138.  
  139. # the <pre> section uses class "pre-section", which allows to use a custom
  140. # look-n-feel via the CSS
  141. sub view_verbatim {
  142.     my ($self, $text) = @_;
  143.     for ($text) {
  144.         s/&/&/g;
  145.         s/</</g;
  146.         s/>/>/g;
  147.     }
  148.  
  149.     # if the <pre> section is too long ps2pdf fails to generate pdf,
  150.     # so split it into 40 lines chunks.
  151.     my $result = '';
  152.     while ($text =~ /((?:[^\n]*\n?){1,40})/sg) {
  153.         next unless length($1); # skip empty matches
  154.         $result .= qq{<pre class="pre-section">$1</pre>\n};
  155.     }
  156.  
  157.     return $result;
  158. }
  159.  
  160.  
  161.  
  162. *anchor        = \&DocSet::Doc::Common::pod_pom_html_anchor;
  163. *view_seq_link_transform_path = \&DocSet::Doc::Common::pod_pom_html_view_seq_link_transform_path;
  164.  
  165. #*view_seq_link = \&DocSet::Doc::Common::pod_pom_html_view_seq_link;
  166.  
  167. 1;
  168.  
  169.  
  170.  
  171. __END__
  172.  
  173. =head1 NAME
  174.  
  175. C<DocSet::Doc::POD2HTMLPS> - POD source to PS (intermediate HTML) target converter
  176.  
  177. =head1 SYNOPSIS
  178.  
  179.  
  180.  
  181. =head1 DESCRIPTION
  182.  
  183. Implements an C<DocSet::Doc> sub-class which converts a source
  184. document in POD, into an output document in PS (intermediate in HTML).
  185.  
  186. =head1 METHODS
  187.  
  188. For the rest of the super class methods see C<DocSet::Doc>.
  189.  
  190. =over
  191.  
  192. =item * convert
  193.  
  194. =back
  195.  
  196. =head1 Rendering Class
  197.  
  198. documents using this class are rendered via
  199. C<DocSet::Doc::POD2HTML::View::HTMLPS>, which is a subclass of
  200. C<Pod::POM::View::HTML>.
  201.  
  202. Since we want the final PDF document which potentially includes many
  203. chapters in it to look more as a book and have a nice Table of
  204. Contents, we need to change the default structure of C<=head1> specs,
  205. so the C<=head1 NAME> becomes a title of the chapter and removed from
  206. the POD source, therefore we need to bump up all the remaining
  207. C<=headX> headers by one. i.e. C<=head1> is rendered as C<=head2>,
  208. C<=head3> as C<=head3>, etc. Therefore we override the super class's
  209. methods C<view_head{1-4}>. In addition we put E<lt>a nameE<gt> anchors
  210. next to the headers so the PDF document can be hyperlinked if the
  211. reader supports this feature.
  212.  
  213. view_seq_file() is overriden too. Here we search for the file relative
  214. to the location of the document and if we find it we include its
  215. contents since the PDFs are created for making dead tree copies and
  216. therefore linking is not an option. Notice that it's OK to say
  217. FE<lt>/etc/passwdE<gt> since it won't be found unless you actually put
  218. it under the current documents path or put the source document in
  219. the I</> path.
  220.  
  221. view_verbatim() is overriden: renders the
  222. E<lt>preE<gt>...E<lt>/preE<gt> html, but defines a CSS class
  223. C<pre-section> so the look-n-feel can be adjusted. in addition it
  224. splits text into 40 lines chunks. This solves two problems:
  225.  
  226. =over
  227.  
  228. =item *
  229.  
  230. C<html2ps> tries to fit the whole E<lt>preE<gt>...E<lt>/preE<gt> in a
  231. single page ending up using a very small unreadable font when the text
  232. is long.
  233.  
  234. =item *
  235.  
  236. C<ps2pdf> fails to convert ps to pdf if the former includes
  237. E<lt>preE<gt>...E<lt>/preE<gt>, longer than 40 lines in one chunk.
  238.  
  239. =back
  240.  
  241. The following rendering methods: anchor() and
  242. view_seq_link_transform_path() are defined in the
  243. C<DocSet::Doc::Common> class and documented there.
  244.  
  245.  
  246. =head1 AUTHORS
  247.  
  248. Stas Bekman E<lt>stas (at) stason.orgE<gt>
  249.  
  250. =cut
  251.  
  252.