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>