Ilya Zakharevich on Thu, 21 Jan 1999 00:04:49 -0500


[Date Prev] [Date Next] [Thread Prev] [Thread Next] [Date Index] [Thread Index]

[PATCH] merge gphelp and paridoc_to_pod


I merged my 2pod converter with gphelp (trying to affect gphelp as
little as possible, since I do not know a simple way to test it).  The
results of conversion to POD are not stellar, but quite useful (at
least when this POD is converted to IBM online book format, other
converters may be not up to task).

Enjoy,
Ilya

P.S.  Online books are viewable on AIX, IBM PC-DOS, and OS/2 (native)
      and Win* (with xview.exe present).

--- ./doc/gphelp.in.orig	Mon Dec 14 14:37:08 1998
+++ ./doc/gphelp.in	Wed Jan 20 22:04:04 1999
@@ -17,6 +17,8 @@
 #  -raw   use internal format for output with @x markers, -detex is implicit
 #         (for the TeX-to-pod converter)
 #
+#  -to_pod file		convert file to POD (should be the only args)
+#
 # Granted environment variables (override):
 #  GPTMPDIR: where temporary files will go (/tmp by default).
 #  GPDOCDIR: where is manual (by default, where make install will put it).
@@ -30,6 +32,9 @@ $xdvi = $ENV{GPXDVI} || "xdvi";
 $gzip = "gzip";
 $zcat = "$gzip -dc";
 $docfile = "$docdir/usersch3.tex";
+
+&to_pod() if @ARGV == 2 && $ARGV[0] eq '-to_pod'; 
+
 &init(); &options();
 &help() if ($#ARGV < 0);
 
@@ -79,6 +84,7 @@ sub init
 {
   $gpmsg = "ugly_kludge_done\n";
   $notfound = "not found !\n";
+  &inittr();
 
   $indent = "   ";
 
@@ -238,15 +244,15 @@ sub format_text
     if (s/^\@9//)
     {
       push(@f_text, "\n$indent" . &fit_line($first)) if (!$last_void);
-      push(@f_text, "") if (/^\@1/);
+      push(@f_text, "") if (/^\@\[startbold\]/);
       push(@f_text, "$indent$_");
       $last_void=1;
     }
-    elsif (/^[\t ]*$/ || /^[\t ]*@.[\t ]*$/)
+    elsif (/^[\t ]*$/ || /^[\t ]*@\[\w+\][\t ]*$/)
     {
       next if ($last_void);
       $last_void=1;
-      push(@f_text, "\n\@0$indent" . &fit_line($first)) if (@w);
+      push(@f_text, "\n\@[endbold]$indent" . &fit_line($first)) if (@w);
       while (@w) { push(@f_text, &fit_line($cols)); }
     }
     else
@@ -255,8 +261,8 @@ sub format_text
       @_ = split(/ /, $_);
       for (@_)
       {
-	s/@@/ /g; push(@w, $_);
-	s/\@.//g; push(@l, length($_));
+	s/\Q$tr{nbrk}/ /g; push(@w, $_);
+	s/\@\[\w+\]//g; push(@l, length($_));
       }
     }
   }
@@ -269,9 +275,9 @@ sub detex
   if (/([^\}]*)\}([^:.\n]*)[ :.]*/)
   {
     if ($raw)
-      { print("\@1$1\@0$2: "); }
+      { print("\@[startbold]$1\@[endbold]$2: "); }
     else
-      { &TeXprint("\@1$1\@0$2:"); }
+      { &TeXprint("\@[startbold]$1\@[endbold]$2:"); }
     $_ = $';
   }
   push(@text, $_);
@@ -291,95 +297,320 @@ sub detex
 }
 
 # We use the special char @ to transmit special sequences
