[BACK]Return to gphelp.in CVS log [TXT][DIR] Up to [local] / OpenXM_contrib / pari-2.2 / doc

Annotation of OpenXM_contrib/pari-2.2/doc/gphelp.in, Revision 1.1.1.1

1.1       noro        1: #!@perl@
                      2: #
                      3: # $Id: gphelp.in,v 1.23 2001/04/04 11:45:41 karim Exp $
                      4: #
                      5: # Copyright (C) 2000  The PARI group.
                      6: #
                      7: # This file is part of the PARI/GP package.
                      8: #
                      9: # PARI/GP is free software; you can redistribute it and/or modify it under the
                     10: # terms of the GNU General Public License as published by the Free Software
                     11: # Foundation. It is distributed in the hope that it will be useful, but WITHOUT
                     12: # ANY WARRANTY WHATSOEVER.
                     13: #
                     14: # Check the License for details. You should have received a copy of it, along
                     15: # with the package; see the file 'COPYING'. If not, write to the Free Software
                     16: # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
                     17:
                     18: # Output extended help corresponding to a given GP command. By default,
                     19: # extract relevant information from  from the PARI manual, run TeX, then open
                     20: # an xdvi display.
                     21: #
                     22: # The manual can be compressed.
                     23: #
                     24: # Usage: gphelp keyword
                     25: #
                     26: # Command line options:
                     27: #  -k: apropos (list of relevant GP functions)
                     28: #  -detex      (-d): don't use TeX + xdvi (implicit when DISPLAY is not set).
                     29: #  -color_help (-ch) <number>: use color "number" (same scheme as in GP)
                     30: #  -color_bold (-cb) <number>: display bold in color "number"
                     31: #  -color_underline (-cu) <number>: display underlined text in color "number"
                     32: #
                     33: #  -raw   use internal format for output with @x markers, -detex is implicit
                     34: #         (for the TeX-to-pod converter)
                     35: #
                     36: #  -to_pod file                convert file to POD (should be the only args)
                     37: #
                     38: #  -to_dumbpod file    same, but without nested formating
                     39: #
                     40: # Granted environment variables (override):
                     41: #  GPTMPDIR: where temporary files will go (/tmp by default).
                     42: #  GPDOCDIR: where is manual (by default, where make install will put it).
                     43: #  GPXDVI: which 'xdvi' program to call (xdvi by default)
                     44: #
                     45: $version= "@version@";
                     46: $miscdir= "@miscdir@";
                     47: # no expanded material (@key@) below
                     48: $wwwsite= "http://www.parigp-home.de/";
                     49: $docdir = $ENV{GPDOCDIR} || $ENV{GPHELP_DOCDIR} || "$miscdir/doc";
                     50:
                     51: $xdvi = $ENV{GPXDVI} || "xdvi";
                     52: $xdviref = $ENV{GPXDVIREF} || "$xdvi -paper 29.7x21cm";
                     53: $gzip = "gzip";
                     54: $zcat = "$gzip -dc";
                     55:
                     56: $refcard = (@ARGV and $ARGV[-1] =~ /refcard/i);
                     57:
                     58: $dumb_pod=1, $ARGV[0] = '-to_pod' if @ARGV && $ARGV[0] eq '-to_dumb_pod';
                     59: &to_pod() if @ARGV == 2 && $ARGV[0] eq '-to_pod';
                     60:
                     61: &options(); &init();
                     62: if ($#ARGV < 0) { &treat($_); cleanexit(); }
                     63:
                     64: &pretex() if (!$detex);
                     65: for (@ARGV) { &treat($_); }
                     66:
                     67:
                     68: if ($apropos) { &apropos_final_print(); cleanexit(); }
                     69: if (!$found) { &clean if (!$detex); cleanexit(); }
                     70:
                     71: &posttex() if (!$detex);
                     72:
                     73: print $gpmsg if (!$detex && $fromgp);
                     74: cleanexit();
                     75:
                     76: #
                     77: # Procedures
                     78: #
                     79: sub cleanexit {
                     80:   print "\e[0m" unless $to_pod;
                     81:   exit 0;
                     82: }
                     83:
                     84: sub help {
                     85:   print "Usage: $0 [-k] [-detex] [-ch c1] [-cb c2] [-cu c3] keyword\n";
                     86:   print "where c1,c2,c3 denote background, bold and underline color\n";
                     87:   exit(1);
                     88: }
                     89:
                     90: sub options
                     91: {
                     92:   $raw = $detex = $fromgp = $apropos = 0;
                     93:   $ch = $cb = $cu = '';
                     94:   while ($_ = $ARGV[0])
                     95:   {
                     96:     last if (! /^-[a-z]/);
                     97:     shift(@ARGV);
                     98:     if ($_ eq "-fromgp")
                     99:       { $fromgp = 1; }
                    100:     elsif ($_ eq "-k")
                    101:       { $apropos = 1; }
                    102:     elsif ($_ eq "-detex" || $_ eq "-d")
                    103:       { $detex = 1; }
                    104:     elsif ($_ eq "-raw")
                    105:       { $raw = $detex = 1; }
                    106:     elsif ($_ eq "-color_help" || $_ eq "-ch")
                    107:       { $ch = &color(shift(@ARGV)); }
                    108:     elsif ($_ eq "-color_bold" || $_ eq "-cb")
                    109:       { $cb = &color(shift(@ARGV)); }
                    110:     elsif ($_ eq "-color_underline" || $_ eq "-cu")
                    111:       { $cu = &color(shift(@ARGV)); }
                    112:     else
                    113:       { &help(); }
                    114:   }
                    115:   $detex = 1 if (!$detex && !$ENV{DISPLAY});
                    116: }
                    117:
                    118: sub init
                    119: {
                    120:   $gpmsg = "ugly_kludge_done\n";
                    121:   &inittr();
                    122:
                    123:   $indent = "   ";
                    124:
                    125:   chdir($docdir);
                    126:   $docfile = "usersch3.tex";
                    127:   $tmpdir = $ENV{GPTMPDIR} || $ENV{TMPDIR} || $ENV{GPHELP_TMPDIR} || "/tmp";
                    128:   $texfile = "$tmpdir/gp.help$$";
                    129:
                    130:   open(IN,"translations") || die("Could not find translation file, docdir='$docdir'");
                    131:   while(<IN>)
                    132:   {
                    133:     chomp; @_ = split(/ *\@ */);
                    134:     $key = shift(@_);
                    135:     $transl{$key} = join('@',@_);
                    136:   }
                    137:   close(IN);
                    138: }
                    139:
                    140: sub not_found
                    141: {
                    142:   local($help) = shift;
                    143:   $help =~ s/\\\\/_B#K#S_/g;
                    144:   $help =~ s/\\(.)/$1/g;
                    145:   $help =~ s/_B#K#S_/\\/g;
                    146:   print "'$help' not found !\n";
                    147: }
                    148:
                    149: sub choose_chap
                    150: {
                    151:   while (s/\@([0-9])$//)
                    152:     { $docfile = "usersch$1.tex"; }
                    153:   if (-r $docfile) { $pipe = ""; }
                    154:   else
                    155:   {
                    156:     die "Cannot find $docfile"
                    157:       if (! -r "$docfile.z" &&
                    158:           ! -r "$docfile.gz" &&
                    159:           ! -r "$docfile.Z");
                    160:     $pipe = $zcat;
                    161:   }
                    162: }
                    163:
                    164: use POSIX 'setsid';
                    165:
                    166: sub open_dvi_then_quit
                    167: {
                    168:   local($dvifile, $viewer)= @_;
                    169:   $dvifile = "$docdir/$dvifile" if (! -f "$dvifile");
                    170:   die "could not find $dvifile" if (! -f "$dvifile");
                    171:   (!$ENV{DISPLAY} && !$ENV{GPXDVI}) && die "xdvi needs X-Windows";
                    172:   print "displaying \'$docdir/$dvifile\'.";
                    173:   setsid; # detach from terminal (^C will not kill xdvi)
                    174:   system("$viewer $dvifile 2>/dev/null >/dev/null&");
                    175:   cleanexit();
                    176: }
                    177:
                    178: sub treat
                    179: {
                    180:   local($help);
                    181:   $_ = $_[0];
                    182:   s/_QUOTE/'/g;
                    183:   s/_BACKQUOTE/`/g;
                    184:   s/_DOUBQUOTE/"/g;
                    185:   s/^ *"(.*)"([^"]*) *$/$1$2/;
                    186:   if (s/\@$//)
                    187:   {
                    188:     $found = 0;
                    189:     $searchall = 1;
                    190:     $help = $_;
                    191:     while (<usersch*.tex*>)
                    192:     {
                    193:       if (/usersch(.*)\.tex/)
                    194:       {
                    195:         &treat("$help\@$1");
                    196:         if ($apropos && $#list > 0 || $#sentence_list > 0)
                    197:         {
                    198:           print "\nChapter $1:\n";
                    199:           print "==========\n";
                    200:           &apropos_final_print();
                    201:         }
                    202:       }
                    203:     }
                    204:     return not_found($help) if (!$found && !$apropos);
                    205:     $searchall = 0;
                    206:     $apropos = 0; return;
                    207:   }
                    208:   &choose_chap;
                    209:
                    210:   if (!$apropos)
                    211:   {
                    212:     open_dvi_then_quit("users.dvi",$xdvi) if (/^$/);
                    213:     open_dvi_then_quit("tutorial.dvi",$xdvi) if (/^tutorial$/);
                    214:     open_dvi_then_quit("refcard.dvi",$xdviref) if (/^refcard$/);
                    215:   }
                    216:
                    217:   if (!$apropos && $transl{$_}) { $_ = $transl{$_}; &choose_chap; }
                    218:   s/(\W)/\\$1/g;
                    219:       ($pipe && open(DOC,"$pipe $docfile |"))
                    220:   || (!$pipe && open(DOC,"$docfile")) || die "Cannot open $docfile: $!";
                    221:   return &apropos($_) if ($apropos);
                    222:   if (/^\\[<>=!]=?|[|&]{1,2}$/)
                    223:     { $_ = 'Comparison and boolean operators'; }
                    224:   $help = $_;
                    225:   while (<DOC>)
                    226:   {
                    227:     if (/^\\(subsubsec[a-z]*|subsec[a-z]*|section|chapter){$help}/)
                    228:       { $first = $_; last; }
                    229:   }
                    230:   if (eof(DOC))
                    231:   {
                    232:     &not_found($help) if (!$searchall);
                    233:     return;
                    234:   }
                    235:   $found = 1;
                    236:
                    237:   if (!$detex) { &tex(); return; }
                    238:
                    239:   &detex(); print "\n" if (!$fromgp);
                    240:   do {local $/; <DOC>} if $^O eq 'os2' and $pipe; # Avoid broken pipe from zcat
                    241:   close(DOC);
                    242: }
                    243:
                    244: #
                    245: #  A propos
                    246: #
                    247:
                    248: sub apropos_print_list
                    249: {
                    250:   $current = "";
                    251:   @_ = sort(@_);
                    252:   for (@_)
                    253:   {
                    254:     next if ($_ eq $current);
                    255:     $current = $_; print "$indent$_\n";
                    256:   }
                    257: }
                    258:
                    259: sub apropos_raw_print
                    260: {
                    261:   $indent = "";
                    262:   &apropos_print_list(@sentence_list);
                    263:   &apropos_print_list(@list);
                    264: }
                    265:
                    266: sub apropos_final_print
                    267: {
                    268:   local($maxlen) = 0;
                    269:   local($i,$nbcol,$current);
                    270:   local($cols) = ($ENV{'COLUMNS'} || 80) - 1;
                    271:
                    272:   if ($raw) { &apropos_raw_print(); return; }
                    273:   @list = sort(@list);
                    274:   for (@list)
                    275:   {
                    276:     $i= length($_);
                    277:     $maxlen = $i if ($i > $maxlen);
                    278:   }
                    279:   $maxlen++; $nbcol = $cols / $maxlen;
                    280:   $nbcol =~ s/\..*//;
                    281:   $nbcol-- if  ($nbcol * $maxlen == $cols);
                    282:   $nbcol = 1 if (!$nbcol);
                    283:
                    284:   $current = ""; $i = 0;
                    285:   for (@list)
                    286:   {
                    287:     next if ($_ eq $current);
                    288:     $current = $_; print($_); $i++;
                    289:     if ($i >= $nbcol)
                    290:     {
                    291:       $i=0; print "\n"; next;
                    292:     }
                    293:     print " " x ($maxlen - length($_));
                    294:   }
                    295:   print "\n" if ($i);
                    296:   if ($#sentence_list > 0)
                    297:   {
                    298:     print "\nSee also:\n" if ($#list > 0);
                    299:     $indent = "  ";
                    300:     apropos_print_list(@sentence_list);
                    301:   }
                    302: }
                    303:
                    304: sub apropos_check
                    305: {
                    306:   local($_) = $line;
                    307:   s/\n/ /g;
                    308:   return if (! /$help/);
                    309:
                    310:   $_ = $current;
                    311:   s/\\b{(.)}/\\$1/; s/\{\}//g;
                    312:   s/\\pow/^/; s/\\%/%/; s/\\bs/\\/; s/\\\#/\#/g;
                    313:   s,\+\$/\$-,+/-,;
                    314:   if (/ /) { push(@sentence_list,$_); } else { push(@list,$_); }
                    315: }
                    316:
                    317: sub apropos
                    318: {
                    319:   local($line,$current,$new);
                    320:   $help = $_[0];
                    321:   $help='\\\\pow' if ($help eq '\^');
                    322:   $help='\\\\til' if ($help eq '\~');
                    323:   @sentence_list = @list = "";
                    324:   while (<DOC>)
                    325:   {
                    326:     if (/^\\(subsubsec[a-z]*|subsec[a-z]*|section|chapter){/)
                    327:     {
                    328:       $new = &get_match($_,'{','}');
                    329:       &apropos_check();
                    330:       $current = $new; $line = "";
                    331:     }
                    332:     $line .= $_;
                    333:   }
                    334:   &apropos_check();
                    335: }
                    336:
                    337: #
                    338: #  Tex Part
                    339: #
                    340: sub pretex
                    341: {
                    342:   open(TEX,">$texfile.tex") || die "Couldn't open $texfile.tex";
                    343:   print TEX << "EOT";
                    344: \\def\\fromgphelp\{\}
                    345: \\input $docdir/parimacro.tex
                    346: EOT
                    347: }
                    348:
                    349: sub tex
                    350: {
                    351:   print TEX "$first";
                    352:   while (<DOC>)
                    353:   {
                    354:     last if /^\\(section|sub[sub]*sec)/i;
                    355:     print TEX;
                    356:   }
                    357:   close(DOC);
                    358: }
                    359:
                    360: sub posttex
                    361: {
                    362:   print TEX "\\vfill\\eject\\bye"; close(TEX);
                    363:
                    364:   chdir($tmpdir);
                    365:   system("tex $texfile.tex 2>/dev/null > /dev/null < /dev/null") == 0
                    366:     || die "could not process $texfile.dvi" if (! -f "$texfile.dvi");
                    367:   setsid; # detach from terminal (^C will not kill xdvi)
                    368:   system("($xdvi $texfile.dvi 2>/dev/null >/dev/null; rm -f $texfile.tex $texfile.dvi $texfile.log)&");
                    369: }
                    370:
                    371: sub clean
                    372: {
                    373:   unlink("$texfile.tex","$texfile.dvi","$texfile.log");
                    374: }
                    375:
                    376: #
                    377: #  Detex Part
                    378: #
                    379: sub fit_loop
                    380: {
                    381:   local($i);
                    382:   return if ($miss > 9);
                    383:   while ($miss > 0)
                    384:   {
                    385: #  print "1:$miss ";print @_;print "\n";
                    386:     for (@_) { $miss-- if (s/([?!\.;])$/$1 /);
                    387:        return if ($miss == 0);
                    388:     }
                    389: #  print "2:$miss ";print @_;print "\n";
                    390:     for (@_) { $miss-- if (s/([?!\.;]) $/$1  /);
                    391:        return if ($miss == 0);
                    392:     }
                    393: #  print "3:$miss ";print @_;print "\n";
                    394:     for (@_) { $miss-- if (s/([\),])$/$1 /);
                    395:        return if ($miss == 0);
                    396:     }
                    397: #  print "4:$miss ";print @_;print "\n";
                    398:     $i = 0;
                    399:     for (@_)
                    400:     {
                    401:       if (!$i) { $i = 1; next; }
                    402:       $miss-- if (s/^\(/ (/);
                    403:        return if ($miss == 0);
                    404:     }
                    405: #  print "5:$miss "; print @_;print "\n";
                    406:     for (@_) { $miss--; s/$/ /;
                    407:        return if ($miss == 0);
                    408:     }
                    409:   }
                    410: }
                    411:
                    412: sub fit_line
                    413: {
                    414:   local($wi, @a);
                    415:   local($l) = -1;
                    416:   local($rem) = $_[0];
                    417:   for (@l)
                    418:   {
                    419:      $l2 = $l; $l += ($_ + 1);
                    420:      last if ($l > $rem);
                    421:      $wi++;
                    422:   }
                    423:   $miss = $rem - $l2;
                    424:   splice(@l, 0, $wi);
                    425:   @a = splice(@w, 0, $wi-1); &fit_loop(@a);
                    426:   push(@a, shift(@w)); return join(' ', @a);
                    427: }
                    428:
                    429: # empty output line
                    430: sub is_void {
                    431:   local($in) = shift;
                    432:   $in =~ s/\@\[\w+\]//g;
                    433:   $in =~ s/\@[012]//g;
                    434:   ($in =~ /^\s*$/)? 1: 0;
                    435: }
                    436:
                    437: sub nl {
                    438:   push(@f_text, shift);
                    439: }
                    440:
                    441: sub format_text
                    442: {
                    443:   local($last_void) = 0;
                    444:   local($add_stuff) = 0;
                    445:   local($cols) = ($ENV{'COLUMNS'} || 80) - 1;
                    446:   local($first) = $cols - length($indent);
                    447:
                    448:   for (@text)
                    449:   {
                    450:     if (s/^\@1//)       # start verbatim
                    451:     {
                    452:       nl(&fit_line($first)) if (@w);
                    453:       nl("") if (!$last_void && !is_void($_)); # add empty line
                    454:       nl("$indent$_");
                    455:     }
                    456:     elsif (s/^\@0//)    # verbatim lines
                    457:     {
                    458:       nl("$indent$_");
                    459:     }
                    460:     elsif (s/^\@2//)       # end verbatim
                    461:     {
                    462:       nl("$indent$_");
                    463:       $last_void = is_void($_);
                    464:     }
                    465:     elsif (is_void($_))    # line is empty
                    466:     {
                    467:       next if (!$add_stuff);
                    468:       nl("") if (!$last_void);
                    469:       $last_void = $add_stuff = 0;
                    470:       nl("\@[endbold]$indent" . &fit_line($first));
                    471:       while (@w) { nl(&fit_line($cols)); }
                    472:     }
                    473:     else
                    474:     {
                    475:       $add_stuff = 1; s/^ +//;
                    476:       @_ = split(/ /, $_);
                    477:       for (@_)
                    478:       {
                    479:        s/\Q$tr{nbrk}/ /g; push(@w, $_);
                    480:         # these codes will be replaced by 1 character
                    481:         s/\@\[(obr|cbr|ouml|uuml|agrav|eacute|ldollar|pm|lt|gt|\{|\})]/\@/g;
                    482:         # the rest will be replaced by zero-width characters
                    483:        s/\@\[\w+\]//g;    push(@l, length($_));
                    484:       }
                    485:     }
                    486:   }
                    487: }
                    488:
                    489: # argument has the form s1${open}s2${close}s3
                    490: # Return 's2'. Set $remainder to 's3'.
                    491: sub get_match
                    492: {
                    493:   local ($_, $open, $close) = (shift,shift,shift);
                    494:   local (@tmp, $arg,$parity,$ok);
                    495:   local ($obr) = 1;
                    496:   $parity = ($open eq $close);
                    497:   /$open/; $_ = $'; # remove everything before (and including) first $open
                    498:
                    499:   while ($_) {
                    500:     @tmp = split(/($open|$close)/);
                    501:     while ($#tmp >= 0) {
                    502:       $_ = shift(@tmp);
                    503:       $obr++ if (/^$open$/);
                    504:       if ($parity && $obr == 2) { $ok = 1; last }
                    505:       $obr-- if (/^$close$/);
                    506:       if (!$obr) { $ok = 1; last }
                    507:       $arg .= $_;
                    508:     }
                    509:     last if ($ok);
                    510:     $_ = <DOC>;
                    511:   }
                    512:   $remainder = join('',@tmp);
                    513:   return $arg;
                    514: }
                    515:
                    516: sub detex
                    517: {
                    518:   local ($fun,$args);
                    519:   chomp;
                    520: # 1: get the function "prototype"
                    521:   $fun = &get_match($_,'{','}');
                    522:   # name
                    523:   $fun = &basic_subst($fun);
                    524:   $_ = $remainder;
                    525:   # args as $(x)$ in \subsecidx{sin}$(x)$:
                    526:   if (/^ *\$/)
                    527:   {
                    528:     $args = &basic_subst(&get_match($_,'\$','\$'));
                    529:     $_ = $remainder;
                    530:   }
                    531:   $_ = <DOC> if (!&basic_subst($_));
                    532:   # dft value as (...) in \subsecidx{echo} (default \kbd{0})
                    533:   if (/^ *\(/)
                    534:   {
                    535:     $args .= ' (' . &basic_subst(&get_match($_,'\(','\)')) . ')';
                    536:     $_ = $remainder;
                    537:   }
                    538:   $args .= ":" if ($args !~ /: *$/ && ($args || $fun !~ /: */));
                    539:
                    540:   $fun = "\@[startbold]$fun\@[endbold]$args";
                    541:   if ($raw) { print("$fun "); } else { &TeXprint($fun); }
                    542: # 2: start parsing the function description
                    543:   if ($_) { s/^ *://; &presubst(); }
                    544:   while (<DOC>)
                    545:   {
                    546:     last if /^\\(section|sub[sub]*sec)/i;
                    547:     &presubst();
                    548:   }
                    549:   if ($raw) { print join("\n", @text); return; }
                    550:
                    551:   &format_text();
                    552:   for (@f_text) { &TeXprint("$_"); }
                    553: }
                    554:
                    555: # We use the special char @ to transmit special sequences
                    556: sub inittr {
                    557:   @ou = qw( dollar nbrk startbold endbold startcode endcode
                    558:            obr cbr uuml ouml agrave eacute
                    559:            startpodcode endpodcode startlink endlink
                    560:            startbcode endbcode startbi endbi startit endit
                    561:            startword endword startlword endlword pm empty gt lt podleader );
                    562:
                    563:   @tr{@ou} = map "\@[$_]", @ou;
                    564:   $tr{dollar} = '$' if $to_pod;
                    565:
                    566:   %pr = ( dollar => '',
                    567:          ldollar => '$',       # literal dollar
                    568:          nbrk => 'S< >',
                    569:          startbold => 'B<',
                    570:          endbold => '>',
                    571:          startcode => 'C<',
                    572:          startlink => 'L<',
                    573:          endlink => '>',
                    574:          endcode => '>',
                    575:          obr => '{',
                    576:          cbr => '}',
                    577:          startpodcode => 'C<',
                    578:          endpodcode => '>',
                    579:          ( $dumb_pod
                    580:            ? (startbcode => 'B<',
                    581:               endbcode => '>',
                    582:               startbi => 'B<',
                    583:               endbi => '>',)
                    584:            : (startbcode => 'B<C<',
                    585:               endbcode => '>>',
                    586:               startbi => 'B<I<',
                    587:               endbi => '>>')),
                    588:          startit => 'I<',
                    589:          endit => '>',
                    590:          startword => 'F<',
                    591:          endword => '>',
                    592:          startlword => ' F<',
                    593:          endlword => '> ',
                    594:          pm => 'F<+->',
                    595:          "gt" => 'E<gt>',
                    596:          "lt" => 'E<lt>',
                    597:          ouml => 'E<ouml>',
                    598:          uuml => 'E<uuml>',
                    599:          eacute => 'E<eacute>',
                    600:          agrave => 'E<agrave>',
                    601:          empty => 'Z<>',
                    602:          podleader => '=',
                    603:        );
                    604: }
                    605:
                    606: sub indent_equally { my $in = shift; $in =~ s/^[ \t]*/    /mg; $in}
                    607:
                    608: sub basic_subst
                    609: {
                    610:   local($_) = shift;
                    611:
                    612:   s/(\S)[ \t]*\n[ \t]+/$1\n/gm;
                    613:   s/([^\\])\\\{/$1$tr{obr}/g;
                    614:   s/([^\\])\\\}/$1$tr{cbr}/g;
                    615:   s/([^\\])\\-/$1/g;
                    616:   s/\A\\q?quad(?![a-zA-Z])\s*/$tr{nbrk}$tr{nbrk}/;
                    617:   s|\\wwwsite|$wwwsite|g;
                    618:   s|\\miscdir|$miscdir|g;
                    619:   s/^\\def\\.*\{\n.*\n\}//gm;
                    620:   s/\\def\\.*//g;
                    621:   s(\\footnote\s*\{?\*+\}?\s*\{\s*((?:[^{}]|\{(?:[^{}]|\{[^{}]*\})*\})*)\})
                    622:     {$tr{startbold}FOOTNOTE$tr{endbold}$tr{lt}$tr{lt}$tr{lt} $1 $tr{gt}$tr{gt}$tr{gt}}g;
                    623:   s/(\{[\w\s]+)\{\}([\s\w]+\})/$1$2/g; # {nf{}init}
                    624:   s(\\op(?![a-zA-Z])\s*)({\\it op\\/})g;       # {nf{}init}
                    625:   s/\\(leavevmode|strut)(?![a-zA-Z])\s*//g;
                    626:   s/ \\funno \s*
                    627:      { \s* ((?:[^{}]|\{[^{}]*\})*) } \s*
                    628:      { \s* ((?:[^{}]|\{[^{}]*\})*) } \s*
                    629:      { \s* ((?:[^{}]|\{[^{}]*\})*) }
                    630:    /\\noindent{\\tt $1 \$\\key{$2}\$($3)}/gx;
                    631:   s/\\funs\s*\{((?:[^{}]|\{[^{}]*\})*)\}\s*\{((?:[^{}]|\{[^{}]*\})*)\}/\\fun{}{$1}{$2}/g;
                    632:   s/\\fun\s*\{([^{}]*)\}\s*\{((?:[^{}]|\{[^{}]*\})*)\}\s*\{((?:[^{}]|\{[^{}]*\})*)\}/\\kbd{$1 \\key{$2}($3)}\\sidx{$2}/g;
                    633:
                    634:   s/\\\\(?=[a-zA-Z])/\\bs /g;
                    635:   s/\\b{}\\b{}/\\bs\\bs /g;
                    636:   s/\\\\/\\bs/g;
                    637:   s/(\'\'|\`\`)/"/g unless $to_pod;     # (english) double quotes
                    638:   # asymptotic or isomorphic (~) [beware of ties]
                    639:   s/(^|[^\\]) +~/$1~/;
                    640:   s/~ */~/;
                    641:   s/(^|[^\\])~/$1$tr{nbrk}/g;           # ties
                    642:   s/\\(simeq|sim|approx)(?![a-zA-Z])/ ~ /g;
                    643:   s/\\til(?![a-zA-Z])/~/g;             # ~ (transpose)
                    644:   s/\\(~|tilde)/~/g;
                    645:
                    646:   s/\\(equiv)(?![a-zA-Z])/ = /g;
                    647:   s/\\`a/$tr{agrave}/; s/\\`{a}/$tr{agrave}/;
                    648:   s/\\"o/$tr{ouml}/;   s/\\"{o}/$tr{ouml}/;
                    649:   s/\\"u/$tr{uuml}/;   s/\\"{u}/$tr{uuml}/;
                    650:   s/\\'e/$tr{eacute}/; s/\\'{e}/$tr{eacute}/;
                    651:
                    652:   s/(^|[^\\])%.*/$1/g;                 # comments
                    653:   s/\\vadjust\s*\{\s*\\penalty\s*\d+\s*\}//g;
                    654:
                    655:   # We do not strip %\n, thus:
                    656:   s/\\kbd{\n\s*/\\kbd{/g;
                    657:   s/\$\\bf(\b|(?=[\d_]))\s*([^\$]+)\$/\$$tr{startbcode}$1$tr{endbcode}\$/g;
                    658:   s/\$/$tr{dollar}/g;                  # math mode
                    659:   s/\t/ /g; s/\\,//g; s/\\[ ;]/ /g;     # various spaces
                    660:   s/\\\///g;                   # italic correction
                    661:   s/^&+//g;                    # tab marks
                    662:   s/([^\\])&+/$1 /g;           # tab marks
                    663:   s/\\TeX\{\}/TeX/g;
                    664:   s/\\TeX(\W)/TeX$1/g;
                    665:   s/ *\\circ\b */ o /g;
                    666:   s/\\d?frac{\s*((?:[^{}]|\{[^{}]*\})*)}{\s*((?:[^{}]|\{[^{}]*\})*)}/($1)\/($2)/g;
                    667:   s(\\d?frac\s*(\d)\s*(\d))(($1/$2))g;
                    668:   s[{\s*(\w)\s*\\over(?![a-zA-Z])\s*(\w)\s*}]{($1/$2)}g;
                    669:   s[{\s*((?:[^{}]|\{[^{}]*\})*)\\over(?![a-zA-Z])\s*((?:[^{}]|\{[^{}]*\})*)}][($1)/($2)]g;
                    670:
                    671:   # \def\synt#1#2{\syn{#1}{\tt #2}}
                    672:   # \def\syn#1#2{\synx{#1}{#2}{#1}}
                    673:   s/\\synt?\{\s*((?:[^{}]|\{[^{}]*\})*)\}\{\s*((?:[^{}]|\{[^{}]*\})*)\}/\\synx{$1}{$2}{$1}/g;
                    674:   # \def\synx#1#2#3{\sidx{#3}The library syntax is $\key{#1}({#2})$}
                    675:   # Often used with embedded {}.
                    676:   s/\\synx\{\s*((?:[^{}]|\{[^{}]*\})*)\}\{\s*((?:[^{}]|\{[^{}]*\})*)\}\{((?:[^{}]|\{[^{}]*\})*)\}/\\sidx{$3}The library syntax is $tr{startbold}$1$tr{endbold}$tr{startpodcode}($2)$tr{endpodcode}/;
                    677:
                    678:   # May be used with an empty arg
                    679:   s/\\typ\{([^\}]*)\}/$tr{startcode}t_$1$tr{endcode}/g;
                    680:
                    681:   s/(\\string)?\\_/_/g;
                    682:   s/\\([#\$&%|])/$1/g;
                    683:   s/\\(hat(?![a-zA-Z])|\^)({\\?\s*})?/^/g;
                    684:   s/ *\\pow(?![a-zA-z]) */^/g;
                    685:
                    686:   s/\\neq?(?![a-zA-Z])/ != /g;
                    687:   s/\\enspace(?![a-zA-Z])/ /g;
                    688:   s/\\times(?![a-zA-Z]) */ x /g;
                    689:   s/\\infty(?![a-zA-Z]) */ oo /g;
                    690:   s/ *\\(bmod|mod) */ mod /g;
                    691:   s/ *\\pmod(?![a-zA-Z]) *\{\s*((?:[^{}]|\{[^{}]*\})*)\}/ (mod $1)/g;
                    692:   s/ *\\cdot(?![a-zA-Z]) */./g;                # Maybe " . "?
                    693:   s/ *(\\|\@)[lc]?dots(?![a-zA-Z]) */.../g;
                    694:   s/\\(log|sin|cos|lim(proj)?|tan|mod|sqrt|exp|ln|det|Re|Im|deg|wp|cap|oplus)(?![a-zA-Z])/$tr{startlword}$1$tr{endlword}/g;
                    695:   s/\\pi(?![a-zA-Z])/$tr{startword}Pi$tr{endword}/g;
                    696:   s/\\(Alpha | Beta | Chi | Delta | Epsilon | Phi | Gamma
                    697:        | Eta | Iota | vartheta | Kappa | Lambda | Mu | Nu | Omicron
                    698:        | Pi | Theta | Rho | Sigma | Tau | Ypsilon | varsigma | Omega
                    699:        | Xi | Psi | Zeta | alpha | beta | chi | delta | varepsilon | phi | gamma
                    700:        | eta | iota | varphi | kappa | lambda | mu | nu | omicron
                    701:        | pi | theta | rho | sigma | tau | ypsilon | varpi | omega
                    702:        | xi | psi | zeta | int
                    703:        | expr | seq | args | gcd | sum | prod | Re | infty )
                    704:       (?![a-zA-Z])/$tr{startword}$1$tr{endword}/xg;
                    705:   s/ *\\in(?![a-zA-Z]) */ belongs to /g;
                    706:   s/\\pm(?![a-zA-Z])/$tr{pm}/g;
                    707:   s/ *\\mid(?![a-zA-Z]) */ | /g;
                    708:
                    709:   s/\\idxtyp\{([^{}]*)\}/\\sidx{t_$1}/g;
                    710:   s/\\ref\{[^\}]*\}/$tr{startbold}??$tr{endbold}/g unless $to_pod;
                    711:   s/\\secref\{[^\}]*\}/Section ($tr{startbold}??$tr{endbold})/g unless $to_pod;
                    712:   s/\\label\{[^\}]*\}//g unless $to_pod;
                    713:
                    714:   s/\\(noindent|medskip|bigskip|smallskip|left|right)(?![a-zA-Z])[ \t]*//g;
                    715:   s/\\vfill *(\\eject)?//g;
                    716:   s/\\(q|quad)(?![a-zA-Z])\s*/  /g;
                    717:   s/\\qquad(?![a-zA-Z])\s*/    /g;
                    718:
                    719:   s/\\centerline\s*\{\s*(?:\\tt\b\s*)?(.*(\n[ \t].*)*)\}(?=\s*$)/indent_equally($1)/ge;
                    720:   s/\\centerline\s*\{\s*(?:\\tt\b\s*)?((?:[^{}]|\{[^{}]*\})*)\}/ indent_equally($1)/ge;
                    721:
                    722:   s/\\big\b//g;
                    723:
                    724:   s/\\settabs.*//;
                    725:   s/^\\\+/$tr{nbrk}/gm;
                    726:   s/\\\+//g;
                    727:   s/\\cr(?![a-zA-Z])//g;
                    728:   s/\\B(?![a-zA-Z])/\\kbd{BIL}/g;
                    729:
                    730:   s/ *([=><]) */ $1 /g;
                    731:   s/ *<  *([=<]) */ <$1 /g;
                    732:   s/ *>  *([=>]) */ >$1 /g;
                    733:   s/ *([*+-\/^&=|:]) += */ $1= /g;
                    734:   s/ *\\Rightarrow */ ==$tr{gt} /g;
                    735:   s/\\rangle(?![a-zA-Z])\s*/$tr{startcode}$tr{gt}$tr{endcode}/g;
                    736:   s/\\langle(?![a-zA-Z])\s*/$tr{startcode}$tr{lt}$tr{endcode}/g;
                    737:   s/\\rightarrow(?![a-zA-Z])\s*/$tr{startcode}--$tr{gt}$tr{endcode}/g;
                    738:   s/\\longleftrightarrow(?![a-zA-Z])\s*/$tr{startcode}$tr{lt}-----$tr{gt}$tr{endcode}/g;
                    739:   s/\\mapsto(?![a-zA-Z])\s*/$tr{startcode}|---$tr{gt}$tr{endcode}/g;
                    740:   s/ *\\geq?(?![a-zA-Z]) *([^ ])/ $tr{startcode}$tr{gt}=$tr{endcode} $1/g;
                    741:   s/ *\\leq?(?![a-zA-Z]) *([^ ])/ $tr{startcode}$tr{lt}=$tr{endcode} $1/g;
                    742:
                    743:   s/\\(vers|PARIversion)(?![a-zA-Z])/$tr{startbold}$version$tr{endbold}/;
                    744:   s/\\([QRCFZNapdf])(?![a-zA-Z])/$tr{startbi}$1$tr{endbi}$2/g;
                    745:   s/\\([QRCFZN])\1(?![a-zA-Z])/$tr{startbi}$1$tr{endbi}$2/g;
                    746:   s/\\Bbb\b\s*(\w)/$tr{startbi}$1$tr{endbi}/g;
                    747:
                    748:   s/\\([oc]br)/$tr{$1}/g;
                    749:   s/\\quo(?![a-zA-Z])/\"/g;
                    750:   s/(^|\s)\{(\w+)\}/$1$2/g;
                    751:
                    752:   s/\\p(?![a-zA-Z])/$tr{startbold}p$tr{endbold}$1/g;
                    753:   s/\\point\{([^\}]*)\}/$tr{startbold}* $1$tr{endbold}/g;
                    754:   s/\\bullet/$tr{startbold}*$tr{endbold}/g;
                    755:   s/\\misctitle\{([^\}]*)\}/$tr{startbold}$1$tr{endbold}/g;
                    756:   s/\\subsec\{([^\}]*)\}/$tr{startbold}$1$tr{endbold}/g unless $to_pod;
                    757:   s/\\teb\{([^\}]*)\}/\\sidx{$1}$tr{startbold}$1$tr{endbold}/g;
                    758:   s/\\tet\{([^\}]*)\}/\\sidx{$1}$tr{startcode}$1$tr{endcode}/g;
                    759:   s/\\tev\{([^\}]*)\}/\\sidx{$1}$tr{startit}$1$tr{endit}/g;
                    760:   s/\\\$/$tr{ldollar}/g;
                    761:   s/\\kbd\s*\{\s*</\\kbd{$tr{lt}/g if $to_pod;
                    762:   s/\\kbd\s*\{\s*>/\\kbd{$tr{gt}/g if $to_pod;
                    763:   s/\\kbd\s*\{((?:[^{}]|\{[^{}]*\})*)\}/$tr{startcode}$1$tr{endcode}/g;
                    764:
                    765:   s/\\key\{((?:[^{}]|\{[^{}]*\})*)\}/$tr{startbold}$1$tr{endbold}/g unless $refcard;
                    766:
                    767:   if ($refcard) {
                    768:     s/\\(?:key|li)\{((?:[^{}]+(?=[{}])|\{[^{}]*\})*)\}\s*\{\}[ \t]*\n/\n\n=back\n\n$1\n\n=over\n\n/g;
                    769:     s/\\(?:key|li)\{((?:[^{}]+(?=[{}])|\{[^{}]*\})*)\}\s*\{(([^{}]+(?=[{}])|\{[^{}]*\})*)\}/\n=item $tr{startcode}$2$tr{endcode}\n\n$1\n/g;
                    770:   }
                    771:
                    772:   s/\\var\{([^\}]*)\}/$tr{startit}$1$tr{endit}/g;
                    773:   s/\\fl(?![a-zA-Z])/$tr{startit}flag$tr{endit}/g;
                    774:   s/\\b{([^}]*)}/$tr{startcode}\\$1$tr{endcode}/g;
                    775:   s/\\kbdsidx/\\sidx/g;
                    776:   s/\\sidx\{[^\}]*\}//g unless $to_pod;
                    777:   s/\\[a-zA-Z]*idx\{([^\}]*)\}/$1/g unless $to_pod;
                    778:   s/\\(?:text|hbox)\s*\{ *(?:\\it\b\s*)?(([^{}]+(?=[{}])|\{[^{}]*\})*)\}/$1/g;
                    779:   s/\\(text|hbox)//g;
                    780:   s/^([ \t]+)\{ *\\(it|sl|bf|tt)\b/S<$1>{\\$2/gm;
                    781:   s/\{ *\\(it|sl) *(([^{}]+(?=[{}])|\{[^{}]*\})*)\}/$tr{startit}$2$tr{endit}/g;
                    782:   s/\{ *\\bf *(([^{}]+(?=[{}])|\{[^{}]*\})*)\}/$tr{startbold}$1$tr{endbold}/g;
                    783:   s/\{ *\\tt *(([^{}]+(?=[{}])|\{[^{}]*\})*)\}/$tr{startpodcode}$1$tr{endpodcode}/g;
                    784:   $seek=1 if (s/\{ *\\it */$tr{startit}/g);
                    785:   if ($seek) { $seek=0 if (s/\}/$tr{endit}/) }
                    786:   s/\\(backslash|bs)\{(\w)\}/\\$2/g;
                    787:   s/\\(backslash|bs)(?![a-zA-Z]) */\\/g;
                    788:
                    789:   s/\@com(.*)$/$tr{startcode}$1$tr{endcode}/g;
                    790:
                    791:   # Last resort:
                    792:   s/\\kbd\s*\{(.*?)\}/$tr{startcode}$1$tr{endcode}/g;
                    793:   s/^([ \t]{3,})\Q$tr{startcode}\E(.*)\Q$tr{endcode}\E/$1$2/gmo if $to_pod;
                    794:   # Last resort:
                    795:   s/^([ \t]{3,})\Q$tr{startcode}\E(.*?)\Q$tr{endcode}\E/$1$2/gmso if $to_pod;
                    796:   # Remove leading spaces unless have embedded wrapped code:
                    797:   s/^[ \t]+//gm if $to_pod and /^\S/ and not /^[ \t]*\n[ \t]/m;
                    798:   s/\{ *\}//g;                 # empty args
                    799:
                    800:   s{\Q$tr{startcode}\E((ftp|http)://.*?)\Q$tr{endcode}\E}{$tr{startlink}$1$tr{endlink}}go if $to_pod;
                    801:   $_;
                    802: }
                    803:
                    804: sub presubst {
                    805:   chomp;
                    806:   if ($in_prog && /(\\|\@)eprog/)
                    807:   {
                    808:     $in_prog = 0;
                    809:     $_ = "\@2" . &code_subst($`) . $tr{endcode};
                    810:     push(@text, $_);
                    811:     $_ = &basic_subst($');
                    812:   }
                    813:   elsif ($in_prog || s/\\bprog(tabs.*)?//g)
                    814:   {
                    815:     $in_prog++;  # = 1 on the \bprog line
                    816:                  # code should start on the next line
                    817:     $_ = &code_subst($_);
                    818:     s/^/\@1$tr{startcode}/ if ($in_prog == 2);
                    819:     s/^/\@0/ if ($in_prog > 2);
                    820:   }
                    821:   else { $_ = &basic_subst($_); }
                    822:   push(@text, $_);
                    823: }
                    824:
                    825: sub code_subst {
                    826:   my $in = shift;
                    827:   $in =~ s/\@dots\b/.../g;
                    828:   $in =~ s/\@miscdir\b/$miscdir/g;
                    829:   if ($in =~ /\@com(.*)/)
                    830:   {
                    831:     if ($to_pod) {
                    832:       $in = $` . &basic_subst($1) . code_subst($');
                    833:     } else {
                    834:       $in = $` . $tr{endcode} . &basic_subst($1) . $tr{startcode} . code_subst($');
                    835:     }
                    836:   }
                    837:   if ($in =~ /\@Ccom(.*)\*\//)
                    838:   {
                    839:     if ($to_pod) {
                    840:       $in = $` .               &basic_subst($1) . "*/" . &code_subst($');
                    841:     } else {
                    842:       $in = $` . $tr{endcode} . &basic_subst($1) . $tr{startcode}
                    843:                                                  . "*/" . &code_subst($');
                    844:     }
                    845:   }
                    846:   $in;
                    847: }
                    848:
                    849: sub wrap_code {
                    850:   my $in = shift;
                    851:   $in =~ s/^[ \t]+$//mg;
                    852:   $in = &code_subst($in);
                    853:   $in =~ s/^(.)/  $1/mg;
                    854:   $in =~ s/\s*\Z//;
                    855: #  $in =~ s/\\kbd\{((?:[^{}]|\{[^{}]*\})*)\}/$1/g if $to_pod;
                    856:   $in =~ s/\$([^\$\n]*)\$/$1/g if $to_pod;
                    857:   "\n\n$in\n\n";
                    858: }
                    859:
                    860: sub indexify {
                    861:   my $in = shift;
                    862:   $in =~ s/(^|and\s+)(\w+)(\$?\()/$1\\idx{$2}$3/g;
                    863:   $in =~ s/^(\\b\{\w+\})(?!\S)/\\idx{$1}/g;
                    864:   $in;
                    865: }
                    866:
                    867: sub for_index {
                    868:   my $in = shift;
                    869:   1 while $in =~ s/\Q$tr{startcode}\E(.*?)\Q$tr{endcode}\E/$1/go;
                    870:   $in;
                    871: }
                    872:
                    873: sub strip_trail { my $in = shift; $in =~ s/\s+\Z//; $in }
                    874:
                    875: # This subroutine works in paragraph mode
                    876: sub TeXprint_topod {
                    877:   s/\A\s+//;
                    878:   s/^\\def\\.*\{\n.*\n\}//gm;
                    879:   s/\\def\\.*//g;              # Repeated in basic_subst, as the next one
                    880:   s/(\{[\w\s]+)\{\}([\s\w]+\})/$1$2/g; # {rnf{}llgram}
                    881:
                    882:   s/\\vbox\s*\{\s*\\bprog/\\bprog/g;
                    883:   s/([\\\@])eprog\s*\}/$1eprog/g;
                    884:
                    885:   #  \n is below to prevent splitting on ' '
                    886:   #  We also remove ':'
                    887:   s/\\sectype\{\s*((?:[^{}]|\{[^{}]*\})*)\}\{\s*((?:[^{}]|\{[^{}]*\})*)\}/\\subsec{Type \\typ{$1} (${2}s)}\n\\sidx{$2}/g;
                    888:   s/\\sectypeindex\{\s*((?:[^{}]|\{[^{}]*\})*)\}\{\s*((?:[^{}]|\{[^{}]*\})*)\}\{\s*((?:[^{}]|\{[^{}]*\})*)\}/\\subsec{Type \\typ{$1} (${2}s)}\n\\sidx{$3}/g;
                    889:   s/\\sectypes\{\s*((?:[^{}]|\{[^{}]*\})*)\}\{\s*((?:[^{}]|\{[^{}]*\})*)\}\{\s*((?:[^{}]|\{[^{}]*\})*)\}/\\subsec{Type \\typ{$1} and \\typ{$1} (${3}s)}\n\\sidx{$3}/g;
                    890:
                    891:   # Try to guard \label/\sidx (removing possible '.')
                    892: #  This somehow breaks index...
                    893: #  s/(\\(?:section|subsec(?:ref|idx|op)?(unix)?)\s*{(?:(?:[^{}]+(?=[{}])|{[^{}]+})+)})\.?\s*\\(label|sidx)/$1\n\\$2/;
                    894:   s/(\\(?:section|subsec(?:ref|idx|op)?)\s*{(?:(?:[^{}]+(?=[{}])|{[^{}]+})+)})\.?\s*\\(label|sidx)/$1\n\\$2/;
                    895:
                    896:   # last if /\\subsec[\\{}ref]*[\\\${]$help[}\\\$]/o;
                    897:   s/\\chapter\s*{((?:[^{}]|\{[^{}]*\})*)}\s*/\n\n$tr{podleader}head1 NAME\n\nlibPARI - $1\n\n$tr{podleader}head1 DESCRIPTION\n\n/;
                    898:   s/\\appendix\s*{((?:[^{}]|\{[^{}]*\})*)}\s*/\n\n$tr{podleader}head1 NAME\n\nAppendix - $1\n\n$tr{podleader}head1 DESCRIPTION\n\n/;
                    899:   s/\\section\s*{((?:[^{}]|\{[^{}]*\})*)}\s*/"\n\n$tr{podleader}head1 " . indexify($1) . "\n\n"/e;
                    900:
                    901:   # Try to delimit by :
                    902:   s/\\subsec(?:ref|idx|op)?(?:unix)?\s*{(([^{}]+(?=[{}])|{[^{}]+})+)}((\W*default:)?[^\n:]*):\s*/"\n\n$tr{podleader}head2 " . indexify("$1$3") . "\n\n"/e;
                    903:   s/\\subsec(?:ref|idx|op)?(?:unix)?\s*{(([^{}]+(?=[{}])|{[^{}]+})+)}([^\n:]*):\s*/"\n\n$tr{podleader}head2 " . indexify("$1$3") . "\n\n"/e;
                    904:   s/\\subsubsec(?:ref|idx|op)?(?:unix)?\s*{(([^{}]+(?=[{}])|{[^{}]+})+)}([^:]*):\s*/"\n\n$tr{podleader}item " . indexify("$1$3") . "\n\n"/e;
                    905: #  s/\\subsubsec\s*{(([^{}]+(?=[{}])|{[^{}]+})+)}\s*$/"\n\n$tr{podleader}item " . indexify("$1") . "\n\n"/e;
                    906:   s/\\subsubsec\s*{(([^{}]+(?=[{}])|{[^{}]+})+)}(.*)$/"\n\n$tr{podleader}item " . indexify("$1") . "$3\n\n"/me;
                    907: #  s/\\subseckbd\s*{(([^{}]+(?=[{}])|{[^{}]+})+)}:\s*/"\n\n$tr{podleader}head2 " . indexify("$1") . "\n\n"/e;
                    908:   s/\\subseckbd\s*{(([^{}]+(?=[{}])|{[^{}]+})+)}([^:]*):\s*/"\n\n$tr{podleader}head2 " . indexify("$1$3") . "\n\n"/e;
                    909:   # Try to delimit by ' '
                    910:   s/\\subsec(?:ref|idx|op)?(?:unix)?\s*{(([^{}]+(?=[{}])|{[^{}]+})+)}(\S*)\s+/"\n\n$tr{podleader}head2 " . indexify("$1$3") . "\n\n"/e;
                    911:   s/\\subsec(?:ref|title|idx|op)?(?:unix)?\s*{(([^{}]+(?=[{}])|{[^{}]*})+)}:?\s*/"\n\n$tr{podleader}head2 " . indexify("$1") . "\n\n"/e;
                    912:
                    913:   # This is to skip preface in refcard:
                    914:   /\Q$tr{podleader}\Ehead1|\\title(?![a-zA-Z])\s*\{/o and $seen_start = 1
                    915:     or $seen_start or return;  # Skip now!
                    916:
                    917:   s/\\title\s*\{([^{}\s]*)(\s+([^{}]*))?\}(\s*\\centerline\s*\{([^{}]*)\})?\s*/$tr{podleader}head1 NAME\n\n$1 - $3.  $5\n\n/ and $seen_title++
                    918:     unless $seen_title;
                    919:   s/\\title\s*\{([^{}\s]*)(\s+([^{}]*))?\}(\s*\\centerline\s*\{([^{}]*)\})?\s*/\n\n/;
                    920:   s/\\parskip.*/\n/g;          # Up to end of the line
                    921:   #s/([A-Z])\</$1 < /g;                # Disambiguate with POD...
                    922:
                    923:   # Duplicate removal of settabs, since they may contain \hskip
                    924:   s/\\settabs.*//;
                    925:   s/^[ \t]*\\hskip\s*\w+/$tr{nbrk}/g;
                    926:   s/[ \t]*\\hskip\s*\w+/\n$tr{nbrk}/g;
                    927:   1 while s/ \\
                    928:             ( (small|big)skip | newcolumn | noindent
                    929:             | (short)?copyrightnotice | hfill | break | par
                    930:             | leavevmode | strut | endgroup | bye
                    931:              )
                    932:             (?![a-zA-Z])[ \t]*(\n\s*)
                    933:             /\n\n/gx;
                    934:
                    935:   s/'(\W)'/{\\tt '$1'}/g;
                    936:   s/(\\\w+)(\\hbox)/$1 $2/g;
                    937:   s/\\hbox\s*\{(?:\\it\b\s*)?((?:\\[\{\}]|[^{}]|\{[^{}]*\})*)\}/$1/g;
                    938:
                    939:   # substitute non-verbatim code
                    940:   $acc = '';
                    941:   pos = 0;
                    942:   while ( s/\A(.*?)\\bprog//s ) {
                    943:     $acc .= basic_subst(strip_trail($1));
                    944:     $_ .= <DOC> until /(\\|@)eprog\b/ or eof(DOC);
                    945:     $acc .= wrap_code($1) if s/\A(?:tabs[^\n]*)?(?![a-zA-Z])[ \t]*\n?(.*?)(\\|@)eprog\s*//s;
                    946:   }
                    947:   $_ = $acc . basic_subst($_);
                    948:
                    949: #  s/\\kbd\{/\{\\tt /g;                # startcode
                    950: #  s/\\typ\{/\{\\tt t_/g;      # startcode
                    951:
                    952:   s/\$\s*(\@\[startbi\][A-Z]\@\[endbi\])\s*\$/$1/g;
                    953: #  s/\\p(\b|(?=[\d_]))/B<p>/g;
                    954:   #s/\$\\bf\b\s*([^\$]+)\$/C<B<$1>>/g;
                    955:
                    956:   @lines = split /^$/m, $_;
                    957:   for (@lines) {
                    958:     s/>/\@[gt]/g unless /^\n*[ \t]/;
                    959:     s/</\@[lt]/g unless /^\n*[ \t]/;
                    960:   }
                    961:   $_ = join '', @lines;
                    962:
                    963:   s/\$\$(.*?)\$\$\s*/\n\nS<  >$tr{startcode}$1$tr{endcode}\n\n/gs;
                    964:   s/\$([^\$]+)\$/$tr{startcode}$1$tr{endcode}/g;
                    965:
                    966:   s/\\s(?:ref|idx){\s*([^{}]*)}/"X<" . for_index($1) . ">"/ge; #
                    967:   s/\\(?:ref|idx){\s*([^{}]*)}/"X<" . for_index($1) . ">$1"/ge;
                    968:
                    969: # Conflict between different versions of PARI and refcard:
                    970: # s/\\(?:key|li)\s*{(.*)}\s*{(.+)}[ \t]*\n/\n\n=item C<$2>\n\n$1\n\n/msg;
                    971: # s/\\(?:key|li)\s*{(.*)}\s*{}[ \t]*\n/\n\n=back\n\n$1\n\n=over\n\n/mgs;
                    972: # s/\\(key|var)(?![a-zA-Z])\s*{(\w+)}/C<$2>/mg;
                    973:   s/\\var\s*{X<(\w+)>(\w+)}/X<$1>$tr{startcode}$2$tr{endcode}/mg;
                    974:   s/\\var\s*{f{}lag}/$tr{startcode}flag$tr{endcode}/mg;
                    975:
                    976:   s/\\metax(?![a-zA-Z])\s*{(.*)}\s*{\s*(\w+)(?=C\<)(.*)}[ \t]*\n/\n\n=item C<L<$2>$3>\n\n$1\n\n/mg;
                    977:   s/\\metax(?![a-zA-Z])\s*{(.*)}\s*{(.*)}[ \t]*\n/\n\n=item C<$2>\n\n$1\n\n/mg;
                    978:   s/C\<\{\}=/C\<=/g;
                    979:   s/\\fl(?![a-zA-Z])/I<flag>/g;
                    980:   s/\\file(?![a-zA-Z])/F<file>/g;
                    981:   s/\\(unix|emacs)\b\s*(\{?)(\s*\\(no)?indent)?\s*/X<\U$1>$2/g;
                    982:   s/\A\\label\s*\{([\w:.-]*)\}([ \t]*\n\s*(?=[^\s=]))?/X<Label $1>/g;
                    983:   s/\\label\s*\{([\w:.-]*)\}/X<Label $1>/g;
                    984:   s/\\secref\s*\{([\w:.-]*)\}/L<Label $1>/g;
                    985:   s/\\begin(double)?indentedkeys\s*/\n\n=over\n\n/g;
                    986:   s/\\end(double)?indentedkeys\s*/\n\n=back\n\n/g;
                    987:   # begin/end group appear in very special context only
                    988:   s/\\begingroup\W.*//s;               # Eat to the end
                    989:   s/\n{3,}/\n\n/g;
                    990:   s/\\subsec\{((?:[^{}]|\{[^{}]*\})+)\}\s*/\n\n=back\n\nB<$1>\n\n=over\n\n/g; # In refcard
                    991:   # for refcard:
                    992:   s/{\\rm(?![a-zA-Z])\s*([^{}]*)}/$1/g;
                    993:   s/\\Z<>/\\/g;                        # Optimize for readability
                    994:
                    995:   # Now replace the POD stuff
                    996:   # Start with cosmetic stuff:
                    997:   $in_code = 0;
                    998:   s/(\@\[((start)|end)code\])/ ($3 ? $in_code++ : --$in_code) ? "" : $1 /ge;
                    999:
                   1000:   if ($dumb_pod) {
                   1001:     my @stack;
                   1002:     s /(\@\[((start)|end)(\w+)\])/
                   1003:       if ($3) {                        # Start
                   1004:        push @stack, $4;
                   1005:        (@stack > 1 ? "\@[end$stack[-2]]" : '') . $1
                   1006:       } else {                 # end
                   1007:        pop @stack;
                   1008:        $1 . (@stack ? "\@[start$stack[-1]]" : '')
                   1009:       }
                   1010:       /ge
                   1011:   }
                   1012:   1 while s/\@\[start(\w+)\](\s*)\@\[end\1\]/$2/g;
                   1013:
                   1014:   s/\@\[(\w+)\]/\@!$pr{$1}/g;
                   1015:   s/(\\\w+)\@!(\w)/$1 $2/g;
                   1016:   s/\@!//g;
                   1017:   s/\\([\{\}])/$1/g;
                   1018:
                   1019:   # Normalize the spacing
                   1020:   s/\n{3,}/\n\n/;
                   1021:   s/\A([ \t]*\n)+//;
                   1022:   # Single label is not healthy...
                   1023:   print "\n" if $last_glued and /\A=/; # POD markup needs a new paragraph
                   1024:   $last_glued = s/((\A|\n\n)(X<[^<>]+>)+)[ \t]*\n\n/$1\n/;
                   1025:
                   1026:   print;
                   1027: }
                   1028:
                   1029: sub color
                   1030: {
                   1031:   local($a);
                   1032:   $_ = $_[0];
                   1033:   if (/[^0-9]/ || $_ < 0 || $_ > 17)
                   1034:     { print "bad color in gphelp: $_\n"; return ""; }
                   1035:   if ($_ < 8) { $a = $_ + 30; } else { $a = $_ + 82; }
                   1036:   return "\e[0;${a}m";
                   1037: }
                   1038:
                   1039: sub TeXprint
                   1040: {
                   1041:   local($_) = $_[0];
                   1042:   s/\@\[obr\]/{/g;
                   1043:   s/\@\[cbr\]/}/g;
                   1044:   # This should better be put in Latin1...  Or Win1251?  ;-)
                   1045:   s/\@\[ouml\]/"o/g;
                   1046:   s/\@\[uuml\]/"u/g;
                   1047:   s/\@\[agrave\]/`a/g;
                   1048:   s/\@\[eacute\]/'e/g;
                   1049:   s/\@\[ldollar\]/\$/g;
                   1050:   s/\@\[end(bold|code|bcode|bi|it)\]/\e[m$ch/g;
                   1051:   s/\@\[start(bold|code|bcode|bi)\]/$cb\e[1m/g;
                   1052:   s/\@\[startit\]/$cu\e[4m/g;
                   1053:   s/\@\[(dollar|empty|endl?word|endpodcode|startl?word|startpodcode)\]//g;
                   1054:   s/\@\[pm\]/±/g;
                   1055:   s/\@\[lt\]/</g;
                   1056:   s/\@\[gt\]/>/g;
                   1057:   s/\\([\{\}])/$1/g;
                   1058:   s/\@\[nbrk\]/ /g; print "$_\n";
                   1059: }
                   1060:
                   1061: sub to_pod {
                   1062:   $to_pod = $ARGV[1];
                   1063:   inittr();
                   1064:   $parifile = $to_pod;
                   1065:   %compress = ('.gz', 'gzip -cd',
                   1066:               '.z', 'gzip -cd',
                   1067:               '.Z', 'zcat',
                   1068:              );
                   1069:   foreach $suffix (keys %compress) {
                   1070:     ($patt = $suffix) =~ s/(\W)/\\$1/;
                   1071:     if ($to_pod =~ /$patt$/) {
                   1072:       $pipe = $compress{$suffix};
                   1073:       last;
                   1074:     }
                   1075:   }
                   1076:   if ($pipe) {
                   1077:     open(DOC,"$pipe $parifile |") ||
                   1078:       die "Cannot open pipe $pipe from $parifile: $!, stopped";
                   1079:   } else {
                   1080:     open(DOC,$parifile) || die "Cannot find file $parifile: $!, stopped";
                   1081:   }
                   1082:   $/='';                       # Paragraph mode
                   1083:   while (<DOC>) {
                   1084:     &TeXprint_topod();
                   1085:   }
                   1086:   if ($pipe) {
                   1087:     close(DOC) || die "Cannot close pipe `$pipe $parifile': $!, stopped";
                   1088:   } else {
                   1089:     close(DOC) || die "Cannot close file $parifile: $!, stopped";
                   1090:   }
                   1091:   cleanexit();
                   1092: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>