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