summaryrefslogtreecommitdiff
path: root/support/tr2latex
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
committerNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
commite0c6872cf40896c7be36b11dcc744620f10adf1d (patch)
tree60335e10d2f4354b0674ec22d7b53f0f8abee672 /support/tr2latex
Initial commit
Diffstat (limited to 'support/tr2latex')
-rw-r--r--support/tr2latex/History105
-rw-r--r--support/tr2latex/INSTALL8
-rw-r--r--support/tr2latex/Makefile54
-rw-r--r--support/tr2latex/Makefile.nmake19
-rw-r--r--support/tr2latex/README56
-rw-r--r--support/tr2latex/TODO8
-rw-r--r--support/tr2latex/diffs.tex80
-rw-r--r--support/tr2latex/flip.h19
-rw-r--r--support/tr2latex/forbid.h41
-rw-r--r--support/tr2latex/getopt.c242
-rw-r--r--support/tr2latex/getopt.h63
-rw-r--r--support/tr2latex/greek.h23
-rw-r--r--support/tr2latex/macros.h100
-rw-r--r--support/tr2latex/maths.h56
-rw-r--r--support/tr2latex/nmake.bat1
-rw-r--r--support/tr2latex/protos.h56
-rw-r--r--support/tr2latex/setups.h64
-rw-r--r--support/tr2latex/simil.h28
-rw-r--r--support/tr2latex/special.h124
-rw-r--r--support/tr2latex/subs.c1375
-rw-r--r--support/tr2latex/testfile230
-rw-r--r--support/tr2latex/tr.c1361
-rw-r--r--support/tr2latex/tr2latex.c222
-rw-r--r--support/tr2latex/tr2latex.man167
-rw-r--r--support/tr2latex/troffman.sty115
-rw-r--r--support/tr2latex/troffms.sty323
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}