remove misleading comment (from M.J.T. Guy)
[p5sagit/p5-mst-13.2.git] / pod / pod2latex.PL
CommitLineData
4633a7c4 1#!/usr/local/bin/perl
2
3use Config;
4use File::Basename qw(&basename &dirname);
3b5ca523 5use Cwd;
4633a7c4 6
7# List explicitly here the variables you want Configure to
8# generate. Metaconfig only looks for shell variables, so you
9# have to mention them as if they were shell variables, not
10# %Config entries. Thus you write
11# $startperl
12# to ensure Configure will look for $Config{startperl}.
13
3b5ca523 14# This forces PL files to create target in same directory as PL file.
15# This is so that make depend always knows where to find PL derivatives.
16$origdir = cwd;
17chdir dirname($0);
18$file = basename($0, '.PL');
774d564b 19$file .= '.com' if $^O eq 'VMS';
4633a7c4 20
21open OUT,">$file" or die "Can't create $file: $!";
22
23print "Extracting $file (with variable substitutions)\n";
24
25# In this section, perl variables will be expanded during extraction.
26# You can use $Config{...} to use Configure variables.
27
28print OUT <<"!GROK!THIS!";
5f05dabc 29$Config{startperl}
30 eval 'exec $Config{perlpath} -S \$0 \${1+"\$@"}'
31 if \$running_under_some_shell;
5d94fbed 32!GROK!THIS!
33
4633a7c4 34# In the following, perl variables are not expanded during extraction.
35
36print OUT <<'!NO!SUBS!';
5d94fbed 37#
748a9306 38# pod2latex, version 1.1
39# by Taro Kawagish (kawagish@imslab.co.jp), Jan 11, 1995.
40#
41# pod2latex filters Perl pod documents to LaTeX documents.
42#
43# What pod2latex does:
44# 1. Pod file 'perl_doc_entry.pod' is filtered to 'perl_doc_entry.tex'.
45# 2. Indented paragraphs are translated into
46# '\begin{verbatim} ... \end{verbatim}'.
47# 3. '=head1 heading' command is translated into '\section{heading}'
48# 4. '=head2 heading' command is translated into '\subsection*{heading}'
49# 5. '=over N' command is translated into
50# '\begin{itemize}' if following =item starts with *,
51# '\begin{enumerate}' if following =item starts with 1.,
52# '\begin{description}' if else.
53# (indentation level N is ignored.)
54# 6. '=item * heading' command is translated into '\item heading',
55# '=item 1. heading' command is translated into '\item heading',
56# '=item heading' command(other) is translated into '\item[heading]'.
57# 7. '=back' command is translated into
58# '\end{itemize}' if started with '\begin{itemize}',
59# '\end{enumerate}' if started with '\begin{enumerate}',
60# '\end{description}' if started with '\begin{description}'.
61# 8. other paragraphs are translated into strings with TeX special characters
62# escaped.
63# 9. In heading text, and other paragraphs, the following translation of pod
64# quotes are done, and then TeX special characters are escaped after that.
65# I<text> to {\em text\/},
66# B<text> to {\bf text},
67# S<text> to text1,
68# where text1 is a string with blank characters replaced with ~,
69# C<text> to {\tt text2},
70# where text2 is a string with TeX special characters escaped to
71# obtain a literal printout,
72# E<text> (HTML escape) to TeX escaped string,
73# L<text> to referencing string as is done by pod2man,
74# F<file> to {\em file\/},
75# Z<> to a null string,
76# 10. those headings are indexed:
77# '=head1 heading' => \section{heading}\index{heading}
78# '=head2 heading' => \subsection*{heading}\index{heading}
79# only when heading does not match frequent patterns such as
80# DESCRIPTION, DIAGNOSTICS,...
81# '=item heading' => \item{heading}\index{heading}
82#
83# Usage:
84# pod2latex perl_doc_entry.pod
85# this will write to a file 'perl_doc_entry.tex'.
86#
87# To LaTeX:
88# The following commands need to be defined in the preamble of the LaTeX
89# document:
90# \def\C++{{\rm C\kern-.05em\raise.3ex\hbox{\footnotesize ++}}}
91# \def\underscore{\leavevmode\kern.04em\vbox{\hrule width 0.4em height 0.3pt}}
92# and \parindent should be set zero:
93# \setlength{\parindent}{0pt}
94#
95# Note:
96# This script was written modifing pod2man.
97#
98# Bug:
99# If HTML escapes E<text> other than E<amp>,E<lt>,E<gt>,E<quot> are used
100# in C<>, translation will produce wrong character strings.
101# Translation of HTML escapes of various European accents might be wrong.
102
103
748a9306 104# TeX special characters.
105##$tt_ables = "!@*()-=+|;:'\"`,./?<>";
106$backslash_escapables = "#\$%&{}_";
107$backslash_escapables2 = "#\$%&{}"; # except _
108##$nonverbables = "^\\~";
109##$bracketesc = "[]";
110##@tex_verb_fences = unpack("aaaaaaaaa","|#@!*+?:;");
111
112@head1_freq_patterns # =head1 patterns which need not be index'ed
113 = ("AUTHOR","Author","BUGS","DATE","DESCRIPTION","DIAGNOSTICS",
114 "ENVIRONMENT","EXAMPLES","FILES","INTRODUCTION","NAME","NOTE",
115 "SEE ALSO","SYNOPSIS","WARNING");
116
117$indent = 0;
118
119# parse the pods, produce LaTeX.
120
d23ed1f2 121use Pod::Plainer;
122open(POD,"-|") or Pod::Plainer -> new() -> parse_from_file($ARGV[0]), exit;
123
748a9306 124($pod=$ARGV[0]) =~ s/\.pod$//;
125open(LATEX,">$pod.tex");
126&do_hdr();
127
128$cutting = 1;
8c634b6e 129$begun = "";
d23ed1f2 130$/ = ""; # record separator is blank lines
748a9306 131while (<POD>) {
132 if ($cutting) {
133 next unless /^=/;
134 $cutting = 0;
135 }
8c634b6e 136 if ($begun) {
137 if (/^=end\s+$begun/) {
138 $begun = "";
139 }
140 elsif ($begun =~ /^(tex|latex)$/) {
141 print LATEX $_;
142 }
143 next;
144 }
748a9306 145 chop;
146 length || (print LATEX "\n") && next;
147
148 # translate indented lines as a verabatim paragraph
149 if (/^\s/) {
150 @lines = split(/\n/);
151 print LATEX "\\begin{verbatim}\n";
152 for (@lines) {
153 1 while s
154 {^( [^\t]* ) \t ( \t* ) }
155 { $1 . ' ' x (8 - (length($1)%8) + 8*(length($2))) }ex;
156 print LATEX $_,"\n";
157 }
158 print LATEX "\\end{verbatim}\n";
159 next;
160 }
161
8c634b6e 162 if (/^=for\s+(\S+)\s*/s) {
163 if ($1 eq "tex" or $1 eq "latex") {
164 print LATEX $',"\n";
165 } else {
166 # ignore unknown for
167 }
168 next;
169 }
170 elsif (/^=begin\s+(\S+)\s*/s) {
171 $begun = $1;
172 if ($1 eq "tex" or $1 eq "latex") {
173 print LATEX $'."\n";
174 }
175 next;
176 }
177
748a9306 178 # preserve '=item' line with pod quotes as they are.
179 if (/^=item/) {
180 ($bareitem = $_) =~ s/^=item\s*//;
181 }
182
183 # check for things that'll hosed our noremap scheme; affects $_
184 &init_noremap();
185
186 # expand strings "func()" as pod quotes.
187 if (!/^=item/) {
188 # first hide pod escapes.
189 # escaped strings are mapped into the ones with the MSB's on.
190 s/([A-Z]<[^<>]*>)/noremap($1)/ge;
191
192 # func() is a reference to a perl function
193 s{\b([:\w]+\(\))}{I<$1>}g;
194 # func(n) is a reference to a man page
195 s{(\w+)(\([^\s,\051]+\))}{I<$1>$2}g;
196 # convert simple variable references
197# s/([\$\@%][\w:]+)/C<$1>/g;
198# s/\$[\w:]+\[[0-9]+\]/C<$&>/g;
199
200 if (m{ ([\-\w]+\([^\051]*?[\@\$,][^\051]*?\))
201 }x && $` !~ /([LCI]<[^<>]*|-)$/ && !/^=\w/)
202 {
203 warn "``$1'' should be a [LCI]<$1> ref";
204 }
205 while (/(-[a-zA-Z])\b/g && $` !~ /[\w\-]$/) {
206 warn "``$1'' should be [CB]<$1> ref";
207 }
208
209 # put back pod quotes so we get the inside of <> processed;
210 $_ = &clear_noremap($_);
211 }
212
213
214 # process TeX special characters
215
216 # First hide HTML quotes E<> since they can be included in C<>.
217 s/(E<[^<>]+>)/noremap($1)/ge;
218
219 # Then hide C<> type literal quotes.
220 # String inside of C<> will later be expanded into {\tt ..} strings
221 # with TeX special characters escaped as needed.
222 s/(C<[^<>]*>)/&noremap($1)/ge;
223
224 # Next escape TeX special characters including other pod quotes B< >,...
225 #
226 # NOTE: s/re/&func($str)/e evaluates $str just once in perl5.
227 # (in perl4 evaluation takes place twice before getting passed to func().)
228
229 # - hyphen => ---
230 s/(\S+)(\s+)-+(\s+)(\S+)/"$1".&noremap(" --- ")."$4"/ge;
231 # '-', '--', "-" => '{\tt -}', '{\tt --}', "{\tt -}"
232## s/("|')(\s*)(-+)(\s*)\1/&noremap("$1$2\{\\tt $3\}$4$1")/ge;
233## changed Wed Jan 25 15:26:39 JST 1995
234 # '-', '--', "-" => '$-$', '$--$', "$-$"
235 s/(\s+)(['"])(-+)([^'"\-]*)\2(\s+|[,.])/"$1$2".&noremap("\$$3\$")."$4$2$5"/ge;
236 s/(\s+)(['"])([^'"\-]*)(-+)(\s*)\2(\s+|[,.])/"$1$2$3".&noremap("\$$4\$")."$5$2$6"/ge;
237 # (--|-) => ($--$|$-$)
238 s/(\s+)\((-+)([=@%\$\+\\\|\w]*)(-*)([=@%\$\+\\\|\w]*)\)(\s+|[,.])/"$1\(".&noremap("\$$2\$")."$3".&noremap("\$$4\$")."$5\)$6"/ge;
239 # numeral - => $-$
240 s/(\(|[0-9]+|\s+)-(\s*\(?\s*[0-9]+)/&noremap("$1\$-\$$2")/ge;
241 # -- in quotes => two separate -
242 s/B<([^<>]*)--([^<>]*)>/&noremap("B<$1\{\\tt --\}$2>")/ge;
243
244 # backslash escapable characters except _.
245 s/([$backslash_escapables2])/&noremap("\\$1")/ge;
246 s/_/&noremap("\\underscore{}")/ge; # a litle thicker than \_.
247 # quote TeX special characters |, ^, ~, \.
248 s/\|/&noremap("\$|\$")/ge;
249 s/\^/&noremap("\$\\hat{\\hspace{0.4em}}\$")/ge;
250 s/\~/&noremap("\$\\tilde{\\hspace{0.4em}}\$")/ge;
251 s/\\/&noremap("\$\\backslash{}\$")/ge;
252 # quote [ and ] to be used in \item[]
253 s/([\[\]])/&noremap("{\\tt $1}")/ge;
254 # characters need to be treated differently in TeX
255 # keep * if an item heading
256 s/^(=item[ \t]+)[*]((.|\n)*)/"$1" . &noremap("*") . "$2"/ge;
257 s/[*]/&noremap("\$\\ast\$")/ge; # other *
258
259 # hide other pod quotes.
260 s/([ABD-Z]<[^<>]*>)/&noremap($1)/ge;
261
262 # escape < and > as math strings,
263 # now that we are done with hiding pod <> quotes.
264 s/</&noremap("\$<\$")/ge;
265 s/>/&noremap("\$>\$")/ge;
266
267 # put it back so we get the <> processed again;
268 $_ = &clear_noremap($_);
269
270
271 # Expand pod quotes recursively:
272 # (1) type face directives [BIFS]<[^<>]*> to appropriate TeX commands,
273 # (2) L<[^<>]*> to reference strings,
274 # (3) C<[^<>]*> to TeX literal quotes,
275 # (4) HTML quotes E<> inside of C<> quotes.
276
277 # Hide E<> again since they can be included in C<>.
278 s/(E<[^<>]+>)/noremap($1)/ge;
279
280 $maxnest = 10;
281 while ($maxnest-- && /[A-Z]</) {
282
283 # bold and italic quotes
284 s/B<([^<>]*)>/"{\\bf $1}"/eg;
285 s#I<([^<>]*)>#"{\\em $1\\/}"#eg;
286
287 # files and filelike refs in italics
288 s#F<([^<>]*)>#"{\\em $1\\/}"#eg;
289
290 # no break quote -- usually we want C<> for this
291 s/S<([^<>]*)>/&nobreak($1)/eg;
292
293 # LREF: a manpage(3f)
294 s:L<([a-zA-Z][^\s\/]+)(\([^\)]+\))?>:the {\\em $1\\/}$2 manpage:g;
295
296 # LREF: an =item on another manpage
297 s{
298 L<([^/]+)/([:\w]+(\(\))?)>
299 } {the C<$2> entry in the I<$1> manpage}gx;
300
301 # LREF: an =item on this manpage
302 s{
303 ((?:L</([:\w]+(\(\))?)>
304 (,?\s+(and\s+)?)?)+)
305 } { &internal_lrefs($1) }gex;
306
307 # LREF: a =head2 (head1?), maybe on a manpage, maybe right here
308 # the "func" can disambiguate
309 s{
310 L<(?:([a-zA-Z]\S+?) /)?"?(.*?)"?>
311 }{
312 do {
313 $1 # if no $1, assume it means on this page.
314 ? "the section on I<$2> in the I<$1> manpage"
315 : "the section on I<$2>"
316 }
317 }gex;
318
d23ed1f2 319 s/X<([^<>]*)>/\\index{$1}/g;
320
748a9306 321 s/Z<>/\\&/g; # the "don't format me" thing
322
323 # comes last because not subject to reprocessing
324 s{
325 C<([^<>]*)>
326 }{
327 do {
328 ($str = $1) =~ tr/\200-\377/\000-\177/; #normalize hidden stuff
329 # expand HTML escapes if any;
330 # WARNING: if HTML escapes other than E<amp>,E<lt>,E<gt>,
331 # E<quot> are in C<>, they will not be printed correctly.
332 $str = &expand_HTML_escapes($str);
333 $strverb = &alltt($str); # Tex verbatim escape of a string.
334 &noremap("$strverb");
335 }
336 }gex;
337
338# if ( /C<([^<>]*)/ ) {
339# $str = $1;
340# if ($str !~ /\|/) { # if includes |
341# s/C<([^<>]*)>/&noremap("\\verb|$str|")/eg;
342# } else {
343# print STDERR "found \| in C<.*> at paragraph $.\n";
344# # find a character not contained in $str to use it as a
345# # separator of the \verb
346# ($chars = $str) =~ s/(\W)/\\$1/g;
347# ## ($chars = $str) =~ s/([\$<>,\|"'\-^{}()*+?\\])/\\$1/g;
348# @fence = grep(!/[ $chars]/,@tex_verb_fences);
349# s/C<([^<>]*)>/&noremap("\\verb$fence[0]$str$fence[0]")/eg;
350# }
351# }
352 }
353
354
355 # process each pod command
356 if (s/^=//) { # if a command
357 s/\n/ /g;
358 ($cmd, $rest) = split(' ', $_, 2);
359 $rest =~ s/^\s*//;
360 $rest =~ s/\s*$//;
361
362 if (defined $rest) {
363 &escapes;
364 }
365
366 $rest = &clear_noremap($rest);
367 $rest = &expand_HTML_escapes($rest);
368
369 if ($cmd eq 'cut') {
370 $cutting = 1;
371 $lastcmd = 'cut';
372 }
373 elsif ($cmd eq 'head1') { # heading type 1
374 $rest =~ s/^\s*//; $rest =~ s/\s*$//;
375 print LATEX "\n\\subsection*{$rest}";
376 # put index entry
377 ($index = $rest) =~ s/^(An?\s+|The\s+)//i; # remove 'A' and 'The'
378 # index only those heads not matching the frequent patterns.
379 foreach $pat (@head1_freq_patterns) {
380 if ($index =~ /^$pat/) {
381 goto freqpatt;
382 }
383 }
384 print LATEX "%\n\\index{$index}\n" if ($index);
385 freqpatt:
386 $lastcmd = 'head1';
387 }
388 elsif ($cmd eq 'head2') { # heading type 2
389 $rest =~ s/^\s*//; $rest =~ s/\s*$//;
390 print LATEX "\n\\subsubsection*{$rest}";
391 # put index entry
392 ($index = $rest) =~ s/^(An?\s+|The\s+)//i; # remove 'A' and 'The'
393 $index =~ s/^Example\s*[1-9][0-9]*\s*:\s*//; # remove 'Example :'
394 print LATEX "%\n\\index{$index}\n" if ($index);
395 $lastcmd = 'head2';
396 }
397 elsif ($cmd eq 'over') { # 1 level within a listing environment
398 push(@indent,$indent);
399 $indent = $rest + 0;
400 $lastcmd = 'over';
401 }
402 elsif ($cmd eq 'back') { # 1 level out of a listing environment
403 $indent = pop(@indent);
404 warn "Unmatched =back\n" unless defined $indent;
405 $listingcmd = pop(@listingcmd);
406 print LATEX "\n\\end{$listingcmd}\n" if ($listingcmd);
407 $lastcmd = 'back';
408 }
409 elsif ($cmd eq 'item') { # an item paragraph starts
410 if ($lastcmd eq 'over') { # if we have just entered listing env
411 # see what type of list environment we are in.
412 if ($rest =~ /^[0-9]\.?/) { # if numeral heading
413 $listingcmd = 'enumerate';
414 } elsif ($rest =~ /^\*\s*/) { # if * heading
415 $listingcmd = 'itemize';
416 } elsif ($rest =~ /^[^*]/) { # if other headings
417 $listingcmd = 'description';
418 } else {
419 warn "unknown list type for item $rest";
420 }
421 print LATEX "\n\\begin{$listingcmd}\n";
422 push(@listingcmd,$listingcmd);
d23ed1f2 423 } elsif ( !@listingcmd ) {
748a9306 424 warn "Illegal '=item' command without preceding 'over':";
425 warn "=item $bareitem";
426 }
427
428 if ($listingcmd eq 'enumerate') {
429 $rest =~ s/^[0-9]+\.?\s*//; # remove numeral heading
430 print LATEX "\n\\item";
431 print LATEX "{\\bf $rest}" if $rest;
432 } elsif ($listingcmd eq 'itemize') {
433 $rest =~ s/^\*\s*//; # remove * heading
434 print LATEX "\n\\item";
435 print LATEX "{\\bf $rest}" if $rest;
436 } else { # description item
437 print LATEX "\n\\item[$rest]";
438 }
439 $lastcmd = 'item';
440 $rightafter_item = 'yes';
441
442 # check if the item heading is short or long.
443 ($itemhead = $rest) =~ s/{\\bf (\S*)}/$1/g;
444 if (length($itemhead) < 4) {
445 $itemshort = "yes";
446 } else {
447 $itemshort = "no";
448 }
449 # write index entry
450 if ($pod =~ "perldiag") { # skip 'perldiag.pod'
451 goto noindex;
452 }
453 # strip out the item of pod quotes and get a plain text entry
454 $bareitem =~ s/\n/ /g; # remove newlines
455 $bareitem =~ s/\s*$//; # remove trailing space
456 $bareitem =~ s/[A-Z]<([^<>]*)>/$1/g; # remove <> quotes
457 ($index = $bareitem) =~ s/^\*\s+//; # remove leading '*'
458 $index =~ s/^(An?\s+|The\s+)//i; # remove 'A' and 'The'
459 $index =~ s/^\s*[1-9][0-9]*\s*[.]\s*$//; # remove numeral only
460 $index =~ s/^\s*\w\s*$//; # remove 1 char only's
461 # quote ", @ and ! with " to be used in makeindex.
462 $index =~ s/"/""/g; # quote "
463 $index =~ s/@/"@/g; # quote @
464 $index =~ s/!/"!/g; # quote !
465 ($rest2=$rest) =~ s/^\*\s+//; # remove *
466 $rest2 =~ s/"/""/g; # quote "
467 $rest2 =~ s/@/"@/g; # quote @
468 $rest2 =~ s/!/"!/g; # quote !
469 if ($pod =~ "(perlfunc|perlvar)") { # when doc is perlfunc,perlvar
470 # take only the 1st word of item heading
471 $index =~ s/^([^{}\s]*)({.*})?([^{}\s]*)\s+.*/\1\2\3/;
472 $rest2 =~ s/^([^{}\s]*)({.*})?([^{}\s]*)\s+.*/\1\2\3/;
473 }
474 if ($index =~ /[A-Za-z\$@%]/) {
475 # write \index{plain_text_entry@TeX_string_entry}
476 print LATEX "%\n\\index{$index\@$rest2}%\n";
477 }
478 noindex:
479 ;
480 }
f9a26a8b 481 elsif ($cmd eq 'pod') {
482 ; # recognise the pod directive, as no op (hs)
483 }
a3cb178b 484 elsif ($cmd eq 'pod') {
485 ; # recognise the pod directive, as no op (hs)
486 }
748a9306 487 else {
488 warn "Unrecognized directive: $cmd\n";
489 }
490 }
491 else { # if not command
492 &escapes;
493 $_ = &clear_noremap($_);
494 $_ = &expand_HTML_escapes($_);
495
496 # if the present paragraphs follows an =item declaration,
497 # put a line break.
498 if ($lastcmd eq 'item' &&
499 $rightafter_item eq 'yes' && $itemshort eq "no") {
500 print LATEX "\\hfil\\\\";
501 $rightafter_item = 'no';
502 }
503 print LATEX "\n",$_;
504 }
505}
506
507print LATEX "\n";
508close(POD);
509close(LATEX);
510
511
512#########################################################################
513
514sub do_hdr {
515 print LATEX "% LaTeX document produced by pod2latex from \"$pod.pod\".\n";
516 print LATEX "% The followings need be defined in the preamble of this document:\n";
517 print LATEX "%\\def\\C++{{\\rm C\\kern-.05em\\raise.3ex\\hbox{\\footnotesize ++}}}\n";
518 print LATEX "%\\def\\underscore{\\leavevmode\\kern.04em\\vbox{\\hrule width 0.4em height 0.3pt}}\n";
519 print LATEX "%\\setlength{\\parindent}{0pt}\n";
520 print LATEX "\n";
521 $podq = &escape_tex_specials("\U$pod\E");
522 print LATEX "\\section{$podq}%\n";
523 print LATEX "\\index{$podq}";
524 print LATEX "\n";
525}
526
527sub nobreak {
528 my $string = shift;
529 $string =~ s/ +/~/g; # TeX no line break
530 $string;
531}
532
533sub noremap {
534 local($thing_to_hide) = shift;
535 $thing_to_hide =~ tr/\000-\177/\200-\377/;
536 return $thing_to_hide;
537}
538
539sub init_noremap {
18b0293d 540 # escape high bit characters in input stream
541 s/([\200-\377])/"E<".ord($1).">"/ge;
748a9306 542}
543
544sub clear_noremap {
545 local($tmp) = shift;
546 $tmp =~ tr/\200-\377/\000-\177/;
547 return $tmp;
548}
549
550sub expand_HTML_escapes {
551 local($s) = $_[0];
18b0293d 552 $s =~ s { E<((\d+)|([A-Za-z]+))> }
748a9306 553 {
554 do {
18b0293d 555 defined($2)
556 ? do { chr($2) }
557 :
558 exists $HTML_Escapes{$3}
559 ? do { $HTML_Escapes{$3} }
748a9306 560 : do {
561 warn "Unknown escape: $& in $_";
562 "E<$1>";
563 }
564 }
565 }egx;
566 return $s;
567}
568
569sub escapes {
570 # make C++ into \C++, which is to be defined as
571 # \def\C++{{\rm C\kern-.05em\raise.3ex\hbox{\footnotesize ++}}}
572 s/\bC\+\+/\\C++{}/g;
573}
574
575# Translate a string into a TeX \tt string to obtain a verbatim print out.
576# TeX special characters are escaped by \.
577# This can be used inside of LaTeX command arguments.
578# We don't use LaTeX \verb since it doesn't work inside of command arguments.
579sub alltt {
580 local($str) = shift;
581 # other chars than #,\,$,%,&,{,},_,\,^,~ ([ and ] included).
582 $str =~ s/([^${backslash_escapables}\\\^\~]+)/&noremap("$&")/eg;
583 # chars #,\,$,%,&,{,} => \# , ...
584 $str =~ s/([$backslash_escapables2])/&noremap("\\$&")/eg;
585 # chars _,\,^,~ => \char`\_ , ...
586 $str =~ s/_/&noremap("\\char`\\_")/eg;
587 $str =~ s/\\/&noremap("\\char`\\\\")/ge;
588 $str =~ s/\^/\\char`\\^/g;
589 $str =~ s/\~/\\char`\\~/g;
590
591 $str =~ tr/\200-\377/\000-\177/; # put back
592 $str = "{\\tt ".$str."}"; # make it a \tt string
593 return $str;
594}
595
596sub escape_tex_specials {
597 local($str) = shift;
598 # other chars than #,\,$,%,&,{,}, _,\,^,~ ([ and ] included).
599 # backslash escapable characters #,\,$,%,&,{,} except _.
600 $str =~ s/([$backslash_escapables2])/&noremap("\\$1")/ge;
601 $str =~ s/_/&noremap("\\underscore{}")/ge; # \_ is too thin.
602 # quote TeX special characters |, ^, ~, \.
603 $str =~ s/\|/&noremap("\$|\$")/ge;
604 $str =~ s/\^/&noremap("\$\\hat{\\hspace{0.4em}}\$")/ge;
605 $str =~ s/\~/&noremap("\$\\tilde{\\hspace{0.4em}}\$")/ge;
606 $str =~ s/\\/&noremap("\$\\backslash{}\$")/ge;
607 # characters need to be treated differently in TeX
608 # *
609 $str =~ s/[*]/&noremap("\$\\ast\$")/ge;
610 # escape < and > as math string,
611 $str =~ s/</&noremap("\$<\$")/ge;
612 $str =~ s/>/&noremap("\$>\$")/ge;
613 $str =~ tr/\200-\377/\000-\177/; # put back
614 return $str;
615}
616
617sub internal_lrefs {
618 local($_) = shift;
619
620 s{L</([^>]+)>}{$1}g;
621 my(@items) = split( /(?:,?\s+(?:and\s+)?)/ );
622 my $retstr = "the ";
623 my $i;
624 for ($i = 0; $i <= $#items; $i++) {
625 $retstr .= "C<$items[$i]>";
626 $retstr .= ", " if @items > 2 && $i != $#items;
627 $retstr .= " and " if $i+2 == @items;
628 }
629 $retstr .= " entr" . ( @items > 1 ? "ies" : "y" )
630 . " elsewhere in this document";
631
632 return $retstr;
633}
634
635# map of HTML escapes to TeX escapes.
636BEGIN {
637%HTML_Escapes = (
638 'amp' => '&', # ampersand
639 'lt' => '<', # left chevron, less-than
640 'gt' => '>', # right chevron, greater-than
641 'quot' => '"', # double quote
642
643 "Aacute" => "\\'{A}", # capital A, acute accent
644 "aacute" => "\\'{a}", # small a, acute accent
645 "Acirc" => "\\^{A}", # capital A, circumflex accent
646 "acirc" => "\\^{a}", # small a, circumflex accent
647 "AElig" => '\\AE', # capital AE diphthong (ligature)
648 "aelig" => '\\ae', # small ae diphthong (ligature)
649 "Agrave" => "\\`{A}", # capital A, grave accent
650 "agrave" => "\\`{a}", # small a, grave accent
651 "Aring" => '\\u{A}', # capital A, ring
652 "aring" => '\\u{a}', # small a, ring
653 "Atilde" => '\\~{A}', # capital A, tilde
654 "atilde" => '\\~{a}', # small a, tilde
655 "Auml" => '\\"{A}', # capital A, dieresis or umlaut mark
656 "auml" => '\\"{a}', # small a, dieresis or umlaut mark
657 "Ccedil" => '\\c{C}', # capital C, cedilla
658 "ccedil" => '\\c{c}', # small c, cedilla
659 "Eacute" => "\\'{E}", # capital E, acute accent
660 "eacute" => "\\'{e}", # small e, acute accent
661 "Ecirc" => "\\^{E}", # capital E, circumflex accent
662 "ecirc" => "\\^{e}", # small e, circumflex accent
663 "Egrave" => "\\`{E}", # capital E, grave accent
664 "egrave" => "\\`{e}", # small e, grave accent
665 "ETH" => '\\OE', # capital Eth, Icelandic
666 "eth" => '\\oe', # small eth, Icelandic
667 "Euml" => '\\"{E}', # capital E, dieresis or umlaut mark
668 "euml" => '\\"{e}', # small e, dieresis or umlaut mark
669 "Iacute" => "\\'{I}", # capital I, acute accent
670 "iacute" => "\\'{i}", # small i, acute accent
671 "Icirc" => "\\^{I}", # capital I, circumflex accent
672 "icirc" => "\\^{i}", # small i, circumflex accent
673 "Igrave" => "\\`{I}", # capital I, grave accent
674 "igrave" => "\\`{i}", # small i, grave accent
675 "Iuml" => '\\"{I}', # capital I, dieresis or umlaut mark
676 "iuml" => '\\"{i}', # small i, dieresis or umlaut mark
677 "Ntilde" => '\\~{N}', # capital N, tilde
678 "ntilde" => '\\~{n}', # small n, tilde
679 "Oacute" => "\\'{O}", # capital O, acute accent
680 "oacute" => "\\'{o}", # small o, acute accent
681 "Ocirc" => "\\^{O}", # capital O, circumflex accent
682 "ocirc" => "\\^{o}", # small o, circumflex accent
683 "Ograve" => "\\`{O}", # capital O, grave accent
684 "ograve" => "\\`{o}", # small o, grave accent
685 "Oslash" => "\\O", # capital O, slash
686 "oslash" => "\\o", # small o, slash
687 "Otilde" => "\\~{O}", # capital O, tilde
688 "otilde" => "\\~{o}", # small o, tilde
689 "Ouml" => '\\"{O}', # capital O, dieresis or umlaut mark
690 "ouml" => '\\"{o}', # small o, dieresis or umlaut mark
f9a26a8b 691 "szlig" => '\\ss{}', # small sharp s, German (sz ligature)
748a9306 692 "THORN" => '\\L', # capital THORN, Icelandic
693 "thorn" => '\\l',, # small thorn, Icelandic
694 "Uacute" => "\\'{U}", # capital U, acute accent
695 "uacute" => "\\'{u}", # small u, acute accent
696 "Ucirc" => "\\^{U}", # capital U, circumflex accent
697 "ucirc" => "\\^{u}", # small u, circumflex accent
698 "Ugrave" => "\\`{U}", # capital U, grave accent
699 "ugrave" => "\\`{u}", # small u, grave accent
700 "Uuml" => '\\"{U}', # capital U, dieresis or umlaut mark
701 "uuml" => '\\"{u}', # small u, dieresis or umlaut mark
702 "Yacute" => "\\'{Y}", # capital Y, acute accent
703 "yacute" => "\\'{y}", # small y, acute accent
704 "yuml" => '\\"{y}', # small y, dieresis or umlaut mark
705);
706}
5d94fbed 707!NO!SUBS!
4633a7c4 708
709close OUT or die "Can't close $file: $!";
710chmod 0755, $file or die "Can't reset permissions for $file: $!\n";
711exec("$Config{'eunicefix'} $file") if $Config{'eunicefix'} ne ':';
3b5ca523 712chdir $origdir;