source: rtems/doc/tools/texi2www/texi2www @ 4567d3ce

4.104.114.84.9
Last change on this file since 4567d3ce was 4567d3ce, checked in by Ralf Corsepius <ralf.corsepius@…>, on May 21, 2003 at 7:33:35 PM

2003-05-21 Ralf Corsepius <corsepiu@…>

  • texi2www: Add support for @ifnottex.
  • Property mode set to 100755
File size: 34.2 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 (/^\@ifnottex/) {
1024            &read_input($echo,'/^\@end\s+ifnottex/',
1025                                              "$texinfo_file[0] line $.");
1026            next;
1027        }
1028        if (/^\@ifhtml/) {
1029            &read_input($echo,'/^\@end\s+ifhtml/',
1030                                              "$texinfo_file[0] line $.");
1031            next;
1032        }
1033        if (/^\@iftex/)  {
1034            &read_input(0,'/^\@end\s+iftex/',
1035                                              "$texinfo_file[0] line $.");
1036            next;
1037        }
1038        if (/^\@tex/)  {
1039            &read_input(0,'/^\@end\s+tex/',
1040                                              "$texinfo_file[0] line $.");
1041            next;
1042        }
1043        if (/^\@ignore/) {
1044            # @ignore doesn't nest
1045            $ignore_from = "$texinfo_file[0] line $.";
1046            while (&texinfo_read()) {
1047                last if (/^\@end\s+ignore/);
1048            }
1049            unless (/^\@end\s+ignore/) {
1050                print "Unexpected EOF while searching from $ignore_from "
1051                    . "for \'\@end ignore\'\n";
1052            }
1053            next;
1054        }
1055        if (/^\@titlepage/) {
1056            &read_input(0,'/^\@end\s+titlepage/',"$texinfo_file[0] line $.");
1057            next;
1058        }
1059
1060        if (/^\@ifclear\s+(\S+)/) {
1061            &read_input($echo&&(!defined($set{$1})),'/^\@end\s+ifclear/',
1062                                                  "$texinfo_file[0] line $.");
1063            next;
1064        }
1065        if (/^\@ifset\s+(\S+)/) {
1066            &read_input($echo&&defined($set{$1}),'/^\@end\s+ifset/',
1067                                                  "$texinfo_file[0] line $.");
1068            next;
1069        }
1070       
1071        return if eval "$terminator_re";
1072
1073        if (/^\@include\s+(\S+)/) {
1074            &open_input_file($1);
1075            next;
1076        }
1077
1078        if (/^\@(set|clear)\s+(\S+)/) {
1079            if ($1 eq "set") {
1080                $set{$2} = 1;
1081            } else {
1082                undef($set{$2});
1083            }
1084        }
1085
1086        next unless $echo;
1087
1088        if (/^\@(\w+)/) {next if $ignore_these_directives{$1};}
1089       
1090        # Hide @@, @{, and @} so later on it'll be easier to process
1091        # stuff like `@code{@@TeX@{@}}'.
1092        s/\$/\$D/g; s/\@\@/\$A/g; s/\@{/\$L/g; s/\@}/\$R/g;
1093
1094        # Convert the HTML special characters
1095        s/\&/\&amp;/g; s/\</\&lt;/g; s/\>/\&gt;/g; s/\"/\&quot;/g;
1096       
1097        $texinfo[$ntexinfo] = $_;
1098        $origin[$ntexinfo] =  "$texinfo_file[0] line $.";
1099        ++$ntexinfo;
1100    }
1101
1102    print "Unexpected EOF while searching from $started_at "
1103        . "for $terminator_re\n";
1104} # read_input
1105
1106########################################################################
1107sub initialize_tables
1108{
1109    # Lists which `@x{y}' get expanded into `y'.
1110    %atxy_2_y = (
1111        'asis', 1,
1112         'r', 1,
1113         'w', 1,
1114    );
1115
1116    # Describes which `@x{y}' get expanded into `<z>y</z>' and what `z'
1117    # is in those expansions!  (If the expansion matches
1118    # ``/(.*),(.*),(.*)/'' then y actually expands to ``$1<$2>y</$2>$3'';
1119    # if z (or $2) begins with ^ then uppercase y before doing the
1120    # expansion).
1121    %atxy_2_zyz= (
1122        'b',         'STRONG',
1123        'cite',      'CITE',
1124        'code',      "CODE",
1125        'dfn',       'EM',
1126        'dmn',       'EM',
1127        'emph',      'EM',
1128        'file',      "`,CODE,'",
1129        'i',         'EM',
1130        'kbd',       'KBD',
1131        'key',       '^CODE',
1132        'math',      'CODE',
1133        'samp',      "`,CODE,'",
1134        'sc',        '^EM',
1135        'strong',    'STRONG',
1136        't',         'CODE',
1137        'titlefont', 'CITE',
1138        'var',       'VAR',
1139    );
1140
1141    # Describes which `@x{y}' can be expanded into `z' and what `z' is in
1142    # those expansions!
1143    %atxy_2_z = (
1144        'TeX',       '<i>T</i>e<i>X</i>',
1145        'bullet',    '*',
1146        'copyright', '(C)',
1147        'dots',      '...',
1148        'equiv',     '==',
1149        'error',     'error-->',
1150        'expansion', '==>',
1151        'minus',     '-',
1152        'point',     '-!-',
1153        'print',     '-|',
1154        'result',    '=>',
1155        'today',     &today(),
1156    );
1157
1158    # Lists the '@x{y}' cross reference commands, and describes how they get
1159    # expanded.  Note the 'X' beginning each expansion -- it's there so 'ref'
1160    # doesn't get expanded to ''!
1161    %atxy_2_ref = (
1162        'xref',     'XSee ',
1163        'ref',      'X',
1164        'pxref',    'Xsee ',
1165        'href',     'X',
1166        'uref',     'X',
1167        'email',    'X',
1168        'inforef',  'XSee ',
1169    );
1170
1171    %ignore_these_directives = (
1172        'author', 1,
1173        'break', 1,
1174        'contents', 1,
1175        'evenfooting', 1,
1176        'everyfooting', 1,
1177        'everyheading', 1,
1178        'finalout', 1,
1179        'footnotestyle', 1,
1180        'headings', 1,
1181        'need', 1,
1182        'noindent', 1,
1183        'oddfooting', 1,
1184        'page', 1,
1185        'paragraphindent', 1,
1186        'setchapternewpage', 1,
1187        'setcontentsaftertitlepage', 1,
1188        'setfilename', 1,
1189        'shortcontents', 1,
1190        'shorttitlepage', 1,
1191        'smallbook', 1,
1192        'sp', 1,
1193        'subtitle', 1,
1194        'summarycontents', 1,
1195        'top', 1,
1196        'vskip', 1,                         
1197    );
1198
1199    # List the section directives and indicate what heading level
1200    # each one gets.
1201    %directive_section = (
1202        'chapter', 1,
1203        'section', 2,
1204        'subsection', 3,
1205        'subsubsection',4,
1206        'appendix', 1,
1207        'appendixsec', 2,
1208        'appendixsubsec', 3,
1209        'appendixsubsubsec', 4,
1210        'chapheading', 1,
1211        'majorheading', 1,
1212        'heading', 2,
1213        'subheading', 3,
1214        'subsubheading', 4,
1215        'unnumbered', 1,
1216        'unnumberedsec', 2,
1217        'unnumberedsubsec', 3,
1218        'unnumberedsubsubsec', 4,
1219    );
1220
1221    # These @ directives begin a block of preformatted text
1222    # (">PRE" means indented inside <PRE>...</PRE>)
1223    %directive_block = (
1224        'cartouche',   'HR',
1225        'display',     '>PRE',
1226        'example',     '>PRE',
1227        'format',      'PRE',
1228        'group',       '-',
1229        'lisp',        '>PRE',
1230        'quotation',   'BLOCKQUOTE',
1231        'smallexample','>PRE',
1232    );
1233
1234    %index_name = (
1235        'cp', 'cpindex',
1236        'fn', 'fnindex',
1237        'ky', 'kyindex',
1238        'pg', 'pgindex',
1239        'tp', 'tpindex',
1240        'vr', 'vrindex',
1241    );
1242    %index_style = (
1243        'fn', 'CODE',
1244        'ky', 'CODE',
1245        'pg', 'CODE',
1246        'tp', 'CODE',
1247        'vr', 'CODE',
1248    );
1249} # initialize_tables
1250
1251########################################################################
1252sub open_input_file
1253{
1254    my $file = "$_[0]" ;
1255    if ( not -f "$file" )
1256    {
1257      foreach $i ( @include_path )
1258      {
1259        if ( -f "$i/$_[0]" ) { $file = "$i/$_[0]"; last ; }
1260      }
1261    }
1262    unshift(@texinfo_file,$file);
1263    print "opening $file ...\n" if $debug{open_input_file};
1264    open($texinfo_file[0],$file) || die "Couldn't open $file: $!\n";
1265} # open_input_file
1266
1267########################################################################
1268sub texinfo_read
1269# Reads the next line of texinfo input into $_.
1270{
1271    do {
1272        $fd = $texinfo_file[0];
1273        $_ = <$fd>;
1274    } while ($_ eq '' && shift @texinfo_file);
1275    return $_;
1276} # texinfo_read
1277
1278########################################################################
1279sub today
1280{
1281    $today = `date`;
1282    $today =~ s/\w+ (\w+ +[0-9]+) [0-9]+:[0-9]+:[0-9]+ \w+ ([0-9]+)\n/$1 $2/;
1283    $today =~ s/ +/ /g;
1284    return $today;
1285} # today
1286
1287########################################################################
1288sub copy_to_destdir
1289{
1290    ($copy_from) = @_;
1291
1292    if ($copy_from =~ m|(.*)/([^/]*)|) {
1293        $copy_from_dir = $1;
1294        $copy_from_file = $2;
1295    } else {
1296        $copy_from_dir = ".";
1297        $copy_from_file = $copy_from;
1298    }
1299
1300    if ($copy_from_dir ne $dir && !-e "$dir/$copy_from_file") {
1301        system("cp $copy_from $dir")
1302            && die "Couldn\'t \`cp $copy_from $dir\'\n";
1303    }
1304}
Note: See TracBrowser for help on using the repository browser.