EBCDIC %HTML_Escapes for Pod::Text, plus sync patch.
[p5sagit/p5-mst-13.2.git] / lib / Pod / Text.pm
index c431728..d62b7a3 100644 (file)
@@ -1,7 +1,5 @@
 package Pod::Text;
 
-# Version 1.02
-
 =head1 NAME
 
 Pod::Text - convert POD data to formatted ASCII text
@@ -14,7 +12,7 @@ Pod::Text - convert POD data to formatted ASCII text
 
 Also:
 
-       pod2text < input.pod
+       pod2text [B<-a>] [B<->I<width>] < input.pod
 
 =head1 DESCRIPTION
 
@@ -27,7 +25,9 @@ will be used to simulate bold and underlined text.
 A separate F<pod2text> program is included that is primarily a wrapper for
 Pod::Text.
 
-The single function C<pod2text()> can take one or two arguments. The first
+The single function C<pod2text()> can take the optional options B<-a>
+for an alternative output format, then a B<->I<width> option with the
+max terminal width, followed by one or two arguments. The first
 should be the name of a file to read the pod from, or "E<lt>&STDIN" to read from
 STDIN. A second argument, if provided, should be a filehandle glob where
 output should be sent.
@@ -49,8 +49,15 @@ require Exporter;
 @ISA = Exporter;
 @EXPORT = qw(pod2text);
 
+use vars qw($VERSION);
+$VERSION = "1.0204";
+
+use locale;    # make \w work right in non-ASCII lands
+
 $termcap=0;
 
+$opt_alt_format = 0;
+
 #$use_format=1;
 
 $UNDL = "\x1b[4m";
