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: ¬_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>