Statistics
| Branch: | Revision:

iof-bird / bird-2.0.1 / doc / sbase / dist / fmt_latex2e.pl @ 6b3f1a54

History | View | Annotate | Download (15.1 KB)

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;