@@ -59,8 +66,7 @@ $BOLD = "\x1b[1m";
 $NORM = "\x1b[0m";
 
 sub pod2text {
-local($file,*OUTPUT) = @_;
-*OUTPUT = *STDOUT if @_<2;
+shift if $opt_alt_format = ($_[0] eq '-a');
 
 if($termcap and !$setuptermcap) {
        $setuptermcap=1;
@@ -75,9 +81,16 @@ if($termcap and !$setuptermcap) {
 $SCREEN = ($_[0] =~ /^-(\d+)/ && (shift, $1))
        ||  $ENV{COLUMNS}
        || ($ENV{TERMCAP} =~ /co#(\d+)/)[0]
-       || (`stty -a 2>/dev/null` =~ /(\d+) columns/)[0]
+       || ($^O ne 'MSWin32' && $^O ne 'dos' && (`stty -a 2>/dev/null` =~ /(\d+) columns/)[0])
        || 72;
 
+@_ = ("<&STDIN") unless @_;
+local($file,*OUTPUT) = @_;
+*OUTPUT = *STDOUT if @_<2;
+
+local $: = $:;
+$: = " \n" if $opt_alt_format; # Do not break ``-L/lib/'' into ``- L/lib/''.
+
 $/ = "";
 
 $FANCY = 0;
@@ -86,6 +99,7 @@ $cutting = 1;
 $DEF_INDENT = 4;
 $indent = $DEF_INDENT;
 $needspace = 0;
+$begun = "";
 
 open(IN, $file) || die "Couldn't open $file: $!";
 
@@ -94,6 +108,15 @@ POD_DIRECTIVE: while (<IN>) {
        next unless /^=/;
        $cutting = 0;
     }
+    if ($begun) {
+        if (/^=end\s+$begun/) {
+             $begun = "";
+        }
+        elsif ($begun eq "text") {
+            print OUTPUT $_;
+        }
+        next;
+    }
     1 while s{^(.*?)(\t+)(.*)$}{
        $1
        . (' ' x (length($2) * 8 - length($1) % 8))
@@ -101,11 +124,26 @@ POD_DIRECTIVE: while (<IN>) {
     }me;
     # Translate verbatim paragraph
     if (/^\s/) {
-       $needspace = 1;
        output($_);
        next;
     }
 
+    if (/^=for\s+(\S+)\s*(.*)/s) {
+        if ($1 eq "text") {
+            print OUTPUT $2,"";
+        } else {
+            # ignore unknown for
+        }
+        next;
+    }
+    elsif (/^=begin\s+(\S+)\s*(.*)/s) {
+        $begun = $1;
+        if ($1 eq "text") {
+            print OUTPUT $2."";
+        }
+        next;
+    }
+
 sub prepare_for_output {
 
     s/\s*$/\n/;
@@ -116,7 +154,12 @@ sub prepare_for_output {
     $maxnest = 10;
     while ($maxnest-- && /[A-Z]</) {
        unless ($FANCY) {
-           s/C<(.*?)>/`$1'/sg;
+           if ($opt_alt_format) {
+               s/[BC]<(.*?)>/``$1''/sg;
+               s/F<(.*?)>/"$1"/sg;
+           } else {
+               s/C<(.*?)>/`$1'/sg;
+           }
        } else {
            s/C<(.*?)>/noremap("E<lchevron>${1}E<rchevron>")/sge;
        }
@@ -124,6 +167,10 @@ sub prepare_for_output {
         s/I<(.*?)>/*$1*/sg;
         # s/[CB]<(.*?)>/bold($1)/ge;
        s/X<.*?>//sg;
+
+       # LREF: a la HREF L<show this text|man/section>
+       s:L<([^|>]+)\|[^>]+>:$1:g;
+
        # LREF: a manpage(3f)
        s:L<([a-zA-Z][^\s\/]+)(\([^\)]+\))?>:the $1$2 manpage:g;
        # LREF: an =item on another manpage
@@ -184,10 +231,18 @@ sub prepare_for_output {
        if ($Cmd eq 'cut') {
            $cutting = 1;
        }
+       elsif ($Cmd eq 'pod') {
+           $cutting = 0;
+       }
        elsif ($Cmd eq 'head1') {
            makespace();
+           if ($opt_alt_format) {
+               print OUTPUT "\n";
+               s/^(.+?)[ \t]*$/==== $1 ====/;
+           }
            print OUTPUT;
            # print OUTPUT uc($_);
+           $needspace = $opt_alt_format;
        }
        elsif ($Cmd eq 'head2') {
            makespace();
@@ -195,7 +250,13 @@ sub prepare_for_output {
            #print ' ' x $DEF_INDENT, $_;
            # print "\xA7";
            s/(\w)/\xA7 $1/ if $FANCY;
-           print OUTPUT ' ' x ($DEF_INDENT/2), $_, "\n";
+           if ($opt_alt_format) {
+               s/^(.+?)[ \t]*$/==   $1   ==/;
+               print OUTPUT "\n", $_;
+           } else {
+               print OUTPUT ' ' x ($DEF_INDENT/2), $_, "\n";
+           }
+           $needspace = $opt_alt_format;
        }
        elsif ($Cmd eq 'over') {
            push(@indent,$indent);
@@ -204,7 +265,6 @@ sub prepare_for_output {
        elsif ($Cmd eq 'back') {
            $indent = pop(@indent);
            warn "Unmatched =back\n" unless defined $indent;
-           $needspace = 1;
        }
        elsif ($Cmd eq 'item') {
            makespace();
@@ -214,16 +274,16 @@ sub prepare_for_output {
                if (length() + 3 < $indent) {
                    my $paratag = $_;
                    $_ = <IN>;
-                   if (/^=/) {  # tricked!
-                       local($indent) = $indent[$#index - 1] || $DEF_INDENT;
+                   if (/^[=\s]/) {  # tricked!, or verbatim paragraph
+                       local($indent) = $indent[$#indent - 1] || $DEF_INDENT;
                        output($paratag);
                        redo POD_DIRECTIVE;
                    }
                    &prepare_for_output;
                    IP_output($paratag, $_);
                } else {
-                   local($indent) = $indent[$#index - 1] || $DEF_INDENT;
-                   output($_);
+                   local($indent) = $indent[$#indent - 1] || $DEF_INDENT;
+                   output($_, 0);
                }
            }
        }
@@ -310,14 +370,16 @@ sub fill {
 
 sub IP_output {
     local($tag, $_) = @_;
-    local($tag_indent) = $indent[$#index - 1] || $DEF_INDENT;
+    local($tag_indent) = $indent[$#indent - 1] || $DEF_INDENT;
     $tag_cols = $SCREEN - $tag_indent;
     $cols = $SCREEN - $indent;
     $tag =~ s/\s*$//;
     s/\s+/ /g;
     s/^ //;
     $str = "format OUTPUT = \n"
-       . (" " x ($tag_indent))
+       . (($opt_alt_format && $tag_indent > 1)
+          ? ":" . " " x ($tag_indent - 1)
+          : " " x ($tag_indent))
        . '@' . ('<' x ($indent - $tag_indent - 1))
        . "^" .  ("<" x ($cols - 1)) . "\n"
        . '$tag, $_'
@@ -345,6 +407,7 @@ sub output {
     } else {
        s/^/' ' x $indent/gem;
        s/^\s+\n$/\n/gm;
+       s/^  /: /s if defined($reformat) && $opt_alt_format;
        print OUTPUT;
     }
 }
@@ -383,7 +446,7 @@ sub clear_noremap {
             defined $HTML_Escapes{$3}
                ? do { $HTML_Escapes{$3} }
                : do {
-                   warn "Unknown escape: $& in $_";
+                   warn "Unknown escape: E<$1> in $_";
                    "E<$1>";
                }
         }
@@ -411,6 +474,7 @@ sub internal_lrefs {
 
 BEGIN {
 
+if (ord("\t") == 9) {
 %HTML_Escapes = (
     'amp'      =>      '&',    #   ampersand
     'lt'       =>      '<',    #   left chevron, less-than
@@ -483,6 +547,85 @@ BEGIN {
     "lchevron" =>      "\xAB", #   left chevron (double less than)
     "rchevron" =>      "\xBB", #   right chevron (double greater than)
 );
+
+}
+else {
+
+# This hash assumes code page IBM-1047:
+%HTML_Escapes = (
+    'amp'      =>      '&',    #   ampersand
+    'lt'       =>      '<',    #   left chevron, less-than
+    'gt'       =>      '>',    #   right chevron, greater-than
+    'quot'     =>      '"',    #   double quote
+
+    "Aacute"   =>      "\x65", #   capital A, acute accent
+    "aacute"   =>      "\x45", #   small a, acute accent
+    "Acirc"    =>      "\x62", #   capital A, circumflex accent
+    "acirc"    =>      "\x42", #   small a, circumflex accent
+    "AElig"    =>      "\x9E", #   capital AE diphthong (ligature)
+    "aelig"    =>      "\x9C", #   small ae diphthong (ligature)
+    "Agrave"   =>      "\x64", #   capital A, grave accent
+    "agrave"   =>      "\x44", #   small a, grave accent
+    "Aring"    =>      "\x67", #   capital A, ring
+    "aring"    =>      "\x47", #   small a, ring
+    "Atilde"   =>      "\x66", #   capital A, tilde
+    "atilde"   =>      "\x46", #   small a, tilde
+    "Auml"     =>      "\x63", #   capital A, dieresis or umlaut mark
+    "auml"     =>      "\x43", #   small a, dieresis or umlaut mark
+    "Ccedil"   =>      "\x68", #   capital C, cedilla
+    "ccedil"   =>      "\x48", #   small c, cedilla
+    "Eacute"   =>      "\x71", #   capital E, acute accent
+    "eacute"   =>      "\x51", #   small e, acute accent
+    "Ecirc"    =>      "\x72", #   capital E, circumflex accent
+    "ecirc"    =>      "\x52", #   small e, circumflex accent
+    "Egrave"   =>      "\x74", #   capital E, grave accent
+    "egrave"   =>      "\x54", #   small e, grave accent
+    "ETH"      =>      "\xAC", #   capital Eth, Icelandic
+    "eth"      =>      "\x8C", #   small eth, Icelandic
+    "Euml"     =>      "\x73", #   capital E, dieresis or umlaut mark
+    "euml"     =>      "\x53", #   small e, dieresis or umlaut mark
+    "Iacute"   =>      "\x75", #   capital I, acute accent
+    "iacute"   =>      "\x55", #   small i, acute accent
+    "Icirc"    =>      "\x76", #   capital I, circumflex accent
+    "icirc"    =>      "\x56", #   small i, circumflex accent
+    "Igrave"   =>      "\x75", #   capital I, grave accent
+    "igrave"   =>      "\x55", #   small i, grave accent
+    "Iuml"     =>      "\x77", #   capital I, dieresis or umlaut mark
+    "iuml"     =>      "\x57", #   small i, dieresis or umlaut mark
+    "Ntilde"   =>      "\x69", #   capital N, tilde
+    "ntilde"   =>      "\x49", #   small n, tilde
+    "Oacute"   =>      "\xEE", #   capital O, acute accent
+    "oacute"   =>      "\xCE", #   small o, acute accent
+    "Ocirc"    =>      "\xEB", #   capital O, circumflex accent
+    "ocirc"    =>      "\xCB", #   small o, circumflex accent
+    "Ograve"   =>      "\xED", #   capital O, grave accent
+    "ograve"   =>      "\xCD", #   small o, grave accent
+    "Oslash"   =>      "\x80", #   capital O, slash
+    "oslash"   =>      "\x70", #   small o, slash
+    "Otilde"   =>      "\xEF", #   capital O, tilde
+    "otilde"   =>      "\xCF", #   small o, tilde
+    "Ouml"     =>      "\xEC", #   capital O, dieresis or umlaut mark
+    "ouml"     =>      "\xCC", #   small o, dieresis or umlaut mark
+    "szlig"    =>      "\x59", #   small sharp s, German (sz ligature)
+    "THORN"    =>      "\xAE", #   capital THORN, Icelandic
+    "thorn"    =>      "\x8E", #   small thorn, Icelandic
+    "Uacute"   =>      "\xFE", #   capital U, acute accent
+    "uacute"   =>      "\xDE", #   small u, acute accent
+    "Ucirc"    =>      "\xFB", #   capital U, circumflex accent
+    "ucirc"    =>      "\xDB", #   small u, circumflex accent
+    "Ugrave"   =>      "\xFD", #   capital U, grave accent
+    "ugrave"   =>      "\xDD", #   small u, grave accent
+    "Uuml"     =>      "\xFC", #   capital U, dieresis or umlaut mark
+    "uuml"     =>      "\xDC", #   small u, dieresis or umlaut mark
+    "Yacute"   =>      "\xBA", #   capital Y, acute accent
+    "yacute"   =>      "\x8D", #   small y, acute accent
+    "yuml"     =>      "\xDF", #   small y, dieresis or umlaut mark
+
+    "lchevron" =>      "\x8A", #   left chevron (double less than)
+    "rchevron" =>      "\x8B", #   right chevron (double greater than)
+);
+}
 }
 
 1;