Annotation of embedaddon/bird/doc/sbase/dist/fmt_txt.pl, revision 1.1.1.1

1.1       misho       1: #
                      2: #  fmt_txt.pl
                      3: #
                      4: #  $Id$
                      5: #
                      6: #  TXT-specific driver stuff
                      7: #
                      8: #  © Copyright 1996, Cees de Groot
                      9: #
                     10: package LinuxDocTools::fmt_txt;
                     11: use strict;
                     12: 
                     13: use File::Copy;
                     14: use Text::EntityMap;
                     15: use LinuxDocTools::CharEnts;
                     16: use LinuxDocTools::Lang;
                     17: use LinuxDocTools::Vars;
                     18: use LinuxDocTools::Utils qw(create_temp);
                     19: 
                     20: my $txt = {};
                     21: $txt->{NAME} = "txt";
                     22: $txt->{HELP} = "";
                     23: $txt->{OPTIONS} = [
                     24:    { option => "manpage", type => "f", short => "m" },
                     25:    { option => "filter",  type => "f", short => "f" },
                     26:    { option => "blanks",  type => "i", short => "b" }
                     27: ];
                     28: $txt->{manpage} = 0;
                     29: $txt->{filter}  = 0;
                     30: $txt->{blanks}  = 3;
                     31: 
                     32: $Formats{$txt->{NAME}} = $txt;
                     33: 
                     34: #
                     35: #  Set correct NsgmlsOpts
                     36: #
                     37: $txt->{preNSGMLS} = sub
                     38: {
                     39:   if ($txt->{manpage})
                     40:     {
                     41:       $global->{NsgmlsOpts} .= " -iman ";
                     42:       $global->{charset} = "man";
                     43:     }
                     44:   else
                     45:     {
                     46:       $global->{NsgmlsOpts} .= " -ifmttxt ";
                     47:       $global->{charset} = "latin1" if $global->{charset} eq "latin";
                     48:     }
                     49: 
                     50: 
                     51:   #
                     52:   #  Is there a cleaner solution than this? Can't do it earlier,
                     53:   #  would show up in the help messages...
                     54:   #
                     55:   #  the language support ja.
                     56:   #  the charset  support nippon.
                     57:   #
                     58:   $global->{format} = $global->{charset};
                     59:   $global->{charset} = "nippon" if $global->{language} eq "ja";
                     60:   $global->{format} = "groff" if $global->{format} eq "ascii";
                     61:   $global->{format} = "groff" if $global->{format} eq "nippon";
                     62:   $global->{format} = "groff" if $global->{format} eq "euc-kr";
                     63:   $ENV{SGML_SEARCH_PATH} =~ s/txt/$global->{format}/;
                     64: 
                     65:   $Formats{"groff"} = $txt;
                     66:   $Formats{"latin1"} = $txt;
                     67:   $Formats{"man"} = $txt;
                     68: 
                     69:   $global->{NsgmlsPrePipe} = "cat $global->{file} " ;
                     70: };
                     71: 
                     72: 
                     73: # Ascii escape sub.  this is called-back by `parse_data' below in
                     74: # `txt_preASP' to properly escape `\' characters coming from the SGML
                     75: # source.
                     76: my $txt_escape = sub {
                     77:     my ($data) = @_;
                     78: 
                     79:     $data =~ s|"|\\\&\"|g;     # Insert zero-width space in front of "
                     80:     $data =~ s|^\.|\\&.|;      # ditto in front of . at start of line
                     81:     $data =~ s|\\|\\\\|g;      # Escape backslashes
                     82: 
                     83:     return ($data);
                     84: };
                     85: 
                     86: #
                     87: #  Run the file through the genertoc utility before sgmlsasp. Not necessary
                     88: #  when producing a manpage. A lot of code from FJM, untested by me.
                     89: #
                     90: $txt->{preASP} = sub
                     91: {
                     92:   my ($infile, $outfile) = @_;
                     93:   my (@toc, @lines);
                     94:   my $char_maps = load_char_maps ('.2tr', [ Text::EntityMap::sdata_dirs() ]);
                     95:   if ( $global->{charset} eq "latin1" )
                     96:    {
                     97:     $char_maps = load_char_maps ('.2l1tr', [ Text::EntityMap::sdata_dirs() ]);
                     98:    }
                     99: 
                    100:    if ($txt->{manpage})
                    101:     {
                    102:      while (<$infile>)
                    103:       {
                    104:        if (/^-/)
                    105:         {
                    106:          my ($str) = $';
                    107:          chop ($str);
                    108:          print $outfile "-" . 
                    109:                  parse_data ($str, $char_maps, $txt_escape) . "\n";
                    110:          next;
                    111:         }
                    112:        elsif (/^A/)
                    113:         {
                    114:          /^A(\S+) (IMPLIED|CDATA|NOTATION|ENTITY|TOKEN)( (.*))?$/
                    115:              || die "bad attribute data: $_\n";
                    116:          my ($name,$type,$value) = ($1,$2,$4);
                    117:          if ($type eq "CDATA")
                    118:           {
                    119:             # CDATA attributes get translated also
                    120:             $value = parse_data ($value, $char_maps, $txt_escape);
                    121:           }
                    122:          print $outfile "A$name $type $value\n";
                    123:          next;
                    124:         }
                    125:         #
                    126:         #  Default action if not skipped over with next: copy in to out.
                    127:         #
                    128:         print $outfile $_;
                    129:       }
                    130: 
                    131:       return;
                    132:     }
                    133: 
                    134:   # note the conversion of `sdata_dirs' list to an anonymous array to
                    135:   # make a single argument
                    136: 
                    137:   #
                    138:   #  Build TOC. The file is read into @lines in the meantime, we need to
                    139:   #  traverse it twice.
                    140:   #
                    141:   push (@toc, "(HLINE\n");
                    142:   push (@toc, ")HLINE\n");
                    143:   push (@toc, "(P\n");
                    144:   push (@toc, "-" . Xlat ("Table of Contents") . "\n");
                    145:   push (@toc, ")P\n");
                    146:   push (@toc, "(VERB\n");
                    147:   my (@prevheader, @header);
                    148:   my $appendix = 0;
                    149:   my $nonprint = 0;
                    150:   while (<$infile>)
                    151:     {
                    152:       push (@lines, $_);
                    153: 
                    154:       if (/^\(SECT(.*)/) 
                    155:         {
                    156:          @prevheader = @header;
                    157:          @header = @header[0..$1];
                    158:          if ($appendix == 1) 
                    159:             {
                    160:              $header[$1] = "A";
                    161:              $appendix = 0;
                    162:             } else 
                    163:             {
                    164:              $header[$1]++;
                    165:            }
                    166:         }
                    167:       if (/^\(APPEND(.*)/) 
                    168:         {
                    169:          $appendix = 1;
                    170:         }
                    171:       if (/^\(HEADING/) 
                    172:         {
                    173:          $_ = <$infile>;
                    174:          s/\\n/ /g;
                    175:          push (@lines, $_);
                    176:          chop;
                    177:          s/^-//;
                    178:          $_ = join(".",@header) . " " . $_;
                    179:          s/\(\\[0-9][0-9][0-9]\)/\\\1/g;
                    180: 
                    181:          if (!$#header) 
                    182:            {
                    183:              # put a newline before top-level sections unless previous was also
                    184:              # a top level section
                    185:              $_ = "\\n" . $_ unless (!$#prevheader);
                    186:              # put a . and a space after top level sections
                    187:              s/ /. /;
                    188: #####        $_ = "-" . $_ . "\\n";
                    189:              $_ = "-" . $_;
                    190:            } 
                    191:          else 
                    192:            {
                    193:              # subsections get indentation matching hierarchy
                    194:              $_ = "-" . "   " x $#header . $_;
                    195:            }
                    196: 
                    197: #      remove tags from a toc
                    198:          s/\)TT//g;
                    199:          s/\(TT//g;
                    200:          s/\)IT//g;
                    201:          s/\(IT//g;
                    202:          s/\)EM//g;
                    203:          s/\(EM//g;
                    204:          s/\)BF//g;
                    205:          s/\(BF//g;
                    206:          s/AID * CDATA.*$//g;
                    207:          s/\)LABEL//g;
                    208:          s/\(LABEL//g;
                    209: 
                    210:          push(@toc, parse_data ($_, $char_maps, $txt_escape));
                    211: 
                    212:          $_ = <$infile>;
                    213:          while (!/^\)HEADING/) {
                    214:            s/\\n/ /g; ####
                    215:            push(@lines, $_);
                    216:            chop;
                    217:            s/^-//;
                    218: 
                    219: #      remove tags from a toc
                    220:            s/\)TT//g;
                    221:            s/\(TT//g;
                    222:            s/\)IT//g;
                    223:            s/\(IT//g;
                    224:            s/\)EM//g;
                    225:            s/\(EM//g;
                    226:            s/\)BF//g;
                    227:            s/\(BF//g;
                    228:            s/AID * CDATA.*$//g;
                    229:            s/\)LABEL//g;
                    230:            s/\(LABEL//g;
                    231: 
                    232: #      remove NIDX, NCDX from a toc entry
                    233:            if (/^\(NIDX$/ || /^\(NCDX$/) { $nonprint = 1; }
                    234:            if (/^\)NIDX$/ || /^\)NCDX$/) { $nonprint = 1; }
                    235: 
                    236: #        $_ = "-" . $_ . "\\n";
                    237:            push(@toc, parse_data ($_, $char_maps, $txt_escape))
                    238:              if (! $nonprint);
                    239:            $_ = <$infile>;
                    240:          }
                    241:          s/\\n/ /g; ###
                    242:          push(@lines, $_);
                    243:          push(@toc, "\\n\n");
                    244:       }
                    245:     }
                    246:   push (@toc, ")VERB\n");
                    247:   push (@toc, "(HLINE\n");
                    248:   push (@toc, ")HLINE\n");
                    249: 
                    250:   my $inheading = 0;
                    251:   my $tipo = '';
                    252:   for (@lines)
                    253:     {
                    254:       if ($inheading)
                    255:         {
                    256:          next if (/^\)TT/ || /^\(TT/ || /^\)IT/ || /^\(IT/ ||
                    257:                    /^\)EM/ || /^\(EM/ || /^\)BF/ || /^\(BF/);
                    258:          if (/^-/) 
                    259:             {
                    260:              $tipo .=  $' ;
                    261:              chop ($tipo);
                    262:              $tipo .= " " unless $tipo =~ / $/;
                    263:            }
                    264:          else 
                    265:            {
                    266:              $tipo =~ s/ $//;
                    267:              if ($tipo)
                    268:                {
                    269:                  print $outfile "-"
                    270:                      . parse_data ($tipo, $char_maps, $txt_escape)
                    271:                      . "\n";
                    272:                }
                    273:              print $outfile $_;
                    274:              $tipo = '';
                    275:            }
                    276:          if (/^\)HEADING/)
                    277:            {
                    278:              $inheading = 0;
                    279:             }
                    280:          next;
                    281:        }
                    282:       if (/^\(HEADING/) 
                    283:         {
                    284:          #
                    285:          #  Go into heading processing mode.
                    286:          #
                    287:          $tipo = '';
                    288:          $inheading = 1;
                    289:        }
                    290:       if (/^\(TOC/)
                    291:         {
                    292:          print $outfile @toc;
                    293:          next;
                    294:        }
                    295:       if (/^-/)
                    296:         {
                    297:          my ($str) = $';
                    298:          chop ($str);
                    299:          print $outfile "-" . parse_data ($str, $char_maps, $txt_escape) . "\n";
                    300:          next;
                    301:         }
                    302:       elsif (/^A/)
                    303:         {
                    304:          /^A(\S+) (IMPLIED|CDATA|NOTATION|ENTITY|TOKEN)( (.*))?$/
                    305:              || die "bad attribute data: $_\n";
                    306:          my ($name,$type,$value) = ($1,$2,$4);
                    307:          if ($type eq "CDATA")
                    308:            {
                    309:              # CDATA attributes get translated also
                    310:              $value = parse_data ($value, $char_maps, $txt_escape);
                    311:            }
                    312:          print $outfile "A$name $type $value\n";
                    313:          next;
                    314:         }
                    315: 
                    316:       #
                    317:       #  Default action if not skipped over with next: copy in to out.
                    318:       #
                    319:       print $outfile $_;
                    320:     }
                    321: };
                    322: 
                    323: 
                    324: #
                    325: #  Take the sgmlsasp output, and make something
                    326: #  useful from it.
                    327: #
                    328: $txt->{postASP} = sub
                    329: {
                    330:   my $infile = shift;
                    331:   my ($outfile, $groffout);
                    332: 
                    333:   if ($txt->{manpage})
                    334:     {
                    335:       $outfile = new FileHandle ">$global->{filename}.man";
                    336:     }
                    337:   else
                    338:     {
                    339:       create_temp("$global->{tmpbase}.txt.1");
                    340:       $outfile = new FileHandle 
                    341:          "|$main::progs->{GROFF} $global->{pass} -T $global->{charset} -t $main::progs->{GROFFMACRO} >\"$global->{tmpbase}.txt.1\"";
                    342:     }
                    343: 
                    344:   #
                    345:   #  Feed $outfile with roff input.
                    346:   #
                    347:   while (<$infile>)
                    348:     {
                    349:       unless (/^\.DS/.../^\.DE/) 
                    350:         {
                    351:          s/^[ \t]{1,}(.*)/$1/g;
                    352:         }
                    353:       s/^\.[ \t].*/\\\&$&/g;
                    354:       s/\\fC/\\fR/g;
                    355:       s/^.ft C/.ft R/g; 
                    356:       print $outfile $_;
                    357:     }  
                    358:   $outfile->close;
                    359: 
                    360:   #
                    361:   #  If we were making a manpage, we're done. Otherwise, a little bit
                    362:   #  of work is left.
                    363:   #
                    364:   if ($txt->{manpage})
                    365:     {
                    366:       return 0;
                    367:     }
                    368:   else
                    369:     {
                    370:       $outfile->open (">$global->{filename}.txt");
                    371:       $groffout = new FileHandle "<$global->{tmpbase}.txt.1";
                    372:       my $count = 0;
                    373:       if ($txt->{filter})
                    374:         {
                    375:          while (<$groffout>)
                    376:            {
                    377:              s/[^\cH][^\cH]\cH\cH//g;
                    378:              s/.//g;
                    379:               if ($txt->{blanks})
                    380:                 {
                    381:                   $count = &{$txt->{cutblank}}($count, $outfile, $_);
                    382:                 }
                    383:               else
                    384:                 {
                    385:                   print $outfile $_;
                    386:                 }
                    387:            }
                    388:        }
                    389:       else
                    390:         {
                    391:           if ($txt->{blanks})
                    392:             {
                    393:               while (<$groffout>)
                    394:                 {
                    395:                   $count = &{$txt->{cutblank}}($count, $outfile, $_);
                    396:                 }
                    397:             }
                    398:           else
                    399:             {
                    400:              copy ($groffout, $outfile);
                    401:             }
                    402:        }
                    403:     }
                    404:   $groffout->close;
                    405:   $outfile->close;
                    406: 
                    407:   return 0;
                    408: };
                    409: 
                    410: $txt->{cutblank} = sub
                    411: {
                    412:   my ($num, $out, $in) = @_;
                    413:   if ( $in =~ /^$/ )
                    414:     {
                    415:       $num++;
                    416:     }
                    417:   else
                    418:     {
                    419:       $num = 0;
                    420:     }
                    421:   if ( $num <= $txt->{blanks} )
                    422:     {
                    423:       print $out $in;
                    424:     }
                    425: 
                    426:   return ($num);
                    427: };
                    428: 
                    429: 1;

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>