source: rtems/doc/tools/texi2www/texi2www @ 0a46c6d

4.104.114.84.95
Last change on this file since 0a46c6d was 0a46c6d, checked in by Joel Sherrill <joel.sherrill@…>, on 04/03/98 at 16:02:24

Added fourth icon which takes user back to the index

  • Property mode set to 100755
File size: 32.0 KB
RevLine 
[8e12a82]1#!/usr/bin/perl
[cfdba52]2# (Works with both perl 4 and perl 5)
[0bbbf52]3#
4#  $Id$
5#
6
[cfdba52]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 `.'.
[3ab325e]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.
[cfdba52]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 `..'.
[3ab325e]30  -dirfile path     -- Specifies a replacement for ../dir.html
[cfdba52]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
[3ab325e]39$icons = ".."; $dir = "."; $dirfile = "../dir.html";
[cfdba52]40while ($ARGV[0] =~ /^-/) {
41    $_ = shift;
[3ab325e]42    if (/-dirfile/) {$dirfile = shift; next;}
[cfdba52]43    if (/-dir/) {$_ = shift; s!/$!!; s!$!/!; $dir = $_; next;}
44    if (/-verbose/) {$verbose = 1; next;}
45    if (/-footer/) {$footer = shift; next;}
[3ab325e]46    if (/-header/) {$header = shift; next;}
[cfdba52]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
[3ab325e]84    return "$dirfile" if ($n =~ /\(dir\)/i); # handle (dir)
[cfdba52]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            }
[0a46c6d]298            &printHTML("<P><HR>\n");
299            &print_arrows;
300            &printHTML("</P>\n");
[cfdba52]301            &print_footer if $footer;
302            &printHTML("</BODY></HTML>\n");
303            close (HTML);
304            return;
305        } elsif ($1 eq 'center') {
306            /^\@center\s+(.*)/;
307            &printHTML("$paragraph_end") if $in_paragraph;
308            &printHTML("<P ALIGN=CENTER>$1</P>\n");
309            $in_paragraph = 0;
310        } elsif ($1 eq 'clear') {
311            /^\@clear\s+(\S+)/;
312            undef($texinfo_variable{$1});
313        } elsif ($1 =~ /^def(code)?index/) {
314            /^\@(def|defcode)index\s+(\w+)/;
315            $index_name{$2} = $2 . "index";
316            $index_style{$2} = 'CODE' if ($1 eq "defcode");
317        } elsif ($1 =~ /^(def.*)/) { # @defn, @defun, ... @deftp
318            &parse_def($1);
319        } elsif ($1 eq 'enumerate') {
320            &parse_enumerate();
321        } elsif ($1 eq 'exdent') {
322            /^\@exdent\s+(.*)/;
323            &printHTML("$paragraph_end") if $in_paragraph;
324            # A bug -- doesn't exdent the line!
325            &printHTML("<P>$1</P>\n");
326            $in_paragraph = 0;
327        } elsif ($1 eq 'flushleft' || $1 eq 'flushright') {
328            &parse_flush();
329        } elsif ($1 eq 'html') {
330            while ($texinfo_index < @texinfo) {
331                &get_more_stuff_to_parse();
332                last if (/^\@end\s+html/);
333                s/\&quot;/\"/g; s/\&gt;/\>/g; s/\&lt;/\</g; s/\&amp;/\&/g;
334                &printHTML("$_");
335            }
336        } elsif ($1 eq 'itemize') {
337            &parse_itemize();
338        } elsif ($1 eq 'menu') {
339            &parse_menu();
340        } elsif ($1 eq 'node') {
[0a46c6d]341            $node=$_;
[cfdba52]342            &process_node();
343        } elsif ($1 eq 'printindex') {
344            /^\@printindex\s+([a-z]+)/;
345            &print_index($1);
346        } elsif ($1 eq 'settitle') {
347            /^\@settitle\s+(.*)/;
348            unless ($title) {$title = $1;}
349        } elsif ($1 eq 'set') {
350            if (/^\@set\s+(\S+)\s+(.+)$/) {
351                $texinfo_variable{$1} = $2;
352            } else {
353                /^\@set\s+(\S+)/;
354                $texinfo_variable{$1} = 1;
355            }
356        } elsif ($1 eq 'syncodeindex') {
357            &process_synindex(1);
358        } elsif ($1 eq 'synindex') {
359            &process_synindex(0);
360        } elsif ($1 =~ /^.?table/) { # @table, @vtable, @ftable
361            unless (/^\@(.?table)\s*\@(\w*)/
362                           && ($2 eq 'asis' || ($tbltype=$atxy_2_zyz{$2}))) {
363                print "**WARNING** $origin[$start_index]: assuming "
364                    . "\@table \@asis\n";
365                $tbltype = '';
366            }
367            &parse_table($1,$tbltype);
368        } elsif ($1 =~ /..?index/) { # @cindex, @findex, .. @auindex, etc.
369            &process_index();
370        } else {
371            print "**WARNING** $origin[$start_index]: ignoring $_";
372        }
373    } else {
374        if (/^\s*$/) {
375            if ($in_paragraph) {
376                &printHTML("$paragraph_end");
377            } elsif ($in_preformatted) {
378                &printHTML("\n");
379            }
380            $in_paragraph = 0;
381        } else {
382            unless ($in_preformatted) {
383                unless ($in_paragraph) {
384                    &printHTML("<P>\n");
385                    $in_paragraph = 1;
386                    $paragraph_end = "</P>\n";
387                }
388            }
389            &printHTML("$_");
390        }
391    }
392} # parse
393
394########################################################################
395sub parse_block
396#
397# Handles @example, @display, etc.
398#
399#    > @example            > <PRE>
400#    > a + b = c     ==>   > a + b = c
401#    > @end example        > </PRE>
402{
403    local ($block,$pre) = @_;
404    local ($started_at);
405
406    $started_at = $start_index;
407
408    &printHTML("$paragraph_end") if $in_paragraph;
409    $in_paragraph = 0;
410
411    if ($pre eq '>PRE') {
412        &printHTML("<DL><DT><DD>\n<PRE>\n");
413    } else {
414        &printHTML("<$pre>\n") unless ($pre eq '-');
415    }
416    $in_preformatted = $block;
417    while ($texinfo_index < @texinfo) {
418        &get_more_stuff_to_parse();
419        if (/^\@end\s+$block/) {
420            if ($pre eq 'HR') {
421                &printHTML("</HR>\n");
422            } elsif ($pre eq '>PRE') {
423                &printHTML("</PRE>\n</DL>\n");
424            } else {
425                &printHTML("</$pre>\n") unless ($pre eq '-');
426            }
427            $in_preformatted = 0;
428            return;
429        }
430        &parse();
431    }
432    print "**ERROR** reached EOF while searching for end of the \@$block "
433        . "block that started on $origin[$started_at]\n";
434} # parse_block
435
436########################################################################
437sub parse_def
438# $_ contains a @def* command
439{
440    local ($def) = @_;
441    local ($started_at,$in_dd);
442
443    $started_at = $start_index;
444       
445    &printHTML("$paragraph_end") if $in_paragraph;
446    $in_paragraph = 0;
447   
448    &printHTML("<DL>\n");
449
450    &printdef();
451
452    while ($texinfo_index < @texinfo) {
453        &get_more_stuff_to_parse();
454        if (/^\@end\s+$def/) {
455            &printHTML("</DL>\n");
456            $in_paragraph = 0;
457            return;
458        }
459        if (s/^(\@def\w+)x\s/$1 /) {&printdef();}
460        else {
461            unless ($in_dd) {
462                &printHTML("<DD>\n");
463                ++$in_dd;
464                $in_paragraph = 1;
465                $paragraph_end = "\n";
466            }
467            &parse();
468        }
469    }
470    print "**ERROR** reached EOF while searching for end of the $def "
471        . "definition that started on $origin[$started_at]\n";
472
473} # parse_def
474sub printdef
475{
476
477    s/\@defun(x?)\s/\@deffn Function /
478        || s/\@defmac(x?)\s/\@deffn Macro /
479        || s/\@defspec(x?)\s/\@deffn \{Special Form\} /
480        || s/\@defvar(x?)\s/\@defvr Variable /
481        || s/\@defopt(x?)\s/\@defvr \{User Option\} /
482        || s/\@deftypefun(x?)\s/\@deftypefn Function /
483        || s/\@deftypevar(x?)\s/\@deftypefn Variable /
484        || s/\@defivar(x?)\s/\@defcv \{Instance Variable\} /
485        || s/\@defmethod(x?)\s/\@defop Method /;
486    s/(\@\w+)x\s/$1 /;
487
488    @words = split;
489
490    $i = 1;
491    $category = $words[$i++];
492    while ($i < @words && $category =~ /^\{[^}]*$/) {
493        $category .= ' ' . $words[$i++];
494    }
495    if ($i>=@words) {
496        print "def error at $origin{$started_at}\n";
497    }
498    $category =~ s/^\{//;
499    $category =~ s/\}$//;
500
501    &printHTML("<DT>$category: ");
502
503    if ($words[0] eq '@deftypefn' || $words[0] eq '@deftypevr'
504        || $words[0] eq '@defcv' || $words[0] eq '@defop') {
505        if ($words[$i] =~ s/^\{//) {
506            &printHTML("<VAR>");
507            until ($words[$i] =~ s/\}$//) {&printHTML("$words[$i++]");}
508            &printHTML("$words[$i++]</VAR> ");
509        } else {
510            &printHTML("<VAR>$words[$i++]</VAR> ");
511        }
512        $words[0] =~ /.*([a-z][a-z])/;
513        $_ = "\@" . $1 . "index " . $words[$i];
514        &process_index;
515    }
516    &printHTML("<STRONG>$words[$i++]</STRONG>\n<VAR>");
517
518    while ($i < @words) {&printHTML(" $words[$i++]");}
519    &printHTML("</VAR>\n");
520
521} # printdef
522
523########################################################################
524sub parse_enumerate
525# $_ is `@enumerate'.  Note that @enumerate with an arg (`@enumerate 3',
526# for example) is kinda funky due to HTML limitations.
527{
528    local ($count,$started_at);
529   
530    $started_at = $start_index;
531
532    &printHTML("$paragraph_end") if $in_paragraph;
533    $in_paragraph = 0;
534
535    if (/^\@enumerate\s*(\S+)/) {$count = $1;}
536
537    &printHTML("<" . ($count ? "UL" : "OL") . ">\n");
538
539    while ($texinfo_index < @texinfo) {
540        &get_more_stuff_to_parse();
541        if (/^\@end\s+enumerate/) {
542            &printHTML("</" . ($count ? "UL" : "OL") . ">\n");
543            return;
544        }
545        if (/^\@item\s+(.*)/ || /^\@item()$/) {
546            if ($count) {
547                &printHTML("<LI>$count: $1\n");
548                ++$count;
549            } else {
550                &printHTML("<LI>$1\n");
551            }
552            $in_paragraph = 1;
553            $paragraph_end = "\n";
554        } else {
555            &parse();
556        }
557    }
558    print "**ERROR** reached EOF while searching for end of the \@enumerate "
559        . "that started on $origin[$started_at]\n";
560} # parse_enumerate
561
562########################################################################
563sub parse_flush
564{
565    local ($started_at,$flush);
566
567    /^\@(\w+)\s/;
568    $flush = $1;
569    $started_at = $start_index;
570
571    &printHTML("$paragraph_end") if $in_paragraph;
572    $in_paragraph = 0;
573
574    while ($texinfo_index < @texinfo) {
575        &get_more_stuff_to_parse();
576        if (/^\@end\s+$flush/) {
577            return;
578        }
579        &parse();
580    }
581    print "**ERROR** reached EOF while searching for end of the $flush "
582        . "that started on $origin[$started_at]\n";
583
584
585} # parse_flush
586
587########################################################################
588sub parse_itemize
589# $_ is `@itemize'.  Due to HTML limitation, `@itemize @bullet' comes
590# out the same as `@itemize @minus'.
591{
592    local ($started_at);
593
594    $started_at = $start_index;
595
596    &printHTML("$paragraph_end") if $in_paragraph;
597    $in_paragraph = 0;
598
599    &printHTML("<UL>\n");
600   
601
602    while ($texinfo_index < @texinfo) {
603        &get_more_stuff_to_parse();
604        if (/^\@end\s+itemize/) {
605            &printHTML("</UL>\n");
606            return;
607        }
608        if (/^\@item\s+(.*)/ || /^\@item()$/) {
609            &printHTML("<LI>$1\n");
610            $in_paragraph = 1;
611            $paragraph_end = "\n";
612        } else {
613            &parse();
614        }
615    }
616    print "**ERROR** reached EOF while searching for end of the itemize "
617        . "that started on $origin[$started_at]\n";
618} # parse_itemize
619
620########################################################################
621sub parse_menu
622{
623    local ($started_at);
624
625    $started_at = $start_index;
626
627    &printHTML("$paragraph_end") if $in_paragraph;
628    $in_paragraph = 0;
629
630    &printHTML("<MENU>\n");
631
632    while ($texinfo_index < @texinfo) {
633        &get_more_stuff_to_parse();
634        if (/^\@end\s+menu/) {
635            &printHTML("</MENU>\n");
636            return;
637        }
638
639        # Like ` * menu-item:: description of item'
640        if (/^\s*\*\s*([^:]*)\s*::\s*(.*)$/) {
641            &printHTML("$paragraph_end") if $in_paragraph;
642            $in_paragraph = 0;
643            $node = &canonical($1);     
644            &printHTML("<LI><A HREF=\"$node\">$1</A>\n");
645            &printHTML("$2\n") if $2;
646        # Like ` * menu-item: cross-reference. description of item'
647        } elsif (/^\s*\*\s*([^:]*)\s*:([^.]*)\.\s*(.*)$/) {
648            &printHTML("$paragraph_end") if $in_paragraph;
649            $in_paragraph = 0;
650            $node = &canonical($2);
651            &printHTML("<LI><A HREF=\"$node\">$1</A>\n");
652            &printHTML("$3\n");
653        } elsif (/^\@/) {
654            print "**WARNING** Don\'t know how to process \`$_\' inside "
655                . "a menu!\n";
656        } else {
657            if (/^\s*$/ && !$in_paragraph) {
658                &printHTML("<P>");
659                $in_paragraph = "1";
660                $paragraph_end = "</P>\n";
661            }
662            &printHTML("$_");
663        }
664    }
665    print "**ERROR** reached EOF while searching for end of the menu "
666        . "that started on $origin[$started_at]\n";
667} # parse_menu
668
669########################################################################
670sub parse_table
671# $_ is `@itemize'.  Due to HTML limitation, `@itemize @bullet' comes
672# out the same as `@itemize @minus'.
673{
674    local ($table,$ttype,$after_DT,$started_at,$first_para);
675    ($table,$ttype) = @_;
676
677    $started_at = $start_index;
678
679    &printHTML("$paragraph_end") if $in_paragraph;
680    $in_paragraph = 0;
681
682    &printHTML("<DL>\n");
683
684    while ($texinfo_index < @texinfo) {
685        &get_more_stuff_to_parse();   
686        if (/^\@end\s+$table/) {
687            &printHTML("</DL>\n");
688            return;
689        }
690        if (/^\@item(x?)\s+(.*)/ || /^\@item(x?)()$/) {
691            $atarg = $2;
692            if ($ttype) {
693                if ($ttype =~ /(.+),(.+),(.+)/) {
694                    $left = $1; $z = $2; $right = $3;
695                } else {
696                    $left = ''; $z = $ttype; $right = '';
697                }
698                if ($z =~ s/^\^//) {$atarg =~ tr/a-z/A-Z/;}
699                &printHTML("<DT>$left<$z>$atarg</$z>$right\n");
700            } else {
701                &printHTML("<DT>$2\n");
702            }
703            $item = $2;
704            if ($item && $table =~ /([fv])table/) {
705                $_ = "\@" . $1 . "index " . $item;
706                &process_index;
707            }
708            $after_DT = 1;
709        } else {
710            if ($after_DT) {
711                &printHTML("<DD>\n");
712                $in_paragraph = 1;
713                $paragraph_end = "\n";
714                $after_DT = 0;
715                $first_para = 1;
716            }
717            unless ($first_para && /^\s*$/) {
718                $first_para = 0;
719                &parse();
720            }
721        }
722    }
723    print "**ERROR** reached EOF while searching for end of the table "
724        . "that started on $origin[$started_at]\n";
725} # parse_table
726
727########################################################################
728sub print_index
729{
730    local ($index) = @_;
731    $index = $index_name{$index};
732
733    eval "\@keys = keys \%$index";
734
735    &printHTML("<MENU>\n");
736    foreach $item (sort texinfo_sort @keys) {
737        eval "\$val = \$$index\{\$item\}";
738        &printHTML("<LI>$val\n");
739    }
740    &printHTML("</MENU>\n");
741} # print_index
742
743sub texinfo_sort
744{
745    $x = $a; $x =~ s/<[^>]*>//g; $x =~ tr/A-Z/a-z/;
746    $y = $b; $y =~ s/<[^>]*>//g; $y =~ tr/A-Z/a-z/;
747    $x cmp $y;
748} # texinfo_sort
749
750########################################################################
751sub process_index
752#
753# For example, `@cindex whatever' generates an entry in %cpindex
754#
755{
756    s/\@cindex/\@cpindex/ || s/\@findex/\@fnindex/
757        || s/\@vindex/\@vrindex/ || s/\@kindex/\@kyindex/
758        || s/\@pindex/\@pgindex/ || s/\@tindex/\@tpindex/;
759
760    /\@(..)index\s+(.*)/;
761
762    if ($x=$index_style{$1}) {
763        $entry = "<A HREF=\"$cthis\"><$x>$2</$x></A>";
764    } else {
765        $entry = "<A HREF=\"$cthis\">$2</A>";
766    }
767
768    print "*** \$$index_name{$1}\{$2\} = $entry\n" if $debug{'index'};
769    eval "\$$index_name{$1}\{\$2\} = \$entry";
770} # process_index
771
[0a46c6d]772########################################################################
773sub print_arrows
774{
775    &printHTML("<LINK REL=\"Precedes\" HREF=\"$cnext\">\n") if $next;
776    &printHTML("<LINK REV=\"Precedes\" HREF=\"$cprev\">\n") if $prev;
777    &printHTML("<LINK REV=\"Subdocument\" HREF=\"$cup\">\n") if $up;
778    &printHTML("</HEAD><BODY><P>\n");
779    if ($cprev) {
780        &printHTML("<A HREF=\"$cprev\"><IMG ALIGN=MIDDLE "
781                   . "SRC=\"$icons/prev-arrow.gif\" ALT=\"PREV\"></A>\n");
782    } else {
783        &printHTML("<A><IMG ALIGN=MIDDLE "
784                   . "SRC=\"$icons/missing-arrow.gif\" ALT=\"prev\"></A>\n");
785    }
786    if ($cup) {
787        &printHTML("<A HREF=\"$cup\"> <IMG ALIGN=MIDDLE "
788                   . "SRC=\"$icons/up-arrow.gif\" ALT=\"UP\"></A>\n");
789    } else {
790        &printHTML("<A><IMG ALIGN=MIDDLE "
791                   . "SRC=\"$icons/missing-arrow.gif\" ALT=\"up\"></A>\n");
792    }
793    if ($cnext) {
794        &printHTML("<A HREF=\"$cnext\"><IMG ALIGN=MIDDLE "
795                   . "SRC=\"$icons/next-arrow.gif\" ALT=\"NEXT\"></A>\n");
796    } else {
797        &printHTML("<A><IMG ALIGN=MIDDLE "
798                   . "SRC=\"$icons/missing-arrow.gif\" ALT=\"next\"></A>\n");
799    }
800
801    &printHTML("<CITE>$title</CITE>") if $title;
802}
803
[cfdba52]804########################################################################
805sub process_node
806# On entry, $_ is an @node line.
807{
808    s/^\@node\s+//;
809    ($this,$next,$prev,$up) = split(/,/);
810
811    &deduce_node_links() unless ($next || $prev || $up);
812
813    $cthis = &canonical($this);
814    $cnext = &canonical($next);
815    $cprev = &canonical($prev);
816    $cup = &canonical($up);
817
818    &terminate_node();
819
820    print "... opening $dir$cthis ...\n" if $debug{nodes};
821    open(HTML,">$dir/$cthis") || die "Couldn't open $dir$cthis -- $!\n";
822   
823    $nfootnotes = 0;
824
825    &printHTML("<HTML>\n");
826    &printHTML("<!-- created $today from " .
827               $origin[$start_index] . " via texi2www -->\n");
[3ab325e]828    &print_header if $header;
[cfdba52]829    &printHTML("<HEAD>\n<TITLE>$this</TITLE>\n");
[0a46c6d]830    &print_arrows;
[cfdba52]831    &printHTML("</P>\n");
832       
833} # process_node
[0a46c6d]834
[cfdba52]835sub terminate_node
836{
837    if ($nfootnotes) {
838        &printHTML("<P><HR>\n");
839        for ($n=0; $n < $nfootnotes; ++$n) {
840            &printHTML("<P>\[" . ($n+1) . "\] $footnote[$n]</P>\n");
841        }
842    }
[0a46c6d]843
844   
845    &printHTML("<P><HR>\n");
846    &print_arrows;
847    &printHTML("</P>\n");
[cfdba52]848    &print_footer if $footer;
849    &printHTML("</BODY></HTML>\n");
850    close (HTML);
851}
852
853########################################################################
854sub process_section
855#
856# On entry:
857#     $_ is the section command (I.e. `@chapter Overview')
858#     $i is the index to $_ in @lines
859{
860    &printHTML("$paragraph_end") if $in_paragraph;
861    $in_paragraph = 0;
862
863    /^\@(\w+)\s+(.*)/;
864
865    $section_number = '';
866    if ($1 eq 'chapter') {
867        ++$chapter; $section=$subsection=$subsubsection=0;
868        $section_number = "Chapter $chapter: ";
869    } elsif ($1 eq 'section') {
870        ++$section; $subsection=$subsubsection=0;
871        $section_number = "$chapter.$section: ";
872    } elsif ($1 eq 'subsection') {
873        ++$subsection; $subsubsection=0;
874        $section_number = "$chapter.$section.$subsection: ";
875    } elsif ($1 eq 'subsubsection') {
876        ++$subsubsection;
877        $section_number = "$chapter.$section.$subsection.$subsubsection: ";
878    } elsif ($1 eq 'appendix') {
879        ++$appendix; $section=$subsection=$subsubsection=0;
880        $x = ('A'..'Z')[$appendix-1];
881        $section_number = "Appendix $x: ";
882    } elsif ($1 eq 'appendixsec') {
883        ++$section; $subsection=$subsubsection=0;
884        $x = ('A'..'Z')[$appendix-1];
885        $section_number = "$x.$section: ";
886    } elsif ($1 eq 'appendixsubsec') {
887        ++$subsection; $subsubsection=0;
888        $x = ('A'..'Z')[$appendix-1];
889        $section_number = "$x.$section.$subsection: ";
890    } elsif ($1 eq 'appendixsubsubsec') {
891        ++$subsubsection;
892        $x = ('A'..'Z')[$appendix-1];
893        $section_number = "$x.$section.$subsection.$subsubsection: ";
894    }
895
896    $x = $directive_section{$1};
897    &printHTML("<H$x>$section_number$2</H$x>\n");
898} # process_section
899
900########################################################################
901sub process_synindex
902#
903# There's perhaps a bug here -- this presumes the @synindex comes before
904# any @?index directives; anything already in <from> doesn't get merged
905# into <to>!
906#
907{
908    local ($code) = @_;         # Either 0 or 1; 1 means @syncodeindex
909
910    /\@syn\w*index\s+(\w+)\s+(\w+)/;
911
912    print "*** synindex $1 $2\n" if $debug{'index'};
913
914    $index_name{$1} = $2 . "index";
915    $index_style{$1} = 'CODE' if $code;
916} # process_synindex
917
918########################################################################
919sub printHTML
920{
921    local ($line) = @_;
922    $line =~ s/\$R/\}/g;
923    $line =~ s/\$L/\{/g;
924    $line =~ s/\$A/\@/g;
925    $line =~ s/\$D/\$/g;
926    if ($debug{printHTML}) {
927        print $line;
928    } else {
929        print HTML $line;
930    }
931} # printHTML
932
[3ab325e]933########################################################################
934sub print_header
935{
936    unless (open(HEADER,$header)) {
937        print "WARNING -- couldn't open header file \"$header\" -- $!\n";
938        $header = 0;
939        return;
940    }
941    while (<HEADER>) {
942        &printHTML($_);
943    }
944    close(HEADER);
945}
946
[cfdba52]947########################################################################
948sub print_footer
949{
950    unless (open(FOOTER,$footer)) {
951        print "WARNING -- couldn't open footer file \"$footer\" -- $!\n";
952        $footer = 0;
953        return;
954    }
955    while (<FOOTER>) {
956        &printHTML($_);
957    }
958    close(FOOTER);
959}
960
961########################################################################
962sub read_input
963#
964# Read the texinfo source into @texinfo.  Don't copy comments or the
965# `@ifxxx' and `@end ifxxx' surrounding [or the contents of] conditional
966# blocks.  Read `@include' files.
967{
968    local ($echo,$terminator_re,$started_at) = @_;
969
970    while (&texinfo_read()) {
971
972        next if (/^\@c$/ || /^\@c\s/ || /^\@comment/);
973
974        if (/^\@ifinfo/) {
975            &read_input($echo,'/^\@end\s+ifinfo/',
976                                              "$texinfo_file[0] line $.");
977            next;
978        }
979        if (/^\@ifhtml/) {
980            &read_input($echo,'/^\@end\s+ifhtml/',
981                                              "$texinfo_file[0] line $.");
982            next;
983        }
984        if (/^\@iftex/)  {
985            &read_input(0,'/^\@end\s+iftex/',
986                                              "$texinfo_file[0] line $.");
987            next;
988        }
989        if (/^\@tex/)  {
990            &read_input(0,'/^\@end\s+tex/',
991                                              "$texinfo_file[0] line $.");
992            next;
993        }
994        if (/^\@ignore/) {
995            # @ignore doesn't nest
996            $ignore_from = "$texinfo_file[0] line $.";
997            while (&texinfo_read()) {
998                last if (/^\@end\s+ignore/);
999            }
1000            unless (/^\@end\s+ignore/) {
1001                print "Unexpected EOF while searching from $ignore_from "
1002                    . "for \'\@end ignore\'\n";
1003            }
1004            next;
1005        }
1006        if (/^\@titlepage/) {
1007            &read_input(0,'/^\@end\s+titlepage/',"$texinfo_file[0] line $.");
1008            next;
1009        }
1010
1011        if (/^\@ifclear\s+(\S+)/) {
1012            &read_input($echo&&(!defined($set{$1})),'/^\@end\s+ifclear/',
1013                                                  "$texinfo_file[0] line $.");
1014            next;
1015        }
1016        if (/^\@ifset\s+(\S+)/) {
1017            &read_input($echo&&defined($set{$1}),'/^\@end\s+ifset/',
1018                                                  "$texinfo_file[0] line $.");
1019            next;
1020        }
1021       
1022        return if eval "$terminator_re";
1023
1024        if (/^\@include\s+(\S+)/) {
1025            &open_input_file($1);
1026            next;
1027        }
1028
1029        if (/^\@(set|clear)\s+(\S+)/) {
1030            if ($1 eq "set") {
1031                $set{$2} = 1;
1032            } else {
1033                undef($set{$2});
1034            }
1035        }
1036
1037        next unless $echo;
1038
1039        if (/^\@(\w+)/) {next if $ignore_these_directives{$1};}
1040       
1041        # Hide @@, @{, and @} so later on it'll be easier to process
1042        # stuff like `@code{@@TeX@{@}}'.
1043        s/\$/\$D/g; s/\@\@/\$A/g; s/\@{/\$L/g; s/\@}/\$R/g;
1044
1045        # Convert the HTML special characters
1046        s/\&/\&amp;/g; s/\</\&lt;/g; s/\>/\&gt;/g; s/\"/\&quot;/g;
1047       
1048        $texinfo[$ntexinfo] = $_;
1049        $origin[$ntexinfo] =  "$texinfo_file[0] line $.";
1050        ++$ntexinfo;
1051    }
1052
1053    print "Unexpected EOF while searching from $started_at "
1054        . "for $terminator_re\n";
1055} # read_input
1056
1057########################################################################
1058sub initialize_tables
1059{
1060    # Lists which `@x{y}' get expanded into `y'.
1061    %atxy_2_y = (
1062        'asis', 1,
1063         'r', 1,
1064         'w', 1,
1065    );
1066
1067    # Describes which `@x{y}' get expanded into `<z>y</z>' and what `z'
1068    # is in those expansions!  (If the expansion matches
1069    # ``/(.*),(.*),(.*)/'' then y actually expands to ``$1<$2>y</$2>$3'';
1070    # if z (or $2) begins with ^ then uppercase y before doing the
1071    # expansion).
1072    %atxy_2_zyz= (
1073        'b',         'STRONG',
1074        'cite',      'CITE',
1075        'code',      "CODE",
1076        'dfn',       'EM',
1077        'dmn',       'EM',
1078        'emph',      'EM',
1079        'file',      "`,CODE,'",
1080        'i',         'EM',
1081        'kbd',       'KBD',
1082        'key',       '^CODE',
1083        'math',      'CODE',
1084        'samp',      "`,CODE,'",
1085        'sc',        '^EM',
1086        'strong',    'STRONG',
1087        't',         'CODE',
1088        'titlefont', 'CITE',
1089        'var',       'VAR',
1090    );
1091
1092    # Describes which `@x{y}' can be expanded into `z' and what `z' is in
1093    # those expansions!
1094    %atxy_2_z = (
1095        'TeX',       '<i>T</i>e<i>X</i>',
1096        'bullet',    '*',
1097        'copyright', '(C)',
1098        'dots',      '...',
1099        'equiv',     '==',
1100        'error',     'error-->',
1101        'expansion', '==>',
1102        'minus',     '-',
1103        'point',     '-!-',
1104        'print',     '-|',
1105        'result',    '=>',
1106        'today',     &today(),
1107    );
1108
1109    # Lists the '@x{y}' cross reference commands, and describes how they get
1110    # expanded.  Note the 'X' beginning each expansion -- it's there so 'ref'
1111    # doesn't get expanded to ''!
1112    %atxy_2_ref = (
1113        'xref',     'XSee ',
1114        'ref',      'X',
1115        'pxref',    'Xsee ',
1116        'href',     'X',
1117        'inforef',  'XSee ',
1118    );
1119
1120    %ignore_these_directives = (
1121        'author', 1,
1122        'break', 1,
1123        'contents', 1,
1124        'evenfooting', 1,
1125        'everyfooting', 1,
1126        'everyheading', 1,
1127        'finalout', 1,
1128        'footnotestyle', 1,
1129        'headings', 1,
1130        'need', 1,
1131        'noindent', 1,
1132        'oddfooting', 1,
1133        'page', 1,
1134        'paragraphindent', 1,
1135        'setchapternewpage', 1,
1136        'setfilename', 1,
1137        'shortcontents', 1,
1138        'shorttitlepage', 1,
1139        'smallbook', 1,
1140        'sp', 1,
1141        'subtitle', 1,
1142        'summarycontents', 1,
1143        'top', 1,
1144        'vskip', 1,                         
1145    );
1146
1147    # List the section directives and indicate what heading level
1148    # each one gets.
1149    %directive_section = (
1150        'chapter', 1,
1151        'section', 2,
1152        'subsection', 3,
1153        'subsubsection',4,
1154        'appendix', 1,
1155        'appendixsec', 2,
1156        'appendixsubsec', 3,
1157        'appendixsubsubsec', 4,
1158        'chapheading', 1,
1159        'majorheading', 1,
1160        'heading', 2,
1161        'subheading', 3,
1162        'subsubheading', 4,
1163        'unnumbered', 1,
1164        'unnumberedsec', 2,
1165        'unnumberedsubsec', 3,
1166        'unnumberedsubsubsec', 4,
1167    );
1168
1169    # These @ directives begin a block of preformatted text
1170    # (">PRE" means indented inside <PRE>...</PRE>)
1171    %directive_block = (
1172        'cartouche',   'HR',
1173        'display',     '>PRE',
1174        'example',     '>PRE',
1175        'format',      'PRE',
1176        'group',       '-',
1177        'lisp',        '>PRE',
1178        'quotation',   'BLOCKQUOTE',
1179        'smallexample','>PRE',
1180    );
1181
1182    %index_name = (
1183        'cp', 'cpindex',
1184        'fn', 'fnindex',
1185        'ky', 'kyindex',
1186        'pg', 'pgindex',
1187        'tp', 'tpindex',
1188        'vr', 'vrindex',
1189    );
1190    %index_style = (
1191        'fn', 'CODE',
1192        'ky', 'CODE',
1193        'pg', 'CODE',
1194        'tp', 'CODE',
1195        'vr', 'CODE',
1196    );
1197} # initialize_tables
1198
1199########################################################################
1200sub open_input_file
1201{
1202    unshift(@texinfo_file,$_[0]);
1203    print "opening $_[0] ...\n" if $debug{open_input_file};
1204    open($texinfo_file[0],$_[0]) || die "Couldn't open $_[0]: $!\n";
1205} # open_input_file
1206
1207########################################################################
1208sub texinfo_read
1209# Reads the next line of texinfo input into $_.
1210{
1211    do {
1212        $fd = $texinfo_file[0];
1213        $_ = <$fd>;
1214    } while ($_ eq '' && shift @texinfo_file);
1215    return $_;
1216} # texinfo_read
1217
1218########################################################################
1219sub today
1220{
1221    $today = `date`;
1222    $today =~ s/\w+ (\w+ +[0-9]+) [0-9]+:[0-9]+:[0-9]+ \w+ ([0-9]+)\n/$1 $2/;
1223    $today =~ s/ +/ /g;
1224    return $today;
1225} # today
1226
1227########################################################################
1228sub copy_to_destdir
1229{
1230    ($copy_from) = @_;
1231
1232    if ($copy_from =~ m|(.*)/([^/]*)|) {
1233        $copy_from_dir = $1;
1234        $copy_from_file = $2;
1235    } else {
1236        $copy_from_dir = ".";
1237        $copy_from_file = $copy_from;
1238    }
1239
1240    if ($copy_from_dir ne $dir && !-e "$dir/$copy_from_file") {
1241        system("cp $copy_from $dir")
1242            && die "Couldn\'t \`cp $copy_from $dir\'\n";
1243    }
1244}
Note: See TracBrowser for help on using the repository browser.