1 # python.perl by Fred L. Drake, Jr. <fdrake@acm.org> -*- perl -*-
3 # Heavily based on Guido van Rossum's myformat.perl (now obsolete).
5 # Extension to LaTeX2HTML for documents using myformat.sty.
6 # Subroutines of the form do_cmd_<name> here define translations
7 # for LaTeX commands \<name> defined in the corresponding .sty file.
16 $param = missing_braces()
17 unless ((s/$next_pair_pr_rx/$param=$2;''/eo)
18 ||(s/$next_pair_rx/$param=$2;''/eo));
22 sub next_optional_argument{
23 my($param,$rx) = ('', "^\\s*(\\[([^]]*)\\])?");
24 s/$rx/$param=$2;''/eo;
28 sub make_icon_filename($){
29 my($myname, $mydir, $myext) = fileparse(@_[0], '\..*');
34 $myext = ".$IMAGE_TYPE"
36 return "$mydir$dd$myname$myext";
41 if ($OFF_SITE_LINK_ICON && ($url =~ /^[-a-zA-Z0-9.]+:/)) {
42 # absolute URL; assume it points off-site
43 my $icon = make_icon_filename($OFF_SITE_LINK_ICON);
44 return (" <img src='$icon'\n"
45 . " border='0' class='offsitelink'"
46 . ($OFF_SITE_LINK_ICON_HEIGHT
47 ? " height='$OFF_SITE_LINK_ICON_HEIGHT'"
49 . ($OFF_SITE_LINK_ICON_WIDTH
50 ? " width='$OFF_SITE_LINK_ICON_WIDTH'"
52 . " alt='[off-site link]'\n"
58 # This is a fairly simple hack; it supports \let when it is used to create
59 # (or redefine) a macro to exactly be some other macro: \let\newname=\oldname.
60 # Many possible uses of \let aren't supported or aren't supported correctly.
65 s/[\\]([a-zA-Z]+)\s*(=\s*)?[\\]([a-zA-Z]*)/$matched=1; ''/e;
67 my($new, $old) = ($1, $3);
68 eval "sub do_cmd_$new { do_cmd_$old" . '(@_); }';
69 print "\ndefining handler for \\$new using \\$old\n";
72 s/[\\]([a-zA-Z]+)\s*(=\s*)?([^\\])/$matched=1; ''/es;
74 my($new, $char) = ($1, $3);
75 eval "sub do_cmd_$new { \"\\$char\" . \@_[0]; }";
76 print "\ndefining handler for \\$new to insert '$char'\n";
79 write_warnings("Could not interpret \\let construct...");
86 # the older version of LaTeX2HTML we use doesn't support this, but we use it:
88 sub do_cmd_textasciitilde{ '~' . @_[0]; }
91 # words typeset in a special way (not in HTML though)
93 sub do_cmd_ABC{ 'ABC' . @_[0]; }
94 sub do_cmd_UNIX{ 'Unix'. @_[0]; }
95 sub do_cmd_ASCII{ 'ASCII' . @_[0]; }
96 sub do_cmd_POSIX{ 'POSIX' . @_[0]; }
97 sub do_cmd_C{ 'C' . @_[0]; }
98 sub do_cmd_Cpp{ 'C++' . @_[0]; }
99 sub do_cmd_EOF{ 'EOF' . @_[0]; }
100 sub do_cmd_NULL{ '<tt class="constant">NULL</tt>' . @_[0]; }
102 sub do_cmd_e{ '\' . @_[0]; }
104 $DEVELOPER_ADDRESS = '';
106 $PACKAGE_VERSION = '';
108 sub do_cmd_version{ $PACKAGE_VERSION . @_[0]; }
109 sub do_cmd_shortversion{ $SHORT_VERSION . @_[0]; }
112 $PACKAGE_VERSION = next_argument();
116 sub do_cmd_setshortversion{
118 $SHORT_VERSION = next_argument();
122 sub do_cmd_authoraddress{
124 $DEVELOPER_ADDRESS = next_argument();
128 #sub do_cmd_developer{ do_cmd_author(@_[0]); }
129 #sub do_cmd_developers{ do_cmd_author(@_[0]); }
130 #sub do_cmd_developersaddress{ do_cmd_authoraddress(@_[0]); }
132 sub do_cmd_hackscore{
139 local($_,$before,$after) = @_;
140 my $stuff = next_argument();
141 return $before . $stuff . $after . $_;
144 $IN_DESC_HANDLER = 0;
146 if ($IN_DESC_HANDLER) {
147 return use_wrappers(@_[0], "</var><big>\[</big><var>",
148 "</var><big>\]</big><var>");
151 return use_wrappers(@_[0], "<big>\[</big>", "<big>\]</big>");
155 # Logical formatting (some based on texinfo), needs to be converted to
156 # minimalist HTML. The "minimalist" is primarily to reduce the size of
157 # output files for users that read them over the network rather than
158 # from local repositories.
160 # \file and \samp are at the end of this file since they screw up fontlock.
162 sub do_cmd_pytype{ return @_[0]; }
164 return use_wrappers(@_[0], '<span class="makevar">', '</span>'); }
166 return use_wrappers(@_[0], '<code>', '</code>'); }
168 return use_wrappers(@_[0], '<tt class="module">', '</tt>'); }
170 return use_wrappers(@_[0], '<tt class="keyword">', '</tt>'); }
171 sub do_cmd_exception{
172 return use_wrappers(@_[0], '<tt class="exception">', '</tt>'); }
174 return use_wrappers(@_[0], '<tt class="class">', '</tt>'); }
176 return use_wrappers(@_[0], '<tt class="function">', '</tt>'); }
178 return use_wrappers(@_[0], '<tt class="constant">', '</tt>'); }
180 return use_wrappers(@_[0], '<tt class="member">', '</tt>'); }
182 return use_wrappers(@_[0], '<tt class="method">', '</tt>'); }
183 sub do_cmd_cfunction{
184 return use_wrappers(@_[0], '<tt class="cfunction">', '</tt>'); }
186 return use_wrappers(@_[0], '<tt class="cdata">', '</tt>'); }
188 return use_wrappers(@_[0], '<tt class="ctype">', '</tt>'); }
190 return use_wrappers(@_[0], '<tt class="regexp">', '</tt>'); }
191 sub do_cmd_character{
192 return use_wrappers(@_[0], '"<tt class="character">', '</tt>"'); }
194 return use_wrappers(@_[0], '<b class="program">', '</b>'); }
195 sub do_cmd_programopt{
196 return use_wrappers(@_[0], '<b class="programopt">', '</b>'); }
197 sub do_cmd_longprogramopt{
198 # note that the --- will be later converted to -- by LaTeX2HTML
199 return use_wrappers(@_[0], '<b class="programopt">---', '</b>'); }
201 return use_wrappers(@_[0], '<span class="email">', '</span>'); }
203 return use_wrappers(@_[0], '<span class="mimetype">', '</span>'); }
205 return use_wrappers(@_[0], "<var>", "</var>"); }
207 return use_wrappers(@_[0], '<i class="dfn">', '</i>'); }
209 return use_wrappers(@_[0], '<i>', '</i>'); }
211 return use_wrappers(@_[0], '<span class="file">', '</span>'); }
213 return do_cmd_file(@_[0]); }
215 return use_wrappers(@_[0], '"<tt class="samp">', '</tt>"'); }
217 return use_wrappers(@_[0], '<kbd>', '</kbd>'); }
219 return use_wrappers(@_[0], '<b>', '</b>'); }
221 return use_wrappers(@_[0], '<b>', '</b>'); }
223 return use_wrappers(@_[0], '<i>', '</i>'); }
226 return '...' . @_[0]; }
227 sub do_cmd_unspecified{
228 return '...' . @_[0]; }
231 sub do_cmd_refmodule{
232 # Insert the right magic to jump to the module definition.
234 my $key = next_optional_argument();
235 my $module = next_argument();
238 return "<tt class='module'><a href='module-$key.html'>$module</a></tt>"
242 sub do_cmd_newsgroup{
244 my $newsgroup = next_argument();
245 my $icon = get_link_icon("news:$newsgroup");
246 my $stuff = "<a class='newsgroup' href='news:$newsgroup'>"
247 . "$newsgroup$icon</a>";
253 my $envvar = next_argument();
254 my($name,$aname,$ahref) = new_link_info();
255 # The <tt> here is really to keep buildindex.py from making
256 # the variable name case-insensitive.
257 add_index_entry("environment variables!$envvar@<tt>$envvar</tt>",
259 add_index_entry("$envvar (environment variable)", $ahref);
260 $aname =~ s/<a/<a class="envvar"/;
261 return "$aname$envvar</a>" . $_;
265 # use the URL as both text and hyperlink
267 my $url = next_argument();
268 my $icon = get_link_icon($url);
269 $url =~ s/~/~/g;
270 return "<a class=\"url\" href=\"$url\">$url$icon</a>" . $_;
274 # two parameters: \manpage{name}{section}
276 my $page = next_argument();
277 my $section = next_argument();
278 return "<span class='manpage'><i>$page</i>($section)</span>" . $_;
281 $PEP_FORMAT = "http://python.sourceforge.net/peps/pep-XXXX.html";
282 $RFC_FORMAT = "http://www.ietf.org/rfc/rfcXXXX.txt";
285 my($rfcnum, $format) = @_;
286 $rfcnum = sprintf("%04d", $rfcnum);
288 $format =~ s/XXXX/$rfcnum/;
294 my $rfcnumber = next_argument();
295 my $id = "rfcref-" . ++$global{'max_id'};
296 my $href = get_rfc_url($rfcnumber, $PEP_FORMAT);
297 my $icon = get_link_icon($href);
299 my $nstr = gen_index_id("Python Enhancement Proposals!PEP $rfcnumber", '');
300 $index{$nstr} .= make_half_href("$CURRENT_FILE#$id");
301 return ("<a class=\"rfc\" name=\"$id\"\nhref=\"$href\">PEP $rfcnumber"
307 my $rfcnumber = next_argument();
308 my $id = "rfcref-" . ++$global{'max_id'};
309 my $href = get_rfc_url($rfcnumber, $RFC_FORMAT);
310 my $icon = get_link_icon($href);
312 my $nstr = gen_index_id("RFC!RFC $rfcnumber", '');
313 $index{$nstr} .= make_half_href("$CURRENT_FILE#$id");
314 return ("<a class=\"rfc\" name=\"$id\"\nhref=\"$href\">RFC $rfcnumber"
318 sub do_cmd_citetitle{
320 my $url = next_optional_argument();
321 my $title = next_argument();
322 my $icon = get_link_icon($url);
325 $repl = ("<em class='citetitle'><a\n"
327 . " title='$title'\n"
328 . " >$title$icon</a></em>");
331 $repl = "<em class='citetitle'\n >$title</em>";
336 sub do_cmd_deprecated{
337 # two parameters: \deprecated{version}{whattodo}
339 my $release = next_argument();
340 my $reason = next_argument();
341 return ('<div class="versionnote">'
342 . "<b>Deprecated since release $release.</b>"
343 . "\n$reason</div><p>"
347 sub do_cmd_versionadded{
348 # one parameter: \versionadded{version}
350 my $release = next_argument();
351 return ("\n<span class='versionnote'>New in version $release.</span>\n"
355 sub do_cmd_versionchanged{
356 # one parameter: \versionchanged{version}
358 my $explanation = next_optional_argument();
359 my $release = next_argument();
360 my $text = "Changed in version $release.";
362 $text = "Changed in version $release:\n$explanation.";
364 return "\n<span class='versionnote'>$text</span>\n" . $_;
368 # These function handle platform dependency tracking.
372 my $platform = next_argument();
373 $ModulePlatforms{"<tt class='module'>$THIS_MODULE</tt>"} = $platform;
374 $platform = "Macintosh"
375 if $platform eq 'Mac';
376 return "\n<p class='availability'>Availability: <span"
377 . "\n class='platform'>$platform</span>.</p>\n" . $_;
380 $IGNORE_PLATFORM_ANNOTATION = '';
381 sub do_cmd_ignorePlatformAnnotation{
383 $IGNORE_PLATFORM_ANNOTATION = next_argument();
392 sub get_indexsubitem{
393 return $INDEX_SUBITEM ? " $INDEX_SUBITEM" : '';
396 sub do_cmd_setindexsubitem{
398 $INDEX_SUBITEM = next_argument();
402 sub do_cmd_withsubitem{
403 # We can't really do the right thing, because LaTeX2HTML doesn't
404 # do things in the right order, but we need to at least strip this stuff
405 # out, and leave anything that the second argument expanded out to.
408 my $oldsubitem = $INDEX_SUBITEM;
409 $INDEX_SUBITEM = next_argument();
410 my $stuff = next_argument();
411 my $br_id = ++$globals{'max_id'};
412 my $marker = "$O$br_id$C";
415 . "\\setindexsubitem$marker$oldsubitem$marker"
419 # This is the prologue macro which is required to start writing the
420 # mod\jobname.idx file; we can just ignore it. (Defining this suppresses
421 # a warning that \makemodindex is unknown.)
423 sub do_cmd_makemodindex{ return @_[0]; }
425 # We're in the document subdirectory when this happens!
427 open(IDXFILE, '>index.dat') || die "\n$!\n";
428 open(INTLABELS, '>intlabels.pl') || die "\n$!\n";
429 print INTLABELS "%internal_labels = ();\n";
430 print INTLABELS "1; # hack in case there are no entries\n\n";
432 # Using \0 for this is bad because we can't use common tools to work with the
433 # resulting files. Things like grep can be useful with this stuff!
435 $IDXFILE_FIELD_SEP = "\1";
438 my ($ahref, $str) = @_;
439 print IDXFILE $ahref, $IDXFILE_FIELD_SEP, $str, "\n";
444 my($node,$target) = @_;
445 print INTLABELS "\$internal_labels{\"$target\"} = \"$URL/$node\";\n";
446 return "<a href='$node#$target'>";
450 # add an entry to the index structures; ignore the return value
451 my($str,$ahref) = @_;
452 $str = gen_index_id($str, '');
453 $index{$str} .= $ahref;
454 write_idxfile($ahref, $str);
458 my $name = "l2h-" . ++$globals{'max_id'};
459 my $aname = "<a name='$name'>";
460 my $ahref = gen_link($CURRENT_FILE, $name);
461 return ($name, $aname, $ahref);
464 $IndexMacroPattern = '';
465 sub define_indexing_macro{
468 for (; $i < $count; ++$i) {
470 my $cmd = "idx_cmd_$name";
471 die "\nNo function $cmd() defined!\n"
473 eval ("sub do_cmd_$name { return process_index_macros("
474 . "\@_[0], '$name'); }");
475 if (length($IndexMacroPattern) == 0) {
476 $IndexMacroPattern = "$name";
479 $IndexMacroPattern .= "|$name";
485 sub process_index_macros{
487 my $cmdname = @_[1]; # This is what triggered us in the first place;
488 # we know it's real, so just process it.
489 my($name,$aname,$ahref) = new_link_info();
490 my $cmd = "idx_cmd_$cmdname";
491 print "\nIndexing: \\$cmdname"
493 &$cmd($ahref); # modifies $_ and adds index entries
494 while (/^[\s\n]*\\($IndexMacroPattern)</) {
498 $cmd = "idx_cmd_$cmdname";
499 if (!defined &$cmd) {
503 s/^[\s\n]*\\$cmdname//;
510 return "$aname$anchor_invisible_mark</a>" . $_;
513 define_indexing_macro('index');
515 my $str = next_argument();
516 add_index_entry("$str", @_[0]);
519 define_indexing_macro('kwindex');
521 my $str = next_argument();
522 add_index_entry("<tt>$str</tt>!keyword", @_[0]);
523 add_index_entry("keyword!<tt>$str</tt>", @_[0]);
526 define_indexing_macro('indexii');
528 my $str1 = next_argument();
529 my $str2 = next_argument();
530 add_index_entry("$str1!$str2", @_[0]);
531 add_index_entry("$str2!$str1", @_[0]);
534 define_indexing_macro('indexiii');
535 sub idx_cmd_indexiii{
536 my $str1 = next_argument();
537 my $str2 = next_argument();
538 my $str3 = next_argument();
539 add_index_entry("$str1!$str2 $str3", @_[0]);
540 add_index_entry("$str2!$str3, $str1", @_[0]);
541 add_index_entry("$str3!$str1 $str2", @_[0]);
544 define_indexing_macro('indexiv');
546 my $str1 = next_argument();
547 my $str2 = next_argument();
548 my $str3 = next_argument();
549 my $str4 = next_argument();
550 add_index_entry("$str1!$str2 $str3 $str4", @_[0]);
551 add_index_entry("$str2!$str3 $str4, $str1", @_[0]);
552 add_index_entry("$str3!$str4, $str1 $str2", @_[0]);
553 add_index_entry("$str4!$$str1 $str2 $str3", @_[0]);
556 define_indexing_macro('ttindex');
558 my $str = next_argument();
559 my $entry = $str . get_indexsubitem();
560 add_index_entry($entry, @_[0]);
563 sub my_typed_index_helper{
564 my($word,$ahref) = @_;
565 my $str = next_argument();
566 add_index_entry("$str $word", $ahref);
567 add_index_entry("$word!$str", $ahref);
570 define_indexing_macro('stindex', 'opindex', 'exindex', 'obindex');
571 sub idx_cmd_stindex{ my_typed_index_helper('statement', @_[0]); }
572 sub idx_cmd_opindex{ my_typed_index_helper('operator', @_[0]); }
573 sub idx_cmd_exindex{ my_typed_index_helper('exception', @_[0]); }
574 sub idx_cmd_obindex{ my_typed_index_helper('object', @_[0]); }
576 define_indexing_macro('bifuncindex');
577 sub idx_cmd_bifuncindex{
578 my $str = next_argument();
579 add_index_entry("<tt class='function'>$str()</tt> (built-in function)",
584 sub make_mod_index_entry{
585 my($str,$define) = @_;
586 my($name,$aname,$ahref) = new_link_info();
587 # equivalent of add_index_entry() using $define instead of ''
588 $ahref =~ s/\#[-_a-zA-Z0-9]*\"/\"/
589 if ($define eq 'DEF');
590 $str = gen_index_id($str, $define);
591 $index{$str} .= $ahref;
592 write_idxfile($ahref, $str);
594 if ($define eq 'DEF') {
595 # add to the module index
596 $str =~ /(<tt.*<\/tt>)/;
598 $Modules{$nstr} .= $ahref;
600 return "$aname$anchor_invisible_mark2</a>";
608 my($word,$name) = @_;
609 my $section_tag = join('', @curr_sec_id);
610 if ($word ne "built-in" && $word ne "extension"
611 && $word ne "standard" && $word ne "") {
612 write_warnings("Bad module type '$word'"
613 . " for \\declaremodule (module $name)");
616 $word = "$word " if $word;
617 $THIS_MODULE = "$name";
618 $INDEX_SUBITEM = "(in module $name)";
620 return make_mod_index_entry(
621 "<tt class='module'>$name</tt> (${word}module)", 'DEF');
624 sub my_module_index_helper{
625 local($word, $_) = @_;
626 my $name = next_argument();
627 return define_module($word, $name) . $_;
630 sub do_cmd_modindex{ return my_module_index_helper('', @_); }
631 sub do_cmd_bimodindex{ return my_module_index_helper('built-in', @_); }
632 sub do_cmd_exmodindex{ return my_module_index_helper('extension', @_); }
633 sub do_cmd_stmodindex{ return my_module_index_helper('standard', @_); }
635 sub ref_module_index_helper{
636 my($word, $ahref) = @_;
637 my $str = next_argument();
638 $word = "$word " if $word;
639 $str = "<tt class='module'>$str</tt> (${word}module)";
640 # can't use add_index_entry() since the 2nd arg to gen_index_id() is used;
641 # just inline it all here
642 $str = gen_index_id($str, 'REF');
643 $index{$str} .= $ahref;
644 write_idxfile($ahref, $str);
647 # these should be adjusted a bit....
648 define_indexing_macro('refmodindex', 'refbimodindex',
649 'refexmodindex', 'refstmodindex');
650 sub idx_cmd_refmodindex{ return ref_module_index_helper('', @_); }
651 sub idx_cmd_refbimodindex{ return ref_module_index_helper('built-in', @_); }
652 sub idx_cmd_refexmodindex{ return ref_module_index_helper('extension', @_); }
653 sub idx_cmd_refstmodindex{ return ref_module_index_helper('standard', @_); }
655 sub do_cmd_nodename{ return do_cmd_label(@_); }
658 $anchor_invisible_mark = ' ';
659 $anchor_invisible_mark2 = '';
661 $icons{'anchor_mark'} = '';
665 # Create an index entry, but include the string in the target anchor
666 # instead of the dummy filler.
668 sub make_str_index_entry{
670 my($name,$aname,$ahref) = new_link_info();
671 add_index_entry($str, $ahref);
672 return "$aname$str</a>";
675 $REFCOUNTS_LOADED = 0;
678 $REFCOUNTS_LOADED = 1;
680 my $myname, $mydir, $myext;
681 ($myname, $mydir, $myext) = fileparse(__FILE__, '\..*');
682 chop $mydir; # remove trailing '/'
683 ($myname, $mydir, $myext) = fileparse($mydir, '\..*');
684 chop $mydir; # remove trailing '/'
685 $mydir = getcwd() . "$dd$mydir"
686 unless $mydir =~ s|^/|/|;
688 my $filename = "$mydir${dd}api${dd}refcounts.dat";
689 open(REFCOUNT_FILE, "<$filename") || die "\n$!\n";
690 print "[loading API refcount data]";
691 while (<REFCOUNT_FILE>) {
692 if (/([a-zA-Z0-9_]+):PyObject\*:([a-zA-Z0-9_]*):(0|[-+]1|null):(.*)$/) {
693 my($func, $param, $count, $comment) = ($1, $2, $3, $4);
694 #print "\n$func($param) --> $count";
695 $REFCOUNTS{"$func:$param"} = $count;
701 my ($func, $param) = @_;
703 unless $REFCOUNTS_LOADED;
704 return $REFCOUNTS{"$func:$param"};
707 sub do_env_cfuncdesc{
709 my $return_type = next_argument();
710 my $function_name = next_argument();
711 my $arg_list = next_argument();
712 my $idx = make_str_index_entry(
713 "<tt class='cfunction'>$function_name()</tt>" . get_indexsubitem());
715 $idx =~ s/\(\)//; # ???? - why both of these?
716 my $result_rc = get_refcount($function_name, '');
718 if ($result_rc eq '+1') {
719 $rcinfo = 'New reference';
721 elsif ($result_rc eq '0') {
722 $rcinfo = 'Borrowed reference';
724 elsif ($result_rc eq 'null') {
725 $rcinfo = 'Always <tt class="constant">NULL</tt>';
728 $rcinfo = ( "\n<div class=\"refcount-info\">"
729 . "\n <span class=\"label\">Return value:</span>"
730 . "\n <span class=\"value\">$rcinfo.</span>"
733 return "<dl><dt>$return_type <b>$idx</b>(<var>$arg_list</var>)\n<dd>"
739 sub do_env_csimplemacrodesc{
741 my $name = next_argument();
742 my $idx = make_str_index_entry("<tt class='macro'>$name</tt>");
743 return "<dl><dt><b>$idx</b>\n<dd>"
748 sub do_env_ctypedesc{
750 my $index_name = next_optional_argument();
751 my $type_name = next_argument();
752 $index_name = $type_name
754 my($name,$aname,$ahref) = new_link_info();
755 add_index_entry("<tt class='ctype'>$index_name</tt> (C type)", $ahref);
756 return "<dl><dt><b><tt class='ctype'>$aname$type_name</a></tt></b>\n<dd>"
763 my $var_type = next_argument();
764 my $var_name = next_argument();
765 my $idx = make_str_index_entry("<tt class='cdata'>$var_name</tt>"
766 . get_indexsubitem());
768 return "<dl><dt>$var_type <b>$idx</b>\n"
775 local($IN_DESC_HANDLER) = 1;
777 return translate_commands($_);
782 my $function_name = next_argument();
783 my $arg_list = convert_args(next_argument());
784 my $idx = make_str_index_entry("<tt class='function'>$function_name()</tt>"
785 . get_indexsubitem());
787 $idx =~ s/\(\)<\/tt>/<\/tt>/;
788 return "<dl><dt><b>$idx</b>(<var>$arg_list</var>)\n<dd>" . $_ . '</dl>';
791 sub do_env_funcdescni{
793 my $function_name = next_argument();
794 my $arg_list = convert_args(next_argument());
795 return "<dl><dt><b><tt class='function'>$function_name</tt></b>"
796 . "(<var>$arg_list</var>)\n"
804 my $function_name = next_argument();
805 my $arg_list = convert_args(next_argument());
806 my $prefix = "<tt class='function'>$function_name()</tt>";
807 my $idx = make_str_index_entry($prefix . get_indexsubitem());
810 return "<dt><b>$prefix</b>(<var>$arg_list</var>)\n<dd>" . $_;
813 sub do_cmd_funclineni{
815 my $function_name = next_argument();
816 my $arg_list = convert_args(next_argument());
817 my $prefix = "<tt class='function'>$function_name</tt>";
819 return "<dt><b>$prefix</b>(<var>$arg_list</var>)\n<dd>" . $_;
822 # Change this flag to index the opcode entries. I don't think it's very
823 # useful to index them, since they're only presented to describe the dis
828 sub do_env_opcodedesc{
830 my $opcode_name = next_argument();
831 my $arg_list = next_argument();
833 if ($INDEX_OPCODES) {
834 $idx = make_str_index_entry("<tt class='opcode'>$opcode_name</tt>"
835 . " (byte code instruction)");
836 $idx =~ s/ \(byte code instruction\)//;
839 $idx = "<tt class='opcode'>$opcode_name</tt>";
841 my $stuff = "<dl><dt><b>$idx</b>";
843 $stuff .= " <var>$arg_list</var>";
845 return $stuff . "\n<dd>" . $_ . '</dl>';
850 my $dataname = next_argument();
851 my $idx = make_str_index_entry("<tt>$dataname</tt>" . get_indexsubitem());
853 return "<dl><dt><b>$idx</b>\n<dd>"
858 sub do_env_datadescni{
860 my $idx = next_argument();
861 if (! $STRING_INDEX_TT) {
862 $idx = "<tt>$idx</tt>";
864 return "<dl><dt><b>$idx</b>\n<dd>" . $_ . '</dl>';
869 my $data_name = next_argument();
870 my $idx = make_str_index_entry("<tt>$data_name</tt>" . get_indexsubitem());
872 return "<dt><b>$idx</b><dd>" . $_;
875 sub do_cmd_datalineni{
877 my $data_name = next_argument();
878 return "<dt><b><tt>$data_name</tt></b><dd>" . $_;
883 my $excname = next_argument();
884 my $idx = make_str_index_entry("<tt class='exception'>$excname</tt>");
885 return "<dl><dt><b>exception $idx</b>\n<dd>" . $_ . '</dl>'
888 sub do_env_fulllineitems{ return do_env_itemize(@_); }
891 sub handle_classlike_descriptor{
892 local($_, $what) = @_;
893 $THIS_CLASS = next_argument();
894 my $arg_list = convert_args(next_argument());
895 $idx = make_str_index_entry(
896 "<tt class='$what'>$THIS_CLASS</tt> ($what in $THIS_MODULE)" );
898 return ("<dl><dt><b>$what $idx</b>(<var>$arg_list</var>)\n<dd>"
903 sub do_env_classdesc{
904 return handle_classlike_descriptor(@_[0], "class");
907 sub do_env_excclassdesc{
908 return handle_classlike_descriptor(@_[0], "exception");
912 sub do_env_methoddesc{
914 my $class_name = next_optional_argument();
915 $class_name = $THIS_CLASS
917 my $method = next_argument();
918 my $arg_list = convert_args(next_argument());
921 $extra = " ($class_name method)";
923 my $idx = make_str_index_entry("<tt class='method'>$method()</tt>$extra");
926 return "<dl><dt><b>$idx</b>(<var>$arg_list</var>)\n<dd>" . $_ . '</dl>';
930 sub do_cmd_methodline{
932 my $class_name = next_optional_argument();
933 $class_name = $THIS_CLASS
935 my $method = next_argument();
936 my $arg_list = convert_args(next_argument());
939 $extra = " ($class_name method)";
941 my $idx = make_str_index_entry("<tt class='method'>$method()</tt>$extra");
944 return "<dt><b>$idx</b>(<var>$arg_list</var>)\n<dd>"
949 sub do_cmd_methodlineni{
951 next_optional_argument();
952 my $method = next_argument();
953 my $arg_list = convert_args(next_argument());
954 return "<dt><b>$method</b>(<var>$arg_list</var>)\n<dd>"
958 sub do_env_methoddescni{
960 next_optional_argument();
961 my $method = next_argument();
962 my $arg_list = convert_args(next_argument());
963 return "<dl><dt><b>$method</b>(<var>$arg_list</var>)\n<dd>"
969 sub do_env_memberdesc{
971 my $class = next_optional_argument();
972 my $member = next_argument();
976 $extra = " ($class attribute)"
978 my $idx = make_str_index_entry("<tt class='member'>$member</tt>$extra");
981 return "<dl><dt><b>$idx</b>\n<dd>" . $_ . '</dl>';
985 sub do_cmd_memberline{
987 my $class = next_optional_argument();
988 my $member = next_argument();
992 $extra = " ($class attribute)"
994 my $idx = make_str_index_entry("<tt class='member'>$member</tt>$extra");
997 return "<dt><b>$idx</b><dd>" . $_;
1000 sub do_env_memberdescni{
1002 next_optional_argument();
1003 my $member = next_argument();
1004 return "<dl><dt><b><tt class='member'>$member</tt></b>\n<dd>"
1010 sub do_cmd_memberlineni{
1012 next_optional_argument();
1013 my $member = next_argument();
1014 return "<dt><b><tt class='member'>$member</tt></b><dd>" . $_;
1017 @col_aligns = ('<td>', '<td>', '<td>', '<td>');
1020 # do a little magic on a font name to get the right behavior in the first
1021 # column of the output table
1023 if ($font eq 'textrm') {
1026 elsif ($font eq 'file' || $font eq 'filenq') {
1027 $font = 'tt class="file"';
1029 elsif ($font eq 'member') {
1030 $font = 'tt class="member"';
1032 elsif ($font eq 'class') {
1033 $font = 'tt class="class"';
1035 elsif ($font eq 'constant') {
1036 $font = 'tt class="constant"';
1038 elsif ($font eq 'kbd') {
1041 elsif ($font eq 'programopt') {
1044 elsif ($font eq 'exception') {
1045 $font = 'tt class="exception"';
1050 sub figure_column_alignment{
1052 my $mark = substr($a, 0, 1);
1055 { $r = ' align="center"'; }
1056 elsif ($mark eq 'r')
1057 { $r = ' align="right"'; }
1058 elsif ($mark eq 'l')
1059 { $r = ' align="left"'; }
1060 elsif ($mark eq 'p')
1061 { $r = ' align="left"'; }
1065 sub setup_column_alignments{
1067 my($s1,$s2,$s3,$s4) = split(/[|]/,$_);
1068 my $a1 = figure_column_alignment($s1);
1069 my $a2 = figure_column_alignment($s2);
1070 my $a3 = figure_column_alignment($s3);
1071 my $a4 = figure_column_alignment($s4);
1072 $col_aligns[0] = "<td$a1 valign=\"baseline\">";
1073 $col_aligns[1] = "<td$a2>";
1074 $col_aligns[2] = "<td$a3>";
1075 $col_aligns[3] = "<td$a4>";
1076 # return the aligned header start tags
1077 return ("<th$a1>", "<th$a2>", "<th$a3>", "<th$a4>");
1080 sub get_table_col1_fonts{
1081 my $font = $globals{'lineifont'};
1082 my ($sfont,$efont) = ('', '');
1085 $efont = "</$font>";
1086 $efont =~ s/ .*>/>/;
1088 return ($sfont, $efont);
1093 my($th1,$th2,$th3,$th4) = setup_column_alignments(next_argument());
1094 my $font = fix_font(next_argument());
1095 my $h1 = next_argument();
1096 my $h2 = next_argument();
1098 $globals{'lineifont'} = $font;
1099 my $a1 = $col_aligns[0];
1100 my $a2 = $col_aligns[1];
1101 s/\\lineii</\\lineii[$a1|$a2]</g;
1102 return '<table border align="center" style="border-collapse: collapse">'
1104 . "\n <tr class=\"tableheader\">"
1105 . "\n $th1<b>$h1</b>\ </th>"
1106 . "\n $th2<b>$h2</b>\ </th>"
1109 . "\n <tbody valign='baseline'>"
1115 sub do_env_longtableii{
1116 return do_env_tableii(@_);
1121 my $aligns = next_optional_argument();
1122 my $c1 = next_argument();
1123 my $c2 = next_argument();
1125 my($sfont,$efont) = get_table_col1_fonts();
1126 $c2 = ' ' if ($c2 eq '');
1127 my($c1align,$c2align) = split('\|', $aligns);
1129 if ($c1align =~ /align="right"/ || $c1 eq '') {
1130 $padding = ' ';
1132 return "\n <tr>$c1align$sfont$c1$efont$padding</td>\n"
1133 . " $c2align$c2</td>"
1137 sub do_env_tableiii{
1139 my($th1,$th2,$th3,$th4) = setup_column_alignments(next_argument());
1140 my $font = fix_font(next_argument());
1141 my $h1 = next_argument();
1142 my $h2 = next_argument();
1143 my $h3 = next_argument();
1145 $globals{'lineifont'} = $font;
1146 my $a1 = $col_aligns[0];
1147 my $a2 = $col_aligns[1];
1148 my $a3 = $col_aligns[2];
1149 s/\\lineiii</\\lineiii[$a1|$a2|$a3]</g;
1150 return '<table border align="center" style="border-collapse: collapse">'
1152 . "\n <tr class=\"tableheader\">"
1153 . "\n $th1<b>$h1</b>\ </th>"
1154 . "\n $th2<b>$h2</b>\ </th>"
1155 . "\n $th3<b>$h3</b>\ </th>"
1158 . "\n <tbody valign='baseline'>"
1164 sub do_env_longtableiii{
1165 return do_env_tableiii(@_);
1170 my $aligns = next_optional_argument();
1171 my $c1 = next_argument();
1172 my $c2 = next_argument();
1173 my $c3 = next_argument();
1175 my($sfont,$efont) = get_table_col1_fonts();
1176 $c3 = ' ' if ($c3 eq '');
1177 my($c1align,$c2align,$c3align) = split('\|', $aligns);
1179 if ($c1align =~ /align="right"/ || $c1 eq '') {
1180 $padding = ' ';
1182 return "\n <tr>$c1align$sfont$c1$efont$padding</td>\n"
1183 . " $c2align$c2</td>\n"
1184 . " $c3align$c3</td>"
1190 my($th1,$th2,$th3,$th4) = setup_column_alignments(next_argument());
1191 my $font = fix_font(next_argument());
1192 my $h1 = next_argument();
1193 my $h2 = next_argument();
1194 my $h3 = next_argument();
1195 my $h4 = next_argument();
1197 $globals{'lineifont'} = $font;
1198 my $a1 = $col_aligns[0];
1199 my $a2 = $col_aligns[1];
1200 my $a3 = $col_aligns[2];
1201 my $a4 = $col_aligns[3];
1202 s/\\lineiv</\\lineiv[$a1|$a2|$a3|$a4]</g;
1203 return '<table border align="center" style="border-collapse: collapse">'
1205 . "\n <tr class=\"tableheader\">"
1206 . "\n $th1<b>$h1</b>\ </th>"
1207 . "\n $th2<b>$h2</b>\ </th>"
1208 . "\n $th3<b>$h3</b>\ </th>"
1209 . "\n $th4<b>$h4</b>\ </th>"
1212 . "\n <tbody valign='baseline'>"
1218 sub do_env_longtableiv{
1219 return do_env_tableiv(@_);
1224 my $aligns = next_optional_argument();
1225 my $c1 = next_argument();
1226 my $c2 = next_argument();
1227 my $c3 = next_argument();
1228 my $c4 = next_argument();
1230 my($sfont,$efont) = get_table_col1_fonts();
1231 $c4 = ' ' if ($c4 eq '');
1232 my($c1align,$c2align,$c3align,$c4align) = split('\|', $aligns);
1234 if ($c1align =~ /align="right"/ || $c1 eq '') {
1235 $padding = ' ';
1237 return "\n <tr>$c1align$sfont$c1$efont$padding</td>\n"
1238 . " $c2align$c2</td>\n"
1239 . " $c3align$c3</td>\n"
1240 . " $c4align$c4</td>"
1245 # These can be used to control the title page appearance;
1246 # they need a little bit of documentation.
1248 # If $TITLE_PAGE_GRAPHIC is set, it should be the name of a file in the
1249 # $ICONSERVER directory, or include path information (other than "./"). The
1250 # default image type will be assumed if an extension is not provided.
1252 # If specified, the "title page" will contain two colums: one containing the
1253 # title/author/etc., and the other containing the graphic. Use the other
1254 # four variables listed here to control specific details of the layout; all
1257 # $TITLE_PAGE_GRAPHIC = "my-company-logo";
1258 # $TITLE_PAGE_GRAPHIC_COLWIDTH = "30%";
1259 # $TITLE_PAGE_GRAPHIC_WIDTH = 150;
1260 # $TITLE_PAGE_GRAPHIC_HEIGHT = 150;
1261 # $TITLE_PAGE_GRAPHIC_ON_RIGHT = 0;
1263 sub make_my_titlepage() {
1266 $the_title .= "\n<h1>$t_title</h1>";
1269 write_warnings("\nThis document has no title.");
1273 my $href = translate_commands($t_authorURL);
1274 $href = make_named_href('author', $href,
1275 "<b><font size='+2'>$t_author</font></b>");
1276 $the_title .= "\n<p>$href</p>";
1279 $the_title .= ("\n<p><b><font size='+2'>$t_author</font></b></p>");
1283 write_warnings("\nThere is no author for this document.");
1286 $the_title .= "\n<p>$t_institute</p>";
1288 if ($DEVELOPER_ADDRESS) {
1289 $the_title .= "\n<p>$DEVELOPER_ADDRESS</p>";
1292 $the_title .= "\n<p><i>$t_affil</i></p>";
1295 $the_title .= "\n<p>";
1296 if ($PACKAGE_VERSION) {
1297 $the_title .= "<strong>Release $PACKAGE_VERSION</strong><br>\n";
1299 $the_title .= "<strong>$t_date</strong></p>"
1302 $the_title .= "\n<p>$t_address</p>";
1305 $the_title .= "\n<p>";
1308 $the_title .= "\n<p>$t_email</p>";
1313 sub make_my_titlegraphic() {
1314 my $filename = make_icon_filename($TITLE_PAGE_GRAPHIC);
1315 my $graphic = "<td class=\"titlegraphic\"";
1316 $graphic .= " width=\"$TITLE_PAGE_GRAPHIC_COLWIDTH\""
1317 if ($TITLE_PAGE_GRAPHIC_COLWIDTH);
1318 $graphic .= "><img";
1319 $graphic .= " width=\"$TITLE_PAGE_GRAPHIC_WIDTH\""
1320 if ($TITLE_PAGE_GRAPHIC_WIDTH);
1321 $graphic .= " height=\"$TITLE_PAGE_GRAPHIC_HEIGHT\""
1322 if ($TITLE_PAGE_GRAPHIC_HEIGHT);
1323 $graphic .= "\n src=\"$filename\"></td>\n";
1327 sub do_cmd_maketitle {
1329 my $the_title = "\n<div class=\"titlepage\">";
1330 if ($TITLE_PAGE_GRAPHIC) {
1331 if ($TITLE_PAGE_GRAPHIC_ON_RIGHT) {
1332 $the_title .= ("\n<table border=\"0\" width=\"100%\">"
1333 . "<tr align=\"right\">\n<td>"
1334 . make_my_titlepage()
1336 . make_my_titlegraphic()
1337 . "</tr>\n</table>");
1340 $the_title .= ("\n<table border=\"0\" width=\"100%\"><tr>\n"
1341 . make_my_titlegraphic()
1343 . make_my_titlepage()
1344 . "</td></tr>\n</table>");
1348 $the_title .= ("\n<center>"
1349 . make_my_titlepage()
1352 $the_title .= "\n</div>";
1353 return $the_title . $_;
1354 $the_title .= "\n</center></div>";
1355 return $the_title . $_ ;
1360 # Module synopsis support
1363 require SynopsisTable;
1365 sub get_chapter_id(){
1366 my $id = do_cmd_thechapter('');
1367 $id =~ s/<SPAN CLASS="arabic">(\d+)<\/SPAN>/\1/;
1372 # 'chapter' => 'SynopsisTable instance'
1373 %ModuleSynopses = ();
1375 sub get_synopsis_table($){
1378 foreach $key (keys %ModuleSynopses) {
1379 if ($key eq $chap) {
1380 return $ModuleSynopses{$chap};
1383 my $st = SynopsisTable->new();
1384 $ModuleSynopses{$chap} = $st;
1388 sub do_cmd_moduleauthor{
1395 sub do_cmd_sectionauthor{
1402 sub do_cmd_declaremodule{
1404 my $key = next_optional_argument();
1405 my $type = next_argument();
1406 my $name = next_argument();
1407 my $st = get_synopsis_table(get_chapter_id());
1409 $key = $name unless $key;
1410 $type = 'built-in' if $type eq 'builtin';
1411 $st->declare($name, $key, $type);
1412 define_module($type, $name);
1413 return anchor_label("module-$key",$CURRENT_FILE,$_)
1416 sub do_cmd_modulesynopsis{
1418 my $st = get_synopsis_table(get_chapter_id());
1419 $st->set_synopsis($THIS_MODULE, translate_commands(next_argument()));
1423 sub do_cmd_localmoduletable{
1425 my $chap = get_chapter_id();
1426 my $st = get_synopsis_table($chap);
1427 $st->set_file("$CURRENT_FILE");
1428 return "<tex2html-localmoduletable><$chap>\\tableofchildlinks[off]" . $_;
1431 sub process_all_localmoduletables{
1434 foreach $key (keys %ModuleSynopses) {
1435 $st = $ModuleSynopses{$key};
1436 $file = $st->get_file();
1438 process_localmoduletables_in_file($file);
1441 print "\nsynopsis table $key has no file association";
1446 sub process_localmoduletables_in_file{
1448 open(MYFILE, "<$file");
1450 sysread(MYFILE, $_, 1024*1024);
1452 # need to get contents of file in $_
1453 while (/<tex2html-localmoduletable><(\d+)>/) {
1456 my $st = get_synopsis_table($chap);
1457 my $data = $st->tohtml();
1460 open(MYFILE,">$file");
1464 sub process_python_state{
1465 process_all_localmoduletables();
1470 # "See also:" -- references placed at the end of a \section
1474 return "<div class='seealso'>\n "
1475 . "<p class='heading'><b>See Also:</b></p>\n"
1480 sub do_cmd_seemodule{
1481 # Insert the right magic to jump to the module definition. This should
1482 # work most of the time, at least for repeat builds....
1484 my $key = next_optional_argument();
1485 my $module = next_argument();
1486 my $text = next_argument();
1490 if ($text =~ /\.$/) {
1493 return '<dl compact class="seemodule">'
1494 . "\n <dt>Module <b><tt class='module'><a href='module-$key.html'>"
1495 . "$module</a></tt>:</b>"
1496 . "\n <dd>$text$period\n </dl>"
1500 sub strip_html_markup($){
1503 $s =~ s/<[a-zA-Z0-9]+(\s+[a-zA-Z0-9]+(\s*=\s*(\'[^\']*\'|\"[^\"]*\"|[a-zA-Z0-9]+))?)*\s*>//g;
1504 $s =~ s/<\/[a-zA-Z0-9]+>//g;
1508 sub handle_rfclike_reference{
1509 local($_, $what, $format) = @_;
1510 my $rfcnum = next_argument();
1511 my $title = next_argument();
1512 my $text = next_argument();
1513 my $url = get_rfc_url($rfcnum, $format);
1514 my $icon = get_link_icon($url);
1515 my $attrtitle = strip_html_markup($title);
1516 return '<dl compact class="seerfc">'
1517 . "\n <dt><a href=\"$url\""
1518 . "\n title=\"$attrtitle\""
1519 . "\n >$what $rfcnum, <em>$title</em>$icon</a>"
1520 . "\n <dd>$text\n </dl>"
1525 return handle_rfclike_reference(@_[0], "PEP", $PEP_FORMAT);
1529 return handle_rfclike_reference(@_[0], "RFC", $RFC_FORMAT);
1532 sub do_cmd_seetitle{
1534 my $url = next_optional_argument();
1535 my $title = next_argument();
1536 my $text = next_argument();
1538 my $icon = get_link_icon($url);
1539 return '<dl compact class="seetitle">'
1540 . "\n <dt><em class=\"citetitle\"><a href=\"$url\""
1541 . "\n >$title$icon</a></em>"
1542 . "\n <dd>$text\n </dl>"
1545 return '<dl compact class="seetitle">'
1546 . "\n <dt><em class=\"citetitle\""
1548 . "\n <dd>$text\n </dl>"
1554 my $url = next_argument();
1555 my $text = next_argument();
1556 my $icon = get_link_icon($url);
1557 return '<dl compact class="seeurl">'
1558 . "\n <dt><a href=\"$url\""
1559 . "\n class=\"url\">$url$icon</a>"
1560 . "\n <dd>$text\n </dl>"
1566 my $content = next_argument();
1567 return '<div class="seetext"><p>' . $content . '</div>' . $_;
1572 # Definition list support.
1575 sub do_env_definitions{
1576 return "<dl class='definitions'>" . @_[0] . "</dl>\n";
1581 my $term = next_argument();
1582 my($name,$aname,$ahref) = new_link_info();
1583 # could easily add an index entry here...
1584 return "<dt><b>$aname" . $term . "</a></b>\n<dd>" . $_;
1588 # I don't recall exactly why this was needed, but it was very much needed.
1589 # We'll see if anything breaks when I move the "code" line out -- some
1590 # things broke with it in.
1593 process_commands_wrap_deferred(<<_RAW_ARG_DEFERRED_CMDS_);
1594 declaremodule # [] # {} # {}
1595 memberline # [] # {}
1596 methodline # [] # {} # {}
1600 setindexsubitem # {}
1601 withsubitem # {} # {}
1602 _RAW_ARG_DEFERRED_CMDS_
1605 $alltt_start = '<dl><dd><pre class="verbatim">';
1606 $alltt_end = '</pre></dl>';
1610 local($closures,$reopens,@open_block_tags);
1612 # get the tag-strings for all open tags
1613 local(@keep_open_tags) = @$open_tags_R;
1614 ($closures,$reopens) = &preserve_open_tags() if (@$open_tags_R);
1616 # get the tags for text-level tags only
1617 $open_tags_R = [ @keep_open_tags ];
1618 local($local_closures, $local_reopens);
1619 ($local_closures, $local_reopens,@open_block_tags)
1620 = &preserve_open_block_tags
1623 $open_tags_R = [ @open_block_tags ];
1626 local($open_tags_R) = [ @open_block_tags ];
1627 local(@save_open_tags) = ();
1629 local($cnt) = ++$global{'max_id'};
1630 $_ = join('',"$O$cnt$C\\tt$O", ++$global{'max_id'}, $C
1631 , $_ , $O, $global{'max_id'}, "$C$O$cnt$C");
1633 $_ = &translate_environments($_);
1634 $_ = &translate_commands($_) if (/\\/);
1636 # preserve space-runs, using
1637 while (s/(\S) ( +)/$1$2;SPMnbsp;/g){};
1638 s/(<BR>) /$1;SPMnbsp;/g;
1640 $_ = join('', $closures, $alltt_start, $local_reopens
1642 , &balance_tags() #, $local_closures
1643 , $alltt_end, $reopens);
1644 undef $open_tags_R; undef @save_open_tags;
1646 $open_tags_R = [ @keep_open_tags ];
1651 1; # This must be the last line