1#!/usr/bin/env perl 2# Project: Documentation Tools 3# Descr: Latex --> MAN-page (groff -man), HTML and TexInfo; 4# Language: PERL (>= 5.0) 5# Author: Dr. J�rgen Vollmer, Juergen.Vollmer@informatik-vollmer.de 6# $Id: latex2man,v 1.156 2010/12/22 12:44:30 vollmer Exp $ 7# 8# Copyright (C) 1998 Dr. Juergen Vollmer 9# Viktoriastrasse 15, D-76133 Karlsruhe, Germany 10# Juergen.Vollmer@informatik-vollmer.de 11# License: 12# This program can be redistributed and/or modified under the terms 13# of the LaTeX Project Public License Distributed from CTAN 14# archives in directory macros/latex/base/lppl.txt; either 15# version 1 of the License, or any later version. 16# 17# If you find this software useful, please send me a postcard. 18 19require 5.0004_03; 20 21use Getopt::Std; 22 23# use strict 'vars'; 24 25$CMD=`basename $0`; chop ($CMD); 26$gen_date = `date`; chomp $gen_date; # date when the output was generated 27 28sub date2str; 29$VERSION = "1.24"; 30$DATE = date2str ('$Date: 2010/12/22 12:44:30 $' =~ m|(\d+/\d+/\d+)|); 31 32$tmp = "/tmp/$CMD.$$"; 33 34################################################################## 35# check option and arguments 36################################################################## 37 38getopts('o:t:c:VhMHTLC:D:a:'); # -D1: write each read line -D2: write each word 39 40sub usage 41{ 42print <<'END'; 43usage: latex2man [-t transfile] [-c cssfile] [-HTML] [-C name] [-h] [-V] infile outfile. 44 A tool to translate UNIX manual pages written with LaTeX into a format 45 understood by the UNIX man(1)-command. 46 Reads infile, writes outfile. 47 48 -t transfile: Translation for user defined LaTeX macros. 49 -c CSSfile: If -H is given, add a link to the \`CSSfile\' and use those 50 CSS definitions. 51 -M: Produce output suitable for the man(1) command (default). 52 -H: Instead of producing output suitable for the man(1) command, 53 HTML code is produced (despite of the name of the command). 54 -T: Instead of producing output suitable for the man(1) command, 55 TEXINFO code is produced (despite of the name of the command). 56 -L: Output the LaTeX source. Useful in conjunctin with the -C 57 option. 58 -C name: Enable conditional text \`name\'. 59 To enable more than one conditional name use quotes: 60 -C 'name1 name2 ...' 61 The following names are defined automatically: 62 -H defines HTML 63 -T defines TEXI 64 -M defines MAN 65 -L defines LATEX 66 -a char: Is used only in conjunction with -T. 67 Background: 68 TEXINFO ignores all blanks before the first word on a 69 new line. In order to produce some additional space before 70 that word (using \SP) some character has to be printed 71 before the additional space. By default this is a . (dot). 72 The \`char' specifies an alternative for that first character. 73 Giving a blank (-a" ") supresses the indentation of a line. 74 Note: only for the first \SP of a series that char is printed. 75 -h: Help. 76 -V: Version. 77 78 Copyright (C) 1998 Dr. J�rgen Vollmer, Viktoriastr. 15, D-76133 Karlsruhe 79 email: Juergen.Vollmer@informatik-vollmer.de 80 License: 81 This program can be redistributed and/or modified under the terms 82 of the LaTeX Project Public License Distributed from CTAN 83 archives in directory macros/latex/base/lppl.txt; either 84 version 1 of the License, or any later version. 85 86 If you find this software useful, please send me a postcard from the place 87 where you are living. 88END 89 print " Version $VERSION, $DATE.\n"; 90 exit 1; 91} 92 93($opt_h) && usage; 94($opt_V) && print "Version: $VERSION, $DATE\n"; 95 96# check command line arguments 97$opt_cnt = 0; 98$opt_cnt++ if ($opt_H); 99$opt_cnt++ if ($opt_T); 100$opt_cnt++ if ($opt_M); 101$opt_cnt++ if ($opt_L); 102if ($opt_cnt == 0) { 103 # if no option -H, -T, -M, -L is given, -M is the default 104 $opt_M = 1; 105} 106die "$CMD: you may give only one of the -H -T -M -L options\n" if ($opt_cnt > 1); 107 108(@ARGV == 2) || die "$CMD: Expected two arguments: infile outfile. Try \`$CMD -h'.\n"; 109 110my %cond_name; 111if ($opt_C) { 112 my $name; 113 foreach $name ((split (/\s/, $opt_C))) { 114 $cond_name{$name} = 1; 115 } 116} 117$cond_name{MAN} = 1 if ($opt_M); 118$cond_name{HTML} = 1 if ($opt_H); 119$cond_name{TEXI} = 1 if ($opt_T); 120$cond_name{LATEX} = 1 if ($opt_L); 121 122 123$SrcFile = $ARGV[0]; 124$DestFile = $ARGV[1]; 125open (SRC, "<$SrcFile") || die "$CMD: Can't open file \`$SrcFile' for reading.\n"; 126if ($opt_H || $opt_T) { 127 # DestFile will be written in the postprocess 128 open (DEST, ">$tmp") || die "$CMD: Can't open file \`$tmp' for writing.\n"; 129} else { 130 open (DEST, ">$DestFile") || die "$CMD: Can't open file \`$DestFile' for writing.\n"; 131} 132 133######################################################################## 134 135# global variables 136 137# $Prefix is used to construct procedure and variable names 138if ($opt_M) { 139 $Prefix = "man"; 140} 141if ($opt_H) { 142 $Prefix = "html"; 143} 144if ($opt_T) { 145 $Prefix = "texi"; 146} 147 148$texiCenterLine = 0; # true, only in TEXI-mode if a line must be centered 149$paragraph = 0; # true, if the last output was a paragraph marker 150$newline = 0; # true, if the last output was a newline char 151 152$first_word = 1; # true, if the next word to be processed is the first 153 # of a new paragraph or after a line break. 154 155# handling of itemize/enumerate/description environments: 156$list_nest = 0; # counts nesting of itemize/enumerate/description envrionments 157$cur_list[0] = "";# array, indexed with list_nest, indicates kind of list: 158 # values are: 'enum' / 'descr' / 'item' 159$item_nr[0] = 0; # array, indexed with list_nest, counts the number of \item in the 160 # list 161$manRS = 0; # true, if for Man a .RS was given after a \item 162 163$inside_verb = 0; # true, if inside a verbatim environment 164$inside_table = 0; # true, if inside a table environment 165$first_column = 0; # true, if this is the first column in a table row 166$columns = 0; # nr of columns in the current table 167$enum_nr = 0; # current number of an enumeration 168$nesting = 0; # count recursive calls of interpret_word 169$section_cnt = 0; # Index into $sections 170#$sections[0] # Array of all sections 171#$section_kind # Array of section kind (subsection/section) 172 173# translation of LaTeX macros without, with one and with two arguments 174$Macro = \%{$Prefix . "Macro"}; 175$Macro1a = \%{$Prefix . "Macro1a"}; 176$Macro1b = \%{$Prefix . "Macro1b"}; 177$Macro2a = \%{$Prefix . "Macro2a"}; 178$Macro2b = \%{$Prefix . "Macro2b"}; 179$Macro2c = \%{$Prefix . "Macro2c"}; 180 181# translations of special characters 182$LetterCode = \%{$Prefix . "LetterCode"}; 183 184######################################################################## 185 186sub interpret_word; 187sub interpret_line; 188sub Print; 189sub PrintM; 190sub NL; 191 192######################################################################## 193# Translation for LaTeX macros for MAN 194 195# translation of special characters 196$manLetterCode{'�'} = '�'; 197$manLetterCode{'�'} = '�'; 198$manLetterCode{'�'} = '�'; 199$manLetterCode{'�'} = '�'; 200$manLetterCode{'�'} = '�'; 201$manLetterCode{'�'} = '�'; 202$manLetterCode{'�'} = '�'; 203 204# LaTeX macros without arguments 205$manMacro{'LaTeX'} = 'LaTeX'; 206$manMacro{'LATEX'} = 'LaTeX'; # needed, since \LaTeX is contained in a 207 # section name (which are transposed 208 # into uppercase 209$manMacro{'itemsep'} = ' '; 210 211# some math 212$manMacro{'rightarrow'} = '-->'; 213$manMacro{'Rightarrow'} = '==>'; 214$manMacro{'leftarrow'} = '<--'; 215$manMacro{'Leftarrow'} = '<=='; 216$manMacro{'ge'} = '>='; 217$manMacro{'le'} = '<='; 218 219$manMacro{'Dollar'} = '$'; 220$manMacro{'Bar'} = '|'; 221$manMacro{'Bs'} = '\\\\'; 222$manMacro{'Tilde'} = '~'; 223$manMacro{'hline'} = '\n_'; 224$manMacro{'noindent'} = ''; 225$manMacro{'copyright'} = '(C)'; 226$manMacro{'Dots'} = '\&...\n'; 227$manMacro{'Circum'} = '^'; 228$manMacro{'Lbr'} = '['; 229$manMacro{'Rbr'} = ']'; 230$manMacro{'LBr'} = '{'; 231$manMacro{'RBr'} = '}'; 232$manMacro{'Percent'} = '%'; 233$manMacro{'Bullet'} = '*'; 234$manMacro{'TEXbr'} = ''; 235$manMacro{'MANbr'} = '\n.br\n'; 236$manMacro{'TEXIbr'} = ''; 237$manMacro{'HTMLbr'} = ''; 238$manMacro{'medskip'} = '\n'; 239$manMacro{'SP'} = '\fB \fP'; # hack hack this works even on 240 # the beginning of a line 241$manMacro{'SPfirst'} = $manMacro{'SP'}; 242 243$manMacro{'~'} = ' '; 244$manMacro{'|'} = '|'; 245$manMacro{'<'} = '<'; 246$manMacro{'>'} = '>'; 247$manMacro{'<='} = '<='; 248$manMacro{'>='} = '>='; 249$manMacro{'='} = '='; 250$manMacro{'<>'} = '<>'; 251$manMacro{'{'} = '{'; 252$manMacro{'}'} = '}'; 253$manMacro{'_'} = '_'; 254$manMacro{'$'} = '$'; 255$manMacro{'#'} = '#'; 256$manMacro{'&'} = '&'; 257$manMacro{'%'} = '%'; 258$manMacro{'-'} = ''; 259$manMacro{','} = ' '; 260 261$manMacro{'\\'} = '\n.br'; # line break 262$manMacro{'\\Tab'} = '\nT}'; # end of column in a table environment 263 264# LaTeX macros with one argument 265$manMacro1a{'emph'} = '\fI'; 266 $manMacro1b{'emph'} = '\fP'; 267$manMacro1a{'textbf'} = '\fB'; 268 $manMacro1b{'textbf'} = '\fP'; 269$manMacro1a{'texttt'} = ''; 270 $manMacro1b{'texttt'} = ''; 271$manMacro1a{'verb'} = ''; 272 $manMacro1b{'verb'} = ''; 273$manMacro1a{'underline'} = '\n.ul\n'; 274 $manMacro1b{'underline'}= '\n'; 275$manMacro1a{'section'} = '\n.SH '; 276 $manMacro1b{'section'} = '\n'; 277$manMacro1a{'subsection'} = '\n.SS '; 278 $manMacro1b{'subsection'} = ''; 279$manMacro1a{'subsubsection'} = '\n.SS '; 280 $manMacro1b{'subsubsection'} = ''; 281 282$manMacro1a{'Prog'} = ''; 283 $manMacro1b{'Prog'} = ''; 284$manMacro1a{'File'} = ''; 285 $manMacro1b{'File'} = ''; 286$manMacro1a{'Opt'} = '\fB'; 287 $manMacro1b{'Opt'} = '\fP'; 288$manMacro1a{'oOpt'} = '[\fB'; 289 $manMacro1b{'oOpt'} = '\fP]'; 290$manMacro1a{'Arg'} = '\fI'; 291 $manMacro1b{'Arg'} = '\fP'; 292$manMacro1a{'oArg'} = '[\fI'; 293 $manMacro1b{'oArg'} = '\fP]'; 294$manMacro1a{'Email'} = '\fB'; 295 $manMacro1b{'Email'} = '\fP'; 296$manMacro1a{'URL'} = '\fB'; 297 $manMacro1b{'URL'} = '\fP'; 298 299# LaTeX macros with two arguments 300$manMacro2a{'Cmd'} = '\fI'; 301 $manMacro2b{'Cmd'} = '\fP('; 302 $manMacro2c{'Cmd'} = ')'; 303$manMacro2a{'OptArg'} = '\fB'; 304 $manMacro2b{'OptArg'} = '\fP\fI'; 305 $manMacro2c{'OptArg'} = '\fP'; 306$manMacro2a{'OptoArg'} = '\fB'; 307 $manMacro2b{'OptoArg'} = '\fP[\fI'; 308 $manMacro2c{'OptoArg'} = '\fP]'; 309$manMacro2a{'oOptArg'} = '[\fB'; 310 $manMacro2b{'oOptArg'} = '\fP\fI'; 311 $manMacro2c{'oOptArg'} = '\fP]'; 312$manMacro2a{'oOptoArg'} = '[\fB'; 313 $manMacro2b{'oOptoArg'} = '\fP[\fI'; 314 $manMacro2c{'oOptoArg'} = '\fP]]'; 315$manMacro2a{'setlength'} = ''; 316 $manMacro2b{'setlength'}= ''; 317 $manMacro2c{'setlength'}= ''; 318 319######################################################################## 320# Translation for LaTeX macros for HTML 321 322# translation of special characters 323$htmlLetterCode{'�'} = 'ä'; 324$htmlLetterCode{'�'} = 'ö'; 325$htmlLetterCode{'�'} = 'ü'; 326$htmlLetterCode{'�'} = 'Ä'; 327$htmlLetterCode{'�'} = 'Ö'; 328$htmlLetterCode{'�'} = 'Ü'; 329$htmlLetterCode{'�'} = 'ß'; 330 331# LaTeX macros without arguments 332$htmlMacro{'LaTeX'} = 'LaTeX'; 333$htmlMacro{'LATEX'} = 'LaTeX'; # needed, since \LaTeX is contained in a 334 # section name (which are transposed 335 # into uppercase 336$htmlMacro{'itemsep'} = ''; 337 338# some math 339$htmlMacro{'rightarrow'} = '-->'; 340$htmlMacro{'Rightarrow'} = '==>'; 341$htmlMacro{'leftarrow'} = '<--'; 342$htmlMacro{'Leftarrow'} = '<=='; 343$htmlMacro{'ge'} = '>'; 344$htmlMacro{'le'} = '<='; 345 346$htmlMacro{'Dollar'} = '$'; 347$htmlMacro{'Bar'} = '|'; 348$htmlMacro{'Bs'} = '\\'; 349$htmlMacro{'Tilde'} = '~'; 350$htmlMacro{'hline'} = ''; 351$htmlMacro{'noindent'} = ''; 352$htmlMacro{'copyright'} = '©'; 353$htmlMacro{'Dots'} = '...'; 354$htmlMacro{'Circum'} = '^'; 355$htmlMacro{'Lbr'} = '['; 356$htmlMacro{'Rbr'} = ']'; 357$htmlMacro{'LBr'} = '{'; 358$htmlMacro{'RBr'} = '}'; 359$htmlMacro{'Percent'} = '%'; 360$htmlMacro{'Bullet'} = '*'; 361$htmlMacro{'TEXbr'} = ''; 362$htmlMacro{'MANbr'} = ''; 363$htmlMacro{'TEXIbr'} = ''; 364$htmlMacro{'HTMLbr'} = '<br>\n'; 365$htmlMacro{'medskip'} = '<br>\n'; 366$htmlMacro{'SP'} = ' '; 367$htmlMacro{'SPfirst'} = $htmlMacro{'SP'}; 368 369$htmlMacro{'~'} = ' '; 370$htmlMacro{'|'} = '|'; 371$htmlMacro{'<'} = '<'; 372$htmlMacro{'>'} = '>'; 373$htmlMacro{'<='} = '<='; 374$htmlMacro{'>='} = '>='; 375$htmlMacro{'='} = '='; 376$htmlMacro{'<>'} = '<>'; 377$htmlMacro{'{'} = '{'; 378$htmlMacro{'}'} = '}'; 379$htmlMacro{'_'} = '_'; 380$htmlMacro{'$'} = '$'; 381$htmlMacro{'#'} = '#'; 382$htmlMacro{'&'} = '&'; 383$htmlMacro{'%'} = '%'; 384$htmlMacro{'-'} = ''; 385$htmlMacro{','} = ' '; 386 387$htmlMacro{'\\'} = '<br>\n'; # line break 388$htmlMacro{'\\Tab'} = '</td>\n</tr>\n'; # end of column in a table environment 389 390# LaTeX macros with one argument 391$htmlMacro1a{'emph'} = '<em>'; 392 $htmlMacro1b{'emph'} = '</em>'; 393$htmlMacro1a{'textbf'} = '<strong>'; 394 $htmlMacro1b{'textbf'} = '</strong>'; 395$htmlMacro1a{'texttt'} = '<tt>'; 396 $htmlMacro1b{'texttt'} = '</tt>'; 397$htmlMacro1a{'verb'} = '<tt>'; 398 $htmlMacro1b{'verb'} = '</tt>'; 399$htmlMacro1a{'underline'} = '<u>'; 400 $htmlMacro1b{'underline'} = '</u>'; 401 $htmlMacro1a{'section'} = '\n<h2>'; 402 $htmlMacro1b{'section'} = '</h2>\n'; 403 $htmlMacro1a{'subsection'} = '\n<h4>'; 404 $htmlMacro1b{'subsection'} = '</h4>\n'; 405 $htmlMacro1a{'subsubsection'} = '\n<h5>'; 406 $htmlMacro1b{'subsubsection'} = '</h5>\n'; 407if ($opt_c) { 408 # use CSS 409 # thanks to Tom Brand <tbrand@manumit-systems.com> 410 $htmlMacro1a{'Email'} = '\n<font class="emailstyle">'; 411 $htmlMacro1b{'Email'} = '</font>'; 412 $htmlMacro1a{'URL'} = '\n<font class="urlstyle">'; 413 $htmlMacro1b{'URL'} = '</font>'; 414 415 $htmlMacro1a{'Prog'} = '<font class="progname">'; 416 $htmlMacro1b{'Prog'} = '</font>'; 417 $htmlMacro1a{'File'} = '<font class="filename">'; 418 $htmlMacro1b{'File'} = '</font>'; 419 $htmlMacro1a{'Opt'} = '<font class="optstyle">'; 420 $htmlMacro1b{'Opt'} = '</font>'; 421 $htmlMacro1a{'oOpt'} = '[<font class="optstyle">'; 422 $htmlMacro1b{'oOpt'} = '</font>]'; 423 $htmlMacro1a{'Arg'} = '<font class="argstyle">'; 424 $htmlMacro1b{'Arg'} = '</font>'; 425 $htmlMacro1a{'oArg'} = '[<font class="argstyle">'; 426 $htmlMacro1b{'oArg'} = '</font>]'; 427} else { 428 # don't use CSS 429 $htmlMacro1a{'Email'} = '\n<tt>'; 430 $htmlMacro1b{'Email'} = '</tt>'; 431 $htmlMacro1a{'URL'} = '\n<tt>'; 432 $htmlMacro1b{'URL'} = '</tt>'; 433 434 $htmlMacro1a{'Prog'} = '<tt>'; 435 $htmlMacro1b{'Prog'} = '</tt>'; 436 $htmlMacro1a{'File'} = '<tt>'; 437 $htmlMacro1b{'File'} = '</tt>'; 438 $htmlMacro1a{'Opt'} = '<b>'; 439 $htmlMacro1b{'Opt'} = '</b>'; 440 $htmlMacro1a{'oOpt'} = '[<b>'; 441 $htmlMacro1b{'oOpt'} = '</b>]'; 442 $htmlMacro1a{'Arg'} = '<i>'; 443 $htmlMacro1b{'Arg'} = '</i>'; 444 $htmlMacro1a{'oArg'} = '[<i>'; 445 $htmlMacro1b{'oArg'} = '</i>]'; 446} 447 448# LaTeX macros with two arguments 449if (opt_c) { 450 $htmlMacro2a{'Cmd'} = '<font class="commandname">'; 451 $htmlMacro2b{'Cmd'} = '</font>('; 452 $htmlMacro2c{'Cmd'} = ')'; 453 $htmlMacro2a{'OptArg'} = '<font class="optstyle">'; 454 $htmlMacro2b{'OptArg'} = '</font><font class="argstyle">'; 455 $htmlMacro2c{'OptArg'} = '</font>'; 456 $htmlMacro2a{'OptoArg'} = '<font class="optstyle">'; 457 $htmlMacro2b{'OptoArg'} = '</font>[<font class="argstyle">'; 458 $htmlMacro2c{'OptoArg'} = '</font>]'; 459 $htmlMacro2a{'oOptArg'} = '[<font class="optstyle">'; 460 $htmlMacro2b{'oOptArg'} = '</font><font class="argstyle">'; 461 $htmlMacro2c{'oOptArg'} = '</font>]'; 462 $htmlMacro2a{'oOptoArg'} = '[<font class="optstyle">'; 463 $htmlMacro2b{'oOptoArg'} = '</font>[<font class="argstyle">'; 464 $htmlMacro2c{'oOptoArg'} = '</font>]]'; 465} else { 466 $htmlMacro2a{'Cmd'} = '<em>'; 467 $htmlMacro2b{'Cmd'} = '</em>('; 468 $htmlMacro2c{'Cmd'} = ')'; 469 $htmlMacro2a{'OptArg'} = '<b>'; 470 $htmlMacro2b{'OptArg'} = '</b><i>'; 471 $htmlMacro2c{'OptArg'} = '</i>'; 472 $htmlMacro2a{'OptoArg'} = '<b>'; 473 $htmlMacro2b{'OptoArg'} = '</b>[<i>'; 474 $htmlMacro2c{'OptoArg'} = '</i>]'; 475 $htmlMacro2a{'oOptArg'} = '[<b>'; 476 $htmlMacro2b{'oOptArg'} = '</b><i>'; 477 $htmlMacro2c{'oOptArg'} = '</i>]'; 478 $htmlMacro2a{'oOptoArg'} = '[<b>'; 479 $htmlMacro2b{'oOptoArg'} = '</b>[<i>'; 480 $htmlMacro2c{'oOptoArg'} = '</i>]]'; 481} 482$htmlMacro2a{'setlength'} = ''; 483 $htmlMacro2b{'setlength'} = ''; 484 $htmlMacro2c{'setlength'} = ''; 485 486# we handle sections in HTML as having two arguments, 1. the number, 2. the name 487if ($opt_c) { 488 # use CSS 489 # thanks to Tom Brand <tbrand@manumit-systems.com> 490 $htmlMacro2a{'section'} = '\n<h2 class="sectionname"><a name="section_'; 491 $htmlMacro2b{'section'} = '">'; 492 $htmlMacro2c{'section'} = '</a></h2>\n'; 493 $htmlMacro2a{'subsection'} = '\n<h4 class="subsectionname"><a name="section_'; 494 $htmlMacro2b{'subsection'} = '">'; 495 $htmlMacro2c{'subsection'} = '</a></h4>\n'; 496 $htmlMacro2a{'subsubsection'} = '\n<h5 class="subsubsectionname"><a name="section_'; 497 $htmlMacro2b{'subsubsection'} = '">'; 498 $htmlMacro2c{'subsubsection'} = '</a></h5>\n'; 499 500 # we handle Email and URL special in HTML, the LaTeX argument is doubled. 501 $htmlMacro2a{'Email'} = '<a class="emailstyle" href ="mailto:'; 502 $htmlMacro2b{'Email'} = '">'; 503 $htmlMacro2c{'Email'} = '</a>'; 504 $htmlMacro2a{'URL'} = '<a class="urlstyle" href ="'; 505 $htmlMacro2b{'URL'} = '"><tt>'; 506 $htmlMacro2c{'URL'} = '</tt></a>'; 507 508}else{ 509 # don't use CSS 510 $htmlMacro2a{'section'} = '\n<h2><a name="section_'; 511 $htmlMacro2b{'section'} = '">'; 512 $htmlMacro2c{'section'} = '</a></h2>\n'; 513 $htmlMacro2a{'subsection'} = '\n<h4><a name="section_'; 514 $htmlMacro2b{'subsection'} = '">'; 515 $htmlMacro2c{'subsection'} = '</a></h4>\n'; 516 $htmlMacro2a{'subsubsection'} = '\n<h5><a name="section_'; 517 $htmlMacro2b{'subsubsection'} = '">'; 518 $htmlMacro2c{'subsubsection'} = '</a></h5>\n'; 519 520 # we handle Email and URL special in HTML, the LaTeX argument is doubled. 521 $htmlMacro2a{'Email'} = '<a href ="mailto:'; 522 $htmlMacro2b{'Email'} = '"><tt>'; 523 $htmlMacro2c{'Email'} = '</tt></a>'; 524 $htmlMacro2a{'URL'} = '<a href ="'; 525 $htmlMacro2b{'URL'} = '"><tt>'; 526 $htmlMacro2c{'URL'} = '</tt></a>'; 527} 528 529######################################################################## 530# Translation for LaTeX macros for TexInfo 531 532# translation of special characters 533$texiLetterCode{'�'} = '@"a'; 534$texiLetterCode{'�'} = '@"o'; 535$texiLetterCode{'�'} = '@"u'; 536$texiLetterCode{'�'} = '@"A'; 537$texiLetterCode{'�'} = '@"O'; 538$texiLetterCode{'�'} = '@"U'; 539$texiLetterCode{'�'} = '@ss{}'; 540 541# LaTeX macros without arguments 542$texiMacro{'LaTeX'} = 'LaTeX'; 543$texiMacro{'LATEX'} = 'LaTeX'; # needed, since \LaTeX is contained in a 544 # section name (which are transposed 545 # into uppercase 546$texiMacro{'itemsep'} = ''; 547 548# some math 549$texiMacro{'rightarrow'} = '-->'; 550$texiMacro{'Rightarrow'} = '==>'; 551$texiMacro{'leftarrow'} = '<--'; 552$texiMacro{'Leftarrow'} = '<=='; 553$texiMacro{'ge'} = '>='; 554$texiMacro{'le'} = '<='; 555 556$texiMacro{'Dollar'} = '$'; 557$texiMacro{'Bar'} = '|'; 558$texiMacro{'Bs'} = '\\'; 559$texiMacro{'Tilde'} = '~'; 560$texiMacro{'hline'} = ''; 561$texiMacro{'noindent'} = '\n@noindent\n'; 562$texiMacro{'copyright'} = '@copyright{}'; 563$texiMacro{'Dots'} = '...'; 564$texiMacro{'Circum'} = '^'; 565$texiMacro{'Lbr'} = '['; 566$texiMacro{'Rbr'} = ']'; 567$texiMacro{'LBr'} = '@{'; 568$texiMacro{'RBr'} = '@}'; 569$texiMacro{'Percent'} = '%'; 570$texiMacro{'Bullet'} = '*'; 571$texiMacro{'TEXbr'} = ''; 572$texiMacro{'MANbr'} = ''; 573$texiMacro{'TEXIbr'} = '@*\n'; 574$texiMacro{'HTMLbr'} = ''; 575$texiMacro{'medskip'} = '@sp 2\n'; 576$texiMacro{'SP'} = '@ @ '; 577 578if ($opt_a) { 579 $texiMacro{'SPfirst'} = $opt_a . '@ '; 580 } else { 581 $texiMacro{'SPfirst'} = '.@ '; 582} 583 584$texiMacro{'~'} = ' '; 585$texiMacro{'|'} = '|'; 586$texiMacro{'<'} = '<'; 587$texiMacro{'>'} = '>'; 588$texiMacro{'<='} = '<='; 589$texiMacro{'>='} = '>='; 590$texiMacro{'='} = '='; 591$texiMacro{'<>'} = '<>'; 592$texiMacro{'{'} = '@{'; 593$texiMacro{'}'} = '@}'; 594$texiMacro{'_'} = '_'; 595$texiMacro{'$'} = '$'; 596$texiMacro{'#'} = '#'; 597$texiMacro{'&'} = '&'; 598$texiMacro{'%'} = '%'; 599$texiMacro{'-'} = '@-'; 600$texiMacro{','} = ' '; 601 602$texiMacro{'\\'} = '@*\n'; # line break 603$texiMacro{'\\Tab'} = '\n'; # end of column in a table environment 604 605# LaTeX macros with one argument 606$texiMacro1a{'emph'} = '@emph{'; $texiMacro1b{'emph'} = '}'; 607$texiMacro1a{'textbf'} = '@strong{'; $texiMacro1b{'textbf'} = '}'; 608$texiMacro1a{'texttt'} = '@t{'; $texiMacro1b{'texttt'} = '}'; 609$texiMacro1a{'verb'} = '@t{'; $texiMacro1b{'verb'} = '}'; 610$texiMacro1a{'underline'} = ''; $texiMacro1b{'underline'} = ''; 611$texiMacro1a{'section'} = '\n@section '; $texiMacro1b{'section'} = '\n'; 612$texiMacro1a{'subsection'} = '\n@subsection '; $texiMacro1b{'subsection'} = '\n'; 613$texiMacro1a{'subsubsection'} = '\n@subsubsection '; $texiMacro1b{'subsubsection'} = '\n'; 614 615$texiMacro1a{'Prog'} = ''; $texiMacro1b{'Prog'} = ''; 616$texiMacro1a{'File'} = '@file{'; $texiMacro1b{'File'} = '}'; 617$texiMacro1a{'Opt'} = ''; $texiMacro1b{'Opt'} = ''; 618$texiMacro1a{'oOpt'} = '[ '; $texiMacro1b{'oOpt'} = ' ]'; 619$texiMacro1a{'Arg'} = '@var{'; $texiMacro1b{'Arg'} = '}'; 620$texiMacro1a{'oArg'} = '[ @var{'; $texiMacro1b{'oArg'} = '} ]'; 621$texiMacro1a{'Email'} = '@email{'; $texiMacro1b{'Email'} = '}'; 622$texiMacro1a{'URL'} = '@url{'; $texiMacro1b{'URL'} = '}'; 623 624# LaTeX macros with two arguments 625$texiMacro2a{'Cmd'} = ''; 626 $texiMacro2b{'Cmd'} = '('; 627 $texiMacro2c{'Cmd'} = ')'; 628$texiMacro2a{'OptArg'} = ''; 629 $texiMacro2b{'OptArg'} = '@var{'; 630 $texiMacro2c{'OptArg'} = '}'; 631$texiMacro2a{'OptoArg'} = ''; 632 $texiMacro2b{'OptoArg'} = '[@var{'; 633 $texiMacro2c{'OptoArg'} = '}]'; 634$texiMacro2a{'oOptArg'} = '[ '; 635 $texiMacro2b{'oOptArg'} = '@var{'; 636 $texiMacro2c{'oOptArg'} = '} ]'; 637$texiMacro2a{'oOptoArg'} = '[ '; 638 $texiMacro2b{'oOptoArg'} = '[@var{'; 639 $texiMacro2c{'oOptoArg'} = '}] ]'; 640$texiMacro2a{'setlength'} = ''; 641 $texiMacro2b{'setlength'} = ''; 642 $texiMacro2c{'setlength'} = ''; 643 644######################################################################## 645# reading of translations for user macros 646 647if ($opt_t) { 648 do $opt_t; 649} 650 651######################################################################## 652# processing for MAN 653 654sub manStart 655{ 656 printf DEST "\'\\\" t\n"; # process with tbl 657 printf DEST ".\\\" Manual page created with $CMD on $gen_date\n"; 658 printf DEST ".\\\" NOTE: This file is generated, DO NOT EDIT.\n"; 659 660 # Definitionen von Verbatimbegin and Verbatimend 661 Print ".de Vb\n.ft CW\n.nf\n..\n.de Ve\n.ft R\n\n.fi\n..\n"; 662 663 Print ".TH \"$Name\" \"$chapter\" \"". $date ."\" \""; 664 interpret_word "$tool"; 665 Print "\" \""; interpret_word "$tool"; Print "\""; NL; 666 # thanks to Andrew Anderson <aja@emulab.ee.mu.oz.au> 667} 668sub manEnd 669{ 670 NL; printf DEST ".\\\" NOTE: This file is generated, DO NOT EDIT.\n"; 671} 672sub manSection 673{ 674 my ($cnt, $kind, $section) = @_; 675 if ($kind ne "subsubsection"){ 676 $section = uc $section; 677 } 678 interpret_line "\\$kind\{$section\}"; 679} 680sub manParagraph 681{ 682 if (!$paragraph) { 683 if ($manRS == 0 && $list_nest > 1) { 684 Print '\n.RS'; 685 $manRS = 1; 686 } 687 Print '\n.PP\n'; 688 $paragraph = 1; 689 } 690} 691sub manVerb 692{ 693 my $arg = $_[0]; 694 if ($arg =~ /^\./) { print DEST '\\&' }; 695 Print $arg 696} 697sub manItemWithArg 698{ 699 my $arg = $_[0]; 700 if ($manRS == 1) { 701 Print '\n.RE\n'; 702 } 703 $manRS = 0; 704 Print '\n.TP\n'; 705 interpret_word $arg; 706 PrintM ' '; 707 NL; 708} 709sub manItem 710{ 711 if ($manRS == 1) { 712 Print '\n.RE\n'; 713 } 714 $manRS = 0; 715 Print '\n.TP\n'; 716 if ($cur_list[$list_nest] eq 'item') { 717 Print '.B *'; 718 } elsif ($cur_list[$list_nest] eq 'enum') { 719 Print $item_nr[$list_nest] . '.'; 720 } 721 NL; 722} 723sub manDescriptionStart 724{ 725 if ($list_nest > 1) { 726 Print '\n.RS\n'; 727 } 728} 729sub manDescriptionEnd 730{ 731 if ($manRS) { 732 Print '\n.RE\n'; 733 $manRS == 0; 734 } 735 if ($list_nest > 1) { 736 Print '\n.RE\n'; 737 } 738 manParagraph; 739} 740sub manItemStart 741{ 742 if ($list_nest > 1) { 743 Print '\n.RS\n'; 744 } 745} 746sub manItemEnd 747{ 748 if ($manRS) { 749 Print '\n.RE\n'; 750 $manRS == 0; 751 } 752 if ($list_nest > 1) { 753 Print '\n.RE\n'; 754 } 755 manParagraph; 756} 757sub manEnumEnd 758{ 759 if ($manRS) { 760 Print '\n.RE\n'; 761 $manRS == 0; 762 } 763 if ($list_nest > 1) { 764 Print '\n.RE\n'; 765 } 766 manParagraph; 767} 768 769sub manEnumStart 770{ 771 if ($list_nest > 1) { 772 Print '\n.RS\n'; 773 } 774} 775sub manCenterStart 776{ 777 PrintM '\n.ce 100\n'; 778} 779sub manCenterEnd 780{ 781 PrintM '\n.ce 0\n'; 782} 783sub manNameStart 784{ 785 interpret_line "\\section\{NAME\}$rest"; 786} 787sub manNameEnd 788{ 789 # nothing 790} 791sub manTableStart 792{ 793 my $columns = $_[0]; 794 my $width = $_[1]; 795 my $i; 796 manParagraph; 797 Print '.TS\n'; 798 Print 'tab(&);\n'; 799 for ($i = 1; $i <= $columns; $i++) { 800 Print " l"; 801 } 802 Print "w($width)" if ($width); 803 Print '.\n'; 804} 805sub manTableSep 806{ 807 Print '\nT}&T{\n'; 808} 809sub manTableEnd 810{ 811 Print '\n.TE\n'; 812 manParagraph; 813} 814 815sub manVerbatimStart 816{ 817 Print '\n.Vb\n'; 818} 819 820sub manVerbatimEnd 821{ 822 Print '.Ve\n'; 823} 824 825sub manVerbatimLine 826{ 827 s/\\/\\\\/g; 828 s/-/\\-/g; 829 print DEST "$_"; 830} 831 832########################################################################### 833# processing for HTML 834 835sub htmlStart 836{ 837 Print "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2 Final//EN\">"; NL; 838 Print "<!-- Manual page created with $CMD on $gen_date"; NL; 839 Print " ** Author of $CMD: Juergen.Vollmer\@informatik-vollmer.de";NL; 840 Print " ** NOTE: This file is generated, DO NOT EDIT. -->"; NL; 841 Print "<html>"; NL; 842 Print "<head><title>$Name</title>"; NL; 843 844 if ($opt_c) { 845 Print '<link href="'.$opt_c.'" rel="stylesheet" type="text/css">'; NL; 846 Print "</head><body>"; NL; 847 Print '<h1 class="titlehead">'; NL; 848 interpret_line $title; 849 Print '</h1>'; NL; 850 Print '<h4 class="authorhead">'; interpret_word $author; Print '</h4>'; NL; 851 Print "<h4 class=\"datehead\">$date</h4>"; NL; 852 Print "<h4 class=\"versionhead\">Version $version</h4>"; NL; 853 } else { 854 Print "</head><body bgcolor=\"white\">"; NL; 855 856 Print "<h1 align=center>"; NL; 857 interpret_line $title; 858 Print "</h1>"; NL; 859 Print "<h4 align=center>"; interpret_word $author; Print "</h4>"; NL; 860 Print "<h4 align=center>$date</h4>"; NL; 861 Print "<h4 align=center>Version $version</h4>"; NL; 862 } 863} 864sub htmlEnd 865{ 866 Print "</body>"; NL; 867 Print "</html>"; NL; 868 Print "<!-- NOTE: This file is generated, DO NOT EDIT. -->"; NL; 869} 870sub htmlSection 871{ 872 my ($cnt, $kind, $section) = @_; 873 interpret_line "\\$kind\{$cnt\}\{$section\}"; 874} 875sub htmlCenterStart 876{ 877 Print '\n<div align=center>\n'; 878} 879sub htmlCenterEnd 880{ 881 Print '\n</div>\n'; 882} 883sub htmlNameStart 884{ 885 # nothing 886} 887sub htmlNameEnd 888{ 889 Print '\n@@INSERTION-POINT@@-TOC@@\n'; 890} 891sub htmlParagraph 892{ 893 if (!$paragraph) { 894 NL; Print "<p>"; NL; 895 $paragraph = 1; 896 } 897} 898sub htmlVerb 899{ 900 $arg = $_[0]; 901 $arg =~ s/&/&/g; 902 $arg =~ s/>/>/g; 903 $arg =~ s/</</g; 904 Print $arg; 905} 906sub htmlItemWithArg 907{ 908 my $arg = $_[0]; 909 NL; 910 if ($item_nr[$list_nest] > 1) { 911 NL; Print "</dd>"; NL; 912 } 913 Print "<dt>"; 914 interpret_word $arg; Print "</dt>"; NL; 915 Print "<dd>"; 916} 917sub htmlItem 918{ 919 if ($item_nr[$list_nest] > 1) { 920 Print '</li>\n'; 921 } 922 if ($cur_list[$list_nest] eq 'item') { 923 Print '<li>'; 924 } elsif ($cur_list[$list_nest] eq 'enum') { 925 Print '<li value =' . $item_nr[$list_nest] .'>'; 926 } 927} 928sub htmlDescriptionStart 929{ 930 NL; Print "<dl compact>"; NL; 931} 932sub htmlDescriptionEnd 933{ 934 NL; Print "</dd>\n</dl>"; NL; 935} 936sub htmlItemStart 937{ 938 NL; Print "<ul compact>"; NL; 939} 940sub htmlItemEnd 941{ 942 NL; Print "</li>\n</ul>"; NL; 943} 944sub htmlEnumStart 945{ 946 NL; Print "<ol compact>"; NL; 947} 948sub htmlEnumEnd 949{ 950 NL; Print "</li>\n</ol>"; NL; 951} 952sub htmlTableStart 953{ 954 my $columns = $_[0]; 955 my $width = $_[1]; 956 NL; 957 if ($opt_c) { 958 Print '<table summary="table" class="tablestyle">'; 959 } else{ 960 Print '<table summary="table">'; 961 } 962 NL; 963} 964sub htmlTableSep 965{ 966 if ($first_column == 0) { 967 Print '</td>\n'; 968 } 969 if ($opt_c) { 970 Print '<td class="cellstyle">'; 971 } else { 972 Print '<td>'; 973 } 974} 975sub htmlTableEnd 976{ 977 NL; Print "</table>"; NL; 978} 979 980sub htmlVerbatimStart 981{ 982 NL; Print '<pre>'; NL; 983} 984 985sub htmlVerbatimEnd 986{ 987 Print '</pre>'; NL; 988} 989 990sub htmlVerbatimLine 991{ 992 s/&/&/g; 993 s/</</g; 994 s/>/>/g; 995 print DEST "$_"; 996} 997 998########################################################################### 999# processing for TexInfo 1000 1001sub texiStart 1002{ 1003 Print '\input texinfo @c -*-texinfo-*-'; NL; 1004 Print '@c %**start of header'; NL; 1005 Print '@setfilename ' . "$name.info"; NL; 1006 Print '@settitle ' . "$name"; NL; 1007 Print '@c %**end of header'; NL; 1008 Print '@c Manual page created with' ." $CMD on $gen_date>"; NL; 1009 Print '@c NOTE: This file is generated, DO NOT EDIT.'; NL; 1010} 1011sub texiEnd 1012{ 1013 Print '@bye'; NL; 1014 Print '@c NOTE: This file is generated, DO NOT EDIT.'; NL; 1015} 1016sub texiSection 1017{ 1018 my ($cnt, $kind, $section) = @_; 1019 if (uc $sections[$cnt-1] eq "SYNOPSIS") { 1020 Print '\n@@INSERTION-POINT@@-TOC@@\n'; 1021 $sections[$cnt-1] = "Top"; # The predecessor node is Top and not SYNOPSIS 1022 } 1023 if (uc $sections[$cnt] eq "SYNOPSIS") { 1024 $cnt == 1 || 1025 die "$CMD: The Synopsis section must be the first section after\n" . 1026 "\t the Name environment\n"; 1027 } else { 1028 Print '\n@@INSERTION-POINT@@-TEXI-SEC@@' . " $kind $cnt" . '\n'; 1029 } 1030 interpret_line "\\$kind\{$section\}"; 1031} 1032sub texiNameStart 1033{ 1034 my ($name, $chapter, $author, $tool) = @_; 1035 $sections[0] = "Top"; 1036 # Print '@dircategory ' .$tool; NL; 1037 Print '@dircategory Man-pages'; NL; 1038 Print '@direntry'; NL; 1039 Print "* " . (ucfirst $name) . ": ($name). Its Man-Page "; NL; 1040 Print '@end direntry'; NL; 1041 Print '@titlepage'; NL; 1042 Print '@title ' . "$name"; NL; 1043 Print '@subtitle ' . "$tool"; NL; 1044 Print '@author ' . "$author"; NL; 1045 Print '@end titlepage'; NL; 1046 Print '\n@@INSERTION-POINT@@-TEXI-TOP@@'; NL; 1047 Print '@top ' . "$name"; NL; 1048} 1049sub texiNameEnd 1050{ 1051 # nothing 1052} 1053sub texiParagraph 1054{ 1055 if (!$paragraph) { 1056 NL; print DEST "\n"; 1057 $paragraph = 1; 1058 } 1059} 1060sub texiVerb 1061{ 1062 $arg = $_[0]; 1063 $arg =~ s/({|})/\@$1/g; 1064 Print $arg; 1065} 1066sub texiItemWithArg 1067{ 1068 my $arg = $_[0]; 1069 Print '\n@item '; 1070 interpret_word $arg; 1071 NL; 1072} 1073sub texiItem 1074{ 1075 Print '\n@item\n'; 1076} 1077sub texiDescriptionStart 1078{ 1079 Print '\n@table @samp\n'; 1080} 1081sub texiDescriptionEnd 1082{ 1083 Print '\n@end table\n'; 1084} 1085sub texiItemStart 1086{ 1087 Print '\n@itemize @bullet\n'; 1088} 1089sub texiItemEnd 1090{ 1091 Print '\n@end itemize\n'; 1092} 1093sub texiCenterStart 1094{ 1095 $texiCenterLine = 1; 1096 $newline = 0; 1097 $texiMacro{'\\'} = '@*'; # line break 1098 $texiMacro{'TEXIbr'} = '@*'; 1099 NL; 1100} 1101sub texiCenterEnd 1102{ 1103 $texiCenterLine = 0; 1104 $newline = 0; 1105 $texiMacro{'\\'} = '@*\n'; # line break 1106 $texiMacro{'TEXIbr'} = '@*\n'; 1107 NL; 1108} 1109 1110sub texiEnumStart 1111{ 1112 Print '\n@enumerate\n'; 1113} 1114sub texiEnumEnd 1115{ 1116 Print '\n@end enumerate\n'; 1117} 1118sub texiTableStart 1119{ 1120 my $columns = $_[0]; 1121 my $width = $_[1]; 1122 my $i; 1123 Print '\n@multitable @columnfractions '; 1124 for ($i = 1; $i <= $columns; $i++) { 1125 Print " " .0.9/$columns ; 1126 } 1127 Print '\n'; 1128} 1129sub texiTableSep 1130{ 1131 Print '@tab '; 1132} 1133sub texiTableEnd 1134{ 1135 Print '\n@end multitable\n'; 1136} 1137 1138sub texiVerbatimStart 1139{ 1140 NL; 1141 Print '@*'; NL 1142} 1143 1144sub texiVerbatimEnd 1145{ 1146 NL; 1147} 1148 1149sub texiVerbatimLine 1150{ 1151 s/({|}|@| )/@\1/g; 1152 chop; 1153 print DEST ".$_\@*\n"; 1154} 1155 1156########################################################################### 1157########################################################################### 1158# general processing 1159 1160# emit an error message is the given macro does not exists. 1161sub check_Macro 1162{ 1163 exists $Macro->{$_[0]} || 1164 die "Error in line $.: no such macro: \\$_[0]\n"; 1165} 1166sub check_Macro1 1167{ 1168 (exists $Macro1a->{$_[0]} && exists $Macro1b->{$_[0]}) || 1169 die "$CMD: Error in line $.: no such macro: \\$_[0]\n"; 1170} 1171sub check_Macro2 1172{ 1173 (exists $Macro2a->{$_[0]} && exists $Macro2b->{$_[0]} && exists $Macro2c->{$_[0]}) || 1174 die "$CMD: Error in line $.: no such macro: \\$_[0]\n"; 1175} 1176 1177sub NL 1178{ 1179 if (!$newline) { 1180 printf DEST "\n"; 1181 if ($texiCenterLine) { 1182 print DEST "\@center "; 1183 } 1184 $newline = 1; 1185 } 1186} 1187 1188sub interpret_word 1189{ 1190 if (@_ <= 0) { 1191 return; 1192 } 1193 $_ = join " ", @_; 1194 my ($s,$m,$a1,$a2,$r); # start, match/macro, argument1, argument2 1195 my $add_blank = 1; # if true, add a blank after the word 1196 if ($opt_D == 2) { 1197 if ($nesting == 0) { 1198 print "**** "; 1199 } else { 1200 print " "; 1201 } 1202 print "\`$_'\n"; 1203 } 1204 1205 if ($opt_H) { 1206 # handling of HTML table rows 1207 if ($inside_table == 1) { 1208 if ($first_column == 1) { 1209 if (/^$/) { 1210 return; 1211 } 1212 if (/^\\hline/) { 1213 if ($opt_c) { 1214 Print '\n<tr class="rowstyle"><td class="cellstyle" colspan=' . $columns . '><hr></td></tr>\n'; 1215 } else { 1216 Print '\n<tr><td colspan=' . $columns . '><hr></td></tr>\n'; 1217 } 1218 } 1219 if ($opt_c) { 1220 Print '\n<tr class="rowstyle">\n<td class="cellstyle">'; 1221 } else { 1222 Print '\n<tr>\n<td>'; 1223 } 1224 } 1225 $first_column = 0; 1226 } 1227 } elsif ($opt_M) { 1228 # handling of troff table rows 1229 if ($inside_table == 1) { 1230 if ($first_column == 1) { 1231 if (/^$/) { 1232 return; 1233 } 1234 Print 'T{\n'; 1235 } 1236 $first_column = 0; 1237 } 1238 } elsif ($opt_T) { 1239 # handling of TexInfo specific stuff 1240 if ($nesting == 0) { 1241 s'@'@@'g; 1242 } 1243 if ($inside_table == 1) { 1244 if ($first_column == 1) { 1245 Print '\n@item '; 1246 } 1247 $first_column = 0; 1248 } 1249 } 1250 1251 $nesting ++; 1252 1253 SWITCH: { 1254 /^$/ && do {$add_blank = 0; 1255 last SWITCH; 1256 }; 1257 /\\verb\+([^+]*)\+/ && do {$s=$`;$m=$1;$r=$'; 1258 interpret_word $s; 1259 PrintM $Macro1a->{'verb'}; 1260 &{$Prefix . "Verb"} ($m); 1261 PrintM $Macro1b->{'verb'}; 1262 interpret_word $r; 1263 last SWITCH; 1264 }; 1265 /\\(".|ss)/ && do {$s=$`;$m=$1;$r=$'; #" 1266 interpret_word $s; 1267 check_Macro $m; 1268 PrintM $Macro->{$m}; 1269 interpret_word $r; 1270 last SWITCH; 1271 }; 1272 /\\item\s*\[([^]]*)\]/ && do {$s=$`;$m=$1;$r=$'; 1273 interpret_word $s; 1274 $item_nr[$list_nest] ++; 1275 &{$Prefix . "ItemWithArg"} ($m); 1276 interpret_word $r; 1277 last SWITCH; 1278 }; 1279 /\\item\s*/ && do {$s=$`;$r=$'; 1280 interpret_word $s; 1281 $item_nr[$list_nest] ++; 1282 &{$Prefix . "Item"}; 1283 interpret_word $r; 1284 last SWITCH; 1285 }; 1286 # LaTeX macros with two arguments 1287 /\\([a-zA-Z]+){([^}]*)}{([^}]*)}/ 1288 && do {$s=$`;$m=$1;$a1=$2;$a2=$3;$r=$'; 1289 check_Macro2 $m; 1290 interpret_word $s; 1291 PrintM $Macro2a->{$m}; 1292 interpret_word $a1; 1293 PrintM $Macro2b->{$m}; 1294 interpret_word $a2; 1295 PrintM $Macro2c->{$m}; 1296 interpret_word $r; 1297 NL; 1298 last SWITCH; 1299 }; 1300 # Special Handling of Email and URL LaTeX macros with one argument 1301 /\\(URL|Email){([^}]*)}/ && ($opt_H) 1302 && do {$s=$`;$m=$1;$a1=$2;$r=$'; 1303 interpret_word $s; 1304 PrintM $Macro2a->{$m}; 1305 interpret_word $a1; 1306 PrintM $Macro2b->{$m}; 1307 interpret_word $a1; 1308 PrintM $Macro2c->{$m}; 1309 interpret_word $r; 1310 NL; 1311 last SWITCH; 1312 }; 1313 # LaTeX macros with one argument 1314 /\\([a-zA-Z]+){([^}]*)}/ && do {$s=$`;$m=$1;$a1=$2;$r=$'; 1315 check_Macro1 $m; 1316 interpret_word $s; 1317 PrintM $Macro1a->{$m}; 1318 interpret_word $a1; 1319 PrintM $Macro1b->{$m}; 1320 interpret_word $r; 1321 NL; 1322 last SWITCH; 1323 }; 1324 # Special handling of some LaTeX macros without an argument 1325 /\\SP\s*/ && do {$s=$`;$m=$1;$r=$'; 1326 interpret_word $s; 1327 if ($first_word) { 1328 PrintM $Macro->{"SPfirst"}; 1329 } else { 1330 PrintM $Macro->{"SP"}; 1331 } 1332 interpret_word $r; 1333 $add_blank = 0; 1334 last SWITCH; 1335 }; 1336 /\\(MANbr|TEXIbr|HTMLbr)\s*/ && do {$s=$`;$m=$1;$r=$'; 1337 # set $first_word to true 1338 check_Macro $m; 1339 interpret_word $s; 1340 PrintM $Macro->{$m}; 1341 $first_word = 1; 1342 interpret_word $r; 1343 $add_blank = 0; 1344 last SWITCH; 1345 }; 1346 # LaTeX macros without an argument: 1347 /\\([a-zA-Z]+)\s*/ && do {$s=$`;$m=$1;$r=$'; 1348 check_Macro $m; 1349 interpret_word $s; 1350 PrintM $Macro->{$m}; 1351 interpret_word $r; 1352 $add_blank = 0; 1353 last SWITCH; 1354 }; 1355 /\\({|}|\$|_|#|&|-|%|,|\.|;)/ && do {$s=$`;$m=$1;$r=$'; 1356 interpret_word $s; 1357 PrintM $Macro->{$m}; 1358 interpret_word $r; 1359 last SWITCH; 1360 }; 1361 # LaTeX Math 1362 /\$(<|>|<=|>=|=|<>)\$/ && do {$s=$`;$m=$1;$r=$'; 1363 interpret_word $s; 1364 PrintM $Macro->{$m}; 1365 interpret_word $r; 1366 last SWITCH; 1367 }; 1368 /\$([^\$]*)\$/ && do {$s=$`;$m=$1;$r=$'; 1369 interpret_word $s; 1370 interpret_word $m; 1371 interpret_word $r; 1372 last SWITCH; 1373 }; 1374 /&/ && do {$s=$`;$r=$'; 1375 interpret_word $s; 1376 &{$Prefix . "TableSep"}; 1377 $first_column = 0; 1378 interpret_word $r; 1379 last SWITCH; 1380 }; 1381 /~/ && do {$s=$`;$r=$'; 1382 interpret_word $s; 1383 PrintM $Macro->{'~'}; 1384 interpret_word $r; 1385 last SWITCH; 1386 }; 1387 /\\\\/ && do {$s=$`;$r=$'; 1388 interpret_word $s; 1389 if ($inside_table) { 1390 PrintM $Macro->{'\\Tab'}; 1391 $first_column = 1; 1392 if (length ($r) > 0) { 1393 interpret_word $r; 1394 } 1395 } else { 1396 PrintM $Macro->{'\\'}; 1397 $first_word = 1; 1398 interpret_word $r; 1399 } 1400 $add_blank = 0; 1401 last SWITCH; 1402 }; 1403 /\\$|\\ / && do {$s=$`;$r=$'; 1404 # LaTeX explicit blank \ will be 1405 # represented as a single \ at 1406 # the end of the word 1407 interpret_word $s; 1408 Print " "; 1409 interpret_word $r; 1410 last SWITCH; 1411 }; 1412 /\\/ && do {$s=$`;$r=$'; 1413 interpret_word $s; 1414 interpret_word "\\$r"; 1415 last SWITCH; 1416 }; 1417 ($opt_M == 1) && /((^\.|')+)/ && do {$s=$`;$m=$1;$r=$'; 1418 interpret_word $s; 1419 print DEST "\\&$m"; 1420 $newline = 0; 1421 interpret_word $r; 1422 last SWITCH; 1423 }; 1424 Print "$_"; 1425 }; 1426 $nesting --; 1427 Print " " if ($nesting == 0 && $add_blank); 1428} 1429 1430sub interpret_line 1431{ 1432 my $line = $_[0]; chomp $line; 1433 my @words = split(/\s+/,$line); 1434 my $max = $#words; 1435 my $i; 1436 my $join = 0; # true, if words must be joined 1437 my $word = ""; # the joined word 1438 my $kind = 0; # 1: item[ .. ], 2: { .. }, 3: \verb+ .. + 1439 if ($max < 0) { 1440 # empty line marks a paragraph 1441 &{$Prefix . "Paragraph"}; 1442 $first_word = 1; 1443 return; 1444 } 1445 for ($i = 0; $i <= $max; $i++) { 1446 $_ = $words[$i]; 1447 # printf "\`$words[$i]'"; 1448 if (/^[\s]*$/) { # skip leading blanks 1449 # nothing 1450 } elsif ((!$join || ($kind != 3)) && /^%+/) { # skip comments 1451 last; 1452 } else { 1453 # if blanks in a { .. }, \item[ .. ], \verb+ .. + then we have to joind words 1454 if ($join) { 1455 # check whether this is the last word to be joined 1456 if ($kind == 1) { # item 1457 $join = index ($_, "]") == -1; 1458 } elsif ($kind == 2) { # braces 1459 my @x = $_ =~ /[^\\]}/g; 1460 $join = $#x == -1; 1461 } elsif ($kind == 3) { # verb 1462 $join = index ($_, "+") == -1; 1463 } 1464 $word .= " " . $words[$i]; 1465 if (!$join) { 1466 interpret_word $word; 1467 $word = ""; 1468 } 1469 } else { 1470 # check whether we have to join some words 1471 if (/\\item/) { 1472 my $cnt1 = tr/[/[/; 1473 my $cnt2 = tr/]/]/; 1474 $join = $cnt1 != $cnt2 | $cnt1 == 0; 1475 $kind = 1; 1476 } elsif (/\\verb/) { 1477 my $cnt = tr/+/+/; 1478 $join = $cnt % 2 != 0; 1479 $kind = 3; 1480 } else { 1481 my @x = $_ =~ /[^\\]{/g; 1482 my @y = $_ =~ /[^\\]}/g; 1483 $join = $#x != $#y; 1484 $kind = 2; 1485 } 1486 if ($join) { 1487 $word = $words[$i]; 1488 } else { 1489 interpret_word $words[$i]; 1490 } 1491 } 1492 } 1493 } 1494 if ($join) { 1495 interpret_word $word; 1496 } 1497 NL; 1498} 1499 1500sub PrintM 1501# print only for Macro command text 1502{ 1503 if (@_ <= 0 || length ($_[0]) == 0) { 1504 return; 1505 } 1506 my $l = shift; 1507 my $c; 1508 $l =~ s/\\n/\n/g; 1509 foreach $c (split ("", $l)) { 1510 if ($c eq "\n") { 1511 NL; 1512 $newline = 0; 1513 } else { 1514 print DEST "$c"; 1515 } 1516 } 1517} 1518 1519sub Print 1520{ 1521 1522 # printf "\`$_[0]'\n"; 1523 if (@_ <= 0 || length ($_[0]) == 0) { 1524 return; 1525 } 1526 my $x = $_[0]; 1527 1528 unless ($x =~ /^\s*$/) { 1529 # if other chars than blanks are printed: 1530 $first_word = 0; 1531 } 1532 1533 if (!$inside_verb) { 1534 # transform special characters 1535 $x =~ s/([�������])/$LetterCode->{"$1"}/go; 1536 } 1537 1538 my @parts = split /\\n/, $x, -1; 1539 # -1: trailing \n generates an empty list element 1540 my $i; 1541 for ($i = 0; $i <= $#parts; $i++) { 1542 if ($newline) { 1543 # skip leading blanks after a newline 1544 $parts[$i] =~ s/^\s+//; 1545 } 1546 if (length($parts[$i]) > 0) { 1547 if ($opt_M) { 1548 $parts[$i] =~ s/\\/\\\\/g; 1549 $parts[$i] =~ s/-/\\-/g; 1550 } 1551 printf DEST "%s", $parts[$i]; 1552 $newline = 0; 1553 } 1554 if ($i < $#parts) { 1555 NL; 1556 } 1557 } 1558 $paragraph = 0; 1559} 1560######################################################################### 1561 1562sub date2str 1563{ 1564 @EnglishMonthName = ('','January','February','March','April','May','June','July', 1565 'August','September','October','November','December'); 1566 # split date 1567 my ($Year,$Month,$Day) = split (/\//,$_[0]); 1568 return $Day . " " . $EnglishMonthName[$Month] . " " . $Year; 1569} 1570 1571$rcs_date=`date '+%Y/%m/%d/'`; # date of the man-page, overwritten 1572 # by \rcsInfo 1573$date = date2str ($rcs_date); 1574$Macro->{'today'} = $date; 1575 1576######################################################################### 1577my @skip; # stack of skip-flags, 1: skip, 0: don't skip 1578push @skip, 0; # synthetic "outer most" IF, don't skip 1579my $last_cond_clause = ""; 1580 1581sub handle_conditional_text 1582{ 1583 $_ = $_[0]; 1584# printf "skip-stack: %s;\t top = %s\n", join (", ", @skip), $skip[-1]; 1585 if (/^\s*%@%\s+IF\s+([^%]*)\s+%@%\s*$/) { 1586 # produce a program, which evaluates the condition: 1587 my $prog_cond = $1; 1588 $prog_cond =~ s/(\w+)/\$$1/g; 1589 my $prog = ""; 1590 my $var; 1591 foreach $var (keys %cond_name) { 1592 if ($var ne "") { 1593 $prog .= "my \$$var = 1; " # declare set names, 1594 # undeclared ones get value 0 1595 } 1596 } 1597 $prog .= "return ($prog_cond) ? 0 : 1;"; 1598# print "\n**** [$prog]\n"; 1599 my $skip = eval $prog; 1600 ($@ eq "") || die "$CMD: error in line $.: wrong condition of `%@% IF.. ($@)\n"; 1601# print "**** skip=$skip\n"; 1602 1603 $last_cond_clause = "IF"; 1604 if ($skip[-1] == 1) { 1605 # skip this text, since outer IF skips 1606 push @skip, 1; 1607 } else { 1608 # outer IF is not skipped, hence consider this IF 1609 push @skip, $skip; 1610 } 1611 } elsif (/^\s*%@%\s+ELSE\s+%@%\s*$/) { 1612 ($last_cond_clause =~ /IF/ && ($#skip > 0)) || 1613 die "$CMD: error in line $.: `%@% ELSE %@%' without an `%@% IF..'\n"; 1614 $last_cond_clause = "ELSE"; 1615 if ($skip[-2] == 0) { 1616 $skip[-1] = $skip[-1]? 0 : 1; 1617 } 1618 } elsif (/^\s*%@%\s+END-IF\s+%@%\s*$/) { 1619 $last_cond_clause = "END-IF"; 1620 ($#skip == 0) && 1621 die "$CMD: error in line $.: `%@% END-IF %@%' without an `%@% IF..'\n"; 1622 pop @skip; 1623 } 1624# print "$last_cond_clause: skip = $skip[-1]\n"; 1625} 1626 1627############################################################################ 1628# handle LaTeX output 1629if ($opt_L) { 1630 while (<SRC>) { 1631 if ($opt_D == 1) { 1632 my $line = $_; chop $line; 1633 print "--- \`$line'\n"; 1634 } 1635 1636 if (/^\s*%@%\s/) { 1637 my $skip = $skip[-1]; 1638 handle_conditional_text ("$_"); 1639 # write %@% directive 1640 print DEST $_; 1641 next; 1642 } 1643 next if ($skip[-1] == 1); 1644 print DEST $_; 1645 } 1646 close (DEST); 1647 exit (0); 1648} 1649 1650############################################################################ 1651# handle non-LaTeX output 1652 1653# read sections 1654# Variables: $section name of the section in uppercase letters 1655# $chapter chapter of the man page 1656# $name name of the man page 1657# $Name name of the man page in uppercase 1658# $author author of the man page 1659# $tool info about the tool set, $name is part of 1660# $date date 1661# $version version info 1662$started = 0; 1663while (<SRC>) { 1664 if ($opt_D == 1) { 1665 my $line = $_; chop $line; 1666 print "--- \`$line'\n"; 1667 } 1668 1669 if ((/^\s*%@%\s/) && ($inside_verb==0)) { 1670 my $skip = $skip[-1]; 1671 handle_conditional_text ("$_"); 1672 } 1673 next if ($skip[-1] == 1); 1674 1675 if ($inside_verb) { 1676 if (/^\s*\\end{verbatim}/) { 1677 if ($started == 1) { 1678 &{$Prefix . "VerbatimEnd"}; 1679 $inside_verb = 0; 1680 } 1681 } else { 1682 &{$Prefix . "VerbatimLine"} ($_); 1683 } 1684 next; 1685 } 1686 1687 # remove {, } around Umlaute 1688 s/{(\\".)}/\1/g; # " 1689 s/{(\\ss)}/\1/g; 1690 1691 # normalize special characters 1692 s/\\"a/�/g; 1693 s/\\"o/�/g; 1694 s/\\"u/�/g; 1695 s/\\"A/�/g; 1696 s/\\"O/�/g; 1697 s/\\"U/�/g; 1698 s/\\ss/�/g; 1699 1700 if (/^\s*\\rcsInfo \$(.*)\$/) { 1701 my ($rcs_id,$rcs_file,$rcs_revision, 1702 $rcs_date,$rcs_time,$rcs_owner,$rcs_status,$rcs_locker) = split(/\s/,$1); 1703 $date = date2str ($rcs_date); 1704 $Macro->{'today'} = $date; 1705 } elsif (/^\s*\\setDate{\\rcsInfoLongDate}/) { 1706 $Macro->{'Date'} = $date; 1707 } elsif (/^\s*\\setDate{\\today}/) { 1708 $Macro->{'Date'} = $date; 1709 } elsif (/^\s*\\setDate{([^}]*)}/) { 1710 $date = $1; 1711 $date =~ s/~/$Macro->{'~'}/g; 1712 $Macro->{'Date'} = $date; 1713 } elsif (/^\s*\\setVersion{([^}]*)}/) { 1714 $version = $1; 1715 $versin =~ s/~/$Macro->{'~'}/g; 1716 $Macro->{'Version'} = $version; 1717 } elsif (/^\s*\\begin{Name}{([^}]*)}{([^}]*)}{([^}]*)}{([^}]*)}{([^}]*)}/) { 1718 $section = "Name"; 1719 $chapter = $1; 1720 $name = $2; 1721 $Name = uc $name; 1722 $author = $3; 1723 $tool = $4; 1724 $title = $5; 1725 $rest = $'; 1726 $started = 1; 1727 $sections[0] = $section; 1728 $section_cnt = 0; 1729 &{$Prefix . "Start"} ($name, $chapter, $author, $tool, $title); 1730 &{$Prefix . "NameStart"} ($name, $chapter, $author, $tool, $title); 1731 } elsif (/^\s*\\end{Name}/) { 1732 &{$Prefix . "NameEnd"} ($name, $chapter, $author, $tool); 1733 } elsif (/^\s*\\begin{Table}(\[([^]]*)\])?{([^}]*)}/) { 1734 # \begin{Table}[width]{columns} 1735 if ($started == 1) { 1736 $columns = $3; 1737 $column = $_[0]; 1738 $inside_table = 1; 1739 $first_column = 1; 1740 &{$Prefix . "TableStart"} ($columns, $2); 1741 } 1742 } elsif (/^\s*\\end{Table}/) { 1743 if ($started == 1) { 1744 $inside_table = 0; 1745 $first_column = 0; 1746 &{$Prefix . "TableEnd"} ($columns); 1747 } 1748 } elsif (/^\s*\\begin{Description}(\[[^]]*\])?/) { 1749 if ($started == 1) { 1750 $list_nest++; 1751 $cur_list[$list_nest] = 'descr'; 1752 $item_nr[$list_nest] = 0; 1753 &{$Prefix . "DescriptionStart"}; 1754 } 1755 } elsif (/^\s*\\end{Description}/) { 1756 if ($started == 1) { 1757 &{$Prefix . "DescriptionEnd"}; 1758 $list_nest--; 1759 } 1760 } elsif (/^\s*\\begin{description}/) { 1761 if ($started == 1) { 1762 $list_nest++; 1763 $cur_list[$list_nest] = 'descr'; 1764 $item_nr[$list_nest] = 0; 1765 &{$Prefix . "DescriptionStart"}; 1766 } 1767 } elsif (/^\s*\\end{description}/) { 1768 if ($started == 1) { 1769 &{$Prefix . "DescriptionEnd"}; 1770 $list_nest--; 1771 } 1772 } elsif (/^\s*\\begin{center}/) { 1773 if ($started == 1) { 1774 &{$Prefix . "CenterStart"}; 1775 } 1776 } elsif (/^\s*\\end{center}/) { 1777 if ($started == 1) { 1778 &{$Prefix . "CenterEnd"}; 1779 } 1780 } elsif (/^\s*\\begin{enumerate}/) { 1781 if ($started == 1) { 1782 $list_nest++; 1783 $cur_list[$list_nest] = 'enum'; 1784 $item_nr[$list_nest] = 0; 1785 &{$Prefix . "EnumStart"} ; 1786 } 1787 } elsif (/^\s*\\end{enumerate}/) { 1788 if ($started == 1) { 1789 &{$Prefix . "EnumEnd"} ; 1790 $list_nest--; 1791 } 1792 } elsif (/^\s*\\begin{itemize}/) { 1793 if ($started == 1) { 1794 $list_nest++; 1795 $cur_list[$list_nest] = 'item'; 1796 $item_nr[$list_nest] = 0; 1797 &{$Prefix . "ItemStart"} ; 1798 } 1799 } elsif (/^\s*\\end{itemize}/) { 1800 if ($started == 1) { 1801 &{$Prefix . "ItemEnd"} ; 1802 $list_nest--; 1803 } 1804 } elsif (/^\s*\\begin{verbatim}/) { 1805 if ($started == 1) { 1806 &{$Prefix . "VerbatimStart"}; 1807 $inside_verb = 1; 1808 } 1809 } elsif (/^\s*\\(subsubsection|subsection|section){([^}]*)}/) { 1810 $kind = $1; 1811 $section = $2; 1812 $section_cnt ++; 1813 $sections[$section_cnt] = $section; 1814 $section_kind[$section_cnt] = $kind; 1815 if ($started == 1) { 1816 &{$Prefix . "Section"} ($section_cnt, $kind, $section); 1817 } 1818 } elsif (/^\s*\\LatexManEnd/) { 1819 last; 1820 } elsif (/^\s*((\\begin{Name|Table|Description})|(\\(sub)?section))/) { 1821 die "$CMD: in line $.\n " . 1822 "Arguments of $1 are not contained in a single " . 1823 "line.\n " . 1824 "Remember: all arguments of a macro must be on the same line.\n"; 1825 } else { 1826 if ($started == 1) { 1827 interpret_line $_; 1828 } 1829 } 1830} 1831&{$Prefix . "End"}; 1832 1833close DEST; 1834 1835if ($opt_H || $opt_T) { 1836 open (TMP, "<$tmp") || die "$CMD: Can't open file \`$tmp' for reading.\n"; 1837 open (DEST, ">$DestFile") || die "$CMD: Can't open file \`$DestFile' for writing.\n"; 1838 while (<TMP>) { 1839 if (/^\@\@INSERTION-POINT\@\@-TOC\@\@$/) { 1840 if ($opt_H) { 1841 # Table of contents for HTML 1842 my $nesting = 0; # nesting of section/subsection/subsubsection 1843 Print '\n<h3>Table of Contents</h3>\n'; 1844 for ($i = 1; $i <= $section_cnt; $i++) { 1845 my $cur_nesting = 0; 1846 if ($section_kind[$i] eq "subsubsection") { 1847 $cur_nesting = 3; 1848 } elsif ($section_kind[$i] eq "subsection") { 1849 $cur_nesting = 2; 1850 } elsif ($section_kind[$i] eq "section") { 1851 $cur_nesting = 1; 1852 } 1853 if ($cur_nesting > $nesting) { 1854 # open a new list 1855 Print '\n<ul>\n' 1856 } 1857 if ($cur_nesting == $nesting) { 1858 # same level, close list item 1859 Print '</li>\n'; 1860 } 1861 if ($cur_nesting < $nesting) { 1862 # close list and list item 1863 for my $i ($cur_nesting .. $nesting-1) { 1864 Print '</li>\n'; 1865 Print '</ul>\n'; 1866 } 1867 } 1868 # print item 1869 Print "<li><a href=\"#section_$i\">"; 1870 interpret_word $sections[$i]; 1871 Print "</a>"; 1872 $nesting = $cur_nesting; 1873 } 1874 # close remaining lists 1875 for my $i (1 .. $nesting) { 1876 Print '</li>\n'; 1877 Print '</ul>\n'; 1878 } 1879 } else { 1880 # Menu of sections for texi 1881 Print '@menu\n'; 1882 for ($i = 2; $i <= $section_cnt; $i++) { 1883 interpret_line "* " . $sections[$i] . "::"; 1884 } 1885 Print '@end menu\n'; 1886 } 1887 } elsif (/\@\@INSERTION-POINT\@\@-TEXI-TOP\@\@/) { 1888 # Texi-top node 1889 Print '@node Top, ' . $sections[2] . ', (dir), (dir)\n'; 1890 } elsif (/\@\@INSERTION-POINT\@\@-TEXI-SEC\@\@ (\w+) (\d+)/) { 1891 # print section header for texi 1892 $kind = $1; 1893 $cnt = $2; 1894 $section = $sections[$cnt]; 1895 Print '@node ' ; 1896 interpret_word "$sections[$cnt], "; 1897 interpret_word "$sections[$cnt+1], "; 1898 interpret_word "$sections[$cnt-1], Top "; 1899 NL; 1900 } else { 1901 print DEST $_; 1902 } 1903 } 1904 close TMP; 1905 close DEST; 1906 unlink $tmp; 1907} 1908 1909######################################################################### 1910 1911## Emacs specific: 1912## Local Variables: *** 1913## mode: perl *** 1914## End: *** 1915 1916