-# @1=\e[1m (start bold mode)
-# @4=\e[4m (start underline mode)
-# @0=\e[m  (start normal mode)
-# @9=\n  (start program example)
-# @@=\n  (for ties a~b --> a@@b --> a b without line break)
+
+sub inittr {
+  @ou = qw( dollar nbrk startbold endbold startcode endcode 
+	    startpodcode endpodcode
+	    startbcode endbcode startbi endbi startit endit
+	    startword endword startlword endlword pm empty gt lt podleader
+	  );
+
+  @tr{@ou} = map "\@[$_]", @ou;
+  $tr{dollar} = '$' if $to_pod;
+  
+  %pr = ( dollar => '',
+	  nbrk => 'S< >', 
+	  startbold => 'B<',
+	  endbold => '>',
+	  startcode => 'C<',
+	  endcode => '>',
+	  startpodcode => 'C<',
+	  endpodcode => '>',
+	  startbcode => 'B<C<',
+	  endbcode => '>>',
+	  startbi => 'B<I<',
+	  endbi => '>>',
+	  startit => 'I<',
+	  endit => '>',
+	  startword => 'F<',
+	  endword => '>',
+	  startlword => ' F<',
+	  endlword => '> ',
+	  pm => 'F<+->',
+	  gt => 'E<gt>',
+	  lt => 'E<lt>',
+	  empty => 'Z<>',
+	  podleader => '=',
+	);
+}
 
 sub presubst
 {
-  chop;
-  s/(\'\'|\`\`)/"/g;               # "
-  s/\\(simeq|sim|approx)\b/ ~ /g;  # asymptotic or equivalent (~)
-  s/([^\\])%.*/$1/; s/^%.*//;      # comments
-  s/\$//g;                         # math mode
-  s/\t/ /g; s/\\,//g; s/\\ / /g;# various spaces
-  s/~/@@/g;
-  s/\\til\b/~/g;                   # ~
-  s/\\\///g;                       # italic correction
-  s/([^\\])&+/$1/g;                # tab marks
-  s/\{ *\}//g;                     # empty args
-  s/\\_/_/g;
-  s/\\#/#/g;
-  s/\\\$/\$/g;
-  s/\\\&/&/g; s/\\%/%/g;
-  s/\\times\b */ x /g;
-  s/\\infty\b */oo /g;
+  chop unless $to_pod;
+  s/\\\\(?=[a-zA-Z])/\\bs /g;
+  s/\\\\/\\bs/g;
+  s/(\'\'|\`\`)/"/g unless $to_pod; # "
+  # asymptotic or equivalent (~)
+  s/(^|[^\\]) +~/$1~/;
+  s/~ */~/;
+  s/(^|[^\\])~/$1$tr{nbrk}/g;
+  s/\\(simeq|sim|approx|equiv)(?![a-zA-Z])/ ~ /g;
+  s/(^|[^\\])%.*/$1/g;		# comments
+  s/\$\\bf(\b|(?=[\d_]))\s*([^\$]+)\$/\$$tr{startbcode}$1$tr{endbcode}\$/g;
+  s/\$/$tr{dollar}/g;		# math mode
+  s/\t/ /g; s/\\,//g; s/\\[ ;]/ /g;# various spaces
+  s/\\til(?![a-zA-Z])/~/g;		# ~
+  s/\\~/~/g;
+  s/\\tilde/~/g;
+  s/\\\///g;			# italic correction
+  s/([^\\])&+/$1/g;		# tab marks
+  s/\\TeX\{\}/TeX/g;
+  s/\\TeX(\W)/TeX$1/g;
+
+  # \def\synt#1#2{\syn{#1}{\tt #2}}
+  # \def\syn#1#2{\synx{#1}{#2}{#1}}
+  s/\\synt?\{\s*((?:[^{}]|\{[^{}]*\})*)\}\{\s*((?:[^{}]|\{[^{}]*\})*)\}/\\synx{$1}{$2}{$1}/g;
+  # \def\synx#1#2#3{\sidx{#3}The library syntax is $\key{#1}({#2})$}
+  # Often used with embedded {}.
+  s/\\synx\{\s*((?:[^{}]|\{[^{}]*\})*)\}\{\s*((?:[^{}]|\{[^{}]*\})*)\}\{((?:[^{}]|\{[^{}]*\})*)\}/\\sidx{$3}The library syntax is $tr{startbold}$1$tr{endbold}$tr{startpodcode}($2)$tr{endpodcode}/;
+
+  # May be used with an empty arg
+  s/\\typ\{([^\}]*)\}/$tr{startcode}t_$1$tr{endcode}/g;
+
+  s/\{ *\}//g;			# empty args
+  s/(\\string)?\\_/_/g;
+  s/\\([#\$&%|])/$1/g;
+  s/\\(hat(?![a-zA-Z])|\^)({\\?\s*})?/^/g;
+  s/\\pow(?![a-zA-z])/^/g;
+
+  s/\\neq?(?![a-zA-Z])/ != /g;
+  s/\\enspace(?![a-zA-Z])/ /g;
+  s/\\times(?![a-zA-Z]) */ x /g;
+  s/\\infty(?![a-zA-Z]) */oo /g;
   s/ *\\(bmod|mod) */ mod /g;
-  s/ *\\cdot\b */./g;
-  s/ *\\c*dots\b */.../g;
-  s/\\(det|tan|exp|ln|log|cos|sin|Re|Im|deg)\b/$1/g;
-  s/\\(alpha|beta|eta|theta|omega|phi)/$1/g;
-  s/\\pi\b/Pi/g; s/\\pow\b/\^/g; s/\\pow([0-9])/\^$1/g;
-  s/ *\\in\b */ belongs to /g;
-  s/\\pm\b/?±/g;
-  s/ *\\mid\b */ | /g;
+  s/ *\\pmod(?![a-zA-Z]) *\{\s*((?:[^{}]|\{[^{}]*\})*)\}/ (mod $1)/g;
+  s/ *\\cdot(?![a-zA-Z]) */./g;		# Maybe " . "?
+  s/ *\\[lc]?dots(?![a-zA-Z]) */.../g;
+  s/\\(log|sin|cos|lim|tan|mod|sqrt|exp|ln|det|Re|Im|deg|wp)(?![a-zA-Z])/$tr{startlword}$1$tr{endlword}/g;
+  s/\\pi(?![a-zA-Z])/$tr{startword}Pi$tr{endword}/g;
+  s/\\(Alpha | Beta | Chi | Delta | Epsilon | Phi | Gamma
+       | Eta | Iota | vartheta | Kappa | Lambda | Mu | Nu | Omicron
+       | Pi | Theta | Rho | Sigma | Tau | Ypsilon | varsigma | Omega
+       | Xi | Psi | Zeta | alpha | beta | chi | delta | varepsilon | phi | gamma
+       | eta | iota | varphi | kappa | lambda | mu | nu | omicron
+       | pi | theta | rho | sigma | tau | ypsilon | varpi | omega
+       | xi | psi | zeta | int
+       | expr | seq | args | gcd | sum | prod | Re | infty )
+      (?![a-zA-Z])/$tr{startword}$1$tr{endword}/xg;
+  s/ *\\in(?![a-zA-Z]) */ belongs to /g;
+  s/\\pm(?![a-zA-Z])/$tr{pm}/g;
+  s/ *\\mid(?![a-zA-Z]) */ | /g;
 
+  s/^\\def\\.*\{\n.*\n\}//gm;
   s/\\def\\.*//;
-  s/\\sidx\{[^\}]*\}//g;
   s/\\idxtyp\{[^\}]*\}//g;
-  s/\\ref\{[^\}]*\}/\@1??\@0/g;
-  s/\\secref\{[^\}]*\}/Section (\@1??\@0)/g;
-  s/\\label\{[^\}]*\}//g;
-  s/\\[a-zA-Z]*idx\{([^\}]*)\}/$1/g;
+  s/\\ref\{[^\}]*\}/$tr{startbold}??$tr{endbold}/g unless $to_pod;
+  s/\\secref\{[^\}]*\}/Section ($tr{startbold}??$tr{endbold})/g unless $to_pod;
+  s/\\label\{[^\}]*\}//g unless $to_pod;
   s/\\(text|hbox)//g;
