diff options
author | Norbert Preining <norbert@preining.info> | 2019-09-02 13:46:59 +0900 |
---|---|---|
committer | Norbert Preining <norbert@preining.info> | 2019-09-02 13:46:59 +0900 |
commit | e0c6872cf40896c7be36b11dcc744620f10adf1d (patch) | |
tree | 60335e10d2f4354b0674ec22d7b53f0f8abee672 /support/tr2latex |
Initial commit
Diffstat (limited to 'support/tr2latex')
26 files changed, 4940 insertions, 0 deletions
diff --git a/support/tr2latex/History b/support/tr2latex/History new file mode 100644 index 0000000000..91e5979678 --- /dev/null +++ b/support/tr2latex/History @@ -0,0 +1,105 @@ + HISTORY + +Copyright (C) 1986, 1987 by Kamal Al-Yahya + 1991, 1992 by Christian Engel + 2008..2018 by Dirk Jagdmann + +Release 2.6 +- fixed some compiler warnings and string functions. +- added many new supported man commands with changes from Lothar Jostameling. + +Release 2.5 +- fix < and > symbols which were not output in LaTeX. + Thanks to Ron Yorston for the patch. + +Release 2.4 +- fix an undersized buffer +- compile on Windows + +Release 2.3 +- some fixes for a 2008 Linux/Unix +- "-b" option + +Revision 2.2 1992/04/27 15:13:51 Christian_Engel +- Fixed a bug in flip_twice I have brought in with revision 1.02 but didn't + notice earlier. It lead to wrong translation of nested flipping math + commands like ``a under hat''. + Bug reported by Richard Walker <richard@cs.anu.edu.au>. +- Some modifications to calm down some strange warnings on strange + compilers reported from the net +- Fixed bug in getopts: now input of stdin by pure command line argument `-' + works properly. +- Fixed bug in main: multiple command line arguments work properly now. + +Revision 2.1 1992/04/24 13:57:46 Christian_Engel +- Fixed inconsistend declaration of variable ``man'' +- Fixed some smaller bugs and inconsistencies reported by netlanders after + releasing Version 2.0 +- Introduced for use of the CenterLine Objectcenter C development software, + i.e. some directives to suppress intended anomalies, as /*EMPTY*/ + while statements + +Revision 2.0 1992/04/22 14:17:26 Christian_Engel +I have turned to version 2 for some important changes: +- No support of K&R anymore. Everything turned to ANSI-C. If you only have a + K&R compiler transform the sources by a K&R to ANSI translator (e.g. ) + or use tr2latex V1.04. +- The Revisions of tr2latex are controlled by RCS. +Furthermore, there have been some smaller improvements: +- added support of MMS package for make under VMS. Thanks to + Richard L. Dyson. + New files: Makefile.mms, make_tr2latex.com, tr2latex.hlp, vaxcrtl.opt. +- fixed some problems compiling on a MIPS M/2000 running RISCos + Thanks to David Osborne <cczdao@mips.ccc.nottingham.ac.uk> + +Revision 1.05, December 9, 1991, Christian Engel +This version hasn't been released. It turned out to be completed and +released as Revision 2.0. +- Moved completely to ANSI, no support of K&R anymore. +- managed troffms.sty to place the output correctly on the page. +- replaced version.h by version.c to make compilation shorter. +- added automatical generation of version numbers and dates + (generation not visible to distributuion package). + +Revision 1.04, July 15, 1991, Christian Engel +- added missing IPlist environment to troffms.sty + +Revision 1.03, June 14, 1991, Christian Engel +- added M. Kaczmarczik's VMS support (thanks to Richard L. Dyson, and + Johannes Braams). This includes the introduction of the -o option. +- changed all names tr2tex.* to tr2latex.* +- added documentation for all new features to tr2latex.man + +Revision 1.02, June 11, 1991, Christian Engel +- fixed some bugs (thank you to Bill Metzenthen and Arjan de Vet) +- now running with Turbo-C (thank you to Bill Metzenthen once more) +- introduced first command line option for for debugging: watch output + immediately if compiled with -DDEBUG and command line option -do is + given. +- support of man macro .P +- now several macros for change of font (.I, .B, .R, .P) work correctly + with more than one argument + +Revision 1.01, May 3, 1991, Christian Engel +- fixed bug with get_multargs() concerning end of line +- introduced command line options -t, -<n>, -s <style> + +Revision 1.00, May 2, 1991, Christian Engel +- file version.h +- support of following man macros: + .MS + .PN + .EX + .EE + .NT +- new macros in troffman.sty: + \beginnotec + \beginnote + \endnote + \IPlist +- correction of bugs in ANSI version +- fixed a bug in getarg that lead to an infinite loop in alternate with + an argument containing '$' or '}'. + +Revision .93, March 4, 1987 +- Posted to comp.sources.unix on 2 Jul 87 by Kamal Al-Yahya diff --git a/support/tr2latex/INSTALL b/support/tr2latex/INSTALL new file mode 100644 index 0000000000..984e5c4407 --- /dev/null +++ b/support/tr2latex/INSTALL @@ -0,0 +1,8 @@ +To compile tr2latex you need a C compiler and GNU make. Edit the +Makefile to customize the installation paths. You should look at the +TEXDIR variable to set your texmf-local directory and PREFIX to choose +the base directory. +Then use "make install" to compile and install tr2latex. + +Windows users have to install a Visual Studio C++ version and build +with the Makefile.nmake or the nmake.bat file. diff --git a/support/tr2latex/Makefile b/support/tr2latex/Makefile new file mode 100644 index 0000000000..f843045aee --- /dev/null +++ b/support/tr2latex/Makefile @@ -0,0 +1,54 @@ +# GNU Makefile for tr2latex on *NIX machines + +# CC chooses your C compiler +CC = gcc + +# PREFIX sets your base directory +PREFIX = /usr/local +#PREFIX = /opt/tr2latex + +# TEXDIR gives the path where the tex library resides (fonts, macros ...) +TEXDIR = $(PREFIX)/share/texmf-local +#TEXDIR = $(PREFIX)/texlive/texmf-local + +# flags for compiling C sources +CFLAGS += -Wall -O2 + +############################################################################## +# nothing to configure beyond this point + +all: tr2latex + +tr2latex: tr2latex.o tr.o subs.o + $(CC) -o $@ $^ + +tr2latex.o: tr2latex.c setups.h protos.h +tr.o: tr.c setups.h protos.h +subs.o: subs.c protos.h setups.h simil.h greek.h macros.h maths.h flip.h forbid.h special.h + +install: tr2latex + install -m 755 -d $(PREFIX)/bin + install -m 755 -d $(PREFIX)/share/man/man1 + install -m 755 -d $(TEXDIR)/macros + install -m 0755 tr2latex $(PREFIX)/bin/tr2latex + install -m 0444 tr2latex.man $(PREFIX)/share/man/man1/tr2latex.1 + install -m 0444 troffman.sty troffms.sty $(TEXDIR)/macros + +uninstall: + rm -f $(PREFIX)/bin/tr2latex $(PREFIX)/share/man/man1/tr2latex.1 $(TEXDIR)/macros/troffman.sty $(TEXDIR)/macros/troffms.sty + +clean: + -rm -f *.o core tr2latex *~ TAGS tags testfile.tex *.pdf *.aux *.log *.toc *.zip + +test: testfile.tex testfile.pdf diffs.pdf + +testfile.tex: testfile tr2latex + ./tr2latex $< > $@ + +%.pdf: %.tex + pdflatex $< + +tr2latex.zip: clean + $(RM) ../$@ + cd .. ; zip -9 -x 'tr2latex/.svn/*' -r $@ tr2latex/ + mv -f ../$@ . diff --git a/support/tr2latex/Makefile.nmake b/support/tr2latex/Makefile.nmake new file mode 100644 index 0000000000..ff9e157019 --- /dev/null +++ b/support/tr2latex/Makefile.nmake @@ -0,0 +1,19 @@ +# a Makefile to build tr2latex with the Microsoft compiler +# use it with "nmake -f Makefile.nmake" + +EXE = tr2latex.exe +OBJ = tr2latex.obj tr.obj subs.obj getopt.obj +CFLAGS = /O1 /Og /Zi /favor:INTEL64 + +all: $(EXE) + +$(EXE): $(OBJ) + link.exe /out:$@ /debug /subsystem:console $(OBJ) setargv.obj + +tr2latex.obj: tr2latex.c setups.h protos.h getopt.h Makefile.nmake +tr.obj: tr.c setups.h protos.h Makefile.nmake +subs.obj: subs.c protos.h setups.h simil.h greek.h macros.h maths.h flip.h forbid.h special.h Makefile.nmake +getopt.obj: getopt.c getopt.h Makefile.nmake + +clean: + del $(OBJ) $(EXE) diff --git a/support/tr2latex/README b/support/tr2latex/README new file mode 100644 index 0000000000..06edbcb11c --- /dev/null +++ b/support/tr2latex/README @@ -0,0 +1,56 @@ +Please read this file before you install the program. + +tr2latex: Troff-to-TeX translator + +Copyright (C) by 1987 Kamal Al-Yahya, 1991,1992 Christian Engel. + +This directory contains a program developed at the Stanford Exploration +Project, Geophysics Department, by Kamal Al-Yahya. It was modified and +enhanced substantially by Christian Engel at the Rheinisch-Westfaelische +Technische Hochschule at Aachen, Germany, Department of Computer Science 4. +Copying the sources and the program to any other machine is permitted +without prior permission provided that copyright messages are kept, no +profit is made by copying the files, and modifications are clearly +documented. + +I would very much appreciate any comments or suggestions. My e-net +address is + kamal@hanauma.stanford.edu +If it doesn't work try + kamal%hanauma@score.stanford.edu + +----------------------------------------------------------------------------- + +It seems as if Kamal isn't to the net anymore. + +I have made several modifications on Kamal's version 0.93 from the net. +Thus I continued my revision numbering with 1.00. The actual revision is +version 2.2 1992/04/27 15:13:26. + +If you modify this source, if you found some bugs, or if you have some +suggestions for improvements then e-mail me as well: + krischan@informatik.rwth-aachen.de + + + USING THE TRANSLATOR + +You can run the program either by + tr2latex < file > file.tex +or + tr2latex file > file.tex +You are most likely to get messages on the standard error telling +you about things it encounters and cannot do. + +Now you have the translated document. Look at it and see if you +can spot a major error. Run it through latex. If it runs and produces +the dvi file, then print it. If you get latex error messages modify +the translated document accordingly and repeat the latex run, and so on. +I usually get away with one or two iterations. + +----------------------------------------------------------------------------- + +And in 2009 it seems as if Christian Engel has vanished from the +Internet as well, so I have took over this project and updated the +build process for a modern UN*X system. + +Comments and questions go to Dirk Jagdmann <doj@cubic.org> diff --git a/support/tr2latex/TODO b/support/tr2latex/TODO new file mode 100644 index 0000000000..1e7ea9b85f --- /dev/null +++ b/support/tr2latex/TODO @@ -0,0 +1,8 @@ +- handling of tables +- handling of tabs +- handling of troff commands: + .bd + .nr + .pl + .ps + .ds diff --git a/support/tr2latex/diffs.tex b/support/tr2latex/diffs.tex new file mode 100644 index 0000000000..392368567f --- /dev/null +++ b/support/tr2latex/diffs.tex @@ -0,0 +1,80 @@ +\documentstyle[11pt]{article} +\begin{document} +\def\troff{{\it troff}} +\def\Troff{{\it Troff}} +\def\ditroff{{\it ditroff}} +\def\Ditroff{{\it Ditroff}} + +\title{Differences between \TeX\ and troff typesetters} + +Outlined below are the differences between \TeX\ and \troff\/ that +I know from experience with the two languages most of which +obtained while writing {\bf tr2latex}. +Most of them are advantages \TeX\ has over \troff. + +There are actually more than one type of \TeX, the most +used ones are \LaTeX\ and plain \TeX. +\Troff\ can also be loaded with various macro packages to +produce variations to plain \troff. Also, \ditroff\ (device independent \troff) +is becoming more and more the standard of \troff. +The following comparison is made mainly between \LaTeX\ and {\bf ms} \troff. +It will be mentioned if in a particular case \ditroff\ makes a difference. + +\begin{itemize} +\item \TeX\ is not system-dependent. \Troff\ is a Unix tool. + +\item In \Troff, tables and equations are handled by preprocessors +while in \TeX\ they are simultaneously processed with text. + +\item \Troff's commands have to start at the beginning of the line +and start with a dot. Equation symbols are recognized when delimited by space. +All \TeX\ commands, in math or non-math mode, start with a backslash +and they don't have to be placed at the beginning of the line. + +\item \TeX\ and \LaTeX\ commands are more verbose than \troff's. +This can be an advantage or disadvantage depending on the user. + +\item \TeX\ processes {\it boxes} such as lines and paragraphs as one unit. +This means it can distribute {\it badness} over that box. +For example, when a spacing between two lines needs to be large, because +a line has large symbols, it will slightly stretch the +line spacing in other lines to make the large spacing not look +too bad. This also makes it avoid orphan lines. + +\item The input to \LaTeX\ is a more structured document with scopes. It makes it +easier to proofread. \Troff's input is less structured. + +\item Some \TeX\ drivers make it very easy to include prepared +graphs with the text. Including graphs with \troff's text is more difficult. + +\item Many fonts can be loaded in a \TeX\ document (up to 32); in \troff, +the limit is 4 (\ditroff\ does not have this restriction). + +\item Non-math macros are defined just like math macros in \TeX. +In \troff, {\bf define} is used for math definitions and {\bf .de} is +used for non-math macros. +\Troff's macros can be made up from anything while +\TeX\ macros cannot have non-letters which is a nuisance sometimes. + +\item There is no limit on the page size in \TeX. The size is limited only by +the output device. \Troff's paper size is limited. + +\item \TeX\ is interactive, while \troff\ is not. However, not many people can +benefit from this feature since they have to be skillful in answering +its questions. + +\item \TeX\ and \LaTeX\ give a {\bf l\,o\,n\,g} ambiguous log file that does not +exactly tell what the error is. \Troff\ does not give error messages. + +\item \LaTeX\ automatically numbers equations and figures, etc. A powerful +cross-referencing technique relieves the user from worrying about having +the right sequence of equations' and figures' numbers. This feature +is not available in \troff. + +\item The documentation in the \LaTeX\ manual is excellent. +\Troff's documentation is scattered over many references. +The documentation in the \TeX Book is very technical and the average reader +may find it unreadable. + +\end{itemize} +\end{document} diff --git a/support/tr2latex/flip.h b/support/tr2latex/flip.h new file mode 100644 index 0000000000..207f97fe8f --- /dev/null +++ b/support/tr2latex/flip.h @@ -0,0 +1,19 @@ +#ifndef FLIP__H +#define FLIP__H + +/* +** tr2latex - troff to LaTeX converter +** COPYRIGHT (C) 1987 Kamal Al-Yahya, 1991,1992 Christian Engel +** +** Module: flip.h +** +** This file contains the words that are placed the opposite way +** in troff and TeX. Is there any more? +*/ + +const char *flip_list[] = +{ +"bar", "dot", "dotdot", "hat", "tilde", "under", "vec" +}; + +#endif diff --git a/support/tr2latex/forbid.h b/support/tr2latex/forbid.h new file mode 100644 index 0000000000..c213d98f6d --- /dev/null +++ b/support/tr2latex/forbid.h @@ -0,0 +1,41 @@ +#ifndef FORBID__H +#define FORBID__H + +/* +** tr2latex - troff to LaTeX converter +** COPYRIGHT (C) 1987 Kamal Al-Yahya, 1991,1992 Christian Engel +** +** Module: forbid.h +** +** This file contains TeX commands that cannot be re-defined. +** Re-defining them is not permitted by TeX (or they may produce +** unpredictable consequences). +** If the troff user happens to re-define one of these, it will be replaced. +** This list is extracted from the starred entries in the index of the TeXBook. +** They are entered here in alphabetical order. +** If the macro has non-alphabetical characters, it will be trapped +** somewhere else; it needn't be put here. +** This list is added to make the program more robust. +** Note that the backslash is omitted. +*/ + +const char *forbid[] = +{ +"atop", "char", "copy", "count", "cr", "crcr", +"day", "def", "divide", "dp", "dump", "edef", +"else", "end", "eqno", "fam", "fi", "font", +"gdef", "global", "halign", "hbox", "hfil", "hfill", +"hfuzz", "hoffset", "hrule", "hsize", "hskip", "hss", +"ht", "if", "ifcase", "ifcat", "ifnum", "ifodd", +"iftrue", "ifx", "indent", "input", "insert", "kern", +"left", "leqno", "let", "limits", "long", "lower", +"mag", "mark", "mkern", "month", "mskip", "multiply", +"muskip", "omit", "or", "outer", "output", "over", +"overline", "par", "raise", "read", "right", "show", +"span", "special", "string", "the", "time", "toks", +"topmark", "topskip", "unkern", "unskip", "vbox", "vfil", +"vfill", "vfuzz", "voffset", "vrule", "vsize", "vskip", +"vsplit", "vss", "vtop", "wd", "write", "xdef" +}; + +#endif diff --git a/support/tr2latex/getopt.c b/support/tr2latex/getopt.c new file mode 100644 index 0000000000..8900065153 --- /dev/null +++ b/support/tr2latex/getopt.c @@ -0,0 +1,242 @@ +/***************************************************************************** +* getopt.c - competent and free getopt library. +* $Header: /home/doj/code/tr2latex/getopt.c,v 1.1 2012-09-02 04:52:22 doj Exp $ +* +* Copyright (c)2002-2003 Mark K. Kim +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* +* * Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* +* * Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in +* the documentation and/or other materials provided with the +* distribution. +* +* * Neither the original author of this software nor the names of its +* contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF +* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH +* DAMAGE. +*/ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include "getopt.h" + +char* optarg = NULL; +int optind = 0; +int opterr = 1; +int optopt = '?'; + +static char** prev_argv = NULL; /* Keep a copy of argv and argc to */ +static int prev_argc = 0; /* tell if getopt params change */ +static int argv_index = 0; /* Option we're checking */ +static int argv_index2 = 0; /* Option argument we're checking */ +static int opt_offset = 0; /* Index into compounded "-option" */ +static int dashdash = 0; /* True if "--" option reached */ +static int nonopt = 0; /* How many nonopts we've found */ + +static void increment_index() +{ + /* Move onto the next option */ + if(argv_index < argv_index2) + { + while(prev_argv[++argv_index] && prev_argv[argv_index][0] != '-' + && argv_index < argv_index2+1); + } + else argv_index++; + opt_offset = 1; +} + +/* +* Permutes argv[] so that the argument currently being processed is moved +* to the end. +*/ +static int permute_argv_once() +{ + /* Movability check */ + if(argv_index + nonopt >= prev_argc) return 1; + /* Move the current option to the end, bring the others to front */ + else + { + char* tmp = prev_argv[argv_index]; + + /* Move the data */ + memmove(&prev_argv[argv_index], &prev_argv[argv_index+1], + sizeof(char**) * (prev_argc - argv_index - 1)); + prev_argv[prev_argc - 1] = tmp; + + nonopt++; + return 0; + } +} + +int getopt(int argc, char** argv, char* optstr) +{ + int c = 0; + + /* If we have new argv, reinitialize */ + if(prev_argv != argv || prev_argc != argc) + { + /* Initialize variables */ + prev_argv = argv; + prev_argc = argc; + argv_index = 1; + argv_index2 = 1; + opt_offset = 1; + dashdash = 0; + nonopt = 0; + } + + /* Jump point in case we want to ignore the current argv_index */ + getopt_top: + + /* Misc. initializations */ + optarg = NULL; + + /* Dash-dash check */ + if(argv[argv_index] && !strcmp(argv[argv_index], "--")) + { + dashdash = 1; + increment_index(); + } + + /* If we're at the end of argv, that's it. */ + if(argv[argv_index] == NULL) + { + c = -1; + } + /* Are we looking at a string? Single dash is also a string */ + else if(dashdash || argv[argv_index][0] != '-' || !strcmp(argv[argv_index], "-")) + { + /* If we want a string... */ + if(optstr[0] == '-') + { + c = 1; + optarg = argv[argv_index]; + increment_index(); + } + /* If we really don't want it (we're in POSIX mode), we're done */ + else if(optstr[0] == '+' || getenv("POSIXLY_CORRECT")) + { + c = -1; + + /* Everything else is a non-opt argument */ + nonopt = argc - argv_index; + } + /* If we mildly don't want it, then move it back */ + else + { + if(!permute_argv_once()) goto getopt_top; + else c = -1; + } + } + /* Otherwise we're looking at an option */ + else + { + char* opt_ptr = NULL; + + /* Grab the option */ + c = argv[argv_index][opt_offset++]; + + /* Is the option in the optstr? */ + if(optstr[0] == '-') opt_ptr = strchr(optstr+1, c); + else opt_ptr = strchr(optstr, c); + /* Invalid argument */ + if(!opt_ptr) + { + if(opterr) + { + fprintf(stderr, "%s: invalid option -- %c\n", argv[0], c); + } + + optopt = c; + c = '?'; + + /* Move onto the next option */ + increment_index(); + } + /* Option takes argument */ + else if(opt_ptr[1] == ':') + { + /* ie, -oARGUMENT, -xxxoARGUMENT, etc. */ + if(argv[argv_index][opt_offset] != '\0') + { + optarg = &argv[argv_index][opt_offset]; + increment_index(); + } + /* ie, -o ARGUMENT (only if it's a required argument) */ + else if(opt_ptr[2] != ':') + { + /* One of those "you're not expected to understand this" moment */ + if(argv_index2 < argv_index) argv_index2 = argv_index; + while(argv[++argv_index2] && argv[argv_index2][0] == '-'); + optarg = argv[argv_index2]; + + /* Don't cross into the non-option argument list */ + if(argv_index2 + nonopt >= prev_argc) optarg = NULL; + + /* Move onto the next option */ + increment_index(); + } + else + { + /* Move onto the next option */ + increment_index(); + } + + /* In case we got no argument for an option with required argument */ + if(optarg == NULL && opt_ptr[2] != ':') + { + optopt = c; + c = '?'; + + if(opterr) + { + fprintf(stderr,"%s: option requires an argument -- %c\n", + argv[0], optopt); + } + } + } + /* Option does not take argument */ + else + { + /* Next argv_index */ + if(argv[argv_index][opt_offset] == '\0') + { + increment_index(); + } + } + } + + /* Calculate optind */ + if(c == -1) + { + optind = argc - nonopt; + } + else + { + optind = argv_index; + } + + return c; +} + +/* vim:ts=3 +*/ diff --git a/support/tr2latex/getopt.h b/support/tr2latex/getopt.h new file mode 100644 index 0000000000..0a85dee199 --- /dev/null +++ b/support/tr2latex/getopt.h @@ -0,0 +1,63 @@ +#ifdef __GNUC__ +#include <getopt.h> +#endif +#ifndef __GNUC__ +/***************************************************************************** +* getopt.h - competent and free getopt library. +* $Header: /home/doj/code/tr2latex/getopt.h,v 1.1 2012-09-02 04:52:22 doj Exp $ +* +* Copyright (c)2002-2003 Mark K. Kim +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* +* * Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* +* * Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in +* the documentation and/or other materials provided with the +* distribution. +* +* * Neither the original author of this software nor the names of its +* contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF +* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH +* DAMAGE. +*/ +#ifndef GETOPT_H_ +#define GETOPT_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +extern char* optarg; +extern int optind; +extern int opterr; +extern int optopt; + +int getopt(int argc, char** argv, char* optstr); + +#ifdef __cplusplus +} +#endif + +#endif /* GETOPT_H_ */ + +#endif +/* vim:ts=3 +*/ diff --git a/support/tr2latex/greek.h b/support/tr2latex/greek.h new file mode 100644 index 0000000000..20e756a749 --- /dev/null +++ b/support/tr2latex/greek.h @@ -0,0 +1,23 @@ +#ifndef GREEK__H +#define GREEK__H + +/* +** tr2latex - troff to LaTeX converter +** COPYRIGHT (C) 1987 Kamal Al-Yahya, 1991,1992 Christian Engel +** +** Module: greek.h +** +** This file contains the list of the upper-case Greek letters. +** In case I overlooked any, it can be added here. +*/ + +const char *GRK_list[] = +{ +"ALPHA", "BETA", "CHI", "DELTA", "EPSILON", +"ETA", "GAMMA", "KAPPA", "LAMDA", "MU", +"NU", "OMEGA", "PHI", "PI", "PSI", +"RHO", "SIGMA", "TAU", "THETA", "UPSILON", +"XI", "ZETA" +}; + +#endif diff --git a/support/tr2latex/macros.h b/support/tr2latex/macros.h new file mode 100644 index 0000000000..b0e4cf47ae --- /dev/null +++ b/support/tr2latex/macros.h @@ -0,0 +1,100 @@ +#ifndef MACROS__H +#define MACROS__H + +/* +** tr2latex - troff to LaTeX converter +** COPYRIGHT (C) 1987 Kamal Al-Yahya, 1991,1992 Christian Engel +** +** Module: macros.h +** +** This file contains the list of non-math macros and plain troff macros. +** Do NOT forget to put the dot for the troff macros, and the backslash +** for TeX macros (two backslashes, one for escape). +** The third column in the list is 0 for macros that have no arguments +** and either 1 or 2 for those that do. If it is 1, then only one line +** will be read as an argument. If it is 2, then lines will be read until +** properly terminated. Arguments for ms macros are terminated by an ms macro +** (e.g. .PP). Plain troff macros are terminated after reading the desired +** number of lines specified by the macro (e.g. .ce 5 will centerline 5 +** lines). The fourth column specifies whether the macro implies a paragraph +** break (par > 1) or not (par = 0). This is needed to terminate some +** environments. If .LP, or .PP, par=1; if .IP, par=2; if .TP, par=3; +** if .QP, par=4. +*/ + +struct macro_table { + const char *troff_mac, *tex_mac; + int arg, macpar; +} macro[] = { +/* troff macro TeX macro argument par */ + { ".1C", "\\onecolumn", 0, 1 }, + { ".2C", "\\twocolumn", 0, 1 }, +/* ".AB", "defined in program" */ + { ".AE", "\\end{abstract}", 0, 1 }, + { ".AI", "\\authoraff", 2, 1 }, + { ".AU", "\\author", 2, 1 }, + { ".Ac", "\\ACK", 0, 1 }, +/* ".B", "defined in program" */ + { ".B1", "\\boxit{", 0, 0 }, + { ".B2", "}", 0, 0 }, +/* ".BX", "defined in program" */ + { ".DE", "\\end{display}", 0, 0 }, +/* { ".DS", "\\displaybegin", 0, 1 },*/ +/* ".ID", "defined in program" */ + { ".LD", "\\begin{display}[L]", 0, 1 }, + { ".CD", "\\begin{display}[C]", 0, 1 }, + { ".BD", "\\begin{display}[B]", 0, 1 }, +/* ".EF", "defined in program" */ +/* ".EH", "defined in program" */ +/* ".EN", "defined in program" */ +/* ".EW", "defined in program" */ + { ".FE", "}", 0, 0 }, + { ".FS", "\\footnote{", 0, 0 }, +/* ".I", "defined in program" */ + { ".Ic", "\\caption{", 0, 1 }, + { ".Ie", "}\\end{figure}", 0, 1 }, + { ".Is", "\\begin{figure}", 0, 1 }, +/* { ".KE", "defined in program" */ +/* { ".KF", "defined in program" */ +/* { ".KS", "defined in program" */ + { ".LG", "\\LarGer", 0, 0 }, + { ".LP", "\\par\\noindent", 0, 1 }, + { ".MH", "\\mhead", 2, 1 }, + { ".ND", "\\centerfoot", 1, 0 }, +/* { ".NH", "defined in program", 1, 1 },*/ + { ".NL", "\\NormaLfont", 0, 0 }, +/* { ".OH", "defined in program" */ +/* { ".OF", "defined in program" */ + { ".P1", "\\thispagestyle{sep}", 0, 1 }, + { ".PP", "\\par", 0, 1 }, + { ".PX", "\\tableofcontents", 0, 1 }, + { ".QE", "\\end{quotation}", 0, 1 }, +/* { ".QP", "defined in program" */ + { ".QS", "\\begin{quotation}", 0, 1 }, +/* { ".R", "defined in program" */ +/* { ".RE", "defined in program" */ +/* { ".RS", "defined in program" */ + { ".SH", "\\shead", 1, 1 }, + { ".SM", "\\SMaller", 0, 0 }, + { ".TH", "\\phead", 1, 0 }, + { ".TC", "\\tableofcontents", 0, 1 }, + { ".TL", "\\title", 2, 1 }, + { ".UC", "", 0, 0 }, + { ".UL", "\\undertext", 1, 0 }, + { ".XP", "\\XParagraph", 0, 1 }, + { ".XS", "\\addcontensline{toc}{section}{", 0, 0 }, + { ".XA", "}\n\\addcontensline{toc}{section}{", 0, 0 }, + { ".XE", "{", 0, 0 }, + { ".ad", "\\adjust", 1, 1 }, + { ".bp", "\\newpage", 0, 1 }, + { ".br", "\\nwl", 0, 0 }, + { ".ce", "\\cntr", 2, 0 }, + { ".cu", "\\undertext", 2, 0 }, + { ".fi", "\\fill", 0, 0 }, + { ".na", "\\raggedright", 0, 0 }, + { ".nf", "\\nofill", 0, 0 }, + { ".ns", "", 0, 0 }, + { ".ul", "\\undertext", 2, 0 } +}; + +#endif diff --git a/support/tr2latex/maths.h b/support/tr2latex/maths.h new file mode 100644 index 0000000000..5f59797c52 --- /dev/null +++ b/support/tr2latex/maths.h @@ -0,0 +1,56 @@ +#ifndef MATHS__H +#define MATHS__H + +/* +** tr2latex - troff to LaTeX converter +** COPYRIGHT (C) 1987 Kamal Al-Yahya, 1991,1992 Christian Engel +** +** Module: maths.h +** +** This file contains a list of the words that have simple +** correspondence in the two languages. +** Do not put here words that require action (like sub). +** If the word is identical in the two languages (except for TeX's backslash), +** put it in simil.h +*/ + +struct math_equiv { + const char *troff_symb, *tex_symb; +} math[] = { +/* troff name TeX name */ + { "!=", "\\neq" }, + { "+-", "\\pm" }, + { ",...,", ",\\ldots," }, + { "-+", "\\mp" }, + { "->", "\\to" }, + { "...", "\\cdots" }, + { "<-", "\\gets" }, + { "<<", "\\gg" }, + { "<=", "\\le" }, + { "==", "\\equiv" }, + { ">=", "\\ge" }, + { ">>", "\\ll" }, + { "^", "\\," }, + { "above", "\\cr" }, + { "ccol", "\\matrix" }, + { "col", "\\matrix" }, + { "cpile", "\\matrix" }, + { "del", "\\nabla" }, + { "fat", "\\boldmath" }, + { "grad", "\\nabla" }, + { "half", "{1\\over 2}" }, + { "inf", "\\infty" }, + { "inter", "\\cap" }, + { "lcol", "\\matrix" }, + { "lineup", "" }, + { "lpile", "\\matrix" }, + { "mark", "" }, + { "nothing", "{}" }, + { "pile", "\\matrix" }, + { "rcol", "\\matrix" }, + { "rpile", "\\matrix" }, + { "union", "\\cup" }, + { "~", "\\ " }, +}; + +#endif diff --git a/support/tr2latex/nmake.bat b/support/tr2latex/nmake.bat new file mode 100644 index 0000000000..bf7c84b0c9 --- /dev/null +++ b/support/tr2latex/nmake.bat @@ -0,0 +1 @@ +nmake.exe -f Makefile.nmake %1 %2 %3 %4 %5 %6 %7 %8 %9
diff --git a/support/tr2latex/protos.h b/support/tr2latex/protos.h new file mode 100644 index 0000000000..6596dcfacd --- /dev/null +++ b/support/tr2latex/protos.h @@ -0,0 +1,56 @@ +#ifndef PROTOS__H +#define PROTOS__H + +/* +** tr2latex - troff to LaTeX converter +** COPYRIGHT (C) 1987 Kamal Al-Yahya, 1991,1992 Christian Engel +** +** This module contains the function prototypes. +*/ + +int CAP_GREEK (char *w); +void GR_to_Greek (char *w, char *ww); +char * alternate (char *pin, char *pout, char *w); +char * do_table (char *pin, char *pout, int *offset); +char * end_env (char *pout); +void envoke_stat (int par); +void errexit (int exitcode); +char * flip (char *pout, char *w); +char * flip_twice (char *pout, char *w, char *ww); +int get_N_lines (char *pin, char *w, int N); +int get_allargs (char *pin, char ***ppw, int rec); +int get_arg (char *pin, char *w, int rec); +void get_brace_arg (char *buf, char *w); +int get_defword (char *pin, char *w, int *illegal); +int get_line (char *pin, char *w, int rec); +int get_multi_line (char *pin, char *w); +int get_mydef (char *pin, char *w); +int get_no_math (char *pin, char *w); +char * get_over_arg (char *pin, char *ww); +int get_ref (char *pin, char *w); +void get_size (char *ww, struct measure *PARAMETER); +int get_string (char *pin, char *w, int rec); +int get_sub_arg (char *pin, char *w); +int get_table_entry (char *pin, char *w, int tab); +int get_till_space (char *pin, char *w); +int getdef (char *pin, char *ww); +int getword (char *pin, char *w); +int is_def (char *w); +int is_flip (char *w); +int is_forbid (char *w); +int is_mathcom (char *w, char *ww); +int is_special (char *w, char *ww); +int is_mydef (char *w); +int is_troff_mac (char *w, char *ww, int *arg, int *par); +void parse_units (char *ww, int *sign, int *units, float *value); +int similar (char *w); +char * skip_line (char *pin); +int skip_white (char *pin); +char * strapp (char *s, char *tail); +void troff_tex (char *pin, char *pout, int mid, int rec); + +#ifdef _MSC_VER +#define snprintf _snprintf +#endif + +#endif diff --git a/support/tr2latex/setups.h b/support/tr2latex/setups.h new file mode 100644 index 0000000000..8232e89355 --- /dev/null +++ b/support/tr2latex/setups.h @@ -0,0 +1,64 @@ +#ifndef SETUPS__H +#define SETUPS__H + +/* +** tr2latex - troff to LaTeX converter +** COPYRIGHT (C) 1987 Kamal Al-Yahya, 1991,1992 Christian Engel +** +** Module: setups.h +** +** setup file +*/ + +#include <ctype.h> +#include <errno.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <time.h> + +#define MAXLEN (1024*1024) /* maximum length of document */ +#define MAXWORD 250 /* maximum word length */ +#define MAXLINE 500 /* maximum line length */ +#define MAXDEF 200 /* maximum number of defines */ +#define MAXARGS 128 /* maximal number of arguments */ + +#define EOS '\0' /* end of string */ + +#ifdef MAIN /* can only declare globals once */ +# define GLOBAL +#else +# define GLOBAL extern +#endif + +GLOBAL int math_mode, /* math mode status */ + de_arg, /* .de argument */ + IP_stat[20], /* IP status */ + QP_stat, /* QP status */ + TP_stat, /* TP status */ + RSRE; /* block indentation level */ + +GLOBAL int debug_o; + +GLOBAL struct defs { + char *def_macro; + char *replace; + int illegal; +} def[MAXDEF]; + +GLOBAL struct mydefs { + char *def_macro; + char *replace; + int illegal; + int arg_no; + int par; /* if it impiles (or contains) a par break */ +} mydef[MAXDEF]; + +GLOBAL struct measure { + char old_units[MAXWORD]; float old_value; + char units[MAXWORD]; float value; + char def_units[MAXWORD]; /* default units */ + int def_value; /* default value: 0 means take last one */ +} linespacing, indent, tmpind, space, vspace; + +#endif diff --git a/support/tr2latex/simil.h b/support/tr2latex/simil.h new file mode 100644 index 0000000000..5bb5363525 --- /dev/null +++ b/support/tr2latex/simil.h @@ -0,0 +1,28 @@ +#ifndef SIMIL__H +#define SIMIL__H + +/* +** tr2latex - troff to LaTeX converter +** COPYRIGHT (C) 1987 Kamal Al-Yahya, 1991,1992 Christian Engel +** +** Module: simil.h +** +** This file contains a list of math words that are similar in the +** two languages (in fact identical except for TeX's backslah). +** If I overlooked anything out, it can be put here +** Do NOT put here words that are similar but require some action (like over) +*/ + +const char *sim_list[] = +{ +"alpha", "approx", "beta", "cdot", "chi", "cos", +"cosh", "cot", "coth", "delta", "det", "epsilon", +"eta", "exp", "gamma", "int", "iota", "kappa", +"lambda", "lim", "ln", "log", "matrix", "max", +"min", "mu", "nu", "omega", "partial", "phi", +"pi", "prime", "prod", "psi", "rho", "sigma", +"sin", "sinh", "sqrt", "sum", "tan", "tanh", +"tau", "theta", "times", "upsilon", "xi", "zeta" +}; + +#endif diff --git a/support/tr2latex/special.h b/support/tr2latex/special.h new file mode 100644 index 0000000000..aa4f24b8bc --- /dev/null +++ b/support/tr2latex/special.h @@ -0,0 +1,124 @@ +/* +** tr2latex - troff to LaTeX converter +** +** Module: special.h +** +*/ +struct special_table { + const char *troff_char, *tex_char; +} special [] = { +/* troff name TeX name */ + {"em", "---"}, + {"hy", "-"}, + {"bu", "$\\bullet$"}, + {"sq", "$\\Box$"}, /* needs package latexsym */ + {"ru", "$\\_$"}, + {"14", "$\\fraction 1/4$"}, + {"12", "$\\fraction 1/2$"}, + {"34", "$\\fraction 3/4$"}, + {"fi", "fi"}, + {"fl", "fl"}, + {"ff", "ff"}, + {"Fi", "ffi"}, + {"Fl", "ffl"}, + {"de", "$^\\circ$"}, + {"dg", "$\\dagger$"}, + {"fm", "$\\prime$"}, + {"ct", "\\textcent"}, + {"rg", "\\textregistered"}, + {"co", "\\textcopyright"}, + {"pl", "$+$"}, + {"mi", "$-$"}, + {"eq", "$=$"}, + {"**", "$\\ast$"}, + {"sc", "\\textsection"}, + {"aa", "\\textasciiacute"}, /* needs package textcomp */ + {"ga", "\\textasciigrave"}, /* needs package textcomp */ + {"ul", "$\\_$"}, + {"sl", "$\\/$"}, + {"*a", "$\\alpha$"}, + {"*b", "$\\beta$"}, + {"*g", "$\\gamma$"}, + {"*d", "$\\delta$"}, + {"*e", "$\\epsilon$"}, + {"*z", "$\\zeta$"}, + {"*y", "$\\eta$"}, + {"*h", "$\\theta$"}, + {"*i", "$\\iota$"}, + {"*k", "$\\kappa$"}, + {"*l", "$\\lambda$"}, + {"*m", "$\\mu$"}, + {"*n", "$\\nu$"}, + {"*c", "$\\xi$"}, + {"*o", "o"}, + {"*p", "$\\pi$"}, + {"*r", "$\\rho$"}, + {"*s", "$\\sigma$"}, + {"ts", "$\\varsigma$"}, + {"*t", "$\\tau$"}, + {"*u", "$\\upsilon$"}, + {"*f", "$\\phi$"}, + {"*x", "$\\chi$"}, + {"*q", "$\\psi$"}, + {"*w", "$\\omega$"}, + {"*G", "$\\Gamma$"}, + {"*D", "$\\Delta$"}, + {"*Y", "$H$"}, + {"*H", "$\\Theta$"}, + {"*L", "$\\Lambda$"}, + {"*C", "$\\Xi$"}, + {"*P", "$\\Pi$"}, + {"*R", "$P$"}, + {"*S", "$\\Sigma$"}, + {"*U", "$\\Upsilon$"}, + {"*F", "$\\Phi$"}, + {"*Q", "$\\Psi$"}, + {"*W", "$\\Omega$"}, + {"sr", "$\\surd$"}, + /*"rn", "$\\`$",*/ + {">=", "$\\geq$"}, + {"<=", "$\\leq$"}, + {"==", "$\\equiv$"}, + {"|=", "$\\simeq$"}, + {"ap", "$\\sim$"}, + {"!=", "$\\neq$"}, + {"->", "$\\to$"}, + {"<-", "$\\gets$"}, + {"ua", "$\\uparrow$"}, + {"da", "$\\downarrow$"}, + {"mu", "$\\times$"}, + {"di", "$\\div$"}, + {"+-", "$\\pm$"}, + {"cu", "$\\cup$"}, + {"ca", "$\\cap$"}, + {"sb", "$\\subset$"}, + {"sp", "$\\supset$"}, + {"ib", "$\\subseteq$"}, + {"ip", "$\\supseteq$"}, + {"if", "$\\infty$"}, + {"pd", "$\\partial$"}, + {"gr", "$\\nabla$"}, + {"no", "$\\neg$"}, + {"is", "$\\int$"}, + {"pt", "$\\propto$"}, + {"es", "$\\emptyset$"}, + {"mo", "$\\in$"}, + {"br", "$\\vert$"}, + {"dd", "$\\ddagger$"}, + {"rh", "$\\Rightarrow$"}, + {"lh", "$\\Leftarrow$"}, + /*{"bs", ""},*/ + {"or", "$\\vert$"}, + {"ci", "$\\bigcirc$"}, + /*{"lt", "$\\$"}, + {"lb", "$\\$"}, + {"rt", "$\\$"}, + {"rb", "$\\$"}, + {"lk", "$\\$"}, + {"rk", "$\\$"},*/ + {"bv", "$\\bracevert$"}, + {"lf", "$\\lfloor$"}, + {"rf", "$\\rfloor$"}, + {"lc", "$\\lceil$"}, + {"rc", "$\\rceil$"} +};
\ No newline at end of file diff --git a/support/tr2latex/subs.c b/support/tr2latex/subs.c new file mode 100644 index 0000000000..c6a2db3b6e --- /dev/null +++ b/support/tr2latex/subs.c @@ -0,0 +1,1375 @@ +/* +** tr2latex - troff to LaTeX converter +** COPYRIGHT (C) 1987 Kamal Al-Yahya, 1991,1992 Christian Engel +** +** Module: subs.c +** +** These subroutines do (in general) small things for the translator. +** They appear in alphabetical order and their names are unique in the +** first six characters. +*/ + +#include "setups.h" +#include "protos.h" +#include "simil.h" +#include "greek.h" +#include "flip.h" +#include "forbid.h" +#include "maths.h" +#include "macros.h" +#include "special.h" + +int get_tbl_txt_entry(char *pin, char *w); + +extern int def_count; +extern int mydef_count; + +/* compile-time counting of elements */ +const int GRK_count = (sizeof(GRK_list) / sizeof(GRK_list[0])); +const int sim_count = (sizeof(sim_list) / sizeof(sim_list[0])); +const int flip_count = (sizeof(flip_list) / sizeof(flip_list[0])); +const int forbd_count = (sizeof(forbid) / sizeof(forbid[0])); +const int mathcom_count = (sizeof(math) / sizeof(struct math_equiv)); +const int macro_count = (sizeof(macro) / sizeof(struct macro_table)); +const int special_count = (sizeof(special) / sizeof(struct special_table)); + +/* +** alternate fonts (manual macro) +*/ +char *alternate(char *pin, char *pout, char *w) +{ + int which = 1; + char font[MAXWORD + 1], font1[MAXWORD + 1], font2[MAXWORD + 1], ww[MAXWORD + 1], tmp[MAXWORD + 1]; + + tmp[0] = EOS; + switch (w[1]) { + case 'R': strcpy(font1, "\\rm"); break; + case 'I': strcpy(font1, "\\it"); break; + case 'B': strcpy(font1, "\\bf"); break; + } + switch (w[2]) { + case 'R': strcpy(font2, "\\rm"); break; + case 'I': strcpy(font2, "\\it"); break; + case 'B': strcpy(font2, "\\bf"); break; + } + + strcpy(font, font1); + while (*pin != '\n' && *pin != EOS) { + pin += get_arg(pin, ww, 1); + if (which == 1) { + snprintf(tmp,sizeof(tmp),"{%s %s}", font1, ww); + which = 2; + } + else { + snprintf(tmp,sizeof(tmp),"{%s %s}", font2, ww); + which = 1; + } + pout = strapp(pout, tmp); + while (*pin == ' ' || *pin == '\t') + pin++; + } + return (pout); +} + + + +/* +** check if w is in the GREEK list +*/ +int CAP_GREEK(char *w) +{ + int i; + + for (i = 0; i < GRK_count; i++) { + if (strcmp(GRK_list[i], w) == 0) + return (1); + } + return (-1); +} + +int prefix(char *small, char *big) +{ + char c; + while ((c = *small++) == *big++) + if (c == EOS) + return (1); + return (c == EOS); +} + +int expflag, ctrflag, boxflag, dboxflag, tab, linsize, allflag, DELIM1, DELIM2; + +struct optstr { + char *optnam; + int *optadd; +}; +struct optstr options[] = { + { "tab", &tab }, + { "TAB", &tab }, + { "allbox", &allflag }, + { "ALLBOX", &allflag }, + { "box", &boxflag }, + { "BOX", &boxflag }, + { "center", &ctrflag }, + { "CENTER", &ctrflag }, + { "delim", &DELIM1 }, + { "DELIM", &DELIM1 }, + { "doublebox", &dboxflag }, + { "DOUBLEBOX", &dboxflag }, + { "expand", &expflag }, + { "EXPAND", &expflag }, + { "linesize", &linsize }, + { "LINESIZE", &linsize }, + { EOS, 0 } +}; + +/* +** get single option +*/ +int get_option(char *pin, char *w) { + char c; + int i, j; + for (j=0; *pin == ',' || *pin == ' ' || *pin == '\t'; j++, pin++); + for (i = 0; (c = *pin++) != EOS && + (c != ' ' && c != '\t' && c != ',' && c != ';' && c != '(') && i < MAXWORD; i++) { + w[i] = c; + } + w[i] = EOS; + return (j+i); +} + +/* +** get table options until ';' +*/ +int get_tbl_options(char *pin, struct optstr *options) +{ + char line[MAXLINE], *cp, nb[25], *t; + struct optstr *lp; + int c, ci, len = 0, found; + char opt[MAXWORD]; + + //tmp[0] = EOS; + for (lp = options; lp->optnam; lp++) + *(lp->optadd) = 0; + tab = '\t'; /* default is tab char */ + len = get_line(pin, line, 0); + if (strchr(line, ';') == 0) + return(0); + cp = line; + while ((c = *cp) != ';') { + cp += get_option(cp, opt); + found = 0; + for (lp = options; lp->optadd; lp++) { + if (strcmp(lp->optnam, opt) == 0) { + *(lp->optadd) = 1; + while (*cp == ' ') cp++; + t = nb; + if (*cp == '(') { + while ((ci = *++cp) != ')') + *t++ = ci; + cp++; + } + *t++ = 0; *t = 0; + if (lp->optadd == &tab) { + if (nb[0]) + *(lp->optadd) = nb[0]; + } else + if (lp->optadd == &linsize) { + *(lp->optadd) = atoi(nb); + } else + if (lp->optadd == &DELIM1) { + DELIM1 = nb[0]; + DELIM2 = nb[1]; + } + found = 1; + break; + } + } + if (!found) + fprintf(stderr, "Illigel option in table definition: %s\n", opt); + } + return(len); +} + + +/* +** translate table +** arguments: +** pin +** pout +** offset amount to offset pin +*/ +char *do_table (char *pin, char *pout, int *offset) +{ + char w[MAXLINE+1], ww[MAXLINE+1], format[MAXWORD+1], tmp[MAXLINE+1]; + char *ptr; + int i, fc = 0, columns = 0; + + tmp[0] = EOS; + ptr = pin; /* remember where we started */ + + pin += get_tbl_options(pin, options); + if (boxflag || dboxflag || allflag) + format[fc++] = '|'; + if (dboxflag) + format[fc++] = '|'; + pin = skip_line(pin); + while (*pin != EOS) { /* get the LAST format line */ + pin += get_line(pin, w, 0); + if (w[strlen(w) - 1] == '.') + break; + else /* not a format line */ + pin = skip_line(pin); + } + for (i = 0; w[i] != '.'; i++) { + switch (w[i]) { + case ' ': + case '\t': + continue; + case 'l': + case 'L': + case 'n': + case 'N': + case 'a': + case 'A': + format[fc++] = 'l'; + break; + case 'r': + case 'R': + format[fc++] = 'r'; + break; + case 'c': + case 'C': + case 's': + case 'S': + format[fc++] = 'c'; + break; + case '|': + format[fc++] = '|'; + break; + case ',': + fc = 0; /* use only last format */ + columns = 0; + continue; + default: + continue; + } + if (allflag) + format[fc++] = '|'; + columns++; + } + if ((boxflag || dboxflag) && !allflag) + format[fc++] = '|'; + if (dboxflag) + format[fc++] = '|'; + if (columns == 0) { + fprintf (stderr, "Sorry, I cannot do tables without a format line\n" + "Doing plain translation of table, lines will be commented\n" + "You need to fix it yourself\n"); + while (*pin != EOS) { + (void) getword (pin, w); + if (strcmp (w,".TE") == 0) { + pin += 4; + break; + } + pin += get_line (pin, w, 1); + *pout++ = '%'; + pout = strapp (pout, w); + pout = strapp (pout, "\n"); + pin++; /* skip the \n */ + } + *offset = pin - ptr; + return (pout); + } + format[fc] = EOS; + pin = skip_line(pin); + pout = strapp(pout, "\\par\\noindent\n"); + if (linsize > 0) { + snprintf(tmp, sizeof(tmp), "{\\arrayrulewidth=%dpt\n", linsize); + pout = strapp(pout, tmp); + } + if (ctrflag) + pout = strapp(pout, "\\begin{center}\n"); + snprintf(tmp, sizeof(tmp), "\\begin{tabular}{%s}\n", format); + pout = strapp (pout, tmp); + if (boxflag || dboxflag || allflag) + pout = strapp(pout, "\\hline\n"); + if (dboxflag) + pout = strapp(pout, "\\hline\n"); + while (*pin != EOS) { + (void)getword(pin, w); + if (strcmp(w, ".sp") == 0) { + pin += get_line(pin, ww, 1); + snprintf(tmp, sizeof(tmp), "%s\n\\\\ ", ww); + pout = strapp(pout, tmp); + continue; + } else if (strcmp(w, "_") == 0) { + pout = strapp(pout, "\\hline\n"); + pin = skip_line(pin); + continue; + } else if (strcmp(w, "=") == 0) { + pout = strapp(pout, "\\hline\n\\hline\n"); + pin = skip_line(pin); + continue; + } else if (strcmp(w, "\n") == 0) { + pin++; + continue; + } + for (i = 0; i < columns - 1; i++) { + (void) getword (pin, w); + if (strcmp (w, ".TE") == 0) { + pin += 4; + if (i == 0 && !boxflag && !dboxflag && !allflag) { + pout -= 3; /* take back the \\ and the \n */ + pout = strapp(pout, "\n"); + } + if (boxflag) + pout = strapp(pout, "\\hline\n"); + if (dboxflag) + pout = strapp(pout, "\\hline\n"); + pout = strapp(pout,"\\end{tabular}\n"); + if (ctrflag) + pout = strapp(pout, "\\end{center}\n"); + if (linsize > 0) + pout = strapp(pout, "}\n"); + pout = strapp(pout, "\\par\n"); + *offset = pin - ptr; + return (pout); + } + (void)get_line(pin, w, 0); + if (strncmp(w, "T{", 2) == 0) { + pin = skip_line(pin); + pin += get_tbl_txt_entry(pin, w); + troff_tex(w, ww, 0, 0); + snprintf(tmp, sizeof(tmp), "\\parbox[t]{%5.4f\\hsize}{\n%s} & ", 1.0 / columns, ww); + pin += get_table_entry(pin, w, tab); + } + else { + pin += get_table_entry(pin, w, tab); + troff_tex(w, ww, 0, 1); + snprintf(tmp, sizeof(tmp), "%s & ", ww); + } + pin++; /* skip tab */ + pout = strapp(pout,tmp); + } /* end for */ + pin += skip_white(pin); + (void) getword (pin, w); + if (strcmp(w, ".TE") == 0) { + fprintf(stderr, "Oops! I goofed. I told I you I am not very good at tables\n" + "I've encountered an unexpected end for the table\n" + "You need to fix it yourself\n"); + pin = skip_line(pin); + if (boxflag || allflag) + pout = strapp(pout, "\\hline\n"); + if (dboxflag) + pout = strapp(pout, "\\hline\n"); + pout = strapp(pout,"\\end{tabular}\n"); + if (ctrflag) + pout = strapp(pout, "\\end{center}\n"); + if (linsize > 0) + pout = strapp(pout, "}\n"); + pout = strapp(pout, "\\par\n"); + *offset = pin - ptr; + return(pout); + } + //pin += skip_white(pin); + (void)get_line(pin, w, 0); + if (strncmp(w, "T{", 2) == 0) { + pin = skip_line(pin); + pin += get_tbl_txt_entry(pin, w); + troff_tex(w, ww, 0, 0); + snprintf(tmp, sizeof(tmp), "\\parbox[t]{%5.4f\\hsize}{\n%s} \\\\\n", 1.0 / columns, ww); + //pin += get_table_entry(pin, w, tab); + } + else { + pin += get_table_entry(pin, w, '\n'); + troff_tex(w, ww, 0, 1); + snprintf(tmp, sizeof(tmp), "%s \\\\\n", ww); + } + pin++; /* skip tab */ + pout = strapp (pout, tmp); + if (allflag) + pout = strapp(pout, "\\hline\n"); + } + fprintf (stderr, "Oops! I goofed. I told I you I am not very good at tables\n" + "File ended and I haven't finished the table!\n" + "You need to fix it yourself\n"); + *offset = pin - ptr; + pout = strapp (pout, "\\end{tabular}\n\\par\n"); + return (pout); +} + + +/* +** end current environment +*/ +char *end_env (char *pout) +{ + if (IP_stat[RSRE]) { + IP_stat[RSRE] = 0; + pout = strapp (pout, "\\end{IPlist}"); + } + if (QP_stat) { + QP_stat = 0; + pout = strapp (pout, "\\end{quotation}"); + } + if (TP_stat) { + TP_stat = 0; + pout = strapp (pout, "\\end{TPlist}"); + } + return(pout); +} + + +/* +** set flag for current environment +*/ +void envoke_stat (int par) +{ + + switch(par) { + case 2: + IP_stat[RSRE] = 1; + break; + case 3: + TP_stat = 1; + break; + case 4: + QP_stat = 1; + break; + default: + break; + } +} + + + +/* +** do the flipping +*/ +char * flip (char *pout, char *w) +{ + int lb=0, rb=0; + char ww[MAXWORD+1], tmp[MAXWORD+1]; + + ww[0] = EOS; + tmp[0] = EOS; + pout--; + while (isspace (*pout)) + pout--; + while (1) { + if (*pout == '{') { + lb++; + if (lb > rb) + break; + } + if (*pout == '}') + rb++; + if (rb == 0) { + if (! isspace (*pout) && *pout != '$') { + pout--; + continue; + } + else + break; + } + pout--; + if (lb == rb && lb != 0) + break; + } + pout++; + if (*pout == '\\') { + pout++; + (void) getword (pout, tmp); + snprintf(ww, sizeof(ww), "\\%s", tmp); + pout--; + } + else if (*pout == '{') + (void) get_brace_arg (pout, ww); + else + (void) getword (pout, ww); + *pout = EOS; + snprintf(tmp,sizeof(tmp),"\\%s %s", w, ww); + pout = strapp (pout, tmp); + return (pout); +} + + + +/* +** take care of things like x hat under +*/ +char * flip_twice (char *pout, char *w, char *ww) +{ + int lb=0, rb=0; + char tmp1[MAXWORD+1], tmp2[MAXWORD+1]; + + tmp1[0] = EOS; tmp2[0] = EOS; + pout--; + while (*pout == ' ' || *pout == '\t' || *pout == '\n') + pout--; + while (1) { + if (*pout == '{') { + lb++; + if (lb > rb) + break; + } + if (*pout == '}') + rb++; + if (rb == 0) { + if (! isspace (*pout) && *pout != '$') { + pout--; + continue; + } + else + break; + } + pout--; + if (lb == rb && lb != 0) + break; + } + pout++; + if (*pout == '\\') { + pout++; + (void) getword(pout,tmp2); + snprintf(tmp1, sizeof(tmp1), "\\%s", tmp2); + pout--; + } + else if (*pout == '{') + (void) get_brace_arg(pout,tmp1); + else + (void) getword(pout,tmp1); + *pout = EOS; + snprintf(tmp2, sizeof(tmp2), "\\%s{\\%s %s}", w, ww, tmp1); + pout = strapp(pout,tmp2); + return(pout); +} + + + +/* +** get argument +** arguments: +** rec=1 means recursive +*/ +int get_arg (register char *pin, char *w, int rec) +{ + int c,len,i; + char ww[MAXWORD+1]; + int delim; + int escape = 0; + + len=0; + while ((c = *pin) == ' ' || c == '\t') { /* skip spaces and tabs */ + pin++; + len++; + } + i = 0; + if (*pin == '{' || *pin == '\"') { + if (*pin == '{') + delim = '}'; + else + delim = '\"'; + pin++; + len++; + while ((c = *pin++) != EOS && (escape || c != delim) && i < MAXWORD) { + /*if (c == ' ' && delim == '\"') + ww[i++] = '\\';*/ + if (escape && c == 't') + ww[i++] = '\t'; + else + ww[i++] = (char)c; + if (c == '\\' && !escape) + escape = 1; + else { + escape = 0; + } + len++; + } + len++; + } + else { + while ((c = *pin++) != EOS && !isspace(c) + /* && c != '$' && c != '}' */ && i < MAXWORD) { + if (math_mode && c == '~') + break; + ww[i++] = (char)c; + len++; + } + } + ww[i] = EOS; + if (rec == 1) /* check if recursion is required */ + troff_tex(ww, w, 1, 1); + else + strcpy(w, ww); + return(len); +} + + +/* +** get all arguments +** arguments: +** rec=1 means recursive +*/ +int get_allargs (register char *pin, char ***ppw, int rec) +{ + int c, i; + static char *ww [MAXARGS]; + char w[MAXWORD+1], *instart; + int nww; + int delim; + + instart = pin; + for (nww = 0; ; nww++) { + while ((c = *pin) == ' ' || c == '\t') /* skip spaces and tabs */ + pin++; + if (c == '\n') { + pin++; + ww [nww] = EOS; + break; + } + ww [nww] = pin; + i=0; + if (*pin == '{' || *pin == '\"') { + if (*pin == '{') + delim = '}'; + else + delim = '\"'; + ww [nww] = ++pin; + while ((c = *pin++) != EOS && c != delim && i < MAXWORD) + /* EMPTY */ + ; + pin [-1] = EOS; + } + else { + while ((c = *pin++) != EOS && !isspace(c) + /* && c != '$' && c != '}' */ && i < MAXWORD) { + if (math_mode && c == '~') + break; + } + pin [-1] = EOS; + if (c == '\n') { + ww [nww + 1] = EOS; + break; + } + } + } + if (rec == 1) { /* check if recursion is required */ + for (i = 0; ww [i]; i++) { + if (ww [i] && *ww [i]) { + troff_tex (ww [i], w, 1, 1); + if (strcmp (ww [i], w) != 0) + ww [i] = strdup(w); + } + } + } + *ppw = ww; + return (pin - instart); +} + + + + +/* +** get argument surrounded by braces +*/ +void get_brace_arg (char *buf, char *w) +{ + int c,i, lb=0, rb=0; + + i=0; + while ((c = *buf++) != EOS) { + w[i++] = (char)c; + if (c == '{') lb++; + if (c == '}') rb++; + if (lb == rb) break; + } + w[i] = EOS; +} + +/* +** get "define" or .de word +** arguments: +** pin delimited by space only +** w delimited by space only +*/ +int get_defword (char *pin, char *w, int *illegal) +{ + int c,i; + + *illegal = 0; + for (i=0; (c = *pin++) != EOS && !isspace (c) && i < MAXWORD; i++) { + w[i] = (char)c; + if (isalpha(c) == 0) + *illegal = 1; /* illegal TeX macro */ + } + w[i] = EOS; + if (*illegal == 0 && is_forbid(w) >= 0) + *illegal=1; + return(i); +} + + +/* +** get the rest of the line +** arguments: +** rec=1 means recursion is required +*/ +int get_line (char *pin, char *w, int rec) +{ + int c,i,len; + int escape=0; + char ww[MAXLINE+1]; + + i=0; + len=0; + c = *pin; + while ((c = *pin++) != EOS && c != '\n' && len < MAXLINE) { + if (de_arg > 0 && !rec && c == '\\' && !escape) + escape = 1; + else { + escape = 0; + ww[i++] = (char)c; + } + len++; + } + ww[i] = EOS; + if (de_arg>0 && ww[0] == '.') { + /* skip blanks */ + for (i=1; ww[i] == ' '; i++); + strcpy(ww+1, ww+i); + } + //fprintf(stderr, "get_line:%s\n", ww); + if (rec == 1) + troff_tex(ww, w, 0, 1); + else + strcpy(w, ww); + //fprintf(stderr, "get_line out:%s\n", w); + return(len); +} + + +/* +** get multi-line argument +*/ +int get_multi_line (char *pin, char *w) +{ + int len=0,l=0,lines=0; + char tmp[MAXWORD+1]; + int c1,c2; + + w[0] = EOS; tmp[0] = EOS; + while (*pin != EOS) { + c1 = *pin; + c2 = *++pin; + --pin; + if (c1 == '.' && isupper(c2)) + break; + lines++; + if (lines > 1) + strcat(w," \\\\\n"); + l = get_line(pin,tmp,1); + strcat(w,tmp); + len += l+1; + pin += l+1; + } + len--; + pin--; + return(len); +} + + +/* +** get the macro substitution +*/ +int get_mydef (char *pin, char *w) +{ + int c1,c2,l,len; + char tmp[MAXLINE+1]; + char ww[MAXLINE*20+1]; + + tmp[0] = EOS; + ww[0] = EOS; + len=1; + while (*pin != EOS) { + c1 = *pin; + c2 = *++pin; + --pin; + if (c1 == '.' && c2 == '.') + break; + l = get_line(pin, tmp, 0); + if (len+l+1 < MAXLINE*20) { + strcat(ww, tmp); + strcat(ww, "\n"); + len += l+1; + pin += l+1; + } else break; + } + troff_tex(ww, w, 0, 1); + return(len); +} + + +/* +** get N lines +*/ +int get_N_lines (char *pin, char *w, int N) +{ + int len=0,l=0,lines=0; + char tmp[MAXWORD+1]; + + w[0] = EOS; tmp[0] = EOS; + while (*pin != EOS && lines < N) { + lines++; + if (lines > 1) + strcat(w," \\\\\n"); + l = get_line(pin, tmp, 1); + strcat(w,tmp); + len += l+1; + pin += l+1; + } + len--; + pin--; + return(len); +} + + +/* +** get text surrounded by quotes in math mode +*/ +int get_no_math (char *pin, char *w) +{ + int c,i,len; + + len = 0; + for (i=0; (c = *pin++) != EOS && c != '\"' && i < MAXWORD; i++) { + if (c == '{' || c == '}') { + w[i] = '\\'; + w[++i] = (char)c; + } + else + w[i] = (char)c; + len++; + } + w[i] = EOS; + return(len); +} + + +/* +** get the denominator of over +*/ +char *get_over_arg (char *pin, char *ww) +{ + char w[MAXWORD+1], tmp1[MAXWORD+1], tmp2[MAXWORD+1]; + int len; + + w[0] = EOS; + tmp1[0] = EOS; + tmp2[0] = EOS; + pin += getword (pin,tmp1); /* read first word */ + pin += skip_white (pin); + len = getword (pin, tmp2); /* read second word */ + strcat(w,tmp1); strcat(w," "); + + /* as long as there is a sup or sub read the next two words */ + while (strcmp (tmp2, "sub") == 0 || strcmp (tmp2, "sup") == 0) { + pin += len; + strcat (w, tmp2); + strcat (w, " "); + pin += skip_white (pin); + pin += getword (pin, tmp1); + strcat (w, tmp1); + strcat (w, " "); + pin += skip_white (pin); + len = getword (pin, tmp2); + } + troff_tex (w, ww, 0, 1); + return (pin); +} + + + +/* +** get reference +*/ +int get_ref (char *pin, char *w) +{ + int len=0, l=0, lines=0; + char tmp[MAXWORD+1]; + + w[0] = EOS; tmp[0] = EOS; + while (*pin != EOS) { + if (*pin == '\n') + break; + (void) getword(pin,tmp); + if (tmp[0] == '.' && isupper(tmp[1])) { + /* these commands don't cause a break in reference */ + if (strcmp (tmp, ".R") != 0 && strcmp (tmp, ".I") != 0 + && strcmp(tmp,".B") != 0) + break; + } + else if (tmp[0] == '.' && !(isupper(tmp[1]))) { + /* these commands don't cause a break in reference */ + if (strcmp (tmp, ".br") != 0 && strcmp (tmp, ".bp") != 0) + break; + } + l = get_line (pin, tmp, 1); + lines++; + if (lines > 1) + strcat (w, " "); + strcat (w, tmp); + len += l+1; + pin += l+1; + } + len--; + pin--; + return (len); +} + + +/* +** +*/ +void get_size (char *ww, struct measure *PARAMETER) +{ + int sign=0, units=0; + float value; + + if (ww[0] == EOS) { + if (PARAMETER->def_value == 0) { + PARAMETER->value = PARAMETER->old_value; + strcpy(PARAMETER->units,PARAMETER->old_units); + } + else { + PARAMETER->value = PARAMETER->def_value; + strcpy(PARAMETER->units,PARAMETER->def_units); + } + } + else { + PARAMETER->old_value = PARAMETER->value; + strcpy (PARAMETER->old_units, PARAMETER->units); + + parse_units (ww, &sign, &units, &value); + + if (units == 'p') + strcpy (PARAMETER->units, "pt"); + else if (units == 'i') + strcpy (PARAMETER->units, "in"); + else if (units == 'c') + strcpy (PARAMETER->units, "cm"); + else if (units == 'm') + strcpy (PARAMETER->units, "em"); + else if (units == 'n') { + value = .5*value; /* n is about half the width of m */ + strcpy (PARAMETER->units, "em"); + } + else if (units == 'v') + strcpy(PARAMETER->units,"ex"); + else if (units == 0) { + if (sign == 0 || PARAMETER->old_units[0] == EOS) + strcpy(PARAMETER->units,PARAMETER->def_units); + else + strcpy(PARAMETER->units,PARAMETER->old_units); + } + else { + fprintf(stderr,"unknown units %c, using default units\n", units); + strcpy(PARAMETER->units,PARAMETER->def_units); + } + if (sign == 0) + PARAMETER->value = value; + else + PARAMETER->value = PARAMETER->old_value + sign*value; + } +} + + + +/* +** get the rest of the line -- Nelson Beebe +** arguments: +** rec=1 means recursion is required +*/ +int get_string (char *pin, char *w, int rec) +{ + int c,i,len; + char ww[MAXLINE+1]; + char *start; + + if (*pin != '\"') + return(get_line(pin,w,rec)); + start = pin; /* remember start so we can find len */ + i=0; + pin++; /* point past initial quote */ + while ((c = *pin++) != EOS && c != '\"' && c != '\n' && i < MAXLINE) + ww[i++] = (char)c; + ww[i] = EOS; + if (c != '\n') /* flush remainder of line */ + while ((c = *pin++) != '\n') + /* EMPTY */ + ; + len = pin - start - 1; /* count only up to NL, not past */ + if (rec == 1) + troff_tex(ww,w,0,1); + else + strcpy(w,ww); + return(len); +} + + + +/* +** get the argument for sub and sup +*/ +int get_sub_arg (char *pin, char *w) +{ + int c,len,i; + char ww[MAXWORD+1], tmp[MAXWORD+1]; + + len=0; tmp[0] = EOS; + while ((c = *pin) == ' ' || c == '\t') { + pin++; + len++; + } + i=0; + while ((c = *pin++) != EOS && c != ' ' && c != '\t' && c != '\n' + && c != '$' && c != '}' && c != '~' && i < MAXWORD) { + ww[i++] = (char)c; + len++; + } + ww[i] = EOS; + if (strcmp(ww,"roman") == 0 || strcmp(ww,"bold") == 0 + || strcmp(w,"italic") == 0) { + (void) get_arg(pin,tmp,0); + snprintf(ww, sizeof(ww), "%s%c%s", ww, c, tmp); + len += strlen(tmp)+1; + } + troff_tex(ww,w,0,1); /* recursive */ + return(len); +} + + +/* +** +*/ +int get_table_entry (char *pin, char *w, int tab) +{ + int i=0, escape=0; + char c; + + while ((c = *pin++) != EOS && (escape || (c != tab && c != '\n')) && i < MAXLINE) { + if (escape && c != '\n') + w[i++] = '\\'; + if (c == '&') + w[i++] = '\\'; + if (c == '\\' && !escape) + escape = 1; + else { + w[i++] = c; + escape = 0; + } + } + w[i] = EOS; + return(i); +} + +int get_tbl_txt_entry(char *pin, char *w) { + int i; + char c, tmp[MAXWORD+1]; + + for (i = 0; (c = *pin++) != EOS && i < MAXLINE; i++) { + w[i] = c; + if (c == '\n') { + (void)get_line(pin, tmp, 0); + if (strncmp(tmp, "T}", 2) == 0) { + w[++i] = EOS; + return (i + 2); + } + } + } + w[i] = EOS; + return (i); +} + + +/* +** get characters till the next space +*/ +int get_till_space (char *pin, char *w) +{ + int c,i; + + for (i=0; (c = *pin++) != EOS && c != ' ' && c != '\n' + && c != '\t' && i < MAXWORD; i++) + w[i] = (char)c; + w[i] = EOS; + return(i); +} + + + +/* +** get the define substitution +*/ +int getdef (char *pin, char *ww) +{ + int c,i,len; + int def_delim; + char w[MAXWORD+1]; + + def_delim = *pin++; /* take first character as delimiter */ + len=1; + i=0; + while ((c = *pin++) != EOS && c != def_delim && i < MAXWORD) { + len++; + w[i++] = (char)c; + } + w[i] = EOS; + len++; + if (c != def_delim) { + fprintf(stderr, + "WARNING: missing right delimiter in define, define=%s\n",w); + len--; + } + troff_tex(w,ww,0,1); /* now translate the substitution */ + return(len); +} + + + +/* +** get an alphanumeric word (dot also) +*/ +int getword (char *pin, char *w) +{ + int c,i; + + for (i=0; (c = *pin++) != EOS + && (isalpha(c) || isdigit(c) || c == '.') && i < MAXWORD; i++) + w[i] = (char)c; + if (i == 0 && c != EOS) + w[i++] = (char)c; + w[i] = EOS; + return(i); +} + + + +/* +** change GREEK to Greek +*/ +void GR_to_Greek (char *w, char *ww) +{ + *ww++ = '\\'; + *ww++ = *w; + while(*++w != EOS) + *ww++ = tolower(*w); + *ww = EOS; +} + + + +/* +** check if w was defined by the user +*/ +int is_def (char *w) +{ + int i; + + for (i=0; i < def_count; i++) { + if (strcmp(def[i].def_macro,w) == 0) + return(i); + } + return(-1); +} + + + +/* +** check if w is in the flip list +*/ +int is_flip (char *w) +{ + int i; + + for (i=0; i < flip_count; i++) { + if (strcmp(flip_list[i],w) == 0) + return(i); + } + return(-1); +} + + + +/* +** check if w is one of those sacred macros +*/ +int is_forbid (char *w) +{ + int i; + + for (i=0; i < forbd_count; i++) { + if (strcmp(forbid[i],w) == 0) + return(i); + } + return(-1); +} + + + +/* +** check if w has a simple correspondence in TeX +*/ +int is_mathcom (char *w, char *ww) +{ + int i; + + for (i = 0; i < mathcom_count; i++) + if (strcmp (math[i].troff_symb, w) == 0) { + strcpy (ww, math[i].tex_symb); + return (i); + } + return (-1); +} + +/* +** +*/ +int is_special (char *w, char *ww) +{ + int i; + //fprintf(stderr, "special_count:%d\n", special_count); + for (i = 0; i < special_count; i++) + if (strcmp (special[i].troff_char, w) == 0) { + strcpy (ww, special[i].tex_char); + //fprintf(stderr, "Special: %d, %s -> %s\n", i, w, ww); + return (i); + } + return (-1); +} + + +/* +** check if w is user-defined macro +*/ +int is_mydef (char *w) +{ + int i; + + for (i=0; i < mydef_count; i++) { + if (strcmp(mydef[i].def_macro,w) == 0) + return(i); + } + return(-1); +} + + + +/* +** check if w is a macro or plain troff command +*/ +int is_troff_mac (char *w, char *ww, int *arg, int *par) +{ + int i; + + for (i=0; i < macro_count; i++) + if (strcmp(macro[i].troff_mac,w) == 0) { + strcpy(ww,macro[i].tex_mac); + *arg = macro[i].arg; + *par = macro[i].macpar; + return(i); + } + return(-1); +} + + +/* +** +*/ +void parse_units (char *ww, int *sign, int *units, float *value) +{ + int len, k=0, i; + char tmp[MAXWORD+1]; + + len = strlen(ww); + if (ww[0] == '-') + *sign = -1; + else if (ww[0] == '+') + *sign = 1; + if (*sign != 0) + k++; + + i=0; + while (k < len) { + if (isdigit(ww[k]) || ww[k] == '.') + tmp[i++] = ww[k++]; + else + break; + } + tmp[i] = EOS; + sscanf(tmp,"%f",value); + i=0; + if (k < len) { + *units = ww[k++]; + if (k < len) + fprintf(stderr, "Suspect problem in parsing %s, unit used is %c\n", + ww, *units); + } +} + + + +/* +** check if w is in the similar list +*/ +int similar (char *w) +{ + int i; + + for (i=0; i < sim_count ; i++) { + if (strcmp(sim_list[i],w) == 0) + return(1); + } + return(-1); +} + + + +/* +** ignore the rest of the line +*/ +char * skip_line (char *pin) +{ + while (*pin != '\n' && *pin != EOS) + pin++; + if (*pin == EOS) + return(pin); + else + return(++pin); +} + + + +/* +** skip white space +*/ +int skip_white (char *pin) +{ + int c,len=0; + + while ((c = *pin++) == ' ' || c == '\t') /* || c == '\n') */ + len++; + return(len); +} + + + +/* +** copy tail[] to s[], return ptr to terminal EOS in s[] +*/ +char * strapp (char *s, char *tail) +{ + while ((*s++ = *tail++) != 0) + if (debug_o) + fputc(s[-1], stderr); + return (s-1); /* pointer to EOS at end of s[] */ +} diff --git a/support/tr2latex/testfile b/support/tr2latex/testfile new file mode 100644 index 0000000000..909b6c83eb --- /dev/null +++ b/support/tr2latex/testfile @@ -0,0 +1,230 @@ +.ds AA Test Troff String +.nr VS 12p +.DA +.ND +.EQ +delim $$ +gsize 11 +define dC "delta C" +define xx 'x sup x' +define B 'bold B' +define (( 'left (' +define )) 'right )' +define ov 'over' +.EN +.ds CF % +.ds LH Al-Yahya +.ds RH troff to LaTeX translator +.TL +Testing the troff-to-LaTeX translator +.AU +Kamal Al-Yahya +.AI +Stanford University +.AB +This file demonstrates the use of \fBtr2latex\fR which translates +documents written in troff to a LaTeX style. +Examples are given to show what the translator can do. +.AE +.TS +allbox; +cfI s s +c cw(1i) cw(1i) +lp9 lp9 lp9. +New York \ +Area Rocks +Era Formation Age (years) +Precambrian Reading Prong >1 billion +Paleozoic Manhattan Prong 400 million +Mesozoic T{ +.na +Newark Basin, incl. +Stockton, Lockatong, and Brunswick formations; also Watchungsand Palisades. +T} 200 million +Cenozoic Coastal Plain T{ +On Long Island 30,000 years;Cretaceous sediments redepositedby recent glaciation. +.ad +T} +.TE +.NH 1 +Section +may be several lines +.LP +Li Eur\*Cop\*`an \*:A\*~z \*(AA lingu\*^es es mem\(embres del sam famili\*'e. +Lor separat existentie es un myth. +Por scientie, musica, sport etc, litot Europa usa li sam vocabular. +Li lingues differe solmen in li grammati\*,Ca, li pronunciation e li plu commun vocabules. +Omnicos directe al desirabilite de un nov lingua franca: On refusa continuar payar custosi traductores. +At solmen va esser necessi far uniform grammatica, pronunciation e plu sommun paroles. +Ma quande lingues coalesce, li grammatica del resultant lingue es plu simplic e regulari quam ti del coalescent lingues. +Li nov lingua franca va esser plu simplic e regulari quam li existent Europan lingues. +.PP +.NH 2 +SubSection +.LD +.TS +tab(&); +l l. +T{ +It va esser tam simplic quam Occidental in fact, it va esser Occidental. +A un Angleso it va semblar un simplificat Angles, quam un skeptic Cambridge amico dit me que Occidental es. +Li Europan lingues es membres del sam familie. +Lor separat existentie es un myth. +T} & T{ +Por scientie, musica, sport etc, litot Europa usa li sam vocabular. +Li lingues differe solmen in li grammatica, li pronunciation e li plu commun vocabules. +Omnicos directe al desirabilite de un nov lingua franca: On refusa continuar payar custosi traductores. +At solmen va esser necessi far uniform grammatica, pronunciation e plu sommun paroles. +T} +.TE +Por scientie, musica, sport etc, litot Europa usa li sam vocabular. +Li lingues differe solmen in li grammatica, li pronunciation e li plu commun vocabules. +.DE +Adjust right +.LP +.\"ad r +Omnicos directe al desirabilite de un nov lingua franca: +On refusa continuar payar custosi traductores. +At solmen va esser necessi far uniform grammatica, +pronunciation e plu sommun paroles. +.\"ad +.LP +.NH 2 +Special Characters +.TS +tab(,),center box linesize(2); +l l l l l l l l l l l. +\(em, \e(em, , \(sc, \e(sc, , \(ib, \e(ib, , \(hy, \e(hy +\(ul, \e(ul, , \(ip, \e(ip, , \(bu, \e(bu, , \(sl, \e(sl +\(if, \e(if, , \e(sq, \e(sq, , \(ts, \e(ts, , \(pd, \e(pd +\(ru, \e(ru, , \(sr, \e(sr, , \(gr, \e(gr, , \(14, \e(14 +\(rn, \e(rn, , \(no, \e(no, , \(12, \e(12, , \(>=, \e(>= +\(is, \e(is, , \(34, \e(34, , \(<=, \e(<=, , \(pt, \e(pt +\(fi, \e(fi, , \(==, \e(==, , \(es, \e(es, , \(fl, \e(fl +\(|=, \e(|=, , \(mo, \e(mo, , \(ff, \e(ff, , \(ap, \e(ap +\(br, \e(br, , \(Fi, \e(Fi, , \(!=, \e(!=, , \(dd, \e(dd +\(Fl, \e(Fl, , \(->, \e(->, , \(rh, \e(rh, , \(de, \e(de +\(<-, \e(<-, , \(lh, \e(lh, , \(dg, \e(dg, , \(ua, \e(ua +\(bs, \e(bs, , \(fm, \e(fm, , \(da, \e(da, , \(or, \e(or +\(ct, \e(ct, , \(mu, \e(mu, , \(ci, \e(ci, , \(rg, \e(rg +\(di, \e(di, , \(bv, \e(bv, , \(co, \e(co, , \(+-, \e(+- +\(lf, \e(lf, , \(pl, \e(pl, , \(cu, \e(cu, , \(rf, \e(rf +\(mi, \e(mi, , \(ca, \e(ca, , \(lc, \e(lc, , \(eq, \e(eq +\(sb, \e(sb, , \(rc, \e(rc, , \(**, \e(**, , \(sp, \e(sp +.TE +.sp +The Macros \e(*a - \e(*w for small greek letters and \e(*A - \e(*W for upper greek letters. +.TS +tab(,); +l l l l l l l l l l l l l l l l l l l l l l l l. + a, b, g, d, e, z, y, h, i, k, l, m, n, c, o, p, r, s, t, u, f, x, q, w +\(*a,\(*b,\(*g,\(*d,\(*e,\(*z,\(*y,\(*h,\(*i,\(*k,\(*l,\(*m,\(*n,\(*c,\(*o,\(*p,\(*r,\(*s,\(*t,\(*u,\(*f,\(*x,\(*q,\(*w +.sp + A, B, G, D, E, Z, Y, H, I, K, L, M, N, C, O, P, R, S, T, U, F, X, Q, W + \(*A,\(*B,\(*G,\(*D,\(*E,\(*Z,\(*Y,\(*H,\(*I,\(*K,\(*L,\(*M,\(*N,\(*C,\(*O,\(*P,\(*R,\(*S,\(*T,\(*U,\(*F,\(*X,\(*Q,\(*W +.TE +.PP +First let's test some equation written for the +.B eqn +preprocessor: +.EQ (1) +2 left ( 1 ~+~ sqrt{omega sub i+1 + zeta -{x+1} over {THETA +1} y + 1} right ) +~~~=~~~ half +.EN +.EQ +X + a >= a SIGMA +.EN +.EQ +left [ +matrix { + ccol { e sub 1 above . above . above e sub i above . above . above e sub N } +} +right ] sub n+1 ~~=~~ y + 1 +.EN +.EQ +bold X + roman a ~>=~ +a under hat fwd 20 sum from i to N lim from {x -> k} dC +.EN +.EQ +(( "speed" times "time" = "distance travelled" )) +.EN +.EQ +beta tilde i >= zeta dC +.EN +.EQ +GAMMA == PI -> upsilon fat xi +.EN +.EQ +G(z) ~=~ e sup { ln ~ G(z) } + ~=~ exp left ( sum from k>=1 { S sub k z sup k } over k right ) + ~=~ prod from k>=1 e sup { S sub k z sup k /k } +.EN +.IP "" 10 +In-line math like $beta +1$ which is surrounded by math delimiters, as +defined by +.I delim +is also translated. +.R +.PP +Only simple tables are translated. Translation of more complicated tables +is painful and I won't do it now. Here is an example: +.TS +tab(&),allbox; +l rc n. +name & type & color & value +_ +$alpha$ & real & red & 2.3 +$x$ & imaginary & green & -1.2 +$a + 2$ & real & white & 0.0 +.TE +\" this is a commented text +.PP +Now we start a figure. +.Is +.sp 3i +.Ic 1 +This is the caption of the figure. +.Ie +.PP +Try some floating objects. +.br +.KS +This text should be kept in one page. i.e. a page break is discouraged here. +.KE +.br +Now a floating text. +.KF +This text should be kept in one page even if we had to move it around, +since it is a +.I floating +object. This is a boxed +.BX word. +.KE +.br +These characters are special in TeX, so they need to be escaped +in the translation % & # _, while these characters have to be +printed in math mode < > |. +.FS +This is a footnote +.FE +.PP +.Ac +Thanks to all of those who contributed by reporting bugs and suggesting +some improvements. Special thanks go to Nelson Beebe for all of his valuable +contributions and suggestions. He is responsible for making the translator +portable to other computers. He also made significant improvements to +the translation of manuals. +.Re +Knuth, D.E., 1984, The TeXBook, Addison-Wesley Publishing Company. +.Re +Lamprt, L., 1986, LaTeX: user's guide & reference manual, Addison-Wesley +Publishing Company. +.Re +Lesk, M.E., 1978, Typing documents on the UNIX +system: using the -ms macros +with troff and nroff, UNIX programmer's manual, v. 2B, sec. 3. +.Re +McGilton, H. and Morgan, R., 1983, Introducing the UNIX system, McGraw-Hill +Book Company. +.bp +.PX
\ No newline at end of file diff --git a/support/tr2latex/tr.c b/support/tr2latex/tr.c new file mode 100644 index 0000000000..ec2d97845d --- /dev/null +++ b/support/tr2latex/tr.c @@ -0,0 +1,1361 @@ +/* -*- mode: C; c-basic-offset: 2; tab-width: 2 -*- */ +/* +** tr2latex - troff to LaTeX converter +** COPYRIGHT (C) 1987 Kamal Al-Yahya, 1991,1992 Christian Engel +** +** Module: tr.c +** +** This module contains the HARD-WIRED rules of the translator. +** It should be handled with care. +*/ + +#include "setups.h" +#include "protos.h" + +int def_count = 0; +int mydef_count = 0; + +extern int man; /* man flag */ + +void troff_tex (char *pin, char *pout, int mid, int rec) +{ + char eqn_no[MAXWORD], w[MAXWORD], ww[MAXLINE], tmp[MAXWORD], tmp2[MAXWORD]; + char *p, **pw; + int len,c,c1,c2,i,j; + int ref = 0; + int put_brace = 0; + int first_word = 1; + int no_word = 1; + int arg = 0; + int par = 0; + int illegal = 0; + int floating = 0; + static int delim_defd = 0; /* whether math delimiter has been defined */ + static char DELIM [] = "$"; + float flen; + int N; + int EXEE = 0; /* example indentation */ + int NTNE = 0; /* note indentation */ + int thisfont = 1; /* default font is roman */ + int lastfont = 1; /* default last font is roman */ + int offset = 0; /* amount to offset pin */ + + *pout = EOS; + w[0] = EOS; + ww[0] = EOS; + tmp[0] = EOS; + tmp2[0] = EOS; + while (*pin != EOS) { + len = getword(pin,w); + c1 = (first_word? '\n': pin[-1]); + c2 = pin[0]; + pin += len; + if (!isspace(w[0])) + no_word = 0; + /* first check if we are in math mode */ + if (math_mode) { + len = get_till_space(pin,ww); + snprintf(tmp,sizeof(tmp),"%s%s",w,ww); + if (strcmp(w,"delim") == 0) { + delim_defd = 1; + pin += skip_white(pin); + DELIM[0] = *pin; + pin = skip_line(pin); + } + /* check if it is a math delimiter; switch to non-math mode if so*/ + else if (delim_defd && strcmp(w,DELIM) == 0) { + math_mode = 0; + *pout++ = '$'; + } + /* check for illegal macros here */ + else if (len > 0 && def_count > 0 && (i=is_def(tmp)) >= 0) { + pin += len; + pout = strapp(pout,def[i].replace); + } + /* See if it is a (legally) defined macro */ + else if (def_count > 0 && (i=is_def(w)) >= 0) { + if (def[i].illegal) + pout = strapp(pout,def[i].replace); + else { + pout = strapp(pout,"\\"); + pout = strapp(pout,w); + } + } + /* Search for commands in some order; + start with non-alphanumeric symbols */ + else if (strcmp(w,"#") == 0 || strcmp(w,"&") == 0 + || strcmp(w,"%") == 0 || strcmp(w,"_") == 0) { + pout = strapp(pout,"\\"); + pout = strapp(pout,w); + } + else if (strcmp(w,"=") == 0) { + if (*pin == '=') { + pin++; + pout = strapp(pout,"\\equiv"); + } + else + pout = strapp(pout,"="); + } + else if (strcmp(w,"<") == 0 || strcmp(w,">") == 0) { + if (*pin == '=') { + pin++; + if (strcmp(w,"<") == 0) + pout = strapp(pout,"\\le"); + else + pout = strapp(pout,"\\ge"); + } + else { + *pout++ = *w; + } + } + else if (strcmp(w,"-") == 0) { + if (*pin == '>') { + pin++; + pout = strapp(pout,"\\to"); + } + else if (*pin == '+') { + pin++; + pout = strapp(pout,"\\mp"); + } + else + *pout++ = '-'; + } + else if (strcmp(w,"+") == 0) { + if (*pin == '-') { + pin++; + pout = strapp(pout,"\\pm"); + } + else + *pout++ = '+'; + } + else if (strcmp(w,"\"") == 0) { + len = get_no_math(pin,ww); + pin += len+1; + if (len > 1) { + snprintf(tmp,sizeof(tmp),"\\ \\it\\hbox{%s}",ww); + pout = strapp(pout,tmp); + } + else if (len == 1) + *pout++ = ww[0]; + } + /* Now search for symbols that start with a captial */ + else if (strcmp(w,".EN") == 0) { + math_mode = 0; + if ((len=strlen(eqn_no)) > 0) + { + snprintf(tmp,sizeof(tmp),"\\eqno %s",eqn_no); + pout = strapp(pout,tmp); + } + eqn_no[0] = EOS; + c1 = *--pout; + c2 = *--pout; + if (c1 == '\n' && c2 == '$') + *--pout = EOS; + else { + pout += 2; + pout = strapp(pout,"$$"); + } + } + /* Now search for symbols that start with a small letter */ + else if (strcmp(w,"bold") == 0 || strcmp(w,"roman") == 0 || + strcmp(w,"italic") == 0) { + pin += get_arg(pin,ww,1); + if (strcmp(w,"bold") == 0) { + snprintf(tmp,sizeof(tmp),"{\\bf %s}",ww); + pout = strapp(pout,tmp); + } + else if (strcmp(w,"roman") == 0) { + snprintf(tmp,sizeof(tmp),"{\\rm %s}",ww); + pout = strapp(pout,tmp); + } + else { + snprintf(tmp,sizeof(tmp),"{\\it %s}",ww); + pout = strapp(pout,tmp); + } + } + else if (strcmp(w, "define") == 0) { + if (def_count >= MAXDEF) { + fprintf(stderr, "Too many defines. MAXDEF=%d\n",MAXDEF); + exit(-1); + } + for (i=0; *--pout != '$' && (unsigned)i < MAXLEN; i++) + tmp[i] = *pout; + tmp[i] = EOS; + strcat(tmp,"$$"); + *--pout = EOS; + pin += skip_white(pin); + pin += get_defword(pin, w, &illegal); + pin += skip_white(pin); + pin += getdef(pin,ww); + if (illegal) { + def[def_count].illegal = 1; + fprintf(stderr, "illegal TeX macro, %s, replacing it\n",w); + def[def_count].replace = strdup(ww); + } + else { + def[def_count].illegal = 0; + snprintf(tmp2, sizeof(tmp2), "\\def\\%s{%s}\n", w, ww); + pout = strapp(pout,tmp2); + } + def[def_count++].def_macro = strdup(w); + pin = skip_line(pin); + for (j=i+1; j >= 0; j--) + *pout++ = tmp[j]; + tmp[0] = EOS; + } + else if (strcmp(w,"gsize") == 0 || strcmp(w,"gfont") == 0) + pin = skip_line(pin); + else if (strcmp(w,"left") == 0 || strcmp(w,"right") == 0) { + snprintf(tmp,sizeof(tmp),"\\%s",w); + pout = strapp(pout,tmp); + pin += skip_white(pin); + len = getword(pin,ww); + if (strcmp(ww,"floor") == 0) { + pin += len; + if (strcmp(w,"left") == 0) + pout = strapp(pout,"\\lfloor"); + else + pout = strapp(pout,"\\rfloor"); + } + else if (strcmp(ww,"nothing") == 0 || ww[0] == '\"') { + pin += len; + *pout++ = '.'; + if (ww[0] == '\"') pin++; + } + else if (*pin == '{' || *pin == '}') + *pout++ = '\\'; + } + else if (strcmp(w,"over") == 0) { + if (!first_word) { + pout--; + for (i=0; isspace (*pout); i++) + tmp[i] = *pout--; + if (*pout == '}' && put_brace == 0) + *pout = ' '; + else { + for (; !isspace(*pout) && *pout != '$'; i++) + tmp[i] = *pout--; + put_brace = 0; + *++pout = '{'; + } + for (j=i-1; j >= 0; j--) + *++pout = tmp[j]; + *++pout = EOS; + } + pout = strapp(pout,"\\over"); + pin += skip_white(pin); + *pout++ = ' '; + if (*pin == '{') + pin++; + else { + pin = get_over_arg(pin,ww); + pout = strapp(pout,ww); + if (*pin != EOS || !first_word) + *pout++ = '}'; + } + } + else if (strcmp(w,"size") == 0) + pin += get_arg(pin,ww,0); + else if (strcmp(w,"sup") == 0 || strcmp(w,"to") == 0 || + strcmp(w,"sub") == 0 || strcmp(w,"from") == 0) { + while ((c = *--pout) == ' ' || c == '\t' || c == '\n') + /* EMPTY */; + *++pout = EOS; + if (strcmp(w,"sup") == 0 || strcmp(w,"to") == 0) + pout = strapp(pout,"^"); + else + pout = strapp(pout,"_"); + pin += skip_white(pin); + len = get_sub_arg(pin,ww); + pin += len; + if (len > 1) { + snprintf(tmp,sizeof(tmp),"{%s}",ww); + pout = strapp(pout,tmp); + len = skip_white(pin); + pin += len; + (void) getword(pin,ww); + if (strcmp(ww,"over") == 0) + put_brace = 1; + pin -= len; + } + else + pout = strapp(pout,ww); + } + else if (strcmp(w,"up") == 0 || strcmp(w,"down") == 0 + || strcmp(w,"fwd") == 0 || strcmp(w,"back") == 0) { + if (strcmp(w,"up") == 0) { + pout = strapp(pout,"\\raise"); + strcpy(tmp,"ex"); + } + else if (strcmp(w,"down") == 0) { + pout = strapp(pout,"\\lower"); + strcpy(tmp,"ex"); + } + else if (strcmp(w,"fwd") == 0) { + pout = strapp(pout,"\\kern"); + strcpy(tmp,"em"); + } + else if (strcmp(w,"back") == 0) { + pout = strapp(pout,"\\kern-"); + strcpy(tmp,"em"); + } + pin += skip_white(pin); + pin += getword(pin,ww); + len = atoi(ww); flen = len/100.; + ww[0] = EOS; + snprintf(tmp2, sizeof(tmp2), "%4.2f%s", flen, tmp); + pout = strapp(pout,tmp2); + } + /* Now check if the word is a member of a group */ + else if (CAP_GREEK(w) > 0) { + GR_to_Greek(w,ww); + pout = strapp(pout,ww); + } + else if (is_flip(w) >= 0) { + if (!first_word) { + len = skip_white(pin); + pin += len; + (void) getword(pin,ww); + if (is_flip(ww) >= 0) { + pin += strlen(ww); + pout = flip_twice(pout,w,ww); + } + else { + pin -= len; + pout = flip(pout,w); + } + } + else { + pout = strapp(pout,"\\"); + pout = strapp(pout,w); + } + } + else if (is_mathcom (w, ww) >= 0) + pout = strapp (pout, ww); + else if (similar(w) > 0) { + pout = strapp (pout, "\\"); + pout = strapp (pout, w); + } + + /* if none of the above math commands matched, it is an ordinary + symbol; just copy it */ + + else + pout = strapp(pout,w); + } + + /* check if it is a math delimiter; switch to math mode if so */ + + else if (strcmp(w,"$") == 0 && de_arg > 0) { + de_arg++; + *pout++ = '#'; + } + else if (delim_defd && strcmp(w,DELIM) == 0) { + math_mode = 1; + *pout++ = '$'; + } + else if (strcmp(w,"$") == 0) + pout = strapp(pout,"\\$"); + + /* check if it is a non-math troff command */ + + else if (c2=='.' && !mid && (c1=='\n' || c1==EOS || first_word)) { + /* Search in some order; start with non-alphanumeric characters */ + if (strcmp(w, ".") == 0) { + c1 = *pin; + c2 = *++pin; + if (c1 == '\\' && c2 == '\"') { + /* Comment starts with .\" */ + ++pin; + pin += get_line(pin,ww,0); + pout = strapp(pout,"%"); + pout = strapp(pout,ww); + } + else if (c1 == '\n') { + pout = strapp(pout, "\n"); + } + else { + fprintf(stderr, + "I cannot translate troff macro .%c%c\n",c1,c2); + pin += get_line(pin,ww,0); + snprintf(tmp, sizeof(tmp), "%%.%c%c%s", c1, c2, ww); + pout = strapp(pout,tmp); + if (*pin == EOS) + *pout++ = '\n'; + } + } + /* Now search for commads that start with a capital */ + else if (strcmp(w,".AB") == 0) { + pin += get_arg(pin,ww,0); + if (strcmp(ww,"no") == 0) + pout = strapp(pout,"\\bigskip"); + else + pout = strapp(pout,"\\begin{abstract}"); + } + else if (strcmp(w,".B") == 0 || strcmp(w,".bf") == 0 || + strcmp(w,".I") == 0 || strcmp(w,".it") == 0 || + strcmp(w,".R") == 0 || strcmp(w,".rm") == 0 || + strcmp(w,".P") == 0) { + if (strcmp(w,".R") == 0 || strcmp(w,".rm") == 0) + strcpy(w, "rm"); + else if (strcmp(w,".B") == 0 || strcmp(w,".bf") == 0) + strcpy(w, "bf"); + else if (strcmp(w,".I") == 0 || strcmp(w,".it") == 0) + strcpy(w, "it"); + else { + switch(lastfont) { + case 1: + strcpy (w, "rm"); + thisfont = 1; + break; + case 2: + strcpy (w, "it"); + thisfont = 2; + break; + case 3: + strcpy (w, "bf"); + thisfont = 3; + break; + default: + strcpy (w, "rm"); + thisfont = 1; + break; + } + } + pin += get_arg(pin, ww, 1); + if (ww[0] == EOS) { + pout = strapp(pout,"\\"); + pout = strapp(pout, w); + } + else { + snprintf(tmp,sizeof(tmp),"{\\%s %s",w,ww); + pout = strapp(pout,tmp); + while (1) { + pin += get_arg(pin, ww, 1); + if (ww[0] == EOS) + break; + snprintf(tmp,sizeof(tmp)," %s",ww); + pout = strapp(pout,tmp); + } + pout = strapp(pout, "}"); + } + } + else if (man && (strcmp(w,".BR") == 0 || strcmp(w,".BI") == 0 + || strcmp(w,".IR") == 0 || strcmp(w,".IB") == 0 + || strcmp(w,".RI") == 0 || strcmp(w,".RB") == 0)){ + pout = alternate(pin,pout,w); + pin = skip_line(pin); + *pout++ = '\n'; + } + else if (strcmp(w,".BX") == 0) { + pin += get_arg(pin,ww,1); + snprintf(tmp,sizeof(tmp),"\\fbox{%s}",ww); + pout = strapp(pout,tmp); + } + else if (strcmp(w, ".DA") == 0) { + pin += get_arg(pin, ww, 0); + if (ww[0] != EOS) { + snprintf(tmp, sizeof(tmp), "\\def\\today{%s}%%\n", ww); + pout = strapp(pout, tmp); + } + pout = strapp(pout, "\\centerfoot{\\today}"); + } + else if (strcmp(w, ".DS") == 0) { + /*pout = end_env(pout);*/ + pout = strapp(pout, "\\begin{display}*"); + pin += get_arg(pin, ww, 0); + if (ww[0]) { + snprintf(tmp, sizeof(tmp), "[%s]", ww); + pout = strapp(pout, tmp); + pin += get_arg(pin, ww, 0); + if (ww[0]) { + (void) get_size(ww, &indent); + snprintf(tmp, sizeof(tmp), "[%3.1f%s]", indent.value, indent.units); + pout = strapp(pout, tmp); + } + } + } + else if (strcmp(w,".EH") == 0 || strcmp(w,".EF") == 0 || + strcmp(w,".OH") == 0 || strcmp(w,".OF") == 0) { + if (strcmp(w,".EH") == 0 || strcmp(w,".EF")) + fprintf(stderr, "%s works only in towside style\n", w); + if (strcmp(w,".EH") == 0) + pout = strapp(pout, "\\EvenHeader"); + else if (strcmp(w,".EF") == 0) + pout = strapp(pout, "\\EvenFooter"); + else if (strcmp(w,".OH") == 0) + pout = strapp(pout, "\\OddHeader"); + else if (strcmp(w,".OF") == 0) + pout = strapp(pout, "\\OddFooter"); + pin += skip_white(pin); + pin += getdef(pin, w) - 1; + pin += getdef(pin, ww) - 1; + pin += getdef(pin, tmp); + snprintf(tmp2, sizeof(tmp2), "{%s}{%s}{%s}", w, ww, tmp); + pout = strapp(pout, tmp2); + } + else if (strcmp(w,".EQ") == 0) { + math_mode = 1; + put_brace = 0; + pout = strapp(pout,"$$"); + len = get_arg(pin,eqn_no,0); + if (strcmp(eqn_no,"I") == 0 || strcmp(eqn_no,"L") == 0) { + fprintf(stderr,"lineups are ignored\n"); + pin += len; + len = get_arg(pin,eqn_no,0); + } + if ((strlen(eqn_no)) > 0) + pin += len; + len = get_arg(pin,tmp,0); + if (strcmp(tmp, "I") == 0 || strcmp(tmp, "L") == 0) { + fprintf(stderr,"lineups are ignored\n"); + pin += len; + } + } + else if (strcmp (w, ".ID") == 0) { + pout = end_env(pout); + pout = strapp(pout, "\\begin{display}[I]"); + pin += get_arg(pin, ww, 0); + if (ww[0]) { + (void) get_size(ww, &indent); + snprintf(tmp, sizeof(tmp), "[%3.1f%s]", indent.value, indent.units); + pout = strapp(pout, tmp); + } + *pout++ = '\n'; + pin = skip_line(pin); + } + else if (strcmp (w, ".IP") == 0) { + pin += get_arg(pin, ww, 1); + strcpy(w, ""); + pin += get_arg(pin, w, 0); + pin = skip_line(pin); + if (IP_stat[RSRE] == 0) { + pout = strapp(pout, "\\begin{IPlist}"); + if (w[0]) { + snprintf(tmp, sizeof(tmp), "[%s]", w); + pout = strapp(pout, tmp); + } + pout = strapp(pout, "\n"); + } + snprintf(tmp, sizeof(tmp), "\\IPitem{{%s}}\n", ww); + pout = strapp(pout,tmp); + if (de_arg > 0) mydef[mydef_count].par = 2; + else IP_stat[RSRE] = 1; + } + else if (strcmp(w, ".KE") == 0) { + if (floating) + pout = strapp(pout, "\\end{figure}"); + else { + if (IP_stat[RSRE] > 1) + IP_stat[RSRE]--; + else + pout = end_env(pout); + pout = strapp(pout, "}"); + } + floating = 0; + } + else if (strcmp(w, ".KS") == 0) { + pout = strapp(pout, "{\\par\\nobreak"); + if (IP_stat[RSRE]) + IP_stat[RSRE]++; + } + else if (strcmp(w, ".KF") == 0) { + floating = 1; + pout = strapp(pout,"\\begin{figure}"); + } + else if (strcmp(w, ".NH") == 0) { + pout = end_env(pout); + pin += get_arg(pin, ww, 0); + pin = skip_line(pin); + switch(ww[0]) { + case '1': + pout = strapp(pout, "\\section{"); + break; + case '2': + pout = strapp(pout, "\\subsection{"); + break; + case '3': + pout = strapp(pout, "\\subsubsection{"); + break; + case '4': + pout = strapp(pout, "\\paragraph{"); + break; + case '5': + pout = strapp(pout, "\\subparagraph{"); + break; + default: + pout = strapp(pout, "\\section{"); + break; + } + len = get_line(pin, ww, 0); + while (ww[0] != '.') { + troff_tex (ww, tmp, 0, 1); + pout = strapp(pout, tmp); + pin += len+1; + len = get_line(pin, ww, 0); + } + //fprintf(stderr, "NH:|%s|\n", tmp); + pout = strapp(pout, "}"); + if (strcmp(ww, ".") != 0) + pout = strapp(pout, "\n"); + //fprintf(stderr, "NH:|%10.20s|\n", pin); + } + else if (strcmp(w,".QP") == 0) { + if (de_arg > 0) + mydef[mydef_count].par = 4; + else + QP_stat = 1; + pout = strapp(pout,"\\begin{quotation}"); + } + else if (strcmp(w,".RE") == 0) { + pout = end_env(pout); + RSRE--; + if (RSRE < 0) + fprintf(stderr,".RE with no matching .RS\n"); + if (man) { + snprintf(tmp, sizeof(tmp), "\\ind{%d\\parindent}", RSRE); + pout = strapp(pout,tmp); + } + pin = skip_line(pin); + } + else if (strcmp(w,".RS") == 0) { + RSRE++; + if (man) { + pin += get_arg (pin, ww, 1); + snprintf(tmp, sizeof(tmp), "\\ind{%d\\parindent}", RSRE); + pout = strapp(pout,tmp); + } + pin = skip_line (pin); + } + else if (strcmp(w,".Re") == 0) { + if (ref == 0) + pout = strapp(pout,"\\REF\n"); + ref++; + pin = skip_line(pin); + pin += get_ref(pin,ww); + snprintf(tmp,sizeof(tmp),"\\reference{%s}",ww); + pout = strapp(pout,tmp); + } + else if (man && (strcmp(w,".TP") == 0 || strcmp(w,".HP") == 0)) { + if (IP_stat[RSRE] && TP_stat) { + pout = strapp(pout,"\\end{IPlist}%\n"); + IP_stat[RSRE] = 0; + } + if (QP_stat && TP_stat) { + pout = strapp(pout,"\\end{quotation}%\n"); + QP_stat = 0; + } + pin = skip_line(pin); + pin += get_line(pin,ww,1); + if (TP_stat == 0) { + snprintf(tmp,sizeof(tmp),"\\begin{TPlist}{%s}\n",ww); + pout = strapp(pout,tmp); + } + snprintf(tmp,sizeof(tmp),"\\item[{%s}]",ww); + pout = strapp(pout,tmp); + if (de_arg > 0) + mydef[mydef_count].par = 3; + else + TP_stat = 1; + } + else if (man && (strcmp(w,".TH") == 0)) { + /* expect something like .TH LS 1 "September 4, 1985"*/ + pin += get_allargs (pin, &pw, 1); + if (pw [0] == NULL || pw [1] == NULL) + fprintf (stderr, "Missing argument in troff macro .TH\n"); + else { + for (j = 2; j <= 5; j++) + if (pw [j] == NULL) + break; + for (; j <= 5; j++) + pw[j] = ""; + snprintf(tmp, sizeof(tmp), "\\phead{%s}{%s}{%s}{%s}{%s}", + pw[0], pw[1], pw[2], pw[3], pw[4]); + pout = strapp (pout, tmp); + } + } + else if (man && strcmp (w, ".PN") == 0) { + pin += get_allargs (pin, &pw, 1); + if (pw [0] == NULL) + fprintf (stderr, "Missing argument in troff macro .PN\n"); + else { + snprintf(tmp, sizeof(tmp), "{\\tt{}%s}%s ", + pw [0], pw [1]? pw [1]: ""); + pout = strapp (pout, tmp); + } + } + else if (man && strcmp (w, ".CW") == 0) + pout = strapp (pout, "\\tt{}"); + else if (man && strcmp (w, ".MS") == 0) { + pin += get_allargs (pin, &pw, 1); + if (pw [0] == NULL || pw [1] == NULL) + fprintf (stderr, "Missing arguments in troff macro .MS\n"); + else { + snprintf(tmp, sizeof(tmp), "{\\tt{}%s}(%s)%s ", + pw [0], pw [1], pw [2]? pw [2]: ""); + pout = strapp (pout, tmp); + } + } + else if (man && strcmp (w, ".EX") == 0) { + pin += get_arg (pin, ww, 1); + pin = skip_line (pin); + snprintf(tmp,sizeof(tmp), "\\nofill\\ind{%d\\parindent}\\tt{}", ++EXEE); + pout = strapp(pout,tmp); + } + else if (man && strcmp (w, ".EE") == 0) { + if (EXEE == 0) + fprintf(stderr,".EE with no matching .EX\n"); + else { + --EXEE; + pout = strapp(pout, "\\fill "); + } + } + else if (man && strcmp (w, ".NT") == 0) { + ++NTNE; + pin += get_allargs (pin, &pw, 1); + if (pw [0] == NULL) + pout = strapp (pout, "\\beginnotec{NOTE}"); + else { + if (strcmp (pw [0], "C") == 0) { + if (pw [1]) { + snprintf (tmp, sizeof(tmp), "\\beginnotec{%s}", pw [1]); + pout = strapp (pout, tmp); + } else { + pout = strapp (pout, "\\beginnotec{NOTE}"); + } + } + else { + snprintf(tmp, sizeof(tmp), "\\beginnote{%s}", pw [0]); + pout = strapp (pout, tmp); + } + } + } + else if (man && strcmp (w, ".NE") == 0) { + if (NTNE == 0) + fprintf(stderr,".NE with no matching .NT\n"); + else { + --NTNE; + pout = strapp(pout, "\n\\end{quote}\n"); + } + } + else if (strcmp(w,".TS") == 0) + { + fprintf(stderr, "I am not very good at tables.\n" + "I can only do very simple ones. " + "You may need to check what I've done.\n"); + pin = skip_line(pin); + pout = do_table(pin,pout,&offset); + pin += offset; + offset = 0; /* reset */ + } + /* Now search for commands that start with small letters */ + else if (strcmp(w,".TE") == 0) { + fprintf(stderr, + "Oops! I goofed. I told you I am not very good at tables.\n" + "I have encountered a table end but I am not in table mode.\n"); + }/* + else if (strcmp(w, ".ad") == 0) { + pin += get_arg(pin, w, 0); + pin += skip_white(pin); + snprintf(tmp, sizeof(tmp), "\\adjust{%s}\n", w); + pout = strapp(pout,tmp); + }*/ + else if (strcmp(w, ".de") == 0) { + de_arg = 1; + if (mydef_count >= MAXDEF) { + fprintf(stderr, + "Too many .de's. MAXDEF=%d\n", MAXDEF); + exit(-1); + } + pin += skip_white(pin); + pin += get_defword(pin, w, &illegal); + pin += skip_white(pin); + pin += get_mydef(pin, ww); + mydef[mydef_count].arg_no = de_arg; + if (illegal) { + mydef[mydef_count].illegal = 1; + fprintf(stderr, + "illegal TeX macro, %s, replacing it\n",w); + mydef[mydef_count].replace = strdup(ww); + } + else { + mydef[mydef_count].illegal = 0; + snprintf(tmp,sizeof(tmp),"\\def\\%s",w); + pout = strapp(pout,tmp); + for (j=1; j<de_arg; j++) { + snprintf(tmp,sizeof(tmp),"#%d",j); + pout = strapp(pout,tmp); + } + snprintf(tmp,sizeof(tmp),"{%s}\n",ww); + pout = strapp(pout,tmp); + } + p = (char *)malloc((unsigned)(strlen(w)+2)); + sprintf(p,".%s",w); + mydef[mydef_count++].def_macro = p; + pin = skip_line(pin); + de_arg = 0; + } + else if (strcmp(w, ".ds") == 0) { + pin += get_arg(pin, w, 0); + pin += skip_white(pin); + pin += get_line(pin, ww, 1); + if ((p = strchr(ww, '%')) != NULL) { + *(p-1) = EOS; + p++; + snprintf(tmp, sizeof(tmp), "%s\\rm\\thepage %s", ww, p); + strcpy(ww, tmp); + } + if (strcmp(w, "LH") == 0) { + snprintf(tmp, sizeof(tmp),"\\lefthead{%s}", ww); + pout = strapp(pout,tmp); + } + else if (strcmp(w, "CH") == 0) { + snprintf(tmp, sizeof(tmp),"\\centerthead{%s}", ww); + pout = strapp(pout,tmp); + } + else if (strcmp(w, "RH") == 0) { + snprintf(tmp, sizeof(tmp),"\\righthead{%s}", ww); + pout = strapp(pout,tmp); + } + else if (strcmp(w, "LF") == 0) { + snprintf(tmp, sizeof(tmp),"\\leftfoot{%s}", ww); + pout = strapp(pout,tmp); + } + else if (strcmp(w, "CF") == 0) { + snprintf(tmp, sizeof(tmp),"\\centerfoot{%s}", ww); + pout = strapp(pout,tmp); + } + else if (strcmp(w, "RF") == 0) { + snprintf(tmp, sizeof(tmp),"\\rightfoot{%s}", ww); + pout = strapp(pout,tmp); + } + else { + fprintf(stderr, "Define troff string '%s'\n", w); + snprintf(tmp, sizeof(tmp), "\\defTroffString{%s}{%s}", w, ww); + pout = strapp(pout,tmp); + } + } + else if (strcmp(w, ".ft") == 0) { + pin += get_arg(pin, ww, 0); + if (ww[0] == EOS) c1 = 'P'; else c1 = ww[0]; + switch(c1) { + case 'R': + lastfont = thisfont; + thisfont = 1; + pout = strapp(pout, "\\rm%"); + break; + case 'I': + lastfont = thisfont; + thisfont = 2; + pout = strapp(pout, "\\it%"); + break; + case 'B': + lastfont = thisfont; + thisfont = 3; + pout = strapp(pout, "\\bf%"); + break; + case 'P': + default: + switch(lastfont) { + case 1: + pout = strapp(pout,"\\rm%"); + thisfont = 1; + break; + case 2: + pout = strapp(pout,"\\it%"); + thisfont = 2; + break; + case 3: + pout = strapp(pout,"\\bf%"); + thisfont = 3; + break; + default: + pout = strapp(pout,"\\rm%"); + thisfont = 1; + break; + } + break; + } + } + else if (strcmp(w,".sp") == 0) { + pin += get_arg(pin,ww,0); + (void) get_size(ww,&space); + snprintf(tmp,sizeof(tmp),"\\par\\vspace{%3.1f%s}",space.value,space.units); + pout = strapp(pout,tmp); + } + else if (strcmp(w,".in") == 0) { + pin += get_arg(pin,ww,0); + (void) get_size(ww,&indent); + snprintf(tmp,sizeof(tmp),"\\ind{%3.1f%s}",indent.value,indent.units); + pout = strapp(pout, tmp); + } + else if (strcmp(w,".ls") == 0) { + pin += get_arg(pin,ww,0); + (void) get_size(ww,&linespacing); + snprintf(tmp,sizeof(tmp),"\\baselineskip=%3.1f%s",linespacing.value, + linespacing.units); + pout = strapp(pout,tmp); + } + else if (strcmp(w,".so") == 0) { + pin += get_arg(pin,ww,0); + snprintf(tmp,sizeof(tmp),"\\input %s",ww); + pout = strapp(pout,tmp); + } + else if (strcmp(w, ".sp") == 0) { + pin += get_arg(pin, ww, 0); + (void) get_size(ww, &space); + snprintf(tmp, sizeof(tmp), "\\par\\noindent\\vspace{%3.1f%s}%%", space.value, space.units); + pout = strapp(pout,tmp); + } + else if (strcmp(w,".ti") == 0) { + pin += get_arg(pin,ww,0); + tmpind.value = indent.value; + strcpy(tmpind.units,indent.units); + (void) get_size(ww,&tmpind); + snprintf(tmp,sizeof(tmp),"\\tmpind{%3.1f%s}", tmpind.value,tmpind.units); + pout = strapp(pout,tmp); + } + else if (strcmp(w,".vs") == 0) { + pin += get_arg(pin,ww,0); + (void) get_size(ww,&vspace); + snprintf(tmp,sizeof(tmp),"\\par\\vspace{%3.1f%s}", vspace.value,vspace.units); + pout = strapp(pout,tmp); + } + else if (strcmp(w,".nr") == 0) { + pin += get_arg(pin, ww, 0); + if (strcmp(ww, "VS") == 0) { + pin += get_arg(pin, tmp, 0); + (void) get_size(tmp, &linespacing); + snprintf(tmp, sizeof(tmp), "\\defTroffNr{%s}{%3.1f%s}\n", ww, + linespacing.value, linespacing.units); + pout = strapp(pout,tmp); + snprintf(tmp, sizeof(tmp), "\\baselineskip=%3.1f%s\n", linespacing.value, + linespacing.units); + pout = strapp(pout,tmp); + } + else + fprintf(stderr, "I do not understand .nr %s yet.\n", ww); + pin = skip_line(pin); + } + /* check if it is a member of a group */ + else if (mydef_count > 0 && (i=is_mydef(w)) >= 0) { + if (mydef[i].par > 0) { + if (de_arg > 0) + mydef[mydef_count].par = mydef[i].par; + else { + pout = end_env(pout); + pout = strapp(pout,"\n"); + } + } + if (mydef[i].illegal) + pout = strapp(pout,mydef[i].replace); + else { + w[0] = '\\'; /* replace dot by backslash */ + pout = strapp(pout,w); + } + for (j=1; j <mydef[i].arg_no; j++) { + pin += get_arg(pin,ww,1); + snprintf(tmp,sizeof(tmp),"{%s}",ww); + pout = strapp(pout,tmp); + } + if (de_arg == 0) + envoke_stat(mydef[i].par); + } + else if ((i=is_troff_mac(w, ww, &arg, &par)) >= 0) { + if (par > 0) { + if (de_arg > 0) + mydef[mydef_count].par = par; + else + pout = end_env(pout); + } + pout = strapp(pout,ww); + if (ww[0] == EOS) + pin = skip_line(pin); + if (ww[0] != EOS && arg == 0) { + pin = skip_line(pin); + *pout++ = '\n'; + } + if (arg > 0) { + if (arg == 1) { + pin += skip_white(pin); + if (*(pin-1) == '\n') + ww[0] = EOS; + else + pin += get_string(pin,ww,1); + } + else { + if (isupper(w[1])) { + pin = skip_line(pin); + pin += get_multi_line(pin, ww); + } + else { + pin += get_arg(pin, tmp, 0); + pin = skip_line(pin); + if (tmp[0] == EOS) + N = 1; + else + N = atoi(tmp); + pin += get_N_lines(pin, ww, N); + } + } + snprintf(tmp2, sizeof(tmp2), "{%s}", ww); + pout = strapp(pout,tmp2); + } + } + /* if none of the above commands matched, it is either + an illegal macro or an unknown command */ + else { + len = get_till_space(pin,ww); + snprintf(tmp,sizeof(tmp),"%s%s",w,ww); + if (mydef_count > 0 && (i=is_mydef(tmp)) >= 0) { + pin += len; + if (mydef[i].par > 0) { + if (de_arg > 0) + mydef[mydef_count].par = mydef[i].par; + else { + pout = end_env(pout); + pout = strapp(pout,"\n"); + } + } + pout = strapp(pout,mydef[i].replace); + for (j=1; j <mydef[i].arg_no; j++) { + pin += get_arg(pin,ww,1); + snprintf(tmp,sizeof(tmp),"{%s}",ww); + pout = strapp(pout,tmp); + } + if (de_arg == 0) + envoke_stat(mydef[i].par); + } + else { + fprintf(stderr, "I cannot translate troff macro %s\n",w); + pin += get_line(pin,ww,0); + pout = strapp(pout,"%"); + pout = strapp(pout,w); + pout = strapp(pout,ww); + if (*pin == EOS) + *pout++ = '\n'; + } + } + } + + /* some manuals have commented lines beginning with ''' */ + else if (c2=='\'' && !mid && (c1=='\n' || c1==EOS || first_word)) { + if (*pin == '\'') { + pin++; + if (*pin == '\'') { + pin++; + pout = strapp(pout,"%"); + } + else + pout = strapp(pout,"''"); + } + else + pout = strapp(pout,"'"); + } + + /* See if it is one of these symbols */ + + else if (strcmp(w,"#") == 0 || strcmp(w,"&") == 0 || + strcmp(w,"{") == 0 || strcmp(w,"}") == 0 || + strcmp(w,"%") == 0 || strcmp(w,"_") == 0 || + strcmp(w,"~") == 0 || strcmp(w,"^") == 0 ) { + pout = strapp(pout,"\\"); + pout = strapp(pout,w); + if (strcmp(w,"~") == 0 || strcmp(w,"^") == 0) + pout = strapp(pout,"{}"); + } + + else if (strcmp(w,">") == 0 || strcmp(w,"<") == 0 + || strcmp(w,"|") == 0) { + snprintf(tmp,sizeof(tmp),"$%s$",w); + pout = strapp(pout,tmp); + } + + /* check for backslash commands */ + + else if (strcmp(w, "\\") == 0) { + switch (*pin) { + case ' ': + case '\t': + case '\n': + pout = strapp(pout,"\\"); + *pout++ = *pin++; + break; + case ',': + pin++; + pout = strapp(pout, "{}"); + break; + case '/': + pin++; + pout = strapp(pout, "\\thinspace "); + break; + case EOS: + break; + case '-': + pin++; + pout = strapp(pout,"--"); + break; + case '~': + case '^': + pin++; + pout = strapp(pout,"\\/"); + break; + case '0': + pin++; + pout = strapp(pout,"\\ "); + break; + case 'e': + pin++; + pout = strapp(pout,"\\textbackslash "); + break; + case '$': + pin++; + if (rec && de_arg > 0) { + de_arg++; + *pout++ = '#'; + } else + pout = strapp(pout, "$"); + break; + case '\\': + pin++; + if (*pin == '$' && de_arg > 0) { + pin++; + de_arg++; + *pout++ = '#'; + } + else + pout = strapp(pout,"\\textbackslash "); + break; + case '`': + case '\'': + break; /* do nothing */ + case '"': + pin++; + if (rec == 1) + pout = strapp(pout, "\""); + else { + pin += get_line(pin, ww, 0); + pout = strapp(pout, "%"); + pout = strapp(pout, ww); + } + break; + case '|': + pin++; + pout = strapp(pout, "\\,"); + break; + case '&': + pin++; + pout = strapp(pout, "{}"); + break; + case '%': + pin++; + pout = strapp(pout,"\\-"); + break; + case '(': + pin++; + w[0] = *pin++; w[1] = *pin++; w[2] = EOS; + if (is_special(w, ww) > -1) { + if (ww[0] == '\\') + snprintf(tmp, sizeof(tmp), "\\hbox{%s}", ww); + else + strcpy(tmp, ww); + pout = strapp(pout, tmp); + } + else if (w[0] == '*') + *pout++ = w[1]; + else + fprintf(stderr, + "I am not prepared to handle \\(%s\n", w); + break; + case '[': /* groff string definition */ + pin++; + len = get_line(pin, tmp, 0); + if ((p=strchr(tmp, ']')) != NULL) { + len = p - tmp; + *p = EOS; + if (len == 2 && is_special(tmp, ww) > -1) { + snprintf(tmp2, sizeof(tmp2), "\\hbox{%s}", ww); + pout = strapp(pout, tmp2); + } else { + snprintf(tmp2, sizeof(tmp2), "\\useTroffString{%s}", tmp); + fprintf(stderr, "Please define TroffString@%s\n", tmp); + pout = strapp(pout, tmp2); + } + pin += (len+1); + } + break; + case 's': + pin +=3; + break; + case '*': + c1 = *++pin; + pin++; + switch (c1) { + case ':': + pout = strapp(pout,"\\\""); + break; + case 'C': + pout = strapp(pout,"\\v"); + break; + case ',': + pout = strapp(pout,"\\c"); + break; + case '`': + case '\'': + case '^': + case '~': + snprintf(tmp, sizeof(tmp), "\\%c", c1); + pout = strapp(pout, tmp); + break; + case '(': + pout = strapp(pout, "\\useTroffString"); + ww[0] = *pin++; ww[1] = *pin++; ww[2] = EOS; + fprintf(stderr, "Check definition of TroffString@%s\n", ww); + break; + case '[': /*GNU troff string reference*/ + len = get_line(pin, tmp, 0); + if ((p=strchr(tmp, ']')) != NULL) { + len = p - tmp; + *p = EOS; + //fprintf(stderr, "Found: \\[%s] len:%d\n", tmp, len); + if (len == 2 && is_special(tmp, ww) > -1) { + snprintf(tmp2, sizeof(tmp2), "\\hbox{%s}", ww); + pout = strapp(pout, tmp2); + } else { + snprintf(tmp2, sizeof(tmp2), "\\useTroffString{%s}", tmp); + fprintf(stderr, "Please define TroffString@%s\n", tmp); + pout = strapp(pout, tmp2); + } + pin += (len+1); + } + break; + default: + fprintf(stderr, "TeX should understand \\%c\n", c1); + snprintf(tmp, sizeof(tmp), "\\%c", c1); + pout = strapp(pout, tmp); + break; + } + if (c1 == '(') { + snprintf(tmp, sizeof(tmp), "{%s}", ww); + pout = strapp(pout, tmp); + } else if (c1 != '[') { + c1 = *pin++; + snprintf(tmp,sizeof(tmp),"{%c}",c1); + pout = strapp(pout,tmp); + } + break; + case 'f': + c1 = *++pin; + pin++; + switch (c1) { + case '1': + case 'R': + lastfont = thisfont; + thisfont = 1; + if (isspace (*pin)) { + *pout++ = ' '; + pin++; + } + pout = strapp(pout,"%\n\\rm "); + break; + case '2': + case 'I': + lastfont = thisfont; + thisfont = 2; + if (isspace (*pin)) { + *pout++ = ' '; + pin++; + } + pout = strapp(pout,"%\n\\it "); + break; + case '3': + case 'B': + lastfont = thisfont; + thisfont = 3; + if (*pin == ' ' || *pin == '\t' || + *pin == '\n' || *pin == '\f') { + *pout++ = ' '; pin++; + } + pout = strapp(pout,"%\n\\bf "); + break; + case 'P': + /* preserve white space - from Nelson Beebe */ + if (isspace (*pin)) { + *pout++ = ' '; + pin++; + } + switch(lastfont) { + case 1: + pout = strapp(pout,"\\rm%\n"); + thisfont = 1; + break; + case 2: + pout = strapp(pout,"\\it%\n"); + thisfont = 2; + break; + case 3: + pout = strapp(pout,"\\bf%\n"); + thisfont = 3; + break; + default: + pout = strapp(pout,"\\rm%\n"); + thisfont = 1; + break; + } + break; + case '(': + ww[0] = *pin++; ww[1] = *pin++; ww[2] = EOS; + snprintf(tmp, sizeof(tmp), "\\useTroffFont{%s}", ww); + pout = strapp(pout, tmp); + fprintf(stderr, "Please define '\\TroffFont@%s' command\n", ww); + break; + default: + fprintf(stderr, "I do not understand \\f%c yet\n",c1); + break; + } + break; + case 'n': + c1 = *++pin; + pin++; + if (c1 == '(') { + ww[0] = *pin++; ww[1] = *pin++; ww[2] = EOS; + snprintf(tmp, sizeof(tmp), "\\useTroffNr[%s]", ww); + fprintf(stderr, "Please define TroffRegister@%s\n", tmp); + pout = strapp(pout, tmp); + } else if (c1 == '[') { + len = get_line(pin, tmp, 0); + if ((p=strchr(tmp, ']')) != NULL) { + len = p - tmp; + *p = EOS; + snprintf(tmp2, sizeof(tmp2), "\\useTroffNr{%s}", tmp); + fprintf(stderr, "Please define TroffRegister@%s\n", tmp); + pout = strapp(pout, tmp2); + pin += (len+1); + //fprintf(stderr, "Found: \\n[%s] len:%d, next:%c\n", tmp, len,*pin); + } + } + break; + default: + fprintf(stderr,"I am not prepared to handle \\%c\n",*pin++); + break; + } + } + + /* if non of the above checks, its a dull word; copy it */ + + else + pout = strapp(pout,w); + *pout = EOS; + ww[0] = EOS; + tmp[0] = EOS; + tmp2[0] = EOS; + if (!no_word) + first_word = 0; + } + /* if file end, close opened environments and delimitters */ + if (rec == 0) { + pout = end_env(pout); + } + + *pout = EOS; +} diff --git a/support/tr2latex/tr2latex.c b/support/tr2latex/tr2latex.c new file mode 100644 index 0000000000..59202b574c --- /dev/null +++ b/support/tr2latex/tr2latex.c @@ -0,0 +1,222 @@ +/* +** tr2latex - troff to LaTeX converter +** COPYRIGHT (C) 1987 Kamal Al-Yahya, 1991,1992 Christian Engel +** +** Module: tr2latex.c +** +** This module contains the main function inititating the translation +** and supporting the Usage. +*/ + +#define MAIN + +#include "getopt.h" +#include "setups.h" +#include "protos.h" +#include <assert.h> + +const char *version = "2.6"; + +int man, /* option -m: manual page */ + fontsize, /* option -9/-10/-11/-12: font size */ + twoside, /* option -t: twoside */ + piped_in; + +char *document = "article"; /* document type, see also -s option */ + +FILE *out_file; /* in case they can't use UN*X redirecting or piping */ + +char *prgname; +char inbuf[MAXLEN], + outbuf[MAXLEN]; + +static void usage (int exitcode) +{ + printf ("tr2latex (c) 1986/1987 Kamal Al-Yahya, 1991 C. Engel, 2008..2016 Dirk Jagdmann\n" + "Version %s\n", + version); + printf ("tr2latex - troff to LaTeX converter\n" + "SYNTAX: tr2latex [-m] [-t] [-<n>] [-s <style>] [-o <outfile>] [-d] [-b] [<file>...]\n" + "options: -m for manual\n" + " -t twoside page style\n" + " -<n> a number n gives the font size (default is 12pt\n" + " for man, 11pt otherwise)\n" + " -s <style> use documentstyle <style> (default is article)\n" + " -o <outfile> send output to <outfile> (default is stdout)\n" + " -d debug output\n" + " -b LaTeX body, don't print declarations\n" + ); + + exit (exitcode); +} + +static void process (FILE *in_file, char *f_name, char *pin, char *pout) +{ + static char sep[] = "--------------------------------------------------"; + + const size_t r = fread(pin, 1, MAXLEN, in_file); + if (r == MAXLEN) + { + fprintf(stderr, "Sorry: document is too large, you have to increase MAXLEN\n"); + exit(EXIT_FAILURE); + } + assert(r < MAXLEN); + pin[r] = EOS; + + fprintf (out_file, "%%%s\n%% start of input file: %s\n%%\n", sep, f_name); + troff_tex (pin, pout, 0, 0); + fputs (pout, out_file); + fprintf (out_file, "%%\n%% end of input file: %s\n%%%s\n", f_name, sep); +} + +int main (int argc, char *argv[]) +{ + char *pin = inbuf, + *pout = outbuf; + FILE *in_file; + time_t timeval; + int c, only_body=0; + + prgname = argv [0]; + out_file = stdout; /* default output */ + + /* process option flags */ + while((c=getopt(argc, argv, "0123456789bhmtds:o:")) != EOF) + switch(c) + { + default: + case '?': + case 'h': usage (EXIT_SUCCESS); + + case 'b': only_body=1; break; + case 'm': man = 1; break; + case 't': twoside = 1; break; + case 's': document = optarg; break; + case 'o': + if ((out_file = fopen(optarg, "w")) == NULL) + { + fprintf(stderr, "%s: can't open %s\n", prgname, optarg); + usage (EXIT_FAILURE); + } + break; + case 'd': debug_o = 1; break; + + case '0': fontsize = 10; break; + case '1': fontsize = 11; break; + case '2': fontsize = 12; break; + case '3': fontsize = 13; break; + case '4': fontsize = 14; break; + case '5': fontsize = 15; break; + case '6': fontsize = 16; break; + case '7': fontsize = 17; break; + case '8': fontsize = 18; break; + case '9': fontsize = 9; break; + } + + /* initialize spacing and indentation parameters */ + strcpy(linespacing.def_units,"\\normalbaselineskip"); + strcpy(linespacing.old_units,"\\normalbaselineskip"); + strcpy(indent.def_units,"em"); + strcpy(indent.old_units,"em"); + strcpy(tmpind.def_units,"em"); + strcpy(tmpind.old_units,"em"); + strcpy(space.def_units,"\\baselineskip"); + strcpy(space.old_units,"\\baselineskip"); + strcpy(vspace.def_units,"pt"); + strcpy(vspace.old_units,"pt"); + linespacing.value = 1.; + linespacing.old_value = 1.; + indent.value = 0.; + indent.old_value = 0.; + tmpind.value = 0.; + tmpind.old_value = 0.; + space.value = 1.; + space.old_value = 1.; + vspace.value = 1.; + vspace.old_value = 1.; + linespacing.def_value = 0; + indent.def_value = 0; + tmpind.def_value = 0; + space.def_value = 1; + vspace.def_value = 1; + + math_mode = 0; /* start with non-math mode */ + de_arg = 0; /* not a .de argument */ + + /* start of translated document */ + + timeval = time(0); + fprintf (out_file, + "%% -*-LaTeX-*-\n" + "%% Converted automatically from troff to LaTeX\n" + "%% by tr2latex %s\n" + "%% on %s" + "%% tr2latex was written by Kamal Al-Yahya at Stanford University <Kamal%%Hanauma@SU-SCORE.ARPA>\n" + "%% and substantially enhanced by Christian Engel at RWTH Aachen <krischan@informatik.rwth-aachen.de>\n" + "%% it is currently maintained by Dirk Jagdmann <doj@cubic.org>\n" + "%% visit http://www.ctan.org/pkg/tr2latex for details.\n" + "%%\n" + "%% troff input file%s:%s", + version, + ctime(&timeval), + argc>2?"s":"", + argc==1?" <stdin>":""); +#if 0 + for (argi = 1; argi < argc; argi++) + { + if (strcmp (argv [argi], "-") == 0) + fprintf (out_file, " <stdin>"); + else + fprintf (out_file, " %s", argv[argi]); + } +#endif + + if(!only_body) + { + /* document style and options */ + fprintf (out_file,"\n\n\\documentclass["); + if (fontsize == 0 && !man) + fontsize = 11; + if (fontsize != 0) + fprintf (out_file,"%dpt", fontsize); + if (twoside) + fputs (",twoside", out_file); + fprintf (out_file,"]{%s}", document); + fprintf (out_file,"\n\n\\usepackage{%s}", man? "troffman": "troffms"); + fprintf (out_file,"\n\\usepackage{textcomp}\n"); + fprintf (out_file,"\n\n\\begin{document}\n"); + } + + if (optind == argc) + process (stdin, "<stdin>", pin, pout); + else + { + for (; optind!=argc; ++optind) + { + if (strcmp (argv[optind], "-") == 0) + process (stdin, "<stdin>", pin, pout); + else if ((in_file = fopen(argv[optind],"r")) == NULL) + fprintf(stderr,"%s: Cannot open input file `%s'\n", + prgname,argv[optind]); + else + { + process (in_file, argv[optind], pin, pout); + fclose(in_file); + } + } + } + + if(!only_body) + { + /* close translated document */ + fputs("\\end{document}\n",out_file); + } + + exit(EXIT_SUCCESS); +} + +void errexit (int exitcode) +{ + fprintf (stderr, "%s: Error #%03d ", prgname, exitcode); + exit (exitcode); +} diff --git a/support/tr2latex/tr2latex.man b/support/tr2latex/tr2latex.man new file mode 100644 index 0000000000..814dcf411c --- /dev/null +++ b/support/tr2latex/tr2latex.man @@ -0,0 +1,167 @@ +.TH "TR2TEX" "1" "25 August 2008" "" "" +.SH "NAME" +tr2latex \- convert a document from troff to LaTeX +.SH "SYNOPSIS" +tr2latex +[\fB\-m\fR] +[\fB\-t\fR] +[\fB\-n\fR] +[\fB\-b\fR] +[\fB\-s style\fR] +[\fB\-o outfile\fR] +filename ... +.SH "DESCRIPTION" +.B Tr2latex +converts a document typeset in +.B troff +to a +.B LaTeX +format. +It is intended to do the first pass of the conversion. The user +should then finish up the rest of the conversion and customize the +converted manuscript to his/her liking. +It can also serve as a tutor for those who want to convert from +troff to LaTeX. +.PP +Most of the converted document will be in LaTeX +but some of it may +be in plain +.B TeX. +It will also use some macros in +.B troffms.sty +or +.B troffman.sty +which are included in the package and must be available to the document +when processed with LaTeX. +.PP +If there is more than one input file, they will all be converted into +one LaTeX document. +.PP +.B Tr2latex +understands most of the +.B \-ms +and +.B \-man +macros and +.B eqn +preprocessor symbols. It also understands several plain +.B troff +commands. Few +.B tbl +preprocessor commands are understood to help convert very simple tables. +.PP +When converting manuals, use the +.B \-m +flag. Otherwise +.B tr2latex +assumes to translate a +.B \-me +input file. +.PP +If a troff command cannot be converted, the line that contain that +command will be commented out. +.PP +NOTE: if you have +.B eqn +symbols, you must have the in\-line mathematics delimiter defined by +.B delim +in the file you are converting. If it is defined in another +setup file, that setup file has to be concatenated with the +file to be converted, otherwise +.B tr2latex +will regard the in\-line math as ordinary text. +.SH "OPTIONS" +.TP 12 +.B \-m +Convert manual pages. This makes +.B tr2latex +understand most of the +.B \-man +macros. It uses the style file +.BI troffman.sty . +.TP +.B \-t +Produce twoside page style. +.TP +.B \-\fIn\fP +Use a font size of +.I R n pt. +The default font size is 12pt for +.B \-man +and 11pt otherwise. +.TP +.B "\-s \fIstyle\fP" +Use the style file +.I style +instead of the default +.BR article.sty . +.TP +.B "\-o \fIoutfile\fP" +Write output to file +.I R outfile . +.TP +\fB\-b\fR +print only the LaTeX body. Usefull when converting manpages which are included in a larger document. +.SH "BUGS" +Many of these bugs are harmless. Most of them cause local errors +that can be fixed in the converted manuscript. +.PP +\- Some macros and macro arguments are not recognized. +.PP +\- Commands that are not separated from their argument by a space are +not properly parsed (e.g .sp3i). +.PP +\- When some operators (notably over, sub and sup) are renamed (via define), +then they are encountered in the text, +.B tr2latex +will treat them as +ordinary macros and will not apply their rules. +.PP +\- rpile, lpile and cpile are treated the same as cpile. +.PP +\- rcol, lcol are treated the same as ccol. +.PP +\- Math\-mode size, gsize, fat, and gfont are ignored. +.PP +\- lineup and mark are ignored. The rules are so different. +.PP +\- Some troff commands are translated to commands that require +delimiters that have to be explicitly put. Since they are +sometimes not put in troff, they can create problems. +Example: .nf not closed by .fi . +.PP +\- When local motions are converted to \\raise or \\lower, an \\hbox +is needed, which has to be put manually after the conversion. +.PP +\- 'a sub i sub j' is converted to 'a_i_j' which TeX +parses as 'a_i{}_j}' with a complaint that it is vague. 'a sub {i sub j}' +is parsed correctly and converted to 'a_{i_j}'. +.PP +\- Line spacing is not changed within a paragraph in TeX +(which is a bad practice anyway). +TeX uses the last line spacing in effect in that paragraph. +.SH "TODO" +.TP +Access registers via +\fB.nr\fR +command. +.TP +handling of tables +.TP +handling of tabs +.TP +\fB.bd\fR +.TP +\fB.pl\fR +.TP +\fB.ps\fR +.TP +\fB.ds\fR +.SH "FILES" +$(TEXLIB)/macros/troffman.sty +.br +$(TEXLIB)/macros/troffms.sty +.SH "AUTHOR" +Kamal Al\-Yahya, Stanford University +.br +Christian Engel, Aachen University of Technology diff --git a/support/tr2latex/troffman.sty b/support/tr2latex/troffman.sty new file mode 100644 index 0000000000..1c8841ef5b --- /dev/null +++ b/support/tr2latex/troffman.sty @@ -0,0 +1,115 @@ +% -*-LaTeX-*- +% TROFFMAN.STY for tr2latex - troff to latex translator +% These macros are intended to be referenced by a LaTeX +% \documentstyle[troffman,twoside]{article} +% command. You can insert an 11pt or 12pt option if you like larger +% type--sizes set here are computed from the LaTeX point size setting. +% Size values have been chosen to closely match Unix manual page +% documents, which are actually too wide and too high for good +% typographic taste and readability. +% I would very much want better macros for the headers and footers. +% Please pass your suggestions to me. -Christian +% +\typeout{TROFFMAN.STY for tr2latex version Revision: 2.2 by Christian_Engel} + +\hbadness=10000 % do not want underfull box messages--there are + % usually lots in man pages +\hfuzz=\maxdimen % no overfull box messages either +\voffset=-0.8in % man pages start high on page +\textheight=9in % and are long +\textwidth=6.5in % troff man pages have very wide text +\parindent=0pt +\oddsidemargin=.0in +\evensidemargin=.0in +\newdimen\singlespacing +\singlespacing=10pt % LaTeX has (10+\@ptsize)pt +\addtolength{\singlespacing}{\@ptsize pt} % get size from \documentstyle[??pt]{} + +% Use conventional typesetting baselineskip spacing for 10pt type +\normalbaselineskip=1.2\singlespacing +\newlength{\parmargin} % whole paragraphs indented this much on man pages +\parskip=1ex +\parmargin=3\normalbaselineskip +\baselineskip=\normalbaselineskip + +\def\empty{} + +% page heading/footing +\newcommand{\phead}[5]{% + \renewcommand{\@oddhead}{%\@setpar{\hangindent=0pt\hangafter=0\@@par} + {\makebox[0.33\textwidth][l]{#1(#2)}\makebox[0.33\textwidth]{#5}\makebox[0.33\textwidth][r]{#1(#2)}}}% + \renewcommand{\@evenhead}{%\@setpar{\hangindent=0pt\hangafter=0\@@par} + {\makebox[0.33\textwidth][l]{#1(#2)}\makebox[0.33\textwidth]{#5}\makebox[0.33\textwidth][r]{#1(#2)}}}% + \renewcommand{\@oddfoot}{%\@setpar{\hangindent=0pt\hangafter=0\@@par} + {\makebox[0.33\textwidth][l]{#4}\makebox[0.33\textwidth]{\thepage}\makebox[0.33\textwidth][r]{#3}}}% + \renewcommand{\@evenfoot}{%\@setpar{\hangindent=0pt\hangafter=0\@@par} + {\makebox[0.33\textwidth][l]{#4}\makebox[0.33\textwidth]{\thepage}\makebox[0.33\textwidth][r]{#3}}}% +} + +% multi-line left-justified subheading +\def\shead#1{ + \par % force out previous paragraph with its \hangindent values + \@setpar{\hangindent=0pt\hangafter=0\@@par} + \typeout{[#1]} % maybe temporary, but nice for progress report + \subsubsection*{#1} + \@setpar{\hangindent=\parmargin\hangafter=0\@@par} +} + +\def\under{\underline} +\def\dotdot{\ddot} +\def\nwl{\hfill\break} % similar to LaTex's \newline but does not + % complain if there is no line to break +\def\ind#1{\par\everypar{\hangindent=#1\hangafter=0\hskip-\parindent}} +\def\tmpind#1{\par\hskip#1} +\newenvironment{SEPcntr}{\begin{center}}{\end{center}} +\def\cntr#1{\begin{SEPcntr} #1 \end{SEPcntr}} +% displayed text, indented, justification off +\def\displaybegin{\par\begingroup\medskip\narrower\narrower\noindent + \obeylines\obeyspaces} +\def\displayend{\endgroup\smallskip\noindent} +% fill and nofill +\def\nofill{\par\begingroup\noindent\obeylines\parskip=0ex + \frenchspacing\@vobeyspaces\linepenalty10000} +{\catcode`\ =\active\gdef\@vobeyspaces{\catcode`\ \active \let \@xobeysp}} +\def\@xobeysp{\leavevmode{} } +\def\fill{\endgroup\noindent} + +\def\beginnotec#1{\par\medskip\centerline{#1}\vskip-2ex\nopagebreak[4] +\begin{quote}\advance\leftskip by \parmargin} +\def\beginnote#1{\par\medskip#1\vskip-2ex\nopagebreak[4] +\begin{quote}\advance\leftskip by \parmargin} +\def\endnote{\end{\quote}} + +% define a boxing macro +\def\boxit#1{\vbox{\hrule\hbox{\vrule\kern10pt\vbox{\medskip\kern5pt#1\bigskip +\kern5pt}\kern10pt\vrule}\hrule}} + +% try this IPlist environment +\newcommand{\deflabel}[1]{#1\hfill} +\newenvironment{IPlist}% +{\par\vspace{-1ex}\begin{list}{}% +{\setlength{\itemsep}{\parsep}% +\setlength{\labelwidth}{\parmargin}% +\addtolength{\leftmargin}{2em}% +\addtolength{\leftmargin}{\labelwidth}% +\addtolength{\leftmargin}{\labelsep}% +\renewcommand{\makelabel}{\deflabel}}}% +{\end{list}} + +\newlength{\IPitemlength} +\newcommand{\IPitem}[1]{\item[#1] +\settowidth{\IPitemlength}{#1} +\ifdim\IPitemlength>\parmargin \nwl \fi +} + +% try this TPlist environment +\newcommand{\TPlistlabel}[1]{\mbox{#1}\hfil} +\newenvironment{TPlist}[1]{ +\begin{list}{} + { + \let\makelabel\TPlistlabel + \settowidth{\labelwidth}{#1mm} + \setlength{\leftmargin}{\parmargin} % all paragraphs have this much + \addtolength{\leftmargin}{\labelwidth} % space for label + } + }{\end{list}} diff --git a/support/tr2latex/troffms.sty b/support/tr2latex/troffms.sty new file mode 100644 index 0000000000..b153e97e23 --- /dev/null +++ b/support/tr2latex/troffms.sty @@ -0,0 +1,323 @@ +% -*-LaTeX-*- +% TROFFMS.STY for tr2latex - troff to latex translator +% These macros are intended to be referenced by a LaTeX +% \documentstyle[troffms,twoside]{article} +% command. You can insert an 11pt or 12pt option if you like larger +% type--sizes set here are computed from the LaTeX point size setting. +% You need these macros since they are refered to by the translator. +% You can modify them if you want. +% I would very much want better macros for the headers and footers. +% Please pass your suggestions to me. -Christian +% Extended by L. Jostameling + +\def\ps@sepone{% + \def\@oddhead{} + \def\@evenhead{} + \def\@oddfoot{\hfil\@oddcfoot\hfil} + \def\@evenfoot{\hfil\@oddcfoot\hfil} +} +\thispagestyle{sepone} + +\def\@threepart#1#2#3{\rlap{#1}\hfil #2\hfil\llap{#3}} +\def\ps@sep{% + \def\@oddhead{\@threepart{\@oddlhead}{\@oddchead}{\@oddrhead}}% + \def\@oddfoot{\@threepart{\@oddlfoot}{\@oddcfoot}{\@oddrfoot}}% + \def\@evenhead{\@threepart{\@evenlhead}{\@evenchead}{\@evenrhead}}% + \def\@evenfoot{\@threepart{\@evenlfoot}{\@evencfoot}{\@evenrfoot}}% +} +\pagestyle{sep} + +\def\lefthead #1{\def\@oddlhead{#1}\def\@evenlhead{#1}} +\def\centerhead#1{\def\@oddchead{#1}\def\@evenchead{#1}} +\def\righthead #1{\def\@oddrhead{#1}\def\@evenrhead{#1}} +\lefthead{} +\centerhead{- \thepage\ -} +\righthead{} + +\def\leftfoot #1{\def\@oddlfoot{#1}\def\@evenlfoot{#1}} +\def\centerfoot#1{\def\@oddcfoot{#1}\def\@evencfoot{#1}} +\def\rightfoot #1{\def\@oddrfoot{#1}\def\@evenrfoot{#1}} +\let\footer\centerfoot +\leftfoot{} +\centerfoot{} +\rightfoot{} + +\newcommand{\EvenHeader}[3]{ + \def\@evenlhead{#1}% + \def\@evenchead{#2}% + \def\@evenrhead{#3}% +} +\newcommand{\EvenFooter}[3]{ + \def\@evenlfoot{#1}% + \def\@evencfoot{#2}% + \def\@evenrfoot{#3}% +} +\newcommand{\OddHeader}[3]{ + \def\@oddlhead{#1}% + \def\@oddchead{#2}% + \def\@oddrhead{#3}% +} +\newcommand{\OddFooter}[3]{ + \def\@oddlfoot{#1}% + \def\@oddcfoot{#2}% + \def\@oddrfoot{#3}% +} + +\def\makefootline{\baselineskip24\p@\line{\the\footline}} +\def\makeheadline{\vbox to 0pt{\vskip-22.5pt \line{vbox to 8.5pt{}\the\headline}\vss}\nointerlineskip} + +\font\bigbf=cmbx10 scaled\magstep 3 +\font\bigit=cmti10 scaled\magstep 2 +\font\bigrm=cmr10 scaled\magstep 2 + +\newdimen\en \en=.5em + +% Dimens for A4 paper +\topmargin=0cm +\ifcase \@ptsize + % mods for 10 pt + % \baselineskip = 12pt + \textheight 53\baselineskip %= 636pt +\or % mods for 11 pt + % \baselineskip = 13.6pt + \textheight 46\baselineskip % = 625pt +\or % mods for 12 pt + % \baselineskip = 15pt + \textheight 42\baselineskip % = 630pt +\fi +\advance\textheight by \topskip + +\textwidth=6.3in +\textfloatsep 30pt plus 3pt minus 6pt +\parskip=5pt +\oddsidemargin=0in +\evensidemargin=6in +\voffset=0in +\newdimen\singlespacing +\singlespacing=11pt % single line spacing +\normalbaselineskip=15pt % 1.5 line spacing +\baselineskip=\normalbaselineskip +\parindent=5\en +\let\@listi\@listii + +% change the BEFORESKIP and AFTERSKIP to make a break after tht head +\def\paragraph{\@startsection + {paragraph}{4}{\z@}{-2ex plus -lex minus -.2ex}{1ex}{\normalsize\bf}} +% set levelnumber for subparagraph to 5 and make no indent +\def\subparagraph{\@startsection + {subparagraph}{5}{\z@}{-2ex plus -lex minus -.2ex}{lex}{\normalsize\bf}} + +\setcounter{secnumdepth}{5} % to number paragraphs and subpara iraphs A +\setcounter{tocdepth}{4} % let paragraphs apear in ToC + +% multi-line title +\newenvironment{SEPtitle}{\begin{center}\bigbf}{\end{center}} +\def\title#1{ + \begin{SEPtitle} + \vbox{\baselineskip=1.5\normalbaselineskip + \vskip1in #1\vskip.3in} + \end{SEPtitle}} +% multi-line author +\newenvironment{SEPauthor}{\begin{center}\bigit}{\end{center}} +\def\author#1{ + \begin{SEPauthor} + \vbox{\baselineskip-1.3\normalbaselineskip + #1 \vskip.3cm} + \end{SEPauthor}} +\newenvironment{SEPauthoraff}{\begin{center}\bigrm}{\end{center}} +\def \authoraff#1{ + \begin{SEPauthoraff} + \vbox{\baselineskip=1.1\normalbaselineskip + #1 \vskip.2in} + \end{SEPauthoraff}} +% multi-line centered section heading +\newenvironment{SEPmhead}{\begin{center}\bf}{\end{center}} +\def\mhead#1{\pagebreak[3] + \begin{SEPmhead}\pagebreak[3] + \vbox{\vskip.3in #1}\nopagebreak + \end{SEPmhead}\nopagebreak} +%multi-line left-justified subheading +%\newenvironment{SEPshead}{\begin{flushleft/}\bf}{\end{flushleft}} +%\def\shead#1{\pagebreak[3] +% \begin{SEPshead}\pagebreak[3] +% \vbox{\vskip.2in #1}\nopagebreak +% \end{SEPhead}\nopagebreak} +\newcommand{\shead}[1]{\subsubsection*{#1}} + +% define ABSTRACT, INTRODUCTION, DISCUSSION, CONCLUSIONS, REFERENCES +% and APPENDIX as the first three letters +\def\ABS{\mhead{ABSTRACT}} +\def\INT{\mhead{INTRODUCTION}} +\def\DIS{\mhead{DISCUSSION}} +\def\CON{\mhead{CONCLUSIONS}} +\def\ACK{\mhead{ACKNOWLEDGMENT}} +\def\REF{\mhead{REFERENCES}} +\def\APP{\mhead{APPENDIX}} +\renewcommand{\abstractname}{\ABS} + +% reference macro, second ... lines are indented +\newdimen\dtmp % temporary dimension variable +\def\reference#1{\baselineskip=\singlespacing \dtmp=\hsize + \advance\dtmp by-\parindent \parshape 2 0in \hsize \parindent + \dtmp \noindent #1 \endgraf \baselineskip=\normalbaselineskip + \vskip4pt + } + +\def\bs{$\backslash$} +\let\under=\underline +\let\dotdot=\ddot + +\def \Dash{\leavevmode $\mathsurround=0pt\vcenter{\hrule width 0.75em}$} + +\def \registered{{\ooalign{\hfil\raise.05ex\hbox{\the\scriptfont0 R}% + \hfil\crcr\mathhexbox20D}}} + +\def\fraction #1/#2{\leavevmode\kern.1em\raise.6ex\hbox{\the\scriptfont 0 #1}% + \kern-.15em/\kern-.2em\lower.4ex\hbox{\the\scriptfont 0 #2}} + +\newcommand{\themonth}{\ifcase\month\or + January\or February\or March\or April\or May\or June\or + July\or August\or September\or October\or November\or December\fi} + +\def\nwl{\ifhmode \unskip\hfil \penalty -\@M\relax\fi} + % similar to latex's \newline but does lot + % complain if there is no line to break +\def\ind#1{\par\noindent\everypar{\hangindent=#1\hangafter=0}} +\def\tmpind#1{\par\hskip#1} +\newenvironment{SEPcntr}{\begin{center}}{\end{center}} +\def\cntr#1{\begin{SEPcntr}#1\end{SEPcntr}} + +% displayed text* indented* justification off +\def\displaybegin{\par\begingroup\medskip\narrower\narrower\noindent + \obeylines\obeyspaces} +\def\displayend{\endgroup\smallskip\noindent} + +% fill and nofill +%\def\nofill{\par\begingroup\noindent\obeylines +% \frenchspacing\@vobeyspaces\linepenalty10000} +\def\nofill{\par\noindent\obeylines + \frenchspacing\@vobeyspaces\linepenalty10000} +%{\catcode`\ =\active\gdef\@vobeyspaces{\catcode`\ \active \let \@xobeysp}} +\def\@xobeysp{\leavevmode{}} +%\def\fill{\endgroup\noindent} +\def\fill{\nonfrenchspacing\allowbreak\noindent} + +% define a boxing macro +\def\boxit#1{\vbox{\hrule\hbox{\vrule\kern10pt\vbox{\medskip\kern5pt#1\bigskip + \kern5pt}\kern10pt\vrule}\hrule}} + +% for the ".ad c" troff command +\def\noragged{\par\leftskip\z@ \rightskip\z@ \let\\=\@normalcr + \parfillskip\@flushglue} +\def\adjust#1{\if#1l \raggedright + \else\if#1c \centering + \else\if#1r \raggedleft + \else\noragged +\fi\fi\fi} +% +\def\XParagraph{\smallbreak \noindent \hangindent=\parindent \hangafter=1} +%\newenviromnent{\XParagraph}{\list{}{\leftmargin\parindent \labelwidth\z@ +% \itemindent-\leftmargin \itemi[]}}{\endlist} + +% \begin{display}[x][y] := dispaly with no keep +% \begin{display}*[x][y] := dispaly with keep +% x=I,L,C,B; default=I; y=indent (L = Left, I = Indent, C = center, B = block) +% +\newdimen{\displaydistance} +\setlength{\displaydistance}{.5\baselineskip} +\newcommand{\@ndmacro}{\relax} +\newenvironment{display}{\parsep\displaydistance + \@ifstar{\samepage\@display}{\@display}}% + {\@ndmacro}% +\def\@display{\obeycr\@ifnextchar[{\@xdisplay}{\@xdisplay[I]}}% +\def\@xdisplay[#1]{\csname @#1display\endcsname}% +\def\@Idisplay{\@ifnextchar[{\@xIdisplay}{\@xIdisplay[\parindent]}}% +\def\@xIdisplay[#1]{\let\@ndmacro\endlist + \def\@nolnerr{}% suppress error message from \obeycr + \list{}{\leftmargin#1\item[]}}% +\def\@Ldisplay{\@xIdisplay[0pt]}% +\def\@Cdisplay{\let\@ndmacro\endcenter + \def\@nolnerr{}% suppress error message from \obeycr + \center}% +\def\@Bdisplay{\def\@ndmacro{\endtabular\endcenter}\center\tabular[t]{l}}% + +% .ux == +\newcommand{\unix}{{\sc Unix}\footnote{UNIX is a trademark of Bell Laboratories.} +\def\unix{{\sc Unix}}} + +\def\setleftmargin[#1]{% + \setlength{\leftmargin}{#1\en}% + \setlength{\labelwidth}{\leftmargin}% + \addtolength{\labelwidth}{-\labelsep}% +} + +% definitions for the '.SM* and '.LG* macros +\newcounter{fontsize} +\setcounter{fontsize}{4} +\newcommand{\SMaller}{% + \addtocounter{fontsize}{-1} + \ifnum\c@fontsize < \z@ \else \SelectFont{\c@fontsize}\fi} +\newcommand{\LarGer}{% + \addtocounter{fontsize}{1} + \ifnum\c@fontsize > 9 \else \SelectFont{\c@fontsize}\fi} +\newcommand{\SelectFont}[1]{ + \ifcase #1 + \tiny \or + \scriptsize \or + \footnotesize\or + \small \or + \normalsize \or + \large \or + \Large \or + \LARGE \or + \huge\or + \Huge + \fi +} + +\newcommand{\Normalfont}{% + \setcounter{fontsize}{4} + \SelectFont{\c@fontsize}} + +% for own defined strings +\def\defTroffString#1#2{\@namedef{TroffString@#1}{#2}} +% +\newcommand{\useTroffString}[1]{\@nameuse{TroffString@#1}} +%\@ifnextchar ({\@@useTroffString}{\@useTroffString}}% +%\def\@useTroffString#1{\@nameuse{TroffString@#1}}% +%\def\@@useTroffString (#1#2{\@nameuse{TroffString@#1#2}}% + +\newlength{\IPitemlength} +\newcommand{\IPitem}[1]{\item[#1] +\settowidth{\IPitemlength}{#1} +\ifdim\IPitemlength>\labelwidth \hfill \break \fi +} +% try this IPlist environment +%\newcommand{\deflabel}[1]{#1\hfill} +\newenvironment{IPlist}{\@IPlist}{\end{list}}% +\def\@IPlist{\par\vspace{-1ex}\@ifnextchar[{\@beginIPlist}{\@beginIPlist[5]}}% +\def\@beginIPlist[#1]{\begin{list}{}{% + \setlength{\itemsep}{\parsep}% + \setleftmargin[#1] + \def \makelabel##1{##1\hfil}% + }% +}% + +\def\TroffString@la{$\langle$} +\def\TroffString@ra{$\rangle$} +\def\TroffString@lq{\textquotedblleft} +\def\TroffString@rq{\textquotedblright} +\def\TroffString@ae{\ae} +\def\TroffString@tx{\TeX} +\def\TroffString@lx{\LaTeX} +\def\TroffString@SN{\thesection.} + +\newcommand{\defTroffNr}[2]{\expandafter + \def\csname TroffRegister@#1\endcsname{#2}} + +\newcommand\useTroffNr[1]{\@nameuse{TroffRegister@#1}} +\defTroffNr{H1}{\thesection} + +\newcommand\useTroffFont[1]{\@nameuse{TroffFont@#1}} +\def\TroffFont@CW{\tt} +\def\TroffFont@CI{\it\ttfamily} |