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

1.1       misho       1: #
                      2: #  fmt_latex2e.pl
                      3: #
                      4: #  $Id$
                      5: #
                      6: #  LaTeX-specific driver stuff
                      7: #
                      8: #  © Copyright 1996, Cees de Groot
                      9: #
                     10: #  Support for PDF files: added by Juan Jose Amor, January 2000
                     11: #  © Copyright 2000, Juan Jose Amor
                     12: #
                     13: package LinuxDocTools::fmt_latex2e;
                     14: use strict;
                     15: 
                     16: use LinuxDocTools::CharEnts;
                     17: use LinuxDocTools::Vars;
                     18: use LinuxDocTools::Lang;
                     19: 
                     20: use File::Copy;
                     21: 
                     22: my $latex2e = {};
                     23: $latex2e->{NAME} = "latex2e";
                     24: $latex2e->{HELP} = <<EOF;
                     25:   Note that this output format requires LaTeX 2e.
                     26: 
                     27: EOF
                     28: $latex2e->{OPTIONS} = [
                     29:    { option => "output", type => "l", 
                     30:      'values' => [ "dvi", "tex", "ps", "pdf" ], short => "o" },
                     31:    { option => "bibtex", type => "f",  short => "b" },
                     32:    { option => "makeindex", type => "f",  short => "m" },
                     33:    { option => "pagenumber", type => "i", short => "n" },
                     34:    { option => "quick",  type => "f",  short => "q" },
                     35:    { option => "dvips",  type => "l",
                     36:      'values' => [ "dvips", "dvi2ps", "jdvi2kps" ], short => "s" },
                     37:    { option => "latex",  type => "l",  
                     38:      'values' => [ "latex", "hlatexp", "platex", "jlatex" ], short => "x" }
                     39: ];
                     40: $latex2e->{output} = "tex";
                     41: $latex2e->{pagenumber} = 1;
                     42: $latex2e->{quick}  = 0;
                     43: $latex2e->{bibtex}  = 0;
                     44: $latex2e->{makeindex} = 0;
                     45: $latex2e->{latex} = "unknown";
                     46: $latex2e->{dvips} = "unknown";
                     47: $Formats{$latex2e->{NAME}} = $latex2e;
                     48: 
                     49: $latex2e->{preNSGMLS} = sub {
                     50:   $global->{NsgmlsOpts} .= " -ifmttex ";
                     51: 
                     52:   #  for Japanese jlatex users
                     53:   if ($global->{language} eq "ja" && $latex2e->{latex} eq "unknown") {
                     54:        $latex2e->{latex} = "jlatex";
                     55:        $latex2e->{dvips} = "dvi2ps";
                     56:   # for Japanese platex users
                     57:   #    $latex2e->{latex} = "platex";
                     58:   #    $latex2e->{dvips} = "dvips";
                     59:   }
                     60: 
                     61:   # for Korean users
                     62:   if ($global->{language} eq "ko" && $latex2e->{latex} eq "unknown") {
                     63:        $latex2e->{latex} = "hlatexp";
                     64:   }
                     65: 
                     66:   # default process command
                     67:   $latex2e->{latex} = "latex" if ($latex2e->{latex} eq "unknown");
                     68:   $latex2e->{dvips} = "dvips" if ($latex2e->{dvips} eq "unknown");
                     69: 
                     70:   $global->{NsgmlsPrePipe} = "cat $global->{file} ";
                     71: };
                     72: 
                     73: # extra `\\' here for standard `nsgmls' output
                     74: my %latex2e_escapes;
                     75: $latex2e_escapes{'#'} = '\\\\#';
                     76: $latex2e_escapes{'$'} = '\\\\$';
                     77: $latex2e_escapes{'%'} = '\\\\%';
                     78: $latex2e_escapes{'&'} = '\\\\&';
                     79: $latex2e_escapes{'~'} = '\\\\~{}';
                     80: $latex2e_escapes{'_'} = '\\\\_';
                     81: $latex2e_escapes{'^'} = '\\\\^{}';
                     82: $latex2e_escapes{'\\'} = '\\verb+\\+';
                     83: $latex2e_escapes{'{'} = '\\\\{';
                     84: $latex2e_escapes{'}'} = '\\\\}';
                     85: $latex2e_escapes{'>'} = '{$>$}';
                     86: $latex2e_escapes{'<'} = '{$<$}';       # wouldn't happen, but that's what'd be
                     87: $latex2e_escapes{'|'} = '{$|$}';
                     88: 
                     89: my $in_verb;
                     90: my $remove_comment; # added 2000 Jan 25 by t.sano
                     91: 
                     92: # passed to `parse_data' below in latex2e_preASP
                     93: my $latex2e_escape = sub {
                     94:     my ($data) = @_;
                     95: 
                     96:     if (!$in_verb) {
                     97:        # escape special characters
                     98:        $data =~ s|([#\$%&~_^\\{}<>\|])|$latex2e_escapes{$1}|ge;
                     99:     }
                    100: 
                    101:     return ($data);
                    102: };
                    103: 
                    104: #
                    105: #  Translate character entities and escape LaTeX special chars.
                    106: #
                    107: $latex2e->{preASP} = sub
                    108: {
                    109:   my ($infile, $outfile) = @_;
                    110: 
                    111:   # note the conversion of `sdata_dirs' list to an anonymous array to
                    112:   # make a single argument
                    113:   my $tex_char_maps = load_char_maps ('.2tex', [ Text::EntityMap::sdata_dirs() ]);
                    114: 
                    115:   # ASCII char maps are used in the verbatim environment because TeX
                    116:   # ignores all the escapes
                    117:   my $ascii_char_maps = load_char_maps ('.2ab', [ Text::EntityMap::sdata_dirs() ]);
                    118:   $ascii_char_maps = load_char_maps ('.2l1b', [ Text::EntityMap::sdata_dirs() ]) if $global->{charset} eq "latin";
                    119: 
                    120:   my $char_maps = $tex_char_maps;
                    121: 
                    122:   # used in `latex2e_escape' anonymous sub to switch between escaping
                    123:   # characters from SGML source or not, depending on whether we're in
                    124:   # a VERB or CODE environment or not
                    125:   $in_verb = 0;
                    126: 
                    127:   # switch to remove empty line from TeX source or not, depending
                    128:   # on whether we're in a HEADING or ABSTRACT environment or not
                    129:   $remove_comment = 0;
                    130: 
                    131:   while (<$infile>)
                    132:     {
                    133:       if (/^-/)
                    134:         {
                    135:            my ($str) = $';
                    136:            chop ($str);
                    137:            $_ = parse_data ($str, $char_maps, $latex2e_escape);
                    138:            if ($remove_comment)
                    139:              {
                    140:                s/(\s+\\n)+//;
                    141:              }
                    142:            print $outfile "-" . $_ . "\n";
                    143:         }
                    144:       elsif (/^A/)
                    145:         {
                    146:          /^A(\S+) (IMPLIED|CDATA|NOTATION|ENTITY|TOKEN)( (.*))?$/
                    147:              || die "bad attribute data: $_\n";
                    148:          my ($name,$type,$value) = ($1,$2,$4);
                    149:          if ($type eq "CDATA")
                    150:            {
                    151:              # CDATA attributes get translated also
                    152:              if ($name eq "URL" or $name eq "ID" or $name eq "CA")
                    153:                {
                    154:                  # URL for url.sty is a kind of verbatim...
                    155:                  # CA is used in "tabular" element.
                    156:                  # Thanks to Evgeny Stambulchik, he posted this fix
                    157:                  # on sgml-tools list. 2000 May 17, t.sano
                    158:                  my $old_verb = $in_verb;
                    159:                  $in_verb = 1;
                    160:                  $value = parse_data ($value, $ascii_char_maps, 
                    161:                      $latex2e_escape);
                    162:                  $in_verb = $old_verb;
                    163:                }
                    164:              else
                    165:                {
                    166:                  $value = parse_data ($value, $char_maps, $latex2e_escape);
                    167:                }
                    168:            }
                    169:          print $outfile "A$name $type $value\n";
                    170:         }
                    171:       elsif (/^\((VERB|CODE)/)
                    172:         {
                    173:          print $outfile $_;
                    174:          # going into VERB/CODE section
                    175:          $in_verb = 1;
                    176:          $char_maps = $ascii_char_maps;
                    177:        }
                    178:       elsif (/^\)(VERB|CODE)/)
                    179:         {
                    180:          print $outfile $_;
                    181:          # leaving VERB/CODE section
                    182:          $in_verb = 0;
                    183:          $char_maps = $tex_char_maps;
                    184:        }
                    185:       elsif (/^\((HEADING|ABSTRACT)/)
                    186:         {
                    187:          print $outfile $_;
                    188:          # empty lines (comment in sgml source) do harm 
                    189:           # in HEADING or ABSTRACT
                    190:          $remove_comment = 1;
                    191:        }
                    192:       elsif (/^\)(HEADING|ABSTRACT)/)
                    193:         {
                    194:          print $outfile $_;
                    195:          # leaving HEADING or ABSTRACT section
                    196:          $remove_comment = 0;
                    197:        }
                    198:       else
                    199:         {
                    200:          print $outfile $_;
                    201:         }
                    202:     }
                    203: };
                    204: 
                    205: # return the string of the name of the macro for urldef
                    206: sub latex2e_defnam($)
                    207: {
                    208:     my ($num) = @_;
                    209: 
                    210:     if ($num > 26*26*26) {
                    211:        die "Too many URLs!\n";
                    212:     }
                    213: 
                    214:     my $anum = ord("a");
                    215: 
                    216:     my $defnam = chr ($anum + ($num / 26 / 26)) .
                    217:                  chr ($anum + ($num / 26 % 26)) .
                    218:                  chr ($anum + ($num % 26));
                    219: 
                    220:     return ($defnam);
                    221: };
                    222: 
                    223: #
                    224: #  Take the sgmlsasp output, and make something
                    225: #  useful from it.
                    226: #
                    227: $latex2e->{postASP} = sub
                    228: {
                    229:   my $infile = shift;
                    230:   my $filename = $global->{filename};
                    231:   my $tmplatexdir = $global->{tmpbase} . "-latex-" . $$ . ".dir";
                    232:   my $tmplatexnam = $tmplatexdir . "/" . $filename;
                    233:   my @epsfiles = ();
                    234:   my @texlines = ();
                    235:   my @urldefines = ();
                    236:   my @urlnames = ();
                    237:   my $urlnum = 0;
                    238:   my $tmpepsf;
                    239:   my $saved_umask = umask;
                    240:   $ENV{TEXINPUTS} .= ":$main::DataDir";
                    241: 
                    242:   umask 0077;
                    243:   mkdir ($tmplatexdir, 0700) || return -1;
                    244: 
                    245:   #
                    246:   # check epsfile is specified in source file
                    247:   # check nameurl specified in source file
                    248:   #
                    249:   {
                    250:       my $epsf;
                    251:       open SGMLFILE, "<$filename.sgml";
                    252:       while (<SGMLFILE>)
                    253:         {
                    254:        # for epsfile
                    255:            if ( s/^\s*<eps\s+file=(.*)>/$1/ )
                    256:              {
                    257:                s/\s+angle=.*//;
                    258:                s/\s+height=.*//;
                    259:                s/\"//g;
                    260:                $epsf = $_;
                    261:                chop ( $epsf );
                    262:                push @epsfiles, $epsf;
                    263:              }
                    264:            if ($latex2e->{output} eq "pdf")
                    265:              {
                    266:               if ( s/^\s*<img\s+src=(.*)>/$1/ )
                    267:                  {
                    268:                    s/\"//g;
                    269:                    $epsf = $_;
                    270:                    chop ( $epsf );
                    271:                    push @epsfiles, $epsf;
                    272:                  }
                    273:              }
                    274:         }
                    275:       close SGMLFILE;
                    276:   }
                    277:   {
                    278:       my $urlid;
                    279:       my $urlnam;
                    280:       my $urldef;
                    281:       while (<$infile>)
                    282:        {
                    283:           push @texlines, $_;
                    284:        # for nameurl
                    285:           if ( /\\nameurl/ )
                    286:             {
                    287:                ($urlid, $urlnam) = ($_ =~ /\\nameurl\{(.*)\}\{(.*)\}/);
                    288:                print $urlnum . ": " . $urlid . "\n" if ( $global->{debug} );
                    289: 
                    290:                $urldef = latex2e_defnam($urlnum) . "url";
                    291:                s/\\nameurl\{.*\}\{.*\}/{\\em $urlnam} {\\tt \\$urldef}/;
                    292:                push @urlnames, $_;
                    293:                push @urldefines, "\\urldef{\\$urldef} \\url{$urlid}\n";
                    294:                $urlnum++;
                    295:             }
                    296:         }
                    297:       close $infile;
                    298:   }
                    299: 
                    300:   open OUTFILE, ">$tmplatexnam.tex";
                    301:   #
                    302:   #  Set the correct \documentclass options.
                    303:   #
                    304:     {
                    305:       my $langlit = ISO2English ($global->{language});
                    306:       $langlit = ($langlit eq 'english') ? "" : ",$langlit"; 
                    307:       my $replace = $global->{papersize} . 'paper' .   $langlit;
                    308:       my $hlatexopt = "";
                    309:       $global->{charset} = "nippon" if ($global->{language} eq "ja");
                    310:       $global->{charset} = "euc-kr" if ($global->{language} eq "ko");
                    311:       $replace = $global->{papersize} . 'paper' if ($global->{charset} eq "nippon") || ($global->{charset} eq "euc-kr");
                    312:       while (defined($texlines[0]))
                    313:         {
                    314:          $_ = shift @texlines;
                    315:           if (/^\\documentclass/) 
                    316:            {
                    317:              if ($global->{language} ne "en" ||
                    318:                  $global->{papersize} ne "a4")
                    319:                {
                    320:                   s/\\documentclass\[.*\]/\\documentclass\[$replace\]/;
                    321:                }
                    322:              if ($global->{charset} eq "nippon") {
                    323:                 if ($latex2e->{latex} eq "platex") {
                    324:                   s/{article}/{jarticle}/;
                    325:                 } elsif ($latex2e->{latex} eq "jlatex") {
                    326:                   s/{article}/{j-article}/;
                    327:                 }
                    328:              }
                    329:               $_ = $_ . "\\makeindex\n" if ($latex2e->{makeindex});
                    330:             }
                    331:           if (/^\\usepackage.epsfig/ && ($global->{charset} eq "euc-kr"))
                    332:             {
                    333:               $hlatexopt = "[noautojosa]" if ($latex2e->{latex} eq "hlatexp");
                    334:               $_ = $_ . "\\usepackage" . "$hlatexopt" . "{hangul}\n"
                    335:             }
                    336:           if ((/\\usepackage.t1enc/) &&
                    337:                 (($global->{charset} eq "nippon") || 
                    338:                  ($global->{charset} eq "euc-kr")))
                    339:             {
                    340:                s/^/%%/;
                    341:             }
                    342:           if (/%end-preamble/)
                    343:            {
                    344:              if ($latex2e->{pagenumber}) 
                    345:                 {
                    346:                  $_ = $_ . '\setcounter{page}{'. 
                    347:                       $latex2e->{pagenumber} . "}\n";
                    348:                } 
                    349:              else 
                    350:                {
                    351:                  $_ = $_ . "\\pagestyle{empty}\n";
                    352:                }
                    353:              $_ = $_ . $global->{pass} . "\n" if ($global->{pass});
                    354:            }
                    355:                  if (/\\nameurl/ && $latex2e->{output} ne "pdf")
                    356:             {
                    357:                $_ = shift @urlnames;
                    358:            }
                    359:          print OUTFILE;
                    360:           if (/%end-preamble/)
                    361:            {
                    362:                if ($urlnum && $latex2e->{output} ne "pdf")
                    363:                  {
                    364:                        while (defined($urldefines[0]))
                    365:                          {
                    366:                                $_ = shift @urldefines;
                    367:                                print OUTFILE;
                    368:                          }
                    369:                  }
                    370:            }
                    371:        }
                    372:     }
                    373:   close OUTFILE;
                    374: 
                    375:   #
                    376:   #  LaTeX, dvips, and assorted cleanups.
                    377:   #
                    378:   if ($latex2e->{output} eq "tex")
                    379:     { 
                    380: # comment out, because this backup action is not documented yet.
                    381: #
                    382: #      if ( -e "$filename.tex" ) {
                    383: #         rename ("$filename.tex", "$filename.tex.back");
                    384: #      }
                    385: 
                    386:       umask $saved_umask;
                    387:       copy ("$tmplatexnam.tex", "$filename.tex");
                    388:       if ( ! $global->{debug} )
                    389:         {
                    390:           unlink ("$tmplatexnam.tex");
                    391:           rmdir ($tmplatexdir) || return -1;
                    392:         }
                    393: 
                    394:       return 0; 
                    395:     }
                    396: 
                    397:   #
                    398:   # Run LaTeX in nonstop mode so it won't prompt & hang on errors.
                    399:   # Suppress the output of LaTeX on all but the last pass, after
                    400:   # references have been resolved.  This avoids large numbers of
                    401:   # spurious warnings.
                    402:   #
                    403:   my $current_dir;
                    404:   chop ($current_dir = `pwd`);
                    405:   print $current_dir . "\n" if ( $global->{debug} );
                    406: 
                    407:   #
                    408:   # copy epsfiles specified in tex file
                    409:   #
                    410:   for my $epsf ( @epsfiles )
                    411:    {
                    412:       $tmpepsf = $tmplatexdir . "/" . $epsf; 
                    413:       print $epsf . " " . $tmpepsf . "\n" if ( $global->{debug} );
                    414:       copy ("$epsf", "$tmpepsf") or die "can not copy graphics\n";
                    415:    }
                    416: 
                    417:   #
                    418:   # go to the temporary directory
                    419:   chdir ($tmplatexdir);
                    420: 
                    421:   my ($latexcommand) = "$latex2e->{latex} '\\nonstopmode\\input{$filename.tex}'";
                    422: 
                    423:   #
                    424:   # We run pdflatex instead of latex if user selected pdf output
                    425:   #
                    426:   if ($latex2e->{output} eq "pdf")
                    427:     {
                    428:       $latexcommand = "pdflatex '\\nonstopmode\\input{$filename.tex}'";
                    429:     }
                    430: 
                    431:   # 
                    432:   # run hlatex if hlatexp is used
                    433:   # for pdf: how about status?(for hlatex and hlatexp)
                    434:   #
                    435:   if ($latex2e->{latex} eq "hlatexp")
                    436:     {
                    437:       #$latex2e->{output} = "ps" if ($latex2e->{output} eq "pdf");
                    438:       $latexcommand = "hlatex '\\nonstopmode\\input{$filename.tex}'";
                    439:     }
                    440: 
                    441:   #
                    442:   # We use jlatex for Japanese encoded (euc-jp) characters.
                    443:   # pdf support for Japanese are not yet. use ps for the time being.
                    444:   #
                    445:   if ($global->{charset} eq "nippon")
                    446:     {
                    447:       $latex2e->{output} = "ps" if ($latex2e->{output} eq "pdf");
                    448:       $latexcommand = "$latex2e->{latex} '\\nonstopmode\\input{$filename.tex}'"
                    449:     }
                    450:   my ($suppress) = $latex2e->{quick} ? "" : ' >/dev/null';
                    451: 
                    452:   system $latexcommand . $suppress  || die "LaTeX problem\n";
                    453:   $latex2e->{bibtex} && system "bibtex $filename.tex";
                    454:   $latex2e->{quick} || system $latexcommand . ' >/dev/null';
                    455:   $latex2e->{quick} || system $latexcommand;
                    456:   if ( ! $global->{debug} )
                    457:     {
                    458:       my @suffixes = qw(log blg aux toc lof lot dlog bbl out);
                    459:       for my $suf (@suffixes)
                    460:         {
                    461:           unlink "$tmplatexnam.$suf";
                    462:         }
                    463:     }
                    464:   #
                    465:   # go back to the working directory
                    466:   chdir ($current_dir);
                    467:   #
                    468:   # output dvi file
                    469:   if ($latex2e->{output} eq "dvi")
                    470:     {
                    471: # comment out, because this backup action is not documented yet.
                    472: #
                    473: #      if ( -e "$filename.dvi" )
                    474: #        {
                    475: #          rename ("$filename.dvi", "$filename.dvi.back");
                    476: #        }
                    477:       umask $saved_umask;
                    478:       copy ("$tmplatexnam.dvi", "$filename.dvi");
                    479:       if ( $global->{debug} )
                    480:         {
                    481:           print "Temporary files are in $tmplatexdir\n";
                    482:           print "Please check there and remove them manually.\n";
                    483:         } else {
                    484:           unlink ("$tmplatexnam.tex", "$tmplatexnam.dvi");
                    485:           for my $epsf ( @epsfiles )
                    486:             {
                    487:                $tmpepsf = $tmplatexdir . "/" . $epsf; 
                    488:                print $tmpepsf . "\n" if ( $global->{debug} );
                    489:                unlink ("$tmpepsf");
                    490:             }
                    491:           rmdir ($tmplatexdir) || return -1;
                    492:         }
                    493:       return 0;
                    494:     }
                    495:   #
                    496:   # output pdf file
                    497:   if ($latex2e->{output} eq "pdf")
                    498:     {
                    499: # comment out, because this backup action is not documented yet.
                    500: #
                    501: #      if ( -e "$filename.pdf" )
                    502: #        {
                    503: #          rename ("$filename.pdf", "$filename.pdf.back");
                    504: #        }
                    505:       umask $saved_umask;
                    506:       copy ("$tmplatexnam.pdf", "$filename.pdf");
                    507:       if ( $global->{debug} )
                    508:         {
                    509:           print "Temporary files are in $tmplatexdir\n";
                    510:           print "Please check there and remove them manually.\n";
                    511:         } else {
                    512:           unlink ("$tmplatexnam.tex", "$tmplatexnam.pdf");
                    513:           for my $epsf ( @epsfiles )
                    514:             {
                    515:                $tmpepsf = $tmplatexdir . "/" . $epsf; 
                    516:                print $tmpepsf . "\n" if ( $global->{debug} );
                    517:                unlink ("$tmpepsf");
                    518:             }
                    519:           rmdir ($tmplatexdir) || return -1;
                    520:         }
                    521:       return 0;
                    522:     }
                    523:   #
                    524:   # convert dvi into ps using dvips command
                    525:   chdir ($tmplatexdir);
                    526:   if ($latex2e->{dvips} eq "dvi2ps")
                    527:     {
                    528:       `dvi2ps -q -o $global->{papersize} -c $tmplatexnam.ps $filename.dvi`;
                    529:     }
                    530:   elsif ($latex2e->{dvips} eq "jdvi2kps")
                    531:     {
                    532:       `jdvi2kps -q -pa $global->{papersize} -o $tmplatexnam.ps $filename.dvi`;
                    533:     }
                    534:   else
                    535:     {
                    536:       `dvips -R -q -t $global->{papersize} -o $tmplatexnam.ps $filename.dvi`;
                    537:     }
                    538: 
                    539:   chdir ($current_dir);
                    540: 
                    541: # comment out, because this backup action is not documented yet.
                    542: #
                    543: #  if ( -e "$filename.ps" )
                    544: #    {
                    545: #      rename ("$filename.ps", "$filename.ps.back");
                    546: #    }
                    547:   umask $saved_umask;
                    548:   copy ("$tmplatexnam.ps", "$filename.ps");
                    549:   unlink ("$tmplatexnam.ps");
                    550:   if ( $global->{debug} )
                    551:     {
                    552:       print "Temporary files are in $tmplatexdir\n";
                    553:       print "Please check there and remove them manually.\n";
                    554:     } else {
                    555:       unlink ("$tmplatexnam.tex", "$tmplatexnam.dvi", "$tmplatexnam.ps");
                    556:       for my $epsf ( @epsfiles )
                    557:         {
                    558:            $tmpepsf = $tmplatexdir . "/" . $epsf; 
                    559:            print $tmpepsf . "\n" if ( $global->{debug} );
                    560:            unlink ("$tmpepsf");
                    561:         }
                    562:       rmdir ($tmplatexdir) || return -1;
                    563:     }
                    564:   return 0;
                    565: 
                    566: };
                    567: 
                    568: 1;

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