+  s/\\rightarrow(?![a-zA-Z])/C<--E<gt>>/g;
+  s/\\longleftrightarrow(?![a-zA-Z])/C<E<lt>-----E<gt>>/g;
 
-  s/\\(noindent|medskip|bigskip|smallskip|left|right)\b[ \t]*//g;
+  s/\\(noindent|medskip|bigskip|smallskip|left|right)(?![a-zA-Z])[ \t]*//g;
   s/\\vfill *\\eject//g;
-  s/\\(q|quad)\b/  /g; s/\\qquad/    /g;
-
-  s/\\settabs.*//; s/\\\+//g; s/\\cr\b//g;
+  s/\\(q|quad)(?![a-zA-Z])/  /g; 
+  s/\\qquad(?![a-zA-Z])/    /g; 
+  s/\\centerline\b/    /g;
+  s/\\big\b//g;
+
+  s/\\settabs.*//; 
+  s/\\\+//g; 
+  s/\\cr(?![a-zA-Z])//g;
 
-  s/ *\\le\b *([^ ])/<=$1/g;
-  s/ *\\ge\b *([^ ])/>=$1/g;
+  s/ *\\leq?(?![a-zA-Z]) *([^ ])/<=$1/g;
+  s/ *\\geq?(?![a-zA-Z]) *([^ ])/>=$1/g;
   s/ *([=><]) */ $1 /g;
   s/ *<  *([=<]) */ <$1 /g;
   s/ *>  *([=>]) */ >$1 /g;
   s/ *=  *= */ == /g;
 
