source: rtems/doc/tools/texi2www/texi2www @ 3ab325e

4.104.114.84.95
Last change on this file since 3ab325e was 3ab325e, checked in by Joel Sherrill <joel.sherrill@…>, on 04/03/98 at 15:41:30

Added -header and -dirfile options.

  • Property mode set to 100755
File size: 31.5 KB
Line 
1#!/usr/bin/perl
2# (Works with both perl 4 and perl 5)
3#
4#  $Id$
5#
6
7$version = 'Jan 2 1996';
8$copyright = <<EOT;
9texi2www - converts texinfo to HTML
10Copyright (C) 1994, 1995, 1996 Tim Singletary
11
12This program is freely distributable under the terms of the GNU
13GENERAL PUBLIC LICENSE.  In particular, modified versions of this
14program must retain this copyright notice and must remain freely
15distributable.
16
17EOT
18$usage = <<EOT;
19Usage: texi2www [option ...] texinfo_file
20where options are:
21  -dir directory    -- Specify output directory.  Default is `.'.
22  -header path      -- Specifies the path to a file containing HTML;
23                       this files gets inserted near the top of each
24                       generated HTML file.
25  -footer path      -- Specifies the path to a file containing HTML;
26                       this files gets inserted near the bottom of each
27                       generated HTML file.
28  -icons path       -- Specifies the path, relative to the output directory,
29                       to the arrow files.  Default is `..'.
30  -dirfile path     -- Specifies a replacement for ../dir.html
31  -verbose          -- Verbose output.
32
33The complete user\'s is available at
34http://sunland.gsfc.nasa.gov/info/texi2www/Top.html
35EOT
36
37########################################################################
38
39$icons = ".."; $dir = "."; $dirfile = "../dir.html";
40while ($ARGV[0] =~ /^-/) {
41    $_ = shift;
42    if (/-dirfile/) {$dirfile = shift; next;}
43    if (/-dir/) {$_ = shift; s!/$!!; s!$!/!; $dir = $_; next;}
44    if (/-verbose/) {$verbose = 1; next;}
45    if (/-footer/) {$footer = shift; next;}
46    if (/-header/) {$header = shift; next;}
47    if (/-icons/) {$_ = shift; s!\/$!!; $icons = $_; next;}
48    die $usage;
49}
50
51&initialize_tables();
52
53#
54# Read the texinfo input into @texinfo
55#
56&open_input_file($ARGV[0]);
57&read_input(1,'/^\@bye/',"$texinfo_file[0] line 1");
58$texinfo[$ntexinfo] = "\@bye\n";
59$origin[$ntexinfo] = "$texinfo_file[0] line $.";
60
61#
62# Parse @texinfo
63#
64$texinfo_index = 0;
65while ($texinfo_index < @texinfo) {
66    &get_more_stuff_to_parse();
67    if (/^\@bye/) {
68        &terminate_node();
69        print "Normal completion\n";
70        exit;
71    }
72    &parse();
73}
74
75print "Huh? didn't parse the \@bye directive!\n";
76
77########################################################################
78sub canonical # (node_name)
79{
80    local ($n) = @_;
81
82    $n =~ s/^\s+//; $n =~ s/\s+$//; # strip whitespace
83
84    return "$dirfile" if ($n =~ /\(dir\)/i); # handle (dir)
85   
86    if ($n =~ /^\(([^\)]+)\)(.*)/) {
87        $p = $1; $p =~ s/^\s+//; $p =~ s/\s+$//; $p .= "/";
88        $n = $2; $n =~ s/^\s+//; $n =~ s/\s+$//;
89    } else {
90        $p = "";
91    }
92
93
94    $n =~ s/\$/\$\$/;           # `$' -> `$$'
95    $n =~ s/_/\$_/g;            # `_' -> `$_'
96    $n =~ s/\s+/_/g;            # whitespace -> `_'
97
98                                # anything else that's funky get
99                                # translated to `$xx' where `xx'
100                                # are hex digits.
101    while ($n =~ /(.*)([^-a-zA-Z0-9\$_.])(.*)/) {
102        $n = $1 . sprintf("\$%02x",ord($2)) . $3;
103    }
104
105    return "$p$n.html" if ($n);
106    return "";
107} # canonical
108
109########################################################################
110sub deduce_node_links
111#
112# On entry, $_ is a node line and $start_index is the index (in @texinfo)
113# the node line.
114#
115# &deduce_node_links() sets $next, $prev, and $up.
116{
117    local ($level,$i,$node,$j);
118
119    # First, search down from this node to the next sectioning command.
120    $level = &determine_node_level($start_index+1);
121
122    # Next, look for the `next' node (i.e., the next node at the
123    # same or a higher level).
124    undef($next);
125    for ($i=$start_index+1; $i < $ntexinfo; ++$i) {
126        $_ = $texinfo[$i];
127        next unless /^\@node +([^,]+).*\n/;
128        $j = &determine_node_level($i+1);
129        if ($j <= $level) {
130            if ($j == $level) {$next = $1;}
131            last;
132        }
133    }
134
135    # Look for the `prev' and `up' nodes
136    undef($prev);
137    undef($up);
138    for ($i=$start_index-1; $i > 1; --$i) {
139        $_ = $texinfo[$i];
140        next unless /^\@node\s+([^,]+).*\n/;
141        $j = &determine_node_level($i+1);
142        if ($j == $level) {
143            unless ($prev) {$prev = $1;}
144        } elsif ($j < $level) {
145            $up = $1;
146            last;
147        }
148    }
149    unless (defined($up)) {$up = "(dir)";}
150
151    $xthis = $this;
152    $xthis =~ s/\n//;
153
154} # deduce_node_links
155
156########################################################################
157sub determine_node_level
158{
159    local ($i) = @_;
160    local ($level);
161
162    $level = 0;
163    while ($i < $ntexinfo) {
164        $_ = $texinfo[$i];
165        ++$i;
166        next if /^\s+$/;
167        last if (/\@node/);
168        last unless (/\@(\w+)/);
169        if ($directive_section{$1}) {
170            $level = $directive_section{$1};
171            last;
172        }
173    }
174
175    return $level;
176} # determine_node_level
177
178
179########################################################################
180sub expand_xref
181{
182    local ($cmd,$arg) = @_;
183    local ($node,$xrefname,$topic,$infofile,$manual,$url,$x);
184
185    if ($cmd eq 'inforef') {
186        ($node,$xrefname,$infofile) = split(/,/,$arg);
187        $topic = $manual = '';
188    } elsif ($cmd eq 'href') {
189        ($xrefname,$node,$infofile,$url) = split(/,/,$arg);
190    } else {
191        ($node,$xrefname,$topic,$infofile,$manual) = split(/,/,$arg);
192    }
193    $xrefname =~ s/^\s+//; $infofile =~ s/^\s+//;
194    $xrefname =~ s/\s+$//; $infofile =~ s/\s+$//;
195    $xrefname =~ s/\s+/ /; $infofile =~ s/\s+/ /;
196    $infofile =~ s/\.texi$//;
197    $infofile =~ s/\.texinfo$//;
198
199    if ($xrefname =~ /^$/) {$xrefname = $node;}
200
201    $node = &canonical($node);
202    unless ($url) {
203        unless ($infofile =~ /^$/) {$url = "../$infofile/";}
204        $url = $url . $node;
205    }
206    $x = "<A HREF=\"$url\">$xrefname</A>";
207} # expand_xref
208
209########################################################################
210sub get_more_stuff_to_parse
211{
212    $start_index = $texinfo_index;
213
214    $_ = '';
215    do {
216        if ($texinfo_index >= @texinfo) {
217            print "Unclosed \@x{y} in chunk beginning at "
218                . "$origin[$start_index]\n";
219            return;
220        }
221        s/\n$/ /;
222        $more = $texinfo[$texinfo_index++];
223        $more =~ s/\@\*/<BR>\n/g;
224        $more =~ s/\@\./\./g;
225        $more =~ s/\@\://g;
226        $more =~ s/\@refill//g;
227
228        $_ .= $more;
229
230        # Expand all @a{b} in line
231        while (/\@(\w+)\{([^{}]*)\}/) {
232            $atcmd = $1;
233            $atarg = $2;
234
235            if ($z = $atxy_2_zyz{$atcmd}) {
236                if ($z =~ /(.+),(.+),(.+)/) {
237                    $left = $1; $z = $2; $right = $3;
238                } else {
239                    $left = ''; $right = '';
240                }
241                if ($z =~ s/^\^//) {$atarg =~ tr/a-z/A-Z/;}
242                $x = "$left<$z>$atarg</$z>$right";
243            } elsif ($atxy_2_y{$atcmd}) {
244                $x = $atarg;
245            } elsif ($z = $atxy_2_z{$atcmd}) {
246                $x = $z;
247            } elsif ($z = $atxy_2_ref{$atcmd}) {
248                $x = $z . &expand_xref($atcmd,$atarg);
249                $x =~ s/^X//; # works because $z must start with 'X'!
250            } elsif ($atcmd eq 'value') {
251                $x = $texinfo_variable{$atarg};
252            } elsif ($atcmd eq 'today') {
253                $x = &today();
254            } elsif ($atcmd eq 'footnote') {
255                $footnote[$nfootnotes++] = $atarg;
256                $x = "\[$nfootnotes\]";
257            } elsif ($atcmd eq 'gif') {
258                $atarg =~ s/,.*//;
259                &copy_to_destdir($atarg);
260                $atarg =~ s|.*/||;
261                $x = "<IMG SRC=\"$atarg\">";
262            } else {
263                print "**WARNING** Don't know how to expand "
264                    . "\@$atcmd\{$atarg\}\n";
265                $debug = 1;
266                $x = "?$atcmd\?$atarg\?";
267            }
268           
269            print "$origin[$start_index]: \@$atcmd\{$atarg\} => $x\n"
270                                                   if $debug{expansions};
271
272            s/\@\w+\{[^{}]*\}/$x/;         
273        }
274    } while (/\@\w+\{[^}]*$/);
275    print "$origin[$start_index]: $_" if $debug{chunks};
276} # get_more_stuff_to_parse
277
278########################################################################
279sub parse
280# On entry:
281#    $_ -- the line(s) to parse.
282#    $start_index -- where, in $texinfo, $_ begins.
283{
284    local ($x);
285
286    if (/^\@(\w+)/) {
287        if ($x=$directive_block{$1}) { # @example, @quotation, etc.
288            &parse_block($1,$x);
289        } elsif ($directive_section{$1}) { # @chapter, @subsection, etc.
290            &process_section();
291        } elsif ($1 eq 'bye') {
292            if ($nfootnotes > 0) {
293                &printHTML("<P><HR>\n");
294                for ($n=0; $n < $nfootnotes; ++$n) {
295                    &printHTML("<P>\[" . ($n+1) . "\] $footnote[$n]</P>\n");
296                }
297            }
298            &print_footer if $footer;
299            &printHTML("</BODY></HTML>\n");
300            close (HTML);
301            return;
302        } elsif ($1 eq 'center') {
303            /^\@center\s+(.*)/;
304            &printHTML("$paragraph_end") if $in_paragraph;
305            &printHTML("<P ALIGN=CENTER>$1</P>\n");
306            $in_paragraph = 0;
307        } elsif ($1 eq 'clear') {
308            /^\@clear\s+(\S+)/;
309            undef($texinfo_variable{$1});
310        } elsif ($1 =~ /^def(code)?index/) {
311            /^\@(def|defcode)index\s+(\w+)/;
312            $index_name{$2} = $2 . "index";
313            $index_style{$2} = 'CODE' if ($1 eq "defcode");
314        } elsif ($1 =~ /^(def.*)/) { # @defn, @defun, ... @deftp
315            &parse_def($1);
316        } elsif ($1 eq 'enumerate') {
317            &parse_enumerate();
318        } elsif ($1 eq 'exdent') {
319            /^\@exdent\s+(.*)/;
320            &printHTML("$paragraph_end") if $in_paragraph;
321            # A bug -- doesn't exdent the line!
322            &printHTML("<P>$1</P>\n");
323            $in_paragraph = 0;
324        } elsif ($1 eq 'flushleft' || $1 eq 'flushright') {
325            &parse_flush();
326        } elsif ($1 eq 'html') {
327            while ($texinfo_index < @texinfo) {
328                &get_more_stuff_to_parse();
329                last if (/^\@end\s+html/);
330                s/\&quot;/\"/g; s/\&gt;/\>/g; s/\&lt;/\</g; s/\&amp;/\&/g;
331                &printHTML("$_");
332            }
333        } elsif ($1 eq 'itemize') {
334            &parse_itemize();
335        } elsif ($1 eq 'menu') {
336            &parse_menu();
337        } elsif ($1 eq 'node') {
338            &process_node();
339        } elsif ($1 eq 'printindex') {
340            /^\@printindex\s+([a-z]+)/;
341            &print_index($1);
342        } elsif ($1 eq 'settitle') {
343            /^\@settitle\s+(.*)/;
344            unless ($title) {$title = $1;}
345        } elsif ($1 eq 'set') {
346            if (/^\@set\s+(\S+)\s+(.+)$/) {
347                $texinfo_variable{$1} = $2;
348            } else {
349                /^\@set\s+(\S+)/;
350                $texinfo_variable{$1} = 1;
351            }
352        } elsif ($1 eq 'syncodeindex') {
353            &process_synindex(1);
354        } elsif ($1 eq 'synindex') {
355            &process_synindex(0);
356        } elsif ($1 =~ /^.?table/) { # @table, @vtable, @ftable
357            unless (/^\@(.?table)\s*\@(\w*)/
358                           && ($2 eq 'asis' || ($tbltype=$atxy_2_zyz{$2}))) {
359                print "**WARNING** $origin[$start_index]: assuming "
360                    . "\@table \@asis\n";
361                $tbltype = '';
362            }
363            &parse_table($1,$tbltype);
364        } elsif ($1 =~ /..?index/) { # @cindex, @findex, .. @auindex, etc.
365            &process_index();
366        } else {
367            print "**WARNING** $origin[$start_index]: ignoring $_";
368        }
369    } else {
370        if (/^\s*$/) {
371            if ($in_paragraph) {
372                &printHTML("$paragraph_end");
373            } elsif ($in_preformatted) {
374                &printHTML("\n");
375            }
376            $in_paragraph = 0;
377        } else {
378            unless ($in_preformatted) {
379                unless ($in_paragraph) {
380                    &printHTML("<P>\n");
381                    $in_paragraph = 1;
382                    $paragraph_end = "</P>\n";
383                }
384            }
385            &printHTML("$_");
386        }
387    }
388} # parse
389
390########################################################################
391sub parse_block
392#
393# Handles @example, @display, etc.
394#
395#    > @example            > <PRE>
396#    > a + b = c     ==>   > a + b = c
397#    > @end example        > </PRE>
398{
399    local ($block,$pre) = @_;
400    local ($started_at);
401
402    $started_at = $start_index;
403
404    &printHTML("$paragraph_end") if $in_paragraph;
405    $in_paragraph = 0;
406
407    if ($pre eq '>PRE') {
408        &printHTML("<DL><DT><DD>\n<PRE>\n");
409    } else {
410        &printHTML("<$pre>\n") unless ($pre eq '-');
411    }
412    $in_preformatted = $block;
413    while ($texinfo_index < @texinfo) {
414        &get_more_stuff_to_parse();
415        if (/^\@end\s+$block/) {
416            if ($pre eq 'HR') {
417                &printHTML("</HR>\n");
418            } elsif ($pre eq '>PRE') {
419                &printHTML("</PRE>\n</DL>\n");
420            } else {
421                &printHTML("</$pre>\n") unless ($pre eq '-');
422            }
423            $in_preformatted = 0;
424            return;
425        }
426        &parse();
427    }
428    print "**ERROR** reached EOF while searching for end of the \@$block "
429        . "block that started on $origin[$started_at]\n";
430} # parse_block
431
432########################################################################
433sub parse_def
434# $_ contains a @def* command
435{
436    local ($def) = @_;
437    local ($started_at,$in_dd);
438
439    $started_at = $start_index;
440       
441    &printHTML("$paragraph_end") if $in_paragraph;
442    $in_paragraph = 0;
443   
444    &printHTML("<DL>\n");
445
446    &printdef();
447
448    while ($texinfo_index < @texinfo) {
449        &get_more_stuff_to_parse();
450        if (/^\@end\s+$def/) {
451            &printHTML("</DL>\n");
452            $in_paragraph = 0;
453            return;
454        }
455        if (s/^(\@def\w+)x\s/$1 /) {&printdef();}
456        else {
457            unless ($in_dd) {
458                &printHTML("<DD>\n");
459                ++$in_dd;
460                $in_paragraph = 1;
461                $paragraph_end = "\n";
462            }
463            &parse();
464        }
465    }
466    print "**ERROR** reached EOF while searching for end of the $def "
467        . "definition that started on $origin[$started_at]\n";
468
469} # parse_def
470sub printdef
471{
472
473    s/\@defun(x?)\s/\@deffn Function /
474        || s/\@defmac(x?)\s/\@deffn Macro /
475        || s/\@defspec(x?)\s/\@deffn \{Special Form\} /
476        || s/\@defvar(x?)\s/\@defvr Variable /
477        || s/\@defopt(x?)\s/\@defvr \{User Option\} /
478        || s/\@deftypefun(x?)\s/\@deftypefn Function /
479        || s/\@deftypevar(x?)\s/\@deftypefn Variable /
480        || s/\@defivar(x?)\s/\@defcv \{Instance Variable\} /
481        || s/\@defmethod(x?)\s/\@defop Method /;
482    s/(\@\w+)x\s/$1 /;
483
484    @words = split;
485
486    $i = 1;
487    $category = $words[$i++];
488    while ($i < @words && $category =~ /^\{[^}]*$/) {
489        $category .= ' ' . $words[$i++];
490    }
491    if ($i>=@words) {
492        print "def error at $origin{$started_at}\n";
493    }
494    $category =~ s/^\{//;
495    $category =~ s/\}$//;
496
497    &printHTML("<DT>$category: ");
498
499    if ($words[0] eq '@deftypefn' || $words[0] eq '@deftypevr'
500        || $words[0] eq '@defcv' || $words[0] eq '@defop') {
501        if ($words[$i] =~ s/^\{//) {
502            &printHTML("<VAR>");
503            until ($words[$i] =~ s/\}$//) {&printHTML("$words[$i++]");}
504            &printHTML("$words[$i++]</VAR> ");
505        } else {
506            &printHTML("<VAR>$words[$i++]</VAR> ");
507        }
508        $words[0] =~ /.*([a-z][a-z])/;
509        $_ = "\@" . $1 . "index " . $words[$i];
510        &process_index;
511    }
512    &printHTML("<STRONG>$words[$i++]</STRONG>\n<VAR>");
513
514    while ($i < @words) {&printHTML(" $words[$i++]");}
515    &printHTML("</VAR>\n");
516
517} # printdef
518
519########################################################################
520sub parse_enumerate
521# $_ is `@enumerate'.  Note that @enumerate with an arg (`@enumerate 3',
522# for example) is kinda funky due to HTML limitations.
523{
524    local ($count,$started_at);
525   
526    $started_at = $start_index;
527
528    &printHTML("$paragraph_end") if $in_paragraph;
529    $in_paragraph = 0;
530
531    if (/^\@enumerate\s*(\S+)/) {$count = $1;}
532
533    &printHTML("<" . ($count ? "UL" : "OL") . ">\n");
534
535    while ($texinfo_index < @texinfo) {
536        &get_more_stuff_to_parse();
537        if (/^\@end\s+enumerate/) {
538            &printHTML("</" . ($count ? "UL" : "OL") . ">\n");
539            return;
540        }
541        if (/^\@item\s+(.*)/ || /^\@item()$/) {
542            if ($count) {
543                &printHTML("<LI>$count: $1\n");
544                ++$count;
545            } else {
546                &printHTML("<LI>$1\n");
547            }
548            $in_paragraph = 1;
549            $paragraph_end = "\n";
550        } else {
551            &parse();
552        }
553    }
554    print "**ERROR** reached EOF while searching for end of the \@enumerate "
555        . "that started on $origin[$started_at]\n";
556} # parse_enumerate
557
558########################################################################
559sub parse_flush
560{
561    local ($started_at,$flush);
562
563    /^\@(\w+)\s/;
564    $flush = $1;
565    $started_at = $start_index;
566
567    &printHTML("$paragraph_end") if $in_paragraph;
568    $in_paragraph = 0;
569
570    while ($texinfo_index < @texinfo) {
571        &get_more_stuff_to_parse();
572        if (/^\@end\s+$flush/) {
573            return;
574        }
575        &parse();
576    }
577    print "**ERROR** reached EOF while searching for end of the $flush "
578        . "that started on $origin[$started_at]\n";
579
580
581} # parse_flush
582
583########################################################################
584sub parse_itemize
585# $_ is `@itemize'.  Due to HTML limitation, `@itemize @bullet' comes
586# out the same as `@itemize @minus'.
587{
588    local ($started_at);
589
590    $started_at = $start_index;
591
592    &printHTML("$paragraph_end") if $in_paragraph;
593    $in_paragraph = 0;
594
595    &printHTML("<UL>\n");
596   
597
598    while ($texinfo_index < @texinfo) {
599        &get_more_stuff_to_parse();
600        if (/^\@end\s+itemize/) {
601            &printHTML("</UL>\n");
602            return;
603        }
604        if (/^\@item\s+(.*)/ || /^\@item()$/) {
605            &printHTML("<LI>$1\n");
606            $in_paragraph = 1;
607            $paragraph_end = "\n";
608        } else {
609            &parse();
610        }
611    }
612    print "**ERROR** reached EOF while searching for end of the itemize "
613        . "that started on $origin[$started_at]\n";
614} # parse_itemize
615
616########################################################################
617sub parse_menu
618{
619    local ($started_at);
620
621    $started_at = $start_index;
622
623    &printHTML("$paragraph_end") if $in_paragraph;
624    $in_paragraph = 0;
625
626    &printHTML("<MENU>\n");
627
628    while ($texinfo_index < @texinfo) {
629        &get_more_stuff_to_parse();
630        if (/^\@end\s+menu/) {
631            &printHTML("</MENU>\n");
632            return;
633        }
634
635        # Like ` * menu-item:: description of item'
636        if (/^\s*\*\s*([^:]*)\s*::\s*(.*)$/) {
637            &printHTML("$paragraph_end") if $in_paragraph;
638            $in_paragraph = 0;
639            $node = &canonical($1);     
640            &printHTML("<LI><A HREF=\"$node\">$1</A>\n");
641            &printHTML("$2\n") if $2;
642        # Like ` * menu-item: cross-reference. description of item'
643        } elsif (/^\s*\*\s*([^:]*)\s*:([^.]*)\.\s*(.*)$/) {
644            &printHTML("$paragraph_end") if $in_paragraph;
645            $in_paragraph = 0;
646            $node = &canonical($2);
647            &printHTML("<LI><A HREF=\"$node\">$1</A>\n");
648            &printHTML("$3\n");
649        } elsif (/^\@/) {
650            print "**WARNING** Don\'t know how to process \`$_\' inside "
651                . "a menu!\n";
652        } else {
653            if (/^\s*$/ && !$in_paragraph) {
654                &printHTML("<P>");
655                $in_paragraph = "1";
656                $paragraph_end = "</P>\n";
657            }
658            &printHTML("$_");
659        }
660    }
661    print "**ERROR** reached EOF while searching for end of the menu "
662        . "that started on $origin[$started_at]\n";
663} # parse_menu
664
665########################################################################
666sub parse_table
667# $_ is `@itemize'.  Due to HTML limitation, `@itemize @bullet' comes
668# out the same as `@itemize @minus'.
669{
670    local ($table,$ttype,$after_DT,$started_at,$first_para);
671    ($table,$ttype) = @_;
672
673    $started_at = $start_index;
674
675    &printHTML("$paragraph_end") if $in_paragraph;
676    $in_paragraph = 0;
677
678    &printHTML("<DL>\n");
679
680    while ($texinfo_index < @texinfo) {
681        &get_more_stuff_to_parse();   
682        if (/^\@end\s+$table/) {
683            &printHTML("</DL>\n");
684            return;
685        }
686        if (/^\@item(x?)\s+(.*)/ || /^\@item(x?)()$/) {
687            $atarg = $2;
688            if ($ttype) {
689                if ($ttype =~ /(.+),(.+),(.+)/) {
690                    $left = $1; $z = $2; $right = $3;
691                } else {
692                    $left = ''; $z = $ttype; $right = '';
693                }
694                if ($z =~ s/^\^//) {$atarg =~ tr/a-z/A-Z/;}
695                &printHTML("<DT>$left<$z>$atarg</$z>$right\n");
696            } else {
697                &printHTML("<DT>$2\n");
698            }
699            $item = $2;
700            if ($item && $table =~ /([fv])table/) {
701                $_ = "\@" . $1 . "index " . $item;
702                &process_index;
703            }
704            $after_DT = 1;
705        } else {
706            if ($after_DT) {
707                &printHTML("<DD>\n");
708                $in_paragraph = 1;
709                $paragraph_end = "\n";
710                $after_DT = 0;
711                $first_para = 1;
712            }
713            unless ($first_para && /^\s*$/) {
714                $first_para = 0;
715                &parse();
716            }
717        }
718    }
719    print "**ERROR** reached EOF while searching for end of the table "
720        . "that started on $origin[$started_at]\n";
721} # parse_table
722
723########################################################################
724sub print_index
725{
726    local ($index) = @_;
727    $index = $index_name{$index};
728
729    eval "\@keys = keys \%$index";
730
731    &printHTML("<MENU>\n");
732    foreach $item (sort texinfo_sort @keys) {
733        eval "\$val = \$$index\{\$item\}";
734        &printHTML("<LI>$val\n");
735    }
736    &printHTML("</MENU>\n");
737} # print_index
738
739sub texinfo_sort
740{
741    $x = $a; $x =~ s/<[^>]*>//g; $x =~ tr/A-Z/a-z/;
742    $y = $b; $y =~ s/<[^>]*>//g; $y =~ tr/A-Z/a-z/;
743    $x cmp $y;
744} # texinfo_sort
745
746########################################################################
747sub process_index
748#
749# For example, `@cindex whatever' generates an entry in %cpindex
750#
751{
752    s/\@cindex/\@cpindex/ || s/\@findex/\@fnindex/
753        || s/\@vindex/\@vrindex/ || s/\@kindex/\@kyindex/
754        || s/\@pindex/\@pgindex/ || s/\@tindex/\@tpindex/;
755
756    /\@(..)index\s+(.*)/;
757
758    if ($x=$index_style{$1}) {
759        $entry = "<A HREF=\"$cthis\"><$x>$2</$x></A>";
760    } else {
761        $entry = "<A HREF=\"$cthis\">$2</A>";
762    }
763
764    print "*** \$$index_name{$1}\{$2\} = $entry\n" if $debug{'index'};
765    eval "\$$index_name{$1}\{\$2\} = \$entry";
766} # process_index
767
768########################################################################
769sub process_node
770# On entry, $_ is an @node line.
771{
772    s/^\@node\s+//;
773    ($this,$next,$prev,$up) = split(/,/);
774
775    &deduce_node_links() unless ($next || $prev || $up);
776
777    $cthis = &canonical($this);
778    $cnext = &canonical($next);
779    $cprev = &canonical($prev);
780    $cup = &canonical($up);
781
782    &terminate_node();
783
784    print "... opening $dir$cthis ...\n" if $debug{nodes};
785    open(HTML,">$dir/$cthis") || die "Couldn't open $dir$cthis -- $!\n";
786   
787    $nfootnotes = 0;
788
789    &printHTML("<HTML>\n");
790    &printHTML("<!-- created $today from " .
791               $origin[$start_index] . " via texi2www -->\n");
792    &print_header if $header;
793    &printHTML("<HEAD>\n<TITLE>$this</TITLE>\n");
794    &printHTML("<LINK REL=\"Precedes\" HREF=\"$cnext\">\n") if $next;
795    &printHTML("<LINK REV=\"Precedes\" HREF=\"$cprev\">\n") if $prev;
796    &printHTML("<LINK REV=\"Subdocument\" HREF=\"$cup\">\n") if $up;
797    &printHTML("</HEAD><BODY><P>\n");
798    if ($cprev) {
799        &printHTML("<A HREF=\"$cprev\"><IMG ALIGN=MIDDLE "
800                   . "SRC=\"$icons/prev-arrow.gif\" ALT=\"PREV\"></A>\n");
801    } else {
802        &printHTML("<A><IMG ALIGN=MIDDLE "
803                   . "SRC=\"$icons/missing-arrow.gif\" ALT=\"prev\"></A>\n");
804    }
805    if ($cup) {
806        &printHTML("<A HREF=\"$cup\"> <IMG ALIGN=MIDDLE "
807                   . "SRC=\"$icons/up-arrow.gif\" ALT=\"UP\"></A>\n");
808    } else {
809        &printHTML("<A><IMG ALIGN=MIDDLE "
810                   . "SRC=\"$icons/missing-arrow.gif\" ALT=\"up\"></A>\n");
811    }
812    if ($cnext) {
813        &printHTML("<A HREF=\"$cnext\"><IMG ALIGN=MIDDLE "
814                   . "SRC=\"$icons/next-arrow.gif\" ALT=\"NEXT\"></A>\n");
815    } else {
816        &printHTML("<A><IMG ALIGN=MIDDLE "
817                   . "SRC=\"$icons/missing-arrow.gif\" ALT=\"next\"></A>\n");
818    }
819    &printHTML("<CITE>$title</CITE>") if $title;
820    &printHTML("</P>\n");
821       
822} # process_node
823sub terminate_node
824{
825    if ($nfootnotes) {
826        &printHTML("<P><HR>\n");
827        for ($n=0; $n < $nfootnotes; ++$n) {
828            &printHTML("<P>\[" . ($n+1) . "\] $footnote[$n]</P>\n");
829        }
830    }
831    &print_footer if $footer;
832    &printHTML("</BODY></HTML>\n");
833    close (HTML);
834}
835
836########################################################################
837sub process_section
838#
839# On entry:
840#     $_ is the section command (I.e. `@chapter Overview')
841#     $i is the index to $_ in @lines
842{
843    &printHTML("$paragraph_end") if $in_paragraph;
844    $in_paragraph = 0;
845
846    /^\@(\w+)\s+(.*)/;
847
848    $section_number = '';
849    if ($1 eq 'chapter') {
850        ++$chapter; $section=$subsection=$subsubsection=0;
851        $section_number = "Chapter $chapter: ";
852    } elsif ($1 eq 'section') {
853        ++$section; $subsection=$subsubsection=0;
854        $section_number = "$chapter.$section: ";
855    } elsif ($1 eq 'subsection') {
856        ++$subsection; $subsubsection=0;
857        $section_number = "$chapter.$section.$subsection: ";
858    } elsif ($1 eq 'subsubsection') {
859        ++$subsubsection;
860        $section_number = "$chapter.$section.$subsection.$subsubsection: ";
861    } elsif ($1 eq 'appendix') {
862        ++$appendix; $section=$subsection=$subsubsection=0;
863        $x = ('A'..'Z')[$appendix-1];
864        $section_number = "Appendix $x: ";
865    } elsif ($1 eq 'appendixsec') {
866        ++$section; $subsection=$subsubsection=0;
867        $x = ('A'..'Z')[$appendix-1];
868        $section_number = "$x.$section: ";
869    } elsif ($1 eq 'appendixsubsec') {
870        ++$subsection; $subsubsection=0;
871        $x = ('A'..'Z')[$appendix-1];
872        $section_number = "$x.$section.$subsection: ";
873    } elsif ($1 eq 'appendixsubsubsec') {
874        ++$subsubsection;
875        $x = ('A'..'Z')[$appendix-1];
876        $section_number = "$x.$section.$subsection.$subsubsection: ";
877    }
878
879    $x = $directive_section{$1};
880    &printHTML("<H$x>$section_number$2</H$x>\n");
881} # process_section
882
883########################################################################
884sub process_synindex
885#
886# There's perhaps a bug here -- this presumes the @synindex comes before
887# any @?index directives; anything already in <from> doesn't get merged
888# into <to>!
889#
890{
891    local ($code) = @_;         # Either 0 or 1; 1 means @syncodeindex
892
893    /\@syn\w*index\s+(\w+)\s+(\w+)/;
894
895    print "*** synindex $1 $2\n" if $debug{'index'};
896
897    $index_name{$1} = $2 . "index";
898    $index_style{$1} = 'CODE' if $code;
899} # process_synindex
900
901########################################################################
902sub printHTML
903{
904    local ($line) = @_;
905    $line =~ s/\$R/\}/g;
906    $line =~ s/\$L/\{/g;
907    $line =~ s/\$A/\@/g;
908    $line =~ s/\$D/\$/g;
909    if ($debug{printHTML}) {
910        print $line;
911    } else {
912        print HTML $line;
913    }
914} # printHTML
915
916########################################################################
917sub print_header
918{
919    unless (open(HEADER,$header)) {
920        print "WARNING -- couldn't open header file \"$header\" -- $!\n";
921        $header = 0;
922        return;
923    }
924    while (<HEADER>) {
925        &printHTML($_);
926    }
927    close(HEADER);
928}
929
930########################################################################
931sub print_footer
932{
933    unless (open(FOOTER,$footer)) {
934        print "WARNING -- couldn't open footer file \"$footer\" -- $!\n";
935        $footer = 0;
936        return;
937    }
938    while (<FOOTER>) {
939        &printHTML($_);
940    }
941    close(FOOTER);
942}
943
944########################################################################
945sub read_input
946#
947# Read the texinfo source into @texinfo.  Don't copy comments or the
948# `@ifxxx' and `@end ifxxx' surrounding [or the contents of] conditional
949# blocks.  Read `@include' files.
950{
951    local ($echo,$terminator_re,$started_at) = @_;
952
953    while (&texinfo_read()) {
954
955        next if (/^\@c$/ || /^\@c\s/ || /^\@comment/);
956
957        if (/^\@ifinfo/) {
958            &read_input($echo,'/^\@end\s+ifinfo/',
959                                              "$texinfo_file[0] line $.");
960            next;
961        }
962        if (/^\@ifhtml/) {
963            &read_input($echo,'/^\@end\s+ifhtml/',
964                                              "$texinfo_file[0] line $.");
965            next;
966        }
967        if (/^\@iftex/)  {
968            &read_input(0,'/^\@end\s+iftex/',
969                                              "$texinfo_file[0] line $.");
970            next;
971        }
972        if (/^\@tex/)  {
973            &read_input(0,'/^\@end\s+tex/',
974                                              "$texinfo_file[0] line $.");
975            next;
976        }
977        if (/^\@ignore/) {
978            # @ignore doesn't nest
979            $ignore_from = "$texinfo_file[0] line $.";
980            while (&texinfo_read()) {
981                last if (/^\@end\s+ignore/);
982            }
983            unless (/^\@end\s+ignore/) {
984                print "Unexpected EOF while searching from $ignore_from "
985                    . "for \'\@end ignore\'\n";
986            }
987            next;
988        }
989        if (/^\@titlepage/) {
990            &read_input(0,'/^\@end\s+titlepage/',"$texinfo_file[0] line $.");
991            next;
992        }
993
994        if (/^\@ifclear\s+(\S+)/) {
995            &read_input($echo&&(!defined($set{$1})),'/^\@end\s+ifclear/',
996                                                  "$texinfo_file[0] line $.");
997            next;
998        }
999        if (/^\@ifset\s+(\S+)/) {
1000            &read_input($echo&&defined($set{$1}),'/^\@end\s+ifset/',
1001                                                  "$texinfo_file[0] line $.");
1002            next;
1003        }
1004       
1005        return if eval "$terminator_re";
1006
1007        if (/^\@include\s+(\S+)/) {
1008            &open_input_file($1);
1009            next;
1010        }
1011
1012        if (/^\@(set|clear)\s+(\S+)/) {
1013            if ($1 eq "set") {
1014                $set{$2} = 1;
1015            } else {
1016                undef($set{$2});
1017            }
1018        }
1019
1020        next unless $echo;
1021
1022        if (/^\@(\w+)/) {next if $ignore_these_directives{$1};}
1023       
1024        # Hide @@, @{, and @} so later on it'll be easier to process
1025        # stuff like `@code{@@TeX@{@}}'.
1026        s/\$/\$D/g; s/\@\@/\$A/g; s/\@{/\$L/g; s/\@}/\$R/g;
1027
1028        # Convert the HTML special characters
1029        s/\&/\&amp;/g; s/\</\&lt;/g; s/\>/\&gt;/g; s/\"/\&quot;/g;
1030       
1031        $texinfo[$ntexinfo] = $_;
1032        $origin[$ntexinfo] =  "$texinfo_file[0] line $.";
1033        ++$ntexinfo;
1034    }
1035
1036    print "Unexpected EOF while searching from $started_at "
1037        . "for $terminator_re\n";
1038} # read_input
1039
1040########################################################################
1041sub initialize_tables
1042{
1043    # Lists which `@x{y}' get expanded into `y'.
1044    %atxy_2_y = (
1045        'asis', 1,
1046         'r', 1,
1047         'w', 1,
1048    );
1049
1050    # Describes which `@x{y}' get expanded into `<z>y</z>' and what `z'
1051    # is in those expansions!  (If the expansion matches
1052    # ``/(.*),(.*),(.*)/'' then y actually expands to ``$1<$2>y</$2>$3'';
1053    # if z (or $2) begins with ^ then uppercase y before doing the
1054    # expansion).
1055    %atxy_2_zyz= (
1056        'b',         'STRONG',
1057        'cite',      'CITE',
1058        'code',      "CODE",
1059        'dfn',       'EM',
1060        'dmn',       'EM',
1061        'emph',      'EM',
1062        'file',      "`,CODE,'",
1063        'i',         'EM',
1064        'kbd',       'KBD',
1065        'key',       '^CODE',
1066        'math',      'CODE',
1067        'samp',      "`,CODE,'",
1068        'sc',        '^EM',
1069        'strong',    'STRONG',
1070        't',         'CODE',
1071        'titlefont', 'CITE',
1072        'var',       'VAR',
1073    );
1074
1075    # Describes which `@x{y}' can be expanded into `z' and what `z' is in
1076    # those expansions!
1077    %atxy_2_z = (
1078        'TeX',       '<i>T</i>e<i>X</i>',
1079        'bullet',    '*',
1080        'copyright', '(C)',
1081        'dots',      '...',
1082        'equiv',     '==',
1083        'error',     'error-->',
1084        'expansion', '==>',
1085        'minus',     '-',
1086        'point',     '-!-',
1087        'print',     '-|',
1088        'result',    '=>',
1089        'today',     &today(),
1090    );
1091
1092    # Lists the '@x{y}' cross reference commands, and describes how they get
1093    # expanded.  Note the 'X' beginning each expansion -- it's there so 'ref'
1094    # doesn't get expanded to ''!
1095    %atxy_2_ref = (
1096        'xref',     'XSee ',
1097        'ref',      'X',
1098        'pxref',    'Xsee ',
1099        'href',     'X',
1100        'inforef',  'XSee ',
1101    );
1102
1103    %ignore_these_directives = (
1104        'author', 1,
1105        'break', 1,
1106        'contents', 1,
1107        'evenfooting', 1,
1108        'everyfooting', 1,
1109        'everyheading', 1,
1110        'finalout', 1,
1111        'footnotestyle', 1,
1112        'headings', 1,
1113        'need', 1,
1114        'noindent', 1,
1115        'oddfooting', 1,
1116        'page', 1,
1117        'paragraphindent', 1,
1118        'setchapternewpage', 1,
1119        'setfilename', 1,
1120        'shortcontents', 1,
1121        'shorttitlepage', 1,
1122        'smallbook', 1,
1123        'sp', 1,
1124        'subtitle', 1,
1125        'summarycontents', 1,
1126        'top', 1,
1127        'vskip', 1,                         
1128    );
1129
1130    # List the section directives and indicate what heading level
1131    # each one gets.
1132    %directive_section = (
1133        'chapter', 1,
1134        'section', 2,
1135        'subsection', 3,
1136        'subsubsection',4,
1137        'appendix', 1,
1138        'appendixsec', 2,
1139        'appendixsubsec', 3,
1140        'appendixsubsubsec', 4,
1141        'chapheading', 1,
1142        'majorheading', 1,
1143        'heading', 2,
1144        'subheading', 3,
1145        'subsubheading', 4,
1146        'unnumbered', 1,
1147        'unnumberedsec', 2,
1148        'unnumberedsubsec', 3,
1149        'unnumberedsubsubsec', 4,
1150    );
1151
1152    # These @ directives begin a block of preformatted text
1153    # (">PRE" means indented inside <PRE>...</PRE>)
1154    %directive_block = (
1155        'cartouche',   'HR',
1156        'display',     '>PRE',
1157        'example',     '>PRE',
1158        'format',      'PRE',
1159        'group',       '-',
1160        'lisp',        '>PRE',
1161        'quotation',   'BLOCKQUOTE',
1162        'smallexample','>PRE',
1163    );
1164
1165    %index_name = (
1166        'cp', 'cpindex',
1167        'fn', 'fnindex',
1168        'ky', 'kyindex',
1169        'pg', 'pgindex',
1170        'tp', 'tpindex',
1171        'vr', 'vrindex',
1172    );
1173    %index_style = (
1174        'fn', 'CODE',
1175        'ky', 'CODE',
1176        'pg', 'CODE',
1177        'tp', 'CODE',
1178        'vr', 'CODE',
1179    );
1180} # initialize_tables
1181
1182########################################################################
1183sub open_input_file
1184{
1185    unshift(@texinfo_file,$_[0]);
1186    print "opening $_[0] ...\n" if $debug{open_input_file};
1187    open($texinfo_file[0],$_[0]) || die "Couldn't open $_[0]: $!\n";
1188} # open_input_file
1189
1190########################################################################
1191sub texinfo_read
1192# Reads the next line of texinfo input into $_.
1193{
1194    do {
1195        $fd = $texinfo_file[0];
1196        $_ = <$fd>;
1197    } while ($_ eq '' && shift @texinfo_file);
1198    return $_;
1199} # texinfo_read
1200
1201########################################################################
1202sub today
1203{
1204    $today = `date`;
1205    $today =~ s/\w+ (\w+ +[0-9]+) [0-9]+:[0-9]+:[0-9]+ \w+ ([0-9]+)\n/$1 $2/;
1206    $today =~ s/ +/ /g;
1207    return $today;
1208} # today
1209
1210########################################################################
1211sub copy_to_destdir
1212{
1213    ($copy_from) = @_;
1214
1215    if ($copy_from =~ m|(.*)/([^/]*)|) {
1216        $copy_from_dir = $1;
1217        $copy_from_file = $2;
1218    } else {
1219        $copy_from_dir = ".";
1220        $copy_from_file = $copy_from;
1221    }
1222
1223    if ($copy_from_dir ne $dir && !-e "$dir/$copy_from_file") {
1224        system("cp $copy_from $dir")
1225            && die "Couldn\'t \`cp $copy_from $dir\'\n";
1226    }
1227}
Note: See TracBrowser for help on using the repository browser.