source: rtems/doc/tools/texi2www/texi2www @ 6449498

4.104.114.84.9
Last change on this file since 6449498 was 6449498, checked in by Joel Sherrill <joel.sherrill@…>, on Jan 17, 2002 at 9:47:47 PM

2001-01-17 Joel Sherrill <joel@…>

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