-  s/\\vers\b/\@1$version\@0/;
-  s/\\(Q|R|C|F|Z)(\b|_)/\@1$1$2\@0/g;
+  s/\\(vers|PARIversion)(?![a-zA-Z])/$tr{startbold}$version$tr{endbold}/;
+  s/\\([QRCFZNapdf])(?![a-zA-Z])/$tr{startbi}$1$tr{endbi}$2/g;
+  s/\\([QRCFZN])\1(?![a-zA-Z])/$tr{startbi}$1$tr{endbi}$2/g;
+  s/\\Bbb\b\s*(\w)/$tr{startbi}$1$tr{endbi}/g;
 
   s/\\obr/{/g; s/\\cbr/}/g;
-  s/\\point\{([^\}]*)\}/\@1* $1\@0/g;
-  s/\\bullet/\@1*\@0/g;
-  s/\\misctitle\{([^\}]*)\}/\@1$1\@0/g;
-  s/\\subsec\{([^\}]*)\}/\@1$1\@0/g;
-  s/\\typ\{([^\}]*)\}/t_\@1$1\@0/g;
-  s/\\teb\{([^\}]*)\}/\@1$1\@0/g;
-  s/\\tet\{([^\}]*)\}/\@1$1\@0/g;
-  s/\\kbd\{([^\}]*)\}/\@1$1\@0/g;
-  s/\\key\{([^\}]*)\}/\@1$1\@0/g;
-  s/\\var\{([^\}]*)\}/\@4$1\@0/g;
-  s/\\fl\b/\@4flag\@0/g;
-  s/\\b{([^}]*)}/\@1\\$1\@0/g;
-  s/\\synx\{([^\}]*)\}\{([^\}]*)\}\{[^\}]*\}/The library syntax is \@1$1\@0($2)/;
-  s/\\synt*\{([^\}]*)\}\{([^\}]*)\}/The library syntax is \@1$1\@0($2)/;
-  s/\{ *\\it *([^\}]*) *\}/\@4$1\@0/g;
-  $seek=1 if (s/\{ *\\it */\@4/g);
-  if ($seek) { $seek=0 if (s/\}/\@0/) }
-  s/\\bs\b */\\/g;
+  s/\\quo(?![a-zA-Z])/\"/g;
+  s/(^|\s)\{(\w+)\}/$1$2/g;
 
