home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / perl_utl.zip / pod2texi.cmd < prev    next >
OS/2 REXX Batch file  |  1996-09-27  |  24KB  |  904 lines

  1. extproc perl -Sx 
  2. #!/usr/build/perl53/bin/perl
  3. #!/usr/local/bin/perl
  4. # changes pod to texinfo
  5. # you still have to insert a few TeXinfo directives to make it look
  6. # right ...
  7. # well, not any more (hopefully).
  8.  
  9. # parts stolen from pod2html (to get the perlpod listings, et al).
  10. # unfortunately, texinfo 1.1 can't jump to a certain location in a 
  11. # info page, so we can't do the kind of cool exactly-this-spot 
  12. # xrefs that html can ...
  13. # By Krishna Sethuraman (krishna@sgi.com)
  14.  
  15. # This was a real hack job -- I started this before I fully understood
  16. # anonymous references, so please feel free
  17. # to hack this apart.
  18.  
  19. # so we can get the locations for the library -> .pm -> module docs
  20.  
  21. use Config;
  22. use File::Find;
  23. sub intern_modnamehash;
  24. sub debug;
  25.  
  26. use vars (@envs);
  27. $modnode = 'Module List';
  28. $modinfofile = 'pm.info';
  29.  
  30. # Im sure not all these are needed, but cant hurt (I hope)
  31.  
  32. @libdirs = qw(archlibexp installarchlib installprivlib privlibexp archlib
  33.       installsitearch installsitelib privlib sitearch sitearchexp
  34.       sitelib sitelibexp);
  35.  
  36. @libdirs = qw(privlib archlib sitelib sitearch);
  37.  
  38. # previously, we used $Config{$libdir} in intern_modnamehash and the
  39. # foreach loop ... now we just use $libdir
  40. @libdirs = @INC;
  41.  
  42. # The beginning of the url for the anchors to the other sections.
  43. $nodeterm = "\c_";
  44. chop($wd=`pwd`);
  45. $type="<A HREF=\"file://localhost".$wd."/";
  46. $debug=0;
  47. $/ = "";
  48. $p=\%p;
  49. #@exclusions=qw(perldebug perlform perlobj perlstyle perltrap perlmod);
  50. $indent=0;
  51. opendir(DIR,".");
  52. @{$p->{"pods"}}=sort grep(/\.pod$/,readdir(DIR)); # sort so perl.pod is first
  53. closedir(DIR);
  54.  
  55. # put all modules into big hash of module name -> file
  56. # save current dir
  57. chop($curdir = `pwd`);
  58.  
  59. # for all library directories, go to that directory and find the .pod and .pm
  60. # files
  61.  
  62. debug("Module pod/pm discovery");
  63. chop($date = `date`);
  64.  
  65. libdir: foreach $libdir (@libdirs) {
  66.     chop($curdir = `pwd`);
  67.     chdir $libdir;
  68.     debug("Looking in $libdir:");
  69.     find (\&intern_modnamehash , '.');
  70.     chdir $curdir;
  71. }
  72.  
  73. chdir $curdir;
  74.  
  75. @modnames = sort keys %modnamehash;
  76.  
  77. # %modnamehash now maps module name -> file name.
  78.  
  79. # (1) LEARN the important stuff.
  80.  
  81. debug("Learning Pods");
  82.  
  83.  
  84. foreach $tmpod (@{$p->{"pods"}}, @modnames){
  85.  
  86. # if its a module, get the full filename
  87.  
  88.     if (defined($modnamehash{$tmpod})) {
  89.     $podfile = $modnamehash{$tmpod};
  90.     } else {
  91.     $podfile = $tmpod;
  92.     }
  93.  
  94.     ($pod=$tmpod)=~s/\.(pod|pm)$//;
  95.     $p->{"podnames"}->{$pod}=1;
  96.     next if grep(/$pod/,@exclusions);
  97.  
  98. # print them out semi-orderedly
  99.     
  100.     &echopod($pod);
  101.  
  102. # for each podfile
  103.  
  104.     open(POD,"<$podfile");
  105.     while(<POD>){
  106. # kill bold/italics
  107.     s/B<([^<>]*)>/$1/g;         # bold
  108.     s/I<([^<>]*)>/$1/g;         # bold
  109. # if = cmd
  110.         if (s/^=//) {
  111.         s/\n$//s;
  112.         s/\n/ /g;
  113.         ($cmd, $_) = split(' ', $_, 2);
  114. # if =item cmd
  115.          if ($cmd eq  "item") {
  116.         ($what,$rest)=split(' ', $_, 2);
  117. # what is now only the (-.) part (dash plus one character)
  118.         $what=~s#(-.).*#$1#;
  119.         $what=~s/\s*$//;
  120.  
  121.         next if defined $p->{"items"}->{$what};
  122. # put it in items subarray as podname_serialnumber(?)
  123.         $p->{"items"}->{$what} = $pod."_".$i++;
  124.         }
  125.         elsif($cmd =~ /^head/){
  126. # if =head cmd
  127.         $_=~s/\s*$//;
  128.         next if defined($p->{"headers"}->{$_});
  129. # put it in headers subarray as podname_serialnumber(?)
  130. # serial numbers, etc., look to be used as tags to indicate a position
  131. # in an html file.  No such luck in texinfo (sigh).
  132.         $p->{"headers"}->{$_} = $pod."_".$i++;
  133.         }
  134.     }
  135.     }
  136. }
  137.  
  138. # we can do all the above, just ignore the _ tagging stuff.  Maybe in the next
  139. # version of texinfo, we can ref a char. position in an info file.
  140.  
  141. # start big top-level files which include everything:
  142.  
  143. &start_big_files;
  144.  
  145. debug ("Reading Pods");
  146.  
  147.     $modulepod = 0;
  148.  
  149. # (2) READ each pod, write structuring information
  150. foreach $tmpod (@{$p->{"pods"}}, @modnames ){
  151.  
  152. # I dont think the table of contents is very useful in TeXinfo
  153. # someone may disagree
  154.     next if $tmpod eq 'perltoc.pod';
  155.  
  156.     if (defined($modnamehash{$tmpod})) {
  157.     # its a module file
  158.     $podfile = $modnamehash{$tmpod};
  159. # this next line gives us an index into @modnames
  160.     $modulepod++;
  161.     } else {
  162.     $podfile = $tmpod;
  163.     }
  164.  
  165.     open(POD,"<$podfile") || die "cant open $podfile";
  166.     ($pod=$tmpod)=~s/\.(pod|pm)$//;
  167.     open(TEXINFO,">$pod.texi");
  168.  
  169.     ($curn,$prevn,$nextn,$upn) = ();
  170.  
  171. # now translate :: to /, for tex/info
  172.  
  173.     ($curn = $pod) =~ s{::}{/}g;
  174.  
  175.     if (! $modulepod) {
  176.     
  177. # check if we have the lines array - if so, we can use it to
  178. # generate pod nodes and prev, next, etc. refs
  179. # the lines array comes from perl.pod, giving us the correct ordering
  180. # for the base pods
  181.  
  182.     if (@linesfornodes) {
  183.         $i=0;
  184.       podline: for (@linesfornodes) {
  185.         last podline if $pod eq $_;
  186.         $i++;
  187.         }
  188. # if we got to $#linesfornodes+1, we didnt find it.
  189.         unless ($i == $#linesfornodes+1) {
  190.         ($prevn, $curn, $nextn) = @linesfornodes[($i?$i-1:0),$i,$i+1];
  191.         $prevn = 'Top' if ($prevn eq $curn);
  192.         }
  193.     }
  194.  
  195. # specific to master perl node
  196.  
  197.     $upn = ($pod eq 'perl')?'(dir)' :'Top';
  198.  
  199.     $pod eq 'perl' and ($curn,$nextn) = ('Top','perldata');
  200.     $prevn eq 'perl' and $prevn = 'Top';
  201.  
  202.     $prevn ||= 'Top';
  203.     $nextn ||= 'Top';
  204.  
  205. } else {
  206. # module pod
  207. # structuring information - yech
  208. # just do a straight giant menu, if we can.  Calculate nodes similar to above.
  209.     
  210.     $idx = $modulepod -1;
  211.     ($prevn,$curn,$nextn) = ($idx?$modnames[$idx-1]:'',
  212.                  @modnames[$idx,$idx+1]);
  213.  
  214.     $prevn =~ s{::}{/}g;
  215.     $curn =~ s{::}{/}g;
  216.     $nextn =~ s{::}{/}g;
  217.  
  218.     $upn = $modnode;
  219. # I used to have these - well just have empty previous and next
  220. # to indicate beginning or end of a set of leaf nodes
  221. #    $prevn ||= $modnode;
  222. #    $nextn ||= $modnode;
  223.  
  224. }
  225.  
  226.     print STDOUT "for pod $pod, \@node $curn, $nextn, $prevn, $upn\n";
  227. #    print STDOUT "@linesfornodes\n";
  228.  
  229.     print TEXINFO <<_EOF_;
  230. \@node $curn, $nextn, $prevn, $upn
  231. _EOF_
  232.  
  233.  
  234.  
  235.     $cutting = 1;
  236.     $newenv = '';
  237.  
  238.     # (3) PROCESS each paragraph
  239. $gotshortdesc = 0;
  240. paragraph:    while (<POD>) {
  241.     if ($cutting) {
  242.         next unless /^=/;
  243.         $cutting = 0;
  244.     }
  245.     chop;
  246.     length || (print "\n") && next;
  247.  
  248.     # Translate verbatim paragraph
  249.  
  250. # greedy matching here will set $1 to all space before first nonspace
  251. # at beginning of string.  Since its unlikely [Ed: but it happens
  252. # sometimes, however, one common case is code examples with blank
  253. # newlines] anything after that in the same paragraph will be
  254. # outdented farther left than the first line, we can kill that much
  255. # whitespace from the beginning of each line.  we kill whitespace from
  256. # beginning of line for verbatim because example mode adds it back in.
  257.  
  258. # XXX - perhaps if we find 2 contiguous outdented paragraphs, we should put
  259. # them in the same @example environment
  260. # maybe the last line of the previous paragraph should be outdented
  261. # the same as the first line of the next.
  262.  
  263.     if (($space) = /^(\s+)/) { 
  264.         &pre_escapes($_);
  265.         @lines = split(/\n/);
  266.         if($lines[0]=~/^\s+(\w*)\t(.*)/){  # maybe a menu
  267.         ($key,$rest)=($1,$2);
  268.         if(defined($p->{"podnames"}->{$key})){ # yup, a menu
  269.             # process menu here. if not a menu, its an example
  270.             # or Its a menu.  Save it for end of node.
  271.             print TEXINFO "\n\@menu\n";
  272.             for (@lines) {
  273.             m/^\s+(\w*)\t(.*)/;
  274.             print TEXINFO "* $1:: $2\n";
  275.             }
  276.  
  277. # special case, top perl node
  278.             if ($key eq 'perl') {
  279.             print TEXINFO <<"EOF";
  280.  
  281. * Module List:($modinfofile)$modnode. Got your modules, right here
  282. * Function Index:: Perl functions and operators
  283. * Predefined Variable Index:: Perl predefined variables
  284. * Diagnostics Index:: Perl diagnostic messages
  285.  
  286.  
  287. EOF
  288. }
  289.  
  290.             print TEXINFO "\@end menu\n\n";
  291. # this next bit we will do by hand for now...
  292. #            for (@lines) {
  293. #            m/^\s+(\w*)\t(.*)/;
  294. #            print TEXINFO "\@include $1.texinfo\n";
  295. #            }
  296.             @linesfornodes = @lines;
  297.             map(s/^\s+(\w*)\t(.*)/$1/,@linesfornodes);
  298.             # done with menu paragraph, next paragraph
  299.             next;
  300.         }
  301.         # not a menu, process it as example
  302.         }
  303.         s/^$space//mg;
  304.         print TEXINFO "\@example\n", $_, "\@end example\n\n";
  305.         next;
  306.     }
  307.  
  308.     $_ = &all_escapes($_,$pod);
  309.  
  310.     if (s/^=//) {
  311.         s/\n$//s;
  312.         s/\n/ /g;
  313.         ($cmd, $_) = split(' ', $_, 2);
  314.         if ($cmd eq 'cut') {
  315.         $cutting = 1;
  316.         }
  317.         elsif ($cmd eq 'head1') {
  318.  
  319. # if NAME, slurp in the next paragraph and use it (instead of 'NAME') as
  320. # a chapter title
  321.  
  322. # have to run it through the escapes ourselves
  323.         if (/^\s*NAME/) {
  324.             $gotshortdesc = 1;
  325.             $podorigshortdesc = <POD>;
  326.             $podshortdesc = $podorigshortdesc;
  327.             # trim actual pod name (should we?)
  328.             $podshortdesc =~ s/^[^---]+-+\s*//;
  329.             $podshortdesc = &all_escapes($podshortdesc, $pod);
  330.             # if the name is multiline, change all but the
  331.             # last to a space
  332.             $podshortdesc =~ s/\n(.+)/ $1/g;
  333.  
  334.             print TEXINFO qq|\@unnumbered $podshortdesc\n|;
  335.  
  336.             # include a menu entry for module pods
  337.             
  338.             chop($nonewline = $podshortdesc);
  339.  
  340.             $modulepod && print MODLISTTEXI
  341.                           qq|* $ {curn}:: $nonewline|;
  342.         }
  343.  
  344.         # print out the heading info anyway
  345.  
  346.         &closeenvs;
  347.         print TEXINFO qq|\@unnumberedsec $_\n\n|;
  348.         
  349.         /^\s*NAME/ && ($_ = $podorigshortdesc,redo paragraph);
  350.  
  351.         }
  352.         elsif ($cmd eq 'head2') {
  353.  
  354.         # if @env has an entry, we had =over or =items
  355.         # but no =back - close it here
  356.  
  357.         &closeenvs;
  358.         print TEXINFO qq|\@unnumberedsubsec $_\n\n|;
  359.         }
  360.         elsif ($cmd eq 'item') {
  361.         ($what,$rest)=split(' ', $_, 2);
  362.         $what=~s/\s*$//;
  363.  
  364. # various cases - single star, star with stuff after it
  365. # number, or something else
  366.  
  367. # people sometimes forget to put a leading =over.
  368. # if =item at top level (empty array), assume =over
  369.  
  370.         if ($what =~ /[*]/) { # if a single star, axe it
  371.         # texinfo itemize can put in its own star.
  372.             $_ = $rest;
  373.  
  374.             if (scalar(@envs) == 0 or $newenv) {
  375.             $newenv = 0,
  376.             unshift (@envs, 'itemize'),
  377.             print TEXINFO '@itemize @bullet', "\n";
  378.              };
  379.             
  380. # if a single star, its a bulleted list with paragraphs - 
  381. # need a newline before paragraphs if theres anything
  382. # left on that line.  Else, if no star,
  383. # its probably going to be a table - no newlines before paragraph
  384.  
  385. # sometimes its not a table (but more so than otherwise)
  386. # tables do the right thing, @itemize items run together
  387. # if no newline - no good heuristic if @item foo because
  388. # dont know if table or itemize ahead of time
  389.  
  390.             $next_para=1 if $rest;
  391.  
  392. # if digits, get rid of them ...
  393.         } elsif ($what =~ /^\d+[.]?/) { 
  394.  
  395.     # texinfo enumerate can put in its own numbers
  396.             $_ = $rest;
  397.  
  398.             if (scalar(@envs) == 0 or $newenv) {
  399.             $newenv = 0,
  400.             unshift (@envs, 'enumerate'),
  401.             print TEXINFO '@enumerate', "\n";
  402.             }
  403.  
  404. # if a single star, its a bulleted list with paragraphs - 
  405. # need a newline before paragraphs.  Else, if digits
  406. # its enumerated - no newlines before paragraph
  407.  
  408.             $next_para=0;
  409.         } else {
  410.  
  411.             if (scalar(@envs) == 0 or $newenv) {
  412.             $newenv = 0,
  413.             unshift (@envs, 'table'),
  414.             print TEXINFO '@table @asis', "\n";
  415.             }
  416.         }
  417.  
  418.         # only if we have starred items do we want to really
  419.         # have separate items - else, two items
  420.         # in a row is likely an itemx
  421.         # candidate.  We will see how this goes
  422.  
  423. # previously we only wanted itemx if they had the first word
  424. # in common (write, write FILEHANDLE, etc.)
  425. #        if($justdid ne $what && $what =~ /[*]/){}
  426.  
  427. # if theres text on the same line as an item in enumerate,
  428. # emacs texinfo processing will complain
  429.  
  430.         if(! $justdid || $what =~ /([*])|(\d+[.]?)/){
  431.             if ($rest && $envs[0] eq 'enumerate') {
  432.             print TEXINFO "\@item \n$_\n";
  433.             } else {
  434.             print TEXINFO "\@item $_\n";
  435.             }
  436.             ($pod =~ /perldiag/) && print TEXINFO "\@dgindex $_\n";
  437.             ($pod =~ /perlfunc/) && print TEXINFO "\@findex $_\n";
  438.             ($pod =~ /perlvar/) && print TEXINFO "\@vindex $_\n";
  439.             $justdid=$what;
  440.         } else {
  441.             print TEXINFO qq{\@itemx $_\n};
  442.         }
  443.         }
  444.         elsif ($cmd eq 'over') {
  445.         # indicate start of a new itemization
  446.         $newenv = 1;
  447.         $justdid = '';
  448.         }
  449.         elsif ($cmd eq 'back') {
  450.         # if @env is empty, we had an =over but no =items
  451.         # bad form, but we can silently continue
  452.         
  453.         print TEXINFO '@end ', shift(@envs), "\n" if @envs;
  454.         }
  455.         else {
  456.         warn "Unrecognized directive: $cmd\n";
  457.         }
  458.     }
  459.     else {
  460. # not a perl command, so dont try to compare vs. the last item for itemxing
  461. # upcoming paragraphs
  462.         $justdid = ''; 
  463.         
  464.         length || next;
  465. # argh - in itemize, it sucks the whole thing up to the next line
  466. # in table, it doesn't
  467. # we don't know whether to do table or itemize
  468.  
  469.         $next_para && print TEXINFO "\n";
  470. #        $next_para && (print TEXINFO  qq{<dd>\n});
  471.         print TEXINFO  "$_\n";
  472. #        $next_para && (print  TEXINFO qq{</dd>\n<p>\n}) && ($next_para=0);
  473.         $next_para = 0;
  474.     }
  475.     }
  476.  
  477. # clean up envs that ran off the end of the document
  478.  
  479.     &closeenvs;
  480.  
  481. # write to our big file of include statements
  482. # need 2 newlines cuz of weirdness (bug?) in texinfo processing
  483.     if (! $modulepod) {
  484.     print BIGTEXI "\@include $nextn.texi\n\n" if ($nextn ne 'Top');
  485.     } else {
  486.     print BIGMODTEXI "\@include $modnames[$idx].texi\n\n" 
  487.     }
  488. # if no short description, still create menu entry
  489.     if ($modulepod && ! $gotshortdesc) {
  490.     print MODLISTTEXI "* ${curn}:: MISSING SHORT DESCRIPTION\n";
  491.     }
  492. }
  493.  
  494. # finish our big files
  495.  
  496. &finish_big_files;
  497.  
  498. #########################################################################
  499.  
  500. sub all_escapes {
  501.     local($_,$pod) = @_;
  502.     &pre_escapes($_);
  503. # bug in texinfo - @@ at beginning of line gets hosed
  504. # only need to fix if not =over paragraph - those work ok
  505.     s/\n@@/\n @@/g;
  506.     $_ = &Do_refs($_,$pod);
  507.     
  508.     s/Z<>//g; #  what to do with this?
  509. #    s/E<lt>/</g;
  510. #    s/E<gt>/>/g;
  511.  
  512.     s/Less_Than_Special_Sequence/</g;
  513.     s/Greater_Than_Special_Sequence/>/g;
  514.  
  515.     return $_;
  516.  
  517.     }
  518.  
  519. sub pre_escapes {
  520.     local($_) = @_;
  521.     s/E<lt>/Less_Than_Special_Sequence/g;
  522.     s/E<gt>/Greater_Than_Special_Sequence/g;
  523.     s/[\@{}\`\']/\@$&/g;
  524. #    s/C<E<lt>E<lt>>/\@code{<<}/g;
  525. #    s/C<-E<gt>>/\@code{->}/g;
  526.     $_[0] = $_;
  527. }
  528.  
  529. sub post_escapes{
  530.     local($_) = @_;
  531. #    s/>>/\>\;\>\;/g;
  532. #    s/([^"AIB])>/$1\>\;/g;
  533.     $_[0] = $_;
  534. }
  535.  
  536. sub Do_refs{
  537. local($para,$pod)=@_;
  538.  
  539. # quick hack, but may slow things down considerably
  540. # since tags are nestable, we must keep going until we cant see
  541. # any more X< (this means we must make sure E<lt> doesnt get
  542. # translated to a < prior to a call to this function, to be safe).  Done
  543. # in pre_escapes.
  544.  
  545. # this will *HANG* if tags are mis-nested!!!!
  546.  
  547. $iter = 0;
  548. pass: while ($para =~ /[LCIBSFZ]</) {
  549.     if ($iter++ == 15) { 
  550.     print  <<EOF;
  551. Too many iterations on this paragraph:
  552.  
  553. $para
  554.  
  555. Most likely an unescaped < or > (use E<lt> or E<gt> instead) or one
  556. of those is missing its mate.
  557.  
  558. EOF
  559.     last pass;
  560.     }
  561. foreach $char (qw(L C I B S F Z)){
  562.     next unless $para =~ /($char<[^<>]*>)/;
  563. # @ar = split paragraph, making array elements out of 
  564. # the current char<foo> as well as regular text
  565.     local(@ar) = split(/($char<[^<>]*>)/,$para);
  566.     local($this,$key,$num,$sec,$also);
  567. # for all @ar elements,
  568.     for($this=0;$this<=$#ar;$this++){
  569. # only handle the current chars char<foo> thingies
  570.         next unless $ar[$this] =~ /$char<([^<>]*)>/;
  571.  
  572. # if just single foo, $key = foo.  Else if foo/bar, $key = foo, 
  573. # $sec = bar.
  574.     $key=$1;
  575.     ($chkkey,$sec) = ($key =~ m|^([^/]+)(?:/([^/]+))?|);
  576. # XXX if chkkey was '' but there was a slash, use the 'in this node' case
  577. # if the key matches a podname, put in a ref to the pod
  578.     if((defined($p->{"podnames"}->{$chkkey})) && ($char eq "L")){
  579.  
  580.         $also = "\@samp{$sec}, " if $sec ;
  581. #        $ar[$this] = "${also}\@xref{$chkkey,\u$chkkey,,$chkkey.info},";
  582.  
  583. # specify the other info file, if necessary:
  584.  
  585.         $shortname = $chkkey;
  586.  
  587.         if (!defined $modnamehash{$pod} &&
  588.         defined $modnamehash{$chkkey}) {
  589.         $chkkey = "($modinfofile)$chkkey";
  590.         } elsif (defined $modnamehash{$pod} &&
  591.              !defined $modnamehash{$chkkey}) {
  592.         $chkkey = "(perl.info)$chkkey";
  593.         }
  594.  
  595. # as stated above, keys to podnames have ::, which we must translate
  596. # to /
  597.         $shortname =~ s{::}{/}g;
  598.         $chkkey =~ s{::}{/}g;
  599.  
  600.         $ar[$this] = "${also}\@xref{$chkkey,\u$shortname},";
  601.         # *note arg2: (arg3) arg1
  602. # otherwise, if char is still "L", then key didnt match a podname
  603. # and therefore is a section on the current manpage
  604.     } 
  605.     elsif ($char eq "L") {
  606.     $ar[$this] = "\@samp{$chkkey} in this node";
  607.     }
  608.  
  609. # if the key matches an item, put in a ref to the item def.
  610. # ignore this for now
  611.     elsif(defined($p->{"items"}->{$key})){
  612.         ($pod2,$num)=split(/_/,$p->{"items"}->{$key},2);
  613.         $ar[$this] = (($pod2 eq $pod) && ($para=~/^\=item/)) ?
  614. #        "\n<A NAME=\"".$p->{"items"}->{$key}."\">\n$key</A>\n"
  615.             $key:$key
  616. #        "\n$type$pod2.html\#".$p->{"items"}->{$key}."\">$key<\/A>\n"
  617.             ;
  618.         }
  619. # if the key matches a header, put in a ref to the header def.
  620. #ignore this to start with
  621.     elsif(defined($p->{"headers"}->{$key})){
  622.         ($pod2,$num)=split(/_/,$p->{"headers"}->{$key},2);
  623.         $ar[$this] = (($pod eq $pod2) && ($para=~/^\=head/)) ? 
  624. #        "\n<A NAME=\"".$p->{"headers"}->{$key}."\">\n$key</A>\n"
  625.         $key:$key
  626. #        "\n$type$pod2.html\#".$p->{"headers"}->{$key}."\">$key<\/A>\n"
  627.             ;
  628.  
  629. # if its an item or header, formatting will be lost because
  630. # of the else construct here
  631.  
  632.     }
  633.     else{
  634.         (warn "No \"=item\" or \"=head\" reference for $ar[$this] in $pod\n") if $debug;
  635.         if ($char eq "L"){
  636.         $ar[$this]=$key;
  637.         }
  638.         elsif($char eq "I"){
  639.         $ar[$this]="\@emph{$key}";
  640.         }
  641.         elsif($char eq "B"){
  642.         $ar[$this]="\@strong{$key}";
  643.         }
  644.         elsif($char eq "S"){
  645.         $ar[$this]="\@w{$key}";
  646.         }
  647.         elsif($char eq "C"){
  648.         $ar[$this]="\@code{$key}";
  649.         }
  650.         elsif($char eq "F"){
  651.         $ar[$this]="\@file{$key}";
  652.         }
  653.     }
  654.     }
  655.     $para=join('',@ar);
  656. }
  657. }
  658. $para;
  659. }
  660.  
  661. sub intern_modnamehash {
  662.  
  663. # File::Find is pretty screwy.
  664. # I think we can't modify $_ or File::Find can screw up
  665.  
  666.     my $shortpath;
  667.     my $thename;
  668.     
  669. # this could be a problem - if we search $sitelibdir,
  670. # its usually a subdir of $libdir, in which case we don't want it
  671. # to think 'site_perl' is a class name.
  672.  
  673. # XXX - may be doing toplevel modules incorrectly in the above case
  674. # is 'name' just the filename?  thats not good ....
  675.     $thename = $File::Find::name;
  676.     $shortpath = $thename;
  677.  
  678. # kill leading './'
  679.  
  680.     $thename =~ s{^[.]/}{};
  681.  
  682. # XXX - take the current $libdir (/foo/bar) 
  683. # and see if the file were testing (/foo/bar/site_perl/Plugh/Blah.pm) is
  684. # in any *other*, deeper subdir in @INC
  685. # (/foo/bar/site_perl) - if so, skip this entry, cuz the deeper 
  686. # subdir will catch it properly (Plugh::Blah)
  687.  
  688. # for other libraries that are proper subdirs of the current libdir
  689.     foreach $otherlibrary (grep /^$libdir.+/, @INC) {
  690.  
  691. # if the other library is part of the current files path, skip it
  692. # because it will be caught when the other library is used
  693.  
  694.     if ("$libdir/$thename" =~ /^$otherlibrary/) {
  695.         print ".";
  696. #        print "Skipping $thename\n";
  697. #        print "cuz $otherlibrary caught/will catch it\n";
  698.         return;
  699.     }
  700.     }
  701.  
  702. # exclude base pods - perlfoo.pod
  703.     ($thename =~ m/perl.*[.]pod/) && return;
  704.  
  705. # for each file entry, kill trailing '.(pod|pm)'
  706.     (-f "$libdir/$thename") &&
  707.     ($thename =~ s{^(.*)[.](pod|pm)$ }{$1}x) or return;
  708.  
  709. # '.pod' files nonhierarchical - keep only last component as module name.
  710. # well, hierarchical in Tk ... keep it hierarchical for now
  711.  
  712. #    if ($2 eq 'pod') {$thename =~ s{.*/([^/]+)}{$1}; }
  713.     
  714. # translate to module syntax
  715.  
  716.     $thename =~ s{/}{::}g;
  717.  
  718. # if its already in the hash, skip it.  We're following @INC order,
  719. # which means if its found in a earlier @INC directory, it will
  720. # be the one thats `use'd.  So rather than overwriting an earlier
  721. # @INC entry with a newer one, we skip the newer one if the earlier
  722. # one exists (or, we could do the foreach on (reverse @INC) instead
  723. # of (@INC)).
  724.  
  725.     
  726.     if (defined $modnamehash{$thename}) {
  727. #    print "already found $thename\n";
  728. #    print "in $modnamehash{$thename}\n";
  729.     return
  730.     };
  731.  
  732.     $modnamehash{$thename} = "$libdir/$shortpath";
  733.  
  734. # If this is a .pm file, is there actually any documentation in it?    
  735.     
  736.     if ($modnamehash{$thename} =~ /[.]pm$/) {
  737.         open(MODULE, "$modnamehash{$thename}");
  738.       line: while ($theline = <MODULE>) {
  739.         $theline =~ /^=head\d/ && last line;
  740.         eof(MODULE) && delete $modnamehash{$thename};
  741.         }
  742.     }
  743.  
  744.     echopod($thename) if $modnamehash{$thename};
  745. }
  746.  
  747. sub wait{1;}
  748.  
  749. sub echopod {
  750.  
  751.     $savenew = $_[0];
  752.  
  753. # if neither has a ::, same line
  754.  
  755.     if ($oldpod !~ /::/ && $_[0] !~ /::/) {
  756.  
  757. # if old one has a ::, different lines
  758.  
  759.     } elsif ($oldpod =~ /::/ && $_[0] !~ /::/) {
  760.  
  761.     print "\n";
  762.  
  763.     } elsif ($oldpod !~ /::/ && $_[0] =~ /::/) {
  764.  
  765. # if its the new one that has ::, start a header line
  766.  
  767.     ($new) = ($_[0] =~ /^([^:]+)::/);
  768.     print "\n${new} modules: ";
  769.     $_[0] = $';
  770.  
  771.     } else {
  772.  
  773. # if both have ::, if stuff before first :: is different, newline
  774. # if stuff before is the same, trim it before printing (same line)
  775.  
  776.     ($old) = ($oldpod =~ /^([^:]+)::/);
  777.     ($new) = ($_[0] =~ /^([^:]+)::/);
  778.     if ($old eq $new) {
  779.         # kill leading stuff
  780.         $_[0] = $';
  781.     } else {
  782.         print "\n${new} modules: ";
  783.         $_[0] = $';
  784.     }
  785.     } 
  786.  
  787.     $oldpod = $savenew;
  788.     
  789.     print $_[0], " ";
  790.  
  791. }
  792.  
  793.  
  794. sub start_big_files {
  795.  
  796. open(BIGTEXI,">bigperl.texi"); 
  797.     print BIGTEXI <<'_EOF_' ;
  798. \input texinfo.tex
  799. @comment %**start of header
  800. @setfilename perl.info
  801. settitle perl
  802. @c footnotestyle separate
  803. @c paragraphindent 2
  804. @smallbook
  805. @comment %**end of header
  806. @defindex dg
  807.  
  808. @include perl.texi
  809.  
  810. _EOF_
  811.  
  812. open(BIGMODTEXI,">bigpm.texi"); 
  813.     print BIGMODTEXI <<'_EOF_', "\@setfilename $modinfofile\n", <<'_MOREEOF_';
  814. \input texinfo.tex
  815. @comment %**start of header
  816. _EOF_
  817. @settitle Big Module file
  818. @c footnotestyle separate
  819. @c paragraphindent 2
  820. @smallbook
  821. @comment %**end of header
  822.  
  823. @comment Giant module file.
  824.  
  825. @include modlist.texi
  826.  
  827. _MOREEOF_
  828.  
  829. open(MODLISTTEXI,">modlist.texi"); 
  830.     print MODLISTTEXI <<"_EOF_" ;
  831. \@node $modnode, (perl.info)Function Index, ,(perl.info)Top
  832. \@unnumbered Module List
  833.  
  834. This is it!  The list of the installed (documented) modules on
  835. $ENV{'HOST'}, as of $date.
  836.  
  837. Texinfo source for this file was generated by $ENV{'USER'} running
  838. pod2texi.pl.  This info file itself was created \@today{}.
  839.  
  840. \@menu
  841.  
  842. _EOF_
  843.  
  844. }
  845.  
  846. sub finish_big_files {
  847. print BIGTEXI << 'EOF';
  848. @include indices.texi
  849.  
  850. @summarycontents
  851. @contents
  852.  
  853. @bye
  854. EOF
  855.  
  856. print BIGMODTEXI << 'EOF';
  857. @summarycontents
  858. @contents
  859.  
  860. @bye
  861. EOF
  862.  
  863. print MODLISTTEXI << 'EOF';
  864. @end menu
  865. EOF
  866.  
  867. # make an index file
  868.  
  869. open(INDICES,">indices.texi");
  870. print INDICES <<'EOF';
  871.  
  872. @node Function Index, Predefined Variable Index, , Top
  873. @comment    node-name,         next,       previous, up
  874. @unnumbered Function Index
  875.  
  876. @printindex fn
  877.  
  878. @node Predefined Variable Index, Diagnostics Index, Function Index, Top
  879. @comment    node-name,         next,       previous, up
  880. @unnumbered Predefined Variable Index
  881.  
  882. @printindex vr
  883.  
  884. @node     Diagnostics Index,  , Predefined Variable Index, Top
  885. @comment      node-name, next,       previous, up
  886. @unnumbered Diagnostics Index
  887.  
  888. @printindex dg
  889.  
  890. EOF
  891. }
  892.  
  893. sub debug {
  894. print "\n", '=' x 79, "\n$_[0]\n", '=' x 79 , "\n";
  895. }
  896.  
  897. sub closeenvs {
  898.     for (@envs) {
  899.     print TEXINFO "\@end $_\n";
  900.     }
  901.     @envs = ();
  902. }
  903.