Initial import to Tizen
[profile/ivi/python-pyOpenSSL.git] / doc / tools / perl / python.perl
1 # python.perl by Fred L. Drake, Jr. <fdrake@acm.org>            -*- perl -*-
2 #
3 # Heavily based on Guido van Rossum's myformat.perl (now obsolete).
4 #
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.
8
9 package main;
10
11 use File::Basename;
12
13
14 sub next_argument{
15     my $param;
16     $param = missing_braces()
17       unless ((s/$next_pair_pr_rx/$param=$2;''/eo)
18               ||(s/$next_pair_rx/$param=$2;''/eo));
19     return $param;
20 }
21
22 sub next_optional_argument{
23     my($param,$rx) = ('', "^\\s*(\\[([^]]*)\\])?");
24     s/$rx/$param=$2;''/eo;
25     return $param;
26 }
27
28 sub make_icon_filename($){
29     my($myname, $mydir, $myext) = fileparse(@_[0], '\..*');
30     chop $mydir;
31     if ($mydir eq '.') {
32         $mydir = $ICONSERVER;
33     }
34     $myext = ".$IMAGE_TYPE"
35       unless $myext;
36     return "$mydir$dd$myname$myext";
37 }
38
39 sub get_link_icon($){
40     my $url = @_[0];
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'"
48                    : '')
49                 . ($OFF_SITE_LINK_ICON_WIDTH
50                    ? " width='$OFF_SITE_LINK_ICON_WIDTH'"
51                    : '')
52                 . " alt='[off-site link]'\n"
53                 . "  >");
54     }
55     return '';
56 }
57
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.
61 #
62 sub do_cmd_let{
63     local($_) = @_;
64     my $matched = 0;
65     s/[\\]([a-zA-Z]+)\s*(=\s*)?[\\]([a-zA-Z]*)/$matched=1; ''/e;
66     if ($matched) {
67         my($new, $old) = ($1, $3);
68         eval "sub do_cmd_$new { do_cmd_$old" . '(@_); }';
69         print "\ndefining handler for \\$new using \\$old\n";
70     }
71     else {
72         s/[\\]([a-zA-Z]+)\s*(=\s*)?([^\\])/$matched=1; ''/es;
73         if ($matched) {
74             my($new, $char) = ($1, $3);
75             eval "sub do_cmd_$new { \"\\$char\" . \@_[0]; }";
76             print "\ndefining handler for \\$new to insert '$char'\n";
77         }
78         else {
79             write_warnings("Could not interpret \\let construct...");
80         }
81     }
82     return $_;
83 }
84
85
86 # the older version of LaTeX2HTML we use doesn't support this, but we use it:
87
88 sub do_cmd_textasciitilde{ '~' . @_[0]; }
89
90
91 # words typeset in a special way (not in HTML though)
92
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]; }
101
102 sub do_cmd_e{ '&#92;' . @_[0]; }
103
104 $DEVELOPER_ADDRESS = '';
105 $SHORT_VERSION = '';
106 $PACKAGE_VERSION = '';
107
108 sub do_cmd_version{ $PACKAGE_VERSION . @_[0]; }
109 sub do_cmd_shortversion{ $SHORT_VERSION . @_[0]; }
110 sub do_cmd_release{
111     local($_) = @_;
112     $PACKAGE_VERSION = next_argument();
113     return $_;
114 }
115
116 sub do_cmd_setshortversion{
117     local($_) = @_;
118     $SHORT_VERSION = next_argument();
119     return $_;
120 }
121
122 sub do_cmd_authoraddress{
123     local($_) = @_;
124     $DEVELOPER_ADDRESS = next_argument();
125     return $_;
126 }
127
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]); }
131
132 sub do_cmd_hackscore{
133     local($_) = @_;
134     next_argument();
135     return '_' . $_;
136 }
137
138 sub use_wrappers{
139     local($_,$before,$after) = @_;
140     my $stuff = next_argument();
141     return $before . $stuff . $after . $_;
142 }
143
144 $IN_DESC_HANDLER = 0;
145 sub do_cmd_optional{
146     if ($IN_DESC_HANDLER) {
147         return use_wrappers(@_[0], "</var><big>\[</big><var>",
148                             "</var><big>\]</big><var>");
149     }
150     else {
151         return use_wrappers(@_[0], "<big>\[</big>", "<big>\]</big>");
152     }
153 }
154
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.
159
160 # \file and \samp are at the end of this file since they screw up fontlock.
161
162 sub do_cmd_pytype{ return @_[0]; }
163 sub do_cmd_makevar{
164     return use_wrappers(@_[0], '<span class="makevar">', '</span>'); }
165 sub do_cmd_code{
166     return use_wrappers(@_[0], '<code>', '</code>'); }
167 sub do_cmd_module{
168     return use_wrappers(@_[0], '<tt class="module">', '</tt>'); }
169 sub do_cmd_keyword{
170     return use_wrappers(@_[0], '<tt class="keyword">', '</tt>'); }
171 sub do_cmd_exception{
172     return use_wrappers(@_[0], '<tt class="exception">', '</tt>'); }
173 sub do_cmd_class{
174     return use_wrappers(@_[0], '<tt class="class">', '</tt>'); }
175 sub do_cmd_function{
176     return use_wrappers(@_[0], '<tt class="function">', '</tt>'); }
177 sub do_cmd_constant{
178     return use_wrappers(@_[0], '<tt class="constant">', '</tt>'); }
179 sub do_cmd_member{
180     return use_wrappers(@_[0], '<tt class="member">', '</tt>'); }
181 sub do_cmd_method{
182     return use_wrappers(@_[0], '<tt class="method">', '</tt>'); }
183 sub do_cmd_cfunction{
184     return use_wrappers(@_[0], '<tt class="cfunction">', '</tt>'); }
185 sub do_cmd_cdata{
186     return use_wrappers(@_[0], '<tt class="cdata">', '</tt>'); }
187 sub do_cmd_ctype{
188     return use_wrappers(@_[0], '<tt class="ctype">', '</tt>'); }
189 sub do_cmd_regexp{
190     return use_wrappers(@_[0], '<tt class="regexp">', '</tt>'); }
191 sub do_cmd_character{
192     return use_wrappers(@_[0], '"<tt class="character">', '</tt>"'); }
193 sub do_cmd_program{
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>'); }
200 sub do_cmd_email{
201     return use_wrappers(@_[0], '<span class="email">', '</span>'); }
202 sub do_cmd_mimetype{
203     return use_wrappers(@_[0], '<span class="mimetype">', '</span>'); }
204 sub do_cmd_var{
205     return use_wrappers(@_[0], "<var>", "</var>"); }
206 sub do_cmd_dfn{
207     return use_wrappers(@_[0], '<i class="dfn">', '</i>'); }
208 sub do_cmd_emph{
209     return use_wrappers(@_[0], '<i>', '</i>'); }
210 sub do_cmd_file{
211     return use_wrappers(@_[0], '<span class="file">', '</span>'); }
212 sub do_cmd_filenq{
213     return do_cmd_file(@_[0]); }
214 sub do_cmd_samp{
215     return use_wrappers(@_[0], '"<tt class="samp">', '</tt>"'); }
216 sub do_cmd_kbd{
217     return use_wrappers(@_[0], '<kbd>', '</kbd>'); }
218 sub do_cmd_strong{
219     return use_wrappers(@_[0], '<b>', '</b>'); }
220 sub do_cmd_textbf{
221     return use_wrappers(@_[0], '<b>', '</b>'); }
222 sub do_cmd_textit{
223     return use_wrappers(@_[0], '<i>', '</i>'); }
224
225 sub do_cmd_moreargs{
226     return '...' . @_[0]; }
227 sub do_cmd_unspecified{
228     return '...' . @_[0]; }
229
230
231 sub do_cmd_refmodule{
232     # Insert the right magic to jump to the module definition.
233     local($_) = @_;
234     my $key = next_optional_argument();
235     my $module = next_argument();
236     $key = $module
237         unless $key;
238     return "<tt class='module'><a href='module-$key.html'>$module</a></tt>"
239       . $_;
240 }
241
242 sub do_cmd_newsgroup{
243     local($_) = @_;
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>";
248     return $stuff . $_;
249 }
250
251 sub do_cmd_envvar{
252     local($_) = @_;
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>",
258                     $ahref);
259     add_index_entry("$envvar (environment variable)", $ahref);
260     $aname =~ s/<a/<a class="envvar"/;
261     return "$aname$envvar</a>" . $_;
262 }
263
264 sub do_cmd_url{
265     # use the URL as both text and hyperlink
266     local($_) = @_;
267     my $url = next_argument();
268     my $icon = get_link_icon($url);
269     $url =~ s/~/&#126;/g;
270     return "<a class=\"url\" href=\"$url\">$url$icon</a>" . $_;
271 }
272
273 sub do_cmd_manpage{
274     # two parameters:  \manpage{name}{section}
275     local($_) = @_;
276     my $page = next_argument();
277     my $section = next_argument();
278     return "<span class='manpage'><i>$page</i>($section)</span>" . $_;
279 }
280
281 $PEP_FORMAT = "http://python.sourceforge.net/peps/pep-XXXX.html";
282 $RFC_FORMAT = "http://www.ietf.org/rfc/rfcXXXX.txt";
283
284 sub get_rfc_url($$){
285     my($rfcnum, $format) = @_;
286     $rfcnum = sprintf("%04d", $rfcnum);
287     $format = "$format";
288     $format =~ s/XXXX/$rfcnum/;
289     return $format;
290 }
291
292 sub do_cmd_pep{
293     local($_) = @_;
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);
298     # Save the reference
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"
302             . "$icon</a>" . $_);
303 }
304
305 sub do_cmd_rfc{
306     local($_) = @_;
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);
311     # Save the reference
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"
315             . "$icon</a>" . $_);
316 }
317
318 sub do_cmd_citetitle{
319     local($_) = @_;
320     my $url = next_optional_argument();
321     my $title = next_argument();
322     my $icon = get_link_icon($url);
323     my $repl = '';
324     if ($url) {
325         $repl = ("<em class='citetitle'><a\n"
326                  . " href='$url'\n"
327                  . " title='$title'\n"
328                  . " >$title$icon</a></em>");
329     }
330     else {
331         $repl = "<em class='citetitle'\n >$title</em>";
332     }
333     return $repl . $_;
334 }
335
336 sub do_cmd_deprecated{
337     # two parameters:  \deprecated{version}{whattodo}
338     local($_) = @_;
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>"
344             . $_);
345 }
346
347 sub do_cmd_versionadded{
348     # one parameter:  \versionadded{version}
349     local($_) = @_;
350     my $release = next_argument();
351     return ("\n<span class='versionnote'>New in version $release.</span>\n"
352             . $_);
353 }
354
355 sub do_cmd_versionchanged{
356     # one parameter:  \versionchanged{version}
357     local($_) = @_;
358     my $explanation = next_optional_argument();
359     my $release = next_argument();
360     my $text = "Changed in version $release.";
361     if ($explanation) {
362         $text = "Changed in version $release:\n$explanation.";
363     }
364     return "\n<span class='versionnote'>$text</span>\n" . $_;
365 }
366
367 #
368 # These function handle platform dependency tracking.
369 #
370 sub do_cmd_platform{
371     local($_) = @_;
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" . $_;
378 }
379
380 $IGNORE_PLATFORM_ANNOTATION = '';
381 sub do_cmd_ignorePlatformAnnotation{
382     local($_) = @_;
383     $IGNORE_PLATFORM_ANNOTATION = next_argument();
384     return $_;
385 }
386
387
388 # index commands
389
390 $INDEX_SUBITEM = "";
391
392 sub get_indexsubitem{
393     return $INDEX_SUBITEM ? " $INDEX_SUBITEM" : '';
394 }
395
396 sub do_cmd_setindexsubitem{
397     local($_) = @_;
398     $INDEX_SUBITEM = next_argument();
399     return $_;
400 }
401
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.
406     #
407     local($_) = @_;
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";
413     return
414       $stuff
415       . "\\setindexsubitem$marker$oldsubitem$marker"
416       . $_;
417 }
418
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.)
422 #
423 sub do_cmd_makemodindex{ return @_[0]; }
424
425 # We're in the document subdirectory when this happens!
426 #
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";
431
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!
434 #
435 $IDXFILE_FIELD_SEP = "\1";
436
437 sub write_idxfile{
438     my ($ahref, $str) = @_;
439     print IDXFILE $ahref, $IDXFILE_FIELD_SEP, $str, "\n";
440 }
441
442
443 sub gen_link{
444     my($node,$target) = @_;
445     print INTLABELS "\$internal_labels{\"$target\"} = \"$URL/$node\";\n";
446     return "<a href='$node#$target'>";
447 }
448
449 sub add_index_entry{
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);
455 }
456
457 sub new_link_info{
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);
462 }
463
464 $IndexMacroPattern = '';
465 sub define_indexing_macro{
466     my $count = @_;
467     my $i = 0;
468     for (; $i < $count; ++$i) {
469         my $name = @_[$i];
470         my $cmd = "idx_cmd_$name";
471         die "\nNo function $cmd() defined!\n"
472           if (!defined &$cmd);
473         eval ("sub do_cmd_$name { return process_index_macros("
474               . "\@_[0], '$name'); }");
475         if (length($IndexMacroPattern) == 0) {
476             $IndexMacroPattern = "$name";
477         }
478         else {
479             $IndexMacroPattern .= "|$name";
480         }
481     }
482 }
483
484 $DEBUG_INDEXING = 0;
485 sub process_index_macros{
486     local($_) = @_;
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"
492       if $DEBUG_INDEXING;
493     &$cmd($ahref);              # modifies $_ and adds index entries
494     while (/^[\s\n]*\\($IndexMacroPattern)</) {
495         $cmdname = "$1";
496         print " \\$cmdname"
497           if $DEBUG_INDEXING;
498         $cmd = "idx_cmd_$cmdname";
499         if (!defined &$cmd) {
500             last;
501         }
502         else {
503             s/^[\s\n]*\\$cmdname//;
504             &$cmd($ahref);
505         }
506     }
507     if (/^[ \t\r\n]/) {
508         $_ = substr($_, 1);
509     }
510     return "$aname$anchor_invisible_mark</a>" . $_;
511 }
512
513 define_indexing_macro('index');
514 sub idx_cmd_index{
515     my $str = next_argument();
516     add_index_entry("$str", @_[0]);
517 }
518
519 define_indexing_macro('kwindex');
520 sub idx_cmd_kwindex{
521     my $str = next_argument();
522     add_index_entry("<tt>$str</tt>!keyword", @_[0]);
523     add_index_entry("keyword!<tt>$str</tt>", @_[0]);
524 }
525
526 define_indexing_macro('indexii');
527 sub idx_cmd_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]);
532 }
533
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]);
542 }
543
544 define_indexing_macro('indexiv');
545 sub idx_cmd_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]);
554 }
555
556 define_indexing_macro('ttindex');
557 sub idx_cmd_ttindex{
558     my $str = next_argument();
559     my $entry = $str . get_indexsubitem();
560     add_index_entry($entry, @_[0]);
561 }
562
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);
568 }
569
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]); }
575
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)",
580                     @_[0]);
581 }
582
583
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);
593
594     if ($define eq 'DEF') {
595         # add to the module index
596         $str =~ /(<tt.*<\/tt>)/;
597         my $nstr = $1;
598         $Modules{$nstr} .= $ahref;
599     }
600     return "$aname$anchor_invisible_mark2</a>";
601 }
602
603
604 $THIS_MODULE = '';
605 $THIS_CLASS = '';
606
607 sub define_module{
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)");
614         $word = "";
615     }
616     $word = "$word " if $word;
617     $THIS_MODULE = "$name";
618     $INDEX_SUBITEM = "(in module $name)";
619     print "[$name]";
620     return make_mod_index_entry(
621         "<tt class='module'>$name</tt> (${word}module)", 'DEF');
622 }
623
624 sub my_module_index_helper{
625     local($word, $_) = @_;
626     my $name = next_argument();
627     return define_module($word, $name) . $_;
628 }
629
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', @_); }
634
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);
645 }
646
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', @_); }
654
655 sub do_cmd_nodename{ return do_cmd_label(@_); }
656
657 sub init_myformat{
658     $anchor_invisible_mark = '&nbsp;';
659     $anchor_invisible_mark2 = '';
660     $anchor_mark = '';
661     $icons{'anchor_mark'} = '';
662 }
663 init_myformat();
664
665 # Create an index entry, but include the string in the target anchor
666 # instead of the dummy filler.
667 #
668 sub make_str_index_entry{
669     my($str) = @_;
670     my($name,$aname,$ahref) = new_link_info();
671     add_index_entry($str, $ahref);
672     return "$aname$str</a>";
673 }
674
675 $REFCOUNTS_LOADED = 0;
676
677 sub load_refcounts{
678     $REFCOUNTS_LOADED = 1;
679
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|^/|/|;
687     local $_;
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;
696         }
697     }
698 }
699
700 sub get_refcount{
701     my ($func, $param) = @_;
702     load_refcounts()
703         unless $REFCOUNTS_LOADED;
704     return $REFCOUNTS{"$func:$param"};
705 }
706
707 sub do_env_cfuncdesc{
708     local($_) = @_;
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());
714     $idx =~ s/ \(.*\)//;
715     $idx =~ s/\(\)//;           # ???? - why both of these?
716     my $result_rc = get_refcount($function_name, '');
717     my $rcinfo = '';
718     if ($result_rc eq '+1') {
719         $rcinfo = 'New reference';
720     }
721     elsif ($result_rc eq '0') {
722         $rcinfo = 'Borrowed reference';
723     }
724     elsif ($result_rc eq 'null') {
725         $rcinfo = 'Always <tt class="constant">NULL</tt>';
726     }
727     if ($rcinfo ne '') {
728         $rcinfo = (  "\n<div class=\"refcount-info\">"
729                    . "\n  <span class=\"label\">Return value:</span>"
730                    . "\n  <span class=\"value\">$rcinfo.</span>"
731                    . "\n</div>");
732     }
733     return "<dl><dt>$return_type <b>$idx</b>(<var>$arg_list</var>)\n<dd>"
734            . $rcinfo
735            . $_
736            . '</dl>';
737 }
738
739 sub do_env_csimplemacrodesc{
740     local($_) = @_;
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>"
744            . $_
745            . '</dl>'
746 }
747
748 sub do_env_ctypedesc{
749     local($_) = @_;
750     my $index_name = next_optional_argument();
751     my $type_name = next_argument();
752     $index_name = $type_name
753       unless $index_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>"
757            . $_
758            . '</dl>'
759 }
760
761 sub do_env_cvardesc{
762     local($_) = @_;
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());
767     $idx =~ s/ \(.*\)//;
768     return "<dl><dt>$var_type <b>$idx</b>\n"
769            . '<dd>'
770            . $_
771            . '</dl>';
772 }
773
774 sub convert_args($){
775     local($IN_DESC_HANDLER) = 1;
776     local($_) = @_;
777     return translate_commands($_);
778 }
779
780 sub do_env_funcdesc{
781     local($_) = @_;
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());
786     $idx =~ s/ \(.*\)//;
787     $idx =~ s/\(\)<\/tt>/<\/tt>/;
788     return "<dl><dt><b>$idx</b>(<var>$arg_list</var>)\n<dd>" . $_ . '</dl>';
789 }
790
791 sub do_env_funcdescni{
792     local($_) = @_;
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"
797       . '<dd>'
798       . $_
799       . '</dl>';
800 }
801
802 sub do_cmd_funcline{
803     local($_) = @_;
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());
808     $prefix =~ s/\(\)//;
809
810     return "<dt><b>$prefix</b>(<var>$arg_list</var>)\n<dd>" . $_;
811 }
812
813 sub do_cmd_funclineni{
814     local($_) = @_;
815     my $function_name = next_argument();
816     my $arg_list = convert_args(next_argument());
817     my $prefix = "<tt class='function'>$function_name</tt>";
818
819     return "<dt><b>$prefix</b>(<var>$arg_list</var>)\n<dd>" . $_;
820 }
821
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
824 # module.
825 #
826 $INDEX_OPCODES = 0;
827
828 sub do_env_opcodedesc{
829     local($_) = @_;
830     my $opcode_name = next_argument();
831     my $arg_list = next_argument();
832     my $idx;
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\)//;
837     }
838     else {
839         $idx = "<tt class='opcode'>$opcode_name</tt>";
840     }
841     my $stuff = "<dl><dt><b>$idx</b>";
842     if ($arg_list) {
843         $stuff .= "&nbsp;&nbsp;&nbsp;&nbsp;<var>$arg_list</var>";
844     }
845     return $stuff . "\n<dd>" . $_ . '</dl>';
846 }
847
848 sub do_env_datadesc{
849     local($_) = @_;
850     my $dataname = next_argument();
851     my $idx = make_str_index_entry("<tt>$dataname</tt>" . get_indexsubitem());
852     $idx =~ s/ \(.*\)//;
853     return "<dl><dt><b>$idx</b>\n<dd>"
854            . $_
855            . '</dl>';
856 }
857
858 sub do_env_datadescni{
859     local($_) = @_;
860     my $idx = next_argument();
861     if (! $STRING_INDEX_TT) {
862         $idx = "<tt>$idx</tt>";
863     }
864     return "<dl><dt><b>$idx</b>\n<dd>" . $_ . '</dl>';
865 }
866
867 sub do_cmd_dataline{
868     local($_) = @_;
869     my $data_name = next_argument();
870     my $idx = make_str_index_entry("<tt>$data_name</tt>" . get_indexsubitem());
871     $idx =~ s/ \(.*\)//;
872     return "<dt><b>$idx</b><dd>" . $_;
873 }
874
875 sub do_cmd_datalineni{
876     local($_) = @_;
877     my $data_name = next_argument();
878     return "<dt><b><tt>$data_name</tt></b><dd>" . $_;
879 }
880
881 sub do_env_excdesc{
882     local($_) = @_;
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>'
886 }
887
888 sub do_env_fulllineitems{ return do_env_itemize(@_); }
889
890
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)" );
897     $idx =~ s/ \(.*\)//;
898     return ("<dl><dt><b>$what $idx</b>(<var>$arg_list</var>)\n<dd>"
899             . $_
900             . '</dl>');
901 }
902
903 sub do_env_classdesc{
904     return handle_classlike_descriptor(@_[0], "class");
905 }
906
907 sub do_env_excclassdesc{
908     return handle_classlike_descriptor(@_[0], "exception");
909 }
910
911
912 sub do_env_methoddesc{
913     local($_) = @_;
914     my $class_name = next_optional_argument();
915     $class_name = $THIS_CLASS
916         unless $class_name;
917     my $method = next_argument();
918     my $arg_list = convert_args(next_argument());
919     my $extra = '';
920     if ($class_name) {
921         $extra = " ($class_name method)";
922     }
923     my $idx = make_str_index_entry("<tt class='method'>$method()</tt>$extra");
924     $idx =~ s/ \(.*\)//;
925     $idx =~ s/\(\)//;
926     return "<dl><dt><b>$idx</b>(<var>$arg_list</var>)\n<dd>" . $_ . '</dl>';
927 }
928
929
930 sub do_cmd_methodline{
931     local($_) = @_;
932     my $class_name = next_optional_argument();
933     $class_name = $THIS_CLASS
934         unless $class_name;
935     my $method = next_argument();
936     my $arg_list = convert_args(next_argument());
937     my $extra = '';
938     if ($class_name) {
939         $extra = " ($class_name method)";
940     }
941     my $idx = make_str_index_entry("<tt class='method'>$method()</tt>$extra");
942     $idx =~ s/ \(.*\)//;
943     $idx =~ s/\(\)//;
944     return "<dt><b>$idx</b>(<var>$arg_list</var>)\n<dd>"
945            . $_;
946 }
947
948
949 sub do_cmd_methodlineni{
950     local($_) = @_;
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>"
955            . $_;
956 }
957
958 sub do_env_methoddescni{
959     local($_) = @_;
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>"
964            . $_
965            . '</dl>';
966 }
967
968
969 sub do_env_memberdesc{
970     local($_) = @_;
971     my $class = next_optional_argument();
972     my $member = next_argument();
973     $class = $THIS_CLASS
974         unless $class;
975     my $extra = '';
976     $extra = " ($class attribute)"
977         if ($class ne '');
978     my $idx = make_str_index_entry("<tt class='member'>$member</tt>$extra");
979     $idx =~ s/ \(.*\)//;
980     $idx =~ s/\(\)//;
981     return "<dl><dt><b>$idx</b>\n<dd>" . $_ . '</dl>';
982 }
983
984
985 sub do_cmd_memberline{
986     local($_) = @_;
987     my $class = next_optional_argument();
988     my $member = next_argument();
989     $class = $THIS_CLASS
990         unless $class;
991     my $extra = '';
992     $extra = " ($class attribute)"
993         if ($class ne '');
994     my $idx = make_str_index_entry("<tt class='member'>$member</tt>$extra");
995     $idx =~ s/ \(.*\)//;
996     $idx =~ s/\(\)//;
997     return "<dt><b>$idx</b><dd>" . $_;
998 }
999
1000 sub do_env_memberdescni{
1001     local($_) = @_;
1002     next_optional_argument();
1003     my $member = next_argument();
1004     return "<dl><dt><b><tt class='member'>$member</tt></b>\n<dd>"
1005            . $_
1006            . '</dl>';
1007 }
1008
1009
1010 sub do_cmd_memberlineni{
1011     local($_) = @_;
1012     next_optional_argument();
1013     my $member = next_argument();
1014     return "<dt><b><tt class='member'>$member</tt></b><dd>" . $_;
1015 }
1016
1017 @col_aligns = ('<td>', '<td>', '<td>', '<td>');
1018
1019 sub fix_font{
1020     # do a little magic on a font name to get the right behavior in the first
1021     # column of the output table
1022     my $font = @_[0];
1023     if ($font eq 'textrm') {
1024         $font = '';
1025     }
1026     elsif ($font eq 'file' || $font eq 'filenq') {
1027         $font = 'tt class="file"';
1028     }
1029     elsif ($font eq 'member') {
1030         $font = 'tt class="member"';
1031     }
1032     elsif ($font eq 'class') {
1033         $font = 'tt class="class"';
1034     }
1035     elsif ($font eq 'constant') {
1036         $font = 'tt class="constant"';
1037     }
1038     elsif ($font eq 'kbd') {
1039         $font = 'kbd';
1040     }
1041     elsif ($font eq 'programopt') {
1042         $font = 'b';
1043     }
1044     elsif ($font eq 'exception') {
1045         $font = 'tt class="exception"';
1046     }
1047     return $font;
1048 }
1049
1050 sub figure_column_alignment{
1051     my $a = @_[0];
1052     my $mark = substr($a, 0, 1);
1053     my $r = '';
1054     if ($mark eq 'c')
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"'; }
1062     return $r;
1063 }
1064
1065 sub setup_column_alignments{
1066     local($_) = @_;
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>");
1078 }
1079
1080 sub get_table_col1_fonts{
1081     my $font = $globals{'lineifont'};
1082     my ($sfont,$efont) = ('', '');
1083     if ($font) {
1084         $sfont = "<$font>";
1085         $efont = "</$font>";
1086         $efont =~ s/ .*>/>/;
1087     }
1088     return ($sfont, $efont);
1089 }
1090
1091 sub do_env_tableii{
1092     local($_) = @_;
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();
1097     s/[\s\n]+//;
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">'
1103            . "\n  <thead>"
1104            . "\n    <tr class=\"tableheader\">"
1105            . "\n      $th1<b>$h1</b>\&nbsp;</th>"
1106            . "\n      $th2<b>$h2</b>\&nbsp;</th>"
1107            . "\n      </tr>"
1108            . "\n    </thead>"
1109            . "\n  <tbody valign='baseline'>"
1110            . $_
1111            . "\n    </tbody>"
1112            . "\n</table>";
1113 }
1114
1115 sub do_env_longtableii{
1116     return do_env_tableii(@_);
1117 }
1118
1119 sub do_cmd_lineii{
1120     local($_) = @_;
1121     my $aligns = next_optional_argument();
1122     my $c1 = next_argument();
1123     my $c2 = next_argument();
1124     s/[\s\n]+//;
1125     my($sfont,$efont) = get_table_col1_fonts();
1126     $c2 = '&nbsp;' if ($c2 eq '');
1127     my($c1align,$c2align) = split('\|', $aligns);
1128     my $padding = '';
1129     if ($c1align =~ /align="right"/ || $c1 eq '') {
1130         $padding = '&nbsp;';
1131     }
1132     return "\n    <tr>$c1align$sfont$c1$efont$padding</td>\n"
1133            . "        $c2align$c2</td>"
1134            . $_;
1135 }
1136
1137 sub do_env_tableiii{
1138     local($_) = @_;
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();
1144     s/[\s\n]+//;
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">'
1151            . "\n  <thead>"
1152            . "\n    <tr class=\"tableheader\">"
1153            . "\n      $th1<b>$h1</b>\&nbsp;</th>"
1154            . "\n      $th2<b>$h2</b>\&nbsp;</th>"
1155            . "\n      $th3<b>$h3</b>\&nbsp;</th>"
1156            . "\n      </tr>"
1157            . "\n    </thead>"
1158            . "\n  <tbody valign='baseline'>"
1159            . $_
1160            . "\n    </tbody>"
1161            . "\n</table>";
1162 }
1163
1164 sub do_env_longtableiii{
1165     return do_env_tableiii(@_);
1166 }
1167
1168 sub do_cmd_lineiii{
1169     local($_) = @_;
1170     my $aligns = next_optional_argument();
1171     my $c1 = next_argument();
1172     my $c2 = next_argument(); 
1173     my $c3 = next_argument();
1174     s/[\s\n]+//;
1175     my($sfont,$efont) = get_table_col1_fonts();
1176     $c3 = '&nbsp;' if ($c3 eq '');
1177     my($c1align,$c2align,$c3align) = split('\|', $aligns);
1178     my $padding = '';
1179     if ($c1align =~ /align="right"/ || $c1 eq '') {
1180         $padding = '&nbsp;';
1181     }
1182     return "\n    <tr>$c1align$sfont$c1$efont$padding</td>\n"
1183            . "        $c2align$c2</td>\n"
1184            . "        $c3align$c3</td>"
1185            . $_;
1186 }
1187
1188 sub do_env_tableiv{
1189     local($_) = @_;
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();
1196     s/[\s\n]+//;
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">'
1204            . "\n  <thead>"
1205            . "\n    <tr class=\"tableheader\">"
1206            . "\n      $th1<b>$h1</b>\&nbsp;</th>"
1207            . "\n      $th2<b>$h2</b>\&nbsp;</th>"
1208            . "\n      $th3<b>$h3</b>\&nbsp;</th>"
1209            . "\n      $th4<b>$h4</b>\&nbsp;</th>"
1210            . "\n      </tr>"
1211            . "\n    </thead>"
1212            . "\n  <tbody valign='baseline'>"
1213            . $_
1214            . "\n    </tbody>"
1215            . "\n</table>";
1216 }
1217
1218 sub do_env_longtableiv{
1219     return do_env_tableiv(@_);
1220 }
1221
1222 sub do_cmd_lineiv{
1223     local($_) = @_;
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();
1229     s/[\s\n]+//;
1230     my($sfont,$efont) = get_table_col1_fonts();
1231     $c4 = '&nbsp;' if ($c4 eq '');
1232     my($c1align,$c2align,$c3align,$c4align) = split('\|', $aligns);
1233     my $padding = '';
1234     if ($c1align =~ /align="right"/ || $c1 eq '') {
1235         $padding = '&nbsp;';
1236     }
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>"
1241            . $_;
1242 }
1243
1244
1245 # These can be used to control the title page appearance;
1246 # they need a little bit of documentation.
1247 #
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.
1251 #
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
1255 # are optional.
1256 #
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;
1262
1263 sub make_my_titlepage() {
1264     my $the_title = "";
1265     if ($t_title) {
1266         $the_title .= "\n<h1>$t_title</h1>";
1267     }
1268     else {
1269         write_warnings("\nThis document has no title.");
1270     }
1271     if ($t_author) {
1272         if ($t_authorURL) {
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>";
1277         }
1278         else {
1279             $the_title .= ("\n<p><b><font size='+2'>$t_author</font></b></p>");
1280         }
1281     }
1282     else {
1283         write_warnings("\nThere is no author for this document.");
1284     }
1285     if ($t_institute) {
1286         $the_title .= "\n<p>$t_institute</p>";
1287     }
1288     if ($DEVELOPER_ADDRESS) {
1289         $the_title .= "\n<p>$DEVELOPER_ADDRESS</p>";
1290     }
1291     if ($t_affil) {
1292         $the_title .= "\n<p><i>$t_affil</i></p>";
1293     }
1294     if ($t_date) {
1295         $the_title .= "\n<p>";
1296         if ($PACKAGE_VERSION) {
1297             $the_title .= "<strong>Release $PACKAGE_VERSION</strong><br>\n";
1298         }
1299         $the_title .= "<strong>$t_date</strong></p>"
1300     }
1301     if ($t_address) {
1302         $the_title .= "\n<p>$t_address</p>";
1303     }
1304     else {
1305         $the_title .= "\n<p>";
1306     }
1307     if ($t_email) {
1308         $the_title .= "\n<p>$t_email</p>";
1309     }
1310     return $the_title;
1311 }
1312
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";
1324     return $graphic;
1325 }
1326
1327 sub do_cmd_maketitle {
1328     local($_) = @_;
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()
1335                            . "</td>\n"
1336                            . make_my_titlegraphic()
1337                            . "</tr>\n</table>");
1338         }
1339         else {
1340             $the_title .= ("\n<table border=\"0\" width=\"100%\"><tr>\n"
1341                            . make_my_titlegraphic()
1342                            . "<td>"
1343                            . make_my_titlepage()
1344                            . "</td></tr>\n</table>");
1345         }
1346     }
1347     else {
1348         $the_title .= ("\n<center>"
1349                        . make_my_titlepage()
1350                        . "\n</center>");
1351     }
1352     $the_title .= "\n</div>";
1353     return $the_title . $_;
1354     $the_title .= "\n</center></div>";
1355     return $the_title . $_ ;
1356 }
1357
1358
1359 #
1360 #  Module synopsis support
1361 #
1362
1363 require SynopsisTable;
1364
1365 sub get_chapter_id(){
1366     my $id = do_cmd_thechapter('');
1367     $id =~ s/<SPAN CLASS="arabic">(\d+)<\/SPAN>/\1/;
1368     $id =~ s/\.//;
1369     return $id;
1370 }
1371
1372 # 'chapter' => 'SynopsisTable instance'
1373 %ModuleSynopses = ();
1374
1375 sub get_synopsis_table($){
1376     my($chap) = @_;
1377     my $key;
1378     foreach $key (keys %ModuleSynopses) {
1379         if ($key eq $chap) {
1380             return $ModuleSynopses{$chap};
1381         }
1382     }
1383     my $st = SynopsisTable->new();
1384     $ModuleSynopses{$chap} = $st;
1385     return $st;
1386 }
1387
1388 sub do_cmd_moduleauthor{
1389     local($_) = @_;
1390     next_argument();
1391     next_argument();
1392     return $_;
1393 }
1394
1395 sub do_cmd_sectionauthor{
1396     local($_) = @_;
1397     next_argument();
1398     next_argument();
1399     return $_;
1400 }
1401
1402 sub do_cmd_declaremodule{
1403     local($_) = @_;
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());
1408     #
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,$_)
1414 }
1415
1416 sub do_cmd_modulesynopsis{
1417     local($_) = @_;
1418     my $st = get_synopsis_table(get_chapter_id());
1419     $st->set_synopsis($THIS_MODULE, translate_commands(next_argument()));
1420     return $_;
1421 }
1422
1423 sub do_cmd_localmoduletable{
1424     local($_) = @_;
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]" . $_;
1429 }
1430
1431 sub process_all_localmoduletables{
1432     my $key;
1433     my $st, $file;
1434     foreach $key (keys %ModuleSynopses) {
1435         $st = $ModuleSynopses{$key};
1436         $file = $st->get_file();
1437         if ($file) {
1438             process_localmoduletables_in_file($file);
1439         }
1440         else {
1441             print "\nsynopsis table $key has no file association";
1442         }
1443     }
1444 }
1445
1446 sub process_localmoduletables_in_file{
1447     my $file = @_[0];
1448     open(MYFILE, "<$file");
1449     local($_);
1450     sysread(MYFILE, $_, 1024*1024);
1451     close(MYFILE);
1452     # need to get contents of file in $_
1453     while (/<tex2html-localmoduletable><(\d+)>/) {
1454         my $match = $&;
1455         my $chap = $1;
1456         my $st = get_synopsis_table($chap);
1457         my $data = $st->tohtml();
1458         s/$match/$data/;
1459     }
1460     open(MYFILE,">$file");
1461     print MYFILE $_;
1462     close(MYFILE);
1463 }
1464 sub process_python_state{
1465     process_all_localmoduletables();
1466 }
1467
1468
1469 #
1470 #  "See also:" -- references placed at the end of a \section
1471 #
1472
1473 sub do_env_seealso{
1474     return "<div class='seealso'>\n  "
1475       . "<p class='heading'><b>See Also:</b></p>\n"
1476       . @_[0]
1477       . '</div>';
1478 }
1479
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....
1483     local($_) = @_;
1484     my $key = next_optional_argument();
1485     my $module = next_argument();
1486     my $text = next_argument();
1487     my $period = '.';
1488     $key = $module
1489         unless $key;
1490     if ($text =~ /\.$/) {
1491         $period = '';
1492     }
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>"
1497       . $_;
1498 }
1499
1500 sub strip_html_markup($){
1501     my $str = @_[0];
1502     my $s = "$str";
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;
1505     return $s;
1506 }
1507
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>"
1521       . $_;
1522 }
1523
1524 sub do_cmd_seepep{
1525     return handle_rfclike_reference(@_[0], "PEP", $PEP_FORMAT);
1526 }
1527
1528 sub do_cmd_seerfc{
1529     return handle_rfclike_reference(@_[0], "RFC", $RFC_FORMAT);
1530 }
1531
1532 sub do_cmd_seetitle{
1533     local($_) = @_;
1534     my $url = next_optional_argument();
1535     my $title = next_argument();
1536     my $text = next_argument();
1537     if ($url) {
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>"
1543           . $_;
1544     }
1545     return '<dl compact class="seetitle">'
1546       . "\n    <dt><em class=\"citetitle\""
1547       . "\n        >$title</em>"
1548       . "\n    <dd>$text\n  </dl>"
1549       . $_;
1550 }
1551
1552 sub do_cmd_seeurl{
1553     local($_) = @_;
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>"
1561       . $_;
1562 }
1563
1564 sub do_cmd_seetext{
1565     local($_) = @_;
1566     my $content = next_argument();
1567     return '<div class="seetext"><p>' . $content . '</div>' . $_;
1568 }
1569
1570
1571 #
1572 #  Definition list support.
1573 #
1574
1575 sub do_env_definitions{
1576     return "<dl class='definitions'>" . @_[0] . "</dl>\n";
1577 }
1578
1579 sub do_cmd_term{
1580     local($_) = @_;
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>" . $_;
1585 }
1586
1587
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.
1591
1592 #code # {}
1593 process_commands_wrap_deferred(<<_RAW_ARG_DEFERRED_CMDS_);
1594 declaremodule # [] # {} # {}
1595 memberline # [] # {}
1596 methodline # [] # {} # {}
1597 modulesynopsis # {}
1598 platform # {}
1599 samp # {}
1600 setindexsubitem # {}
1601 withsubitem # {} # {}
1602 _RAW_ARG_DEFERRED_CMDS_
1603
1604
1605 $alltt_start = '<dl><dd><pre class="verbatim">';
1606 $alltt_end = '</pre></dl>';
1607
1608 sub do_env_alltt {
1609     local ($_) = @_;
1610     local($closures,$reopens,@open_block_tags);
1611
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);
1615
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
1621         if (@$open_tags_R);
1622
1623     $open_tags_R = [ @open_block_tags ];
1624
1625     do {
1626         local($open_tags_R) = [ @open_block_tags ];
1627         local(@save_open_tags) = ();
1628
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");
1632
1633         $_ = &translate_environments($_);
1634         $_ = &translate_commands($_) if (/\\/);
1635
1636         # preserve space-runs, using &nbsp;
1637         while (s/(\S) ( +)/$1$2;SPMnbsp;/g){};
1638         s/(<BR>) /$1;SPMnbsp;/g;
1639
1640         $_ = join('', $closures, $alltt_start, $local_reopens
1641                 , $_
1642                 , &balance_tags() #, $local_closures
1643                 , $alltt_end, $reopens);
1644         undef $open_tags_R; undef @save_open_tags;
1645     };
1646     $open_tags_R = [ @keep_open_tags ];
1647     $_;
1648 }
1649
1650
1651 1;                              # This must be the last line