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