source: rtems/doc/tools/texi2www/texi2www @ 8e12a82

4.104.114.84.95
Last change on this file since 8e12a82 was 8e12a82, checked in by Joel Sherrill <joel.sherrill@…>, on Apr 3, 1998 at 3:35:52 PM

Changed Perl executable location

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