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

4.104.114.84.95
Last change on this file since f52fed0 was f52fed0, checked in by Ralf Corsepius <ralf.corsepius@…>, on 01/20/06 at 17:00:04

2006-01-20 Ralf Corsepius <ralf.corsepius@…>

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