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

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

1.1       maekawa     1: #!@perl@
                      2: #
                      3: # Output extended help corresponding to a given GP command. By default,
                      4: # extract relevant information from  from the PARI manual, run TeX, then open
                      5: # an xdvi display.
                      6: #
                      7: # The manual can be compressed.
                      8: #
                      9: # Usage: gphelp keyword
                     10: #
                     11: # Command line options:
                     12: #  -k: apropos (list of relevant GP functions)
                     13: #  -detex      (-d): don't use TeX + xdvi (implicit when DISPLAY is not set).
                     14: #  -color_help (-ch) <number>: use color "number" (same scheme as in GP)
                     15: #  -color_bold (-cb) <number>: display bold in color "number"
                     16: #  -color_underline (-cu) <number>: display underlined text in color "number"
                     17: #
                     18: #  -raw   use internal format for output with @x markers, -detex is implicit
                     19: #         (for the TeX-to-pod converter)
                     20: #
                     21: #  -to_pod file                convert file to POD (should be the only args)
                     22: #
                     23: # Granted environment variables (override):
                     24: #  GPTMPDIR: where temporary files will go (/tmp by default).
                     25: #  GPDOCDIR: where is manual (by default, where make install will put it).
                     26: #  GPXDVI: which 'xdvi' program to call (xdvi by default)
                     27: #
                     28: $version= "@version@";
                     29: $docdir = $ENV{GPDOCDIR} || $ENV{GPHELP_DOCDIR} || "@miscdir@";
                     30: # no expanded material (@key@) below
                     31:
                     32: $xdvi = $ENV{GPXDVI} || "xdvi";
                     33: $gzip = "gzip";
                     34: $zcat = "$gzip -dc";
                     35:
                     36: &to_pod() if @ARGV == 2 && $ARGV[0] eq '-to_pod';
                     37:
                     38: &options(); &init();
                     39: if ($#ARGV < 0) { &treat($_); exit 0; }
                     40:
                     41: &pretex() if (!$detex);
                     42: for (@ARGV) { &treat($_); }
                     43:
                     44: if ($apropos) { &apropos_final_print(); exit 0; }
                     45: if (!$found) { &clean if (!$detex); exit 0; }
                     46:
                     47: &posttex() if (!$detex);
                     48:
                     49: print $gpmsg if (!$detex && $fromgp);
                     50: exit 0;
                     51:
                     52: #
                     53: # Procedures
                     54: #
                     55: sub help
                     56: {
                     57:   print "Usage: $0 [-k] [-detex] [-ch c1] [-cb c2] [-cu c3] keyword\n";
                     58:   print "where c1,c2,c3 denote background, bold and underline color\n";
                     59:   exit(1);
                     60: }
                     61:
                     62: sub options
                     63: {
                     64:   while ($_ = $ARGV[0])
                     65:   {
                     66:     last if (! /^-[a-z]/);
                     67:     shift(@ARGV);
                     68:     if ($_ eq "-fromgp")
                     69:       { $fromgp = 1; }
                     70:     elsif ($_ eq "-k")
                     71:       { $apropos = 1; }
                     72:     elsif ($_ eq "-detex" || $_ eq "-d")
                     73:       { $detex = 1; }
                     74:     elsif ($_ eq "-raw")
                     75:       { $raw = $detex = 1; }
                     76:     elsif ($_ eq "-color_help" || $_ eq "-ch")
                     77:       { $ch = &color(shift(@ARGV)); }
                     78:     elsif ($_ eq "-color_bold" || $_ eq "-cb")
                     79:       { $cb = &color(shift(@ARGV)); }
                     80:     elsif ($_ eq "-color_underline" || $_ eq "-cu")
                     81:       { $cu = &color(shift(@ARGV)); }
                     82:     else
                     83:       { &help(); }
                     84:   }
                     85:   $detex = 1 if (!$detex && !$ENV{DISPLAY});
                     86: }
                     87:
                     88: sub init
                     89: {
                     90:   $gpmsg = "ugly_kludge_done\n";
                     91:   $notfound = "not found !\n";
                     92:   &inittr();
                     93:
                     94:   $indent = "   ";
                     95:
                     96:   chdir($docdir);
                     97:   $docfile = "usersch3.tex";
                     98:   $tmpdir = $ENV{GPTMPDIR} || $ENV{TMPDIR} || $ENV{GPHELP_TMPDIR} || "/tmp";
                     99:   $texfile = "$tmpdir/gp.help$$";
                    100:
                    101:   open(IN,"translations") || die("Could not find translation file");
                    102:   while(<IN>)
                    103:   {
                    104:     chop; @_ = split(/ *\@ */);
                    105:     $key = shift(@_);
                    106:     $transl{$key} = join('@',@_);
                    107:   }
                    108:   close(IN);
                    109: }
                    110:
                    111: sub choose_chap
                    112: {
                    113:   while (s/\@([0-9])$//)
                    114:     { $docfile = "usersch$1.tex"; }
                    115:   if (-r $docfile) { $pipe = ""; }
                    116:   else
                    117:   {
                    118:     die "Cannot find $docfile"
                    119:       if (! -r "$docfile.z" &&
                    120:           ! -r "$docfile.gz" &&
                    121:           ! -r "$docfile.Z");
                    122:     $pipe = $zcat;
                    123:   }
                    124: }
                    125:
                    126: sub open_dvi_then_quit
                    127: {
                    128:   local($dvifile) = $_[0];
                    129:   $dvifile = "$docdir/$dvifile" if (! -f "$dvifile");
                    130:   die "could not find $dvifile" if (! -f "$dvifile");
                    131:   (!$ENV{DISPLAY} && !$ENV{GPXDVI}) && die "xdvi needs X-Windows";
                    132:   system("$xdvi $dvifile 2>/dev/null >/dev/null&");
                    133:   exit 0;
                    134: }
                    135:
                    136: sub treat
                    137: {
                    138:   $_ = $_[0]; s/^ *"(.*)"([^"]*) *$/$1$2/;
                    139:   if (s/\@$//)
                    140:   {
                    141:     $found = 0;
                    142:     $searchall = 1;
                    143:     $help = $_;
                    144:     while (<usersch*.tex*>)
                    145:     {
                    146:       if (/usersch(.*)\.tex/)
                    147:       {
                    148:         &treat("$help\@$1");
                    149:         if ($apropos && $#list > 0 || $#sentence_list > 0)
                    150:         {
                    151:           print "\nChapter $1:\n";
                    152:           print "==========\n";
                    153:           &apropos_final_print();
                    154:         }
                    155:       }
                    156:     }
                    157:     if (!$found && !$apropos) { print "$help $notfound"; return }
                    158:     $searchall = 0;
                    159:     $apropos = 0; return;
                    160:   }
                    161:   &choose_chap;
                    162:
                    163:   if (!$apropos)
                    164:   {
                    165:     open_dvi_then_quit("users.dvi") if (/^$/);
                    166:     open_dvi_then_quit("tutorial.dvi") if (/^tutorial$/);
                    167:     open_dvi_then_quit("refcard.dvi") if (/^refcard$/);
                    168:   }
                    169:
                    170:   if (!$apropos && $transl{$_}) { $_ = $transl{$_}; &choose_chap; }
                    171:   s/(\W)/\\$1/g;
                    172:       ($pipe && open(DOC,"$pipe $docfile |"))
                    173:   || (!$pipe && open(DOC,"$docfile")) || die "Cannot open $docfile: $!";
                    174:   return &apropos($_) if ($apropos);
                    175:   if (/^\\[<>=!]=?|[|&]{1,2}$/)
                    176:     { $_ = 'Comparison and boolean operators'; }
                    177:   $help = $_;
                    178:   while (<DOC>)
                    179:   {
                    180:     if (/^\\(subsubsec[a-z]*|subsec[a-z]*|section|chapter){$help}/)
                    181:       { $first = $_; last; }
                    182:   }
                    183:   if (eof(DOC) && !$searchall) { print "$help $notfound"; return }
                    184:   $found = 1;
                    185:
                    186:   if (!$detex) { &tex(); return; }
                    187:
                    188:   &detex(); print "\n" if (!$fromgp);
                    189:   close(DOC);
                    190: }
                    191:
                    192: #
                    193: #  A propos
                    194: #
                    195:
                    196: sub apropos_print_list
                    197: {
                    198:   $current = "";
                    199:   @_ = sort(@_);
                    200:   for (@_)
                    201:   {
                    202:     next if ($_ eq $current);
                    203:     $current = $_; print "$indent$_\n";
                    204:   }
                    205: }
                    206:
                    207: sub apropos_raw_print
                    208: {
                    209:   $indent = "";
                    210:   &apropos_print_list(@sentence_list);
                    211:   &apropos_print_list(@list);
                    212: }
                    213:
                    214: sub apropos_final_print
                    215: {
                    216:   local($maxlen) = 0;
                    217:   local($i,$nbcol,$current);
                    218:   local($cols) = ($ENV{'COLUMNS'} || 80) - 1;
                    219:
                    220:   if ($raw) { &apropos_raw_print(); return; }
                    221:   @list = sort(@list);
                    222:   for (@list)
                    223:   {
                    224:     $i= length($_);
                    225:     $maxlen = $i if ($i > $maxlen);
                    226:   }
                    227:   $maxlen++; $nbcol = $cols / $maxlen;
                    228:   $nbcol =~ s/\..*//;
                    229:   $nbcol-- if  ($nbcol * $maxlen == $cols);
                    230:   $nbcol = 1 if (!$nbcol);
                    231:
                    232:   $current = ""; $i = 0;
                    233:   for (@list)
                    234:   {
                    235:     next if ($_ eq $current);
                    236:     $current = $_; print($_); $i++;
                    237:     if ($i >= $nbcol)
                    238:     {
                    239:       $i=0; print "\n"; next;
                    240:     }
                    241:     print " " x ($maxlen - length($_));
                    242:   }
                    243:   print "\n" if ($i);
                    244:   if ($#sentence_list > 0)
                    245:   {
                    246:     print "\nSee also:\n" if ($#list > 0);
                    247:     $indent = "  ";
                    248:     apropos_print_list(@sentence_list);
                    249:   }
                    250: }
                    251:
                    252: sub apropos_check
                    253: {
                    254:   local($_) = $line;
                    255:   s/\n/ /g;
                    256:   return if (! /$help/);
                    257:
                    258:   $_ = $current;
                    259:   s/\{\}//g; s/\}.*//;
                    260:   s/\\pow/^/; s/\\%/%/; s/\\bs/\\/; s/\\\#/\#/g;
                    261:   s,\+\$/\$-,+/-,;
                    262:   if (/ /) { push(@sentence_list,$_); } else { push(@list,$_); }
                    263: }
                    264:
                    265: sub apropos
                    266: {
                    267:   local($line,$current,$new);
                    268:   $help = $_[0];
                    269:   $help='\\\\pow' if ($help eq '\^');
                    270:   $help='\\\\til' if ($help eq '\~');
                    271:   @sentence_list = @list = "";
                    272:   while (<DOC>)
                    273:   {
                    274:     if (/^\\(subsubsec[a-z]*|subsec[a-z]*|section|chapter){(.*)}/)
                    275:     {
                    276:       $new = $2;
                    277:       &apropos_check();
                    278:       $current = $new; $line = "";
                    279:     }
                    280:     $line .= $_;
                    281:   }
                    282:   &apropos_check();
                    283: }
                    284:
                    285: #
                    286: #  Tex Part
                    287: #
                    288: sub pretex
                    289: {
                    290:   open(TEX,">$texfile.tex") || die "Couldn't open $texfile.tex";
                    291:   print TEX << "EOT";
                    292: \\def\\fromgphelp\{\}
                    293: \\input $docdir/parimacro.tex
                    294: EOT
                    295: }
                    296:
                    297: sub tex
                    298: {
                    299:   print TEX "$first";;
                    300:   while (<DOC>)
                    301:   {
                    302:     last if /^\\(section|sub[sub]*sec)/i;
                    303:     print TEX;
                    304:   }
                    305:   close(DOC);
                    306: }
                    307:
                    308: sub posttex
                    309: {
                    310:   print TEX "\\vfill\\eject\\bye"; close(TEX);
                    311:
                    312:   chdir($tmpdir);
                    313:   system("tex $texfile.tex 2>/dev/null > /dev/null < /dev/null") == 0
                    314:     || die "could not process $texfile.dvi" if (! -f "$texfile.dvi");
                    315:   system("($xdvi $texfile.dvi 2>/dev/null >/dev/null; rm -f $texfile.tex $texfile.dvi $texfile.log)&");
                    316:   &handler(1);
                    317: }
                    318:
                    319: sub clean
                    320: {
                    321:   unlink("$texfile.tex","$texfile.dvi","$texfile.log");
                    322: }
                    323:
                    324: sub handler
                    325: {
                    326:   &clean if (!$_[0]);
                    327:   $SIG{'INT'} = 'DEFAULT';
                    328:   $SIG{'QUIT'} = 'DEFAULT';
                    329: }
                    330:
                    331: #
                    332: #  Detex Part
                    333: #
                    334: sub fit_loop
                    335: {
                    336:   return if ($miss > 9);
                    337:   while ($miss > 0)
                    338:   {
                    339: #  print "1:$miss ";print @_;print "\n";
                    340:     for (@_) { $miss-- if (s/([?!\.;])$/$1 /);
                    341:        return if ($miss == 0);
                    342:     }
                    343: #  print "2:$miss ";print @_;print "\n";
                    344:     for (@_) { $miss-- if (s/([?!\.;]) $/$1  /);
                    345:        return if ($miss == 0);
                    346:     }
                    347: #  print "3:$miss ";print @_;print "\n";
                    348:     for (@_) { $miss-- if (s/([\),])$/$1 /);
                    349:        return if ($miss == 0);
                    350:     }
                    351: #  print "4:$miss ";print @_;print "\n";
                    352:     for (@_) { $miss-- if (s/^\(/ (/);
                    353:        return if ($miss == 0);
                    354:     }
                    355: #  print "5:$miss "; print @_;print "\n";
                    356:     for (@_) { $miss--; s/$/ /;
                    357:        return if ($miss == 0);
                    358:     }
                    359:   }
                    360: }
                    361:
                    362: sub fit_line
                    363: {
                    364:   local($wi, @a);
                    365:   local($l) = -1;
                    366:   local($rem) = $_[0];
                    367:   for (@l)
                    368:   {
                    369:      $l2 = $l; $l += ($_ + 1);
                    370:      last if ($l > $rem);
                    371:      $wi++;
                    372:   }
                    373:   $miss = $rem - $l2;
                    374:   splice(@l, 0, $wi);
                    375:   @a = splice(@w, 0, $wi-1); &fit_loop(@a);
                    376:   push(@a, shift(@w)); return join(' ', @a);
                    377: }
                    378:
                    379: sub format_text
                    380: {
                    381:   local($last_void) = 0;
                    382:   local($cols) = ($ENV{'COLUMNS'} || 80) - 1;
                    383:   local($first) = $cols - length($indent);
                    384:
                    385:   for (@text)
                    386:   {
                    387:     if (s/^\@9//)
                    388:     {
                    389:       push(@f_text, "\n$indent" . &fit_line($first)) if (!$last_void);
                    390:       push(@f_text, "") if (/^\@\[startbold\]/);
                    391:       push(@f_text, "$indent$_");
                    392:       $last_void=1;
                    393:     }
                    394:     elsif (/^[\t ]*$/ || /^[\t ]*@\[\w+\][\t ]*$/)
                    395:     {
                    396:       next if ($last_void);
                    397:       $last_void=1;
                    398:       push(@f_text, "\n\@[endbold]$indent" . &fit_line($first)) if (@w);
                    399:       while (@w) { push(@f_text, &fit_line($cols)); }
                    400:     }
                    401:     else
                    402:     {
                    403:       $last_void = 0 ;
                    404:       @_ = split(/ /, $_);
                    405:       for (@_)
                    406:       {
                    407:        s/\Q$tr{nbrk}/ /g; push(@w, $_);
                    408:        s/\@\[\w+\]//g; push(@l, length($_));
                    409:       }
                    410:     }
                    411:   }
                    412: }
                    413:
                    414: sub detex
                    415: {
                    416:   s/^\\[a-z][^\{]*\{//;
                    417:   &presubst();
                    418:   if (/([^\}]*)\.*\}\.*([^:\n]*)[ :.]*/)
                    419:   {
                    420:     if ($raw)
                    421:       { print("\@[startbold]$1\@[endbold]$2: "); }
                    422:     else
                    423:       { &TeXprint("\@[startbold]$1\@[endbold]$2:"); }
                    424:     $_ = $';
                    425:   }
                    426:   push(@text, $_);
                    427:   while (<DOC>)
                    428:   {
                    429:     last if /^\\(section|sub[sub]*sec)/i;
                    430:     &presubst(); push(@text, $_);
                    431:   }
                    432:   if ($raw)
                    433:   {
                    434:     print join("\n", @text);
                    435:     return;
                    436:   }
                    437:
                    438:   &format_text();
                    439:   for (@f_text) { &TeXprint("$_"); }
                    440: }
                    441:
                    442: # We use the special char @ to transmit special sequences
                    443: sub inittr {
                    444:   @ou = qw( dollar nbrk startbold endbold startcode endcode
                    445:            startpodcode endpodcode
                    446:            startbcode endbcode startbi endbi startit endit
                    447:            startword endword startlword endlword pm empty gt lt podleader
                    448:          );
                    449:
                    450:   @tr{@ou} = map "\@[$_]", @ou;
                    451:   $tr{dollar} = '$' if $to_pod;
                    452:
                    453:   %pr = ( dollar => '',
                    454:          nbrk => 'S< >',
                    455:          startbold => 'B<',
                    456:          endbold => '>',
                    457:          startcode => 'C<',
                    458:          endcode => '>',
                    459:          startpodcode => 'C<',
                    460:          endpodcode => '>',
                    461:          startbcode => 'B<C<',
                    462:          endbcode => '>>',
                    463:          startbi => 'B<I<',
                    464:          endbi => '>>',
                    465:          startit => 'I<',
                    466:          endit => '>',
                    467:          startword => 'F<',
                    468:          endword => '>',
                    469:          startlword => ' F<',
                    470:          endlword => '> ',
                    471:          pm => 'F<+->',
                    472:          gt => 'E<gt>',
                    473:          lt => 'E<lt>',
                    474:          empty => 'Z<>',
                    475:          podleader => '=',
                    476:        );
                    477: }
                    478:
                    479: sub presubst
                    480: {
                    481:   chop unless $to_pod;
                    482:   s/\\\\(?=[a-zA-Z])/\\bs /g;
                    483:   s/\\\\/\\bs/g;
                    484:   s/(\'\'|\`\`)/"/g unless $to_pod; # "
                    485:   # asymptotic or equivalent (~)
                    486:   s/(^|[^\\]) +~/$1~/;
                    487:   s/~ */~/;
                    488:   s/(^|[^\\])~/$1$tr{nbrk}/g;
                    489:   s/\\(simeq|sim|approx|equiv)(?![a-zA-Z])/ ~ /g;
                    490:   s/(^|[^\\])%.*/$1/g;         # comments
                    491:   s/\$\\bf(\b|(?=[\d_]))\s*([^\$]+)\$/\$$tr{startbcode}$1$tr{endbcode}\$/g;
                    492:   s/\$/$tr{dollar}/g;          # math mode
                    493:   s/\t/ /g; s/\\,//g; s/\\[ ;]/ /g;# various spaces
                    494:   s/\\til(?![a-zA-Z])/~/g;             # ~
                    495:   s/\\~/~/g;
                    496:   s/\\tilde/~/g;
                    497:   s/\\\///g;                   # italic correction
                    498:   s/([^\\])&+/$1/g;            # tab marks
                    499:   s/\\TeX\{\}/TeX/g;
                    500:   s/\\TeX(\W)/TeX$1/g;
                    501:   s/ *\\circ\b */ o /g;
                    502:
                    503:   # \def\synt#1#2{\syn{#1}{\tt #2}}
                    504:   # \def\syn#1#2{\synx{#1}{#2}{#1}}
                    505:   s/\\synt?\{\s*((?:[^{}]|\{[^{}]*\})*)\}\{\s*((?:[^{}]|\{[^{}]*\})*)\}/\\synx{$1}{$2}{$1}/g;
                    506:   # \def\synx#1#2#3{\sidx{#3}The library syntax is $\key{#1}({#2})$}
                    507:   # Often used with embedded {}.
                    508:   s/\\synx\{\s*((?:[^{}]|\{[^{}]*\})*)\}\{\s*((?:[^{}]|\{[^{}]*\})*)\}\{((?:[^{}]|\{[^{}]*\})*)\}/\\sidx{$3}The library syntax is $tr{startbold}$1$tr{endbold}$tr{startpodcode}($2)$tr{endpodcode}/;
                    509:
                    510:   # May be used with an empty arg
                    511:   s/\\typ\{([^\}]*)\}/$tr{startcode}t_$1$tr{endcode}/g;
                    512:
                    513:   s/\{ *\}//g;                 # empty args
                    514:   s/(\\string)?\\_/_/g;
                    515:   s/\\([#\$&%|])/$1/g;
                    516:   s/\\(hat(?![a-zA-Z])|\^)({\\?\s*})?/^/g;
                    517:   s/ *\\pow(?![a-zA-z]) */^/g;
                    518:
                    519:   s/\\neq?(?![a-zA-Z])/ != /g;
                    520:   s/\\enspace(?![a-zA-Z])/ /g;
                    521:   s/\\times(?![a-zA-Z]) */ x /g;
                    522:   s/\\infty(?![a-zA-Z]) */oo /g;
                    523:   s/ *\\(bmod|mod) */ mod /g;
                    524:   s/ *\\pmod(?![a-zA-Z]) *\{\s*((?:[^{}]|\{[^{}]*\})*)\}/ (mod $1)/g;
                    525:   s/ *\\cdot(?![a-zA-Z]) */./g;                # Maybe " . "?
                    526:   s/ *\\[lc]?dots(?![a-zA-Z]) */.../g;
                    527:   s/\\(log|sin|cos|lim|tan|mod|sqrt|exp|ln|det|Re|Im|deg|wp)(?![a-zA-Z])/$tr{startlword}$1$tr{endlword}/g;
                    528:   s/\\pi(?![a-zA-Z])/$tr{startword}Pi$tr{endword}/g;
                    529:   s/\\(Alpha | Beta | Chi | Delta | Epsilon | Phi | Gamma
                    530:        | Eta | Iota | vartheta | Kappa | Lambda | Mu | Nu | Omicron
                    531:        | Pi | Theta | Rho | Sigma | Tau | Ypsilon | varsigma | Omega
                    532:        | Xi | Psi | Zeta | alpha | beta | chi | delta | varepsilon | phi | gamma
                    533:        | eta | iota | varphi | kappa | lambda | mu | nu | omicron
                    534:        | pi | theta | rho | sigma | tau | ypsilon | varpi | omega
                    535:        | xi | psi | zeta | int
                    536:        | expr | seq | args | gcd | sum | prod | Re | infty )
                    537:       (?![a-zA-Z])/$tr{startword}$1$tr{endword}/xg;
                    538:   s/ *\\in(?![a-zA-Z]) */ belongs to /g;
                    539:   s/\\pm(?![a-zA-Z])/$tr{pm}/g;
                    540:   s/ *\\mid(?![a-zA-Z]) */ | /g;
                    541:
                    542:   s/^\\def\\.*\{\n.*\n\}//gm;
                    543:   s/\\def\\.*//;
                    544:   s/\\idxtyp\{[^\}]*\}//g;
                    545:   s/\\ref\{[^\}]*\}/$tr{startbold}??$tr{endbold}/g unless $to_pod;
                    546:   s/\\secref\{[^\}]*\}/Section ($tr{startbold}??$tr{endbold})/g unless $to_pod;
                    547:   s/\\label\{[^\}]*\}//g unless $to_pod;
                    548:   s/\\(text|hbox)//g;
                    549:   s/\\rightarrow(?![a-zA-Z])/C<--E<gt>>/g;
                    550:   s/\\longleftrightarrow(?![a-zA-Z])/C<E<lt>-----E<gt>>/g;
                    551:
                    552:   s/\\(noindent|medskip|bigskip|smallskip|left|right)(?![a-zA-Z])[ \t]*//g;
                    553:   s/\\vfill *\\eject//g;
                    554:   s/\\(q|quad)(?![a-zA-Z])/  /g;
                    555:   s/\\qquad(?![a-zA-Z])/    /g;
                    556:   s/\\centerline\b/    /g;
                    557:   s/\\big\b//g;
                    558:
                    559:   s/\\settabs.*//;
                    560:   s/\\\+//g;
                    561:   s/\\cr(?![a-zA-Z])//g;
                    562:
                    563:   s/ *\\leq?(?![a-zA-Z]) *([^ ])/<=$1/g;
                    564:   s/ *\\geq?(?![a-zA-Z]) *([^ ])/>=$1/g;
                    565:   s/ *([=><]) */ $1 /g;
                    566:   s/ *<  *([=<]) */ <$1 /g;
                    567:   s/ *>  *([=>]) */ >$1 /g;
                    568:   s/ *=  *= */ == /g;
                    569:
                    570:   s/\\(vers|PARIversion)(?![a-zA-Z])/$tr{startbold}$version$tr{endbold}/;
                    571:   s/\\([QRCFZNapdf])(?![a-zA-Z])/$tr{startbi}$1$tr{endbi}$2/g;
                    572:   s/\\([QRCFZN])\1(?![a-zA-Z])/$tr{startbi}$1$tr{endbi}$2/g;
                    573:   s/\\Bbb\b\s*(\w)/$tr{startbi}$1$tr{endbi}/g;
                    574:
                    575:   s/\\obr/{/g; s/\\cbr/}/g;
                    576:   s/\\quo(?![a-zA-Z])/\"/g;
                    577:   s/(^|\s)\{(\w+)\}/$1$2/g;
                    578:
                    579:   s/\\p(?![a-zA-Z])/$tr{startbold}p$tr{endbold}$1/g;
                    580:   s/\\point\{([^\}]*)\}/$tr{startbold}* $1$tr{endbold}/g;
                    581:   s/\\bullet/$tr{startbold}*$tr{endbold}/g;
                    582:   s/\\misctitle\{([^\}]*)\}/$tr{startbold}$1$tr{endbold}/g;
                    583:   s/\\subsec\{([^\}]*)\}/$tr{startbold}$1$tr{endbold}/g unless $to_pod;
                    584:   s/\\teb\{([^\}]*)\}/\\sidx{$1}$tr{startbold}$1$tr{endbold}/g;
                    585:   s/\\tet\{([^\}]*)\}/\\sidx{$1}$tr{startcode}$1$tr{endcode}/g;
                    586:   s/\\tec\{\s*([^{}]*)\}\{\s*([^{}]*)\}/\\sidx{$1}$1$tr{startcode}$2$tr{endcode}/g;
                    587:   s/\\kbd\{((?:[^{}]|\{[^{}]*\})*)\}/$tr{startcode}$1$tr{endcode}/g;
                    588:   s/\\key\{([^\}]*)\}/$tr{startbold}$1$tr{endbold}/g;
                    589:   s/\\var\{([^\}]*)\}/$tr{startit}$1$tr{endit}/g;
                    590:   s/\\fl(?![a-zA-Z])/$tr{startit}flag$tr{endit}/g;
                    591:   s/\\b{([^}]*)}/$tr{startcode}\\$1$tr{endcode}/g;
                    592:   s/\\sidx\{[^\}]*\}//g unless $to_pod;
                    593:   s/\\[a-zA-Z]*idx\{([^\}]*)\}/$1/g unless $to_pod;
                    594:   s/\{ *\\(it|sl) *(([^{}]+(?=[{}])|\{[^{}]+\})*)\}/$tr{startit}$2$tr{endit}/g;
                    595:   s/\{ *\\bf *(([^{}]+(?=[{}])|\{[^{}]+\})*)\}/$tr{startbold}$1$tr{endbold}/g;
                    596:   s/\{ *\\tt *(([^{}]+(?=[{}])|\{[^{}]+\})*)\}/$tr{startpodcode}$1$tr{endpodcode}/g;
                    597:   $seek=1 if (s/\{ *\\it */$tr{startit}/g);
                    598:   if ($seek) { $seek=0 if (s/\}/$tr{endit}/) }
                    599:   s/\\(backslash|bs)\{(\w)\}/\\$2/g;
                    600:   s/\\(backslash|bs)(?![a-zA-Z]) */\\/g;
                    601:
                    602:   return if $to_pod;
                    603:
                    604:   $in_prog = 0 if (s/\\eprog/$tr{endbold}/g);
                    605:   if ($in_prog || s/\\bprog(tabs.*)?//g)
                    606:   {
                    607:     $in_prog++;
                    608:     s/^/\@9$tr{startbold}/ if ($in_prog==2);
                    609:     s/^/\@9/ if ($in_prog>2);
                    610:   }
                    611: }
                    612:
                    613: sub wrap_code {
                    614:   my $in = shift;
                    615:   $in =~ s/^[ \t]+$//mg;
                    616: #  if ($in =~ /[A-Z]</ && 0) {                 # No such things so early
                    617: #    $in =~ s/^(.)/\nS<  >$1/mg;
                    618: #  } else {
                    619:     $in =~ s/^(.)/  $1/mg;
                    620: #  }
                    621:   $in
                    622: }
                    623:
                    624: sub rewrap_code {      # This code got some escapes inside...
                    625:   my $in = shift;
                    626:   $in =~ s/((^|\n\n)[ \t]+(.|\n(?!\n))*[A-Z]<(.|\n(?!\n))*)/rewrap_lines($1)/e;
                    627:   $in
                    628: }
                    629:
                    630: sub rewrap_lines {     # This code got some escapes inside...
                    631:   my $in = shift;
                    632:   $in =~ s/^([ \t]+)(.*)/\nS<$1>$2\n/mg;
                    633:   $in
                    634: }
                    635:
                    636: sub indexify {
                    637:   my $in = shift;
                    638:   $in =~ s/(^|and\s+)(\w+)(\$?\()/$1\\idx{$2}$3/g;
                    639:   $in;
                    640: }
                    641:
                    642: sub TeXprint_topod {
                    643:   s/\A\s+//;
                    644:   s/^\\def\\.*\{\n.*\n\}//gm;
                    645:   s/\\def\\.*//;               # Repeated in presubst
                    646:
                    647:   # \def\sectype#1#2{\subsec{Type \typ{#1} (#2s):}\sidx{#2}}
                    648:   # \def\sectypeindex#1#2#3{\subsec{Type \typ{#1} (#2):}\sidx{#3}}
                    649:   # \def\sectypes#1#2#3{\subsec{Types \typ{#1} and \typ{#2} (#3s):}\sidx{#3}}
                    650:
                    651:   #  \n is below to prevent splitting on ' '
                    652:   #  We also remove ':'
                    653:   s/\\sectype\{\s*((?:[^{}]|\{[^{}]*\})*)\}\{\s*((?:[^{}]|\{[^{}]*\})*)\}/\\subsec{Type \\typ{$1} (${2}s)}\n\\sidx{$2}/g;
                    654:   s/\\sectypeindex\{\s*((?:[^{}]|\{[^{}]*\})*)\}\{\s*((?:[^{}]|\{[^{}]*\})*)\}\{\s*((?:[^{}]|\{[^{}]*\})*)\}/\\subsec{Type \\typ{$1} (${2}s)}\n\\sidx{$3}/g;
                    655:   s/\\sectypes\{\s*((?:[^{}]|\{[^{}]*\})*)\}\{\s*((?:[^{}]|\{[^{}]*\})*)\}\{\s*((?:[^{}]|\{[^{}]*\})*)\}/\\subsec{Type \\typ{$1} and \\typ{$1} (${3}s)}\n\\sidx{$3}/g;
                    656:
                    657:   # Try to guard \label/\sidx (removing possible '.')
                    658:   s/(\\(?:section|subsec(?:ref|idx|op)?)\s*{(?:(?:[^{}]+(?=[{}])|{[^{}]+})+)})\.?\s*\\(label|sidx)/$1\n\\$2/;
                    659:
                    660:   # last if /\\subsec[\\{}ref]*[\\\${]$help[}\\\$]/o;
                    661:   s/\\chapter\s*{((?:[^{}]|\{[^{}]*\})*)}/\n\n$tr{podleader}head1 NAME\n\nlibPARI - $1\n\n$tr{podleader}head1 DESCRIPTION\n\n/;
                    662:   s/\\section\s*{((?:[^{}]|\{[^{}]*\})*)}/"\n\n$tr{podleader}head1 " . indexify($1) . "\n\n"/e;
                    663:
                    664:   # Try to delimit by :
                    665:   s/\\subsec(?:ref|idx|op)?\s*{(([^{}]+(?=[{}])|{[^{}]+})+)}([^\n:]*):\s*/"\n\n$tr{podleader}head2 " . indexify("$1$3") . "\n\n"/e;
                    666:   s/\\subsubsec(?:ref|idx|op)?(?:unix)?\s*{(([^{}]+(?=[{}])|{[^{}]+})+)}([^:]*):\s*/"\n\n$tr{podleader}item " . indexify("$1$3") . "\n\n"/e;
                    667:   # Try to delimit by ' '
                    668:   s/\\subsec(?:ref|idx|op)?\s*{(([^{}]+(?=[{}])|{[^{}]+})+)}(\S*)\s+/"\n\n$tr{podleader}head2 " . indexify("$1$3") . "\n\n"/e;
                    669:   s/\\subsec(?:ref|title|idx|op)?\s*{(([^{}]+(?=[{}])|{[^{}]*})+)}:?\s*/"\n\n$tr{podleader}head2 " . indexify("$1") . "\n\n"/e;
                    670:
                    671:   # This is to skip preface in refcard:
                    672:   /\Q$tr{podleader}\Ehead1|\\title(?![a-zA-Z])\s*\{/ and $seen_start = 1
                    673:     or $seen_start or return;  # Skip now!
                    674:
                    675:   s/\\title\s*\{([^{}\s]*)(\s+([^{}]*))?\}(\s*\\centerline\s*\{([^{}]*)\})?/$tr{podleader}head1 NAME\n\n$1 - $3.  $5\n\n/ and $seen_title++
                    676:     unless $seen_title;
                    677:   s/\\title\s*\{([^{}\s]*)(\s+([^{}]*))?\}(\s*\\centerline\s*\{([^{}]*)\})?/\n\n/;
                    678:   s/\\parskip.*/\n/g;          # Up to end of the line
                    679:   #s/([A-Z])\</$1 < /g;                # Disambiguate with POD...
                    680:   s/\\((small|big)skip|newcolumn|noindent|(short)?copyrightnotice|hfill|break|par|leavevmode|strut|endgroup|bye)(?![a-zA-Z])[ \t]*/\n\n/g;
                    681:   s/^[ \t]*\\hskip\s*\w+//gm;
                    682:
                    683:   s/'(\W)'/{\\tt '$1'}/g;
                    684:   s/(\\\w+)(\\hbox)/$1 $2/g;
                    685:   s/\\hbox\s*\{((?:\\[\{\}]|[^{}]|\{[^{}]*\})*)\}/$1/g;
                    686:   s/\\h\b/ /g;
                    687:
                    688:   # XXXX ????
                    689:   s/^{\\tt\s*\\obeylines\s*(([^{}]+(?=[{}])|{[^{}]*})+)}/\bprog $1 \eprog/g;
                    690:   s/\\bprog(?:tabs[^\n]*)?(?![a-zA-Z])\s*(.*?)\\eprog/wrap_code($1)/ges;
                    691:
                    692:   presubst();
                    693:
                    694: #  s/\\kbd\{/\{\\tt /g;                # startcode
                    695: #  s/\\typ\{/\{\\tt t_/g;      # startcode
                    696:
                    697:   s/\$\s*(\@\[startbi\][A-Z]\@\[endbi\])\s*\$/$1/g;
                    698: #  s/\\([RQZCF])(\b|(?=[\d_]))/B<I<$1>>/g;
                    699: #  s/\\p(\b|(?=[\d_]))/B<p>/g;
                    700:   #s/\$\\bf\b\s*([^\$]+)\$/C<B<$1>>/g;
                    701:
                    702:   @lines = split /^$/m, $_;
                    703:   for (@lines) {
                    704:     s/>/\@[gt]/g unless /^\s/;
                    705:     s/</\@[lt]/g unless /^\s/;
                    706:   }
                    707:   $_ = join '', @lines;
                    708:
                    709:   s/\$\$(.*?)\$\$[ \t]*/\n\nS<  >C<$1>\n\n/gs;
                    710:   s/\$([^\$]+)\$/C<$1>/g;
                    711:
                    712:   s/\\d?frac{\s*((?:[^{}]|\{[^{}]*\})*)}{\s*((?:[^{}]|\{[^{}]*\})*)}/($1)\/($2)/g;
                    713:
                    714:   s/\\s(?:ref|idx){\s*([^{}]*)}/X<$1>/g; #
                    715:   s/\\(?:ref|idx){\s*([^{}]*)}/X<$1>$1/g;
                    716:
                    717:
                    718: #  s/\\(backslash|bs)\s*(\b|(?=[\d_]|C\<))/\\Z<>/g;
                    719: #  s/\\bmod\b/ mod /g;
                    720:
                    721:   #s/\\pm(\b|(?=[\d_]))/F<+->/g;
                    722:   #s/\\noindent(\b|(?=[\d_]))/  /g;
                    723:
                    724:   # Conflict between different versions of PARI and refcard:
                    725:   s/\\(?:key|li)(?![a-zA-Z])\s*{(.*)}\s*{(.+)}[ \t]*\n/\n\n=item C<$2>\n\n$1\n\n/mg;
                    726:   s/\\(?:key|li)(?![a-zA-Z])\s*{(.*)}\s*{}[ \t]*\n/\n\n=back\n\n$1\n\n=over\n\n/mg;
                    727:   s/\\(key|var)(?![a-zA-Z])\s*{(\w+)}/C<$2>/mg;
                    728:   s/\\var(?![a-zA-Z])\s*{X<(\w+)>(\w+)}/X<$1>C<$2>/mg;
                    729:   s/\\var(?![a-zA-Z])\s*{f{}lag}/C<flag>/mg;
                    730:
                    731:   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;
                    732:   s/\\metax(?![a-zA-Z])\s*{(.*)}\s*{(.*)}[ \t]*\n/\n\n=item C<$2>\n\n$1\n\n/mg;
                    733:   s/C\<\{\}=/C\<=/g;
                    734:   s/\\fl(?![a-zA-Z])/I<flag>/g;
                    735:   s/\\file(?![a-zA-Z])/F<file>/g;
                    736:   s/\\label\s*\{([\w:.-]*)\}/X<Label $1>/g;
                    737:   s/\\secref\s*\{([\w:.-]*)\}/L<Label $1>/g;
                    738:   s/\\begin(double)?indentedkeys/\n\n=over\n\n/g;
                    739:   s/\\end(double)?indentedkeys/\n\n=back\n\n/g;
                    740:   # begin/end group appear in very special context only
                    741:   s/\\begingroup\W.*//s;               # Eat to the end
                    742:   s/\n{3,}/\n\n/g;
                    743:   s/\\subsec\{((?:[^{}]|\{[^{}]*\})+)\}/\n\n=back\n\nB<$1>\n\n=over\n\n/g; # In refcard
                    744:   # for refcard:
                    745:   s/{\\rm(?![a-zA-Z])\s*([^{}]*)}/$1/g;
                    746:   s/\\Z<>/\\/g;                        # Optimize for readability
                    747:   s/\@\[(\w+)\]/\@!$pr{$1}/g;
                    748:   s/(\\\w+)\@!(\w)/$1 $2/g;
                    749:   s/\@!//g;
                    750:   s/\\([\{\}])/$1/g;
                    751:
                    752:   #$_ = rewrap_code($_) if /(^|\n\n)[ \t]/;    # flacky yet...
                    753:
                    754:   print;
                    755: }
                    756:
                    757: sub color
                    758: {
                    759:   local($a);
                    760:   $_ = $_[0];
                    761:   if (/[^0-9]/ || $_ < 0 || $_ > 17)
                    762:     { print "bad color in gphelp: $_\n"; return ""; }
                    763:   if ($_ < 8) { $a = $_ + 30; } else { $a = $_ + 82; }
                    764:   return "\e[0;${a}m";
                    765: }
                    766:
                    767: sub TeXprint
                    768: {
                    769:   $_= $_[0];
                    770:   s/ *\@\[end(bold|code|bcode|bi|it)\]/\e[m$ch/g;
                    771:   s/\@\[start(bold|code|bcode|bi)\] */$cb\e[1m/g;
                    772:   s/\@\[startit\] */$cu\e[4m/g;
                    773:   s/\@\[(dollar|empty|endl?word|endpodcode|startl?word|startpodcode)\]//g;
                    774:   s/\@\[pm\]/±/g;
                    775:   s/\\([\{\}])/$1/g;
                    776:   s/\@\[nbrk\]/ /g; print "$_\n";
                    777: }
                    778:
                    779:
                    780: sub to_pod {
                    781:   $to_pod = $ARGV[1];
                    782:   inittr();
                    783:   $parifile = $to_pod;
                    784:   %compress = ('.gz', 'gzip -cd',
                    785:               '.z', 'gzip -cd',
                    786:               '.Z', 'zcat',
                    787:              );
                    788:   foreach $suffix (keys %compress) {
                    789:     ($patt = $suffix) =~ s/(\W)/\\$1/;
                    790:     if ($to_pod =~ /$patt$/) {
                    791:       $pipe = $compress{$suffix};
                    792:       last;
                    793:     }
                    794:   }
                    795:   if ($pipe) {
                    796:     open(DOC,"$pipe $parifile |") ||
                    797:       die "Cannot open pipe $pipe from $parifile: $!, stopped";
                    798:   } else {
                    799:     open(DOC,$parifile) || die "Cannot find file $parifile: $!, stopped";
                    800:   }
                    801:   $/='';                       # Paragraph mode
                    802:   while (<DOC>) {
                    803:     &TeXprint_topod();
                    804:   }
                    805:   if ($pipe) {
                    806:     close(DOC) || die "Cannot close pipe `$pipe $parifile': $!, stopped";
                    807:   } else {
                    808:     close(DOC) || die "Cannot close file $parifile: $!, stopped";
                    809:   }
                    810:   exit 0;
                    811: }

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