-  $in_prog = 0 if (s/\\eprog/\@0/g);
-  if ($in_prog || s/\\bprog//g)
+  s/\\p(?![a-zA-Z])/$tr{startbold}p$tr{endbold}$1/g;
+  s/\\point\{([^\}]*)\}/$tr{startbold}* $1$tr{endbold}/g;
+  s/\\bullet/$tr{startbold}*$tr{endbold}/g;
+  s/\\misctitle\{([^\}]*)\}/$tr{startbold}$1$tr{endbold}/g;
+  s/\\subsec\{([^\}]*)\}/$tr{startbold}$1$tr{endbold}/g unless $to_pod;
+  s/\\teb\{([^\}]*)\}/\\sidx{$1}$tr{startbold}$1$tr{endbold}/g;
+  s/\\tet\{([^\}]*)\}/\\sidx{$1}$tr{startcode}$1$tr{endcode}/g;
+  s/\\tec\{\s*([^{}]*)\}\{\s*([^{}]*)\}/\\sidx{$1}$1$tr{startcode}$2$tr{endcode}/g;
+  s/\\kbd\{((?:[^{}]|\{[^{}]*\})*)\}/$tr{startcode}$1$tr{endcode}/g;
+  s/\\key\{([^\}]*)\}/$tr{startbold}$1$tr{endbold}/g;
+  s/\\var\{([^\}]*)\}/$tr{startit}$1$tr{endit}/g;
+  s/\\fl(?![a-zA-Z])/$tr{startit}flag$tr{endit}/g;
+  s/\\b{([^}]*)}/$tr{startcode}\\$1$tr{endcode}/g;
+  s/\\sidx\{[^\}]*\}//g unless $to_pod;
+  s/\\[a-zA-Z]*idx\{([^\}]*)\}/$1/g unless $to_pod;
+  s/\{ *\\(it|sl) *(([^{}]+(?=[{}])|\{[^{}]+\})*)\}/$tr{startit}$2$tr{endit}/g;
+  s/\{ *\\bf *(([^{}]+(?=[{}])|\{[^{}]+\})*)\}/$tr{startbold}$1$tr{endbold}/g;
+  s/\{ *\\tt *(([^{}]+(?=[{}])|\{[^{}]+\})*)\}/$tr{startpodcode}$1$tr{endpodcode}/g;
+  $seek=1 if (s/\{ *\\it */$tr{startit}/g);
+  if ($seek) { $seek=0 if (s/\}/$tr{endit}/) }
+  s/\\(backslash|bs)\{(\w)\}/\\$2/g;
+  s/\\(backslash|bs)(?![a-zA-Z]) */\\/g;
+
+  return if $to_pod;
+
+  $in_prog = 0 if (s/\\eprog/$tr{endbold}/g);
+  if ($in_prog || s/\\bprog(tabs.*)?//g)
   {
     $in_prog++;
-    s/^/\@9\@1/ if ($in_prog==2);
+    s/^/\@9$tr{startbold}/ if ($in_prog==2);
     s/^/\@9/ if ($in_prog>2);
   }
 }
 
