/[MITgcm]/mitgcm.org/devel/buildweb/pkg/swish-e/doc/Pod/HtmlPsPdf/Chapter.pm
ViewVC logotype

Annotation of /mitgcm.org/devel/buildweb/pkg/swish-e/doc/Pod/HtmlPsPdf/Chapter.pm

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.1 - (hide annotations) (download)
Fri Sep 20 19:47:29 2002 UTC (22 years, 10 months ago) by adcroft
Branch point for: Import, MAIN
Initial revision

1 adcroft 1.1 package Pod::HtmlPsPdf::Chapter;
2    
3     use strict;
4    
5     use Pod::HtmlPsPdf::Html ();
6     use Pod::HtmlPsPdf::Common ();
7    
8     use Pod::HtmlPsPdf::Config ();
9     my $config = Pod::HtmlPsPdf::Config->new();
10    
11    
12     ########
13     sub new{
14     my $class = shift;
15    
16     # book object
17     my $book_obj = shift;
18    
19     my ($file_name, $src_root, $src_file, $verbose, $doc_root,
20     $curr_page, $curr_page_index, $prev_page, $next_page) = @_;
21    
22     # extract the base name
23     # Note that this must match Book.pm pod_newer_split()
24     my ($base_name) = ($file_name =~ /^(.+)\.pod$/);
25    
26     # make it html ext if it was a pod
27     $file_name =~ s/\.pod$/.html/;
28    
29     my $self = bless {
30     book_obj => $book_obj,
31     base_name => $base_name,
32     file_name => $file_name,
33     src_file => $src_file,
34     src_root => $src_root,
35     verbose => $verbose,
36     curr_page => $curr_page,
37     curr_page_index => $curr_page_index,
38     prev_page => $prev_page,
39     next_page => $next_page,
40     doc_root => $doc_root,
41     content => [],
42     title => '',
43     body => '',
44     index => '',
45     change_time_stamp => '',
46     }, ref($class)||$class;
47    
48     # read the file and attributes
49     $self->get_pod_file();
50    
51     return $self;
52    
53     } # end of sub new
54    
55    
56     # you can only retrieve data from this class, you cannot modify it.
57     ##############
58     sub get_param{
59     my $self = shift;
60    
61     return () unless @_;
62     return unless defined wantarray;
63     my @values = map {defined $self->{$_} ? $self->{$_} : ''} @_;
64    
65     return wantarray ? @values : $values[0];
66    
67     } # end of sub get_param
68    
69    
70     # read the file set the content and attibutes
71     #############
72     sub get_pod_file{
73     my $self = shift;
74    
75     my $src_file = $self->{src_file};
76     Pod::HtmlPsPdf::Common::read_file($src_file,$self->{content});
77    
78     # file change timestamp
79     my ($mon,$day,$year) = (localtime ( (stat($src_file))[9] ) )[4,3,5];
80     $self->{change_time_stamp} = sprintf "%02d/%02d/%04d", ++$mon,$day,1900+$year;
81    
82     } # end of sub get_pod_file
83    
84     =item podify_items()
85    
86     podify_items(\@pars);
87    
88     Podify text to represent items in pod, e.g:
89    
90     1 Some text from item Item1
91    
92     2 Some text from item Item2
93    
94     becomes:
95    
96     =over 4
97    
98     =item 1
99    
100     Some text from item Item1
101    
102     =item 2
103    
104     Some text from item Item2
105    
106     =back
107    
108     podify_items() accepts 'C<*>' and digits as bullets
109    
110     podify_items() receives a ref to array of paragraphs as a parameter
111     and modifies it. Nothing returned.
112    
113     =cut
114    
115     #################
116     sub podify_items{
117     my $self = shift;
118    
119     # tmp result
120     my @pars = ();
121     my $items = 0;
122     foreach (@{$self->{content}}) {
123     # is it an item?
124     if (s/^(\*|\d+)\s+/=item $1\n\n/) {
125     $items++;
126     # first time insert the =over pod tag
127     push @pars, "=over 4" if $items == 1;
128     push @pars, split /\n\n/, $_;
129     } else {
130     # comlete the =over =item =back tag
131     push @pars, "=back" if $items;
132     push @pars, $_;
133     # not a tag item
134     $items = 0;
135     }
136     } # end of foreach (@$r_pars)
137    
138     # update the content
139     @{$self->{content}} = @pars;
140     } # end of sub podify_items
141    
142    
143     # convert POD => HTML
144     #############
145     sub pod2html{
146     my $self = shift;
147     my @podpath = qw(.);
148    
149     my $book_obj = $self->{book_obj};
150     my ($rh_main_toc,$rh_valid_anchors, $rh_links_to_check) =
151     $self->{book_obj}->get_param(qw(rh_main_toc rh_valid_anchors rh_links_to_check));
152    
153     # print "###: $rh_valid_anchors, $rh_links_to_check\n";
154    
155     # @content enters as pod, when returns - it's html
156     Pod::HtmlPsPdf::Html::pod2html(\@podpath,
157     $self->{src_root},
158     $self->{doc_root},
159     $self->{verbose},
160     $self->{content},
161     $rh_main_toc,
162     $self->{curr_page},
163     $self->{curr_page_index},
164     $rh_valid_anchors,
165     $rh_links_to_check
166     );
167    
168     # print "###: $rh_valid_anchors, $rh_links_to_check\n";
169    
170     } # end of sub pod2html
171    
172    
173     # splits the content into parts like title, index, body
174     #############
175     sub parse_html{
176     my $self = shift;
177    
178     my $content = join "", @{$self->{content}};
179     # extract the body
180     my ($title) = ($content =~ m|<TITLE>(.*)</TITLE>|si);
181     my ($body) = ($content =~ m|<BODY[^>]*>(.*)</BODY>|si);
182     $title ||= '';
183     $body ||= '';
184    
185     # extract index
186     my $index =
187     $body =~ s|<!-- INDEX BEGIN -->(.*)<!-- INDEX END -->||si
188     ? $1 : '';
189    
190     # remove first header
191     $body =~ s|<H1[^<]+</H1>||si;
192    
193     # add a left colour bar for <pre></pre> sections
194     $body =~
195     s{
196     <PRE>(.*?)</PRE>
197     }
198     {
199     <table>
200     <tr>
201    
202     <td bgcolor="#eeeeee" width="1">
203     &nbsp;
204     </td>
205    
206     <td>
207     <pre>$1</pre>
208     </td>
209    
210     </tr>
211     </table>
212     }gsix;
213    
214    
215    
216    
217     $self->{title} = $title || '';
218     $self->{body} = $body || '';
219     $self->{index} = $index || '';
220    
221     # for (qw(title index)) {
222     # print "\n" x 3, "$_ :\n",$self->{$_},"\n";
223     # }
224     # exit;
225    
226     } # end of sub parse_html
227    
228    
229     # writes an html file
230     ##################
231     sub write_html_file{
232     my $self = shift;
233    
234     # read the template page
235     my $template = $config->get_param('tmpl_page_html');
236     my @page_tmpl = ();
237     Pod::HtmlPsPdf::Common::read_file($template,\@page_tmpl);
238    
239     # convert
240     $self->template2release(\@page_tmpl);
241    
242     ### apply html version specific changes
243    
244     # # add the <a name="anchor##"> for each para
245     # my $anchor_count = 0;
246     # for (@page_tmpl){
247     # s|\n<P>\n|qq{\n<P><A NAME="anchor}.$anchor_count++.qq{"></A>\n}|seg
248     # }
249    
250     # add the links to #toc, before the <HR> tags. But skip the first
251     # <HR> tgas, so we will start the replace after the TOC itself.
252     my $after_toc = 0;
253     for (@page_tmpl){
254     $after_toc = 1 if !$after_toc and m|</UL>|i;
255     next unless $after_toc;
256     s|<HR>|[ <B><FONT SIZE=-1><A HREF="#toc">TOC</A></FONT></B> ]\n<HR>|sgi
257     }
258    
259     # write the file
260     my $rel_root = $config->get_param('rel_root');
261     Pod::HtmlPsPdf::Common::write_file("$rel_root/$self->{file_name}",\@page_tmpl);
262    
263     } # end of sub write_html_file
264    
265    
266    
267     # writes an html file for the later PS generation
268     ##################
269     sub write_ps_html_file{
270     my $self = shift;
271    
272     # read the template page
273     my $template = $config->get_param('tmpl_page_ps');
274     my @page_tmpl = ();
275     Pod::HtmlPsPdf::Common::read_file($template,\@page_tmpl);
276    
277     # convert
278     $self->template2release(\@page_tmpl);
279    
280     ### apply html PS version specific changes
281    
282     for (@page_tmpl){
283    
284     if ($Pod::HtmlPsPdf::RunTime::options{slides_mode}) {
285     # create the page breakers for slides
286     s|<HR>|<HR class=PAGE-BREAK>|gsi;
287     } else {
288     # remove the <HR> tags
289     s|<HR>||gsi;
290     }
291    
292     # bump up the $digit in the <h$digit></h$digit> by one to create a
293     # nice structured PS/PDF, must skip the first <h1> standing for
294     # the name of the chapter
295     s|(</?H)(\d)>|$1.($2+1).">"|egsi;
296     }
297    
298     # write the file
299     my $ps_root = $config->get_param('ps_root');
300     Pod::HtmlPsPdf::Common::write_file("$ps_root/$self->{file_name}",\@page_tmpl);
301    
302     } # end of sub write_ps_html_file
303    
304    
305     # convert the template into the release version
306     # input: ref to template array
307     ###################
308     sub template2release{
309     my $self = shift;
310     my $ra_tmpl = shift;
311    
312     my %replace_map =
313     (
314     DOC_ROOT => $self->{doc_root},
315     PREVPAGE => ($self->{prev_page}
316     ? qq{<a href="$self->{prev_page}">Prev</a>}
317     : ''
318     ),
319     NEXTPAGE => ($self->{next_page}
320     ? qq{<a href="$self->{next_page}">Next</a>}
321     : ''
322     ),
323     TITLE => $self->{title},
324     INDEX => $self->{index},
325     BODY => $self->{body},
326     MODIFIED => $self->{change_time_stamp},
327     );
328    
329     for (@{$ra_tmpl}){
330     s/\[(\w+)\]/$replace_map{$1}/g
331     }
332    
333     } # end of sub template2release
334    
335    
336    
337    
338     # writes a split html files for easier searching if the original html
339     # is too big
340     #
341     # note that this function destroyes all the parsed structures, if you
342     # intend to make a use of them later, consider using the copy instead.
343     #
344     ##################
345     sub write_split_html_files{
346     my $self = shift;
347    
348     print "+++ Making split\n" if $Pod::HtmlPsPdf::RunTime::options{verbose};
349    
350     # prepare directory
351     my $split_root = $config->get_param('split_root');
352     my $split_base_dir = "$split_root/".$self->{base_name};
353     my $dir_mode = $config->get_param('dir_mode');
354     mkdir $split_base_dir, $dir_mode unless -d $split_base_dir;
355    
356     # read the template page
357     my $template = $config->get_param('tmpl_page_split_html');
358     my @page_tmpl = ();
359     Pod::HtmlPsPdf::Common::read_file($template,\@page_tmpl);
360    
361     ### parse html ###
362    
363     # 1. parse index
364     # 2. parse body
365    
366     ### parse index ###
367    
368     #########################################
369     # the datastructure we are going to build
370     #
371     # $node->[$idx_link]->$
372     # $node->[$idx_level]->$
373     # $node->[$idx_parent]->$
374     # $node->[$idx_kids]->[]
375     #########################################
376    
377     my $root_anchor = 'index.html';
378     my @parents = ($root_anchor);
379     my @keys = qw(link level parent kids);
380     my %keys = ();
381     @keys{@keys} = 0..$#keys;
382     my %index = ();
383     my $level = 0;
384    
385     # initialize the root entry
386     $index{$root_anchor}->[$keys{link}]
387     = qq{<LI><A HREF="index.html"><b>}.$self->{title}.qq{</b></A>};
388     $index{$root_anchor}->[$keys{level}] = $level;
389     $index{$root_anchor}->[$keys{parent}] = '';
390     $index{$root_anchor}->[$keys{kids}] = [];
391    
392     while ( $self->{index} =~ /(.*\n)/g ){
393     local $_ = $1 || '';
394     # assumption: there can be one tag/item per line!
395     chomp;
396    
397     # start of level
398     if (m|<ul>|i){
399     $level++;
400     next;
401     }
402    
403     # end of level
404     if (m|</ul>|i){
405     $level--;
406     pop @parents;
407     next;
408     }
409    
410     next unless m|<li>|i;
411    
412     s/A HREF="#(\w+)"/A HREF="$1.html"/i;
413     my $anchor = $1 || '';
414     warn("!!! No anchor found"), next unless $anchor;
415     # make it html
416     $anchor .= '.html';
417    
418     $index{$anchor}->[$keys{link}] = $_;
419     $index{$anchor}->[$keys{level}] = $level;
420    
421     my $parent_anchor = $parents[$level-1];
422     $index{$anchor}->[$keys{parent}] = $parent_anchor;
423     splice @parents,$level,1,$anchor;
424    
425     # now update parent's kids field by pushing yourself to the end
426     push @{ $index{$parent_anchor}->[$keys{kids}] }, $anchor;
427    
428     # init your kids
429     $index{$anchor}->[$keys{kids}] = [];
430    
431     } # end of while ( $self->{index} =~ /(.*\n)/g )
432    
433     ### parse body ###
434    
435     # create the split version:
436     my %sections = ();
437     my $prev_anchor = '';
438     my %item = ();
439    
440     while ( $self->{body} =~ /(.*\n)/g ){
441     my $line = $1;
442    
443     if ( $line =~ m|<H(\d)><A NAME="([^\"]+)">([^>]+)</A></H|){
444    
445     my $anchor = $2;
446    
447     # was a previous item already?
448     if (%item) {
449    
450     # curr anchor is the 'next' for the 'prev' item
451     $item{next} = $anchor;
452    
453     # store it away
454     %{$sections{$item{anchor}}} = %item;
455    
456     # set the previous anchor
457     $prev_anchor = $item{anchor};
458    
459     # reset the prev item
460     %item = ();
461     }
462    
463     # start a new item
464     $item{level} = $1;
465     $item{anchor} = $anchor;
466     $item{title} = $3;
467     $item{prev} = $prev_anchor;
468    
469     # # find out who are your parents
470     # splice @parents, $item{level}-1;
471     # # remember who are your parents
472     # @{$item{parents}} = @parents;
473     # # add yourself as a father
474     # push @parents,$item{anchor} ;
475    
476     } else {
477    
478     # %item wasn't started yet
479     next unless %item;
480    
481     $item{content} .= "$line";
482     } # end of if ( $line =~ m|<H(\d)><A NAME....
483    
484     } # end of while ( $self->{body} =~ /(.*)/g ){
485    
486    
487     # last item add (cannot be added in while loop)
488     if (%item) {
489    
490     # curr anchor is the 'next' for the 'prev' item
491     $item{next} = '';
492    
493     # store it away
494     %{$sections{$item{anchor}}} = %item;
495    
496     # reset the prev item
497     %item = ();
498    
499     } # end of if (%item)
500    
501    
502     ### generate split html pages ###
503    
504     my $pod_title = $self->{title};
505     for my $sec (keys %sections) {
506    
507     my $anchor = "$sec.html";
508    
509     ### prepare the top index with parents dynasty only ###
510     my $top_index = '';
511     my $parent_anchor = $anchor;
512     my @parents = ();
513     while ($parent_anchor = $index{$parent_anchor}->[$keys{parent}]) {
514     unshift @parents, $parent_anchor;
515     }
516     my @close_top_index = ();
517    
518     # top level
519     {
520     local $_ = $anchor;
521     $top_index .= "<UL>\n";
522     $top_index .= qq{<LI><a href="../index.html">Split Version TOC</a>\n};
523     unshift @close_top_index,"</UL>";
524     }
525    
526     for (@parents,$anchor) {
527     my $level = $index{$_}->[$keys{level}] + 1;
528     $level *= 4;
529     $top_index .= ' ' x $level . "<UL>\n";
530     if ($_ eq $anchor) {
531     my $title = $sections{$sec}->{title};
532     $top_index .= qq{<h1><font color="brown">$title</font></h1>\n};
533     } else {
534     $top_index .= $index{$_}->[$keys{link}] . "\n";
535     }
536     unshift @close_top_index,' ' x $level ."</UL>";
537     }
538    
539    
540     $top_index .= join "\n",@close_top_index,"\n";
541    
542     ### generate sub-index for this section ###
543     my $level = $index{$anchor}->[$keys{level}];
544     my @close_bot_index = ();
545     my $bot_index = "\n";
546     for (0..$level) {
547     $bot_index .= " " x $level . "<UL>\n";
548     }
549     $bot_index .= nested_kids(\%index,$anchor,$keys{kids},$keys{link});
550     for (0..$level) {
551     $bot_index .= " " x $level . "</UL>\n";
552     }
553    
554     # recursive function
555     ################
556     sub nested_kids{
557     my $r_index = shift;
558     my $anchor = shift;
559     my $kids_key = shift;
560     my $link_key = shift;
561    
562     my @kids = @{$r_index->{$anchor}->[$kids_key]};
563     return '' unless @kids;
564    
565     my $subidx .= "<UL>\n";
566     for my $kid_anchor (@kids){
567     $subidx .= $r_index->{$kid_anchor}->[$link_key] . "\n";
568     $subidx .= nested_kids($r_index,$kid_anchor,$kids_key,$link_key);
569     }
570     $subidx .= "</UL>\n";
571     return $subidx;
572     } # end of sub nested_kids
573    
574    
575     # set values for template conversion.
576     # these destroy the original values
577     $self->{full_title} = $top_index;
578     $self->{title} = $sections{$sec}->{title};
579     $self->{body} = $sections{$sec}->{content};
580    
581     # fix internal links to work with subdirs created by the split version
582     $self->{body} =~ s|A HREF="(?:[\./]*)?([^.]+)\.html#?"|A HREF="../$1/index.html"|g;
583     $self->{body} =~ s|A HREF="(?:[\./]*)?([^.]+)\.html#(.+?)"|A HREF="../$1/$2.html"|g;
584    
585     # append the submenu
586     $self->{body} .= $bot_index;
587    
588     # convert
589     my @tmpl_copy = @page_tmpl;
590     $self->split_template2release(\@tmpl_copy);
591    
592     # write the section as a file
593     my $filename = "$split_base_dir/".$sections{$sec}->{anchor}.".html";
594     Pod::HtmlPsPdf::Common::write_file($filename,\@tmpl_copy);
595    
596     } # end of for (keys %sections)
597    
598     ### now write the index.html for original file ###
599     # correct the links
600     $self->{index} =~ s/A HREF="#([^\"]*)"/A HREF="$1.html"/g;
601     $self->{body} = $self->{index}."\n<hr>";
602     $self->{full_title} = qq{<h1><font color="brown">$pod_title</font></h1>\n};
603     $self->{title} = $pod_title;
604    
605     my @tmpl_copy = @page_tmpl;
606     $self->split_template2release(\@tmpl_copy);
607    
608     # write the file
609     my $filename = "$split_base_dir/index.html";
610     Pod::HtmlPsPdf::Common::write_file($filename,\@tmpl_copy);
611    
612    
613     } # end of sub write_split_html_files
614    
615     # convert the template into the release version
616     # input: ref to template array
617     ###################
618     use File::Basename;
619    
620     sub split_template2release{
621     my $self = shift;
622     my $ra_tmpl = shift;
623    
624     my $full_file_name = $self->{curr_page};
625     #$full_file_name =~ s|^.*?(\w+)\.\w+$|$1|;
626     # Just want the basename, correct? Is it always .pod?
627     $full_file_name = $1 if $full_file_name =~ m!([^/]+)\.\w+$!;
628    
629     my %replace_map =
630     (
631     PAGE => $full_file_name,
632     DOC_ROOT => $self->{doc_root},
633     PREVPAGE => ($self->{prev_page}
634     ? qq{<a href="$self->{prev_page}">Prev</a>}
635     : ''
636     ),
637     NEXTPAGE => ($self->{next_page}
638     ? qq{<a href="$self->{next_page}">Next</a>}
639     : ''
640     ),
641     FULLTITLE=> $self->{full_title},
642     TITLE => $self->{title},
643     # INDEX => $self->{index},
644     BODY => $self->{body},
645     MODIFIED => $self->{change_time_stamp},
646     );
647    
648     for (@{$ra_tmpl}){
649     s/\[(\w+)\]/$replace_map{$1}/g
650     }
651    
652     } # end of sub split_template2release
653    
654    
655    
656    
657    
658    
659     1;
660     __END__

  ViewVC Help
Powered by ViewVC 1.1.22