Annotation of embedaddon/bird2/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>