+sub wrap_code {
+  my $in = shift;
+  $in =~ s/^[ \t]+$//mg;
+#  if ($in =~ /[A-Z]</ && 0) {			# No such things so early
+#    $in =~ s/^(.)/\nS<  >$1/mg;
+#  } else {
+    $in =~ s/^(.)/  $1/mg;
+#  }
+  $in
+}
+
+sub rewrap_code {	# This code got some escapes inside...
+  my $in = shift;
+  $in =~ s/((^|\n\n)[ \t]+(.|\n(?!\n))*[A-Z]<(.|\n(?!\n))*)/rewrap_lines($1)/e;
+  $in
+}
+
+sub rewrap_lines {	# This code got some escapes inside...
+  my $in = shift;
+  $in =~ s/^([ \t]+)(.*)/\nS<$1>$2\n/mg;
+  $in
+}
+
+sub indexify ($) {
+  my $in = shift;
+  $in =~ s/(^|and\s+)(\w+)(\$?\()/$1\\idx{$2}$3/g;
+  $in;
+}
+
+sub TeXprint_topod {
+  s/\A\s+//;
+  s/^\\def\\.*\{\n.*\n\}//gm;
+  s/\\def\\.*//;		# Repeated in presubst
+
+  # \def\sectype#1#2{\subsec{Type \typ{#1} (#2s):}\sidx{#2}}
+  # \def\sectypeindex#1#2#3{\subsec{Type \typ{#1} (#2):}\sidx{#3}}
+  # \def\sectypes#1#2#3{\subsec{Types \typ{#1} and \typ{#2} (#3s):}\sidx{#3}}
+
+  #  \n is below to prevent splitting on ' '
+  #  We also remove ':'
+  s/\\sectype\{\s*((?:[^{}]|\{[^{}]*\})*)\}\{\s*((?:[^{}]|\{[^{}]*\})*)\}/\\subsec{Type \\typ{$1} (${2}s)}\n\\sidx{$2}/g;
+  s/\\sectypeindex\{\s*((?:[^{}]|\{[^{}]*\})*)\}\{\s*((?:[^{}]|\{[^{}]*\})*)\}\{\s*((?:[^{}]|\{[^{}]*\})*)\}/\\subsec{Type \\typ{$1} (${2}s)}\n\\sidx{$3}/g;
+  s/\\sectypes\{\s*((?:[^{}]|\{[^{}]*\})*)\}\{\s*((?:[^{}]|\{[^{}]*\})*)\}\{\s*((?:[^{}]|\{[^{}]*\})*)\}/\\subsec{Type \\typ{$1} and \\typ{$1} (${3}s)}\n\\sidx{$3}/g;
+
+  # Try to guard \label/\sidx (removing possible '.')
+  s/(\\(?:section|subsec(?:ref|idx|op)?)\s*{(?:(?:[^{}]+(?=[{}])|{[^{}]+})+)})\.?\s*\\(label|sidx)/$1\n\\$2/;
+
+  # last if /\\subsec[\\{}ref]*[\\\${]$help[}\\\$]/o;
+  s/\\chapter\s*{((?:[^{}]|\{[^{}]*\})*)}/\n\n$tr{podleader}head1 NAME\n\nlibPARI - $1\n\n$tr{podleader}head1 DESCRIPTION\n\n/;
+  s/\\section\s*{((?:[^{}]|\{[^{}]*\})*)}/"\n\n$tr{podleader}head1 " . indexify($1) . "\n\n"/e;
+
+  # Try to delimit by :
+  s/\\subsec(?:ref|idx|op)?\s*{(([^{}]+(?=[{}])|{[^{}]+})+)}([^\n:]*):\s*/"\n\n$tr{podleader}head2 " . indexify("$1$3") . "\n\n"/e;
+  s/\\subsubsec(?:ref|idx|op)?(?:unix)?\s*{(([^{}]+(?=[{}])|{[^{}]+})+)}([^:]*):\s*/"\n\n$tr{podleader}item " . indexify("$1$3") . "\n\n"/e;
+  # Try to delimit by ' '
+  s/\\subsec(?:ref|idx|op)?\s*{(([^{}]+(?=[{}])|{[^{}]+})+)}(\S*)\s+/"\n\n$tr{podleader}head2 " . indexify("$1$3") . "\n\n"/e;
+  s/\\subsec(?:ref|title|idx|op)?\s*{(([^{}]+(?=[{}])|{[^{}]*})+)}:?\s*/"\n\n$tr{podleader}head2 " . indexify("$1") . "\n\n"/e;
+
+  # This is to skip preface in refcard:
+  /\Q$tr{podleader}\Ehead1|\\title(?![a-zA-Z])\s*\{/ and $seen_start = 1
+    or $seen_start or return;	# Skip now!
+
+  s/\\title\s*\{([^{}\s]*)(\s+([^{}]*))?\}(\s*\\centerline\s*\{([^{}]*)\})?/$tr{podleader}head1 NAME\n\n$1 - $3.  $5\n\n/ and $seen_title++ 
+    unless $seen_title;
+  s/\\title\s*\{([^{}\s]*)(\s+([^{}]*))?\}(\s*\\centerline\s*\{([^{}]*)\})?/\n\n/;
+  s/\\parskip.*/\n/g;		# Up to end of the line
+  #s/([A-Z])\</$1 < /g;		# Disambiguate with POD...
+  s/\\((small|big)skip|newcolumn|noindent|(short)?copyrightnotice|hfill|break|par|leavevmode|strut|endgroup|bye)(?![a-zA-Z])[ \t]*/\n\n/g;
+  s/^[ \t]*\\hskip\s*\w+//gm;
+
+  s/'(\W)'/{\\tt '$1'}/g;
+  s/(\\\w+)(\\hbox)/$1 $2/g;
+  s/\\hbox\s*\{((?:\\[\{\}]|[^{}]|\{[^{}]*\})*)\}/$1/g;
+  s/\\h\b/ /g;
+
+  # XXXX ????
+  s/^{\\tt\s*\\obeylines\s*(([^{}]+(?=[{}])|{[^{}]*})+)}/\bprog $1 \eprog/g;
+  s/\\bprog(?:tabs[^\n]*)?(?![a-zA-Z])\s*(.*?)\\eprog/wrap_code($1)/ges;
+
+  presubst();
+
+#  s/\\kbd\{/\{\\tt /g;		# startcode
+#  s/\\typ\{/\{\\tt t_/g;	# startcode
+
+  s/\$\s*(\@\[startbi\][A-Z]\@\[endbi\])\s*\$/$1/g;
+#  s/\\([RQZCF])(\b|(?=[\d_]))/B<I<$1>>/g;
+#  s/\\p(\b|(?=[\d_]))/B<p>/g;
+  #s/\$\\bf\b\s*([^\$]+)\$/C<B<$1>>/g;
+
+  @lines = split /^$/m, $_;
+  for (@lines) {
+    s/>/\@[gt]/g unless /^\s/;
+    s/</\@[lt]/g unless /^\s/;
+  }
+  $_ = join '', @lines;
+
+  s/\$\$(.*?)\$\$[ \t]*/\n\nS<  >C<$1>\n\n/gs;
+  s/\$([^\$]+)\$/C<$1>/g;
+
+  s/\\d?frac{\s*((?:[^{}]|\{[^{}]*\})*)}{\s*((?:[^{}]|\{[^{}]*\})*)}/($1)\/($2)/g;
+
+  s/\\s(?:ref|idx){\s*([^{}]*)}/X<$1>/g; # 
+  s/\\(?:ref|idx){\s*([^{}]*)}/X<$1>$1/g;
+
+
+#  s/\\(backslash|bs)\s*(\b|(?=[\d_]|C\<))/\\Z<>/g;
+#  s/\\bmod\b/ mod /g;
+
+  #s/\\pm(\b|(?=[\d_]))/F<+->/g;
+  #s/\\noindent(\b|(?=[\d_]))/  /g;
+
+  # Conflict between different versions of PARI and refcard:
+  s/\\(?:key|li)(?![a-zA-Z])\s*{(.*)}\s*{(.+)}[ \t]*\n/\n\n=item C<$2>\n\n$1\n\n/mg;
+  s/\\(?:key|li)(?![a-zA-Z])\s*{(.*)}\s*{}[ \t]*\n/\n\n=back\n\n$1\n\n=over\n\n/mg;
+  s/\\(key|var)(?![a-zA-Z])\s*{(\w+)}/C<$2>/mg;
+  s/\\var(?![a-zA-Z])\s*{X<(\w+)>(\w+)}/X<$1>C<$2>/mg;
+  s/\\var(?![a-zA-Z])\s*{f{}lag}/C<flag>/mg;
+
+  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;
+  s/\\metax(?![a-zA-Z])\s*{(.*)}\s*{(.*)}[ \t]*\n/\n\n=item C<$2>\n\n$1\n\n/mg;
+  s/C\<\{\}=/C\<=/g;
+  s/\\fl(?![a-zA-Z])/I<flag>/g;
+  s/\\file(?![a-zA-Z])/F<file>/g;
+  s/\\label\s*\{([\w:.-]*)\}/X<Label $1>/g;
+  s/\\secref\s*\{([\w:.-]*)\}/L<Label $1>/g;
+  s/\\begin(double)?indentedkeys/\n\n=over\n\n/g;
+  s/\\end(double)?indentedkeys/\n\n=back\n\n/g;
+  # begin/end group appear in very special context only
+  s/\\begingroup\W.*//s;		# Eat to the end
+  s/\n{3,}/\n\n/g;
+  s/\\subsec\{((?:[^{}]|\{[^{}]*\})+)\}/\n\n=back\n\nB<$1>\n\n=over\n\n/g; # In refcard
+  # for refcard:
+  s/{\\rm(?![a-zA-Z])\s*([^{}]*)}/$1/g;
+  s/\\Z<>/\\/g;			# Optimize for readability
+  s/\@\[(\w+)\]/\@!$pr{$1}/g;
+  s/(\\\w+)\@!(\w)/$1 $2/g;
+  s/\@!//g;
+  s/\\([\{\}])/$1/g;
+
+  #$_ = rewrap_code($_) if /(^|\n\n)[ \t]/;	# flacky yet...
+
+  print;
+}
+
 sub color
 {
   local($a);
@@ -393,9 +624,46 @@ sub color
 sub TeXprint
 {
   $_= $_[0];
-  s/ *\@0/\e[m$ch/g;
-  s/\@1 */$cb\e[1m/g;
-  s/\@4 */$cu\e[4m/g;
+  s/ *\@\[end(bold|code|bcode|bi|it)\]/\e[m$ch/g;
+  s/\@\[start(bold|code|bcode|bi)\] */$cb\e[1m/g;
+  s/\@\[startit\] */$cu\e[4m/g;
+  s/\@\[(dollar|empty|endl?word|endpodcode|startl?word|startpodcode)\]//g;
+  s/\@\[pm\]/±/g;
   s/\\([\{\}])/$1/g;
   print "$_\n";
 }
+
+
+sub to_pod {
+  $to_pod = $ARGV[1];
+  inittr();
+  $parifile = $to_pod;
+  %compress = ('.gz', 'gzip -cd',
+	       '.z', 'gzip -cd',
+	       '.Z', 'zcat',
+	      );
+  foreach $suffix (keys %compress) {
+    ($patt = $suffix) =~ s/(\W)/\\$1/;
+    if ($topod =~ /$patt$/) {
+      $pipe = $compress{$suffix};
+      last;
+    }
+  }
+  if ($pipe) {
+    open(DOC,"$pipe $parifile |") || 
+      die "Cannot open pipe $pipe from $parifile: $!, stopped";
+  } else {
+    open(DOC,$parifile) || die "Cannot find file $parifile: $!, stopped";
+  }
+  $/='';			# Paragraph mode
+  while (<DOC>) {
+    &TeXprint_topod();
+  }
+  if ($pipe) {
+    close(DOC) || die "Cannot close pipe `$pipe $parifile': $!, stopped";
+  } else {
+    close(DOC) || die "Cannot close file $parifile: $!, stopped";
+  }
+  exit 0;
+}
+