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