utils/wxhelp/src/*.def
utils/wxhelp/src/*.rc
-utils/tex2rtf/src/wxwin/*.*
-utils/tex2rtf/src/*.cpp
-utils/tex2rtf/src/*.h
-utils/tex2rtf/src/make*.*
-utils/tex2rtf/src/*.xbm
-utils/tex2rtf/src/*.xpm
-utils/tex2rtf/src/*.sty
-utils/tex2rtf/src/*.ini
-utils/tex2rtf/src/*.inf
-utils/tex2rtf/lib/dummy
-utils/tex2rtf/src/*.bmp
-utils/tex2rtf/src/*.ico
-utils/tex2rtf/src/*.def
-utils/tex2rtf/src/*.rc
-utils/tex2rtf/tools/lacheck/*.*
-utils/tex2rtf/tools/tcheck/*.awk
-utils/tex2rtf/tools/tcheck/*.pl
-utils/tex2rtf/tools/tcheck/*.bat
-
utils/wxtree/src/*.cpp
utils/wxtree/src/*.h
utils/wxtree/src/makefile*
zip32 -@ %dest\ogl3.zip < %src\utils\ogl\distrib\ogl.rsp
+rem Tex2RTF
+zip32 -@ %dest\tex2rtf.zip < %src\distrib\msw\tex2rtf.rsp
+
cd %dest
echo wxWindows archived.
for this style.}
\twocolitem{\windowstyle{wxDOUBLE\_BORDER}}{Displays a double border. Windows only.}
\twocolitem{\windowstyle{wxSUNKEN\_BORDER}}{Displays a sunken border.}
-\twocolitem{\windowstyle{wxRAISED\_BORDER}}{Displays a sunken border.}
+\twocolitem{\windowstyle{wxRAISED\_BORDER}}{Displays a raised border.}
\twocolitem{\windowstyle{wxSTATIC\_BORDER}}{Displays a border suitable for a static control.}
\twocolitem{\windowstyle{wxTRANSPARENT\_WINDOW}}{The window is transparent, that is, it will not receive paint
events. Windows only.}
OBJECTS = bombs.o bombs1.o game.o
-include ../../src/makeprog.env
+include ../../../src/makeprog.env
wxMemStruct *from = NULL;
if (sinceCheckpoint && checkPoint)
from = checkPoint->m_next;
- if (from == (wxMemStruct*) NULL)
+ else
from = wxDebugContext::GetHead () ;
for (wxMemStruct * st = from; st != 0; st = st->m_next)
--- /dev/null
+% fancyheadings.sty version 1.92
+% Fancy headers and footers.
+% Piet van Oostrum, Dept of Computer Science, University of Utrecht
+% Padualaan 14, P.O. Box 80.089, 3508 TB Utrecht, The Netherlands
+% Telephone: +31-30-531806. piet@cs.ruu.nl (mcvax!sun4nl!ruuinf!piet)
+% Sep 16, 1994
+% version 1.4: Correction for use with \reversemargin
+% Sep 29, 1994:
+% version 1.5: Added the \iftopfloat, \ifbotfloat and \iffloatpage commands
+% Oct 4, 1994:
+% version 1.6: Reset single spacing in headers/footers for use with
+% setspace.sty or doublespace.sty
+% Oct 4, 1994:
+% version 1.7: changed \let\@mkboth\markboth to
+% \def\@mkboth{\protect\markboth} to make it more robust
+% Dec 5, 1994:
+% version 1.8: corrections for amsbook/amsart: define \@chapapp and (more
+% importantly) use the \chapter/sectionmark definitions from ps@headings if
+% they exist (which should be true for all standard classes).
+% May 31, 1995:
+% version 1.9: The proposed \renewcommand{\headrulewidth}{\iffloatpage...
+% construction in the doc did not work properly with the fancyplain style.
+% June 1, 1995:
+% version 1.91: The definition of \@mkboth wasn't restored on subsequent
+% \pagestyle{fancy}'s.
+% June 1, 1995:
+% version 1.92: The sequence \pagestyle{fancyplain} \pagestyle{plain}
+% \pagestyle{fancy} would erroneously select the plain version.
+
+\def\lhead{\@ifnextchar[{\@xlhead}{\@ylhead}}
+\def\@xlhead[#1]#2{\gdef\@elhead{#1}\gdef\@olhead{#2}}
+\def\@ylhead#1{\gdef\@elhead{#1}\gdef\@olhead{#1}}
+
+\def\chead{\@ifnextchar[{\@xchead}{\@ychead}}
+\def\@xchead[#1]#2{\gdef\@echead{#1}\gdef\@ochead{#2}}
+\def\@ychead#1{\gdef\@echead{#1}\gdef\@ochead{#1}}
+
+\def\rhead{\@ifnextchar[{\@xrhead}{\@yrhead}}
+\def\@xrhead[#1]#2{\gdef\@erhead{#1}\gdef\@orhead{#2}}
+\def\@yrhead#1{\gdef\@erhead{#1}\gdef\@orhead{#1}}
+
+\def\lfoot{\@ifnextchar[{\@xlfoot}{\@ylfoot}}
+\def\@xlfoot[#1]#2{\gdef\@elfoot{#1}\gdef\@olfoot{#2}}
+\def\@ylfoot#1{\gdef\@elfoot{#1}\gdef\@olfoot{#1}}
+
+\def\cfoot{\@ifnextchar[{\@xcfoot}{\@ycfoot}}
+\def\@xcfoot[#1]#2{\gdef\@ecfoot{#1}\gdef\@ocfoot{#2}}
+\def\@ycfoot#1{\gdef\@ecfoot{#1}\gdef\@ocfoot{#1}}
+
+\def\rfoot{\@ifnextchar[{\@xrfoot}{\@yrfoot}}
+\def\@xrfoot[#1]#2{\gdef\@erfoot{#1}\gdef\@orfoot{#2}}
+\def\@yrfoot#1{\gdef\@erfoot{#1}\gdef\@orfoot{#1}}
+
+\newdimen\headrulewidth
+\newdimen\footrulewidth
+\newdimen\plainheadrulewidth
+\newdimen\plainfootrulewidth
+\newdimen\headwidth
+\newif\if@fancyplain
+\def\fancyplain#1#2{\if@fancyplain#1\else#2\fi}
+
+% Command to reset various things in the headers:
+% a.o. single spacing (taken from setspace.sty)
+% and the catcode of ^^M (so that epsf files in the header work if a
+% verbatim crosses a page boundary)
+\def\fancy@reset{\restorecr
+ \def\baselinestretch{1}%
+ \ifx\undefined\@newbaseline% NFSS not present; 2.09 or 2e
+ \ifx\@currsize\normalsize\@normalsize\else\@currsize\fi%
+ \else% NFSS (2.09) present
+ \@newbaseline%
+ \fi}
+
+% Initialization of the head and foot text.
+
+\headrulewidth 0.4pt
+\footrulewidth\z@
+\plainheadrulewidth\z@
+\plainfootrulewidth\z@
+
+\lhead[\fancyplain{}{\sl\rightmark}]{\fancyplain{}{\sl\leftmark}}
+% i.e. empty on ``plain'' pages, \rightmark on even, \leftmark on odd pages
+\chead{}
+\rhead[\fancyplain{}{\sl\leftmark}]{\fancyplain{}{\sl\rightmark}}
+% i.e. empty on ``plain'' pages, \leftmark on even, \rightmark on odd pages
+\lfoot{}
+\cfoot{\rm\thepage} % page number
+\rfoot{}
+
+% Put together a header or footer given the left, center and
+% right text, fillers at left and right and a rule.
+% The \lap commands put the text into an hbox of zero size,
+% so overlapping text does not generate an errormessage.
+
+\def\@fancyhead#1#2#3#4#5{#1\hbox to\headwidth{\fancy@reset\vbox{\hbox
+{\rlap{\parbox[b]{\headwidth}{\raggedright#2\strut}}\hfill
+\parbox[b]{\headwidth}{\centering#3\strut}\hfill
+\llap{\parbox[b]{\headwidth}{\raggedleft#4\strut}}}\headrule}}#5}
+
+
+\def\@fancyfoot#1#2#3#4#5{#1\hbox to\headwidth{\fancy@reset\vbox{\footrule
+\hbox{\rlap{\parbox[t]{\headwidth}{\raggedright#2\strut}}\hfill
+\parbox[t]{\headwidth}{\centering#3\strut}\hfill
+\llap{\parbox[t]{\headwidth}{\raggedleft#4\strut}}}}}#5}
+
+\def\headrule{{\if@fancyplain\let\headrulewidth\plainheadrulewidth\fi
+\hrule\@height\headrulewidth\@width\headwidth \vskip-\headrulewidth}}
+
+\def\footrule{{\if@fancyplain\let\footrulewidth\plainfootrulewidth\fi
+\vskip-0.3\normalbaselineskip\vskip-\footrulewidth
+\hrule\@width\headwidth\@height\footrulewidth\vskip0.3\normalbaselineskip}}
+
+\def\ps@fancy{%
+\@ifundefined{@chapapp}{\let\@chapapp\chaptername}{}%for amsbook
+\@ifundefined{chapter}{\def\sectionmark##1{\markboth
+{\uppercase{\ifnum \c@secnumdepth>\z@
+ \thesection\hskip 1em\relax \fi ##1}}{}}%
+\def\subsectionmark##1{\markright {\ifnum \c@secnumdepth >\@ne
+ \thesubsection\hskip 1em\relax \fi ##1}}}%
+{\def\chaptermark##1{\markboth {\uppercase{\ifnum \c@secnumdepth>\m@ne
+ \@chapapp\ \thechapter. \ \fi ##1}}{}}
+\def\sectionmark##1{\markright{\uppercase{\ifnum \c@secnumdepth >\z@
+ \thesection. \ \fi ##1}}}}%
+\csname ps@headings\endcsname % use \ps@headings defaults if they exist
+\ps@@fancy
+\gdef\ps@fancy{\@fancyplainfalse\ps@@fancy}%
+\headwidth\textwidth}
+\def\ps@fancyplain{\ps@fancy \let\ps@plain\ps@plain@fancy}
+\def\ps@plain@fancy{\@fancyplaintrue\ps@@fancy}
+\def\ps@@fancy{%
+\def\@mkboth{\protect\markboth}%
+\def\@oddhead{\@fancyhead\@lodd\@olhead\@ochead\@orhead\@rodd}%
+\def\@oddfoot{\@fancyfoot\@lodd\@olfoot\@ocfoot\@orfoot\@rodd}%
+\def\@evenhead{\@fancyhead\@rodd\@elhead\@echead\@erhead\@lodd}%
+\def\@evenfoot{\@fancyfoot\@rodd\@elfoot\@ecfoot\@erfoot\@lodd}%
+}
+\def\@lodd{\if@reversemargin\hss\else\relax\fi}
+\def\@rodd{\if@reversemargin\relax\else\hss\fi}
+
+\let\latex@makecol\@makecol
+\def\@makecol{\let\topfloat\@toplist\let\botfloat\@botlist\latex@makecol}
+\def\iftopfloat#1#2{\ifx\topfloat\empty #2\else #1\fi}
+\def\ifbotfloat#1#2{\ifx\botfloat\empty #2\else #1\fi}
+\def\iffloatpage#1#2{\if@fcolmade #1\else #2\fi}
+
--- /dev/null
+Installation Instructions for Tex2RTF
+-------------------------------------
+
+Binaries are supplied for Windows 3.1 and for Sun workstations.
+
+If these don't work for you, or you are using a different system, you
+will need to compile Tex2RTF. There are several options for doing this.
+
+(1) GUI version
+
+If you want to have a graphical interface for Tex2RTF
+(not essential for a conversion utility!) then you
+will need to download wxWindows from skye.aiai.ed.ac.uk
+(192.41.104.6) in the directory /pub/wxwin/beta, files
+wx150?_*.tar.Z (or .gz) where ? is the latest beta letter,
+currently i.
+
+On UNIX, you will then need to decide whether you want to produce
+an XView or Motif version (provided you have one of these
+toolkits), and change the makefiles in accordingly,
+in wx/src/x, wx/src/base and wx/utils/tex2rtf/src.
+
+Use the makefile target 'xview' or 'motif' from each of the directories
+wx/src/x and wx/utils/tex2rtf/src.
+
+Under Windows, just type 'nmake -f makefile.dos' if you're
+using a Microsoft-compatible compiler (you'll need to
+change the makefiles or build project files for other compilers.)
+
+(2) Non-GUI version
+
+Under UNIX, simply use the target 'nogui'. The supplied files in the
+src/wxwin directory supply the essential utilities from wxWindows, and
+Tex2RTF will be built as a command-line program.
+
+On a PC, add 'NOGUI=1' to the makefile command line. Note that the small
+amount of memory available under DOS can cause catastrophic crashes for
+large input files, due to the lack of memory checking, so be warned! The
+Windows version is a more sensible choice.
+
+-------------------------------------------------------------------------
+Julian Smart, February 1993
+J.Smart@ed.ac.uk
--- /dev/null
+% makeidx.sty 20-Jan-87 modified for international usage
+%
+% Modified by J.Schrod (TeXsys).
+% according to the suggestion of H.Partl (TU Wien) in german.sty
+% to make caption names adaptable to other languages.
+
+\@ifundefined{seeterm}{\def\seeterm{see}}{} % <-----------
+
+\def\see#1#2{{\em \seeterm\/} #1}
+\def\printindex{\@input{\jobname.ind}}
+
--- /dev/null
+% SOBER.STY van Nico Poppelier
+% Adapted by Julian Smart for his own
+% nefarious purposes
+% --------------------------------------
+% Koppen van secties, subsecties, ...
+% --------------------------------------
+%
+% --------------------------------------
+% fontgrootte en regelafstand
+% (met de notatie X/Y wordt bedoeld
+% 'letter X op regelafstand Y')
+% --------------------------------------
+%
+% 10pt 11pt 12pt
+% \scriptsize 7/ 8 8/ 9.5 8/ 9.5
+% \tiny 5/ 6 6/ 7 6/ 7
+% \small 9/11 10/12 11/13.6
+% \footnotesize 8/ 9.5 9/11 10/12
+% \@normalsize 10/12 11/13.6 12/15
+% \large 12/14 12/14 14/18
+% \Large 14/18 14/18 17/22
+% \LARGE 17/22 17/22 20/25
+% \huge 20/25 20/25 25/30
+% \Huge 25/30 25/30 25/30
+%
+% de syntax van \@startsection is:
+% \@startsection
+% {Name}{Level}{Indent}{Before_skip}{After_Skip}{Type_face}
+% Indent : inspring van kop vanaf linkermarge
+% Before_skip: wit boven kopje
+% (< 0 geeft aan dat eerste alinea niet inspringt)
+% After_skip : wit onder kopje indien >= 0
+% horizontaal wit na kopje,
+% met kopje op de regel indien < 0
+%
+% notatie voor <glue>: <dimen>(<stretch>)(<shrink>)
+%
+% in LaTeX's standaard-stijlen (onafhankelijk van \@ptsize):
+%
+% Indent Before_skip After_skip Type_face
+% section 0 -3.5ex (-1ex)(-0.2ex) 2.3ex(0.2ex) \Large\bf
+% subsection 0 -3.25ex(-1ex)(-0.2ex) 1.5ex(0.2ex) \large\bf
+% subsubsection 0 -3.25ex(-1ex)(-0.2ex) 1.5ex(0.2ex) \normalsize\bf
+% paragraph 0 3.25ex( 1ex)( 0.2ex) -1em()() \normalsize\bf
+% subparagraph \parindent 3.25ex( 1ex)( 0.2ex) -1em()() \normalsize\bf
+%
+%
+% in een soberder uitvoering (onafhankelijk van \@ptsize):
+%
+\def\section{\@startsection{section}{1}
+%{\z@}{-2.5ex plus -0.5ex minus -0.1ex}{0.5ex plus 0.1ex}{\large\bf}}
+{\z@}{-2.5ex plus -0.5ex minus -0.1ex}{0.5ex plus 0.1ex}{\large\bf}}
+\def\subsection{\@startsection{subsection}{2}
+{\z@}{-2.25ex plus -0.3ex minus -0.2ex}{0.05ex plus 0.05ex}{\normalsize\bf}}
+\def\subsubsection{\@startsection{subsubsection}{3}
+{\z@}{-2.25ex plus -0.3ex minus -0.2ex}{0.05ex plus 0.05ex}{\normalsize\sc}}
+\def\paragraph{\@startsection{paragraph}{4}
+{\z@}{2ex plus 0.5ex minus 0.1ex}{-0.7em}{\normalsize\it}}
+\def\subparagraph{\@startsection{subparagraph}{4}
+{\parindent}{2ex plus 0.5ex minus 0.1ex}{-0.7em}{\normalsize\it}}
+%
+% --------------------------------------
+% Hoofdstuk-koppen
+% --------------------------------------
+%
+% LaTeX's book style (standaard documentstijl) definieert
+% de hoofdstuk-koppen onafhankelijk van \@ptsize
+%
+
+\def\@makechapterhead#1{\vspace*{20pt}%
+% Next line repaired by Piet van Oostrum - June 14, 1991.
+%{\parindent 0pt\Large\bf \ifnum\c@secnumdepth>\m@ne\thechapter \fi
+{\parindent 0pt\LARGE\bf \ifnum\c@secnumdepth>\m@ne\thechapter. \hskip 1em \fi%
+{\raggedright\LARGE\bf #1}\\\rule[10pt]{\textwidth}{0.3mm}\par\nobreak \vskip25pt} }
+
+\def\@makeschapterhead#1{
+ \vspace*{20pt} { \parindent 0pt \raggedright
+ \LARGE\bf#1\par\nobreak\vskip25pt } }
+%
+% --------------------------------------
+% List-omgevingen (itemize en enumerate)
+% --------------------------------------
+%
+% De volgende parameters zijn relevant in een list-omgeving:
+%
+% \labelsep : afstand tussen label en item
+% \labelwidth : breedte van label
+% \leftmargin : afstand tussen linkermarge en item
+% \rightmargin : afstand tussen item en rechtermarge
+% \listparindent: indentatie voor vervolg-alinea's in item
+% \parsep : verticaal wit tussen vervolg-alinea's in item
+% \itemsep : verticaal wit tussen opeenvolgende item's
+% \topsep,
+% \partopsep : wit boven item 1 = \topsep + \parskip
+% (geen alinea-overgang boven lijst)
+% wit boven item 1 = \topsep + \parskip + \partopsep
+% (alinea-overgang boven lijst)
+%
+% zie verder LaTeX-boek 5.7.1 en C.5.3
+% --------------------------------------
+%
+% De parameters voor niveau 1 worden gedefinieerd op top-niveau en
+% \@listi definieert uitsluitend \leftmargin
+%
+% size = small (9pt, 10pt, 11pt)
+\def\@listi{\topsep 0.4ex \parsep 0pt \itemsep \parsep}
+% \topsep 4pt(2pt)(2pt) 6pt(2pt)(2pt) 9pt(3pt)(5pt)
+% \parsep 2pt(1pt)(1pt) 3pt(2pt)(1pt) 4.5pt(2pt)(1pt)
+%
+% size = footnotesize (8pt, 9pt, 10pt)
+\def\@listi{\topsep 0.4ex \parsep 0pt \itemsep \parsep}
+% \topsep 3pt(1pt)(1pt) 4pt(2pt)(2pt) 6pt(2pt)(2pt)
+% \parsep 2pt(1pt)(1pt) 2pt(1pt)(1pt) 3pt(2pt)(1pt)
+%
+% size = normalsize (and bigger)
+% \parskip 0pt(1pt) 0pt(1pt) 0pt(1pt)
+% \parindent 15pt 17pt 1.5em
+% \topsep 8pt(2pt)(4pt) 9pt(3pt)(5pt) 10pt(4pt)(6pt)
+% \partopsep 2pt(1pt)(1pt) 3pt(1pt)(2pt) 3pt(2pt)(2pt)
+% \itemsep 4pt(2pt)(1pt) 4.5pt(2pt)(1pt) 5pt(2.5pt)(1pt
+% \parsep 4pt(2pt)(1pt) 4.5pt(2pt)(1pt) 5pt(2.5pt)(1pt)
+\topsep 0.4ex \partopsep 0pt \itemsep 0pt \parsep 0pt
+%
+% \leftmargini 2.5em \leftmarginii 2.2em \leftmarginiii 1.87em
+% \leftmarginiv 1.7em \leftmarginv 1.0em \leftmarginvi 1.0em
+%
+% \leftmargin\leftmargini
+% \labelwidth\leftmargini\advance\labelwidth-\labelsep
+% \labelsep 0.5em
+%
+% \def\@listi{\leftmargin\leftmargini}
+%
+\def\@listii{\leftmargin\leftmarginii
+ \labelwidth\leftmarginii\advance\labelwidth-\labelsep
+% \topsep 4pt(2pt)(1pt) 4.5pt(2pt)(1pt) 5pt(2.5pt)(1pt)
+% \parsep 2pt(1pt)(1pt) 2pt(1pt)(1pt) 2.5pt(1pt)(1pt)
+ \topsep 0pt \parsep 0pt \itemsep \parsep}
+%
+\def\@listiii{\leftmargin\leftmarginiii
+ \labelwidth\leftmarginiii\advance\labelwidth-\labelsep
+% \topsep 2pt(1pt)(1pt) 2pt(1pt)(1pt) 2.5pt(1pt)(1pt)
+% \partopsep 1pt(0pt)(1pt) 1pt(0pt)(1pt) 1pt(0pt)(1pt)
+ \parsep \z@ \topsep 0pt \partopsep 0pt \itemsep \topsep}
+%
+% \def\@listiv{\leftmargin\leftmarginiv
+% \labelwidth\leftmarginiv\advance\labelwidth-\labelsep}
+%
+% \def\@listv{ \leftmargin\leftmarginv
+% \labelwidth\leftmarginv\advance\labelwidth-\labelsep}
+%
+% \def\@listvi{\leftmargin\leftmarginvi
+% \labelwidth\leftmarginvi\advance\labelwidth-\labelsep}
+
+
--- /dev/null
+% mytitle.sty
+% Julian Smart's Enhanced Titlepage
+
+\def\maketitle{\begin{titlepage}
+\let\footnotesize\small \let\footnoterule\relax \setcounter{page}{0}
+%\null
+%\vfil
+\vspace*{2cm}\begin{flushleft}
+{\huge \sf\@title\\\rule{\textwidth}{0.5mm}} \vskip 3em {\large \lineskip .75em
+{\sf\@author}
+\par}
+\vskip 1.5em {\large\sf \@date \par} \end{flushleft} \par
+\@thanks
+\vfill
+{\sf\small\begin{flushright}%
+Artificial Intelligence Applications Institute\\
+University of Edinburgh\\
+80 South Bridge\\
+EH1 1HN\\
+Tel. 0131-650-2746
+\end{flushright}}
+\null
+\end{titlepage}
+\setcounter{footnote}{0} \let\thanks\relax
+\gdef\@thanks{}\gdef\@author{}\gdef\@title{}\let\maketitle\relax}
+\def\abstractname{Abstract} % <----------
+\def\abstract{\titlepage
+\null\vfil
+\begin{center}
+{\bf \abstractname} % <----------
+% {\bf Abstract}
+\end{center}}
+\def\endabstract{\par\vfil\null\endtitlepage}
--- /dev/null
+Implementation notes
+--------------------
+
+Files
+-----
+
+The library tex2any.lib contains the generic Latex parser.
+It comprises tex2any.cc, tex2any.h and texutils.cc.
+
+The executable Tex2RTF is made up of tex2any.lib,
+tex2rtf.cc (main driver and user interface), and specific
+drivers for generating output: rtfutils.cc, htmlutil.cc
+and xlputils.cc.
+
+Data structures
+---------------
+
+Class declarations are found in tex2any.h.
+
+TexMacroDef holds a macro (Latex command) definition: name, identifier,
+number of arguments, whether it should be ignored, etc. Integer
+identifiers are used for each Latex command for efficiency when
+generating output. A hash table MacroDefs stores all the TexMacroDefs,
+indexed on command name.
+
+Each unit of a Latex file is stored in a TexChunk. A TexChunk can be
+a macro, argument or just a string: a TexChunk macro has child
+chunks for the arguments, and each argument will have one or more
+children for representing another command or a simple string.
+
+Parsing
+-------
+
+Parsing is relatively add hoc. read_a_line reads in a line at a time,
+doing some processing for file commands (e.g. input, verbatiminclude).
+File handles are stored in a stack so file input commands may be nested.
+
+ParseArg parses an argument (which might be the whole Latex input,
+which is treated as an argument) or a single command, or a command
+argument. The parsing gets a little hairy because an environment,
+a normal command and bracketed commands (e.g. {\bf thing}) all get
+parsed into the same format. An environment, for example,
+is usually a one-argument command, as is {\bf thing}. It also
+deals with user-defined macros.
+
+Whilst parsing, the function MatchMacro gets called to
+attempt to find a command following a backslash (or the
+start of an environment). ParseMacroBody parses the
+arguments of a command when one is found.
+
+Generation
+----------
+
+The upshot of parsing is a hierarchy of TexChunks.
+TraverseFromDocument calls the recursive TraverseFromChunk,
+and is called by the 'client' converter application to
+start the generation process. TraverseFromChunk
+calls the two functions OnMacro and OnArgument,
+twice for each chunk to allow for preprocessing
+and postprocessing of each macro or argument.
+
+The client defines OnMacro and OnArgument to test
+the command identifier, and output the appropriate
+code. To help do this, the function TexOutput
+outputs to the current stream(s), and
+SetCurrentOutput(s) allows the setting of one
+or two output streams for the output to be sent to.
+Usually two outputs at a time are sufficient for
+hypertext applications where a title is likely
+to appear in an index and as a section header.
+
+There are support functions for getting the string
+data for the current chunk (GetArgData) and the
+current chunk (GetArgChunk). If you have a handle
+on a chunk, you can output it several times by calling
+TraverseChildrenFromChunk (not TraverseFromChunk because
+that causes infinite recursion).
+
+The client (here, Tex2RTF) also defines OnError and OnInform output
+functions appropriate to the desired user interface.
+
+References
+----------
+
+Adding, finding and resolving references are supported
+with functions from texutils.cc. WriteTexReferences
+and ReadTexReferences allow saving and reading references
+between conversion processes, rather like real LaTeX.
+
+Bibliography
+------------
+
+Again texutils.cc provides functions for reading in .bib files and
+resolving references. The function OutputBibItem gives a generic way
+outputting bibliography items, by 'faking' calls to OnMacro and
+OnArgument, allowing the existing low-level client code to take care of
+formatting.
+
+Units
+-----
+
+Unit parsing code is in texutils.cc as ParseUnitArgument. It converts
+units to points.
+
+Common errors
+-------------
+
+1) Macro not found: \end{center} ...
+
+Rewrite:
+
+\begin{center}
+{\large{\underline{A}}}
+\end{center}
+
+as:
+
+\begin{center}
+{\large \underline{A}}
+\end{center}
+
+2) Tables crash RTF. Set 'compatibility ' to TRUE in .ini file; also
+check for \\ end of row characters on their own on a line, insert
+correct number of ampersands for the number of columns. E.g.
+
+hello & world\\
+\\
+
+becomes
+
+hello & world\\
+&\\
+
+3) If list items indent erratically, try increasing
+listItemIndent to give more space between label and following text.
+A global replace of '\item [' to '\item[' may also be helpful to remove
+unnecessary space before the item label.
+
+4) Missing figure or section references: ensure all labels _directly_ follow captions
+or sections (no intervening white space).
--- /dev/null
+%
+% %%%%%%% %%%%% %%%%%% %%%%% % %
+% % % % % % % % % %
+% % % % % % % % % %
+% %%%%%%% %%%%% %%%%%% % % %
+% % % % % % % % %
+% % % % % % % % %
+% % %%%%%% %%%%%% %%%%% % %
+%
+% By Jean Orloff
+% Comments & suggestions by e-mail: ORLOFF@surya11.cern.ch
+% No modification of this file allowed if not e-sent to me.
+%
+% A simple way to measure the size of encapsulated postscript figures
+% from inside TeX, and to use it for automatically formatting texts
+% with inserted figures. Works both under Plain TeX-based macros
+% (Phyzzx, Harvmac, Psizzl, ...) and LaTeX environment.
+% Provides exactly the same result on any PostScript printer provided
+% the single instruction \psfor... is changed to fit the needs of the
+% particular dvi->ps translator used.
+% History:
+% 1.31: adds \psforDVIALW(?)
+% 1.30: adds \splitfile & \joinfiles for multi-file management
+% 1.24: fix error handling & add \psonlyboxes
+% 1.23: adds \putsp@ce for OzTeX fix
+% 1.22: makes \drawingBox \global for use in Phyzzx
+% 1.21: accepts %%BoundingBox: (atend)
+% 1.20: tries to add \psfordvitps for the TeXPS package.
+% 1.10: adds \psforoztex, error handling...
+%2345678 1 2345678 2 2345678 3 2345678 4 2345678 5 2345678 6 2345678 7 23456789
+%
+\def\temp{1.31}
+\let\tempp=\relax
+\expandafter\ifx\csname psboxversion\endcsname\relax
+ \message{version: \temp}
+\else
+ \ifdim\temp cm>\psboxversion cm
+ \message{version: \temp}
+ \else
+ \message{psbox(\psboxversion) is already loaded: I won't load
+ psbox(\temp)!}
+ \let\temp=\psboxversion
+ \let\tempp=\endinput
+ \fi
+\fi
+\tempp
+\let\psboxversion=\temp
+\catcode`\@=11
+% Every macro likes a little privacy...
+%
+% Some common defs
+%
+\def\execute#1{#1}% NOT stupid: cs in #1 are then identified BEFORE execution
+\def\psm@keother#1{\catcode`#112\relax}% borrowed from latex
+\def\executeinspecs#1{%
+\execute{\begingroup\let\do\psm@keother\dospecials\catcode`\^^M=9#1\endgroup}}
+%
+%Trying to tame the variety of \special commands for Postscript: the
+% universal internal command \PSspeci@l##1##2 takes ##1 to be the
+% filename and ##2 to be the integer scale factor*1000 (as for usual
+% TeX \scale commands)
+%
+\def\psfortextures{% For TeXtures on the Macintosh
+%-----------------
+\def\PSspeci@l##1##2{%
+\special{illustration ##1\space scaled ##2}%
+}}
+%
+\def\psfordvitops{% For the DVItoPS converter on IBM mainframes
+%----------------
+\def\PSspeci@l##1##2{%
+\special{dvitops: import ##1\space \the\drawingwd \the\drawinght}%
+}}
+%
+\def\psfordvips{% For DVIPS converter on VAX, UNIX and PC's
+%--------------
+\def\PSspeci@l##1##2{%
+% \special{/@scaleunit 1000 def}% never read dox without trying!
+\d@my=0.1bp \d@mx=\drawingwd \divide\d@mx by\d@my%
+\special{PSfile=##1\space llx=\psllx\space lly=\pslly\space%
+urx=\psurx\space ury=\psury\space rwi=\number\d@mx}%
+}}
+%
+\def\psforoztex{% For the OzTeX shareware on the Macintosh
+%--------------
+\def\PSspeci@l##1##2{%
+\special{##1 \space
+ ##2 1000 div dup scale
+ \putsp@ce{\number-\psllx} \putsp@ce{\number-\pslly} translate
+}%
+}}
+\def\putsp@ce#1{#1 }
+%
+\def\psfordvitps{% From the UNIX TeXPS package, vers.>3.12
+%---------------
+% Convert a dimension into the number \psn@sp (in scaled points)
+\def\psdimt@n@sp##1{\d@mx=##1\relax\edef\psn@sp{\number\d@mx}}
+\def\PSspeci@l##1##2{%
+% psfig.psr contains the def of "startTexFig": if you can locate it
+% and include the correct pathname, it should work
+\special{dvitps: Include0 "psfig.psr"}% contains def of "startTexFig"
+\psdimt@n@sp{\drawingwd}
+\special{dvitps: Literal "\psn@sp\space"}
+\psdimt@n@sp{\drawinght}
+\special{dvitps: Literal "\psn@sp\space"}
+\psdimt@n@sp{\psllx bp}
+\special{dvitps: Literal "\psn@sp\space"}
+\psdimt@n@sp{\pslly bp}
+\special{dvitps: Literal "\psn@sp\space"}
+\psdimt@n@sp{\psurx bp}
+\special{dvitps: Literal "\psn@sp\space"}
+\psdimt@n@sp{\psury bp}
+\special{dvitps: Literal "\psn@sp\space startTexFig\space"}
+\special{dvitps: Include1 "##1"}
+\special{dvitps: Literal "endTexFig\space"}
+}}
+\def\psforDVIALW{% Try for dvialw, a UNIX public domain
+%---------------
+\def\PSspeci@l##1##2{
+\special{language "PS"
+literal "##2 1000 div dup scale"
+include "##1"}}}
+\def\psonlyboxes{% Draft-like behaviour if none of the others works
+%---------------
+\def\PSspeci@l##1##2{%
+\at(0cm;0cm){\boxit{\vbox to\drawinght
+ {\vss
+ \hbox to\drawingwd{\at(0cm;0cm){\hbox{(##1)}}\hss}
+ }}}
+}%
+}
+%
+\def\psloc@lerr#1{%
+\let\savedPSspeci@l=\PSspeci@l%
+\def\PSspeci@l##1##2{%
+\at(0cm;0cm){\boxit{\vbox to\drawinght
+ {\vss
+ \hbox to\drawingwd{\at(0cm;0cm){\hbox{(##1) #1}}\hss}
+ }}}
+\let\PSspeci@l=\savedPSspeci@l% restore normal output for other figs!
+}%
+}
+%
+%\def\psfor... add your own!
+%
+% \ReadPSize{PSfilename} reads the dimensions of a PostScript drawing
+% and stores it in \drawinght(wd)
+\newread\pst@mpin
+\newdimen\drawinght\newdimen\drawingwd
+\newdimen\psxoffset\newdimen\psyoffset
+\newbox\drawingBox
+\newif\ifNotB@undingBox
+\newhelp\PShelp{Proceed: you'll have a 5cm square blank box instead of
+your graphics (Jean Orloff).}
+\def\@mpty{}
+\def\s@tsize#1 #2 #3 #4\@ndsize{
+ \def\psllx{#1}\def\pslly{#2}%
+ \def\psurx{#3}\def\psury{#4}% needed by a crazyness of dvips!
+ \ifx\psurx\@mpty\NotB@undingBoxtrue% this is not a valid one!
+ \else
+ \drawinght=#4bp\advance\drawinght by-#2bp
+ \drawingwd=#3bp\advance\drawingwd by-#1bp
+% !Units related by crazy factors as bp/pt=72.27/72 should be BANNED!
+ \fi
+ }
+\def\sc@nline#1:#2\@ndline{\edef\p@rameter{#1}\edef\v@lue{#2}}
+\def\g@bblefirstblank#1#2:{\ifx#1 \else#1\fi#2}
+\def\psm@keother#1{\catcode`#112\relax}% borrowed from latex
+\def\execute#1{#1}% Seems stupid, but cs are identified BEFORE execution
+{\catcode`\%=12
+\xdef\B@undingBox{%%BoundingBox}
+} %% is not a true comment in PostScript, even if % is!
+\def\ReadPSize#1{
+ \edef\PSfilename{#1}
+ \openin\pst@mpin=#1\relax
+ \ifeof\pst@mpin \errhelp=\PShelp
+ \errmessage{I haven't found your postscript file (\PSfilename)}
+ \psloc@lerr{was not found}
+ \s@tsize 0 0 142 142\@ndsize
+ \closein\pst@mpin
+ \else
+ \immediate\write\psbj@inaux{#1,}
+ \loop
+ \executeinspecs{\catcode`\ =10\global\read\pst@mpin to\n@xtline}
+ \ifeof\pst@mpin
+ \errhelp=\PShelp
+ \errmessage{(\PSfilename) is not an Encapsulated PostScript File:
+ I could not find any \B@undingBox: line.}
+ \edef\v@lue{0 0 142 142:}
+ \psloc@lerr{is not an EPSFile}
+ \NotB@undingBoxfalse
+ \else
+ \expandafter\sc@nline\n@xtline:\@ndline
+ \ifx\p@rameter\B@undingBox\NotB@undingBoxfalse
+ \edef\t@mp{%
+ \expandafter\g@bblefirstblank\v@lue\space\space\space}
+ \expandafter\s@tsize\t@mp\@ndsize
+ \else\NotB@undingBoxtrue
+ \fi
+ \fi
+ \ifNotB@undingBox\repeat
+ \closein\pst@mpin
+ \fi
+\message{#1}
+}
+%
+% \psboxto(xdim;ydim){psfilename}: you specify the dimensions and
+% TeX uniformly scales to fit the largest one. If xdim=0pt, the
+% scale is fully determined by ydim and vice versa.
+% Notice: psboxes are a real vboxes; couldn't take hbox otherwise all
+% indentation and all cr's would be interpreted as spaces (hugh!).
+%
+\newcount\xscale \newcount\yscale \newdimen\pscm\pscm=1cm
+\newdimen\d@mx \newdimen\d@my
+\let\ps@nnotation=\relax
+\def\psboxto(#1;#2)#3{\vbox{
+ \ReadPSize{#3}
+ \divide\drawingwd by 1000
+ \divide\drawinght by 1000
+ \d@mx=#1
+ \ifdim\d@mx=0pt\xscale=1000
+ \else \xscale=\d@mx \divide \xscale by \drawingwd\fi
+ \d@my=#2
+ \ifdim\d@my=0pt\yscale=1000
+ \else \yscale=\d@my \divide \yscale by \drawinght\fi
+ \ifnum\yscale=1000
+ \else\ifnum\xscale=1000\xscale=\yscale
+ \else\ifnum\yscale<\xscale\xscale=\yscale\fi
+ \fi
+ \fi
+ \divide \psxoffset by 1000\multiply\psxoffset by \xscale
+ \divide \psyoffset by 1000\multiply\psyoffset by \xscale
+ \global\divide\pscm by 1000
+ \global\multiply\pscm by\xscale
+ \multiply\drawingwd by\xscale \multiply\drawinght by\xscale
+ \ifdim\d@mx=0pt\d@mx=\drawingwd\fi
+ \ifdim\d@my=0pt\d@my=\drawinght\fi
+ \message{scaled \the\xscale}
+ \hbox to\d@mx{\hss\vbox to\d@my{\vss
+ \global\setbox\drawingBox=\hbox to 0pt{\kern\psxoffset\vbox to 0pt{
+ \kern-\psyoffset
+ \PSspeci@l{\PSfilename}{\the\xscale}
+ \vss}\hss\ps@nnotation}
+ \global\ht\drawingBox=\the\drawinght
+ \global\wd\drawingBox=\the\drawingwd
+ \baselineskip=0pt
+ \copy\drawingBox
+ \vss}\hss}
+ \global\psxoffset=0pt
+ \global\psyoffset=0pt% These are local to one figure
+ \global\pscm=1cm
+ \global\drawingwd=\drawingwd
+ \global\drawinght=\drawinght
+}}
+%
+% \psboxscaled{scalefactor*1000}{PSfilename} allows to bypass the
+% rounding errors of TeX integer divisions for situations where the
+% TeX box should fit the original BoundingBox with a precision better
+% than 1/1000.
+%
+\def\psboxscaled#1#2{\vbox{
+ \ReadPSize{#2}
+ \xscale=#1
+ \message{scaled \the\xscale}
+ \divide\drawingwd by 1000\multiply\drawingwd by\xscale
+ \divide\drawinght by 1000\multiply\drawinght by\xscale
+ \divide \psxoffset by 1000\multiply\psxoffset by \xscale
+ \divide \psyoffset by 1000\multiply\psyoffset by \xscale
+ \global\divide\pscm by 1000
+ \global\multiply\pscm by\xscale
+ \global\setbox\drawingBox=\hbox to 0pt{\kern\psxoffset\vbox to 0pt{
+ \kern-\psyoffset
+ \PSspeci@l{\PSfilename}{\the\xscale}
+ \vss}\hss\ps@nnotation}
+ \global\ht\drawingBox=\the\drawinght
+ \global\wd\drawingBox=\the\drawingwd
+ \baselineskip=0pt
+ \copy\drawingBox
+ \global\psxoffset=0pt
+ \global\psyoffset=0pt% These are local to one figure
+ \global\pscm=1cm
+ \global\drawingwd=\drawingwd
+ \global\drawinght=\drawinght
+}}
+%
+% \psbox{PSfilename} makes a TeX box having the minimal size to
+% enclose the picture
+\def\psbox#1{\psboxscaled{1000}{#1}}
+%
+%
+% \joinfiles file1, file2, ...n \into joinedfilename .
+% makes one file out of many
+% \splitfile joinedfilename
+% the opposite
+%
+%\def\execute#1{#1}% NOT stupid: cs in #1 are then identified BEFORE execution
+%\def\psm@keother#1{\catcode`#112\relax}% borrowed from latex
+%\def\executeinspecs#1{%
+%\execute{\begingroup\let\do\psm@keother\dospecials\catcode`\^^M=9#1\endgroup}}
+%\newread\pst@mpin
+\newif\ifn@teof\n@teoftrue
+\newif\ifc@ntrolline
+\newif\ifmatch
+\newread\j@insplitin
+\newwrite\j@insplitout
+\newwrite\psbj@inaux
+\immediate\openout\psbj@inaux=psbjoin.aux
+\immediate\write\psbj@inaux{\string\joinfiles}
+\immediate\write\psbj@inaux{\jobname,}
+%
+% We redefine input to keep track of the various files inputted
+%
+\immediate\let\oldinput=\input
+\def\input#1 {
+ \immediate\write\psbj@inaux{#1,}
+ \oldinput #1 }
+\def\empty{}
+\def\setmatchif#1\contains#2{
+ \def\match##1#2##2\endmatch{
+ \def\tmp{##2}
+ \ifx\empty\tmp
+ \matchfalse
+ \else
+ \matchtrue
+ \fi}
+ \match#1#2\endmatch}
+\def\warnopenout#1#2{
+ \setmatchif{TrashMe,psbjoin.aux,psbjoin.all}\contains{#2}
+ \ifmatch
+ \else
+ \immediate\openin\pst@mpin=#2
+ \ifeof\pst@mpin
+ \else
+ \errhelp{If the content of this file is so precious to you, abort (ie
+press x or e) and rename it before retrying.}
+ \errmessage{I'm just about to replace your file named #2}
+ \fi
+ \immediate\closein\pst@mpin
+ \fi
+ \message{#2}
+ \immediate\openout#1=#2}
+% No comments allowed below: % will have an unusual catcode
+{
+\catcode`\%=12
+\gdef\splitfile#1 {
+ \immediate\openin\j@insplitin=#1
+ \message{Splitting file #1 into:}
+ \warnopenout\j@insplitout{TrashMe}
+ \loop
+ \ifeof
+ \j@insplitin\immediate\closein\j@insplitin\n@teoffalse
+ \else
+ \n@teoftrue
+ \executeinspecs{\global\read\j@insplitin to\spl@tinline\expandafter
+ \ch@ckbeginnewfile\spl@tinline%Beginning-Of-File-Named:%\endcheck}
+ \ifc@ntrolline
+ \else
+ \toks0=\expandafter{\spl@tinline}
+ \immediate\write\j@insplitout{\the\toks0}
+ \fi
+ \fi
+ \ifn@teof\repeat
+ \immediate\closeout\j@insplitout}
+\gdef\ch@ckbeginnewfile#1%Beginning-Of-File-Named:#2%#3\endcheck{
+ \def\t@mp{#1}
+ \ifx\empty\t@mp
+ \def\t@mp{#3}
+ \ifx\empty\t@mp
+ \global\c@ntrollinefalse
+ \else
+ \immediate\closeout\j@insplitout
+ \warnopenout\j@insplitout{#2}
+ \global\c@ntrollinetrue
+ \fi
+ \else
+ \global\c@ntrollinefalse
+ \fi}
+\gdef\joinfiles#1\into#2 {
+ \message{Joining following files into}
+ \warnopenout\j@insplitout{#2}
+ \message{:}
+ {
+ \edef\w@##1{\immediate\write\j@insplitout{##1}}
+ \w@{% This text was produced with psbox's \string\joinfiles.}
+ \w@{% To decompose and tex it:}
+ \w@{%-save this with a filename CONTAINING ONLY LETTERS, and no extensions}
+ \w@{% (say, JOINTFIL), in some uncrowded directory;}
+ \w@{%-make sure you can \string\input\space psbox.tex (version>=1.3);}
+ \w@{%-tex JOINTFIL using Plain, or LaTeX, or whatever is needed by}
+ \w@{% the first part in the joining (after splitting JOINTFIL into}
+ \w@{% it's constituents, TeX will try to process it as it stands).}
+ \w@{\string\input\space psbox.tex}
+ \w@{\string\splitfile{\string\jobname}}
+ }
+ \tre@tfilelist#1, \endtre@t
+ \immediate\closeout\j@insplitout}
+\gdef\tre@tfilelist#1, #2\endtre@t{
+ \def\t@mp{#1}
+ \ifx\empty\t@mp
+ \else
+ \llj@in{#1}
+ \tre@tfilelist#2, \endtre@t
+ \fi}
+\gdef\llj@in#1{
+ \immediate\openin\j@insplitin=#1
+ \ifeof\j@insplitin
+ \errmessage{I couldn't find file #1.}
+ \else
+ \message{#1}
+ \toks0={%Beginning-Of-File-Named:#1}
+ \immediate\write\j@insplitout{\the\toks0}
+ \executeinspecs{\global\read\j@insplitin to\oldj@ininline}
+ \loop
+ \ifeof\j@insplitin\immediate\closein\j@insplitin\n@teoffalse
+ \else\n@teoftrue
+ \executeinspecs{\global\read\j@insplitin to\j@ininline}
+ \toks0=\expandafter{\oldj@ininline}
+ \let\oldj@ininline=\j@ininline
+ \immediate\write\j@insplitout{\the\toks0}
+ \fi
+ \ifn@teof
+ \repeat
+ \immediate\closein\j@insplitin
+ \fi}
+}
+% To be put at the end of a file, for making an tar-like file containing
+% everything it used.
+\def\autojoin{
+ \immediate\write\psbj@inaux{\string\into\space psbjoin.all}
+ \immediate\closeout\psbj@inaux
+ \input psbjoin.aux
+}
+%
+% Annotations & Captions etc...
+%
+%
+% \centinsert{anybox} is just a centered \midinsert, but is included as
+% people barely use the original inserts from TeX.
+%
+\def\centinsert#1{\midinsert\line{\hss#1\hss}\endinsert}
+\def\psannotate#1#2{\def\ps@nnotation{#2\global\let\ps@nnotation=\relax}#1}
+\def\pscaption#1#2{\vbox{
+ \setbox\drawingBox=#1
+ \copy\drawingBox
+ \vskip\baselineskip
+ \vbox{\hsize=\wd\drawingBox\setbox0=\hbox{#2}
+ \ifdim\wd0>\hsize
+ \noindent\unhbox0\tolerance=5000
+ \else\centerline{\box0}
+ \fi
+}}}
+% for compatibility with older versions
+\def\psfig#1#2#3{\pscaption{\psannotate{#1}{#2}}{#3}}
+\def\psfigurebox#1#2#3{\pscaption{\psannotate{\psbox{#1}}{#2}}{#3}}
+%
+% \at(#1;#2)#3 puts #3 at #1-higher and #2-right of the current
+% position without moving it (to be used in annotations).
+\def\at(#1;#2)#3{\setbox0=\hbox{#3}\ht0=0pt\dp0=0pt
+ \rlap{\kern#1\vbox to0pt{\kern-#2\box0\vss}}}
+%
+% \gridfill(ht;wd) makes a 1cm*1cm grid of ht by wd whose lower-left
+% corner is the current point
+\newdimen\gridht \newdimen\gridwd
+\def\gridfill(#1;#2){
+ \setbox0=\hbox to 1\pscm
+ {\vrule height1\pscm width.4pt\leaders\hrule\hfill}
+ \gridht=#1
+ \divide\gridht by \ht0
+ \multiply\gridht by \ht0
+ \gridwd=#2
+ \divide\gridwd by \wd0
+ \multiply\gridwd by \wd0
+ \advance \gridwd by \wd0
+ \vbox to \gridht{\leaders\hbox to\gridwd{\leaders\box0\hfill}\vfill}}
+%
+% Useful to measure where to put annotations
+\def\fillinggrid{\at(0cm;0cm){\vbox{
+ \gridfill(\drawinght;\drawingwd)}}}
+%
+% \textleftof\anybox: Sample text\endtext
+% inserts "Sample text" on the left of \anybox ie \vbox, \psbox.
+% \textrightof is the symmetric (not documented, too uggly)
+% Welcome any suggestion about clean wraparound macros from
+% TeXhackers reading this
+%
+\def\textleftof#1:{
+ \setbox1=#1
+ \setbox0=\vbox\bgroup
+ \advance\hsize by -\wd1 \advance\hsize by -2em}
+\def\textrightof#1:{
+ \setbox0=#1
+ \setbox1=\vbox\bgroup
+ \advance\hsize by -\wd0 \advance\hsize by -2em}
+\def\endtext{
+ \egroup
+ \hbox to \hsize{\valign{\vfil##\vfil\cr%
+\box0\cr%
+\noalign{\hss}\box1\cr}}}
+%
+% \frameit{\thick}{\skip}{\anybox}
+% draws with thickness \thick a box around \anybox, leaving \skip of
+% blank around it. eg \frameit{0.5pt}{1pt}{\hbox{hello}}
+% \boxit{\anybox} is a shortcut.
+\def\frameit#1#2#3{\hbox{\vrule width#1\vbox{
+ \hrule height#1\vskip#2\hbox{\hskip#2\vbox{#3}\hskip#2}%
+ \vskip#2\hrule height#1}\vrule width#1}}
+\def\boxit#1{\frameit{0.4pt}{0pt}{#1}}
+%
+%
+\catcode`\@=12 % cs containing @ are unreachable
+%
+% CUSTOMIZE YOUR DEFAULT DRIVER:
+% Uncomment the line corresponding to your TeX system:
+%\psfortextures% For TeXtures on the Macintosh
+%\psforoztex % For OzTeX shareware on the Macintosh
+%\psfordvitops % For the DVItoPS converter for TeX on IBM mainframes
+ \psfordvips % For DVIPS converter on VAX and UNIX
+%\psfordvitps % For dvitps from TeXPS package under UNIX
+%\psforDVIALW % For DVIALW, UNIX public domain
+%\psonlyboxes % Blank Boxes (when all else fails).
--- /dev/null
+
++++++ Announcing Tex2RTF +++++
++++++ A Free LaTeX to RTF, Windows Help RTF, HTML & wxHelp converter +++++
+
+Purpose
+=======
+
+ * Allows you to maintain manuals in printed and hypertext formats.
+
+ * Allows conversion of existing LaTeX documents to word processor
+ formats (usually some 'tweaking' is required to conform to
+ Tex2RTF restrictions).
+
+Input
+=====
+
+A LaTeX subset with some additional hypertext macros; no maths,
+minimal table support.
+
+Caveat: Please do not expect to convert arbitrary LaTex files without
+editing: this is not the primary intention of Tex2RTF. Success converting
+existing LaTeX depends on your expectations and the style in which
+the LaTeX was written. Tex2RTF does not accept pure TeX (non-LaTeX)
+documents.
+
+Output
+======
+
+ * ordinary RTF
+
+ * Windows Help hypertext RTF
+
+ * HTML (the World Wide Web hypertext format)
+
+ * wxHelp (the wxWindows GUI library help file format)
+
+Installation
+============
+
+Under Windows, please run the supplied install.exe program. The Tex2RTF
+manual itself serves as an example input file, in the docs subdirectory
+with various .sty, .ini, and .gif files that you may need for your
+own documents. See the online manual for further details.
+
+Platforms supported
+===================
+
+ * SPARC Open Look
+
+ * SPARC Motif
+
+ * Windows 3.1
+
+Where to get it
+===============
+
+The latest version of Tex2RTF can be accessed by anonymous ftp from
+ftp.aiai.ed.ac.uk in the directory /pub/packages/tex2rtf.
+The WWW pages are at http://www.aiai.ed.ac.uk/~jacs/tex2rtf.html.
+
+Tex2RTF was developed using the free Open Look/Motif/Windows 3.1 C++
+class library wxWindows, also available from the above FTP site in the
+/pub/packages/wxwin directory.
+The wxWindows WWW pages are at http://www.aiai.ed.ac.uk/~jacs/wxwin.html.
+
+
+------------------------------------------------------------------
+Julian Smart, November 1995
+
+Artificial Intelligence Applications Institute
+University of Edinburgh
+80 South Bridge
+Edinburgh
+Scotland
+EH1 1HN
+
+EMAIL: J.Smart@ed.ac.uk
+TEL: 0131 650 2746
+
+
+
--- /dev/null
+@techreport{robins87,
+author = {Robins, Gabriel},
+title = {The {ISI} grapher: a portable tool for displaying graphs pictorially (ISI/RS-87-196)},
+institution = {University of South California},
+year = {1987},
+month = {September}
+}
+@book{helpbook,
+author = {Boggan, Scott and Fakas, David and Welinske, Joe}
+, title = {Developing on-line help for {W}indows}
+, publisher = {Sams Publishing}
+, address = {11711 North College, Carmel, Indiana 46032, USA}
+, year = {1993}
+}
+@book{kopka,
+author = {Kopka, Helmut and Daly, Patrick W.}
+, title = {A Guide to LaTeX}
+, publisher = {Addison-Wesley}
+, year = {1993}
+}
+@book{pfeiffer,
+author = {Pfeiffer, Katherine Shelly}
+, title = {Word for Windows Design Companion}
+, publisher = {Ventana Press}
+, year = {1994}
+}
+@manual{smart93a,
+author = {Smart, Julian}
+, title = {wxWindows 1.50 User Manual}
+, publisher = {Artificial Intelligence Applications Institute}
+, organization = {University of Edinburgh}
+, address = {80 South Bridge, Edinburgh, EH1 1HN}
+, year = {1993}
+}
+
--- /dev/null
+[OPTIONS]
+BMROOT=.
+TITLE=Tex2RTF Manual
+CONTENTS=Contents
+COMPRESS=HIGH
+
+[FILES]
+tex2rtf.rtf
+
+[CONFIG]
+CreateButton("Up", "&Up", "JumpId(`tex2rtf.hlp', `Contents')")
+BrowseButtons()
+
+[MAP]
+
+[BITMAPS]
+
--- /dev/null
+; Tex2RTF initialisation file for 16-bit WinHelp
+runTwice = yes
+titleFontSize = 12
+authorFontSize = 10
+chapterFontSize = 12
+sectionFontSize = 12
+subsectionFontSize = 12
+headerRule = yes
+footerRule = yes
+useHeadingStyles = yes
+contentsDepth = 2
+listItemIndent=40
+winHelpContents = yes
+winHelpVersion = 3 ; 3 for Windows 3.x, 4 for Windows 95
+generateHPJ = yes
+htmlBrowseButtons = bitmap
+winHelpTitle = "Tex2RTF Manual"
+truncateFilenames = yes
+combineSubSections = yes
+htmlIndex = yes
+htmlFrameContents = no
--- /dev/null
+\documentstyle[a4,makeidx,verbatim,texhelp,fancyhea,mysober,mytitle]{report}%
+\input{psbox.tex}
+\newcommand{\commandref}[2]{\helpref{{\tt $\backslash$#1}}{#2}}%
+\newcommand{\commandrefn}[2]{\helprefn{{\tt $\backslash$#1}}{#2}\index{#1}}%
+\newcommand{\commandpageref}[2]{\latexignore{\helprefn{{\tt $\backslash$#1}}{#2}}\latexonly{{\tt $\backslash$#1} {\it page \pageref{#2}}}\index{#1}}%
+\newcommand{\indexit}[1]{#1\index{#1}}%
+\newcommand{\inioption}[1]{{\bf {\tt #1}}\index{#1}}%
+\parskip=10pt%
+\parindent=0pt%
+%\backgroundcolour{255;255;255}\textcolour{0;0;0}% Has an effect in HTML only
+\winhelpignore{\title{Manual for Tex2RTF 1.64:\\A \LaTeX\ to RTF and HTML converter}%
+\author{Julian Smart}%
+\date{October 1997}%
+}%
+\winhelponly{\title{Manual for Tex2RTF 1.64}%
+\author{by Julian Smart\\$$\image{1cm;0cm}{tex2rtf.wmf}$$}%
+}%
+\makeindex%
+\begin{document}%
+\maketitle%
+\pagestyle{fancyplain}%
+\bibliographystyle{plain}%
+\pagenumbering{roman}%
+\setheader{{\it CONTENTS}}{}{}{}{}{{\it CONTENTS}}%
+\setfooter{\thepage}{}{}{}{}{\thepage}%
+\tableofcontents%
+
+\chapter*{Copyright notice}%
+\setheader{{\it COPYRIGHT}}{}{}{}{}{{\it COPYRIGHT}}%
+\setfooter{\thepage}{}{}{}{}{\thepage}%
+
+Copyright (c) 1997 Julian Smart.
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose is hereby granted without fee, provided that the
+above copyright notice, author statement and this permission notice appear in
+all copies of this software and related documentation.
+
+THE SOFTWARE IS PROVIDED ``AS-IS'' AND WITHOUT WARRANTY OF ANY KIND, EXPRESS,
+IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF
+MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+
+IN NO EVENT SHALL JULIAN SMART OR THE ARTIFICIAL INTELLIGENCE
+APPLICATIONS INSTITUTE OR UNIVERSITY OF EDINBURGH BE LIABLE FOR ANY
+SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY
+OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+PERFORMANCE OF THIS SOFTWARE.
+
+\chapter{Introduction}%
+\pagenumbering{arabic}%
+\setheader{{\it CHAPTER \thechapter}}{}{}{}{}{{\it CHAPTER \thechapter}}%
+\setfooter{\thepage}{}{}{}{}{\thepage}%
+
+This document describes a utility for converting \popref{\LaTeX}{latexgloss}\ files into
+several other formats.
+
+Only a subset of \LaTeX\ can be processed by this utility, especially
+since the target document language will never perfectly match \LaTeX.
+Whether the quality of the results is good enough will depend upon the
+application and your own expectations. {\it This caveat is worth emphasizing}, because
+many people assume that any old \LaTeX\ document will go through without modification: it might,
+but the chances are you'll need to modify it a bit for Tex2RTF. Tex2RTF was written with
+portable document maintenance and generation in mind, with less emphasis on accepting all \LaTeX\ syntax.
+You have been warned!
+
+Tex2RTF is heavily biased towards making on-line, hypertext versions of
+\rtfsp\LaTeX\ documents, but the \popref{RTF}{rtf} converter can be used to generate linear,
+paper-based documents too.
+
+The latest version of Tex2RTF, plus source code, can be accessedfrom:
+
+\begin{verbatim}
+http://web.ukonline.co.uk/julian.smart/tex2rtf
+ftp://www.remstar.com/pub/wxwin/tex2rtf
+\end{verbatim}
+
+It is available in Sun Open Look, Motif, Windows 3.1, Windows 95/NT, and
+non-GUI UNIX versions.
+
+Tex2RTF was developed using the free Open Look, Motif and Windows 3.1
+C++ class library \popref{wxWindows}{wxwindows}.
+
+\section{Status of Tex2RTF}\index{status of Tex2RTF}%
+
+Tex2RTF is under continual development, often following users'
+suggestions. From version 1.33, Tex2RTF is effectively in a second phase
+of development. In addition to the bare minimum of syntax and facilities
+for producing useable help systems or linear RTF, commands are being
+added to allow visually effective, even aesthetically pleasing,
+documentation to be produced.
+
+Examples are the \verb$\indented$, \verb$\twocollist$ and \verb$\marginpar$\rtfsp
+commands; over time I hope to be able to reproduce most of the popular
+styles of formatting and presentation in Windows Help files, whilst
+allowing a reasonable equivalent to be generated in the other formats.
+
+Some new developments in the various formats still need to be catered
+for by Tex2RTF, such as Windows 95 help files and HTML 3.0. Features
+that can be added to Tex2RTF as a result of these developments include
+math and inline image map support in HTML, table support in Windows
+Help, and generally better formatting abilities in both. However, documentation
+about these formats is sketchy at the time of writing (October 1995).
+
+\section{Acknowledgements}\index{acknowledgements}%
+
+Thanks are due to the many people in AIAI and on the Internet at large
+who have pointed out bugs or shortcomings in Tex2RTF. Michel Lavaud has been
+a great help in giving advice for improvements to the manual.
+
+\section{Change log}\index{change log}%
+
+Version 1.64, October 20th 1998
+
+\begin{itemize}\itemsep=0pt
+\item Added \verb$\insertatlevel$ command.
+\end{itemize}
+
+Version 1.63, October 21st 1997
+
+\begin{itemize}\itemsep=0pt
+\item Debugged problem with Word bookmarks not being inserted for unnumbered
+sections.
+\end{itemize}
+
+Version 1.62, August 18th 1997
+
+\begin{itemize}\itemsep=0pt
+\item Added contributed changes by Andreas Münzenmaier to support German
+accents by allowing the characters to be placed in input files, and also
+converting them back to character codes in the WinHelp {\tt .cnt} file.
+\item Now \verb$\helpref$ causes page references to be inserted in linear RTF,
+or section references if not on Word mode.
+\item WinHelp table caption bug fixed.
+\end{itemize}
+
+Version 1.61, June 11th 1997
+
+\begin{itemize}\itemsep=0pt
+\item \verb$\fcol$ now works in HTML using the FONT tag.
+\item \verb$\twocollist$ works in indented paragraphs, and is now
+implemented properly using tables in HTML.
+\item New boolean option {\bf combineSubSections} added, which switches off
+the generation of separate HTML files below section level. This can reduce the
+number of HTML files substantially.
+\end{itemize}
+
+Version 1.60, February 18th 1997
+
+\begin{itemize}\itemsep=0pt
+\item The index command now allows complex LaTeX instead of inserting the
+first argument verbatim.
+\end{itemize}
+
+Version 1.59, February 14th 1997
+
+\begin{itemize}\itemsep=0pt
+\item Added special processing for a chapter called Popups.
+\end{itemize}
+
+Version 1.58, August 1st 1996
+
+\begin{itemize}\itemsep=0pt
+\item Added HTML settings: backgroundImage, backgroundColour, textColour,
+linkColour, followedLinkColour.
+\item Added \verb$\backgroundimage$, \verb$\backgroundcolour$, \verb$\linkcolour$,
+\verb$followedLinkColour$. \verb$\background$ now obsolete (but behaviour is
+backward compatible).
+\item The default background colour is now white.
+\item Debugged HTML \verb$\ss$ (put in wrong place in code).
+\end{itemize}
+
+Version 1.57, July 27th 1996
+
+\begin{itemize}\itemsep=0pt
+\item Added upperCaseNames setting; now all links in HTML files are in lower
+case unless specified otherwise.
+\end{itemize}
+
+Version 1.56, May 25th 1996
+
+\begin{itemize}\itemsep=0pt
+\item Debugged \verb$\special$ processing for HTML (escaped characters such ampersand).
+\item Added contentsDepth for Word RTF contents page.
+\item Removed overlapping href in HTML pages.
+\end{itemize}
+
+Version 1.55, May 6th 1996
+
+\begin{itemize}\itemsep=0pt
+\item \verb$\verb$ support corrected for HTML.
+\item Added {\it abstractName} setting.
+\item Debugged incorrect centring for HTML buttons.
+\end{itemize}
+
+Version 1.54, Feburary 28th 1996
+
+\begin{itemize}\itemsep=0pt
+\item Bug fix for 24-bit bitmap inclusion when generating RTF:
+caused a floating point error.
+\item Added htmlIndex setting, to generate an {\tt .htx} index file of an HTML document for
+use in wxHelp version 2 or other programs.
+\item Fixed header/footer bug.
+\item Change colons to spaces for WinHelp RTF keywords, since the colon has a specific meaning in WinHelp.
+\end{itemize}
+
+Version 1.53, January 1995
+
+\begin{itemize}\itemsep=0pt
+\item Now stores paths from file inclusions, so that if you include
+a file A from a separate directory, which then includes a file B
+relative to that directory, Tex2RTF will search in the path
+of A to find file B.
+\end{itemize}
+
+Version 1.52, December 1995
+
+\begin{itemize}\itemsep=0pt
+\item \verb$\helpref$ and related commands now generate italicized instead
+of bold `anchor' text for linear formats.
+\item Cured bug where Tex2RTF could hang on start up, while reading
+the {\tt tex2rtf.ini} file. This occurred when a comment finished with
+the end of file.
+\item Split the commands reference in two (\LaTeX\ and Tex2RTF commands),
+and added a {\it Commands by category} section.
+\item Removed a bug that caused HTML output to be garbled on the
+second pass.
+\end{itemize}
+
+Version 1.51: Windows 95 enhancements.
+
+\begin{itemize}\itemsep=0pt
+\item Added settings winHelpContents (for generating {\tt .cnt} file), winHelpVersion (for specifying
+target version of WinHelp).
+\item Added space to non-scrolling region of topic.
+\item If winHelpVersion is 4, makes non-scrolling region grey and the rest yellow.
+\item Added \verb$\settransparency$ command for WinHelp 4 transparent bitmaps.
+\end{itemize}
+
+Version 1.50:
+
+\begin{itemize}\itemsep=0pt
+\item Tidied up HTML generation (headers and bodies in the right places).
+\item Eliminated extra space after verbatim in HTML.
+\item Added support for simple tables in HTML.
+\item Added \verb$\textcolour$, \verb$\background$ for colouring text and background in HTML.
+\item Added \verb$\copyright$, \verb$\registered$ symbols in HTML.
+\item Added \verb$\imagel$, \verb$\imager$ for left and right aligned images
+in HTML.
+\item Added \verb$\brclear$ for clearing image alignment in HTML.
+\item Added \LaTeX\ font size support in HTML (\verb$\small$, \verb$\large$ etc.) using Netscape font extensions.
+\item HTML button-bar change: always shows the same buttons, but may make one or more insensitive. Changing button positions
+could be very annoying.
+\item Tidied up RTF generation for non-Word viewers ({\it useWord} set to {\it false}). Will now look reasonable using
+Windows 95 Quick View and WordPad: WordPad doesn't do tables but does bitmaps, and QuickView does tables but not
+bitmaps. Such is life.
+\end{itemize}
+
+Version 1.49:
+
+\begin{itemize}\itemsep=0pt
+\item Cured some bugs (char used for fgetc instead of int) so now compiles for
+WIN32s.
+\end{itemize}
+
+Version 1.48:
+
+\begin{itemize}\itemsep=0pt
+\item Added some LaTeX2e fonts commands such as \verb$\rmfamily$, \verb$\textrm$, \verb$\emph$.
+Most of these are aliases for other commands.
+\end{itemize}
+
+Up to version 1.47:
+
+\begin{itemize}\itemsep=0pt
+\item Added \verb$\backslashraw$, \verb$\rbraceraw$ and \verb$\lbraceraw$ commands
+to help output arbitrary RTF.
+\item Added \verb$\sethotspotcolour$, \verb$\sethotspotunderline$ commands for controlling
+WinHelp hotspot appearance.
+\item Added truncateFilenames option.
+\item Improved HTML inline image handling.
+\end{itemize}
+
+Up to version 1.46:
+
+\begin{itemize}
+\itemsep=0pt
+\item Added \verb$\urlref$ command for specifying HTML URLs.
+\item Started support for translating .SHG files to HTML .map files
+(this works if compiled under Borland, not MS VC++ for some reason!)
+\item Fixed nasty memory bug in HTML code (thanks Petr).
+\end{itemize}
+
+Version 1.40:
+
+\begin{itemize}
+\itemsep=0pt
+\item Added {\it generateHPJ} option for generating the .HPJ WinHelp project file
+\item Added support for DDE via a small command set
+\end{itemize}
+
+Version 1.39:
+
+\begin{itemize}
+\itemsep=0pt
+\item Option for using Word's INCLUDEPICTURE or IMPORT field, since the method that
+works for Works, doesn't work for Word! See {\it bitmapMethod} in the
+settings section.
+\end{itemize}
+
+Version 1.37-1.38:
+
+\begin{itemize}
+\itemsep=0pt
+\item Improved bibliography reading and cured some minor bugs
+\item Added \verb$\ss$ German sharp s
+\item Added rudimentary \verb$\special$ command (simply copies the argument
+to the output)
+\item Added missing '.' in subsubsection reference
+\item Added primitive internationalisation support with contentsName, tablesName etc.
+\end{itemize}
+
+Version 1.36:
+
+\begin{itemize}
+\itemsep=0pt
+\item All HTML special characters now correctly delimited by a semicolon.
+\item Cured HTML section-duplicating bug I introduced in 1.35.
+\item Cured too much spacing after sections in RTF, introduced in 1.35.
+\end{itemize}
+
+Version 1.35:
+
+\begin{itemize}
+\itemsep=0pt
+\item Added TCHECK tool, to help track down common Tex2RTF syntax problems.
+\item Included Kresten Thorup's LACHECK \LaTeX\ checking tool with DOS executable.
+\item Now ignores \verb|\@| command.
+\item Table of contents now includes numbered subsubsections.
+\end{itemize}
+
+Version 1.34:
+
+\begin{itemize}
+\itemsep=0pt
+\item Added \verb$\multicolumn$ `support' to stop RTF readers crashing.
+\item Added {\it useWord, defaultColumnWidth, compatibility} options to {\tt .ini} file.
+\item \verb$\comment$ environment now doesn't complain about unknown syntax.
+\item Added \verb$\toocomplex$ environment that treats its contents as
+verbatim in output, treated as normal output in true \LaTeX.
+\item End-of-line comments allowed in in {\tt .ini} files, using semicolon,
+percent or hash characters to denote a comment.
+\item For linear RTF, Word for Windows support for \verb$\printindex$,\rtfsp
+\verb$\index$, \verb$\pageref$, \verb$\listoftables$, \verb$\listoffigures$, contents page.
+\item Added RTF support for various symbols.
+\item Added colour support, with \verb$\definecolour$, \verb$\fcol$ and \verb$\bcol$ commands.
+\item Fixed some bugs: page numbering problems, macros deleted after first pass.
+\end{itemize}
+
+Version 1.33:
+
+\begin{itemize}
+\itemsep=0pt
+\item Added -charset command-line switch.
+\item Added \verb$\itemsep$, \verb$\twocolumn$, \verb$\onecolumn$, \verb$\setfooter$, \verb$\setheader$, \verb$\pagestyle$,
+\verb$\pagenumbering$, \verb$\thechapter$, \verb$\thesection$, \verb$\thepage$, \verb$\thebibliography$, \verb$\bibitem$ commands.
+\item New environment called \verb$\twocollist$ for making two-column lists,
+with formatting optimized for target file format.
+\item New \verb$\indented$ environment for controlling indentation.
+\item List indentation and bulleting improved.
+\item Added commands \verb$\normalbox$, \verb$\normalboxd$ for putting borders around text.
+\item Many options can now be specified in the {\tt .ini} file along with custom macros.
+\item Cured bug that put too much vertical space after some commands.
+\item Improved table formatting.
+\item Optional `Up' button in WinHelp files for easier navigation.
+\item Verbatim lines followed by \verb$\par$ in RTF, to improve WinHelp wrapping.
+\item Conversion may now be aborted under Windows by attempting to close the application.
+\item Added conditional output for all formats: \verb$\latexignore$, \verb$\latexonly$, \verb$\rtfignore$, \verb$\rtfonly$,
+\verb$\winhelpignore$, \verb$\winhelponly$, \verb$\htmlignore$, \verb$\htmlonly$, \verb$\xlpignore$, \verb$\xlponly$.
+\item HTML generator can now add Contents, Up, $<<$ and $>>$ buttons (text or bitmap) to
+each page except titlepage.
+\end{itemize}
+
+Version 1.32:
+
+\begin{itemize}
+\itemsep=0pt
+\item \verb$\footnote$ command now supported in WinHelp RTF, and \verb$\footnotepopup$\rtfsp
+added.
+\end{itemize}
+
+Version 1.31:
+
+\begin{itemize}
+\itemsep=0pt
+\item \verb$\footnote$ command now supported, in linear RTF only.
+\item Added {\tt -bufsize} option, for converting large documents.
+\end{itemize}
+
+Version 1.30:
+
+\begin{itemize}
+\itemsep=0pt
+\item \verb$\image$ command now scales metafiles (but not bitmaps).
+\item Fixed macro loading bug, now informs the user of the found macro filename.
+\item Now supports paragraph and subparagraph commands.
+\item Support for some accents added.
+\item \verb$\verb$ command now supported.
+\item Bug in subsubsection handling fixed.
+\item Can save conversion log in a text file.
+\end{itemize}
+
+Version 1.22:
+
+\begin{itemize}
+\itemsep=0pt
+\item More informative, warns against use of some commands.
+\item Added compile-time support for non-GUI environments (such as plain UNIX).
+\item Improved HTML support.
+\end{itemize}
+
+\chapter{Running Tex2RTF}\index{running Tex2RTF}%
+\setheader{{\it CHAPTER \thechapter}}{}{}{}{}{{\it CHAPTER \thechapter}}%
+\setfooter{\thepage}{}{}{}{}{\thepage}%
+
+Tex2RTF may be run in a number of ways: with or without command line arguments,
+interactively or in batch mode, and with an optional initialisation file
+for specifying \LaTeX\ macros and detailed options.
+
+Tex2RTF accepts two arguments (input and output filenames) and trailing
+(optional) switches. If both filenames are given, the utility will work
+in batch mode. Otherwise, if Tex2RTF has been compiled for GUI
+operation, a main window will be shown, with appropriate menu items for
+selecting input and output filenames, starting off the conversion
+process, and so on.
+
+Note that if the file {\tt bullet.bmp}\index{bullets} is found by Tex2RTF, this bitmap
+will be used as the bullet for items in \verb$\itemize$ lists, for WinHelp
+output. Otherwise, a symbol will be inserted (linear RTF) or bold `o'
+will be used instead (all other formats).
+
+Syntax error reporting is fairly minimal. Unrecognised macro errors may
+actually be produced by an unbalanced brace or passing the wrong number of
+arguments to a command, so look in the vicinity of the error for the
+real cause.
+
+\normalbox{Some of the syntax that is OK for true \LaTeX\ but which trips up
+Tex2RTF, may be detected by the TCHECK\index{TCHECK} program included in the tools
+directory of the Tex2RTF distribution. Some \LaTeX\ errors may be picked up
+by the LACHECK\index{LACHECK} program, also found in the tools directory.}
+
+It is recommended that you run Tex2RTF twice in order to be sure of
+resolving all references and including an up-to-date contents page.
+
+If importing RTF files into Word for Windows\index{Microsoft Word}, you may need to reformat
+the document. The easiest way to do this is to select all text with
+CTRL-A, then reformat with F9. Reformat again to ensure all references
+are resolved. For the second format, respond with {\it Update Entire
+Table} to prompts.
+
+\winhelponly{
+\section{Tex2RTF Interface}
+
+This is the Tex2RTF interface under Windows. Click on an area of the
+picture for more information.
+
+$$\imagemap{1cm;0cm}{screen}{mapref}$$
+
+\subsection{Menu bar}\label{menubar}
+
+Use the menubar for interactive operations.
+
+\subsection{Message area}\label{messagearea}
+
+Tex2RTF writes warning and error messages on this window.
+
+\subsection{Status line}\label{statusline}
+
+Displays help on menu items as the user drags the cursor over the menus.
+
+\subsection{Mode indicator}\label{modeindicator}
+
+Displays the output mode Tex2RTF is currently in.
+}
+
+\section{Command line arguments}\index{command line arguments}%
+
+These are the optional arguments you may give Tex2RTF on the command line.
+
+\twocolwidtha{5cm}
+\begin{twocollist}
+\twocolitem{{\bf -bufsize}}{Specifies buffer size in K (default 60 under Windows,
+500 under UNIX). Large files (particularly large verbatim environments)
+may require a large buffer size, equal to the largest argument of a \LaTeX\ command.
+Note that this value may not be larger than 64 under Windows.}
+\twocolitem{{\bf -html}}{Specifies HTML (World Wide Web) output.}
+\twocolitem{{\bf -interactive}}{Forces interactive mode even if both
+filenames are given.}
+\twocolitem{{\bf -charset charset}}{Specifies a character set for
+RTF production. This can be one of ansi, mac, pc, and pca.
+The default is ansi.}
+\twocolitem{{\bf -macros filename}}{Specifies a file for the custom macro
+file -- see \helpref{Macro not found error}{macronotfound}.}
+\twocolitem{{\bf -rtf}}{Specifies linear RTF output.}
+\twocolitem{{\bf -sync}}{Forces synchronous mode (no yielding to other
+processes) -- usually use this in non-interactive mode.}
+\twocolitem{{\bf -twice}}{Tells Tex2RTF to run the conversion twice to ensure all
+references and citations are resolved and the contents page included.}
+\twocolitem{{\bf -winhelp}}{Specifies Windows Help RTF output.}
+\end{twocollist}
+
+\section{Initialisation file syntax}\label{inifile}\index{initialisation file}%
+
+The initialisation file contains further detailed options for
+customising Tex2RTF's behaviour. A file may be specified
+with the {\tt -macros} command line switch, otherwise Tex2RTF
+looks for the file {\tt tex2rtf.ini} in the working directory
+or input file directory.
+
+The file may comprise macro\index{macros} (command) definitions or option settings.
+
+The syntax for a macro definition is:
+
+\begin{verbatim}
+ \name [number of args] {...LaTeX code...}
+\end{verbatim}
+
+For example:
+
+\begin{verbatim}
+ \crazy [2]{{\bf #2} is crazy but #1 is not}
+ \something [0]{}
+ \julian [0]{Julian Smart}
+\end{verbatim}
+
+The syntax for an option setting is:
+
+\begin{verbatim}
+ name = value
+\end{verbatim}
+
+or
+
+\begin{verbatim}
+ name = "value"
+\end{verbatim}
+
+For example:
+
+\begin{verbatim}
+ conversionMode = RTF
+ runTwice = true
+ titleFontSize = 12
+ authorFontSize = 10
+ headerRule = yes
+ footerRule = yes
+\end{verbatim}
+
+Options expecting boolean values accept {\it 1, 0, true, false, yes, no} in any combination of upper or
+lower case.
+
+End-of-line comments are allowed in an initialisation file, using the
+hash, semicolon or percent signs to denote the start of a comment, which runs
+until the end of the line.
+
+\subsection{Tex2RTF options}\index{options in initialisation file}\index{tex2rtf.ini}\index{initialisation file}\index{macros}%
+
+These are the allowable options in an initialisation file.
+
+\subsubsection{General options}\label{generaloptions}
+
+\twocolwidtha{5cm}
+\begin{twocollist}
+\htmlignore{\twocolitemruled{Option}{Description}}
+\twocolitem{\inioption{compatibility}}{Set to true for maximum \LaTeX\ compatibility, e.g. if
+tables crash RTF readers. Should be false (default) if the Tex2RTF guidelines
+are followed, e.g. use of $\backslash${\tt row} command in tabular environment.}
+\twocolitem{\inioption{conversionMode}}{One of RTF, WinHelp, XLP (or wxHelp), and HTML.}
+\twocolitem{\inioption{ignoreInput}}{Adds the filename to the list of files ignored by the $\backslash${\tt input} command.
+The only default filename in the list is {\tt psbox.tex}.}
+\twocolitem{\inioption{isInteractive}}{If true, runs in interactive mode (the default).}
+\twocolitem{\inioption{runTwice}}{If true, runs the converter twice.}
+\end{twocollist}
+
+\subsubsection{Presentation options}\index{options, presentation}%
+
+\begin{twocollist}
+\htmlignore{\twocolitemruled{Option}{Description}}
+\twocolitem{\inioption{authorFontSize}}{Specifies the point size for the author and date (RTF only).}
+\twocolitem{\inioption{chapterFontSize}}{Specifies the point size for chapter headings (RTF only).}
+\twocolitem{\inioption{documentFontSize}}{One of 10, 11 and 12, to specify the main font size
+independently of the \LaTeX\ document style command.}
+\twocolitem{\inioption{sectionFontSize}}{Specifies the point size for section headings (RTF only).}
+\twocolitem{\inioption{subsectionFontSize}}{Specifies the point size for subsection headings (RTF only).}
+\twocolitem{\inioption{titleFontSize}}{Specifies the point size for the title (RTF only).}
+\twocolitem{\inioption{chapterName}}{The string used when referencing chapters. The default is ``chapter".}
+\twocolitem{\inioption{sectionName}}{The string used when referencing sections. The default is ``section".}
+\twocolitem{\inioption{subsectionName}}{The string used when referencing subsections. The default is ``subsection".}
+\twocolitem{\inioption{subsubsectionName}}{The string used when referencing subsubsections. The default is ``subsubsection".}
+\twocolitem{\inioption{indexName}}{The string used for printing the index heading. The default is ``Index".}
+\twocolitem{\inioption{contentsName}}{The string used for printing the contents heading. The default is ``Contents".}
+\twocolitem{\inioption{abstractName}}{The string used for printing the abstract heading. The default is ``Abstract".}
+\twocolitem{\inioption{tablesName}}{The string used for printing the list of tables heading. The default is ``List of Tables".}
+\twocolitem{\inioption{tableName}}{The string used when referencing a table. The default is ``table".}
+\twocolitem{\inioption{figuresName}}{The string used for printing the list of figures heading. The default is ``List of Figures".}
+\twocolitem{\inioption{figureName}}{The string used when referencing a figure. The default is ``figure".}
+\twocolitem{\inioption{glossaryName}}{The string used for printing the glossary heading. The default is ``Glossary".}
+\twocolitem{\inioption{referencesName}}{The string used for printing the references heading. The default is ``References".}
+\end{twocollist}
+
+\subsubsection{RTF and WinHelp options}\label{rtfwinhelpoptions}\index{options, RTF}\index{RTF}%
+
+\begin{twocollist}
+\htmlignore{\twocolitemruled{Option}{Description}}
+\twocolitem{\inioption{bitmapMethod}}{Can be ``hex'' (embed the hex data in the file with a $\backslash$dibitmap keyword),
+``includepicture'' (use the MS Word 6.0 INCLUDEPICTURE field) or ``import'' (an earlier name
+for INCLUDEPICTURE). ``hex'' may be used for importing into MS Works, but this doesn't work
+for Word 6.0. The default is ``includepicture''.}
+\twocolitem{\inioption{contentsDepth}}{The depth of headings that is displayed in the table of contents. The default
+is 4 but you may wish to reduce this, for example for manuals that document C++ and have a large number of
+headings for member functions.}
+\twocolitem{\inioption{defaultColumnWidth}}{The width in points for columns in tables
+where the width of the column is not set by using {\it p} in the tabular
+argument. The default is 100.}
+\twocolitem{\inioption{footerRule}}{If true, draws a rule above footers (linear RTF only).}
+\twocolitem{\inioption{generateHPJ}}{If true, generates a .HPJ project file (WinHelp mode only).}
+\twocolitem{\inioption{headerRule}}{If true, draws a rule below headers (linear RTF only).}
+\twocolitem{\inioption{listLabelIndent}}{Specifies the size of list item label indentation, in points.
+The default is 18.}
+\twocolitem{\inioption{listItemIndent}}{Specifies the size of list item indentation, in points. The default
+is 40.}
+\twocolitem{\inioption{indexSubsections}}{If true (the default), subsection and subsubsection
+titles are indexed in RTF mode.}
+\twocolitem{\inioption{mirrorMargins}}{If true, margins are mirrored in twosided documents (linear RTF only).}
+\twocolitem{\inioption{useWord}}{If true (the default), Word for Windows RTF
+formatting is used where possibly, e.g. for the table of contents, list of
+tables, and list of figures.}
+\twocolitem{\inioption{useHeadingStyles}}{If true (the default), sections are marked with
+appropriate heading styles for generating the table of contents in RTF.}
+\twocolitem{\inioption{useUpButton}}{If true (the default), WinHelp files will be generated with an {\bf Up}\rtfsp
+button to make browsing easier. Note that you need to put an extra line in the CONFIG section
+of your .HPJ file:
+
+{\tt CreateButton("Up", "\&Up", "JumpId(`name.hlp', `Contents')")}
+
+where {\tt name.hlp} is the name of your help file.}
+%%% NEED TO BREAK THE LIST AT THE PAGE BREAK BECAUSE LATEX IS STUPID
+%%% UNFORTUNATELY, Tex2RTF IS STUPIDER SO NEED TO COMMENT OUT THIS
+%%% LINE WHEN MAKING HTML, RTF, XLP
+%\latexonly{\end{twocollist}\newpage\begin{twocollist}}
+\twocolitem{\inioption{winHelpContents}}{If yes, ok or true, a WinHelp {\tt .cnt} file will be generated (used in Windows 95 for either old WinHelp
+files or new WinHelp 4 files).}
+\twocolitem{\inioption{winHelpVersion}}{The version of WinHelp being targetted. This affects the generated {\tt .hpj} file and features
+such as transparent bitmaps which are new to version 4 or later. The default is 3.}
+\twocolitem{\inioption{winHelpTitle}}{Windows Help file title, inserted into the project file if {\it generateHPJ} is true.}
+\end{twocollist}
+
+\subsubsection{HTML options}\label{htmloptions}\index{options, HTML}\index{HTML}%
+
+\begin{twocollist}
+\htmlignore{\twocolitemruled{Option}{Description}}
+\twocolitem{\inioption{htmlBrowseButtons}}{Allows generation of Contents, Up, browse back and browse forward
+buttons on each HTML page except title page. Specify none, text or bitmap. If you specify
+bitmap, make sure that the files {\tt contents.gif}, {\tt up.gif}, {\tt back.gif} and {\tt forward.gif} are in the
+directory where the HTML files will reside: samples are given in the docs directory.}
+\twocolitem{\inioption{truncateFilenames}}{If true, uses {\tt .htm} suffix instead of {\tt .html},
+and truncates filenames within HTML documents.}
+\twocolitem{\inioption{htmlIndex}}{If true, specifies generation of an {\tt .htx} index file for an HTML document.
+This file can be used in wxHelp version 2 or other programs. The file consists of a number of lines,
+each line with three fields separated by bar characters: the indexed phrase, the file, and a label in the file.}
+\twocolitem{\inioption{upperCaseNames}}{If true, filenames in links are in upper case. By default
+filenames are in lower case.}
+\twocolitem{\inioption{backgroundColour}}{Specifies the RGB background colour for the document, e.g. {\tt 255;255;255} for white.
+The default is white.}
+\twocolitem{\inioption{backgroundImage}}{Specifies the RGB background image for the document, e.g. {\tt tile.gif}.}
+\twocolitem{\inioption{textColour}}{Specifies the RGB text colour for the document, e.g. {\tt 0;0;0} for black.}
+\twocolitem{\inioption{linkColour}}{Specifies the RGB link colour for the document, e.g. {\tt 0;0;255} for blue.}
+\twocolitem{\inioption{followedLinkColour}}{Specifies the RGB followed link colour for the document, e.g. {\tt 0;0;255} for blue.}
+\twocolitem{\inioption{combineSubSections}}{If true (or yes), switches off
+the generation of separate HTML files below section level. This can reduce the
+number of HTML files substantially. A subsection contents list is inserted before
+the first subsection.}
+\end{twocollist}
+
+\section{DDE commands}\index{DDE}%
+
+A Windows program can hold a conversation with Tex2RTF using DDE. The Tex2RTF server name is
+``TEX2RTF'', and the topic name to use is also ``TEX2RTF''.
+
+Tex2RTF functionality is accessed using the DDE {\it Execute} message.
+The {\it Execute} data should consist of a command name and possibly one
+argument, e.g.
+
+\begin{verbatim}
+ INPUT c:\docs\mine.tex
+\end{verbatim}
+
+If the command is not recognised, a standard TEX2RTF.INI option is assumed.
+
+The {\it Request} DDE message can be used to query the return status of an {\it Execute}
+command, and will be one of {\it OK} (no error), {\it CONVERSION ERROR}, or a more
+specific error string.
+
+The following DDE commands may be used:
+
+\begin{twocollist}
+\htmlignore{\twocolitemruled{Command}{Description}}
+\twocolitem{\inioption{EXIT}}{Takes no argument, and exits Tex2RTF.}
+\twocolitem{\inioption{GO}}{Takes no argument, and initiates the conversion.}
+\twocolitem{\inioption{INPUT}}{Takes a file name as the argument, and sets the input file to be this name.}
+\twocolitem{\inioption{MINIMIZE}}{Takes no argument, and minimizes Tex2RTF.}
+\twocolitem{\inioption{OUTPUT}}{Takes a file name as the argument, and sets the input file to be this name.}
+\twocolitem{\inioption{RESTORE}}{The same as SHOW.}
+\twocolitem{\inioption{SHOW}}{Takes no argument, and unminimizes Tex2RTF.}
+\end{twocollist}
+
+\section{Performance issues}\index{performance}%
+
+Since Tex2RTF reads the whole file into memory, a lot of memory is needed.
+For very large documents, 16MB of RAM is adviseable.
+
+I tested conversion of the wxWindows 1.63 manual on both VC++ 1.5 and
+Watcom WIN32s versions of Tex2RTF, both running under Windows 3.11 on a
+Gateway P60 with 16MB of RAM and a 2MB disk cache. Two passes were
+made, with 1.5MB of WinHelp RTF being generated. The unoptimized 16-bit
+version took 169 seconds. The optimized WIN32s version took 126 seconds,
+a significant improvement. Systems with faster disk subsystems should see
+an even better relative performance of the 32-bit version.
+
+\chapter{Writing documents with Tex2RTF}\index{LaTeX}%
+\setheader{{\it CHAPTER \thechapter}}{}{}{}{}{{\it CHAPTER \thechapter}}%
+\setfooter{\thepage}{}{}{}{}{\thepage}%
+
+\section{Why use \LaTeX?}
+
+\LaTeX\ happens to be a very convenient format if you need to produce
+documents (such as manuals, help facilities, up-to-date information) in
+both printed and on-line media. Being a language rather than a WYSIWYG system,
+it allows explicit specification of layout and document structure, lending
+itself well to hypertext applications and automatic document generation.
+Many people also prefer to use \LaTeX\ for ordinary use since it encourages
+a logical document structure and the user is not distracted by having to perfect
+the appearance; many layout decisions are taken by \LaTeX\ automatically.
+
+Although \LaTeX\ is not as fancy as modern word processors and desk-top
+publishing packages, it is for many purposes quite adequate, and sometimes
+more flexible than its modern counterparts.
+
+The conversion utility gives \LaTeX\ a new lease of life by allowing
+virtually all other wordprocessor formats to be generated from documents
+containing a reasonable subset of \LaTeX\ syntax. From the same \LaTeX\
+sources, we can now generate printed manuals, Windows Help files, \popref{wxHelp}{wxhelp}\rtfsp
+files, RTF-compatible word processor formats such as MS Word, and \popref{HTML}{html}\rtfsp
+files for use in the World Wide Web. Since the conversion tool is
+free, as are \LaTeX, HTML viewers, wxHelp and (effectively) Windows
+Help, there are no financial or time penalties for providing
+documentation in a wide range of printed and hypertext formats.
+
+\section{Help versus the printed page}\index{on-line help}%
+
+The purist may argue, quite rightly, that on-line help systems and
+printed manuals have different characteristics; help windows tend to be
+much smaller than pages, help topics should be more stand-alone than
+pages in a manual, navigation methods are very different, etc. Therefore,
+help systems should be {\it based} on printed documentation but
+separately hand-crafted into hypertext help, preferably by an
+independent person or team.
+
+This might be the ideal, but many organisations or individuals simply
+do not have the time: on-line help wouldn't get done if the
+documentation effort had to be doubled. However, Tex2RTF does provide
+some commands to allow tailoring the documentation to printed or
+on-line form, such as \verb$\helponly$ and \verb$\helpignore$. An awareness
+of the design issues should go a long way to making the compromise
+a good one, so a book such as {\it Developing On-line Help for Windows} \cite{helpbook} is highly recommended.
+
+\section{Output Formats}\index{output formats}%
+
+At present the following output formats are supported:
+
+\begin{itemize}
+\itemsep=0pt
+\item RTF (Rich Text Format)\index{RTF}. This is the most well developed
+converter. RTF is commonly used as a document exchange format amongst
+Windows-based applications, and is the input for the Windows Help
+Compiler. Tex2RTF supports both linear documents and Windows Help
+hypertext format.
+\item HTML (Hypertext Markup Language)\index{HTML}. This an SGML-based format
+commonly used by documents in the World Wide Web distributed hypertext
+system, and formats text dynamically rather like Windows Help.
+\item wxHelp\index{wxHelp}. This is the platform-independent help system for
+the class library wxWindows (see the wxWindows User Manual \cite{smart93a}).
+It can display ASCII files with embedded codes
+for changing font styles, but no formatting is done by wxHelp.
+\end{itemize}
+
+\section{What compromises must I make?}\index{compromises}\index{LaTeX}%
+
+As a \LaTeX\ user, you need to be aware that some commands or facilities
+don't transfer to other formats, either because they are not supported
+by the target format or because the converter does not support them.
+Maths formatting is a good example of an unsupported feature.
+
+Sometimes \LaTeX\ facilities must be accessed in a slightly different
+way to support the variety of formats, particularly hypertext formats
+where \LaTeX\ references are often replaced by hypertext jumps (but must
+still look right in printed documentation). Tables don't transfer well
+to RTF and HTML (and not at all to wxHelp) but an attempt is made
+to approximate tables so long as special row commands are used, instead
+of the usual end of row delimiter.
+
+Bibliographies are handled quite well since the utilities can read in\rtfsp
+{\tt .bib} files and resolve citations. Numbers are used in citations;
+the references are not yet sorted alphabetically.
+
+Pictures\index{pictures} are handled in a limited way: if the PSBOX\index{PSBOX} macro package is
+used, an \verb$\image$ command can be used to place Encapsulated PostScript
+files in \LaTeX, and Windows RGB-encoded bitmap files or placeable
+metafiles when converting to RTF.
+
+Nested file inclusion\index{file inclusion} is handled with \verb$\input$, \verb$\include$ and \verb$\verbatiminput$,
+and the comment environment is supported. However, using \verb$\input$\rtfsp
+to include macro packages is not advisable. If you do this,
+make sure you add a line in the Tex2RTF initialisation file to ignore
+this file, unless it's a simple \LaTeX\ file that conforms to Tex2RTF
+restrictions. The file {\tt psbox.tex} is the only file ignored
+by Tex2RTF by default.
+
+Because of the way \LaTeX\ is parsed, some syntax\index{syntax restrictions} has to conform to a
+few simple rules. Commands such as \verb$\bf$ and \verb$\it$ need to occur
+immediately after a left brace, and have a block of their own, since
+the text within their scope is regarded as its argument. This syntax
+means the same thing as using \verb$\begin ... \end$, which is usually
+a one argument command (the argument is the text between the \verb$\begin$\rtfsp
+and \verb$\end$). See \helpref{Space}{space}.
+
+As a Windows hypertext help writer\index{on-line help}, you don't have access to all RTF
+commands but you'll be able to get most of what you want. In particular,
+any \LaTeX\ document you write will automatically be a hypertext
+document, because the converter takes advantage of the hierarchy of
+sections. Further jumps can be placed using the commands
+\rtfsp\commandrefn{label}{label}, \commandrefn{helpref}{helpref},
+\rtfsp\commandrefn{helprefn}{helprefn}, and \commandrefn{popref}{popref}.
+Tex2RTF outputs help files that may be read linearly using the
+\rtfsp$<<$ and $>>$ buttons, and an additonal Up button for
+ease of navigation.
+
+When writing HTML, multiple files are generated from one \LaTeX\ file
+since browsing HTML works best with many small files rather than a few
+large ones.
+
+wxHelp files are least well supported since there is no formatting
+support, only font style, sizes and colours. Still, some hypertext help
+support on UNIX/X platforms is better than none. wxHelp is now being rewritten (March 1996)
+to use HTML files.
+
+Sometimes you will use a local macro package that is unrecognised by
+the converters. In this case, you may define a custom macro file
+where macros are defined in terms of supported \LaTeX\ commands
+and text. Even if the result is not the same as in \LaTeX, you
+can probably end up with something adequate, and at least avoid
+undefined macro errors. See \helpref{Initialisation file syntax}{inifile} for
+further information.
+
+\section{Changes to LaTeX syntax}
+
+Here are the conventions you need to observe to satisfy the Tex2RTF
+parser.
+
+\subsection{Space}\label{space}\index{space}%
+
+Tex2RTF attempts to insert spaces where \LaTeX\ assumes whitespace.
+However, for the benefit of RTF conversion, you need to use the \commandrefn{rtfsp}{rtfsp} command
+where a command or brace within a paragraph begins or ends with a macro. For example:
+
+\begin{verbatim}
+ Within a paragraph, you need to be careful about commands
+ \rtfsp{\it that begin at the start of a line.}
+\end{verbatim}
+
+As normal with \LaTeX, two newlines represents a paragraph break,
+although \commandrefn{par}{par} can also be used at the end of a paragraph.
+
+You need to have a blank line between section and some environment
+commands and the first paragraph or your document will look rather
+weird, e.g. headings running into paragraphs.
+
+wxHelp is more fussy than \LaTeX\ or RTF: you need to use percent
+characters at line ends liberally to eliminate newlines after commands
+on single lines.
+
+\subsection{Command arguments}\index{LaTeX commands}%
+
+Commands that have one or more arguments can be used in the following
+three ways:
+
+\begin{verbatim}
+ \bf{Some text.}
+
+ \begin{bf}
+ Some text.
+ \end{bf}
+
+ {\bf Some text.}
+\end{verbatim}
+
+The first method is a normal \LaTeX\ command.
+
+The second method is called an {\it environment}; \LaTeX\ has specific
+environments that do not always correspond to normal commands, but
+Tex2RTF recognizes environments and normal commands interchangeably, so
+long as the command has no more than two arguments.
+
+With the third method, it is important that the command has its own
+pair of braces, and that the command immediately follows the first brace.
+Otherwise, the parser cannot parse the argument(s) properly.
+With multiple arguments, each should be enclosed in braces.
+
+Optional arguments are specified using square brackets or parentheses.
+
+The braces that start command arguments must not be seperated from
+the other arguments by whitespace. For example, the following produces
+an error:
+
+\begin{verbatim}
+ \image{5cm;0cm}
+ {picture.eps}
+\end{verbatim}
+
+and should be replaced by
+
+\begin{verbatim}
+ \image{5cm;0cm}{picture.eps}
+\end{verbatim}
+
+\subsection{Avoid the setlength command}
+
+Using the $\backslash$setlength command doesn't work, since its first
+argument looks like a command with the wrong number of arguments. Use an
+alternative form instead, e.g.
+
+\begin{verbatim}
+ \parindent 0pt
+\end{verbatim}
+
+instead of
+
+\begin{verbatim}
+ \setlength{\parindent}{0pt}
+\end{verbatim}
+
+\subsection{Units}\index{units}%
+
+Only a subset of \LaTeX\ units may be used for specifying dimensions.
+Valid units are {\tt pt, mm, cm} and {\tt in}. Units should usually
+be specified for dimensions or the results may be unexpected.
+
+\subsection{Labels}\index{labels}%
+
+The \verb$\label$ command may be used for sections and figure captions,
+but must come immediately after the section or caption commands with no
+intervening whitespace.
+
+\subsection{Tables}\label{tables}\index{tables}%
+
+For best layout, table rows should be enclosed in a \verb$\row$\rtfsp
+or \verb$\ruledrow$ command, since Tex2RTF can't cope with parsing
+the \LaTeX\ tabular syntax unaided. However, if you really don't want
+to go through \LaTeX\ files inserting new syntax, set the {\it compatibility}\rtfsp
+flag to TRUE in your {\tt tex2rtf.ini} file. In this mode, Tex2RTF tries to make
+the best of a bad job, but the results won't be optimal (e.g., no table
+borders). Without this flag set, normal \LaTeX\ tables can crash RTF readers
+such as Word for Windows.
+
+\section{Tex2RTF for non-LaTeX users}\index{LaTeX}%
+
+You don't need to have \LaTeX\ installed to use Tex2RTF. You
+can still output RTF files to be imported into your favourite
+word processor, and hypertext files for on-line help.
+
+This chapter gives a very brief introduction to \LaTeX. For further
+information, Kopka and Daly's {\it A Guide to \LaTeX} \cite{kopka} is
+recommended.
+
+\subsection{What is \LaTeX?}
+
+\LaTeX\ is a macro package built on top of the typesetting package,
+\TeX. \TeX\ was written by Donald Knuth in the 1970s, and Leslie
+Lamport wrote \LaTeX\ as a higher-level, easier way to write \TeX.
+
+\TeX\ was quite advanced for its day, and is still used (particularly by
+academics) because of its free availability and its flexibility in
+typesetting maths and other symbols. It's more like a programming
+language than a word processor, with embedded commands prefixed by a
+backslash and block structure. Like programs, \TeX\ documents are
+processed by a `compiler', outputting a .dvi file, which is a device
+independent file which can be read by many converters for output
+onto physical devices, such as screens and printers.
+
+A reason for its longevity is the ability to add facilities to
+\TeX, using macro packages that define new commands.
+
+\LaTeX\ is the most popular way to write \TeX. Although WYSIWYG
+word processors and DTP packages are outstripping \LaTeX, the increasing
+interest in hypertext and mark-up languages makes \LaTeX\ relevant as
+a similar language to SGML documents (such as World Wide Web HTML files).
+
+Also, languages such as \LaTeX\ (and Rich Text Format, which it resembles
+in many ways) are {\it complementary} to WYSIWYG packages. These languages
+allow automatic production and translation of documents, where manual
+mark-up is impractical or undesirable.
+
+Since the source code of \TeX\ and \LaTeX\ is in the public domain,
+there are many free and commercial implementations of \LaTeX\ for almost
+every computer in existance. Of PC implementations, EmTeX is arguably
+the best and most complete. You can download it from various FTP sites.
+
+If you don't want to use \LaTeX\ itself, you may wish to use a program
+called lacheck to check your documents before using Tex2RTF, since it
+catches some mistakes that Tex2RTF doesn't.
+
+\subsection{Document structure}
+
+Here is a sample of a typical \LaTeX\ document:
+
+\begin{verbatim}
+ \documentstyle[a4,texhelp]{report}
+ \title{A title}
+ \author{Julian Smart}
+ \date{October 1993}
+ \begin{document}
+ \maketitle
+
+ \chapter{Introduction}
+
+ ...
+
+ \section{A section}
+
+ ...
+
+ \end{document}
+\end{verbatim}
+
+The first line is always a \verb$\documentstyle$ command. The square brackets
+enclose optional {\it style} files (suffix {\tt .sty}) that alter the appearance
+of the document or provide new commands, and the curly brackets enclose
+the mandatory style, in this case `report'.
+
+Before the document begins properly with \verb$\begin{document}$,
+you can write various commands that have an effect on the appearance of the
+document or define title page information. The \verb$\maketitle$ command
+writes the title page using information defined previously (title, author,
+date).
+
+A report has chapters, which are divided into sections, and can be further
+divided into subsections and subsubsections. To start a new section, you
+write the appropriate section command with the section heading; there is
+no specific end section command, since a new section heading or the end
+of the document will indicate the end of the previous section.
+
+An article is divided into sections, subsections and subsubsections, but
+has no chapters. This is so an article can be included in a report as a chapter.
+
+Tex2RTF is written to deal with reports best, so stick with the report
+style if you can.
+
+\subsection{Command syntax}
+
+There are several kinds of commands in \LaTeX. Most involve a keyword
+prefixed with a backslash. Here are some examples:
+
+\begin{verbatim}
+ \titlepage
+
+ \centerline{This is a centred line}
+
+ \begin{center}
+ This is a centred
+ paragraph
+ \end{center}
+
+ {\bf This is bold font}
+\end{verbatim}
+
+The first example has no arguments. The second has one argument. The third
+example is an {\it environment} which uses the begin and end keywords instead
+of a pair of braces to enclose an argument (usually one). The fourth is an example
+of using a command within a pair of braces: the command applies to the scope within
+the braces. Tex2RTF treats this form as if it were a command with one argument,
+with the right brace delimiting the argument. In this case, the command must
+immediately follow a left brace as shown.
+
+Commands may be nested, but not overlapped.
+
+\subsection{Space}\index{space}%
+
+In \LaTeX, white space is mostly ignored, line breaks make no difference.
+However, \LaTeX\ interprets two successive newlines (a blank line) as
+denoting a paragraph break. You may also use the \verb$\par$ command to end
+a paragraph.
+
+\section{Hypertext features}\index{hypertext}%
+
+\LaTeX\ is inherently suitable for specifying hypertext documents since
+it encourages description of the logical structure of a document using
+section commands. Therefore, a \LaTeX\ document is automatically
+a hypertext document, without any further editing.
+
+For Windows Help, a single RTF file is generated with topics
+corresponding to sections. A top level contents page shows each chapter
+or top-level section, and each chapter or section ends with a list of
+further sections or subsections. Tex2RTF outputs help files that may be
+read linearly using the \rtfsp$<<$ and $>>$ buttons.
+
+Similarly, a single wxHelp XLP file is generated.
+
+For HTML, a different file is generated for each section, since the
+XMOSAIC browser works best with a large number of small files. The files
+are named automatically based on the name of the output file, with the
+contents page filename being formed from the output filename with {\tt
+\_contents} appended to the name. If the truncateFilenames option is
+begin used, then the contents page is just the root name, with a .htm
+suffix. The conversion may result in the generation of several hundred
+files for a large \LaTeX\ input file.
+
+To specify explicit jumps around a hypertext file, the \commandrefn{helpref}{helpref} command is
+used. The first argument is the text to be displayed at the point of reference,
+which will be highlighted in a hypertext file to allow jumping to a reference.
+The second argument is the reference label (there should be a corresponding
+\rtfsp\commandrefn{label}{label} command in the file, following a section or figure).
+
+To use extra Tex2RTF features in proper \LaTeX, such as \verb$\helpref$\rtfsp
+and the C++ and CLIPS class reference documentation features, include
+the style file {\tt texhelp.sty}.
+
+\section{Special sections}\index{special sections}%
+
+The treatment of bibliography, glossary and index are worth special mention.
+
+\subsection{Bibliography}\label{bibsection}\index{bibliography}%
+
+Tex2RTF recognises standard \LaTeX\ bibliography files (usually with {\tt .bib} extension)
+and resolves citations. The \commandrefn{bibliography}{bibliographycmd}\rtfsp
+command reads the given {\tt .bib} file and includes a list of
+references at that point in the input. Only numbered, unsorted
+references are catered for at the moment, with no variation in
+bibliography style. A {\bf References} heading is placed in the contents
+section. Note that Tex2RTF must be run twice to ensure the citations are
+resolved properly.
+
+Tex2RTF can also cope with the \verb$\thebibliography$ environment, with \rtfsp
+\verb$\bibitem$ commands, so long as the text following the first \verb$\bibitem$\rtfsp
+argument is enclosed in braces as if it were a second argument.
+
+\subsection{Glossary}\label{glossarysection}\index{glossary}%
+
+Glossaries are formatted according to the following scheme.
+The \commandrefn{helpglossary}{helpglossary} environment is used together with
+the \commandrefn{gloss}{gloss} command for glossary entries. In \LaTeX\ this
+is interpreted as a description list, and each glossary entry is an item.
+In on-line help, each glossary entry is a section.
+
+A labelled glossary entry command may be referenced by \commandrefn{popref}{popref}\rtfsp
+to provide a quick popup explanation of a term.
+
+\subsection{Index}\index{index}%
+
+The explicit index is assumed to be redundant in on-line help, since
+search facilities are provided. Therefore the \verb$\printindex$ command
+does nothing in on-line versions. In linear RTF an index field is
+added, and \commandrefn{index}{index} marks words for inserting in the index.
+
+In Windows Help, all section headings and C++ function names are treated
+as keywords. A keyword may be ambiguous, that is, refer to more than one
+section in the help file. This automatic indexing may not always be
+adequate, so the \LaTeX\ \commandrefn{index}{index} command may be used
+to add keywords.
+
+In wxHelp, all section headings are indexed.
+
+\section{Authoring HTML documents}
+
+When an HTML document is generated, the suffix `\_contents' is appended
+to the input file root. This will be the contents page for the document.
+A number of further HTML files will be generated, possibly a large number
+for a document with a large number of sections. If you are running
+a 16-bit Windows version of Tex2RTF, you may wish to use
+the {\it truncateFilenames} option to generate DOS filenames with
+appropriately truncated references inside the HTML files.
+
+\normalbox{Tip: to reduce the number of sections generated and make
+the document more linear, you could define new chapter and section
+commands. Alias them to the normal commands in real LaTeX (edit {\tt texhelp.sty}), and
+to appropriate bold/large headings (but not section commands) in
+the Tex2RTF initialisation file.}
+
+Each HTML section file (except for the contents page) is given browse
+buttons, similar to a Windows Help file: Contents, Up, Down, Back, Forward.
+You can set {\it htmlBrowseButtons} to specify whether bitmaps or text should
+be used for these buttons. On a text-only browser, the buttons will show
+as text even if images have been specified.
+
+As well as the usual jumps within a document, you can use the \commandref{urlref}{urlref} command to jump
+to other documents. `Advanced features' which are implemented for HTML include:
+
+\begin{itemize}\itemsep=0pt
+\item Simple tables: \commandref{tabular}{tabular} command
+\item Background colour/bitmap: \commandref{backgroundcolour}{backgroundcolour} and
+\rtfsp\commandref{backgroundimage}{backgroundimage}
+\item Text colour: \commandref{textcolour}{textcolour} command
+\end{itemize}
+
+See \helpref{HTML options}{htmloptions} for relevant initialisation file
+switches.
+
+\section{Authoring Windows Help documents}\index{WinHelp files}%
+
+To produce a Windows Help file, you need to generate a WinHelp RTF file
+with Tex2RTF and then invoke a Windows Help compiler (such as hc505.exe)
+to translate this to a .hlp file.
+
+WinHelp support has split into two streams, Windows 3.1 help format
+and Windows 95 (WinHelp 4) format. You control this with the {\it winHelpVersion} option,
+setting it to 3 for Windows 3.1, and 4 for Windows 95. In the latter case,
+you also need the Help Compiler for Windows (hcw.exe and associated components)
+which are available in the WIN32 SDK and with Windows 95 compilers.
+
+Tex2RTF can produce a Windows 95 {\tt .cnt} file if {\it winHelpContents}\index{CNT file} is switched
+on. This file is used to generate the new-style contents page, allowing
+hierarchical browsing of the topic contents. In fact this file can be used
+with ordinary Windows 3.1 files on Windows 95: so to hedge your bets,
+generate a Windows 3.1 help file along with {\tt .cnt} file.
+
+Tex2RTF also generates (optionally) a {\tt .hpj} (Help Project) file\index{HPJ file} which is
+fed to the help compiler and specifies the RTF file being used amongst
+other things. In WinHelp 4 mode, Tex2RTF adds entries to the project
+to enhance the appearance of the help file. In particular, the
+non-scrolling (topic title) region is coloured grey, and the rest
+is coloured a light yellow in keeping with other Windows 95 help
+files.
+
+\normalbox{Tip: you can maintain two versions of a help file
+by specifying an alternative {\tt .ini} file on the command
+line when invoking Tex2RTF, and compiling to a different directory.
+Tex2RTF instructs the help compiler to use the input file directory
+to find bitmaps and metafiles, so using a different output directory
+is not a problem. See the Tex2RTF {\tt src/makefile.dos} for an example
+of maintaining both formats.}
+
+There is a slight wrinkle with generation of the {\tt .cnt} file:
+to work around a `feature' in the Windows 95 help compiler, Tex2RTF may insert
+extra book icons in the contents page. So your contents page
+may not exactly match the structure in your LaTeX file.
+
+`Advanced features' which are implemented for WinHelp include:
+
+\begin{itemize}\itemsep=0pt
+\item Transparency: \commandref{settransparency}{settransparency} command
+\item Colour: \commandref{definecolour}{definecolour}, \commandref{fcol}{fcol}, \commandref{bcol}{bcol} commands
+\item Hot spot appearance: \commandref{sethotspotcolour}{sethotspotcolour}, \commandref{sethotspotunderline}{sethotspotunderline} commands
+\end{itemize}
+
+Tex2RTF automatically generates browse buttons for jumping to the
+above, previous and next topics.
+
+See \helpref{RTF/WinHelp options}{rtfwinhelpoptions} for
+relevant initialisation file switches.
+
+\section{Authoring linear RTF documents}\index{RTF}%
+
+Linear RTF documents come in two main flavours. It can produce simple
+RTF that can be read by a wide variety of readers, such as
+Windows 95 WordPad, the Windows 95 viewer, and most word processors.
+Tex2RTF can also output MS Word compatible RTF which has special
+fields for contents page and index formatting, headings, and
+other enhancements.
+
+Use the {\it useWord} initialisation file flag to switch Word mode
+on or off.
+Hypertext links (using \verb$\helpref$ and other commands) will be formatted as
+bold `anchor' text plus a section or figure number in parentheses.
+
+In Word mode, using an index section generates a proper Word index.
+Similarly, a Word table of contents, list of figures, list of tables
+and page reference may be generated.
+
+See \helpref{RTF/WinHelp options}{rtfwinhelpoptions} for
+relevant initialisation file switches.
+
+\section{Authoring wxHelp documents}\index{wxHelp}%
+
+The wxHelp (.xlp) file is the most basic kind of file that Tex2RTF
+can handle. Since spacing is passed through to the output, you need to
+format your input document appropriately, with lines of reasonable length.
+
+The generated xlp file is an ASCII file that can be read directly by
+wxHelp, the generic wxWindows help viewer.
+
+\chapter{Command reference}\index{command reference}%
+\setheader{{\it CHAPTER \thechapter}}{}{}{}{}{{\it CHAPTER \thechapter}}%
+\setfooter{\thepage}{}{}{}{}{\thepage}%
+
+The following lists commands which are recognised by the converters. The reader
+can assume that commands not mentioned here are unrecognised or ignored.
+
+Each command is listed with its name, the number of arguments it takes
+(excluding optional arguments), and a description. Note that if the
+command is used as an environment (using \verb$\begin$ and \verb$\end$) then
+the number of arguments must be either one or two. For example, the\rtfsp
+\verb$\tabular$ environment takes two arguments: a first argument for
+specifying the formatting, and the second argument for the body of the
+environment.
+
+\begin{verbatim}
+ \begin{tabular}{|l|l|}
+ \row{One&Two}
+ \row{Three&Four}
+ \end{tabular}
+\end{verbatim}
+
+\section{\LaTeX\ Commands}
+
+\subsection*{abstract:1}\label{abstract}
+
+This standard \LaTeX\ environment prepares an abstract page, and is
+treated as an ordinary chapter or section in on-line help.
+
+\subsection*{addcontentsline:3}\label{addcontentsline}
+
+Adds a chapter title to the contents page. Linear RTF. Rarely required.
+
+%\subsection*{appendix}
+%\subsection*{arabic}
+%\subsection*{array}
+\subsection*{author:1}\label{author}
+
+Defines the author, for output when \verb$\maketitle$ is used.
+
+\subsection*{backslash:0}\label{backslash}
+
+Outputs a backslash in math mode (should be enclosed by two dollar symbols).
+
+\subsection*{bf:1}\label{bf}
+
+Specifies bold font.
+
+\subsection*{bffamily:1}\label{bffamily}
+
+Specifies bold font.
+
+\subsection*{bibitem:2}\label{bibitem}
+
+For parsing convenience, \verb$\bibitem$ requires two arguments: a cite key and item.
+\rtfsp\LaTeX\ syntax permits writing this as if it were two arguments,
+even though it is in fact only one. This command is used within
+a \commandrefn{thebibliography}{thebibliography} environment. The preferred
+method is to store references in {\tt .bib} files and use the \commandrefn{bibliography}{bibliographycmd}\rtfsp
+command to generate a bibliography section automatically.
+
+\subsection*{bibliographystyle:1}\label{bibliographystyle}
+
+Currently doesn't affect the style of bibliography, but probably will
+in the future.
+
+\subsection*{bibliography:0}\label{bibliographycmd}
+
+Includes the bibliography at this point in the document. See the section
+on \helpref{bibliographies}{bibsection}.
+
+%\subsection*{caption*}
+\subsection*{caption:1}\label{caption}
+
+Specifies a caption (within a \commandrefn{figure}{figure} or \commandrefn{table}{table} environment). This may
+be followed immediately by a \commandrefn{label}{label} command.
+
+\subsection*{cdots:0}\label{cdots}
+
+Outputs three dots.
+
+\subsection*{centerline:1}\label{centerline}
+
+Centres (or centers!) a line of text.
+
+%\subsection*{centering}
+\subsection*{center:1}\label{center}
+
+Centres a block of text.
+
+\subsection*{chapter:1}\label{chapter}
+
+Outputs a chapter heading. If the chapter's name is Popups\index{popups}, the chapter title will not be
+put in the contents, to allow popups to be placed in a document without the popup
+sections being directly accessible.
+
+\subsection*{chapter*:1}\label{chaptersX}
+
+Outputs a chapter heading with no contents entry.
+
+\subsection*{cite:1}\label{cite}
+
+Cite a reference. The argument is a reference key as defined in a \LaTeX\ {\tt .bib}\rtfsp
+file.
+
+\subsection*{comment:1}\label{comment}
+
+An environment that allows large comments in \LaTeX\ files: the argument
+is ignored in all formats. Useful for commenting out parts of files that
+cannot be handled by \LaTeX, such as the picture environment. See also\rtfsp
+\commandrefn{toocomplex}{toocomplex}.
+
+\subsection*{date:1}\label{date}
+
+Specifies the date of a document; only output by \commandrefn{maketitle}{maketitle}.
+
+\subsection*{description:1}\label{description}
+
+A list environment, where each \commandrefn{item}{item} command must be
+followed by optional square-bracketed text which will be highlighted.
+
+%\subsection*{destruct:1}\label{destruct}
+
+\subsection*{document:1}\label{document}
+
+This environment should enclose the body of a document.
+
+\subsection*{documentstyle:1}\label{documentstyle}
+
+Specifies the main style (report, article etc.) and, optionally, style files
+such as {\tt texhelp.sty}. A report has \commandrefn{chapters}{chapter}, while an article's top-level
+sections are specified using \commandrefn{section}{section}.
+
+%\subsection*{doublespace}\label{doublespace}
+\subsection*{em:1}\label{em}
+
+Emphasizes text (italic in RTF).
+
+\subsection*{emph:1}\label{emph}
+
+Same as \commandrefn{em}{em}.
+
+\subsection*{enumerate:1}\label{enumerate}
+
+Enumerate list environment: numbers the \commandrefn{items}{item}.
+
+%\subsection*{equation}\label{equation}
+%\subsection*{evensidemargin}
+%\subsection*{fbox:1}\label{fbox}
+
+\subsection*{figure:1}\label{figure}
+
+A figure environment: does nothing special, except allows interpretation of
+embedded \helpref{caption}{caption} commands as figures rather than (say) tables.
+
+\subsection*{flushleft:1}\label{flushleft}
+
+Flushes the given text to the left margin.
+
+\subsection*{flushright:1}\label{flushright}
+
+Flushes the given text to the right margin.
+
+%\subsection*{footheight}\label{footheight}
+\subsection*{footnote:1}\label{footnote}
+
+In linear RTF, a footnote is created. Whether this appears at the end of
+the section or the bottom of the page appears to depend on the current
+document style, at least for MS Word 6.0 for Windows. The default seems
+to be to put the footnotes at the end of the section, which is probably
+not the best assumption.
+
+In WinHelp RTF, a bracketed number is generated for the footnote
+and the footnote becomes a popup topic. It is probably preferable
+to change footnote commands to \commandref{footnotepopup}{footnotepopup},
+or \commandref{popref}{popref} references to glossary entries.
+
+This command is not supported for formats other than \LaTeX,
+linear RTF and WinHelp RTF.
+
+\subsection*{hline:0}\label{hline}
+
+Within a \commandrefn{tabular}{tabular} environment, draws a horizontal
+rule below the current row. Note that this does not work in RTF for the
+last row of a table, in which case the command \commandrefn{ruledrow}{ruledrow}\rtfsp
+should be used instead.
+
+\subsection*{hrule:0}\label{hrule}
+
+Draws a horizontal line below the current paragraph. For example:
+
+\begin{verbatim}
+ This paragraph should have a horizontal rule following it.\hrule
+\end{verbatim}
+
+gives:
+
+This paragraph should have a horizontal rule following it.\hrule
+
+%\subsection*{hspace*}\label{hspaceX}
+%\subsection*{hspace}\label{hspace}
+%\subsection*{hskip*}\label{hskipX}
+%\subsection*{hskip}\label{hskip}
+
+\subsection*{huge:1}\label{huge1}
+
+Outputs the argument in huge text.
+
+\subsection*{Huge:1}\label{Huge2}
+
+Outputs the argument in huger text than \commandrefn{huge}{huge1}.
+
+\subsection*{HUGE:1}\label{HUGE3}
+
+Outputs the argument in huger text than \commandrefn{Huge}{Huge2}.
+
+\subsection*{include:1}\label{include}
+
+Include the given file. The command must not be preceded by any whitespace,
+and spurious whitespace between elements of the command will also
+trip up Tex2RTF.
+
+\subsection*{index:1}\label{index}
+
+In WinHelp mode, adds a keyword to the keyword list for the current
+topic. This keyword must currently be straight text, with no embedded
+commands. The conversion process must be run twice (without quitting
+Tex2RTF inbetween) to resolve the keyword references.
+
+\subsection*{input:1}\label{input}
+
+Include the given file. The command must not be preceded by any whitespace,
+and spurious whitespace between elements of the command will also
+trip up Tex2RTF.
+
+\subsection*{insertatlevel:2}\label{insertatlevel}
+
+Insert some text at a particular level of the document. For example,
+
+\begin{verbatim}
+ \insertatlevel{2}{Some text}
+\end{verbatim}
+
+inserts "Some text" at level 2 (for a report, the current section). This
+allows you to insert headings into an automatically-generated section contents,
+for example.
+
+\subsection*{it:1}\label{it}
+
+Marks the argument in italic.
+
+\subsection*{itemize:1}\label{itemize}
+
+Indents each \commandrefn{item}{item} of a list and precedes with a bullet.
+If the file {\tt bullet.bmp} is found by Tex2RTF, this bitmap will be
+used as the bullet (WinHelp RTF); otherwise, a symbol or bold `o' will be used instead,
+depending on output format.
+
+Use \commandrefn{itemsep}{itemsep} to specify the separation between
+list items. Currently this only works for linear or WinHelp RTF output.
+If the value is more than zero, an extra paragraph is inserted.
+
+\subsection*{item:0}\label{item}
+
+Marks an item of a \commandrefn{itemize}{itemize}, \commandrefn{description}{description} or \commandrefn{enumerate}{enumerate}
+list. Items within a description environment should have an `optional' argument
+in square brackets which will be highlighted.
+
+\subsection*{itemsep:0}\label{itemsep}
+
+Use this command to specify the separation between
+list items. Currently this only works for linear or WinHelp RTF output.
+If the value is zero, no extra paragraph is inserted; if the value
+is more than zero, an extra paragraph is inserted.
+
+\subsection*{itshape:1}\label{itshape}
+
+Marks the argument in italic.
+
+%\subsection*{kill}\label{kill}
+\subsection*{label:1}\label{label}
+
+Labels the chapter, section, subsection, subsubsection or figure caption
+with the given label. This must be an ASCII string, and duplicate items
+with different case letters are not allowed.
+
+The command must follow immediately after the section or caption command,
+with no intervening whitespace.
+
+\subsection*{large:1}\label{large1}
+
+Marks the argument in large text.
+
+\subsection*{Large:1}\label{Large2}
+
+Makes the argument display in larger text than \commandrefn{large}{large1}.
+
+\subsection*{LARGE:1}\label{LARGE3}
+
+Makes the argument display in larger text than \commandrefn{Large}{Large2}.
+
+\subsection*{LaTeX:0}\label{LaTeX}
+
+Outputs the annoying \LaTeX\ upper and lower case name.
+
+\subsection*{ldots:0}\label{ldots}
+
+Outputs three dots.
+
+%\subsection*{linebreak}\label{linebreak}
+%\subsection*{listoffigures}\label{listoffigures}
+%\subsection*{listoftables}\label{listoftables}
+%\subsection*{makeglossary}\label{makeglossary}
+%\subsection*{makeindex}\label{makeindex}
+\subsection*{maketitle:0}\label{maketitle}
+
+Makes the article or report title by outputting the \commandrefn{title}{title},
+\rtfsp\commandrefn{author}{author} and optionally \commandrefn{date}{date}.
+
+%\subsection*{markright}\label{markright}
+%\subsection*{markboth}\label{markboth}
+
+\subsection*{marginparwidth:1}\label{marginparwidth}
+
+Specifies the width of a margin paragraph.
+
+\subsection*{marginpar:1}\label{marginpar}
+
+Inserts a marginal note. It is best to use the Tex2RTF extensions \rtfsp
+\commandrefn{marginparodd}{marginparodd} and \commandrefn{marginpareven}{marginpareven} \rtfsp
+for best results.
+
+\subsection*{marginpareven:1}\label{marginpareven}
+
+Inserts a marginal note on even pages. This is required for RTF generation since
+it is impossible for Tex2RTF to know in advance which side of paper the marginal note
+will fall upon, and the text has to be positioned using absolute dimensions.
+If only one sided output is required, use \commandrefn{marginparodd}{marginparodd} \rtfsp
+instead.
+
+\subsection*{marginparodd:1}\label{marginparodd}
+
+Inserts a marginal note on odd pages. This is required for RTF generation since
+it is impossible for Tex2RTF to know in advance which side of paper the marginal note
+will fall upon, and the text has to be positioned using absolute dimensions.
+
+Also, even if one-sided output is required, this command should be used instead
+of \verb$\marginpar$ because the \LaTeX\ command allows it to be used
+just before a paragraph. Normally, if this were done, the marginal note would
+not be aligned with the paragraph succeeding it. For example:
+
+\begin{verbatim}
+ \marginparodd{{\it Note:} if nothing happens, perhaps you
+ have not plugged your computer in at the mains.}%
+ To start using your computer, push the Power button
+ and wait for text to appear on the screen.
+\end{verbatim}
+
+Note the percent sign after the \verb$\marginparodd$ command: without it,
+\LaTeX\ refuses to believe that the following text is part of the
+same paragraph, and will print the note at the wrong place.
+
+You should use \commandrefn{textwidth}{textwidth} to allow space for marginal
+notes, and also \commandrefn{marginparwidth}{marginparwidth} to specify the size of
+the marginal note.
+
+In WinHelp, HTML and wxHelp, marginal notes are treated as normal text delineated
+with horizontal rules above and below.
+
+%\subsection*{mbox:1}\label{mbox}
+
+\subsection*{mdseries:1}\label{mdseries}
+
+Changes to a medium-weight font. Un-emboldens in RTF mode, no effect in other modes.
+
+\subsection*{multicolumn:3}\label{multicolumn}
+
+Used in \commandrefn{tabular}{tabular} environment to denote a cell that
+spans more than one column. Only supplied for compatibility with
+existing \LaTeX\ files, since all it does in RTF is output the correct
+number of cell commands, with the multicolumn text squashed into one cell.
+
+\subsection*{newcommand:3}\label{newcommand}
+
+Define a new command; arguments are the command, the number of
+arguments, and the command body. For example:
+
+\begin{verbatim}
+ \newcommand{\crazy}[2]{{\bf #1} is crazy but {\bf #2} is not.}
+\end{verbatim}
+
+The command must have no whitespace at the start of the line or between
+the three arguments.
+
+New commands may also be defined in the {\tt tex2rtf.ini} file using
+slightly different syntax (see \helpref{Macro not found error}{macronotfound}).
+
+%\subsection*{newcounter}\label{newcounter}
+%\subsection*{newline}\label{newline}
+\subsection*{newpage:0}\label{newpage}
+
+Inserts a page break.
+
+\subsection*{nocite:1}\label{nocite}
+
+Specifies that this reference should appear in the bibliography,
+but the citation should not appear in the text.
+
+See also \commandrefn{cite}{cite}.
+
+\subsection*{noindent:0}\label{noindent}
+
+Sets paragraph indentation to zero. See also \commandrefn{parindent}{parindent}.
+
+%\subsection*{nolinebreak}\label{nolinebreak}
+%\subsection*{nopagebreak}\label{nopagebreak}
+
+\subsection*{normalsize:1}\label{normalsize}
+
+Sets the font size back to normal.
+
+\subsection*{onecolumn:0}\label{onecolumn}
+
+Sets the number of columns to one. \LaTeX\ and linear RTF only.
+
+%\subsection*{oddsidemargin}\label{oddsidemargin}
+%\subsection*{pagebreak}\label{pagebreak}
+\subsection*{pageref:1}\label{pageref}
+
+In linear RTF, generates a page reference to the given label.
+
+\subsection*{pagestyle:1}\label{pagestyle}
+
+If argument is {\tt fancyplain} or {\tt fancy}, Tex2RTF
+separates the header from the rest of the page with a rule.
+This command must be defined for headers and footers to
+work properly. See also \commandrefn{setheader}{setheader},
+\commandrefn{setfooter}{setfooter}.
+
+\LaTeX\ and linear RTF only.
+
+\subsection*{pagenumbering:1}\label{pagenumbering}
+
+The argument may be one of:
+
+\begin{description}
+\itemsep=0pt
+\item[alph] a, b, ...
+\item[Alph] A, B, ...
+\item[arabic] 1, 2, ...
+\item[roman] i, ii, ...
+\item[Roman] I, II, ...
+\end{description}
+
+\LaTeX\ and linear RTF only.
+
+\subsection*{paragraph:0}\label{paragraph}
+
+Behaves as for a subsubsection.
+
+\subsection*{paragraph*:0}\label{paragraphX}
+
+Behaves as for a subsubsection.
+
+\subsection*{parindent:1}\label{parindent}
+
+Indents the first line of succeeding paragraphs by the given amount.
+
+\subsection*{parskip:1}\label{parskip}
+
+Changes the spacing between paragraphs. In fact, in RTF this will cause
+two \commandrefn{par}{par} commands to be output if parskip is greater
+than zero.
+
+%\subsection*{part*}\label{partX}
+%\subsection*{part}\label{part}
+\subsection*{par:0}\label{par}
+
+Causes the paragraph to end at this point. \LaTeX\ and Tex2RTF also
+treat two consecutive newlines as a paragraph break.
+
+%\subsection*{pfunc}\label{pfunc}
+%\subsection*{picture}\label{picture}
+\subsection*{printindex:0}\label{printindex}
+
+In linear RTF, inserts an index.
+
+\subsection*{quote:1}\label{quote}
+
+Indents a short quotation.
+
+\subsection*{quotation:1}\label{quotation}
+
+Indents a long quotation.
+
+%\subsection*{raggedbottom}\label{raggedbottom}
+%\subsection*{raggedleft}\label{raggedleft}
+%\subsection*{raggedright}\label{raggedright}
+
+\subsection*{ref:1}\label{ref}
+
+In \LaTeX\ and linear RTF, refers to a \commandrefn{label}{label} and
+causes the number of that section or figure to be printed.
+
+\subsection*{rm:1}\label{rm}
+
+Causes the argument to be formatted in a plain, roman font.
+In fact, does nothing in RTF, HTML and XLP modes.
+
+\subsection*{rmfamily:1}\label{rmfamily}
+
+Causes the argument to be formatted in a plain, roman font.
+In fact, does nothing in RTF, HTML and XLP modes.
+
+%\subsection*{roman}\label{roman1}
+%\subsection*{Roman}\label{Roman2}
+
+\subsection*{sc:1}\label{sc}
+
+Prints the output in small capitals.
+
+\subsection*{scshape:1}\label{scshape}
+
+Prints the output in small capitals.
+
+\subsection*{section:1}\label{section}
+
+Section header, with an entry in the contents page.
+
+\subsection*{section*:1}\label{sectionX}
+
+Section header, with no entry in the contents page.
+
+%\subsection*{setcounter}\label{setcounter}
+\subsection*{sf:1}\label{sf}
+
+Should format in a sans-serif font. Does nothing in Tex2RTF.
+
+\subsection*{sffamily:1}\label{sffamily}
+
+Should format in a sans-serif font. Does nothing in Tex2RTF.
+
+\subsection*{shortcite:1}\label{shortcite}
+
+The same as \commandrefn{cite}{cite}.
+
+%\subsection*{singlespace}\label{singlespace}
+%\subsection*{sloppypar}\label{sloppypar}
+%\subsection*{sloppy}\label{sloppy}
+
+\subsection*{sl:1}\label{sl}
+
+In Tex2RTF, the same as \commandrefn{it}{it}. The LaTeX interpretation is `slanted text'.
+
+\subsection*{slshape:1}\label{slshape}
+
+In Tex2RTF, the same as \commandrefn{itshape}{itshape}. The LaTeX interpretation is `slanted text'.
+
+\subsection*{small:1}\label{small}
+
+Prints the argument in a small font.
+
+\subsection*{special:1}\label{special}
+
+Simply copies the argument to the output file without processing
+(except \verb$\}$ is translated to \verb$}$, and \verb$\{$ is
+translated to \verb${$, to allow for insertion of braces).
+
+\subsection*{ss:0}\label{ss}
+
+Outputs the German sharp S character \ss.
+
+%\subsection*{subitem}\label{subitem}
+\subsection*{subparagraph:1}\label{subparagraph}
+
+Behaves as for a subsubsection.
+
+\subsection*{subparagraph*:1}\label{subparagraphX}
+
+Behaves as for a subsubsection.
+
+\subsection*{subsection:1}\label{subsection}
+
+Subsection header, with an entry in the contents page.
+
+\subsection*{subsection*:1}\label{subsectionX}
+
+Subsection header, with no entry in the contents page.
+
+\subsection*{subsubsection:1}\label{subsubsection}
+
+Subsubsection header, with an entry in the contents page.
+
+\subsection*{subsubsection*:1}\label{subsubsectionX}
+
+Subsubsection header, with no entry in the contents page.
+
+\subsection*{tabbing:1}\label{tabbing}
+
+Tabbing environment: doesn't work properly in RTF.
+
+\subsection*{table:1}\label{table}
+
+An environment for tables. The only thing that Tex2RTF does with this
+is to interpret an embedded \helpref{caption}{caption} command differently
+from figures.
+
+\subsection*{tableofcontents:0}\label{tableofcontents}
+
+Inserts the table of contents at this point. In linear RTF mode, a
+proper Word for Windows table of contents will be inserted unless either
+of the variables {\it insertTOC} or {\it useWord} is set to {\it false}.
+
+\subsection*{tabular:2}\label{tabular}
+
+Tabular environment: an attempt is made to output something
+reasonable in RTF and HTML formats, although currently only simple
+tables will work. The first argument specifies the column formatting.
+a pipe symbol (\verb$|$) denotes a vertical border, one of {\tt l, r, c}\rtfsp
+signifies a normal column of default width, and {\tt p} followed by
+a dimension specifies a column of given width. It is recommended that
+the {\tt p} is used since Tex2RTF cannot deduce a column width in the
+same way that \LaTeX\ can.
+
+Horizontal rules are achieved with \commandrefn{hline}{hline}; two together
+signify a double rule. Note that in HTML, all rows and the table itself are bordered
+automatically.
+
+Use the Tex2RTF \commandrefn{row}{row} and \commandrefn{ruledrow}{ruledrow} commands
+for best effect.
+
+For two-column tables that work in WinHelp files, use \commandrefn{twocollist}{twocollist} instead.
+
+Example:
+
+\begin{verbatim}
+ \begin{tabular}{|l|p{8.5cm}|}\hline
+ \row{{\bf A.I.}&{\bf Simulation}}\hline\hline
+ \row{rules&constraints/methods}
+ \row{planning&design of experiments}
+ \row{diagnosis&analysis of results}
+ \ruledrow{learning&detection of connections}
+ \end{tabular}
+\end{verbatim}
+
+This produces:
+
+\begin{tabular}{|l|p{8.5cm}|}\hline
+\row{{\bf A.I.}&{\bf Simulation}}\hline\hline
+\row{rules&constraints/methods}
+\row{planning&design of experiments}
+\row{diagnosis&analysis of results}
+\ruledrow{learning&detection of connections}
+\end{tabular}
+
+%\subsection*{tab:1}\label{tab}
+\subsection*{TeX:0}\label{TeX}
+
+Outputs the annoying \TeX\ upper and lower case name.
+
+\subsection*{textbf:1}\label{textbf}
+
+Same as \commandrefn{bf}{bf}.
+
+\subsection*{textit:1}\label{textit}
+
+Same as \commandrefn{it}{it}.
+
+\subsection*{textrm:1}\label{textrm}
+
+Same as \commandrefn{rm}{rm}.
+
+\subsection*{textsf:1}\label{textsf}
+
+Same as \commandrefn{sf}{sf}.
+
+\subsection*{textsc:1}\label{textsc}
+
+Same as \commandrefn{sc}{sc}.
+
+\subsection*{textsl:1}\label{textsl}
+
+Same as \commandrefn{sl}{sl}.
+
+\subsection*{texttt:1}\label{texttt}
+
+Same as \commandrefn{tt}{tt}.
+
+
+\subsection*{textwidth:1}\label{textwidth}
+
+Sets the text width (valid for RTF only). This might be used
+in conjunction with \commandrefn{marginpar}{marginpar}, for example,
+to leave space for marginal notes.
+
+%\subsection*{textheight}\label{textheight}
+\subsection*{thebibliography:1}\label{thebibliography}
+
+An environment for specifying the bibliography as a series of\rtfsp
+\commandrefn{bibitem}{bibitem} commands; the preferred method is to use
+\rtfsp{\tt .bib} files and \commandrefn{bibliography}{bibliographycmd} instead.
+
+%\subsection*{titlepage:0}\label{titlepage}
+
+\subsection*{title:1}\label{title}
+
+Sets the title, to be output when the command \commandrefn{maketitle}{maketitle}\rtfsp
+is used.
+
+\subsection*{tiny:1}\label{tiny}
+
+Prints the argument in a very small font.
+
+\subsection*{today:0}\label{today}
+
+Outputs today's date.
+
+%\subsection*{topmargin}\label{topmargin}
+%\subsection*{topskip}\label{topskip}
+\subsection*{tt:1}\label{tt}
+
+Outputs the argument in teletype font.
+
+\subsection*{ttfamily:1}\label{ttfamily}
+
+Outputs the argument in teletype font.
+
+%\subsection*{typein}\label{typein}
+\subsection*{typeout:1}\label{typeout}
+
+Outputs the text on the Tex2RTF text window.
+
+\subsection*{twocolumn:0}\label{twocolumn}
+
+Sets the number of columns to two. \LaTeX\ and linear RTF only.
+
+\subsection*{underline:1}\label{underline}
+
+Underlines the argument.
+
+\subsection*{upshape:1}\label{upshape}
+
+Changes to an upright font. Un-italicizes in RTF mode, no effect in other modes.
+
+\subsection*{verbatiminput:1}\label{verbatiminput}
+
+Include the given file as if it were within a \commandrefn{verbatim}{verbatim}\rtfsp
+environment. The command must not be preceded by any whitespace,
+and spurious whitespace between elements of the command will also
+trip up Tex2RTF.
+
+\subsection*{verbatim:1}\label{verbatim}
+
+Uses a fixed-width font to format the argument without interpreting
+any \LaTeX\ commands.
+
+\subsection*{verb}\label{verb}
+
+The \verb$\verb$ command is like the \commandref{verbatim}{verbatim} environment,
+but for small amounts of text. The syntax is:
+
+\begin{verbatim}
+ \verb<char><text><char>
+\end{verbatim}
+
+The character {\it char} is used as a delimiter; it may be any character
+not ocurring in the following text, except asterisk.
+
+For example, \verb@\verb$\thing%^&$@ produces \verb$\thing%^&$.
+
+%\subsection*{verse}\label{verse}
+%\subsection*{vfill}\label{vfill}
+%\subsection*{vline}\label{vline}
+%\subsection*{void}\label{void}
+%\subsection*{vrule}\label{vrule}
+%\subsection*{vspace*}\label{vspaceX}
+%\subsection*{vskip*}\label{vskipX}
+%\subsection*{vspace}\label{vspace}
+%\subsection*{vskip}\label{vskip}
+
+
+\section{Tex2RTF Commands}
+
+\subsection*{backgroundcolour:1}\label{backgroundcolour}
+
+Specifies the page background colour, in HTML only. The argument consists
+of three numbers from 0 to 255 separated by semicolons, for red, green and blue values respectively.
+
+\begin{verbatim}
+ \backgroundcolour{255;255;255}
+ \backgroundcolour{0;0;255}
+\end{verbatim}
+
+The first example sets the background to white, the second sets the background to blue.
+
+Instead of using a LaTeX command, you may find it more convenient to use the equivalent {\tt .ini} file
+setting, {\it backgroundColour}.
+
+\subsection*{backgroundimage:1}\label{backgroundimage}
+
+Specifies the page background image, in HTML only. The argument
+is a URL for the GIF file to be used as the background.
+
+For example:
+
+\begin{verbatim}
+ \backgroundimage{tile.gif}
+\end{verbatim}
+
+This sets the background to a tile file.
+
+Instead of using a LaTeX command, you may find it more convenient to use the equivalent {\tt .ini} file
+setting, {\it backgroundImage}.
+
+\subsection*{backslashraw:0}\label{backslashraw}
+
+Outputs a raw backslash into the output (not LaTeX). Useful when
+inserting RTF (for example) that cannot be dealt with by Tex2RTF.
+E.g.
+
+\begin{verbatim}
+ \backslashraw{'e3}
+\end{verbatim}
+
+inserts the text \verb$\'e3$ into the RTF file.
+
+\subsection*{bcol:2}\label{bcol}
+
+Sets the background colour for a block of text (RTF only). Has no known effect
+in the RTF readers currently tried (Word for Window and Windows Help).
+
+See also \commandrefn{definecolour}{definecolour}, \commandrefn{fcol}{fcol}.
+
+%\subsection*{baselineskip}
+%\subsection*{boxit:1}\label{boxit}
+
+\subsection*{brclear:0}\label{brclear}
+
+Stops aligning content following a left or right-aligned image in HTML only.
+
+See also \commandrefn{imagel}{imagel}, \commandrefn{imager}{imager}.
+
+\subsection*{cextract:0}\label{cextract}
+
+Prints a C++ extraction operator (\cextract).
+
+\subsection*{chapterheading:1}\label{chapterheading}
+
+Like \commandrefn{chapter}{chapter}, but does not increment the chapter
+number and does not print a chapter number in the printed documentation
+contents page, or in the chapter heading. Used to implement \helpref{glossaries}{glossarysection} and
+other sections that are not real chapters.
+
+\subsection*{cinsert:0}\label{cinsert}
+
+Prints a C++ insertion operator (\cinsert).
+
+\subsection*{class:1}\label{class}
+
+Outputs the argument, an index entry (\LaTeX\ only) and a keyword entry (WinHelp only).
+Used in class reference documentation.
+
+%\subsection*{cleardoublepage}
+%\subsection*{clearpage}
+%\subsection*{cline}
+\subsection*{clipsfunc:3}\label{clipsfunc}
+
+Formats a CLIPS function, given the return value, function name, and
+arguments.
+
+%\subsection*{columnsep}
+\subsection*{copyright:0}\label{copyright}
+
+Outputs the copyright symbol.
+
+\subsection*{cparam:2}\label{cparam}
+
+Formats a CLIPS type and argument. Used within the third argument of
+a \commandrefn{clipsfunc}{clipsfunc} command.
+
+\subsection*{definecolour:4}\label{definecolour}
+
+Defines a new colour that can be used in the document (RTF only). This
+command can also be spelt \verb$\definecolor$.
+
+The first argument is the lower-case name of the colour, and the following
+three arguments specify the red, green and blue intensities, in the range 0 to 255.
+
+The default colours are equivalent to the following definitions:
+
+\begin{verbatim}
+ \definecolour{black}{0}{0}{0}
+ \definecolour{cyan}{0}{255}{255}
+ \definecolour{green}{0}{255}{0}
+ \definecolour{magenta}{255}{0}{255}
+ \definecolour{red}{255}{0}{0}
+ \definecolour{yellow}{255}{255}{0}
+ \definecolour{white}{255}{255}{255}
+\end{verbatim}
+
+To use colours in a document, use the \commandrefn{fcol}{fcol} and \commandrefn{bcol}{bcol} commands.
+
+Note that a document that defines its own colours should be converted twice within
+the same Tex2RTF session.
+
+\subsection*{fcol:2}\label{fcol}
+
+Sets the foreground colour for a block of text (RTF and HTML).
+
+For example:
+
+\begin{verbatim}
+ This sentence is brightened up by some \fcol{red}{red text}.
+\end{verbatim}
+
+gives:
+
+This sentence is brightened up by some \fcol{red}{red text}.
+
+See also \commandrefn{definecolour}{definecolour}, \commandrefn{bcol}{bcol}.
+
+\subsection*{followedlinkcolour:1}\label{followedlinkcolour}
+
+Specifies the followed link colour for the whole page, HTML only. The argument consists
+of three numbers from 0 to 255 separated by semicolons, for red, green and blue values respectively.
+
+For example:
+
+\begin{verbatim}
+ \followedlinkcolour{255;255;255}
+ \followedlinkcolour{0;0;255}
+\end{verbatim}
+
+The first example sets the followed link text to white, and the second sets the followed link text to blue.
+
+See also \commandrefn{backgroundcolour}{backgroundcolour}, \commandrefn{textcolour}{textcolour},
+\rtfsp\commandrefn{linkcolour}{linkcolour}.
+
+Instead of using a LaTeX command, you may find it more convenient to use the equivalent {\tt .ini} file
+setting, {\it followedLinkColour}.
+
+\subsection*{footnotepopup:2}\label{footnotepopup}
+
+In linear RTF, a footnote is created following the first argument, as with
+\commandref{footnote}{footnote}.
+
+In WinHelp RTF, a the first argument is highlighted and becomes
+a popup reference to the second argument. See also \commandref{footnote}{footnote}\rtfsp
+and \commandref{popref}{popref}.
+
+This command is not supported for formats other than \LaTeX,
+linear RTF and WinHelp RTF.
+
+%\subsection*{footskip}\label{footskip}
+%\subsection*{framebox:1}\label{framebox}
+
+\subsection*{functionsection:1}\label{functionsection}
+
+Defines a subsection, adding the C++ function name to the \LaTeX\ index or the
+WinHelp keyword list.
+
+Should be followed by a \commandrefn{func}{func} command to specify function
+details.
+
+\subsection*{func:3}\label{func}
+
+Defines a C++ function, given the return type, function name, and parameter list.
+
+Should occur after a \commandrefn{functionsection}{functionsection} command.
+
+%\subsection*{glossary:}\label{glossary}
+\subsection*{gloss:1}\label{gloss}
+
+Marks a glossary entry. In \LaTeX, this is a synonym for an \commandrefn{item}{item}
+with an optional argument, within a \commandrefn{description}{description} environment,
+and the argument is added to the index.
+
+In Windows Help, this is identical to a \commandrefn{section*}{sectionX} in a report.
+
+If labels are associated with the glossary entries, they can be referenced by
+\commandref{helpref}{helpref} or \commandref{popref}{popref} jumps. A glossary entry is
+currently the only type of destination that popref may refer to.
+
+This is an example of making a glossary in a report:
+
+\begin{verbatim}
+ \begin{helpglossary}
+
+ \gloss{API}\label{api}
+
+ Application Programmer's Interface - a set of calls and
+ classes defining how a library (in this case, wxWindows)
+ can be used.
+
+ \gloss{Canvas}\label{canvas}
+
+ A canvas in XView and wxWindows is a subwindow...
+
+ \gloss{DDE}\label{dde}
+
+ Dynamic Data Exchange - Microsoft's interprocess
+ communication protocol. wxWindows provides an abstraction
+ of DDE under both Windows and UNIX.
+
+ \end{helpglossary}
+\end{verbatim}
+
+%\subsection*{headheight}\label{headheight}
+\subsection*{helpglossary:1}\label{helpglossary}
+
+An environment for making a glossary (not standard \LaTeX). See \commandrefn{gloss}{gloss} for
+usage.
+
+\subsection*{helpignore:1}\label{helpignore}
+
+Ignores the argument in Tex2RTF generated files, but not \LaTeX.
+
+\subsection*{helponly:1}\label{helponly}
+
+Only outputs the argument in Tex2RTF generated files.
+
+\subsection*{helpinput:1}\label{helpinput}
+
+Only includes the given file in Tex2RTF generated files.
+
+\subsection*{helpfontfamily:1}\label{helpfontfamily}
+
+Specifies the font family for Tex2RTF generated files. The argument
+may be Swiss or Times.
+
+\subsection*{helpfontsize:1}\label{helpfontsize}
+
+Specifies the font size for Tex2RTF generated files.
+
+\subsection*{helpref:2}\label{helpref}
+
+Specifies a jump to a labelled chapter, section, subsection subsubsection
+or figure.
+
+The first argument is text to be highlighted (mouseable in help systems)
+and the second is the reference label. In linear documents, the section number
+is given following the text, unless the \commandrefn{helprefn}{helprefn} command
+is used instead, where the section number is suppressed.
+
+Note that when generating HTML, the label {\it contents} is automatically defined,
+and may be referenced using \verb$\helpref$.
+
+\subsection*{helprefn:2}\label{helprefn}
+
+Specifies a jump to a labelled chapter, section, subsection subsubsection
+or figure.
+
+The first argument is text to be highlighted (mouseable in help systems)
+and the second is the reference label. See \commandrefn{helpref}{helpref} for
+the form where the section number is printed in linear documents.
+
+%\subsection*{hfill}\label{hfill}
+\subsection*{htmlignore:1}\label{htmlignore}
+
+Ignores the argument in HTML.
+
+\subsection*{htmlonly:1}\label{htmlonly}
+
+Only outputs the argument in HTML.
+
+\subsection*{image:2}\label{image}
+
+This is translated to a PSBOX macro package \verb$\psboxto$ command in \LaTeX,
+the first argument being a sizing command and the second a filename.
+
+In HTML mode, the second argument is used to generate a PostScript file reference.
+
+In RTF mode, the second argument is tried with first a BMP extension and
+then a WMF extension to find a suitable Windows bitmap file, placeable
+metafile, or segmented hypergraphics file (.SHG). If a suitable file is
+found, in Windows Help mode a {\tt bmc}\rtfsp command is inserted into
+the RTF file with a reference to the file. In linear RTF mode, the
+bitmap or metafile is converted into hex and inserted into the RTF
+document.
+
+Note that only RGB-encoded Windows bitmaps, or placeable metafiles, are
+valid for input to Tex2RTF. You can convert a RLE (run length encoded)
+bitmap file into a (bigger) RGB file using a program such as Paintshop
+Pro. A placeable metafile has a special header with dimension
+information. One may be constructed by a wxWindows program by calling
+the function wxMakeMetafilePlaceable. The Microsoft Windows SDK has a
+sample program that loads and steps through placeable and ordinary
+metafiles.
+
+Another wrinkle is that programs differ in the methods they
+use to recognise pictures in RTF files. You may need to use the {\it bitmapMethod} setting,
+which can be ``hex'' (embed the hex data in the file with a \verb$\dibitmap$ keyword),
+``includepicture'' (use the MS Word 6.0 INCLUDEPICTURE field) or ``import''
+(an earlier name for INCLUDEPICTURE).
+
+Here is an example of using the \verb$\image$ command.
+
+\begin{verbatim}
+ \begin{figure}
+ $$\image{5cm;0cm}{heart.ps}$$
+
+ \caption{My picture}\label{piccy}
+ \end{figure}
+\end{verbatim}
+
+The dollars centre the image in the horizontal plane. The syntax
+of the first argument to \verb$\image$ is taken from syntax used by the \verb$\psbox$\rtfsp
+package: it allows specification of the horizontal and vertical
+dimensions of the image. Scaling will take place for PostScript
+and metafile images. A value of zero indicates that the image should
+be scaled in proportion to the non-zero dimension. Zeros for both
+dimensions will leave the image unscaled in the case of metafiles,
+or scaled to fit the page in the case of PostScript.
+
+See also \commandrefn{imagel}{imagel}, \commandrefn{imager}{imager} for aligned images in
+HTML.
+
+\subsection*{imagel:2}\label{imagel}
+
+Similar to \commandrefn{image}{image}, but left-aligns the image with respect to the following
+content. Use \commandrefn{brclear}{brclear} to stop aligning the content to the right of the image.
+
+See also \commandrefn{imager}{imager}.
+
+\subsection*{imagemap:3}\label{imagemap}
+
+This is translated to an HTML image map reference, or (in LaTeX) a PostScript psbox
+command. This allows images in HTML to have hotspots, where the user clicks on a
+part of the image and the browser jumps to a particular file.
+
+The first argument is the same as the first argument to the \commandref{image}{image}\rtfsp
+command (ignored in HTML). The second argument must be the name of the
+image map entry, and the second is the filename to be displayed inline.
+
+\begin{verbatim}
+ \imagemap{}{tree.gif}{myname}
+\end{verbatim}
+
+translates to:
+
+\begin{verbatim}
+ <a href="/cgi-bin/imagemap/mymap">
+ <img src="tree.gif" ismap></a><p>
+\end{verbatim}
+
+The snag with this is that, apart from the inconvenience of having to
+register a map file with the server, the map file will also have
+references to particular HTML files. If they exist in the current
+document, these names are not known until the file is generated. In which case, the
+map entries should probably refer to symbolic links that can be easily
+changed later.
+
+\subsection*{imager:2}\label{imager}
+
+Similar to \commandrefn{image}{image}, but right-aligns the image with respect to the following
+content. Use \commandrefn{brclear}{brclear} to stop aligning the content to the left of the image.
+
+See also \commandrefn{imagel}{imagel}.
+
+%\subsection*{includeonly}\label{includeonly}
+\subsection*{indented:2}\label{indented}
+
+Environment supplied by Tex2RTF to allow (possibly nested) indentation of
+\LaTeX\ and RTF text. The first argument is the amount to be indented.
+
+For example:
+
+\begin{verbatim}
+ \begin{indented}{2cm}
+ This text should be indented by a couple of centimetres.
+ This can be useful to highlight paragraphs.
+ \end{indented}
+\end{verbatim}
+
+produces:
+
+\begin{indented}{2cm}
+This text should be indented by a couple of centimetres. This can be
+useful to highlight paragraphs.
+\end{indented}
+
+\subsection*{latexignore:1}\label{latexignore}
+
+Ignores the argument in \LaTeX.
+
+\subsection*{latexonly:1}\label{latexonly}
+
+Only prints the argument in \LaTeX.
+
+%\subsection*{lbox}\label{lbox}
+
+\subsection*{lbraceraw:0}\label{lbraceraw}
+
+Outputs a raw left brace into the output (not LaTeX). Useful when
+inserting RTF (for example) that cannot be dealt with by Tex2RTF.
+
+\subsection*{linkcolour:1}\label{linkcolour}
+
+Specifies the link colour for the whole page, HTML only. The argument consists
+of three numbers from 0 to 255 separated by semicolons, for red, green and blue values respectively.
+
+For example:
+
+\begin{verbatim}
+ \linkcolour{255;255;255}
+ \linkcolour{0;0;255}
+\end{verbatim}
+
+The first example sets the link text to white, and the second sets the link text to blue.
+
+See also \commandrefn{backgroundcolour}{backgroundcolour}, \commandrefn{textcolour}{textcolour},
+\rtfsp\commandrefn{followedlinkcolour}{followedlinkcolour}.
+
+Instead of using a LaTeX command, you may find it more convenient to use the equivalent {\tt .ini} file
+setting, {\it linkColour}.
+
+\subsection*{membersection:1}\label{membersection}
+
+Used when formatting C++ classes to print a subsection for the member name.
+
+\subsection*{member:1}\label{member}
+
+Used to format a C++ member variable name.
+
+\subsection*{normalbox:1}\label{normalbox}
+
+Draws a box around the given paragraph in \LaTeX\ and RTF. In HTML
+and XLP formats, horizontal rules are drawn before and after the text.
+
+For example:
+
+\begin{verbatim}
+ \normalbox{This should be a boxed paragraph for highlighting
+ important information, such as information for registering
+ a shareware program.}
+\end{verbatim}
+
+gives:
+
+\normalbox{This should be a boxed paragraph for highlighting important
+information, such as information for registering a shareware program.}
+
+See also \commandrefn{normalboxd}{normalboxd} for double-bordered text.
+
+\subsection*{normalboxd:1}\label{normalboxd}
+
+Draws a double border around the given paragraph in \LaTeX\ and RTF. In
+HTML and XLP formats, horizontal rules are drawn before and after the
+text.
+
+For example:
+
+\begin{verbatim}
+ \normalboxd{This should be a boxed paragraph for
+ highlighting important information, such as information
+ for registering a shareware program.}
+\end{verbatim}
+
+gives:
+
+\normalboxd{This should be a boxed paragraph for highlighting important
+information,such as information for registering a shareware program.}
+
+See also \commandrefn{normalbox}{normalbox} for single-bordered text.
+
+\subsection*{param:1}\label{param}
+
+Formats a C++ type and argument pair. Should be used within the third argument
+of a a \commandrefn{func}{func} command.
+
+\subsection*{popref:2}\label{popref}
+
+Similar to \commandrefn{helprefn}{helprefn}, except that in Windows Help,
+the destination text is popped up in a small window to be dismissed with
+a mouse click, instead of going to a separate section.
+
+Currently this command can only refer to a labelled glossary entry; see
+\commandrefn{gloss}{gloss}.
+
+\subsection*{psboxto:2}\label{psboxto}
+
+Identical to \commandrefn{image}{image}.
+
+%\subsection*{psbox}\label{psbox}
+\subsection*{rbraceraw:0}\label{rbraceraw}
+
+Outputs a raw right brace into the output (not LaTeX). Useful when
+inserting RTF (for example) that cannot be dealt with by Tex2RTF.
+
+\subsection*{registered:0}\label{registered}
+
+Outputs the `registered' symbol in HTML, and (r) in other formats.
+
+\subsection*{row:1}\label{row}
+
+A Tex2RTF command signifying the row of a table within the \commandrefn{tabular}{tabular}\rtfsp
+environment. See also \commandrefn{ruledrow}{ruledrow}.
+
+\subsection*{ruledrow:1}\label{ruledrow}
+
+A Tex2RTF command signifying a ruled row of a table within the \commandrefn{tabular}{tabular}\rtfsp
+environment. See also \commandrefn{row}{row}.
+
+\subsection*{rtfignore:1}\label{rtfignore}
+
+Ignores the argument in linear RTF.
+
+\subsection*{rtfonly:1}\label{rtfonly}
+
+Only outputs the argument in linear RTF.
+
+\subsection*{rtfsp:0}\label{rtfsp}
+
+Outputs a space in RTF. Tex2RTF tries to insert a space where one is implied
+by a newline, but cannot cope where a line starts or ends with a command,
+in the middle of a paragraph. Use this command to insert a space explicitly.
+
+\subsection*{sectionheading:1}\label{sectionheading}
+
+Like \commandrefn{section}{section}, but does not increment the section
+number and does not print a section number in the printed documentation
+contents page, or in the section heading.
+
+\subsection*{setfooter:6}\label{setfooter}
+
+Tex2RTF has a non-standard way of setting headers and footers,
+but the default macro definitions in {\tt texhelp.sty} may be altered
+to your current method.
+
+The arguments are as follows:
+
+\begin{enumerate}
+\itemsep=0pt
+\item Left footer, even pages
+\item Centre footer, even pages
+\item Right footer, even pages
+\item Left footer, odd pages
+\item Centre footer, odd pages
+\item Right footer, odd pages
+\end{enumerate}
+
+For many documents, the first three arguments will be left empty.
+
+The behaviour for first pages of a chapter, section or document
+is to have a blank header, but print the footer.
+
+For best results, define headers and footers for {\it each chapter or
+section}.
+
+Note that this command works only for \LaTeX\ and linear RTF. See also\rtfsp
+\commandrefn{setheader}{setheader}.
+
+\subsection*{setheader:6}\label{setheader}
+
+Tex2RTF has a non-standard way of setting headers and footers,
+but the default macro definitions in {\tt texhelp.sty} may be altered
+to your current method.
+
+The arguments are as follows:
+
+\begin{enumerate}
+\itemsep=0pt
+\item Left header, even pages
+\item Centre header, even pages
+\item Right header, even pages
+\item Left header, odd pages
+\item Centre header, odd pages
+\item Right header, odd pages
+\end{enumerate}
+
+For many documents, the first three arguments will be left empty.
+If \commandrefn{pagestyle}{pagestyle} is not plain or empty, the
+header will separated from the rest of the page by a rule.
+
+The behaviour for first pages of a chapter, section or document
+is to have a blank header, but print the footer.
+
+For best results, define headers and footers for {\it each chapter or
+section}.
+
+Note that this command works only for \LaTeX\ and linear RTF. See also\rtfsp
+\commandrefn{setfooter}{setfooter}.
+
+\subsection*{sethotspotcolour:1}\label{sethotspotcolour}
+
+If the argument is yes, on or ok, subsequent WinHelp hotspots will be green.
+If any other value, the hotspots will be the normal text colour. Note that this
+doesn't apply to section hotspots, only to helpref hotspots.
+
+\subsection*{sethotspotunderline:1}\label{sethotspotunderline}
+
+If the argument is yes, on or ok, subsequent WinHelp hotspots will be
+underlined (the default). If any other value, the hotspots will not be
+underlined. Note that this doesn't apply to section hotspots, only to
+helpref hotspots.
+
+\subsection*{settransparency:1}\label{settransparency}
+
+WinHelp mode only (version 4 of WinHelp). If the argument is yes, on or ok, subsequent bitmaps
+will be inserted in transparent mode: areas of white will be made transparent.
+If the argument is any other value (such as no, ok or false), the bitmaps will not be transparent.
+
+\subsection*{textcolour:1}\label{textcolour}
+
+Specifies the text foreground colour for the whole page, HTML only. The argument consists
+of three numbers from 0 to 255 separated by semicolons, for red, green and blue values respectively.
+
+For example:
+
+\begin{verbatim}
+ \textcolour{255;255;255}
+ \textcolour{0;0;255}
+\end{verbatim}
+
+The first example sets the text to white, and the second sets the text to blue.
+
+See also \commandrefn{backgroundcolour}{backgroundcolour}, \commandrefn{linkcolour}{linkcolour},
+\rtfsp\commandrefn{followedlinkcolour}{followedlinkcolour}.
+
+Instead of using a LaTeX command, you may find it more convenient to use the equivalent {\tt .ini} file
+setting, {\it textColour}.
+
+\subsection*{toocomplex:1}\label{toocomplex}
+
+An environment for dealing with complex \LaTeX\ commands that
+Tex2RTF cannot handle. In normal \LaTeX, the argument will be output
+as normal. In Tex2RTF output, the argument will be output as verbatim text,
+for the user to hand-translate into the desired output format.
+
+See also \commandrefn{comment}{comment}.
+
+\subsection*{twocolitem:2}\label{twocolitem}
+
+Used to specify a row for a two column list, a Tex2RTF
+extension to optimize two-column lists for different
+file formats. See \commandrefn{twocollist}{twocollist},
+\rtfsp\commandrefn{twocolitemruled}{twocolitemruled}.
+
+\subsection*{twocolitemruled:2}\label{twocolitemruled}
+
+Used to specify a ruled row for a two column list, a Tex2RTF
+extension to optimize two-column lists for different
+file formats. See \commandrefn{twocollist}{twocollist},
+\rtfsp\commandrefn{twocolitem}{twocolitem}.
+
+\subsection*{twocollist:1}\label{twocollist}
+
+A Tex2RTF environment for specifying a table of two columns, often
+used in manuals and help files (for example, for listing commands and
+their meanings). The first column should be one line only, and
+the second can be an arbitrary number of paragraphs.
+
+The reason that a normal tabular environment cannot be used is that
+WinHelp does not allow borders in table cells, so a different method
+must be employed if any of the rows are to be ruled. In \LaTeX, a table
+is used to implement this environment. In RTF, indentation is used instead.
+
+Use this environment in conjunction with \commandrefn{twocolitem}{twocolitem} and\rtfsp
+\commandrefn{twocolitemruled}{twocolitemruled}. To set the widths of the first
+and second column, use \commandrefn{twocolwidtha}{twocolwidtha} and\rtfsp
+\commandrefn{twocolwidthb}{twocolwidthb}.
+
+Example:
+
+\begin{verbatim}
+ \htmlignore{\begin{twocollist}}
+ \twocolitemruled{{\bf Command}}{{\bf Description}}
+ \twocolitem{File}{The file menu is used to select various
+ file-related operations, such as saving and loading.}
+ \twocolitem{Edit}{The Edit menu is used for
+ selection, copying, pasting, etc.}
+ \end{twocollist}
+\end{verbatim}
+
+This produces:
+
+\begin{twocollist}
+\twocolitemruled{{\bf Command}}{{\bf Description}}
+\twocolitem{File}{The file menu is used to select various file-related
+operations, such as saving and loading.}
+\twocolitem{Edit}{The Edit menu is used for selection, copying, pasting, etc.}
+\end{twocollist}
+
+\subsection*{twocolwidtha:1}\label{twocolwidtha}
+
+Sets the width of the first column in a two column list to the given
+dimension. See also \commandrefn{twocollist}{twocollist} and \commandrefn{twocolwidthb}{twocolwidthb}.
+
+\subsection*{twocolwidthb:1}\label{twocolwidthb}
+
+Sets the width of the second column in a two column list to the given
+dimension. See also \commandrefn{twocollist}{twocollist} and \commandrefn{twocolwidtha}{twocolwidtha}.
+
+\subsection*{urlref:2}\label{urlref}
+
+Specifies a jump to a URL (univeral resource location).
+
+The first argument is text to be highlighted (mouseable in HTML browsers)
+and the second is the URL. In linear documents, the URL
+is given following the text.
+
+Example:
+
+\begin{verbatim}
+ See also the \urlref{wxWindows manual}
+ {http://www.aiai.ed.ac.uk/~jacs.html}.
+\end{verbatim}
+
+(the line is broken only to keep to this manual's page width).
+
+\subsection*{winhelpignore:1}\label{winhelpignore}
+
+Ignores the argument in WinHelp RTF.
+
+\subsection*{winhelponly:1}\label{winhelponly}
+
+Only outputs the argument in WinHelp RTF.
+
+\subsection*{xlpignore:1}\label{xlpignore}
+
+Ignores the argument in XLP mode (wxHelp files).
+
+\subsection*{xlponly:1}\label{xlponly}
+
+Only outputs the argument in XLP mode (wxHelp files).
+
+\section{Accents}\label{accents}
+
+The following \LaTeX\ accents work for RTF and HTML production:
+
+\begin{itemize}%
+\itemsep=0pt
+\item \verb$\'{a}$ produces \'{a}. Valid for a, e, i, o, u, A, E, I, O, U
+\item \verb$\`{a}$ produces \`{a}. Valid for a, e, i, o, u, y, A, E, I, O, U, Y
+\item \verb$\^{a}$ produces \^{a}. Valid for a, e, i, o, u, A, E, I, O, U
+\item \verb$\~{a}$ produces \~{a}. Valid for a, n, o, A, N, O
+\item \verb$\"{a}$ produces \"{a}. Valid for a, e, i, o, u, y, A, E, I, O, U, Y
+\item \verb$\.{a}$ produces \.{a}. Valid for a, A
+\end{itemize}
+
+\section{Commands by category}\index{commands}%
+
+Below are categories of \LaTeX\ commands, to help you find the right
+command for a particular purpose.
+
+\subsection{Font commands}
+
+\begin{itemize}\itemsep=0pt
+\item \commandpageref{bf}{bf}
+\item \commandpageref{bffamily}{bffamily}
+\item \commandpageref{em}{em}
+\item \commandpageref{emph}{emph}
+\item \commandpageref{huge}{huge1}
+\item \commandpageref{Huge}{Huge2}
+\item \commandpageref{HUGE}{HUGE3}
+\item \commandpageref{it}{it}
+\item \commandpageref{itshape}{itshape}
+\item \commandpageref{large}{large1}
+\item \commandpageref{Large}{Large2}
+\item \commandpageref{LARGE}{LARGE3}
+\item \commandpageref{mdseries}{mdseries}
+\item \commandpageref{normalsize}{normalsize}
+\item \commandpageref{rm}{rm}
+\item \commandpageref{rmfamily}{rmfamily}
+\item \commandpageref{sc}{sc}
+\item \commandpageref{scshape}{scshape}
+\item \commandpageref{sf}{sf}
+\item \commandpageref{sffamily}{sffamily}
+\item \commandpageref{sl}{sl}
+\item \commandpageref{slshape}{slshape}
+\item \commandpageref{small}{small}
+\item \commandpageref{textbf}{textbf}
+\item \commandpageref{textit}{textit}
+\item \commandpageref{textrm}{textrm}
+\item \commandpageref{textsf}{textsf}
+\item \commandpageref{textsc}{textsc}
+\item \commandpageref{textsl}{textsl}
+\item \commandpageref{texttt}{texttt}
+\item \commandpageref{tiny}{tiny}
+\item \commandpageref{tt}{tt}
+\item \commandpageref{ttfamily}{ttfamily}
+\item \commandpageref{underline}{underline}
+\item \commandpageref{upshape}{upshape}
+\end{itemize}
+
+\subsection{Paragraph formatting}
+
+\begin{itemize}\itemsep=0pt
+\item \commandpageref{centerline}{centerline}
+\item \commandpageref{comment}{comment}
+\item \commandpageref{flushleft}{flushleft}
+\item \commandpageref{footnote}{footnote}
+\item \commandpageref{indented}{indented}
+\item \commandpageref{marginparwidth}{marginparwidth}
+\item \commandpageref{marginpar}{marginpar}
+\item \commandpageref{marginpareven}{marginpareven}
+\item \commandpageref{marginparodd}{marginparodd}
+\item \commandpageref{multicolumn}{multicolumn}
+\item \commandpageref{newpage}{newpage}
+\item \commandpageref{noindent}{noindent}
+\item \commandpageref{onecolumn}{onecolumn}
+\item \commandpageref{parindent}{parindent}
+\item \commandpageref{parskip}{parskip}
+\item \commandpageref{par}{par}
+\item \commandpageref{quote}{quote}
+\item \commandpageref{quotation}{quotation}
+\item \commandpageref{textwidth}{textwidth}
+\item \commandpageref{twocolumn}{twocolumn}
+\item \commandpageref{verbatim}{verbatim}
+\item \commandpageref{verb}{verb}
+\end{itemize}
+
+\subsection{Special effects}
+
+\begin{itemize}\itemsep=0pt
+\item \commandpageref{backgroundcolour}{backgroundcolour}
+\item \commandpageref{backgroundimage}{backgroundimage}
+\item \commandpageref{backslashraw}{backslashraw}
+\item \commandpageref{bcol}{bcol}
+\item \commandpageref{definecolour}{definecolour}
+\item \commandpageref{fcol}{fcol}
+\item \commandpageref{followedlinkcolour}{followedlinkcolour}
+\item \commandpageref{helpfontfamily}{helpfontfamily}
+\item \commandpageref{helpfontsize}{helpfontsize}
+\item \commandpageref{hrule}{hrule}
+\item \commandpageref{linkcolour}{linkcolour}
+\item \commandpageref{normalbox}{normalbox}
+\item \commandpageref{normalboxd}{normalboxd}
+\item \commandpageref{sethotspotcolour}{sethotspotcolour}
+\item \commandpageref{sethotspotunderline}{sethotspotunderline}
+\item \commandpageref{settransparency}{settransparency}
+\item \commandpageref{textcolour}{textcolour}
+\item \commandpageref{typeout}{typeout}
+\end{itemize}
+
+\subsection{Lists}
+
+\begin{itemize}\itemsep=0pt
+\item \commandpageref{description}{description}
+\item \commandpageref{enumerate}{enumerate}
+\item \commandpageref{itemize}{itemize}
+\item \commandpageref{item}{item}
+\item \commandpageref{itemsep}{itemsep}
+\item \commandpageref{twocolitem}{twocolitem}
+\item \commandpageref{twocolitemruled}{twocolitemruled}
+\item \commandpageref{twocollist}{twocollist}
+\item \commandpageref{twocolwidtha}{twocolwidtha}
+\item \commandpageref{twocolwidthb}{twocolwidthb}
+\end{itemize}
+
+\subsection{Sectioning}
+
+\begin{itemize}\itemsep=0pt
+\item \commandpageref{chapter}{chapter}
+\item \commandpageref{chapter*}{chaptersX}
+\item \commandpageref{chapterheading}{chapterheading}
+\item \commandpageref{insertatlevel}{insertatlevel}
+\item \commandpageref{paragraph}{paragraph}
+\item \commandpageref{paragraph*}{paragraphX}
+\item \commandpageref{section}{section}
+\item \commandpageref{section*}{sectionX}
+\item \commandpageref{sectionheading}{sectionheading}
+\item \commandpageref{subparagraph}{subparagraph}
+\item \commandpageref{subparagraph*}{subparagraphX}
+\item \commandpageref{subsection}{subsection}
+\item \commandpageref{subsection*}{subsectionX}
+\item \commandpageref{subsubsection}{subsubsection}
+\item \commandpageref{subsubsection*}{subsubsectionX}
+\end{itemize}
+
+\subsection{Pictures}
+
+\begin{itemize}\itemsep=0pt
+\item \commandpageref{brclear}{brclear}
+\item \commandpageref{image}{image}
+\item \commandpageref{imagel}{imagel}
+\item \commandpageref{imagemap}{imagemap}
+\item \commandpageref{imager}{imager}
+\item \commandpageref{psboxto}{psboxto}
+\end{itemize}
+
+\subsection{References and jumps}
+
+\begin{itemize}\itemsep=0pt
+\item \commandpageref{footnotepopup}{footnotepopup}
+\item \commandpageref{helpref}{helpref}
+\item \commandpageref{helprefn}{helprefn}
+\item \commandpageref{label}{label}
+\item \commandpageref{pageref}{pageref}
+\item \commandpageref{popref}{popref}
+\item \commandpageref{ref}{ref}
+\item \commandpageref{urlref}{urlref}
+\end{itemize}
+
+\subsection{Tables and figures}
+
+\begin{itemize}\itemsep=0pt
+\item \commandpageref{caption}{caption}
+\item \commandpageref{figure}{figure}
+\item \commandpageref{hline}{hline}
+\item \commandpageref{ruledrow}{ruledrow}
+\item \commandpageref{tabbing}{tabbing}
+\item \commandpageref{tabular}{tabular}
+\end{itemize}
+
+\subsection{Table of contents}
+
+\begin{itemize}\itemsep=0pt
+\item \commandpageref{addcontentsline}{addcontentsline}
+\item \commandpageref{author}{author}
+\item \commandpageref{date}{date}
+\item \commandpageref{maketitle}{maketitle}
+\item \commandpageref{tableofcontents}{tableofcontents}
+\item \commandpageref{title}{title}
+\end{itemize}
+
+\subsection{Special sections}
+
+\begin{itemize}\itemsep=0pt
+\item \commandpageref{bibitem}{bibitem}
+\item \commandpageref{bibliographystyle}{bibliographystyle}
+\item \commandpageref{bibliography}{bibliographycmd}
+\item \commandpageref{cite}{cite}
+\item \commandpageref{gloss}{gloss}
+\item \commandpageref{helpglossary}{helpglossary}
+\item \commandpageref{index}{index}
+\item \commandpageref{nocite}{nocite}
+\item \commandpageref{printindex}{printindex}
+\item \commandpageref{shortcite}{shortcite}
+\item \commandpageref{thebibliography}{thebibliography}
+\end{itemize}
+
+
+\subsection{Symbols}
+
+\begin{itemize}\itemsep=0pt
+\item \commandpageref{backslash}{backslash}
+\item \commandpageref{cdots}{cdots}
+\item \commandpageref{cextract}{cextract}
+\item \commandpageref{cinsert}{cinsert}
+\item \commandpageref{copyright}{copyright}
+\item \commandpageref{LaTeX}{LaTeX}
+\item \commandpageref{lbraceraw}{lbraceraw}
+\item \commandpageref{ldots}{ldots}
+\item \commandpageref{rbraceraw}{rbraceraw}
+\item \commandpageref{registered}{registered}
+\item \commandpageref{rtfsp}{rtfsp}
+\item \commandpageref{ss}{ss}
+\item \commandpageref{TeX}{TeX}
+\item \commandpageref{today}{today}
+\end{itemize}
+
+\subsection{Document organisation}
+
+\begin{itemize}\itemsep=0pt
+\item \commandpageref{document}{document}
+\item \commandpageref{documentstyle}{documentstyle}
+\item \commandpageref{helpignore}{helpignore}
+\item \commandpageref{helponly}{helponly}
+\item \commandpageref{helpinput}{helpinput}
+\item \commandpageref{htmlignore}{htmlignore}
+\item \commandpageref{htmlonly}{htmlonly}
+\item \commandpageref{include}{include}
+\item \commandpageref{input}{input}
+\item \commandpageref{latexignore}{latexignore}
+\item \commandpageref{latexonly}{latexonly}
+\item \commandpageref{newcommand}{newcommand}
+\item \commandpageref{pagestyle}{pagestyle}
+\item \commandpageref{pagenumbering}{pagenumbering}
+\item \commandpageref{rtfignore}{rtfignore}
+\item \commandpageref{rtfonly}{rtfonly}
+\item \commandpageref{setfooter}{setfooter}
+\item \commandpageref{setheader}{setheader}
+\item \commandpageref{special}{special}
+\item \commandpageref{toocomplex}{toocomplex}
+\item \commandpageref{verbatiminput}{verbatiminput}
+\item \commandpageref{winhelpignore}{winhelpignore}
+\item \commandpageref{winhelponly}{winhelponly}
+\item \commandpageref{xlpignore}{xlpignore}
+\item \commandpageref{xlponly}{xlponly}
+\end{itemize}
+
+\chapter{Bugs and troubleshooting}\label{errors}\index{bugs}\index{errors}\index{troubleshooting}%
+\setheader{{\it CHAPTER \thechapter}}{}{}{}{}{{\it CHAPTER \thechapter}}%
+\setfooter{\thepage}{}{}{}{}{\thepage}%
+
+\section{Bugs}
+
+\begin{description}
+\item[Command parsing.] If a command is used followed by inappropriate
+argument syntax, Tex2RTF can crash. This an occur when a command is
+used in an asterisk form that is only formed in the non-asterisk
+variety. The non-asterisk form is assumed, which makes the following
+asterisk trip up the parser.
+\item[Setlength.] Using the $\backslash$setlength command doesn't work,
+since its first argument looks like a command with the wrong number
+of arguments. Use an alternative form instead, e.g. \verb$\parindent 0pt$ instead
+of \verb$\setlength{parindent}{0pt}$.
+\item[Newcommand bug.] Environments in a command definition confuse
+Tex2RTF. Use the command form instead (e.g. $\backslash$flushleft\{...\} instead
+of $\backslash$begin\{flushleft\} ... $\backslash$end\{flushleft\}.
+\item[Bibliography.] There's no flexibility in the way references
+are output: I expect I'll get round to doing something better,
+but only if people tell me they need it!
+\item[Tables.] Tables can't handle all \LaTeX\ syntax, and require
+the Tex2RTF \verb$\row$ commands for decent formatting. Still, it's
+better than it was (RTF only).
+\item[Indexes and glossaries.] Not completely supported.
+\item[Crashes.] Crashes may be due to an input file exceeding the fixed-size
+buffer used for converting command arguments, especially for the \verb$\verbatim$\rtfsp
+command. Use the {\tt -bufsize} switch to increase the buffer size.
+\item[Verbatiminput.] Verbatiminput files which do not end with a blank line
+can trip up following commands.
+\end{description}
+
+\section{Troubleshooting}
+
+Below are some common problems and possible solutions.
+
+\normalbox{Some of the syntax that is OK for true \LaTeX\ but which trips up
+Tex2RTF, may be detected by the TCHECK program included in the tools
+directory of the Tex2RTF distribution. Some \LaTeX\ errors may be picked up
+by the LACHECK program, also found in the tools directory.}
+
+\subsection{Macro not found}\label{macronotfound}\index{macro not found error}%
+
+This error may indicate that Tex2RTF has not implemented a standard
+\rtfsp\LaTeX\ command, or that a local macro package is being used that
+Tex2RTF does not know about. It can cause spurious secondary
+errors, such as not recognising the end document command.
+
+You can get round this by defining a macro file (default name {\tt tex2rtf.ini})
+containing command definitions, such as:
+
+\begin{verbatim}
+ \crazy [2]{{\bf #2} is crazy but #1 is not}
+ \something [0]{}
+ \julian [0]{Julian Smart}
+\end{verbatim}
+
+New commands may be defined in \LaTeX\ files, but custom macro files
+will have to be defined when local style files are being used. See\rtfsp
+\helpref{Initialisation file syntax}{inifile} for further details.
+
+The `Macro not found' error can also be caused by a syntax error such as
+an unbalanced brace or passing the wrong number of arguments to a command,
+so look in the vicinity of the reported error for the real cause.
+
+Here is one obscure situation that causes this error:
+
+\begin{verbatim}
+ \begin{center}
+ {\large{\underline{A}}}
+ \end{center}
+\end{verbatim}
+
+The problem is too many curly brackets. This should be rewritten as:
+
+\begin{verbatim}
+ \begin{center}
+ {\large \underline{A}}
+ \end{center}
+\end{verbatim}
+
+Often you get a `Macro not found' error for \verb$\end{document}$. This
+is a spurious side-effect of an earlier error, usually an incorrect number
+of arguments to a command. The location of the true error is then anywhere
+in the document. To home in on the error, try putting a verbatim environment
+\rtfsp\verb$\begin{comment}...\end{comment}$ around much of the document,
+and then move the \verb$\begin{comment}$ line down until the error
+manifests itself.
+
+\subsection{Unresolved reference}\index{references, unresolved}%
+
+References and citations are usually resolved on a second pass of
+Tex2RTF. If this doesn't work, then a missing label or bibliographical
+entry is to blame.
+
+\subsection{Output crashes the RTF reader}
+
+This could be due to confusing table syntax. Set {\it compatibility} to\rtfsp
+{\it TRUE} in {\tt .ini} file; also check for end of row characters backslash characters
+on their own on a line, and insert correct number of ampersands for the number of
+columns. E.g.
+
+\begin{verbatim}
+ hello & world\\
+ \\
+\end{verbatim}
+
+becomes
+
+\begin{verbatim}
+ hello & world\\
+ &\\
+\end{verbatim}
+
+\subsection{Erratic list indentation}
+
+Try increasing the value of the variable {\it listItemIndent} (default 40
+points) to give more space between label and following text. A global
+replacement of \verb$\item [$ with \verb$\item[$ may also be helpful to remove
+unnecessary space before the item label.
+
+\subsection{Missing figure or section reference}
+
+Ensure all labels {\it directly} follow captions or sections (no intervening
+white space).
+
+\subsection{Linear RTF looks odd}
+
+For viewing by programs other than MS Word, you should set the variable {\it useWord} to {\it false}. This
+will turn off some of the special RTF keywords recognised by Word (and possibly other advanced RTF readers).
+
+\subsection{Paragraphs preceding lists are formatted weirdly.}
+
+If a list has spurious spacing in it, e.g. before a \verb$\item$ command, the preceding
+paragraph can take on some of the list's indentation. This may be a WinHelp bug, or an aspect
+of RTF I don't fully understand. The solution is to remove unnecessary space.
+
+\subsection{Unresolved references in Word for Windows}\index{Microsoft Word}%
+
+If question marks appear instead of numbers for figures and tables,
+select all (e.g. CTRL-A), then press F9 {\it twice} to reformat the
+document twice. For the second format, respond with {\it Update Entire
+Table} to any prompts.
+
+\subsection{The Windows 95 help file contents hierarchy looks wrong}\index{WinHelp files}%
+
+WinHelp version 4 (or the WIN32 Help Compiler) does not allow a
+book in the contents list to be followed by a page at the same level.
+A book must be followed by a book, for some strange reason, otherwise
+the page will be tacked on to the pages of the book above it, i.e. placed
+at the wrong level.
+
+To get around this, Tex2RTF inserts a book in some places, if there
+was a book preceding it on the same level. This results in more
+navigation than necessary, but is better than a wrong contents page.
+
+\newpage
+
+% Puts books in the bibliography without needing to cite them in the
+% text
+\nocite{smart93a}%
+\nocite{kopka}%
+\nocite{pfeiffer}%
+
+\bibliography{refs}
+\addcontentsline{toc}{chapter}{Bibliography}
+\setheader{{\it REFERENCES}}{}{}{}{}{{\it REFERENCES}}%
+\setfooter{\thepage}{}{}{}{}{\thepage}%
+
+\begin{helpglossary}
+\setheader{{\it GLOSSARY}}{}{}{}{}{{\it GLOSSARY}}%
+\setfooter{\thepage}{}{}{}{}{\thepage}%
+
+\gloss{GUI}
+
+Graphical User Interface, such as Windows 3 or X.
+
+\gloss{HTML}\label{html}
+
+Hypertext Markup Language; an SGML document type, used for providing
+hypertext information on the World Wide Web, a distributed hypertext
+system on the Internet.
+
+\gloss{LaTeX}\label{latexgloss}
+
+A typesetting language implemented as a set of \TeX\ macros. It is
+distinguished for allowing specification of the document structure,
+whilst taking care of most layout concerns. It represents the opposite
+end of the spectrum from WYSIWYG word processors.
+
+\gloss{RTF}\label{rtf}
+
+Rich Text Format: an interchange format for word processor files,
+used for importing and exporting formatted documents, and as the
+input to the Windows Help compiler.
+
+\gloss{wxHelp}\label{wxhelp}
+
+wxHelp is the hypertext help facility used to provide on-line
+documentation for UNIX-based wxWindows applications. Under Windows 3.1,
+Windows Help is used instead.
+
+\gloss{wxWindows}\label{wxwindows}
+
+wxWindows is a free C++ toolkit for writing applications that are
+portable across several platforms. Currently these are Motif, Open Look,
+Windows 3.1 and Windows NT. Tex2RTF is written using wxWindows.
+
+\end{helpglossary}
+
+\addcontentsline{toc}{chapter}{Index}
+\setheader{{\it INDEX}}{}{}{}{}{{\it INDEX}}%
+\setfooter{\thepage}{}{}{}{}{\thepage}%
+\printindex%
+
+\end{document}
--- /dev/null
+% LaTeX style file
+% Name: texhelp.sty
+% Author: Julian Smart
+%
+% Purpose
+% -------
+% Style file to enable the simultaneous preparation of printed LaTeX and on-line
+% hypertext manuals.
+% Use in conjunction with Tex2RTF (see Tex2RTF documentation).
+%
+% Note that if a non-ASCII character starts a newline and there should be a space
+% between the last word on the previous line and the first word on this line,
+% you need to use \rtfsp to generate a space in Windows Help. \rtfsp is ignored
+% in all other formats.
+%
+% Julian Smart
+% Artificial Intelligence Applications Institute
+%
+%
+% ============== C++/CLIPS Documentation Facilities ==============
+%
+% Each class definition should be typeset with e.g.
+%
+% \section{\class{Name}: Parent}
+%
+% followed by a description of the class.
+% Each member should follow:
+%
+% \membersection{wxName::Member}
+%
+% with a description of what this member does.
+% Then, one (or more if overloaded) member (function) in detail:
+%
+% \func{return type}{name}{args}
+% or
+% \member{type}{name}
+%
+% where args is a list of \param{type}{name}, ...
+
+% Function, e.g.
+% e.g. to typeset
+%
+% void DoIt(char *string);
+%
+% write:
+%
+% \func{void}{DoIt}{\param{char *}{string}}
+%
+
+\newcommand{\func}[3]{\hangafter=1\noindent\hangindent=10mm
+{{\it #1} {\bf #2}\index{#2}}(#3)}
+
+% For function/type definition where the name is a pointer,
+% e.g. to typeset
+%
+% typedef void (*wxFunction)(wxObject&)
+%
+% write:
+%
+% \pfunc{typedef void}{wxFunction}{param{wxObject&}}
+
+\newcommand{\pfunc}[3]{\hangafter=1\noindent\hangindent=10mm
+{{\it #1} ({\bf *#2})\index{#2}}(#3)}
+
+% Use an ordinary \section command for class name definitions.
+
+% This is used for a member, such as wxBitmap: GetDepth
+\newcommand{\membersection}[1]{\subsection*{#1}\index{#1}}
+
+% CLIPS function
+\newcommand{\clipsfunc}[3]{\hangafter=1\noindent\hangindent=10mm
+{{\bf #1} ({\bf #2}\index{#2}}#3)}
+
+\newcommand{\clipssection}[1]{\chapter{#1}}
+
+% This is used for a CLIPS function name
+\newcommand{\functionsection}[1]{\subsection*{#1}}
+
+% Member: a type and a name
+\newcommand{\member}[2]{{\bf #1 \it #2}}
+
+% C++ Parameter: a type and a name (no intervening space)
+\newcommand{\param}[2]{{\it #1}{\bf #2}}
+
+% CLIPS Parameter: a type and a name (one intervening space)
+\newcommand{\cparam}[2]{{\bf #1} {\it #2}}
+
+% Class: puts in index
+\newcommand{\class}[1]{#1\index{#1}}
+
+% Void type
+\newcommand{\void}{{\it void}}
+
+% Typeset destructor
+\newcommand{\destruct}[1]{{$\sim$}#1}
+
+% Typeset insert/extract operators
+\newcommand{\cinsert}{$<<$}
+\newcommand{\cextract}{$>>$}
+
+
+% =================== Hypertext facilities ===================
+%
+% To insert hyperlinks (or references, in Latex), \label the sections
+% or membersections \label{ref-label} immediately after the section, on the same line,
+% and use \helpref{text-to-show}{ref-label} to make a reference.
+%
+
+% Type text with section reference
+\newcommand{\helpref}[2]{{\it #1} (section \ref{#2}) }
+
+% Type text with URL in verbatim mode
+\newcommand{\urlref}[2]{#1 (\verb$#2$)}
+
+% Don't typeset section number in LaTeX
+\newcommand{\helprefn}[2]{{\it #1}}
+
+% Like helpref, but popup text in WinHelp instead of hyperlinked
+\newcommand{\popref}[2]{{\it #1}}
+
+% Like footnote, but popup text.
+\newcommand{\footnotepopup}[2]{{\it #1}\footnote{#2}}
+
+% =================== On-line help specific macros ===================
+%
+
+% Global document font size/family, help only.
+\newcommand{\helpfontsize}[1]{}
+\newcommand{\helpfontfamily}[1]{}
+
+% Ignore in all on-line help
+\newcommand{\helpignore}[1]{#1}
+% Only print in all on-line help
+\newcommand{\helponly}[1]{}
+
+% Ignore in LaTeX
+\newcommand{\latexignore}[1]{}
+% Only print in LaTeX
+\newcommand{\latexonly}[1]{#1}
+
+% Ignore in linear RTF
+\newcommand{\rtfignore}[1]{#1}
+% Only print in linear RTF
+\newcommand{\rtfonly}[1]{}
+
+% Ignore in WinHelp RTF
+\newcommand{\winhelpignore}[1]{#1}
+% Only print in WinHelp RTF
+\newcommand{\winhelponly}[1]{}
+
+% Ignore in wxHelp
+\newcommand{\xlpignore}[1]{#1}
+% Only print in wxHelp
+\newcommand{\xlponly}[1]{}
+
+% Ignore in HTML
+\newcommand{\htmlignore}[1]{#1}
+% Only print in HTML
+\newcommand{\htmlonly}[1]{}
+
+% Input a file only for help system (binder thickness is not a limitation
+% in help systems!)
+\newcommand{\helpinput}[1]{}
+
+\newcommand{\rtfsp}{ } % Force a space in RTF, ignore in Latex
+
+% =================== Miscellaneous macros ===================
+%
+% Headings consistent with generated ones
+\newcommand{\myheading}[1]{\vspace*{25pt}
+\begin{flushleft}
+{\LARGE \bf #1}
+\end{flushleft}
+\vskip 20pt
+}
+
+% Heading with entry in contents page.
+\newcommand{\chapterheading}[1]{\myheading{#1}
+\addcontentsline{toc}{chapter}{#1}}
+
+\newcommand{\sectionheading}[1]{\myheading{#1}
+\addcontentsline{toc}{section}{#1}}
+
+% Glossary environment
+\newenvironment{helpglossary}{\newpage\chapterheading{Glossary}\begin{description}}{\end{description}}
+
+% Glossary entry
+\newcommand{\gloss}[1]{\item[#1]\index{#1}}
+
+% Image: EPS in Latex, BMP or MF (whatever's available) in RTF. Requires psbox.
+\newcommand{\image}[2]{\psboxto(#1){#2}}
+
+% Image, left aligned (HTML)
+\newcommand{\imager}[2]{\psboxto(#1){#2}}
+
+% Image, right aligned (HTML)
+\newcommand{\imagel}[2]{\psboxto(#1){#2}}
+
+% Imagemap: principally for HTML only. In Latex,
+% acts like \image.
+\newcommand{\imagemap}[3]{\psboxto(#1){#2}}
+
+% Headers and footers
+% \setheader{EvenPageLeft}{EvenPageCentre}{EvenPageRight}
+% {OddPageLeft}{OddPageCentre}{OddPageRight}
+\newcommand{\setheader}[6]{
+\lhead[\fancyplain{}{#1}]{\fancyplain{}{#4}}
+\chead[\fancyplain{}{#2}]{\fancyplain{}{#5}}
+\rhead[\fancyplain{}{#3}]{\fancyplain{}{#6}}
+}
+
+% \setfooter{EvenPageLeft}{EvenPageCentre}{EvenPageRight}
+% {OddPageLeft}{OddPageCentre}{OddPageRight}
+\newcommand{\setfooter}[6]{
+\lfoot[\fancyplain{#1}{#1}]{\fancyplain{#4}{#4}}
+\cfoot[\fancyplain{#2}{#2}]{\fancyplain{#5}{#5}}
+\rfoot[\fancyplain{#3}{#3}]{\fancyplain{#6}{#6}}
+}
+
+% Needed for telling RTF where margin paragraph should go
+% in mirrored margins mode.
+\newcommand{\marginpareven}[1]{\hspace*{0pt}\marginpar{#1}}
+\newcommand{\marginparodd}[1]{\hspace*{0pt}\marginpar{#1}}
+
+% Environment for two-column table popular in WinHelp and manuals.
+\newcommand{\twocolwidtha}[1]{\def\twocolwidthaval{#1}}
+\newcommand{\twocolwidthb}[1]{\def\twocolwidthbval{#1}}
+\newcommand{\twocolspacing}[1]{\def\twocolspacingval{#1}}
+
+\twocolwidtha{3cm}
+\twocolwidthb{8.5cm}
+\twocolspacing{2}
+
+\newcommand{\twocolitem}[2]{#1 & #2\\}
+\newcommand{\twocolitemruled}[2]{#1 & #2\\\hline}
+
+\newenvironment{twocollist}{\renewcommand{\arraystretch}{\twocolspacingval}\begin{tabular}{lp{\twocolwidthbval}}}%
+{\end{tabular}\renewcommand{\arraystretch}{1}}
+
+% Specifying table rows for RTF compatibility
+\newcommand{\row}[1]{#1\\}
+
+% Use for the last ruled row for correct RTF generation.
+\newcommand{\ruledrow}[1]{#1\\\hline}
+
+% Indentation environment. Arg1 is left margin size
+\newenvironment{indented}[1]{\begin{list}{}{\leftmargin=#1}\item[]}%
+{\end{list}}
+
+% Framed box of text, normal formatting.
+\newcommand{\normalbox}[1]{\fbox{\vbox{#1}}}
+% Double-framed box of text.
+\newcommand{\normalboxd}[1]{\fbox{\fbox{\vbox{#1}}}}
+
+% WITHDRAWN -- can't do in RTF, easily.
+% Framed box of text, horizontally centred. Ragged right within box.
+% \newcommand{\centeredbox}[2]{\begin{center}\fbox{\parbox{#1}{\raggedright#2}}\end{center}}
+% Double-framed box of text, horizontally centred. Ragged right within box.
+% \newcommand{\centeredboxd}[2]{\begin{center}\fbox{\fbox{\parbox{#1}{\raggedright#2}}}\end{center}}
+
+% toocomplex environment: simply prints the argument in LaTeX,
+% comes out verbatim in all generated formats.
+\newenvironment{toocomplex}{}{}
+
+% Colour: dummy commands since LaTeX doesn't support colour.
+% \definecolour{name}{red}{blue}{green}
+% \fcol{name}{text} ; Foreground
+% \bcol{name}{text} ; Background
+\newcommand{\definecolour}[4]{}
+\newcommand{\definecolor}[4]{}
+\newcommand{\fcol}[2]{#2}
+\newcommand{\bcol}[2]{#2}
+\newcommand{\sethotspotcolour}[1]{}
+\newcommand{\sethotspotunderline}[1]{}
+\newcommand{\settransparency}[1]{}
+\newcommand{\backslashraw}[0]{}
+\newcommand{\lbraceraw}[0]{}
+\newcommand{\rbraceraw}[0]{}
+\newcommand{\registered}[0]{(r)}
+\newcommand{\background}[1]{}
+\newcommand{\textcolour}[1]{}
+\newcommand{\overview}[2]{See \helpref{#1}{#2}.}
--- /dev/null
+%%
+%% This is file `verbatim.sty' generated
+%% on <1991/9/3> with the docstrip utility (v1.1l test).
+%%
+%% The original source file was `verbatim.doc'.
+%%
+%%
+%% Copyright (C) 1989,1990,1991 by Rainer Schoepf. All rights reserved.
+%%
+%% IMPORTANT NOTICE:
+%%
+%% You are not allowed to change this file. You may however copy this file
+%% to a different name and then change this copy.
+%%
+%% You are allowed to distribute this file under the condition that it is
+%% distributed together with all files mentioned in readme.mz4. If you
+%% receive only some of these files from someone, complain!
+%%
+%% You are NOT ALLOWED to distribute this file alone. You are NOT ALLOWED
+%% to take money for the distribution or use of this file (or a changed
+%% version) except for some nominal charge for copying etc.
+%%
+%% Error Reports in case of UNCHANGED versions to
+%%
+%% Rainer Schoepf
+%% Konrad-Zuse-Zentrum fuer Informationstechnik Berlin
+%% Heilbronner Str. 10
+%% W-1000 Berlin 31
+%% Federal Republic of Germany
+%% Internet: <SCHOEPF@SC.ZIB-Berlin.DE>
+%%
+\def\fileversion{v1.4f}
+\def\filedate{91/08/05}
+\def\docdate{91/08/05}
+
+%% \CheckSum{439}
+%% \CharacterTable
+%% {Upper-case \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z
+%% Lower-case \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z
+%% Digits \0\1\2\3\4\5\6\7\8\9
+%% Exclamation \! Double quote \" Hash (number) \#
+%% Dollar \$ Percent \% Ampersand \&
+%% Acute accent \' Left paren \( Right paren \)
+%% Asterisk \* Plus \+ Comma \,
+%% Minus \- Point \. Solidus \/
+%% Colon \: Semicolon \; Less than \<
+%% Equals \= Greater than \> Question mark \?
+%% Commercial at \@ Left bracket \[ Backslash \\
+%% Right bracket \] Circumflex \^ Underscore \_
+%% Grave accent \` Left brace \{ Vertical bar \|
+%% Right brace \} Tilde \~}
+%%
+%% Style-option `verbatim' to use with LaTeX v2.09
+%% Copyright (C) 1989, 1990, 1991 by Rainer Sch\"opf, all rights reserved.
+\@ifundefined{verbatim@@@}{}{\endinput}
+\typeout{Style-Option: `verbatim'
+ \fileversion \space <\filedate> (RmS)}
+\typeout{English Documentation
+ \@spaces \@spaces \space <\docdate> (RmS)}
+\def\addto@hook#1#2{#1\expandafter{\the#1#2}}
+\newtoks\every@verbatim
+\every@verbatim={}
+\def\@makeother#1{\catcode`#112\relax}
+\begingroup
+ \catcode`\ =\active%
+\gdef\@vobeyspaces{\catcode`\ \active\let \@xobeysp}%
+\endgroup
+\def\@xobeysp{\leavevmode\penalty\@M\ }
+\newtoks\verbatim@line
+\def\verbatim@startline{\verbatim@line{}}
+\def\verbatim@addtoline#1{%
+ \verbatim@line\expandafter{\the\verbatim@line#1}}
+\def\verbatim@processline{\the\verbatim@line\par}
+\def\verbatim@finish{\ifcat$\the\verbatim@line$\else
+ \verbatim@processline\fi}
+\begingroup
+ \catcode`\`=\active
+ \gdef\verbatim@font{\tt \catcode96\active
+ \def`{\leavevmode\kern\z@\char96 }}
+\endgroup
+\def\@verbatim{\the\every@verbatim
+ \trivlist \item[]%
+ \leftskip\@totalleftmargin\rightskip\z@
+ \parindent\z@\parfillskip\@flushglue\parskip\z@
+ \@@par
+ \def\par{\leavevmode\null\@@par\penalty\interlinepenalty}%
+ \obeylines
+ \verbatim@font
+ \let\do\@makeother \dospecials}
+\def\verbatim{\@verbatim \frenchspacing\@vobeyspaces\verbatim@start}
+\@namedef{verbatim*}{\@verbatim\verbatim@start}
+\let\endverbatim=\endtrivlist
+\expandafter\let\csname endverbatim*\endcsname =\endtrivlist
+\def\comment{\@bsphack
+ \let\do\@makeother\dospecials\catcode`\^^M\active
+ \let\verbatim@startline\relax
+ \let\verbatim@addtoline\@gobble
+ \let\verbatim@processline\relax
+ \let\verbatim@finish\relax
+ \verbatim@}
+\let\endcomment=\@esphack
+\@ifundefined{vrb@catcodes}%
+ {\def\vrb@catcodes{%
+ \catcode`\!12\catcode`\[12\catcode`\]12}}{}
+\begingroup
+ \vrb@catcodes
+ \lccode`\!=`\\ \lccode`\[=`\{ \lccode`\]=`\}
+ \catcode`\~=\active \lccode`\~=`\^^M
+ \lccode`\C=`\C
+ \lowercase{%
+ \gdef\verbatim@start#1{%
+ \verbatim@startline
+ \if\noexpand#1\noexpand~%
+ \let\next\verbatim@
+ \else \def\next{\verbatim@#1}\fi
+ \next}%
+ \gdef\verbatim@#1~{\verbatim@@#1!end\@nil}%
+ \gdef\verbatim@@#1!end{%
+ \verbatim@addtoline{#1}%
+ \futurelet\next\verbatim@@@}%
+ \gdef\verbatim@@@#1\@nil{%
+ \ifx\next\@nil
+ \verbatim@processline
+ \verbatim@startline
+ \let\next\verbatim@
+ \else
+ \def\@tempa##1!end\@nil{\toks@{##1}}%
+ \@tempa#1\@nil
+ \@temptokena{!end}%
+ \edef\next{\noexpand\verbatim@test\the\toks@\noexpand~}%
+ \fi \next}%
+ \gdef\verbatim@test#1{%
+ \let\next\verbatim@test
+ \if\noexpand#1\noexpand~%
+ \expandafter\verbatim@addtoline
+ \expandafter{\the\@temptokena}%
+ \verbatim@processline
+ \verbatim@startline
+ \let\next\verbatim@
+ \else \if\noexpand#1
+ \@temptokena\expandafter{\the\@temptokena#1}%
+ \else \if\noexpand#1\noexpand[%
+ \let\@tempc\@empty
+ \let\next\verbatim@testend
+ \else
+ \expandafter\verbatim@addtoline
+ \expandafter{\the\@temptokena}%
+ \def\next{\verbatim@#1}%
+ \fi\fi\fi
+ \next}%
+ \gdef\verbatim@testend#1{%
+ \if\noexpand#1\noexpand~%
+ \expandafter\verbatim@addtoline
+ \expandafter{\the\@temptokena[}%
+ \expandafter\verbatim@addtoline
+ \expandafter{\@tempc}%
+ \verbatim@processline
+ \verbatim@startline
+ \let\next\verbatim@
+ \else\if\noexpand#1\noexpand]%
+ \let\next\verbatim@@testend
+ \else\if\noexpand#1\noexpand!%
+ \expandafter\verbatim@addtoline
+ \expandafter{\the\@temptokena[}%
+ \expandafter\verbatim@addtoline
+ \expandafter{\@tempc}%
+ \def\next{\verbatim@!}%
+ \else \expandafter\def\expandafter\@tempc\expandafter
+ {\@tempc#1}\fi\fi\fi
+ \next}%
+ \gdef\verbatim@@testend{%
+ \ifx\@tempc\@currenvir
+ \verbatim@finish
+ \edef\next{\noexpand\end{\@currenvir}%
+ \noexpand\verbatim@rescan{\@currenvir}}%
+ \else
+ \expandafter\verbatim@addtoline
+ \expandafter{\the\@temptokena[}%
+ \expandafter\verbatim@addtoline
+ \expandafter{\@tempc]}%
+ \let\next\verbatim@
+ \fi
+ \next}%
+ \gdef\verbatim@rescan#1#2~{\if\noexpand~\noexpand#2~\else
+ \@warning{Characters dropped after `\string\end{#1}'}\fi}}
+\endgroup
+\def\verbatiminput{\begingroup
+ \@ifstar\sverbatim@input\verbatim@input}
+\def\sverbatim@input#1{\@verbatim
+ \@input{#1}\endtrivlist\endgroup\@doendpe}
+\def\verbatim@input#1{\@verbatim
+ \frenchspacing \@vobeyspaces
+ \@input{#1}\endtrivlist\endgroup\@doendpe}
+\begingroup
+ \lccode`\~=`\^^M
+ \lowercase{%
+ \gdef\verb{\begingroup
+ \verbatim@font
+ \catcode`\^^M\active
+ \def~{\endgroup\@latexerr{\string\verb\space command ended by
+ end of line.}\@ehc}%
+ \let\do\@makeother \dospecials
+ \@ifstar\@sverb{\@vobeyspaces \frenchspacing \@sverb}}}
+\endgroup
+\def\@sverb#1{%
+ \catcode`#1\active
+ \lccode`\~`#1%
+ \lowercase{\let~\endgroup}%
+ \leavevmode\null}
+\endinput
+%%
+%% End of file `verbatim.sty'.
--- /dev/null
+/////////////////////////////////////////////////////////////////////////////
+// Name: bmputils.h
+// Purpose: Utilities for manipulating bitmap and metafile images for
+// the purposes of conversion to RTF
+// Author: Julian Smart
+// Modified by:
+// Created: 7.9.93
+// RCS-ID: $Id$
+// Copyright: (c) Julian Smart
+// Licence: wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+static char hexArray[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B',
+ 'C', 'D', 'E', 'F' };
+
+void DecToHex(int dec, char *buf)
+{
+ int firstDigit = (int)(dec/16.0);
+ int secondDigit = (int)(dec - (firstDigit*16.0));
+ buf[0] = hexArray[firstDigit];
+ buf[1] = hexArray[secondDigit];
+ buf[2] = 0;
+}
+
+static unsigned int getshort(FILE *fp)
+{
+ int c, c1;
+ c = getc(fp); c1 = getc(fp);
+ return ((unsigned int) c) + (((unsigned int) c1) << 8);
+}
+
+static unsigned long getint(FILE *fp)
+{
+ int c, c1, c2, c3;
+ c = getc(fp); c1 = getc(fp); c2 = getc(fp); c3 = getc(fp);
+ return (long)((long) c) +
+ (((long) c1) << 8) +
+ (((long) c2) << 16) +
+ (((long) c3) << 24);
+}
+
+bool GetBMPHeader(FILE *fp, int *Width, int *Height, int *Planes, int *BitsPerPixel)
+{
+ unsigned long bfSize, bfOffBits, biSize, biWidth, biHeight, biPlanes;
+ unsigned long biBitCount, biCompression, biSizeImage, biXPelsPerMeter;
+ unsigned long biYPelsPerMeter, biClrUsed, biClrImportant;
+
+ /* read the file type (first two bytes) */
+ int c = getc(fp); int c1 = getc(fp);
+ if (c!='B' || c1!='M') { return FALSE; }
+
+ bfSize = getint(fp);
+ getshort(fp); /* reserved and ignored */
+ getshort(fp);
+ bfOffBits = getint(fp);
+
+ biSize = getint(fp);
+ biWidth = getint(fp);
+ biHeight = getint(fp);
+ biPlanes = getshort(fp);
+ biBitCount = getshort(fp);
+ biCompression = getint(fp);
+ biSizeImage = getint(fp);
+ biXPelsPerMeter = getint(fp);
+ biYPelsPerMeter = getint(fp);
+ biClrUsed = getint(fp);
+ biClrImportant = getint(fp);
+
+ *Width = (int)biWidth;
+ *Height = (int)biHeight;
+ *Planes = (int)biPlanes;
+ *BitsPerPixel = (int)biBitCount;
+
+// fseek(fp, bfOffBits, SEEK_SET);
+
+ return TRUE;
+}
+
+static int scanLineWidth = 0;
+
+bool OutputBitmapHeader(FILE *fd, bool isWinHelp = FALSE)
+{
+ int Width, Height, Planes, BitsPerPixel;
+ if (!GetBMPHeader(fd, &Width, &Height, &Planes, &BitsPerPixel))
+ return FALSE;
+
+ scanLineWidth = (int)((float)Width/(8.0/(float)BitsPerPixel));
+ if ((float)((int)(scanLineWidth/2.0)) != (float)(scanLineWidth/2.0))
+ scanLineWidth ++;
+
+ int goalW = 15*Width;
+ int goalH = 15*Height;
+
+ TexOutput("{\\pict");
+ if (isWinHelp) TexOutput("\\wbitmap0");
+ else TexOutput("\\dibitmap");
+
+ char buf[50];
+ TexOutput("\\picw"); sprintf(buf, "%d", Width); TexOutput(buf);
+ TexOutput("\\pich"); sprintf(buf, "%d", Height); TexOutput(buf);
+ TexOutput("\\wbmbitspixel"); sprintf(buf, "%d", BitsPerPixel); TexOutput(buf);
+ TexOutput("\\wbmplanes"); sprintf(buf, "%d", Planes); TexOutput(buf);
+ TexOutput("\\wbmwidthbytes"); sprintf(buf, "%d", scanLineWidth); TexOutput(buf);
+ TexOutput("\\picwgoal"); sprintf(buf, "%d", goalW); TexOutput(buf);
+ TexOutput("\\pichgoal"); sprintf(buf, "%d", goalH); TexOutput(buf);
+ TexOutput("\n");
+ return TRUE;
+}
+
+
+bool OutputBitmapData(FILE *fd)
+{
+ fseek(fd, 14, SEEK_SET);
+ int bytesSoFar = 0;
+ int ch = getc(fd);
+ char hexBuf[3];
+ while (ch != EOF)
+ {
+ if (bytesSoFar == scanLineWidth)
+ {
+ bytesSoFar = 0;
+ TexOutput("\n");
+ }
+ DecToHex(ch, hexBuf);
+ TexOutput(hexBuf);
+ bytesSoFar ++;
+ ch = getc(fd);
+ }
+ TexOutput("\n}\n");
+ return TRUE;
+}
+
+#ifdef __WXMSW__
+struct mfPLACEABLEHEADER {
+ DWORD key;
+ HANDLE hmf;
+ RECT bbox;
+ WORD inch;
+ DWORD reserved;
+ WORD checksum;
+};
+
+// Returns size in TWIPS
+bool GetMetafileHeader(FILE *handle, int *width, int *height)
+{
+ char buffer[40];
+ mfPLACEABLEHEADER *theHeader = (mfPLACEABLEHEADER *)&buffer;
+ fread((void *)theHeader, sizeof(char), sizeof(mfPLACEABLEHEADER), handle);
+ if (theHeader->key != 0x9AC6CDD7)
+ {
+ return FALSE;
+ }
+
+ float widthInUnits = (float)theHeader->bbox.right - theHeader->bbox.left;
+ float heightInUnits = (float)theHeader->bbox.bottom - theHeader->bbox.top;
+ *width = (int)((widthInUnits*1440.0)/theHeader->inch);
+ *height = (int)((heightInUnits*1440.0)/theHeader->inch);
+ return TRUE;
+}
+
+bool OutputMetafileHeader(FILE *handle, bool isWinHelp, int userWidth, int userHeight)
+{
+ int Width, Height;
+ if (!GetMetafileHeader(handle, &Width, &Height))
+ return FALSE;
+
+ scanLineWidth = 64;
+ int goalW = Width;
+ int goalH = Height;
+
+ // Scale to user's dimensions if we have the information
+ if (userWidth > 0 && userHeight == 0)
+ {
+ double scaleFactor = ((double)userWidth/(double)goalW);
+ goalW = userWidth;
+ goalH = (int)((goalH * scaleFactor) + 0.5);
+ }
+ else if (userWidth == 0 && userHeight > 0)
+ {
+ double scaleFactor = ((double)userHeight/(double)goalH);
+ goalH = userHeight;
+ goalW = (int)((goalW * scaleFactor) + 0.5);
+ }
+ else if (userWidth > 0 && userHeight > 0)
+ {
+ goalW = userWidth;
+ goalH = userHeight;
+ }
+
+ TexOutput("{\\pict");
+ TexOutput("\\wmetafile8");
+
+ char buf[50];
+ TexOutput("\\picw"); sprintf(buf, "%d", Width); TexOutput(buf);
+ TexOutput("\\pich"); sprintf(buf, "%d", Height); TexOutput(buf);
+ TexOutput("\\picwgoal"); sprintf(buf, "%d", goalW); TexOutput(buf);
+ TexOutput("\\pichgoal"); sprintf(buf, "%d", goalH); TexOutput(buf);
+ TexOutput("\n");
+ return TRUE;
+}
+
+bool OutputMetafileData(FILE *handle)
+{
+ int bytesSoFar = 0;
+ char hexBuf[3];
+ int ch;
+ do
+ {
+ ch = getc(handle);
+ if (bytesSoFar == scanLineWidth)
+ {
+ bytesSoFar = 0;
+ TexOutput("\n");
+ }
+ if (ch != EOF)
+ {
+ DecToHex(ch, hexBuf);
+ TexOutput(hexBuf);
+ bytesSoFar ++;
+ }
+ } while (ch != EOF);
+ TexOutput("\n}\n");
+ return TRUE;
+}
+
+#endif
+
--- /dev/null
+NAME TEX2RTF
+DESCRIPTION 'Tex2Rtf'
+;
+EXETYPE DOS
+;
+CODE PRELOAD MOVEABLE DISCARDABLE
+DATA PRELOAD MOVEABLE MULTIPLE
+;
+HEAPSIZE 1024
+STACKSIZE 8192
--- /dev/null
+/////////////////////////////////////////////////////////////////////////////
+// Name: htmlutil.cpp
+// Purpose: Converts Latex to HTML
+// Author: Julian Smart
+// Modified by:
+// Created: 7.9.93
+// RCS-ID: $Id$
+// Copyright: (c) Julian Smart
+// Licence: wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+
+#ifndef WX_PRECOMP
+#include "wx/wx.h"
+#endif
+
+#include "tex2any.h"
+#include "tex2rtf.h"
+#include "table.h"
+
+extern void DecToHex(int, char *);
+void GenerateHTMLIndexFile(char *fname);
+void OutputContentsFrame(void);
+
+#include "readshg.h" // Segmented hypergraphics parsing
+
+char *ChaptersName = NULL;
+char *SectionsName = NULL;
+char *SubsectionsName = NULL;
+char *SubsubsectionsName = NULL;
+char *TitlepageName = NULL;
+char *lastFileName = NULL;
+char *lastTopic = NULL;
+char *currentFileName = NULL;
+char *contentsFrameName = NULL;
+
+static TexChunk *descriptionItemArg = NULL;
+static TexChunk *helpRefFilename = NULL;
+static TexChunk *helpRefText = NULL;
+static int indentLevel = 0;
+static int citeCount = 1;
+extern FILE *Contents;
+FILE *FrameContents = NULL;
+FILE *Titlepage = NULL;
+// FILE *FrameTitlepage = NULL;
+int fileId = 0;
+bool subsectionStarted = FALSE;
+
+// Which column of a row are we in? (Assumes no nested tables, of course)
+int currentColumn = 0;
+
+// Are we in verbatim mode? If so, format differently.
+static bool inVerbatim = FALSE;
+
+// Need to know whether we're in a table or figure for benefit
+// of listoffigures/listoftables
+static bool inFigure = FALSE;
+static bool inTable = FALSE;
+
+// This is defined in the Tex2Any library.
+extern char *BigBuffer;
+
+class HyperReference: public wxObject
+{
+ public:
+ char *refName;
+ char *refFile;
+ HyperReference(char *name, char *file)
+ {
+ if (name) refName = copystring(name);
+ if (file) refFile = copystring(file);
+ }
+};
+
+class TexNextPage: public wxObject
+{
+ public:
+ char *label;
+ char *filename;
+ TexNextPage(char *theLabel, char *theFile)
+ {
+ label = copystring(theLabel);
+ filename = copystring(theFile);
+ }
+ ~TexNextPage(void)
+ {
+ delete[] label;
+ delete[] filename;
+ }
+};
+
+wxHashTable TexNextPages(wxKEY_STRING);
+
+static char *CurrentChapterName = NULL;
+static char *CurrentChapterFile = NULL;
+static char *CurrentSectionName = NULL;
+static char *CurrentSectionFile = NULL;
+static char *CurrentSubsectionName = NULL;
+static char *CurrentSubsectionFile = NULL;
+static char *CurrentSubsubsectionName = NULL;
+static char *CurrentSubsubsectionFile = NULL;
+static char *CurrentTopic = NULL;
+
+static void SetCurrentTopic(char *s)
+{
+ if (CurrentTopic) delete[] CurrentTopic;
+ CurrentTopic = copystring(s);
+}
+
+void SetCurrentChapterName(char *s, char *file)
+{
+ if (CurrentChapterName) delete[] CurrentChapterName;
+ CurrentChapterName = copystring(s);
+ if (CurrentChapterFile) delete[] CurrentChapterFile;
+ CurrentChapterFile = copystring(file);
+
+ currentFileName = CurrentChapterFile;
+
+ SetCurrentTopic(s);
+}
+void SetCurrentSectionName(char *s, char *file)
+{
+ if (CurrentSectionName) delete[] CurrentSectionName;
+ CurrentSectionName = copystring(s);
+ if (CurrentSectionFile) delete[] CurrentSectionFile;
+ CurrentSectionFile = copystring(file);
+
+ currentFileName = CurrentSectionFile;
+ SetCurrentTopic(s);
+}
+void SetCurrentSubsectionName(char *s, char *file)
+{
+ if (CurrentSubsectionName) delete[] CurrentSubsectionName;
+ CurrentSubsectionName = copystring(s);
+ if (CurrentSubsectionFile) delete[] CurrentSubsectionFile;
+ CurrentSubsectionFile = copystring(file);
+ currentFileName = CurrentSubsectionFile;
+ SetCurrentTopic(s);
+}
+void SetCurrentSubsubsectionName(char *s, char *file)
+{
+ if (CurrentSubsubsectionName) delete[] CurrentSubsubsectionName;
+ CurrentSubsubsectionName = copystring(s);
+ if (CurrentSubsubsectionFile) delete[] CurrentSubsubsectionFile;
+ CurrentSubsubsectionFile = copystring(file);
+ currentFileName = CurrentSubsubsectionFile;
+ SetCurrentTopic(s);
+}
+
+/*
+ * Close former filedescriptor and reopen using another filename.
+ *
+ */
+
+void ReopenFile(FILE **fd, char **fileName)
+{
+ if (*fd)
+ {
+ fprintf(*fd, "\n</BODY></HTML>\n");
+ fclose(*fd);
+ }
+ fileId ++;
+ char buf[400];
+ if (truncateFilenames)
+ sprintf(buf, "%s%d.htm", FileRoot, fileId);
+ else
+ sprintf(buf, "%s%d.html", FileRoot, fileId);
+ if (*fileName) delete[] *fileName;
+ *fileName = copystring(FileNameFromPath(buf));
+ *fd = fopen(buf, "w");
+ fprintf(*fd, "<HTML>\n");
+}
+
+/*
+ * Reopen section contents file, i.e. the index appended to each section
+ * in subsectionCombine mode
+ */
+
+static char *SectionContentsFilename = NULL;
+static FILE *SectionContentsFD = NULL;
+
+void ReopenSectionContentsFile(void)
+{
+ if ( SectionContentsFD )
+ {
+ fclose(SectionContentsFD);
+ }
+ if ( SectionContentsFilename )
+ delete[] SectionContentsFilename;
+ SectionContentsFD = NULL;
+ SectionContentsFilename = NULL;
+
+ // Create the name from the current section filename
+ if ( CurrentSectionFile )
+ {
+ char buf[256];
+ strcpy(buf, CurrentSectionFile);
+ wxStripExtension(buf);
+ strcat(buf, ".con");
+ SectionContentsFilename = copystring(buf);
+
+ SectionContentsFD = fopen(SectionContentsFilename, "w");
+ }
+}
+
+
+/*
+ * Given a TexChunk with a string value, scans through the string
+ * converting Latex-isms into HTML-isms, such as 2 newlines -> <P>.
+ *
+ */
+
+void ProcessText2HTML(TexChunk *chunk)
+{
+ bool changed = FALSE;
+ int ptr = 0;
+ int i = 0;
+ char ch = 1;
+ int len = strlen(chunk->value);
+ while (ch != 0)
+ {
+ ch = chunk->value[i];
+
+ // 2 newlines means \par
+ if (!inVerbatim && chunk->value[i] == 10 && ((len > i+1 && chunk->value[i+1] == 10) ||
+ ((len > i+1 && chunk->value[i+1] == 13) &&
+ (len > i+2 && chunk->value[i+2] == 10))))
+ {
+ BigBuffer[ptr] = 0; strcat(BigBuffer, "<P>\n\n"); ptr += 5;
+ i += 2;
+ changed = TRUE;
+ }
+ else if (!inVerbatim && ch == '`' && (len >= i+1 && chunk->value[i+1] == '`'))
+ {
+ BigBuffer[ptr] = '"'; ptr ++;
+ i += 2;
+ changed = TRUE;
+ }
+ else if (!inVerbatim && ch == '`') // Change ` to '
+ {
+ BigBuffer[ptr] = 39; ptr ++;
+ i += 1;
+ changed = TRUE;
+ }
+ else if (ch == '<') // Change < to <
+ {
+ BigBuffer[ptr] = 0;
+ strcat(BigBuffer, "<");
+ ptr += 4;
+ i += 1;
+ changed = TRUE;
+ }
+ else if (ch == '>') // Change > to >
+ {
+ BigBuffer[ptr] = 0;
+ strcat(BigBuffer, ">");
+ ptr += 4;
+ i += 1;
+ changed = TRUE;
+ }
+ else
+ {
+ BigBuffer[ptr] = ch;
+ i ++;
+ ptr ++;
+ }
+ }
+ BigBuffer[ptr] = 0;
+
+ if (changed)
+ {
+ delete chunk->value;
+ chunk->value = copystring(BigBuffer);
+ }
+}
+
+/*
+ * Scan through all chunks starting from the given one,
+ * calling ProcessText2HTML to convert Latex-isms to RTF-isms.
+ * This should be called after Tex2Any has parsed the file,
+ * and before TraverseDocument is called.
+ *
+ */
+
+void Text2HTML(TexChunk *chunk)
+{
+ Tex2RTFYield();
+ if (stopRunning) return;
+
+ switch (chunk->type)
+ {
+ case CHUNK_TYPE_MACRO:
+ {
+ TexMacroDef *def = chunk->def;
+
+ if (def && def->ignore)
+ return;
+
+ if (def && (def->macroId == ltVERBATIM || def->macroId == ltVERB || def->macroId == ltSPECIAL))
+ inVerbatim = TRUE;
+
+ wxNode *node = chunk->children.First();
+ while (node)
+ {
+ TexChunk *child_chunk = (TexChunk *)node->Data();
+ Text2HTML(child_chunk);
+ node = node->Next();
+ }
+
+ if (def && (def->macroId == ltVERBATIM || def->macroId == ltVERB || def->macroId == ltSPECIAL))
+ inVerbatim = FALSE;
+
+ break;
+ }
+ case CHUNK_TYPE_ARG:
+ {
+ wxNode *node = chunk->children.First();
+ while (node)
+ {
+ TexChunk *child_chunk = (TexChunk *)node->Data();
+ Text2HTML(child_chunk);
+ node = node->Next();
+ }
+
+ break;
+ }
+ case CHUNK_TYPE_STRING:
+ {
+ if (chunk->value)
+ ProcessText2HTML(chunk);
+ break;
+ }
+ }
+}
+
+/*
+ * Add appropriate browse buttons to this page.
+ *
+ */
+
+void AddBrowseButtons(char *upLabel, char *upFilename,
+ char *previousLabel, char *previousFilename,
+ char *thisLabel, char *thisFilename)
+{
+ char contentsReferenceBuf[80];
+ char upReferenceBuf[80];
+ char backReferenceBuf[80];
+ char forwardReferenceBuf[80];
+ if (htmlBrowseButtons == HTML_BUTTONS_NONE)
+ return;
+
+ char *contentsReference = NULL;
+ if (htmlBrowseButtons == HTML_BUTTONS_TEXT)
+ contentsReference = ContentsNameString;
+ else
+ {
+// contentsReference = "<img align=center src=\"contents.gif\" BORDER=0 ALT=\"Contents\">";
+ contentsReference = contentsReferenceBuf;
+ sprintf(contentsReference, "<img align=center src=\"%s\" BORDER=0 ALT=\"Contents\">", ConvertCase("contents.gif"));
+ }
+
+ char *upReference = NULL;
+ if (htmlBrowseButtons == HTML_BUTTONS_TEXT)
+ upReference = UpNameString;
+ else
+ {
+// upReference = "<img align=center src=\"up.gif\" ALT=\"Up\">";
+ upReference = upReferenceBuf;
+ sprintf(upReference, "<img align=center src=\"%s\" BORDER=0 ALT=\"Up\">", ConvertCase("up.gif"));
+ }
+
+ char *backReference = NULL;
+ if (htmlBrowseButtons == HTML_BUTTONS_TEXT)
+ backReference = "<<";
+ else
+ {
+// backReference = "<img align=center src=\"back.gif\" ALT=\"Previous\">";
+ backReference = backReferenceBuf;
+ sprintf(backReference, "<img align=center src=\"%s\" BORDER=0 ALT=\"Previous\">", ConvertCase("back.gif"));
+ }
+
+ char *forwardReference = NULL;
+ if (htmlBrowseButtons == HTML_BUTTONS_TEXT)
+ forwardReference = ">>";
+ else
+ {
+// forwardReference = "<img align=center src=\"forward.gif\" ALT=\"Next\">";
+ forwardReference = forwardReferenceBuf;
+ sprintf(forwardReference, "<img align=center src=\"%s\" BORDER=0 ALT=\"Next\">", ConvertCase("forward.gif"));
+ }
+
+ TexOutput("<CENTER>");
+
+ char buf[200];
+
+ /*
+ * Contents button
+ *
+ */
+
+ if (truncateFilenames)
+ {
+ char buf1[80];
+ strcpy(buf1, ConvertCase(FileNameFromPath(FileRoot)));
+ sprintf(buf, "\n<A HREF=\"%s.%s\">%s</A> ", buf1, ConvertCase("htm"), contentsReference);
+ }
+ else
+ {
+ char buf1[80];
+ strcpy(buf1, ConvertCase(FileNameFromPath(FileRoot)));
+ sprintf(buf, "\n<A HREF=\"%s%s\">%s</A> ", buf1, ConvertCase("_contents.html"), contentsReference);
+ }
+// TexOutput("<NOFRAMES>");
+ TexOutput(buf);
+// TexOutput("</NOFRAMES>");
+
+ /*
+ * Up button
+ *
+ */
+
+ if (upLabel && upFilename)
+ {
+ if (strlen(upLabel) > 0)
+ sprintf(buf, "<A HREF=\"%s#%s\">%s</A> ", ConvertCase(upFilename), upLabel, upReference);
+ else
+ sprintf(buf, "<A HREF=\"%s\">%s</A> ", ConvertCase(upFilename), upReference);
+ if (strcmp(upLabel, "contents") == 0)
+ {
+// TexOutput("<NOFRAMES>");
+ TexOutput(buf);
+// TexOutput("</NOFRAMES>");
+ }
+ else
+ TexOutput(buf);
+ }
+
+ /*
+ * << button
+ *
+ */
+
+ if (previousLabel && previousFilename)
+ {
+ sprintf(buf, "<A HREF=\"%s#%s\">%s</A> ", ConvertCase(previousFilename), previousLabel, backReference);
+ if (strcmp(previousLabel, "contents") == 0)
+ {
+// TexOutput("<NOFRAMES>");
+ TexOutput(buf);
+// TexOutput("</NOFRAMES>");
+ }
+ else
+ TexOutput(buf);
+ }
+ else
+ {
+ // A placeholder so the buttons don't keep moving position
+ sprintf(buf, "%s ", backReference);
+ TexOutput(buf);
+ }
+
+ char *nextLabel = NULL;
+ char *nextFilename = NULL;
+
+ // Get the next page, and record the previous page's 'next' page
+ // (i.e. this page)
+ TexNextPage *nextPage = (TexNextPage *)TexNextPages.Get(thisLabel);
+ if (nextPage)
+ {
+ nextLabel = nextPage->label;
+ nextFilename = nextPage->filename;
+ }
+ if (previousLabel && previousFilename)
+ {
+ TexNextPage *oldNextPage = (TexNextPage *)TexNextPages.Get(previousLabel);
+ if (oldNextPage)
+ {
+ delete oldNextPage;
+ TexNextPages.Delete(previousLabel);
+ }
+ TexNextPage *newNextPage = new TexNextPage(thisLabel, thisFilename);
+ TexNextPages.Put(previousLabel, newNextPage);
+ }
+
+ /*
+ * >> button
+ *
+ */
+
+ if (nextLabel && nextFilename)
+ {
+ sprintf(buf, "<A HREF=\"%s#%s\">%s</A> ", ConvertCase(nextFilename), nextLabel, forwardReference);
+ TexOutput(buf);
+ }
+ else
+ {
+ // A placeholder so the buttons don't keep moving position
+ sprintf(buf, "%s ", forwardReference);
+ TexOutput(buf);
+ }
+
+ /*
+ * Horizontal rule to finish it off nicely.
+ *
+ */
+ TexOutput("</CENTER>");
+ TexOutput("<HR>\n");
+
+ // Update last topic/filename
+ if (lastFileName)
+ delete[] lastFileName;
+ lastFileName = copystring(thisFilename);
+ if (lastTopic)
+ delete[] lastTopic;
+ lastTopic = copystring(thisLabel);
+}
+
+// A colour string is either 3 numbers separated by semicolons (RGB),
+// or a reference to a GIF. Return the filename or a hex string like #934CE8
+char *ParseColourString(char *bkStr, bool *isPicture)
+{
+ static char resStr[300];
+ strcpy(resStr, bkStr);
+ char *tok1 = strtok(resStr, ";");
+ char *tok2 = strtok(NULL, ";");
+ if (tok1)
+ {
+ if (!tok2)
+ {
+ *isPicture = TRUE;
+ return resStr;
+ }
+ else
+ {
+ *isPicture = FALSE;
+ char *tok3 = strtok(NULL, ";");
+ if (tok3)
+ {
+ // Now convert 3 strings into decimal numbers, and then hex numbers.
+ int red = atoi(tok1);
+ int green = atoi(tok2);
+ int blue = atoi(tok3);
+
+ strcpy(resStr, "#");
+
+ char buf[3];
+ DecToHex(red, buf);
+ strcat(resStr, buf);
+ DecToHex(green, buf);
+ strcat(resStr, buf);
+ DecToHex(blue, buf);
+ strcat(resStr, buf);
+ return resStr;
+ }
+ else return NULL;
+ }
+ }
+ else return NULL;
+}
+
+// Output start of <BODY> block
+void OutputBodyStart(void)
+{
+ TexOutput("\n<BODY");
+ if (backgroundImageString)
+ {
+ bool isPicture = FALSE;
+ char *s = ParseColourString(backgroundImageString, &isPicture);
+ if (s)
+ {
+ TexOutput(" BACKGROUND=\""); TexOutput(s); TexOutput("\"");
+ }
+ }
+ if (backgroundColourString)
+ {
+ bool isPicture = FALSE;
+ char *s = ParseColourString(backgroundColourString, &isPicture);
+ if (s)
+ {
+ TexOutput(" BGCOLOR="); TexOutput(s);
+ }
+ }
+
+ // Set foreground text colour, if one is specified
+ if (textColourString)
+ {
+ bool isPicture = FALSE;
+ char *s = ParseColourString(textColourString, &isPicture);
+ if (s)
+ {
+ TexOutput(" TEXT="); TexOutput(s);
+ }
+ }
+ // Set link text colour, if one is specified
+ if (linkColourString)
+ {
+ bool isPicture = FALSE;
+ char *s = ParseColourString(linkColourString, &isPicture);
+ if (s)
+ {
+ TexOutput(" LINK="); TexOutput(s);
+ }
+ }
+ // Set followed link text colour, if one is specified
+ if (followedLinkColourString)
+ {
+ bool isPicture = FALSE;
+ char *s = ParseColourString(followedLinkColourString, &isPicture);
+ if (s)
+ {
+ TexOutput(" VLINK="); TexOutput(s);
+ }
+ }
+ TexOutput(">\n");
+}
+
+// Called on start/end of macro examination
+void HTMLOnMacro(int macroId, int no_args, bool start)
+{
+ switch (macroId)
+ {
+ case ltCHAPTER:
+ case ltCHAPTERSTAR:
+ case ltCHAPTERHEADING:
+ {
+ if (!start)
+ {
+ sectionNo = 0;
+ figureNo = 0;
+ subsectionNo = 0;
+ subsubsectionNo = 0;
+ if (macroId != ltCHAPTERSTAR)
+ chapterNo ++;
+
+ SetCurrentOutput(NULL);
+ startedSections = TRUE;
+
+ char *topicName = FindTopicName(GetNextChunk());
+ ReopenFile(&Chapters, &ChaptersName);
+ AddTexRef(topicName, ChaptersName, ChapterNameString);
+
+ SetCurrentChapterName(topicName, ChaptersName);
+
+ SetCurrentOutput(Chapters);
+
+ TexOutput("<head><title>");
+ OutputCurrentSection(); // Repeat section header
+ TexOutput("</title></head>\n");
+ OutputBodyStart();
+
+ char titleBuf[200];
+ if (truncateFilenames)
+ sprintf(titleBuf, "%s.htm", FileNameFromPath(FileRoot));
+ else
+ sprintf(titleBuf, "%s_contents.html", FileNameFromPath(FileRoot));
+
+ fprintf(Chapters, "<A NAME=\"%s\"></A>", topicName);
+
+ AddBrowseButtons("", titleBuf, // Up
+ lastTopic, lastFileName, // Last topic
+ topicName, ChaptersName); // This topic
+
+ fprintf(Contents, "\n<LI><A HREF=\"%s#%s\">", ConvertCase(ChaptersName), topicName);
+
+ if (htmlFrameContents && FrameContents)
+ {
+ SetCurrentOutput(FrameContents);
+ fprintf(FrameContents, "\n<LI><A HREF=\"%s#%s\" TARGET=\"mainwindow\">", ConvertCase(ChaptersName), topicName);
+ OutputCurrentSection();
+ fprintf(FrameContents, "</A>\n");
+ }
+
+ SetCurrentOutputs(Contents, Chapters);
+ fprintf(Chapters, "\n<H2>");
+ OutputCurrentSection();
+ fprintf(Contents, "</A>\n");
+ fprintf(Chapters, "</H2>\n");
+
+ SetCurrentOutput(Chapters);
+
+ // Add this section title to the list of keywords
+ if (htmlIndex)
+ {
+ OutputCurrentSectionToString(wxBuffer);
+ AddKeyWordForTopic(topicName, wxBuffer, ConvertCase(currentFileName));
+ }
+ }
+ break;
+ }
+ case ltSECTION:
+ case ltSECTIONSTAR:
+ case ltSECTIONHEADING:
+ case ltGLOSS:
+ {
+ if (!start)
+ {
+ subsectionNo = 0;
+ subsubsectionNo = 0;
+ subsectionStarted = FALSE;
+
+ if (macroId != ltSECTIONSTAR)
+ sectionNo ++;
+
+ SetCurrentOutput(NULL);
+ startedSections = TRUE;
+
+ char *topicName = FindTopicName(GetNextChunk());
+ ReopenFile(&Sections, &SectionsName);
+ AddTexRef(topicName, SectionsName, SectionNameString);
+
+ SetCurrentSectionName(topicName, SectionsName);
+
+ SetCurrentOutput(Sections);
+ TexOutput("<head><title>");
+ OutputCurrentSection();
+ TexOutput("</title></head>\n");
+ OutputBodyStart();
+
+ fprintf(Sections, "<A NAME=\"%s\"></A>", topicName);
+ AddBrowseButtons(CurrentChapterName, CurrentChapterFile, // Up
+ lastTopic, lastFileName, // Last topic
+ topicName, SectionsName); // This topic
+
+ FILE *jumpFrom = ((DocumentStyle == LATEX_ARTICLE) ? Contents : Chapters);
+
+ SetCurrentOutputs(jumpFrom, Sections);
+ if (DocumentStyle == LATEX_ARTICLE)
+ fprintf(jumpFrom, "\n<LI><A HREF=\"%s#%s\">", ConvertCase(SectionsName), topicName);
+ else
+ fprintf(jumpFrom, "\n<A HREF=\"%s#%s\"><B>", ConvertCase(SectionsName), topicName);
+
+ fprintf(Sections, "\n<H2>");
+ OutputCurrentSection();
+
+ if (DocumentStyle == LATEX_ARTICLE)
+ fprintf(jumpFrom, "</A>\n");
+ else
+ fprintf(jumpFrom, "</B></A><BR>\n");
+ fprintf(Sections, "</H2>\n");
+
+ SetCurrentOutput(Sections);
+ // Add this section title to the list of keywords
+ if (htmlIndex)
+ {
+ OutputCurrentSectionToString(wxBuffer);
+ AddKeyWordForTopic(topicName, wxBuffer, currentFileName);
+ }
+ }
+ break;
+ }
+ case ltSUBSECTION:
+ case ltSUBSECTIONSTAR:
+ case ltMEMBERSECTION:
+ case ltFUNCTIONSECTION:
+ {
+ if (!start)
+ {
+ if (!Sections)
+ {
+ OnError("You cannot have a subsection before a section!");
+ }
+ else
+ {
+ subsubsectionNo = 0;
+
+ if (macroId != ltSUBSECTIONSTAR)
+ subsectionNo ++;
+
+ if ( combineSubSections && !subsectionStarted )
+ {
+ // Read old .con file in at this point
+ char buf[256];
+ strcpy(buf, CurrentSectionFile);
+ wxStripExtension(buf);
+ strcat(buf, ".con");
+ FILE *fd = fopen(buf, "r");
+ if ( fd )
+ {
+ int ch = getc(fd);
+ while (ch != EOF)
+ {
+ putc(ch, Sections);
+ ch = getc(fd);
+ }
+ fclose(fd);
+ }
+ fprintf(Sections, "<P>\n");
+
+ // Close old file, create a new file for the sub(sub)section contents entries
+ ReopenSectionContentsFile();
+ }
+
+ startedSections = TRUE;
+ subsectionStarted = TRUE;
+
+ char *topicName = FindTopicName(GetNextChunk());
+
+ if ( !combineSubSections )
+ {
+ SetCurrentOutput(NULL);
+ ReopenFile(&Subsections, &SubsectionsName);
+ AddTexRef(topicName, SubsectionsName, SubsectionNameString);
+ SetCurrentSubsectionName(topicName, SubsectionsName);
+ SetCurrentOutput(Subsections);
+
+ TexOutput("<head><title>");
+ OutputCurrentSection();
+ TexOutput("</title></head>\n");
+ OutputBodyStart();
+
+ fprintf(Subsections, "<A NAME=\"%s\"></A>", topicName);
+ AddBrowseButtons(CurrentSectionName, CurrentSectionFile, // Up
+ lastTopic, lastFileName, // Last topic
+ topicName, SubsectionsName); // This topic
+
+ SetCurrentOutputs(Sections, Subsections);
+ fprintf(Sections, "\n<A HREF=\"%s#%s\"><B>", ConvertCase(SubsectionsName), topicName);
+
+ fprintf(Subsections, "\n<H3>");
+ OutputCurrentSection();
+ fprintf(Sections, "</B></A><BR>\n");
+ fprintf(Subsections, "</H3>\n");
+
+ SetCurrentOutput(Subsections);
+ }
+ else
+ {
+ AddTexRef(topicName, SectionsName, SubsectionNameString);
+ SetCurrentSubsectionName(topicName, SectionsName);
+// if ( subsectionNo != 0 )
+ fprintf(Sections, "\n<HR>\n");
+
+ // We're putting everything into the section file
+ fprintf(Sections, "<A NAME=\"%s\"></A>", topicName);
+ fprintf(Sections, "\n<H3>");
+ OutputCurrentSection();
+ fprintf(Sections, "</H3>\n");
+
+ SetCurrentOutput(SectionContentsFD);
+ fprintf(SectionContentsFD, "<A HREF=\"#%s\">", topicName);
+ OutputCurrentSection();
+ TexOutput("</A><BR>\n");
+
+ SetCurrentOutput(Sections);
+ }
+ // Add this section title to the list of keywords
+ if (htmlIndex)
+ {
+ OutputCurrentSectionToString(wxBuffer);
+ AddKeyWordForTopic(topicName, wxBuffer, currentFileName);
+ }
+
+ }
+ }
+ break;
+ }
+ case ltSUBSUBSECTION:
+ case ltSUBSUBSECTIONSTAR:
+ {
+ if (!start)
+ {
+ if (!Subsections && !combineSubSections)
+ {
+ OnError("You cannot have a subsubsection before a subsection!");
+ }
+ else
+ {
+ if (macroId != ltSUBSUBSECTIONSTAR)
+ subsubsectionNo ++;
+
+ startedSections = TRUE;
+
+ char *topicName = FindTopicName(GetNextChunk());
+
+ if ( !combineSubSections )
+ {
+ SetCurrentOutput(NULL);
+ ReopenFile(&Subsubsections, &SubsubsectionsName);
+ AddTexRef(topicName, SubsubsectionsName, SubsubsectionNameString);
+ SetCurrentSubsubsectionName(topicName, SubsubsectionsName);
+
+ SetCurrentOutput(Subsubsections);
+ TexOutput("<head><title>");
+ OutputCurrentSection();
+ TexOutput("</title></head>\n");
+ OutputBodyStart();
+
+ fprintf(Subsubsections, "<A NAME=\"%s\"></A>", topicName);
+
+ AddBrowseButtons(CurrentSubsectionName, CurrentSubsectionFile, // Up
+ lastTopic, lastFileName, // Last topic
+ topicName, SubsubsectionsName); // This topic
+
+ SetCurrentOutputs(Subsections, Subsubsections);
+ fprintf(Subsections, "\n<A HREF=\"%s#%s\"><B>", ConvertCase(SubsubsectionsName), topicName);
+
+ fprintf(Subsubsections, "\n<H3>");
+ OutputCurrentSection();
+ fprintf(Subsections, "</B></A><BR>\n");
+ fprintf(Subsubsections, "</H3>\n");
+ }
+ else
+ {
+ AddTexRef(topicName, SectionsName, SubsubsectionNameString);
+ SetCurrentSubsectionName(topicName, SectionsName);
+ fprintf(Sections, "\n<HR>\n");
+
+ // We're putting everything into the section file
+ fprintf(Sections, "<A NAME=\"%s\"></A>", topicName);
+ fprintf(Sections, "\n<H3>");
+ OutputCurrentSection();
+ fprintf(Sections, "</H3>\n");
+/* TODO: where do we put subsubsection contents entry - indented, with subsection entries?
+ SetCurrentOutput(SectionContentsFD);
+ fprintf(SectionContentsFD, "<A HREF=\"#%s\">", topicName);
+ OutputCurrentSection();
+ TexOutput("</A><BR>");
+*/
+ SetCurrentOutput(Sections);
+ }
+
+ // Add this section title to the list of keywords
+ if (htmlIndex)
+ {
+ OutputCurrentSectionToString(wxBuffer);
+ AddKeyWordForTopic(topicName, wxBuffer, currentFileName);
+ }
+ }
+ }
+ break;
+ }
+ case ltFUNC:
+ case ltPFUNC:
+ {
+ if ( !combineSubSections )
+ SetCurrentOutput(Subsections);
+ else
+ SetCurrentOutput(Sections);
+ if (start)
+ {
+ }
+ else
+ {
+ }
+ break;
+ }
+ case ltCLIPSFUNC:
+ {
+ if ( !combineSubSections )
+ SetCurrentOutput(Subsections);
+ else
+ SetCurrentOutput(Sections);
+ if (start)
+ {
+ }
+ else
+ {
+ }
+ break;
+ }
+ case ltMEMBER:
+ {
+ if ( !combineSubSections )
+ SetCurrentOutput(Subsections);
+ else
+ SetCurrentOutput(Sections);
+ if (start)
+ {
+ }
+ else
+ {
+ }
+ break;
+ }
+ case ltVOID:
+// if (start)
+// TexOutput("<B>void</B>");
+ break;
+ case ltHARDY:
+ if (start)
+ TexOutput("HARDY");
+ break;
+ case ltWXCLIPS:
+ if (start)
+ TexOutput("wxCLIPS");
+ break;
+ case ltAMPERSAND:
+ if (start)
+ TexOutput("&");
+ break;
+ case ltSPECIALAMPERSAND:
+ {
+ if (start)
+ {
+ if (inTabular)
+ {
+ // End cell, start cell
+ TexOutput("</TD>");
+
+ // Start new row and cell, setting alignment for the first cell.
+ if (currentColumn < noColumns)
+ currentColumn ++;
+
+ char buf[100];
+ if (TableData[currentColumn].justification == 'c')
+ sprintf(buf, "\n<TD ALIGN=CENTER>");
+ else if (TableData[currentColumn].justification == 'r')
+ sprintf(buf, "\n<TD ALIGN=RIGHT>");
+ else if (TableData[currentColumn].absWidth)
+ {
+ // Convert from points * 20 into pixels.
+ int points = TableData[currentColumn].width / 20;
+
+ // Say the display is 100 DPI (dots/pixels per inch).
+ // There are 72 pts to the inch. So 1pt = 1/72 inch, or 100 * 1/72 dots.
+ int pixels = (int)(points * 100.0 / 72.0);
+ sprintf(buf, "<TD ALIGN=CENTER WIDTH=%d>", pixels);
+ }
+ else
+ sprintf(buf, "\n<TD ALIGN=LEFT>");
+ TexOutput(buf);
+ }
+ else
+ TexOutput("&");
+ }
+ break;
+ }
+ case ltBACKSLASHCHAR:
+ {
+ if (start)
+ {
+ if (inTabular)
+ {
+ // End row. In fact, tables without use of \row or \ruledrow isn't supported for
+ // HTML: the syntax is too different (e.g. how do we know where to put the first </TH>
+ // if we've ended the last row?). So normally you wouldn't use \\ to end a row.
+ TexOutput("</TR>\n");
+ }
+ else
+ TexOutput("<BR>\n");
+ }
+ break;
+ }
+ case ltROW:
+ case ltRULEDROW:
+ {
+ if (start)
+ {
+ currentColumn = 0;
+
+ // Start new row and cell, setting alignment for the first cell.
+ char buf[100];
+ if (TableData[currentColumn].justification == 'c')
+ sprintf(buf, "<TR>\n<TD ALIGN=CENTER>");
+ else if (TableData[currentColumn].justification == 'r')
+ sprintf(buf, "<TR>\n<TD ALIGN=RIGHT>");
+ else if (TableData[currentColumn].absWidth)
+ {
+ // Convert from points * 20 into pixels.
+ int points = TableData[currentColumn].width / 20;
+
+ // Say the display is 100 DPI (dots/pixels per inch).
+ // There are 72 pts to the inch. So 1pt = 1/72 inch, or 100 * 1/72 dots.
+ int pixels = (int)(points * 100.0 / 72.0);
+ sprintf(buf, "<TR>\n<TD ALIGN=CENTER WIDTH=%d>", pixels);
+ }
+ else
+ sprintf(buf, "<TR>\n<TD ALIGN=LEFT>");
+ TexOutput(buf);
+ }
+ else
+ {
+ // End cell and row
+ // Start new row and cell
+ TexOutput("</TD>\n</TR>\n");
+ }
+ break;
+ }
+ // HTML-only: break until the end of the picture (both margins are clear).
+ case ltBRCLEAR:
+ {
+ if (start)
+ TexOutput("<BR CLEAR=ALL>");
+ break;
+ }
+ case ltRTFSP: // Explicit space, RTF only
+ break;
+ case ltSPECIALTILDE:
+ {
+ if (start)
+ {
+ if (inVerbatim)
+ TexOutput("~");
+ else
+ TexOutput(" ");
+ }
+ break;
+ }
+ case ltINDENTED :
+ {
+ if ( start )
+ TexOutput("<UL><UL>\n");
+ else
+ TexOutput("</UL></UL>\n");
+ break;
+ }
+ case ltITEMIZE:
+ case ltENUMERATE:
+ case ltDESCRIPTION:
+// case ltTWOCOLLIST:
+ {
+ if (start)
+ {
+ indentLevel ++;
+
+ int listType;
+ if (macroId == ltENUMERATE)
+ listType = LATEX_ENUMERATE;
+ else if (macroId == ltITEMIZE)
+ listType = LATEX_ITEMIZE;
+ else
+ listType = LATEX_DESCRIPTION;
+
+ itemizeStack.Insert(new ItemizeStruc(listType));
+ switch (listType)
+ {
+ case LATEX_ITEMIZE:
+ TexOutput("<UL>\n");
+ break;
+ case LATEX_ENUMERATE:
+ TexOutput("<OL>\n");
+ break;
+ case LATEX_DESCRIPTION:
+ default:
+ TexOutput("<DL>\n");
+ break;
+ }
+ }
+ else
+ {
+ indentLevel --;
+ if (itemizeStack.First())
+ {
+ ItemizeStruc *struc = (ItemizeStruc *)itemizeStack.First()->Data();
+ switch (struc->listType)
+ {
+ case LATEX_ITEMIZE:
+ TexOutput("</UL>\n");
+ break;
+ case LATEX_ENUMERATE:
+ TexOutput("</OL>\n");
+ break;
+ case LATEX_DESCRIPTION:
+ default:
+ TexOutput("</DL>\n");
+ break;
+ }
+
+ delete struc;
+ delete itemizeStack.First();
+ }
+ }
+ break;
+ }
+ case ltTWOCOLLIST :
+ {
+ if ( start )
+ TexOutput("\n<TABLE>\n");
+ else
+ TexOutput("\n</TABLE>\n");
+ break;
+ }
+ case ltPAR:
+ {
+ if (start)
+ TexOutput("<P>\n");
+ break;
+ }
+/* For footnotes we need to output the text at the bottom of the page and
+ * insert a reference to it. Is it worth the trouble...
+ case ltFOOTNOTE:
+ case ltFOOTNOTEPOPUP:
+ {
+ if (start)
+ {
+ TexOutput("<FN>);
+ }
+ else TexOutput("</FN>");
+ break;
+ }
+*/
+ case ltVERB:
+ {
+ if (start)
+ TexOutput("<TT>");
+ else TexOutput("</TT>");
+ break;
+ }
+ case ltVERBATIM:
+ {
+ if (start)
+ {
+ char buf[100];
+ sprintf(buf, "<PRE>\n");
+ TexOutput(buf);
+ }
+ else TexOutput("</PRE>\n");
+ break;
+ }
+ case ltCENTERLINE:
+ case ltCENTER:
+ {
+ if (start)
+ {
+ TexOutput("<CENTER>");
+ }
+ else TexOutput("</CENTER>");
+ break;
+ }
+ case ltFLUSHLEFT:
+ {
+/*
+ if (start)
+ {
+ TexOutput("{\\ql ");
+ }
+ else TexOutput("}\\par\\pard\n");
+*/
+ break;
+ }
+ case ltFLUSHRIGHT:
+ {
+/*
+ if (start)
+ {
+ TexOutput("{\\qr ");
+ }
+ else TexOutput("}\\par\\pard\n");
+*/
+ break;
+ }
+ case ltSMALL:
+ {
+ if (start)
+ {
+ // Netscape extension
+ TexOutput("<FONT SIZE=2>");
+ }
+ else TexOutput("</FONT>");
+ break;
+ }
+ case ltTINY:
+ {
+ if (start)
+ {
+ // Netscape extension
+ TexOutput("<FONT SIZE=1>");
+ }
+ else TexOutput("</FONT>");
+ break;
+ }
+ case ltNORMALSIZE:
+ {
+ if (start)
+ {
+ // Netscape extension
+ TexOutput("<FONT SIZE=3>");
+ }
+ else TexOutput("</FONT>");
+ break;
+ }
+ case ltlarge:
+ {
+ if (start)
+ {
+ // Netscape extension
+ TexOutput("<FONT SIZE=4>");
+ }
+ else TexOutput("</FONT>");
+ break;
+ }
+ case ltLarge:
+ {
+ if (start)
+ {
+ // Netscape extension
+ TexOutput("<FONT SIZE=5>");
+ }
+ else TexOutput("</FONT>");
+ break;
+ }
+ case ltLARGE:
+ {
+ if (start)
+ {
+ // Netscape extension
+ TexOutput("<FONT SIZE=6>");
+ }
+ else TexOutput("</FONT>");
+ break;
+ }
+ case ltBFSERIES:
+ case ltTEXTBF:
+ case ltBF:
+ {
+ if (start)
+ {
+ TexOutput("<B>");
+ }
+ else TexOutput("</B>");
+ break;
+ }
+ case ltITSHAPE:
+ case ltTEXTIT:
+ case ltIT:
+ {
+ if (start)
+ {
+ TexOutput("<I>");
+ }
+ else TexOutput("</I>");
+ break;
+ }
+ case ltEMPH:
+ case ltEM:
+ {
+ if (start)
+ {
+ TexOutput("<EM>");
+ }
+ else TexOutput("</EM>");
+ break;
+ }
+ case ltUNDERLINE:
+ {
+ if (start)
+ {
+ TexOutput("<UL>");
+ }
+ else TexOutput("</UL>");
+ break;
+ }
+ case ltTTFAMILY:
+ case ltTEXTTT:
+ case ltTT:
+ {
+ if (start)
+ {
+ TexOutput("<TT>");
+ }
+ else TexOutput("</TT>");
+ break;
+ }
+ case ltCOPYRIGHT:
+ {
+ if (start)
+ TexOutput("©", TRUE);
+ break;
+ }
+ case ltREGISTERED:
+ {
+ if (start)
+ TexOutput("®", TRUE);
+ break;
+ }
+ // Arrows
+ case ltLEFTARROW:
+ {
+ if (start) TexOutput("<--");
+ break;
+ }
+ case ltLEFTARROW2:
+ {
+ if (start) TexOutput("<==");
+ break;
+ }
+ case ltRIGHTARROW:
+ {
+ if (start) TexOutput("-->");
+ break;
+ }
+ case ltRIGHTARROW2:
+ {
+ if (start) TexOutput("==>");
+ break;
+ }
+ case ltLEFTRIGHTARROW:
+ {
+ if (start) TexOutput("<-->");
+ break;
+ }
+ case ltLEFTRIGHTARROW2:
+ {
+ if (start) TexOutput("<==>");
+ break;
+ }
+/*
+ case ltSC:
+ {
+ break;
+ }
+*/
+ case ltITEM:
+ {
+ if (!start)
+ {
+ wxNode *node = itemizeStack.First();
+ if (node)
+ {
+ ItemizeStruc *struc = (ItemizeStruc *)node->Data();
+ struc->currentItem += 1;
+ if (struc->listType == LATEX_DESCRIPTION)
+ {
+ if (descriptionItemArg)
+ {
+ TexOutput("<DT> ");
+ TraverseChildrenFromChunk(descriptionItemArg);
+ TexOutput("\n");
+ descriptionItemArg = NULL;
+ }
+ TexOutput("<DD>");
+ }
+ else
+ TexOutput("<LI>");
+ }
+ }
+ break;
+ }
+ case ltMAKETITLE:
+ {
+ if (start && DocumentTitle && DocumentAuthor)
+ {
+ // Add a special label for the contents page.
+// TexOutput("<CENTER>\n");
+ TexOutput("<A NAME=\"contents\">");
+ TexOutput("<H2 ALIGN=CENTER>\n");
+ TraverseChildrenFromChunk(DocumentTitle);
+ TexOutput("</H2>");
+ TexOutput("<P>");
+ TexOutput("</A>\n");
+ TexOutput("<P>\n\n");
+ TexOutput("<H3 ALIGN=CENTER>");
+ TraverseChildrenFromChunk(DocumentAuthor);
+ TexOutput("</H3><P>\n\n");
+ if (DocumentDate)
+ {
+ TexOutput("<H3 ALIGN=CENTER>");
+ TraverseChildrenFromChunk(DocumentDate);
+ TexOutput("</H3><P>\n\n");
+ }
+// TexOutput("\n</CENTER>\n");
+ TexOutput("\n<P><HR><P>\n");
+
+/*
+ // Now do optional frame contents page
+ if (htmlFrameContents && FrameContents)
+ {
+ SetCurrentOutput(FrameContents);
+
+ // Add a special label for the contents page.
+ TexOutput("<CENTER>\n");
+ TexOutput("<H3>\n");
+ TraverseChildrenFromChunk(DocumentTitle);
+ TexOutput("</H3>");
+ TexOutput("<P>");
+ TexOutput("</A>\n");
+ TexOutput("<P>\n\n");
+ TexOutput("<H3>");
+ TraverseChildrenFromChunk(DocumentAuthor);
+ TexOutput("</H3><P>\n\n");
+ if (DocumentDate)
+ {
+ TexOutput("<H4>");
+ TraverseChildrenFromChunk(DocumentDate);
+ TexOutput("</H4><P>\n\n");
+ }
+ TexOutput("\n</CENTER>\n");
+ TexOutput("<P><HR><P>\n");
+
+ SetCurrentOutput(Titlepage);
+ }
+*/
+ }
+ break;
+ }
+ case ltHELPREF:
+ case ltHELPREFN:
+ case ltPOPREF:
+ case ltURLREF:
+ {
+ if (start)
+ {
+ helpRefFilename = NULL;
+ helpRefText = NULL;
+ }
+ break;
+ }
+ case ltBIBLIOGRAPHY:
+ {
+ if (start)
+ {
+ DefaultOnMacro(macroId, no_args, start);
+ }
+ else
+ {
+ DefaultOnMacro(macroId, no_args, start);
+ TexOutput("</DL>\n");
+ }
+ break;
+ }
+ case ltHRULE:
+ {
+ if (start)
+ {
+ TexOutput("<HR>\n");
+ }
+ break;
+ }
+ case ltRULE:
+ {
+ if (start)
+ {
+ TexOutput("<HR>\n");
+ }
+ break;
+ }
+ case ltTABLEOFCONTENTS:
+ {
+ if (start)
+ {
+ FILE *fd = fopen(ContentsName, "r");
+ if (fd)
+ {
+ int ch = getc(fd);
+ while (ch != EOF)
+ {
+ putc(ch, Titlepage);
+ ch = getc(fd);
+ }
+ fclose(fd);
+ }
+ else
+ {
+ TexOutput("RUN TEX2RTF AGAIN FOR CONTENTS PAGE\n");
+ OnInform("Run Tex2RTF again to include contents page.");
+ }
+ }
+ break;
+ }
+ case ltLANGLEBRA:
+ {
+ if (start)
+ TexOutput("<");
+ break;
+ }
+ case ltRANGLEBRA:
+ {
+ if (start)
+ TexOutput(">");
+ break;
+ }
+ case ltQUOTE:
+ case ltQUOTATION:
+ {
+ if (start)
+ TexOutput("<BLOCKQUOTE>");
+ else
+ TexOutput("</BLOCKQUOTE>");
+ break;
+ }
+ case ltCAPTION:
+ case ltCAPTIONSTAR:
+ {
+ if (start)
+ {
+ if (inTabular)
+ TexOutput("\n<CAPTION>");
+
+ char figBuf[40];
+
+ if ( inFigure )
+ {
+ figureNo ++;
+
+ if (DocumentStyle != LATEX_ARTICLE)
+ sprintf(figBuf, "%s %d.%d: ", FigureNameString, chapterNo, figureNo);
+ else
+ sprintf(figBuf, "%s %d: ", FigureNameString, figureNo);
+ }
+ else
+ {
+ tableNo ++;
+
+ if (DocumentStyle != LATEX_ARTICLE)
+ sprintf(figBuf, "%s %d.%d: ", TableNameString, chapterNo, tableNo);
+ else
+ sprintf(figBuf, "%s %d: ", TableNameString, tableNo);
+ }
+
+ TexOutput(figBuf);
+ }
+ else
+ {
+ if (inTabular)
+ TexOutput("\n</CAPTION>\n");
+
+ char *topicName = FindTopicName(GetNextChunk());
+
+ int n = inFigure ? figureNo : tableNo;
+
+ AddTexRef(topicName, NULL, NULL,
+ ((DocumentStyle != LATEX_ARTICLE) ? chapterNo : n),
+ ((DocumentStyle != LATEX_ARTICLE) ? n : 0));
+ }
+ break;
+ }
+ case ltSS:
+ {
+ if (start) TexOutput("ß");
+ break;
+ }
+ case ltFIGURE:
+ {
+ if (start) inFigure = TRUE;
+ else inFigure = FALSE;
+ break;
+ }
+ case ltTABLE:
+ {
+ if (start) inTable = TRUE;
+ else inTable = FALSE;
+ break;
+ }
+ default:
+ DefaultOnMacro(macroId, no_args, start);
+ break;
+ }
+}
+
+// Called on start/end of argument examination
+bool HTMLOnArgument(int macroId, int arg_no, bool start)
+{
+ switch (macroId)
+ {
+ case ltCHAPTER:
+ case ltCHAPTERSTAR:
+ case ltCHAPTERHEADING:
+ case ltSECTION:
+ case ltSECTIONSTAR:
+ case ltSECTIONHEADING:
+ case ltSUBSECTION:
+ case ltSUBSECTIONSTAR:
+ case ltSUBSUBSECTION:
+ case ltSUBSUBSECTIONSTAR:
+ case ltGLOSS:
+ case ltMEMBERSECTION:
+ case ltFUNCTIONSECTION:
+ {
+ if (!start && (arg_no == 1))
+ currentSection = GetArgChunk();
+ return FALSE;
+ break;
+ }
+ case ltFUNC:
+ {
+ if (start && (arg_no == 1))
+ TexOutput("<B>");
+
+ if (!start && (arg_no == 1))
+ TexOutput("</B> ");
+
+ if (start && (arg_no == 2))
+ {
+ if (!suppressNameDecoration) TexOutput("<B>");
+ currentMember = GetArgChunk();
+ }
+ if (!start && (arg_no == 2))
+ {
+ if (!suppressNameDecoration) TexOutput("</B>");
+ }
+
+ if (start && (arg_no == 3))
+ TexOutput("(");
+ if (!start && (arg_no == 3))
+ TexOutput(")");
+ break;
+ }
+ case ltCLIPSFUNC:
+ {
+ if (start && (arg_no == 1))
+ TexOutput("<B>");
+ if (!start && (arg_no == 1))
+ TexOutput("</B> ");
+
+ if (start && (arg_no == 2))
+ {
+ if (!suppressNameDecoration) TexOutput("( ");
+ currentMember = GetArgChunk();
+ }
+ if (!start && (arg_no == 2))
+ {
+ }
+
+ if (!start && (arg_no == 3))
+ TexOutput(")");
+ break;
+ }
+ case ltPFUNC:
+ {
+ if (!start && (arg_no == 1))
+ TexOutput(" ");
+
+ if (start && (arg_no == 2))
+ TexOutput("(*");
+ if (!start && (arg_no == 2))
+ TexOutput(")");
+
+ if (start && (arg_no == 2))
+ currentMember = GetArgChunk();
+
+ if (start && (arg_no == 3))
+ TexOutput("(");
+ if (!start && (arg_no == 3))
+ TexOutput(")");
+ break;
+ }
+ case ltPARAM:
+ {
+ if (start && (arg_no == 1))
+ TexOutput("<B>");
+ if (!start && (arg_no == 1))
+ TexOutput("</B>");
+ if (start && (arg_no == 2))
+ {
+ TexOutput("<I>");
+ }
+ if (!start && (arg_no == 2))
+ {
+ TexOutput("</I>");
+ }
+ break;
+ }
+ case ltCPARAM:
+ {
+ if (start && (arg_no == 1))
+ TexOutput("<B>");
+ if (!start && (arg_no == 1))
+ TexOutput("</B> "); // This is the difference from param - one space!
+ if (start && (arg_no == 2))
+ {
+ TexOutput("<I>");
+ }
+ if (!start && (arg_no == 2))
+ {
+ TexOutput("</I>");
+ }
+ break;
+ }
+ case ltMEMBER:
+ {
+ if (!start && (arg_no == 1))
+ TexOutput(" ");
+
+ if (start && (arg_no == 2))
+ currentMember = GetArgChunk();
+ break;
+ }
+ case ltREF:
+ {
+ if (start)
+ {
+ char *sec = NULL;
+
+ char *refName = GetArgData();
+ if (refName)
+ {
+ TexRef *texRef = FindReference(refName);
+ if (texRef)
+ {
+ sec = texRef->sectionNumber;
+ }
+ }
+ if (sec)
+ {
+ TexOutput(sec);
+ }
+ return FALSE;
+ }
+ break;
+ }
+ case ltURLREF:
+ {
+ if (IsArgOptional())
+ return FALSE;
+ else if ((GetNoArgs() - arg_no) == 1)
+ {
+ if (start)
+ helpRefText = GetArgChunk();
+ return FALSE;
+ }
+ else if ((GetNoArgs() - arg_no) == 0) // Arg = 2, or 3 if first is optional
+ {
+ if (start)
+ {
+ TexChunk *ref = GetArgChunk();
+ TexOutput("<A HREF=\"");
+ inVerbatim = TRUE;
+ TraverseChildrenFromChunk(ref);
+ inVerbatim = FALSE;
+ TexOutput("\">");
+ if (helpRefText)
+ TraverseChildrenFromChunk(helpRefText);
+ TexOutput("</A>");
+ }
+ return FALSE;
+ }
+ break;
+ }
+ case ltHELPREF:
+ case ltHELPREFN:
+ case ltPOPREF:
+ {
+ if (IsArgOptional())
+ {
+ if (start)
+ helpRefFilename = GetArgChunk();
+ return FALSE;
+ }
+ if ((GetNoArgs() - arg_no) == 1)
+ {
+ if (start)
+ helpRefText = GetArgChunk();
+ return FALSE;
+ }
+ else if ((GetNoArgs() - arg_no) == 0) // Arg = 2, or 3 if first is optional
+ {
+ if (start)
+ {
+ char *refName = GetArgData();
+ char *refFilename = NULL;
+
+ if (refName)
+ {
+ TexRef *texRef = FindReference(refName);
+ if (texRef)
+ {
+ if (texRef->refFile && strcmp(texRef->refFile, "??") != 0)
+ refFilename = texRef->refFile;
+
+ TexOutput("<A HREF=\"");
+ // If a filename is supplied, use it, otherwise try to
+ // use the filename associated with the reference (from this document).
+ if (helpRefFilename)
+ {
+ TraverseChildrenFromChunk(helpRefFilename);
+ TexOutput("#");
+ }
+ else if (refFilename)
+ {
+ TexOutput(ConvertCase(refFilename));
+ TexOutput("#");
+ }
+ TexOutput(refName);
+ TexOutput("\">");
+ if (helpRefText)
+ TraverseChildrenFromChunk(helpRefText);
+ TexOutput("</A>");
+ }
+ else
+ {
+ if (helpRefText)
+ TraverseChildrenFromChunk(helpRefText);
+ TexOutput(" (REF NOT FOUND)");
+ }
+ }
+ else TexOutput("??");
+ }
+ return FALSE;
+ }
+ break;
+ }
+ case ltIMAGE:
+ case ltIMAGEL:
+ case ltIMAGER:
+ case ltPSBOXTO:
+ {
+ if (arg_no == 2)
+ {
+ if (start)
+ {
+ char *alignment = "";
+ if (macroId == ltIMAGEL)
+ alignment = " align=left";
+ else if (macroId == ltIMAGER)
+ alignment = " align=right";
+
+ // Try to find an XBM or GIF image first.
+ char *filename = copystring(GetArgData());
+ char buf[500];
+
+ strcpy(buf, filename);
+ StripExtension(buf);
+ strcat(buf, ".xbm");
+ wxString f = TexPathList.FindValidPath(buf);
+
+ if (f == "") // Try for a GIF instead
+ {
+ strcpy(buf, filename);
+ StripExtension(buf);
+ strcat(buf, ".gif");
+ f = TexPathList.FindValidPath(buf);
+ }
+ if (f != "")
+ {
+ char *inlineFilename = copystring(f);
+#if 0
+ char *originalFilename = TexPathList.FindValidPath(filename);
+ // If we have found the existing filename, make the inline
+ // image point to the original file (could be PS, for example)
+ if (originalFilename && (strcmp(inlineFilename, originalFilename) != 0))
+ {
+ TexOutput("<A HREF=\"");
+ TexOutput(ConvertCase(originalFilename));
+ TexOutput("\">");
+ TexOutput("<img src=\"");
+ TexOutput(ConvertCase(wxFileNameFromPath(inlineFilename)));
+ TexOutput("\""); TexOutput(alignment); TexOutput("></A>");
+ }
+ else
+#endif
+ {
+ TexOutput("<img src=\"");
+ TexOutput(ConvertCase(wxFileNameFromPath(inlineFilename)));
+ TexOutput("\""); TexOutput(alignment); TexOutput("></A>");
+ delete[] inlineFilename;
+ }
+ }
+ else
+ {
+ // Last resort - a link to a PS file.
+ TexOutput("<A HREF=\"");
+ TexOutput(ConvertCase(wxFileNameFromPath(filename)));
+ TexOutput("\">Picture</A>\n");
+ sprintf(buf, "Warning: could not find an inline XBM/GIF for %s.", filename);
+ OnInform(buf);
+ }
+ }
+ }
+ return FALSE;
+ break;
+ }
+ // First arg is PSBOX spec (ignored), second is image file, third is map name.
+ case ltIMAGEMAP:
+ {
+ static char *imageFile = NULL;
+ if (start && (arg_no == 2))
+ {
+ // Try to find an XBM or GIF image first.
+ char *filename = copystring(GetArgData());
+ char buf[500];
+
+ strcpy(buf, filename);
+ StripExtension(buf);
+ strcat(buf, ".xbm");
+ wxString f = TexPathList.FindValidPath(buf);
+
+ if (f == "") // Try for a GIF instead
+ {
+ strcpy(buf, filename);
+ StripExtension(buf);
+ strcat(buf, ".gif");
+ f = TexPathList.FindValidPath(buf);
+ }
+ if (f == "")
+ {
+ char buf[300];
+ sprintf(buf, "Warning: could not find an inline XBM/GIF for %s.", filename);
+ OnInform(buf);
+ }
+ delete[] filename;
+ if (imageFile)
+ delete[] imageFile;
+ imageFile = NULL;
+ if (f)
+ {
+ imageFile = copystring(f);
+ }
+ }
+ else if (start && (arg_no == 3))
+ {
+ if (imageFile)
+ {
+ // First, try to find a .shg (segmented hypergraphics file)
+ // that we can convert to a map file
+ char buf[256];
+ strcpy(buf, imageFile);
+ StripExtension(buf);
+ strcat(buf, ".shg");
+ wxString f = TexPathList.FindValidPath(buf);
+
+ if (f != "")
+ {
+ // The default HTML file to go to is THIS file (so a no-op)
+ SHGToMap((char*) (const char*) f, currentFileName);
+ }
+
+ char *mapName = GetArgData();
+ TexOutput("<A HREF=\"/cgi-bin/imagemap/");
+ if (mapName)
+ TexOutput(mapName);
+ else
+ TexOutput("unknown");
+ TexOutput("\">");
+ TexOutput("<img src=\"");
+ TexOutput(ConvertCase(wxFileNameFromPath(imageFile)));
+ TexOutput("\" ISMAP></A><P>");
+ delete[] imageFile;
+ imageFile = NULL;
+ }
+ }
+ return FALSE;
+ break;
+ }
+ case ltINDENTED :
+ {
+ if ( arg_no == 1 )
+ return FALSE;
+ else
+ {
+ return TRUE;
+ }
+ }
+ case ltITEM:
+ {
+ if (start)
+ {
+ descriptionItemArg = GetArgChunk();
+ return FALSE;
+ }
+ }
+ case ltTWOCOLITEM:
+ case ltTWOCOLITEMRULED:
+ {
+/*
+ if (start && (arg_no == 1))
+ TexOutput("\n<DT> ");
+ if (start && (arg_no == 2))
+ TexOutput("<DD> ");
+*/
+ if (arg_no == 1)
+ {
+ if ( start )
+ TexOutput("\n<TR><TD VALIGN=TOP>\n");
+ else
+ TexOutput("\n</TD>\n");
+ }
+ if (arg_no == 2)
+ {
+ if ( start )
+ TexOutput("\n<TD VALIGN=TOP>\n");
+ else
+ TexOutput("\n</TD></TR>\n");
+ }
+ return TRUE;
+ break;
+ }
+ case ltNUMBEREDBIBITEM:
+ {
+ if (arg_no == 1 && start)
+ {
+ TexOutput("\n<DT> ");
+ }
+ if (arg_no == 2 && !start)
+ TexOutput("<P>\n");
+ break;
+ }
+ case ltBIBITEM:
+ {
+ char buf[100];
+ if (arg_no == 1 && start)
+ {
+ char *citeKey = GetArgData();
+ TexRef *ref = (TexRef *)TexReferences.Get(citeKey);
+ if (ref)
+ {
+ if (ref->sectionNumber) delete[] ref->sectionNumber;
+ sprintf(buf, "[%d]", citeCount);
+ ref->sectionNumber = copystring(buf);
+ }
+
+ sprintf(buf, "\n<DT> [%d] ", citeCount);
+ TexOutput(buf);
+ citeCount ++;
+ return FALSE;
+ }
+ if (arg_no == 2 && !start)
+ TexOutput("<P>\n");
+ return TRUE;
+ break;
+ }
+ case ltMARGINPAR:
+ case ltMARGINPARODD:
+ case ltMARGINPAREVEN:
+ case ltNORMALBOX:
+ case ltNORMALBOXD:
+ {
+ if (start)
+ {
+ TexOutput("<HR>\n");
+ return TRUE;
+ }
+ else
+ TexOutput("<HR><P>\n");
+ break;
+ }
+ /*
+ * Accents
+ *
+ */
+ case ltACCENT_GRAVE:
+ {
+ if (start)
+ {
+ char *val = GetArgData();
+ if (val)
+ {
+ switch (val[0])
+ {
+ case 'a':
+ TexOutput("à");
+ break;
+ case 'e':
+ TexOutput("è");
+ break;
+ case 'i':
+ TexOutput("ì");
+ break;
+ case 'o':
+ TexOutput("ò");
+ break;
+ case 'u':
+ TexOutput("ù");
+ break;
+ case 'A':
+ TexOutput("À");
+ break;
+ case 'E':
+ TexOutput("È");
+ break;
+ case 'I':
+ TexOutput("Ì");
+ break;
+ case 'O':
+ TexOutput("Ò");
+ break;
+ case 'U':
+ TexOutput("Ì");
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ return FALSE;
+ break;
+ }
+ case ltACCENT_ACUTE:
+ {
+ if (start)
+ {
+ char *val = GetArgData();
+ if (val)
+ {
+ switch (val[0])
+ {
+ case 'a':
+ TexOutput("á");
+ break;
+ case 'e':
+ TexOutput("é");
+ break;
+ case 'i':
+ TexOutput("í");
+ break;
+ case 'o':
+ TexOutput("ó");
+ break;
+ case 'u':
+ TexOutput("ú");
+ break;
+ case 'y':
+ TexOutput("ý");
+ break;
+ case 'A':
+ TexOutput("Á");
+ break;
+ case 'E':
+ TexOutput("É");
+ break;
+ case 'I':
+ TexOutput("Í");
+ break;
+ case 'O':
+ TexOutput("Ó");
+ break;
+ case 'U':
+ TexOutput("Ú");
+ break;
+ case 'Y':
+ TexOutput("Ý");
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ return FALSE;
+ break;
+ }
+ case ltACCENT_CARET:
+ {
+ if (start)
+ {
+ char *val = GetArgData();
+ if (val)
+ {
+ switch (val[0])
+ {
+ case 'a':
+ TexOutput("â");
+ break;
+ case 'e':
+ TexOutput("ê");
+ break;
+ case 'i':
+ TexOutput("î");
+ break;
+ case 'o':
+ TexOutput("ô");
+ break;
+ case 'u':
+ TexOutput("û");
+ break;
+ case 'A':
+ TexOutput("Â");
+ break;
+ case 'E':
+ TexOutput("Ê");
+ break;
+ case 'I':
+ TexOutput("Î");
+ break;
+ case 'O':
+ TexOutput("Ô");
+ break;
+ case 'U':
+ TexOutput("Î");
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ return FALSE;
+ break;
+ }
+ case ltACCENT_TILDE:
+ {
+ if (start)
+ {
+ char *val = GetArgData();
+ if (val)
+ {
+ switch (val[0])
+ {
+ case ' ':
+ TexOutput("~");
+ break;
+ case 'a':
+ TexOutput("ã");
+ break;
+ case 'n':
+ TexOutput("ñ");
+ break;
+ case 'o':
+ TexOutput("õ");
+ break;
+ case 'A':
+ TexOutput("Ã");
+ break;
+ case 'N':
+ TexOutput("Ñ");
+ break;
+ case 'O':
+ TexOutput("Õ");
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ return FALSE;
+ break;
+ }
+ case ltACCENT_UMLAUT:
+ {
+ if (start)
+ {
+ char *val = GetArgData();
+ if (val)
+ {
+ switch (val[0])
+ {
+ case 'a':
+ TexOutput("ä");
+ break;
+ case 'e':
+ TexOutput("ë");
+ break;
+ case 'i':
+ TexOutput("ï");
+ break;
+ case 'o':
+ TexOutput("ö");
+ break;
+ case 'u':
+ TexOutput("ü");
+ break;
+ case 'y':
+ TexOutput("ÿ");
+ break;
+ case 'A':
+ TexOutput("Ä");
+ break;
+ case 'E':
+ TexOutput("Ë");
+ break;
+ case 'I':
+ TexOutput("Ï");
+ break;
+ case 'O':
+ TexOutput("Ö");
+ break;
+ case 'U':
+ TexOutput("Ü");
+ break;
+ case 'Y':
+ TexOutput("Ÿ");
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ return FALSE;
+ break;
+ }
+ case ltACCENT_DOT:
+ {
+ if (start)
+ {
+ char *val = GetArgData();
+ if (val)
+ {
+ switch (val[0])
+ {
+ case 'a':
+ TexOutput("å");
+ break;
+ case 'A':
+ TexOutput("Å");
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ return FALSE;
+ break;
+ }
+ case ltBACKGROUND:
+ {
+ if (start)
+ {
+ char *val = GetArgData();
+ if (val)
+ {
+ bool isPicture = FALSE;
+ char *s = ParseColourString(val, &isPicture);
+ if (isPicture)
+ {
+ if (backgroundImageString)
+ delete[] backgroundImageString;
+ backgroundImageString = copystring(val);
+ }
+ else
+ {
+ if (backgroundColourString)
+ delete[] backgroundColourString;
+ backgroundColourString = copystring(val);
+ }
+ }
+ }
+ return FALSE;
+ break;
+ }
+ case ltBACKGROUNDIMAGE:
+ {
+ if (start)
+ {
+ char *val = GetArgData();
+ if (val)
+ {
+ if (backgroundImageString)
+ delete[] backgroundImageString;
+ backgroundImageString = copystring(val);
+ }
+ }
+ return FALSE;
+ break;
+ }
+ case ltBACKGROUNDCOLOUR:
+ {
+ if (start)
+ {
+ char *val = GetArgData();
+ if (val)
+ {
+ if (backgroundColourString)
+ delete[] backgroundColourString;
+ backgroundColourString = copystring(val);
+ }
+ }
+ return FALSE;
+ break;
+ }
+ case ltTEXTCOLOUR:
+ {
+ if (start)
+ {
+ char *val = GetArgData();
+ if (val)
+ {
+ if (textColourString)
+ delete[] textColourString;
+ textColourString = copystring(val);
+ }
+ }
+ return FALSE;
+ break;
+ }
+ case ltLINKCOLOUR:
+ {
+ if (start)
+ {
+ char *val = GetArgData();
+ if (val)
+ {
+ if (linkColourString)
+ delete[] linkColourString;
+ linkColourString = copystring(val);
+ }
+ }
+ return FALSE;
+ break;
+ }
+ case ltFOLLOWEDLINKCOLOUR:
+ {
+ if (start)
+ {
+ char *val = GetArgData();
+ if (val)
+ {
+ if (followedLinkColourString)
+ delete[] followedLinkColourString;
+ followedLinkColourString = copystring(val);
+ }
+ }
+ return FALSE;
+ break;
+ }
+ case ltACCENT_CADILLA:
+ {
+ if (start)
+ {
+ char *val = GetArgData();
+ if (val)
+ {
+ switch (val[0])
+ {
+ case 'c':
+ TexOutput("ç");
+ break;
+ case 'C':
+ TexOutput("Ç");
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ return FALSE;
+ break;
+ }
+/*
+ case ltFOOTNOTE:
+ case ltFOOTNOTEPOPUP:
+ {
+ if (arg_no == 1)
+ return TRUE;
+ else
+ return FALSE;
+ break;
+ }
+*/
+ case ltTABULAR:
+ case ltSUPERTABULAR:
+ {
+ if (arg_no == 1)
+ {
+ if (start)
+ {
+ currentRowNumber = 0;
+ inTabular = TRUE;
+ startRows = TRUE;
+ tableVerticalLineLeft = FALSE;
+ tableVerticalLineRight = FALSE;
+ int currentWidth = 0;
+
+ char *alignString = copystring(GetArgData());
+ ParseTableArgument(alignString);
+
+ TexOutput("<TABLE BORDER>\n");
+
+ // Write the first row formatting for compatibility
+ // with standard Latex
+ if (compatibilityMode)
+ {
+ TexOutput("<TR>\n<TD>");
+/*
+ for (int i = 0; i < noColumns; i++)
+ {
+ currentWidth += TableData[i].width;
+ sprintf(buf, "\\cellx%d", currentWidth);
+ TexOutput(buf);
+ }
+ TexOutput("\\pard\\intbl\n");
+*/
+ }
+ delete[] alignString;
+
+ return FALSE;
+ }
+ }
+ else if (arg_no == 2 && !start)
+ {
+ TexOutput("</TABLE>\n");
+ inTabular = FALSE;
+ }
+ break;
+ }
+ case ltTHEBIBLIOGRAPHY:
+ {
+ if (start && (arg_no == 1))
+ {
+ ReopenFile(&Chapters, &ChaptersName);
+ AddTexRef("bibliography", ChaptersName, "bibliography");
+ SetCurrentSubsectionName("bibliography", ChaptersName);
+
+ citeCount = 1;
+
+ SetCurrentOutput(Chapters);
+
+ char titleBuf[150];
+ if (truncateFilenames)
+ sprintf(titleBuf, "%s.htm", FileNameFromPath(FileRoot));
+ else
+ sprintf(titleBuf, "%s_contents.html", FileNameFromPath(FileRoot));
+
+ TexOutput("<head><title>");
+ TexOutput(ReferencesNameString);
+ TexOutput("</title></head>\n");
+ OutputBodyStart();
+
+ fprintf(Chapters, "<A NAME=\"%s\">\n<H2>%s", "bibliography", ReferencesNameString);
+ AddBrowseButtons("contents", titleBuf, // Up
+ lastTopic, lastFileName, // Last topic
+ "bibliography", ChaptersName); // This topic
+
+ SetCurrentOutputs(Contents, Chapters);
+ fprintf(Contents, "\n<LI><A HREF=\"%s#%s\">", ConvertCase(ChaptersName), "bibliography");
+
+ fprintf(Contents, "%s</A>\n", ReferencesNameString);
+ fprintf(Chapters, "</H2>\n</A>\n");
+
+ SetCurrentOutput(Chapters);
+ return FALSE;
+ }
+ if (!start && (arg_no == 2))
+ {
+ }
+ return TRUE;
+ break;
+ }
+ case ltINDEX:
+ {
+ /* Build up list of keywords associated with topics */
+ if (start)
+ {
+// char *entry = GetArgData();
+ char buf[300];
+ OutputChunkToString(GetArgChunk(), buf);
+ if (CurrentTopic)
+ {
+ AddKeyWordForTopic(CurrentTopic, buf, currentFileName);
+ }
+ }
+ return FALSE;
+ break;
+ }
+ case ltFCOL:
+// case ltBCOL:
+ {
+ if (start)
+ {
+ switch (arg_no)
+ {
+ case 1:
+ {
+ char *name = GetArgData();
+ char buf2[10];
+ if (!FindColourHTMLString(name, buf2))
+ {
+ strcpy(buf2, "#000000");
+ char buf[100];
+ sprintf(buf, "Could not find colour name %s", name);
+ OnError(buf);
+ }
+ TexOutput("<FONT COLOR=\"");
+ TexOutput(buf2);
+ TexOutput("\">");
+ break;
+ }
+ case 2:
+ {
+ return TRUE;
+ break;
+ }
+ default:
+ break;
+ }
+ }
+ else
+ {
+ if (arg_no == 2) TexOutput("</FONT>");
+ }
+ return FALSE;
+ break;
+ }
+ case ltINSERTATLEVEL:
+ {
+ // This macro allows you to insert text at a different level
+ // from the current level, e.g. into the Sections from within a subsubsection.
+ if (useWord)
+ return FALSE;
+ static int currentLevelNo = 1;
+ static FILE* oldLevelFile = Chapters;
+ if (start)
+ {
+ switch (arg_no)
+ {
+ case 1:
+ {
+ oldLevelFile = CurrentOutput1;
+
+ char *str = GetArgData();
+ currentLevelNo = atoi(str);
+ FILE* outputFile;
+ // TODO: cope with article style (no chapters)
+ switch (currentLevelNo)
+ {
+ case 1:
+ {
+ outputFile = Chapters;
+ break;
+ }
+ case 2:
+ {
+ outputFile = Sections;
+ break;
+ }
+ case 3:
+ {
+ outputFile = Subsections;
+ break;
+ }
+ case 4:
+ {
+ outputFile = Subsubsections;
+ break;
+ }
+ default:
+ {
+ outputFile = NULL;
+ break;
+ }
+ }
+ if (outputFile)
+ CurrentOutput1 = outputFile;
+ return FALSE;
+ break;
+ }
+ case 2:
+ {
+ return TRUE;
+ break;
+ }
+ default:
+ break;
+ }
+ return TRUE;
+ }
+ else
+ {
+ if (arg_no == 2)
+ {
+ CurrentOutput1 = oldLevelFile;
+ }
+ return TRUE;
+ }
+ }
+ default:
+ return DefaultOnArgument(macroId, arg_no, start);
+ break;
+ }
+ return TRUE;
+}
+
+bool HTMLGo(void)
+{
+ fileId = 0;
+ inVerbatim = FALSE;
+ indentLevel = 0;
+ inTabular = FALSE;
+ startRows = FALSE;
+ tableVerticalLineLeft = FALSE;
+ tableVerticalLineRight = FALSE;
+ noColumns = 0;
+
+ if (InputFile && OutputFile)
+ {
+ // Do some HTML-specific transformations on all the strings,
+ // recursively
+ Text2HTML(GetTopLevelChunk());
+
+ char buf[300];
+ if (truncateFilenames)
+ sprintf(buf, "%s.htm", FileRoot);
+ else
+ sprintf(buf, "%s_contents.html", FileRoot);
+ if (TitlepageName) delete[] TitlepageName;
+ TitlepageName = copystring(buf);
+ Titlepage = fopen(buf, "w");
+
+ if (truncateFilenames)
+ sprintf(buf, "%s_fc.htm", FileRoot);
+ else
+ sprintf(buf, "%s_fcontents.html", FileRoot);
+
+ contentsFrameName = copystring(buf);
+
+ Contents = fopen(TmpContentsName, "w");
+
+ if (htmlFrameContents)
+ {
+// FrameContents = fopen(TmpFrameContentsName, "w");
+ FrameContents = fopen(contentsFrameName, "w");
+ fprintf(FrameContents, "<HTML>\n<UL>\n");
+ }
+
+ if (!Titlepage || !Contents)
+ {
+ OnError("Cannot open output file!");
+ return FALSE;
+ }
+ AddTexRef("contents", FileNameFromPath(TitlepageName), ContentsNameString);
+
+ fprintf(Contents, "<P><P><H2>%s</H2><P><P>\n", ContentsNameString);
+
+ fprintf(Contents, "<UL>\n");
+
+ SetCurrentOutput(Titlepage);
+ OnInform("Converting...");
+
+ TraverseDocument();
+ fprintf(Contents, "</UL>\n\n");
+
+// SetCurrentOutput(Titlepage);
+ fclose(Titlepage);
+
+ if (Contents)
+ {
+// fprintf(Titlepage, "\n</BODY></HTML>\n");
+ fclose(Contents);
+ Contents = NULL;
+ }
+
+ if (FrameContents)
+ {
+ fprintf(FrameContents, "\n</UL>\n");
+ fprintf(FrameContents, "</HTML>\n");
+ fclose(FrameContents);
+ FrameContents = NULL;
+ }
+
+ if (Chapters)
+ {
+ fprintf(Chapters, "\n</BODY></HTML>\n");
+ fclose(Chapters);
+ Chapters = NULL;
+ }
+ if (Sections)
+ {
+ fprintf(Sections, "\n</BODY></HTML>\n");
+ fclose(Sections);
+ Sections = NULL;
+ }
+ if (Subsections && !combineSubSections)
+ {
+ fprintf(Subsections, "\n</BODY></HTML>\n");
+ fclose(Subsections);
+ Subsections = NULL;
+ }
+ if (Subsubsections && !combineSubSections)
+ {
+ fprintf(Subsubsections, "\n</BODY></HTML>\n");
+ fclose(Subsubsections);
+ Subsubsections = NULL;
+ }
+ if ( SectionContentsFD )
+ {
+ fclose(SectionContentsFD);
+ SectionContentsFD = NULL;
+ }
+
+ // Create a temporary file for the title page header, add some info,
+ // and concat the titlepage just generated.
+ // This is necessary in order to put the title of the document
+ // at the TOP of the file within <HEAD>, even though we only find out
+ // what it is later on.
+ FILE *tmpTitle = fopen("title.tmp", "w");
+ if (tmpTitle)
+ {
+ if (DocumentTitle)
+ {
+ SetCurrentOutput(tmpTitle);
+ TexOutput("\n<HTML>\n<HEAD><TITLE>");
+ TraverseChildrenFromChunk(DocumentTitle);
+ TexOutput("</TITLE></HEAD>\n");
+ }
+ else
+ {
+ SetCurrentOutput(tmpTitle);
+ if (contentsString)
+ fprintf(tmpTitle, "<HEAD><TITLE>%s</TITLE></HEAD>\n\n", contentsString);
+ else
+ fprintf(tmpTitle, "<HEAD><TITLE>%s</TITLE></HEAD>\n\n", FileNameFromPath(FileRoot));
+ }
+
+ // Output frame information
+ if (htmlFrameContents)
+ {
+ char firstFileName[300];
+ if (truncateFilenames)
+ sprintf(firstFileName, "%s1.htm", FileRoot);
+ else
+ sprintf(firstFileName, "%s1.html", FileRoot);
+
+ fprintf(tmpTitle, "<FRAMESET COLS=\"30%%,70%%\">\n");
+
+ fprintf(tmpTitle, "<FRAME SRC=\"%s\">\n", ConvertCase(FileNameFromPath(contentsFrameName)));
+ fprintf(tmpTitle, "<FRAME SRC=\"%s\" NAME=\"mainwindow\">\n", ConvertCase(FileNameFromPath(firstFileName)));
+ fprintf(tmpTitle, "</FRAMESET>\n");
+
+ fprintf(tmpTitle, "<NOFRAMES>\n");
+ }
+
+ // Output <BODY...> to temporary title page
+ OutputBodyStart();
+
+ // Concat titlepage
+ FILE *fd = fopen(TitlepageName, "r");
+ if (fd)
+ {
+ int ch = getc(fd);
+ while (ch != EOF)
+ {
+ putc(ch, tmpTitle);
+ ch = getc(fd);
+ }
+ fclose(fd);
+ }
+
+ fprintf(tmpTitle, "\n</BODY>\n");
+
+ if (htmlFrameContents)
+ {
+ fprintf(tmpTitle, "\n</NOFRAMES>\n");
+ }
+ fprintf(tmpTitle, "\n</HTML>\n");
+
+ fclose(tmpTitle);
+ if (FileExists(TitlepageName)) wxRemoveFile(TitlepageName);
+ if (!wxRenameFile("title.tmp", TitlepageName))
+ {
+ wxCopyFile("title.tmp", TitlepageName);
+ wxRemoveFile("title.tmp");
+ }
+ }
+
+ if (lastFileName) delete[] lastFileName;
+ lastFileName = NULL;
+ if (lastTopic) delete[] lastTopic;
+ lastTopic = NULL;
+
+ if (FileExists(ContentsName)) wxRemoveFile(ContentsName);
+
+ if (!wxRenameFile(TmpContentsName, ContentsName))
+ {
+ wxCopyFile(TmpContentsName, ContentsName);
+ wxRemoveFile(TmpContentsName);
+ }
+
+ // Generate .htx file if requested
+ if (htmlIndex)
+ {
+ char htmlIndexName[300];
+ sprintf(htmlIndexName, "%s.htx", FileRoot);
+ GenerateHTMLIndexFile(htmlIndexName);
+ }
+
+ return TRUE;
+ }
+ return FALSE;
+}
+
+// Output .htx index file
+void GenerateHTMLIndexFile(char *fname)
+{
+ FILE *fd = fopen(fname, "w");
+ if (!fd)
+ return;
+
+ TopicTable.BeginFind();
+ wxNode *node = NULL;
+ while ((node = TopicTable.Next()))
+ {
+ TexTopic *texTopic = (TexTopic *)node->Data();
+ const char *topicName = node->GetKeyString();
+ if (texTopic->filename && texTopic->keywords)
+ {
+ wxNode *node1 = texTopic->keywords->First();
+ while (node1)
+ {
+ char *s = (char *)node1->Data();
+ fprintf(fd, "%s|%s|%s\n", topicName, texTopic->filename, s);
+ node1 = node1->Next();
+ }
+ }
+ }
+ fclose(fd);
+}
--- /dev/null
+#
+# File: makefile.b32
+# Author: Julian Smart
+# Created: 1993
+# Updated:
+# Copyright:
+#
+# "%W% %G%"
+#
+# Makefile : Builds tex2rtf
+
+# WXWIN and BCCDIR are set by parent make
+
+WXDIR = $(WXWIN)
+!include $(WXDIR)\src\makeb32.env
+
+WXLIBDIR = $(WXDIR)\lib
+WXINC = $(WXDIR)\include\msw
+WXLIB = $(WXLIBDIR)\wx32.lib
+LIBS=$(WXLIB) cw32 import32 ole2w32
+
+TARGET=tex2rtf
+
+!if "$(FINAL)" == "0"
+LINKFLAGS=/v /Tpe /L$(WXLIBDIR);$(BCCDIR)\lib
+OPT = -Od
+DEBUG_FLAGS= -v
+!else
+LINKFLAGS=/Tpe /L$(WXLIBDIR);$(BCCDIR)\lib
+OPT = -Od
+DEBUG_FLAGS =
+!endif
+CPPFLAGS=$(DEBUG_FLAGS) $(OPT) @$(CFG)
+
+OBJECTS = tex2rtf.obj tex2any.obj texutils.obj rtfutils.obj xlputils.obj htmlutil.obj readshg.obj table.obj
+
+$(TARGET).exe: $(OBJECTS) $(TARGET).res
+ tlink32 $(LINKFLAGS) @&&!
+c0w32.obj $(OBJECTS)
+$(TARGET)
+nul
+$(LIBS)
+$(TARGET).def
+$(TARGET).res
+!
+
+.$(SRCSUFF).obj:
+ bcc32 $(CPPFLAGS) -c {$< }
+
+.c.obj:
+ bcc32 $(CPPFLAGS) -P- -c {$< }
+
+$(TARGET).res : $(TARGET).rc $(WXDIR)\include\wx\msw\wx.rc
+ brc32 -r /i$(BCCDIR)\include /i$(WXDIR)\include $(TARGET)
+
+clean:
+ -erase *.obj
+ -erase *.exe
+ -erase *.res
+ -erase *.map
+ -erase *.rws
+
--- /dev/null
+#
+# File: makefile.bcc
+# Author: Julian Smart
+# Created: 1998
+# Updated:
+#
+# Builds a BC++ 16-bit sample
+
+!if "$(WXWIN)" == ""
+!error You must define the WXWIN variable in autoexec.bat, e.g. WXWIN=c:\wx
+!endif
+
+WXDIR = $(WXWIN)
+
+TARGET=tex2rtf
+OBJECTS = tex2rtf.obj tex2any.obj texutils.obj rtfutils.obj xlputils.obj htmlutil.obj readshg.obj table.obj
+
+!include $(WXDIR)\src\makeprog.bcc
+
--- /dev/null
+#
+# File: makefile.dos
+# Author: Julian Smart
+# Created: 1998
+# Updated:
+#
+# Makefile : Builds 16-bit sample, VC++ 1.5
+# Use FINAL=1 argument to nmake to build final version with no debugging
+# info
+
+WXDIR = $(WXWIN)
+
+TARGET=tex2rtf
+OBJECTS = tex2rtf.obj tex2any.obj texutils.obj rtfutils.obj xlputils.obj htmlutil.obj readshg.obj table.obj
+
+!include $(WXDIR)\src\makeprog.msc
+
--- /dev/null
+#
+# File: makefile.g95
+# Author: Julian Smart
+# Created: 1996
+# Updated:
+#
+# "%W% %G%"
+#
+# Makefile for Tex2RTF (GNU-WIN32)
+
+WXDIR = ../../..
+
+# All common UNIX compiler flags and options are now in
+# this central makefile.
+include $(WXDIR)/src/makeg95.env
+
+OBJECTS = $(OBJDIR)/tex2rtf.$(OBJSUFF) $(OBJDIR)/texutils.$(OBJSUFF) $(OBJDIR)/tex2any.$(OBJSUFF)\
+ $(OBJDIR)/htmlutil.$(OBJSUFF) $(OBJDIR)/rtfutils.$(OBJSUFF) $(OBJDIR)/xlputils.$(OBJSUFF)\
+ $(OBJDIR)/table.$(OBJSUFF) $(OBJDIR)/readshg.$(OBJSUFF)\
+ $(OBJDIR)/tex2rtf_resources.$(OBJSUFF)
+
+all: $(OBJDIR) tex2rtf$(GUISUFFIX)$(EXESUFF)
+
+INC = $(COMPPATHS) -I$(WXDIR)/include/msw -I$(WXDIR)/include/base -I../../wxhelp/src
+CPPFLAGS = $(XINCLUDE) $(INC) $(OPTIONS) $(GUI) -DDEBUG='$(DEBUG)' $(DEBUGFLAGS) $(WARN) $(OPT)
+
+$(OBJDIR):
+ mkdir $(OBJDIR)
+
+tex2rtf$(GUISUFFIX)$(EXESUFF): $(OBJECTS) $(WXLIB)
+ $(CC) $(LDFLAGS) -o tex2rtf$(GUISUFFIX)$(EXESUFF) $(OBJECTS) $(LDLIBS)
+
+$(OBJDIR)/tex2rtf.$(OBJSUFF): tex2rtf.$(SRCSUFF) tex2rtf.h tex2any.h
+ $(CC) -c $(CPPFLAGS) -o $@ tex2rtf.$(SRCSUFF)
+
+$(OBJDIR)/texutils.$(OBJSUFF): texutils.$(SRCSUFF) tex2rtf.h tex2any.h
+ $(CC) -c $(CPPFLAGS) -o $@ texutils.$(SRCSUFF)
+
+$(OBJDIR)/tex2any.$(OBJSUFF): tex2any.$(SRCSUFF) tex2any.h
+ $(CC) -c $(CPPFLAGS) -o $@ tex2any.$(SRCSUFF)
+
+$(OBJDIR)/htmlutil.$(OBJSUFF): htmlutil.$(SRCSUFF) tex2any.h
+ $(CC) -c $(CPPFLAGS) -o $@ htmlutil.$(SRCSUFF)
+
+$(OBJDIR)/rtfutils.$(OBJSUFF): rtfutils.$(SRCSUFF) tex2any.h
+ $(CC) -c $(CPPFLAGS) -o $@ rtfutils.$(SRCSUFF)
+
+$(OBJDIR)/xlputils.$(OBJSUFF): xlputils.$(SRCSUFF) tex2any.h
+ $(CC) -c $(CPPFLAGS) -o $@ xlputils.$(SRCSUFF)
+
+$(OBJDIR)/table.$(OBJSUFF): table.$(SRCSUFF) tex2any.h
+ $(CC) -c $(CPPFLAGS) -o $@ table.$(SRCSUFF)
+
+$(OBJDIR)/readshg.$(OBJSUFF): readshg.$(SRCSUFF) readshg.h
+ $(CC) -c $(CPPFLAGS) -o $@ readshg.$(SRCSUFF)
+
+$(OBJDIR)/tex2rtf_resources.o: tex2rtf.rc
+ $(RESCOMP) -i tex2rtf.rc -o $(OBJDIR)/tex2rtf_resources.o $(RESFLAGS)
+
+clean:
+ rm -f $(OBJECTS) tex2rtf$(GUISUFFIX).exe core *.rsc *.res
--- /dev/null
+#
+# File: makefile.nt
+# Author: Julian Smart
+# Created: 1993
+# Copyright: (c) 1993, AIAI, University of Edinburgh
+#
+# "%W% %G%"
+#
+# Makefile : Builds Tex2RTF on Windows Windows 95/NT
+#
+!include <..\..\..\src\ntwxwin.mak>
+
+TEX2RTFDIR = $(WXDIR)\utils\tex2rtf
+TEX2RTFINC = $(TEX2RTFDIR)\src
+PROGRAM=tex2rtf
+DOCDIR=$(WXDIR)\docs
+LOCALDOCDIR=$(WXDIR)\utils\tex2rtf\docs
+THISDIR=$(TEX2RTFDIR)\src
+
+OBJECTS = tex2rtf.obj tex2any.obj texutils.obj rtfutils.obj xlputils.obj htmlutil.obj readshg.obj table.obj
+
+all: tex2rtf.exe
+
+wx:
+ cd $(WXDIR)\src\msw
+ nmake -f makefile.nt
+ cd $(TEX2RTFDIR)\src
+
+$(PROGRAM).exe: $(WXLIB) $(OBJECTS) $(PROGRAM).res
+ $(link) @<<
+-out:$(PROGRAM).exe
+$(LINKFLAGS)
+$(DUMMYOBJ) $(OBJECTS) $(PROGRAM).res
+$(LIBS)
+<<
+
+$(PROGRAM).res : $(PROGRAM).rc $(WXDIR)\include\wx\msw\wx.rc
+ $(rc) -r /i$(WXDIR)\include -fo$@ $(PROGRAM).rc
+
+tex2any.obj: tex2any.$(SRCSUFF) tex2any.h
+ cl @<<
+$(CPPFLAGS) /c /Tp $*.$(SRCSUFF)
+<<
+
+texutils.obj: texutils.$(SRCSUFF) tex2any.h
+ cl @<<
+$(CPPFLAGS) /c /Tp $*.$(SRCSUFF)
+<<
+
+tex2rtf.obj: tex2rtf.$(SRCSUFF) bmputils.h tex2rtf.h tex2any.h
+ cl @<<
+$(CPPFLAGS) /c /Tp $*.$(SRCSUFF)
+<<
+
+rtfutils.obj: rtfutils.$(SRCSUFF) tex2rtf.h bmputils.h tex2any.h readshg.h table.h
+ cl @<<
+$(CPPFLAGS) /c /Tp $*.$(SRCSUFF)
+<<
+
+table.obj: table.$(SRCSUFF) table.h
+ cl @<<
+$(CPPFLAGS) /c /Tp $*.$(SRCSUFF)
+<<
+
+readshg.obj: readshg.$(SRCSUFF) readshg.h
+ cl @<<
+$(CPPFLAGS) /c /Tp $*.$(SRCSUFF)
+<<
+
+xlputils.obj: xlputils.$(SRCSUFF) tex2rtf.h rtfutils.h tex2any.h
+ cl @<<
+$(CPPFLAGS) /c /Tp $*.$(SRCSUFF)
+<<
+
+htmlutil.obj: htmlutil.$(SRCSUFF) tex2rtf.h tex2any.h table.h
+ cl @<<
+$(CPPFLAGS) /c /Tp $*.$(SRCSUFF)
+<<
+
+clean:
+ -erase *.obj
+ -erase *.sbr
+ -erase *.exe
+ -erase *.res
+ -erase *.map
+ -erase *.pdb
+
+cleanall:
+ erase *.exe *.obj *.pch *.res
+
+DOCSOURCES=$(LOCALDOCDIR)\tex2rtf.tex
+
+html: $(DOCDIR)\html\tex2rtf\t2rtf.htm
+hlp: $(DOCDIR)\winhelp\tex2rtf.hlp
+pdfrtf: $(DOCDIR)\pdf\tex2rtf.rtf
+ps: $(WXDIR)\docs\ps\tex2rtf.ps
+
+$(DOCDIR)\winhelp\tex2rtf.hlp: $(LOCALDOCDIR)\tex2rtf.rtf $(LOCALDOCDIR)\tex2rtf.hpj
+ cd $(LOCALDOCDIR)
+ -erase tex2rtf.ph
+ hc tex2rtf
+ copy tex2rtf.hlp $(DOCDIR)\winhelp\tex2rtf.hlp
+ copy tex2rtf.cnt $(DOCDIR)\winhelp\tex2rtf.cnt
+ cd $(THISDIR)
+
+$(LOCALDOCDIR)\tex2rtf.rtf: $(DOCSOURCES)
+ cd $(LOCALDOCDIR)
+ -start /w tex2rtf $(LOCALDOCDIR)\tex2rtf.tex $(LOCALDOCDIR)\tex2rtf.rtf -twice -winhelp
+ cd $(THISDIR)
+
+$(DOCDIR)\pdf\tex2rtf.rtf: $(DOCSOURCES)
+ cd $(LOCALDOCDIR)
+ -copy *.bmp *.wmf $(DOCDIR)\pdf
+ -start /w tex2rtf $(LOCALDOCDIR)\tex2rtf.tex $(DOCDIR)\pdf\tex2rtf.rtf -twice -rtf
+ cd $(THISDIR)
+
+$(DOCDIR)\html\tex2rtf\t2rtf.htm: $(DOCSOURCES)
+ cd $(LOCALDOCDIR)
+ -mkdir $(DOCDIR)\html\tex2rtf
+ -start /w tex2rtf $(LOCALDOCDIR)\tex2rtf.tex $(DOCDIR)\html\tex2rtf\t2rtf.htm -twice -html
+ -erase $(DOCDIR)\html\tex2rtf\*.con
+ -erase $(DOCDIR)\html\tex2rtf\*.ref
+ cd $(THISDIR)
+
+$(LOCALDOCDIR)\tex2rtf.dvi: $(DOCSOURCES)
+ cd $(LOCALDOCDIR)
+ -latex tex2rtf
+ -latex tex2rtf
+ -makeindx tex2rtf
+ -bibtex tex2rtf
+ -latex tex2rtf
+ -latex tex2rtf
+ cd $(THISDIR)
+
+$(WXDIR)\docs\ps\tex2rtf.ps: $(LOCALDOCDIR)\tex2rtf.dvi
+ cd $(LOCALDOCDIR)
+ -dvips32 -o tex2rtf.ps tex2rtf
+ copy tex2rtf.ps $(WXDIR)\docs\ps\tex2rtf.ps
+ cd $(THISDIR)
+
+
--- /dev/null
+#
+# File: makefile.unx
+# Author: Julian Smart
+# Created: 1998
+# Updated:
+# Copyright: (c) 1998 Julian Smart
+#
+# "%W% %G%"
+#
+# Makefile for Tex2RTF (Unix)
+
+PROGRAM=tex2rtf
+
+OBJECTS = tex2rtf.o tex2any.o texutils.o rtfutils.o xlputils.o htmlutil.o readshg.o table.o
+
+include ../../../src/makeprog.env
+
--- /dev/null
+#
+# Makefile for WATCOM
+#
+# 8 Nov 1994
+#
+
+WXDIR = $(%WXWIN)
+
+PROGRAM = tex2rtf
+OBJECTS = tex2rtf.obj tex2any.obj texutils.obj rtfutils.obj xlputils.obj htmlutil.obj readshg.obj table.obj
+
+!include $(WXDIR)\src\makeprog.wat
+
+
--- /dev/null
+# From: Juan Altmayer Pizzorno[SMTP:juan@vms.gmd.de]
+# Sent: 31 May 1996 10:11
+# To: J.Smart@ed.ac.uk
+# Subject: Changes to Tex2RTF
+#
+# Hello,
+#
+# Recently I've been looking for a way to create and maintain documentation on
+# multiple platforms out of a single source -- specifically, something that
+# prints nicely and can be converted to WinHelp and HTML. I liked the approach
+# of Tex2RTF, so I set off to give it a try... I found out it would crash
+# when submitted to a certain LaTeX file I created. I wanted to find out why,
+# so I went on and worked on compiling on my PC: Windows NT 4.0 beta, Visual
+# C++ 4.1a. Since all I was interested on was the convertion utility, I tried
+# to make it work without a GUI. It didn't compile immediately, but after a
+# few small changes it now works like a charm. Unfortunately it doesn't crash
+# anymore, so I can't tell why it used to... Anyway, I wanted to contribute
+# the changes back: I'm appending two files to this message, the first a
+# description of the changes, and the second a quick-and-dirty makefile that
+# doesn't require wxWindows to run. Please do write to me if you have any
+# questions or anything.
+#
+# Last but not least, it's great that you took the time and wrote Tex2RTF!!
+#
+# Quick-and-dirty makefile for building Tex2RTF without the wx
+# libraries on a Windows NT machine. If you want to use it for
+# "real", please update the dependancies between object and include
+# files. Created for Windows NT 4.0 and Visual C++ 4.1.
+#
+# Juan Altmayer Pizzorno, May 1996
+#
+
+syslibs=kernel32.lib advapi32.lib
+
+cxxflags=/nologo /MD /W0 /O2 /Zi /D "WIN32" /D "_WIN32" /D "_DEBUG" /c
+linkflags=$(syslibs) /out:$@ /nologo /debug
+
+!if "$(PROCESSOR_ARCHITECTURE)" == "x86"
+cxxflags=$(cxxflags) /G5 # optimize for pentium
+!endif
+
+cxx=cl
+link=link
+remove=del
+cxxflags=$(cxxflags) /I wxwin /D wx_msw /D WINVER=0x0400 /D WIN95=0
+cxxflags=$(cxxflags) /D "NO_GUI"
+
+objects=tex2any.obj texutils.obj tex2rtf.obj rtfutils.obj table.obj readshg.obj xlputils.obj htmlutil.obj
+objects=$(objects) wb_hash.obj wb_list.obj wb_obj.obj wb_utils.obj
+
+all : tex2rtf.exe
+
+clean :
+ -$(remove) *.obj
+
+cleanall : clean
+ -$(remove) *.exe *.pdb *.ilk
+
+tex2rtf.exe : $(objects)
+ $(link) $(linkflags) $(objects)
+
+tex2any.obj : tex2any.cpp tex2any.h
+ $(cxx) $(cxxflags) tex2any.cpp
+
+texutils.obj : texutils.cpp tex2any.h
+ $(cxx) $(cxxflags) texutils.cpp
+
+tex2rtf.obj : tex2rtf.cpp bmputils.h tex2rtf.h tex2any.h
+ $(cxx) $(cxxflags) tex2rtf.cpp
+
+rtfutils.obj : rtfutils.cpp tex2rtf.h bmputils.h tex2any.h readshg.h table.h
+ $(cxx) $(cxxflags) rtfutils.cpp
+
+table.obj : table.cpp table.h
+ $(cxx) $(cxxflags) table.cpp
+
+readshg.obj : readshg.cpp readshg.h
+ $(cxx) $(cxxflags) readshg.cpp
+
+xlputils.obj : xlputils.cpp tex2rtf.h rtfutils.h tex2any.h
+ $(cxx) $(cxxflags) xlputils.cpp
+
+htmlutil.obj : htmlutil.cpp tex2rtf.h tex2any.h table.h
+ $(cxx) $(cxxflags) htmlutil.cpp
+
+wb_hash.obj : wxwin\wb_hash.cpp
+ $(cxx) $(cxxflags) wxwin\wb_hash.cpp
+
+wb_list.obj : wxwin\wb_list.cpp
+ $(cxx) $(cxxflags) wxwin\wb_list.cpp
+
+wb_obj.obj : wxwin\wb_obj.cpp
+ $(cxx) $(cxxflags) wxwin\wb_obj.cpp
+
+wb_utils.obj : wxwin\wb_utils.cpp
+ $(cxx) $(cxxflags) wxwin\wb_utils.cpp
+
+
--- /dev/null
+/*
+ * File: maths.cc
+ * Purpose: Beginnings of a maths parser for LaTeX.
+ * NOT IMPLEMENTED. I'm still thinking how best to do this...
+ *
+ */
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx_prec.h"
+
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+
+#ifndef WX_PRECOMP
+#include <wx.h>
+#endif
+
+#include <ctype.h>
+#include "tex2any.h"
+#include <stdlib.h>
+#include <time.h>
+
--- /dev/null
+/////////////////////////////////////////////////////////////////////////////
+// Name: readshg.cpp
+// Purpose: Petr Smilauer's .SHG (Segmented Hypergraphics file) reading
+// code.
+// Note: .SHG is undocumented (anywhere!) so this is
+// reverse-engineering
+// and guesswork at its best.
+// Author: Petr Smilauer
+// Modified by:
+// Created: 01/01/99
+// RCS-ID: $Id$
+// Copyright: (c) Petr Smilauer
+// Licence: wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+
+#ifndef WX_PRECOMP
+#include "wx/wx.h"
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "readshg.h"
+#include "tex2any.h"
+
+// Returns the number of hotspots, and the array of hotspots.
+// E.g.
+// HotSpots *array;
+// int n = ParseSHG("thing.shg", &array);
+
+int ParseSHG( const char* fileName, HotSpot **hotspots)
+{ FILE* fSHG = fopen( fileName, "rb");
+ long offset;
+ int nHotspots = 0;
+
+ if(fSHG == 0)
+ return 0;
+ nHotspots = 0;
+ //first, look at offset OFF_OFFSET to get another offset :-)
+ fseek( fSHG, OFF_OFFSET, SEEK_SET);
+ offset = 0L; // init whole 4-byte variable
+ fread( &offset, 2, 1, fSHG); // get the offset in first two bytes..
+ if(offset == 0) // if zero, used next DWORD field
+ fread( &offset, 4, 1, fSHG);// this is our offset for very long DIB
+ offset += 9; // don't know hot this delta comes-about
+ if(fseek( fSHG, offset, SEEK_SET) != 0)
+ {
+ fclose( fSHG);
+ return -1; // this is probably because incorrect offset calculation.
+ }
+ fread( &nHotspots, 2, 1, fSHG);
+
+ *hotspots = new HotSpot[nHotspots];
+
+ int nMacroStrings = 0;
+
+ fread( &nMacroStrings, 2, 1, fSHG); // we can ignore the macros, as this is
+ // repeated later, but we need to know how much to skip
+ fseek( fSHG, 2, SEEK_CUR); // skip another 2 bytes I do not understand ;-)
+
+ ShgInfoBlock sib;
+ int i;
+
+ int sizeOf = sizeof( ShgInfoBlock);
+
+ for( i = 0 ; i < nHotspots ; ++i)
+ {
+ fread( &sib, sizeOf, 1, fSHG); // read one hotspot' info
+ // analyse it:
+ (*hotspots)[i].type = (HotspotType)(sib.hotspotType & 0xFB);
+ (*hotspots)[i].left = sib.left;
+ (*hotspots)[i].top = sib.top;
+ (*hotspots)[i].right = sib.left + sib.width;
+ (*hotspots)[i].bottom = sib.top + sib.height;
+ (*hotspots)[i].IsVisible = ((sib.hotspotType & 4) == 0);
+ (*hotspots)[i].szHlpTopic_Macro[0] = '\0';
+ }
+ // we have it...now read-off the macro-string block
+ if(nMacroStrings > 0)
+ fseek( fSHG, nMacroStrings, SEEK_CUR); //nMacroStrings is byte offset...
+ // and, at the last, read through the strings: hotspot-id[ignored], then topic/macro
+ int c;
+ for( i = 0 ; i < nHotspots ; ++i)
+ {
+ while( (c = fgetc( fSHG)) != 0)
+ ;
+ // now read it:
+ int j = 0;
+ while( (c = fgetc( fSHG)) != 0)
+ {
+ (*hotspots)[i].szHlpTopic_Macro[j] = c;
+ ++j;
+ }
+ (*hotspots)[i].szHlpTopic_Macro[j] = 0;
+ }
+ fclose( fSHG);
+ return nHotspots;
+}
+
+
+// Convert Windows .SHG file to HTML map file
+
+bool SHGToMap(char *filename, char *defaultFile)
+{
+ // Test the SHG parser
+ HotSpot *hotspots = NULL;
+ int n = ParseSHG(filename, &hotspots);
+ if (n == 0)
+ return FALSE;
+
+ char buf[100];
+ sprintf(buf, "Converting .SHG file to HTML map file: there are %d hotspots in %s.", n, filename);
+ OnInform(buf);
+
+ char outBuf[256];
+ strcpy(outBuf, filename);
+ StripExtension(outBuf);
+ strcat(outBuf, ".map");
+
+ FILE *fd = fopen(outBuf, "w");
+ if (!fd)
+ {
+ OnError("Could not open .map file for writing.");
+ delete[] hotspots;
+ return FALSE;
+ }
+
+ fprintf(fd, "default %s\n", defaultFile);
+ for (int i = 0; i < n; i++)
+ {
+ char *refFilename = "??";
+
+ TexRef *texRef = FindReference(hotspots[i].szHlpTopic_Macro);
+ if (texRef)
+ refFilename = texRef->refFile;
+ else
+ {
+ char buf[300];
+ sprintf(buf, "Warning: could not find hotspot reference %s", hotspots[i].szHlpTopic_Macro);
+ OnInform(buf);
+ }
+ fprintf(fd, "rect %s %d %d %d %d\n", refFilename, (int)hotspots[i].left, (int)hotspots[i].top,
+ (int)hotspots[i].right, (int)hotspots[i].bottom);
+ }
+ fprintf(fd, "\n");
+
+ fclose(fd);
+
+ delete[] hotspots;
+ return TRUE;
+}
+
--- /dev/null
+/////////////////////////////////////////////////////////////////////////////
+// Name: readshg.h
+// Purpose: Petr Smilauer's .SHG (Segmented Hypergraphics file) reading
+// code.
+// Note: .SHG is undocumented (anywhere!) so this is
+// reverse-engineering
+// and guesswork at its best.
+// Author: Petr Smilauer
+// Modified by:
+// Created: 01/01/99
+// RCS-ID: $Id$
+// Copyright: (c) Petr Smilauer
+// Licence: wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifndef readshgh
+#define readshgh
+
+#include <stdio.h>
+#include <stdlib.h>
+
+typedef enum { TypePopup = 0xE2, TypeJump = 0xE3, TypeMacro = 0xC8} HotspotType;
+
+#define NOT_VISIBLE 0x04
+
+typedef struct
+{
+ unsigned char hotspotType;// combines HotspotType /w NOT_VISIBLE if appropriate
+ unsigned char flag; // NOT_VISIBLE or 0 ??
+ unsigned char skip; // 0, always??
+ unsigned short left,
+ top,
+ width, // left+width/top+height give right/bottom,
+ height; // =>right and bottom edge are not 'included'
+ unsigned char magic[4]; // wonderful numbers: for macros, this seems
+ // (at least first 2 bytes) to represent offset into macro-strings block.
+} ShgInfoBlock; // whole block is just 15 bytes long. How weird!
+
+#define OFF_OFFSET 0x20 // this is offset, where WORD (?) lies
+#define OFFSET_DELTA 9 // we must add this to get real offset from file beginning
+
+struct HotSpot
+{
+ HotspotType type;
+ unsigned int left,
+ top,
+ right,
+ bottom;
+ char szHlpTopic_Macro[65];
+ bool IsVisible;
+};
+
+// Returns the number of hotspots, and the array of hotspots.
+// E.g.
+// HotSpots *array;
+// int n = ParseSHG("thing.shg", &array);
+
+extern int ParseSHG( const char* fileName, HotSpot **hotspots);
+
+// Converts Windows .SHG file to HTML map file
+extern bool SHGToMap(char *filename, char *defaultFile);
+
+#endif
+
--- /dev/null
+/////////////////////////////////////////////////////////////////////////////
+// Name: rtfutils.cpp
+// Purpose: Converts Latex to Word RTF/WinHelp RTF
+// Author: Julian Smart
+// Modified by:
+// Created: 7.9.93
+// RCS-ID: $Id$
+// Copyright: (c) Julian Smart
+// Licence: wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+
+#ifndef WX_PRECOMP
+#include "wx/wx.h"
+#endif
+
+#include "tex2any.h"
+#include "tex2rtf.h"
+#include <ctype.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#ifdef __WIN32__
+#include <windows.h>
+#endif
+
+#include "bmputils.h"
+#include "table.h"
+
+wxList itemizeStack;
+static int indentLevel = 0;
+static int forbidParindent = 0; // if > 0, no parindent (e.g. in center environment)
+int forbidResetPar = 0; // If > 0, don't reset memory of having output a new par
+
+static char *contentsLineSection = NULL;
+static char *contentsLineValue = NULL;
+static TexChunk *descriptionItemArg = NULL;
+static wxStringList environmentStack; // Stack of paragraph styles we need to remember
+static int footnoteCount = 0;
+static int citeCount = 1;
+extern char *FileRoot;
+extern bool winHelp;
+extern bool startedSections;
+extern FILE *Contents;
+extern FILE *Chapters;
+extern FILE *Popups;
+extern FILE *WinHelpContentsFile;
+extern char *RTFCharset;
+// This is defined in the Tex2Any library and isn't in use after parsing
+extern char *BigBuffer;
+// Are we in verbatim mode? If so, format differently.
+static bool inVerbatim = FALSE;
+
+// We're in a series of PopRef topics, so don't output section headings
+bool inPopRefSection = FALSE;
+
+// Green colour?
+static bool hotSpotColour = TRUE;
+static bool hotSpotUnderline = TRUE;
+
+// Transparency (WHITE = transparent)
+static bool bitmapTransparency = TRUE;
+
+// Linear RTF requires us to set the style per section.
+static char *currentNumberStyle = NULL;
+static int currentItemSep = 8;
+static int CurrentTextWidth = 8640; // Say, six inches
+static int CurrentLeftMarginOdd = 400;
+static int CurrentLeftMarginEven = 1440;
+static int CurrentRightMarginOdd = 1440;
+static int CurrentRightMarginEven = 400;
+static int CurrentMarginParWidth = 2000;
+static int CurrentMarginParSep = 400; // Gap between marginpar and text
+static int CurrentMarginParX = CurrentLeftMarginOdd + CurrentTextWidth + CurrentMarginParSep;
+static int GutterWidth = 2300;
+
+// Two-column table dimensions, in twips
+static int TwoColWidthA = 1500;
+static int TwoColWidthB = 3000;
+
+const int PageWidth = 12242; // 8.25 inches wide for A4
+
+
+/*
+ * Flag to say we've just issued a \par\pard command, so don't
+ * repeat this unnecessarily.
+ *
+ */
+
+int issuedNewParagraph = 0;
+
+// Need to know whether we're in a table or figure for benefit
+// of listoffigures/listoftables
+static bool inFigure = FALSE;
+static bool inTable = FALSE;
+
+/*
+ * Current topics
+ *
+ */
+static char *CurrentChapterName = NULL;
+static char *CurrentSectionName = NULL;
+static char *CurrentSubsectionName = NULL;
+static char *CurrentTopic = NULL;
+
+static bool InPopups()
+{
+ if (CurrentChapterName && (strcmp(CurrentChapterName, "popups") == 0))
+ return TRUE;
+ if (CurrentSectionName && (strcmp(CurrentSectionName, "popups") == 0))
+ return TRUE;
+ return FALSE;
+}
+
+static void SetCurrentTopic(char *s)
+{
+ if (CurrentTopic) delete[] CurrentTopic;
+ CurrentTopic = copystring(s);
+}
+
+void SetCurrentChapterName(char *s)
+{
+ if (CurrentChapterName) delete[] CurrentChapterName;
+ CurrentChapterName = copystring(s);
+ SetCurrentTopic(s);
+}
+void SetCurrentSectionName(char *s)
+{
+ if (CurrentSectionName) delete[] CurrentSectionName;
+ CurrentSectionName = copystring(s);
+ SetCurrentTopic(s);
+}
+void SetCurrentSubsectionName(char *s)
+{
+ if (CurrentSubsectionName) delete[] CurrentSubsectionName;
+ CurrentSubsectionName = copystring(s);
+ SetCurrentTopic(s);
+}
+
+// Indicate that a parent topic at level 'level' has children.
+// Level 1 is a chapter, 2 is a section, etc.
+void NotifyParentHasChildren(int parentLevel)
+{
+ char *parentTopic = NULL;
+ switch (parentLevel)
+ {
+ case 1:
+ {
+ parentTopic = CurrentChapterName;
+ break;
+ }
+ case 2:
+ {
+ parentTopic = CurrentSectionName;
+ break;
+ }
+ case 3:
+ {
+ parentTopic = CurrentSubsectionName;
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+ if (parentTopic)
+ {
+ TexTopic *texTopic = (TexTopic *)TopicTable.Get(parentTopic);
+ if (!texTopic)
+ {
+ texTopic = new TexTopic;
+ TopicTable.Put(parentTopic, texTopic);
+ }
+ texTopic->hasChildren = TRUE;
+ }
+}
+
+// Have to keep a count of what levels are books, what are pages,
+// in order to correct for a Win95 bug which means that if you
+// have a book at level n, and then a page at level n, the page
+// ends up on level n + 1.
+
+bool ContentsLevels[5];
+
+// Reset below this level (starts from 1)
+void ResetContentsLevels(int l)
+{
+ int i;
+ for (i = l; i < 5; i++)
+ ContentsLevels[i] = FALSE;
+
+ // There are always books on the top level
+ ContentsLevels[0] = TRUE;
+}
+
+// Output a WinHelp section as a keyword, substituting
+// : for space.
+void OutputSectionKeyword(FILE *fd)
+{
+ OutputCurrentSectionToString(wxBuffer);
+
+ int i;
+ for (i = 0; i < strlen(wxBuffer); i++)
+ if (wxBuffer[i] == ':')
+ wxBuffer[i] = ' ';
+ // Don't write to index if there's some RTF in the string
+ else if ( wxBuffer[i] == '{' )
+ return;
+
+ fprintf(fd, "K{\\footnote {K} ");
+ fprintf(fd, "%s", wxBuffer);
+
+ fprintf(fd, "}\n");
+}
+
+// Write a line for the .cnt file, if we're doing this.
+void WriteWinHelpContentsFileLine(char *topicName, char *xitle, int level)
+{
+ // First, convert any RTF characters to ASCII
+ char title[255];
+ int s=0;
+ int d=0;
+ while ( (xitle[s]!=0)&&(d<255) )
+ {
+ char ch=xitle[s]&0xff;
+ if (ch==0x5c) {
+ char ch1=xitle[s+1]&0xff;
+ char ch2=xitle[s+2]&0xff;
+ char ch3=xitle[s+3]&0xff;
+ char ch4=xitle[s+4]&0xff;
+ s+=4; // next character
+ char a=0;
+ if ((ch1==0x27)&&(ch2==0x66)&&(ch3==0x36)) { title[d++]='ö'; a=1; }
+ if ((ch1==0x27)&&(ch2==0x65)&&(ch3==0x34)) { title[d++]='ä'; a=1; }
+ if ((ch1==0x27)&&(ch2==0x66)&&(ch3==0x63)) { title[d++]='ü'; a=1; }
+ if ((ch1==0x27)&&(ch2==0x64)&&(ch3==0x36)) { title[d++]='Ö'; a=1; }
+ if ((ch1==0x27)&&(ch2==0x63)&&(ch3==0x34)) { title[d++]='Ä'; a=1; }
+ if ((ch1==0x27)&&(ch2==0x64)&&(ch3==0x63)) { title[d++]='Ü'; a=1; }
+// if (a==0)
+// printf("!!!!! %04X %04X %04X %04X! \n",ch1,ch2,ch3,ch4);
+ } else {
+ title[d++]=ch;
+ s++;
+ }
+ }
+ title[d]=0;
+
+ // Section (2) becomes level 1 if it's an article.
+ if (DocumentStyle == LATEX_ARTICLE)
+ level --;
+
+ if (level == 0) // Means we had a Chapter in an article, oops.
+ return;
+
+ ResetContentsLevels(level);
+
+ if (!title)
+ return;
+
+ if (winHelp && winHelpContents && WinHelpContentsFile)
+ {
+ TexTopic *texTopic = (TexTopic *)TopicTable.Get(topicName);
+ if (texTopic)
+ {
+ // If a previous section at this level was a book, we *have* to have a
+ // book not a page, because of a bug in WHC (or WinHelp 4).
+ if (texTopic->hasChildren || level == 1 || ContentsLevels[level-1])
+ {
+ // At this level, we have a pointer to a further hierarchy.
+ // So we need a 'book' consisting of (say) Chapter 1.
+ fprintf(WinHelpContentsFile, "%d %s\n", level, title);
+
+ // Then we have a 'page' consisting of the text for this chapter
+ fprintf(WinHelpContentsFile, "%d %s=%s\n", level+1, title, topicName);
+
+ // Then we'll be writing out further pages or books at level + 1...
+
+ // Remember that at this level, we had a book and *must* for the
+ // remainder of sections at this level.
+ ContentsLevels[level-1] = TRUE;
+ }
+ else
+ {
+ fprintf(WinHelpContentsFile, "%d %s=%s\n", level, title, topicName);
+ }
+ }
+ else
+ {
+ if (level == 1 || ContentsLevels[level-1])
+ {
+ // Always have a book at level 1
+ fprintf(WinHelpContentsFile, "%d %s\n", level, title);
+ fprintf(WinHelpContentsFile, "%d %s=%s\n", level+1, title, topicName);
+ ContentsLevels[level-1] = TRUE;
+ }
+ else
+ // Probably doesn't have children if it hasn't been added to the topic table
+ fprintf(WinHelpContentsFile, "%d %s=%s\n", level, title, topicName);
+ }
+ }
+}
+
+void SplitIndexEntry(char *entry, char *buf1, char *buf2)
+{
+ int len = strlen(entry); int i = 0;
+ while ((i < len) && entry[i] != '!')
+ { buf1[i] = entry[i]; i ++; }
+ buf1[i] = 0; buf2[0] = 0; int j = 0;
+
+ if (entry[i] == '!')
+ {
+ i ++;
+ while (i < len) { buf2[j] = entry[i]; i ++; j++; }
+ buf2[j] = 0;
+ }
+}
+
+/*
+ * Output topic index entries in WinHelp RTF
+ *
+ */
+void GenerateKeywordsForTopic(char *topic)
+{
+ TexTopic *texTopic = (TexTopic *)TopicTable.Get(topic);
+ if (!texTopic)
+ return;
+
+ wxStringList *list = texTopic->keywords;
+ if (list)
+ {
+ wxNode *node = list->First();
+ while (node)
+ {
+ char *s = (char *)node->Data();
+
+ // Must separate out main entry form subentry (only 1 subentry allowed)
+ char buf1[100]; char buf2[100];
+ SplitIndexEntry(s, buf1, buf2);
+
+ // Check for ':' which messes up index
+ int i;
+ for (i = 0; i < strlen(buf1) ; i++)
+ if (buf1[i] == ':')
+ buf1[i] = ' ';
+ for (i = 0; i < strlen(buf2) ; i++)
+ if (buf2[i] == ':')
+ buf2[i] = ' ';
+
+ // {K} is a strange fix to prevent words beginning with K not
+ // being indexed properly
+ TexOutput("K{\\footnote {K} ");
+ TexOutput(buf1);
+ if (strlen(buf2) > 0)
+ {
+ // Output subentry
+ TexOutput(", ");
+ TexOutput(buf2);
+ }
+ TexOutput("}\n");
+ node = node->Next();
+ }
+ }
+}
+
+/*
+ * Output index entry in linear RTF
+ *
+ */
+
+void GenerateIndexEntry(char *entry)
+{
+ if (useWord)
+ {
+ char buf1[100]; char buf2[100];
+ SplitIndexEntry(entry, buf1, buf2);
+
+ TexOutput("{\\xe\\v {");
+ TexOutput(buf1);
+ if (strlen(buf2) > 0)
+ {
+ TexOutput("\\:");
+ TexOutput(buf2);
+ }
+ TexOutput("}}");
+ }
+}
+
+ /*
+ * Write a suitable RTF header.
+ *
+ */
+
+void WriteColourTable(FILE *fd)
+{
+ fprintf(fd, "{\\colortbl");
+ wxNode *node = ColourTable.First();
+ while (node)
+ {
+ ColourTableEntry *entry = (ColourTableEntry *)node->Data();
+ fprintf(fd, "\\red%d\\green%d\\blue%d;\n", entry->red, entry->green, entry->blue);
+ node = node->Next();
+ }
+ fprintf(fd, "}");
+}
+
+/*
+ * Write heading style
+ *
+ */
+
+void WriteHeadingStyle(FILE *fd, int heading)
+{
+ switch (heading)
+ {
+ case 1:
+ {
+ fprintf(fd, "\\b\\fs%d", chapterFont*2);
+ break;
+ }
+ case 2:
+ {
+ fprintf(fd, "\\b\\fs%d", sectionFont*2);
+ break;
+ }
+ case 3:
+ {
+ fprintf(fd, "\\b\\fs%d", subsectionFont*2);
+ break;
+ }
+ case 4:
+ {
+ fprintf(fd, "\\b\\fs%d", subsectionFont*2);
+ break;
+ }
+ default:
+ break;
+ }
+}
+
+void WriteRTFHeader(FILE *fd)
+{
+ fprintf(fd, "{\\rtf1\\%s \\deff0\n", RTFCharset);
+ fprintf(fd, "{\\fonttbl{\\f0\\froman Times New Roman;}{\\f1\\ftech Symbol;}{\\f2\\fswiss Arial;}\n");
+ fprintf(fd, "{\\f3\\fmodern Courier;}{\\f4\\ftech Wingdings;}{\\f5\\ftech Monotype Sorts;}\n}");
+ /*
+ * Style sheet
+ */
+ fprintf(fd, "{\\stylesheet{\\f2\\fs20 \\snext0 Normal;}\n");
+ // Headings
+ fprintf(fd, "{\\s1 "); WriteHeadingStyle(fd, 1); fprintf(fd, "\\sbasedon0\\snext0 heading 1;}\n");
+ fprintf(fd, "{\\s2 "); WriteHeadingStyle(fd, 2); fprintf(fd, "\\sbasedon0\\snext0 heading 2;}\n");
+ fprintf(fd, "{\\s3 "); WriteHeadingStyle(fd, 3); fprintf(fd, "\\sbasedon0\\snext0 heading 3;}\n");
+ fprintf(fd, "{\\s4 "); WriteHeadingStyle(fd, 4); fprintf(fd, "\\sbasedon0\\snext0 heading 4;}\n");
+ // Table of contents styles
+ fprintf(fd, "{\\s20\\sb300\\tqr\\tldot\\tx8640 \\b\\f2 \\sbasedon0\\snext0 toc 1;}\n");
+
+ fprintf(fd, "{\\s21\\sb90\\tqr\\tldot\\li400\\tqr\\tx8640 \\f2\\fs20\\sbasedon0\\snext0 toc 2;}\n");
+ fprintf(fd, "{\\s22\\sb90\\tqr\\tldot\\li800\\tx8640 \\f2\\fs20 \\sbasedon0\\snext0 toc 3;}\n");
+ fprintf(fd, "{\\s23\\sb90\\tqr\\tldot\\li1200\\tx8640 \\f2\\fs20 \\sbasedon0\\snext0 toc 4;}\n");
+
+ // Index styles
+ fprintf(fd, "{\\s30\\fi-200\\li200\\tqr\\tx3960 \\f2\\fs18 \\sbasedon0\\snext0 index 1;}\n");
+ fprintf(fd, "{\\s31\\fi-200\\li400\\tqr\\tx3960 \\f2\\fs18 \\sbasedon0\\snext0 index 2;}\n");
+ fprintf(fd, "{\\s32\\fi-200\\li600\\tqr\\tx3960 \\f2\\fs18 \\sbasedon0\\snext0 index 3;}\n");
+ fprintf(fd, "{\\s33\\fi-200\\li800\\tqr\\tx3960 \\f2\\fs18 \\sbasedon0\\snext0 index 4;}\n");
+ fprintf(fd, "{\\s35\\qc\\sb240\\sa120 \\b\\f2\\fs26 \\sbasedon0\\snext30 index heading;}\n");
+ fprintf(fd, "}\n");
+
+ WriteColourTable(fd);
+ fprintf(fd, "\n\\ftnbj\\ftnrestart"); // Latex default is footnotes at bottom of page, not section.
+ fprintf(fd, "\n");
+}
+
+void OutputNumberStyle(char *numberStyle)
+{
+ if (numberStyle)
+ {
+ if (strcmp(numberStyle, "arabic") == 0)
+ {
+ TexOutput("\\pgndec");
+ }
+ else if (strcmp(numberStyle, "roman") == 0)
+ {
+ TexOutput("\\pgnlcrm");
+ }
+ else if (strcmp(numberStyle, "Roman") == 0)
+ {
+ TexOutput("\\pgnucrm");
+ }
+ else if (strcmp(numberStyle, "alph") == 0)
+ {
+ TexOutput("\\pgnlcltr");
+ }
+ else if (strcmp(numberStyle, "Alph") == 0)
+ {
+ TexOutput("\\pgnucltr");
+ }
+ }
+}
+
+/*
+ * Write a Windows help project file
+ */
+
+bool WriteHPJ(char *filename)
+{
+ char hpjFilename[256];
+ char helpFile[50];
+ char rtfFile[50];
+ strcpy(hpjFilename, filename);
+ StripExtension(hpjFilename);
+ strcat(hpjFilename, ".hpj");
+
+ strcpy(helpFile, FileNameFromPath(filename));
+ StripExtension(helpFile);
+ strcpy(rtfFile, helpFile);
+ strcat(helpFile, ".hlp");
+ strcat(rtfFile, ".rtf");
+
+ FILE *fd = fopen(hpjFilename, "w");
+ if (!fd)
+ return FALSE;
+
+ char *helpTitle = winHelpTitle;
+ if (!helpTitle)
+ helpTitle = "Untitled";
+
+ char *thePath = wxPathOnly(InputFile);
+ if (!thePath)
+ thePath = ".";
+ fprintf(fd, "[OPTIONS]\n");
+ fprintf(fd, "BMROOT=%s ; Assume that bitmaps are where the source is\n", thePath);
+ fprintf(fd, "TITLE=%s\n", helpTitle);
+ fprintf(fd, "CONTENTS=Contents\n");
+
+ if (winHelpVersion > 3)
+ {
+ fprintf(fd, "; COMPRESS=12 Hall Zeck ; Max compression, but needs lots of memory\n");
+ fprintf(fd, "COMPRESS=8 Zeck\n");
+ fprintf(fd, "LCID=0x809 0x0 0x0 ;English (British)\n");
+ fprintf(fd, "HLP=.\\%s.hlp\n", wxFileNameFromPath(FileRoot));
+ }
+ else
+ {
+ fprintf(fd, "COMPRESS=HIGH\n");
+ }
+ fprintf(fd, "\n");
+
+ if (winHelpVersion > 3)
+ {
+ fprintf(fd, "[WINDOWS]\n");
+ fprintf(fd, "Main=\"\",(553,102,400,600),20736,(r14876671),(r12632256),f3\n");
+ fprintf(fd, "\n");
+ }
+
+ fprintf(fd, "[FILES]\n%s\n\n", rtfFile);
+ fprintf(fd, "[CONFIG]\n");
+ if (useUpButton)
+ fprintf(fd, "CreateButton(\"Up\", \"&Up\", \"JumpId(`%s', `Contents')\")\n", helpFile);
+ fprintf(fd, "BrowseButtons()\n\n");
+ fprintf(fd, "[MAP]\n\n[BITMAPS]\n\n");
+ fclose(fd);
+ return TRUE;
+}
+
+
+/*
+ * Given a TexChunk with a string value, scans through the string
+ * converting Latex-isms into RTF-isms, such as 2 newlines -> \par,
+ * and inserting spaces at the start of lines since in Latex, a newline
+ * implies a space, but not in RTF.
+ *
+ */
+
+void ProcessText2RTF(TexChunk *chunk)
+{
+ bool changed = FALSE;
+ int ptr = 0;
+ int i = 0;
+ char ch = 1;
+ int len = strlen(chunk->value);
+ while (ch != 0)
+ {
+ ch = chunk->value[i];
+
+ if (ch == 10)
+ {
+ if (inVerbatim)
+ {
+ BigBuffer[ptr] = 0; strcat(BigBuffer, "\\par\n"); ptr += 5;
+ i ++;
+ changed = TRUE;
+ }
+ else
+ {
+ // If the first character of the next line is ASCII,
+ // put a space in. Implicit in Latex, not in RTF.
+ /*
+ The reason this is difficult is that you don't really know
+ where a space would be appropriate. If you always put in a space
+ when you find a newline, unwanted spaces appear in the text.
+ */
+ if ((i > 0) && (len > i+1 && isascii(chunk->value[i+1]) &&
+ !isspace(chunk->value[i+1])) ||
+ ((len > i+1 && chunk->value[i+1] == 13) &&
+ (len > i+2 && isascii(chunk->value[i+2]) &&
+ !isspace(chunk->value[i+2]))))
+// if (TRUE)
+ {
+ // DOS files have a 13 after the 10
+ BigBuffer[ptr] = 10;
+ ptr ++;
+ i ++;
+ if (chunk->value[i] == 13)
+ {
+ BigBuffer[ptr] = 13;
+ ptr ++;
+ i ++;
+ }
+
+ BigBuffer[ptr] = ' ';
+ ptr ++;
+
+ // Note that the actual ASCII character seen is dealt with in the next
+ // iteration
+ changed = TRUE;
+ }
+ else
+ {
+ BigBuffer[ptr] = ch;
+ i ++;
+ }
+ }
+ }
+ else if (!inVerbatim && ch == '`' && (len >= i+1 && chunk->value[i+1] == '`'))
+ {
+ BigBuffer[ptr] = '"'; ptr ++;
+ i += 2;
+ changed = TRUE;
+ }
+ else if (!inVerbatim && ch == '`') // Change ` to '
+ {
+ BigBuffer[ptr] = 39; ptr ++;
+ i += 1;
+ changed = TRUE;
+ }
+ else if (inVerbatim && ch == '\\') // Change backslash to two backslashes
+ {
+ BigBuffer[ptr] = '\\'; ptr ++;
+ BigBuffer[ptr] = '\\'; ptr ++;
+ i += 1;
+ changed = TRUE;
+ }
+ else if (inVerbatim && (ch == '{' || ch == '}')) // Escape the curly bracket
+ {
+ BigBuffer[ptr] = '\\'; ptr ++;
+ BigBuffer[ptr] = ch; ptr ++;
+ i += 1;
+ changed = TRUE;
+ }
+ else
+ {
+ BigBuffer[ptr] = ch;
+ i ++;
+ ptr ++;
+ }
+ }
+ BigBuffer[ptr] = 0;
+
+ if (changed)
+ {
+ delete[] chunk->value;
+ chunk->value = copystring(BigBuffer);
+ }
+}
+
+/*
+ * Scan through all chunks starting from the given one,
+ * calling ProcessText2RTF to convert Latex-isms to RTF-isms.
+ * This should be called after Tex2Any has parsed the file,
+ * and before TraverseDocument is called.
+ *
+ */
+
+void Text2RTF(TexChunk *chunk)
+{
+ Tex2RTFYield();
+ if (stopRunning) return;
+
+ switch (chunk->type)
+ {
+ case CHUNK_TYPE_MACRO:
+ {
+ TexMacroDef *def = chunk->def;
+ if (def && def->ignore)
+ return;
+
+ if (def && (def->macroId == ltVERBATIM || def->macroId == ltVERB))
+ inVerbatim = TRUE;
+
+ wxNode *node = chunk->children.First();
+ while (node)
+ {
+ TexChunk *child_chunk = (TexChunk *)node->Data();
+ Text2RTF(child_chunk);
+ node = node->Next();
+ }
+
+ if (def && (def->macroId == ltVERBATIM || def->macroId == ltVERB))
+ inVerbatim = FALSE;
+
+ break;
+ }
+ case CHUNK_TYPE_ARG:
+ {
+ wxNode *node = chunk->children.First();
+ while (node)
+ {
+ TexChunk *child_chunk = (TexChunk *)node->Data();
+ Text2RTF(child_chunk);
+ node = node->Next();
+ }
+
+ break;
+ }
+ case CHUNK_TYPE_STRING:
+ {
+ if (chunk->value)
+ ProcessText2RTF(chunk);
+ break;
+ }
+ }
+}
+
+/*
+ * Not used yet
+ *
+ */
+
+char browseBuf[10];
+static long browseId = 0;
+char *GetBrowseString(void)
+{
+ char buf[10];
+ browseId ++;
+ sprintf(buf, "%ld", browseId);
+ int noZeroes = 5-strlen(buf);
+ strcpy(browseBuf, "browse");
+ for (int i = 0; i < noZeroes; i++)
+ strcat(browseBuf, "0");
+ strcat(browseBuf, buf);
+ return browseBuf;
+}
+
+/*
+ * Keeping track of environments to restore the styles after \pard.
+ * Push strings like "\qc" onto stack.
+ *
+ */
+
+void PushEnvironmentStyle(char *style)
+{
+ environmentStack.Add(style);
+}
+
+void PopEnvironmentStyle(void)
+{
+ wxNode *node = environmentStack.Last();
+ if (node)
+ {
+ char *val = (char *)node->Data();
+ delete[] val;
+ delete node;
+ }
+}
+
+// Write out the styles, most recent first.
+void WriteEnvironmentStyles(void)
+{
+ wxNode *node = environmentStack.Last();
+ while (node)
+ {
+ char *val = (char *)node->Data();
+ TexOutput(val);
+ node = node->Next();
+ }
+ if (!inTabular && (ParIndent > 0) && (forbidParindent == 0))
+ {
+ char buf[15];
+ sprintf(buf, "\\fi%d", ParIndent*20); // Convert points to TWIPS
+ TexOutput(buf);
+ }
+ if (environmentStack.Number() > 0 || (ParIndent > 0))
+ TexOutput("\n");
+}
+
+
+/*
+ * Output a header
+ *
+ */
+
+void OutputRTFHeaderCommands(void)
+{
+ char buf[300];
+ if (PageStyle && strcmp(PageStyle, "plain") == 0)
+ {
+ TexOutput("{\\headerl }{\\headerr }");
+ }
+ else if (PageStyle && strcmp(PageStyle, "empty") == 0)
+ {
+ TexOutput("{\\headerl }{\\headerr }");
+ }
+ else if (PageStyle && strcmp(PageStyle, "headings") == 0)
+ {
+ // Left header
+ TexOutput("{\\headerl\\fi0 ");
+
+ if (headerRule)
+ TexOutput("\\brdrb\\brdrs\\brdrw15\\brsp20 ");
+
+ TexOutput("{\\i \\qr ");
+ if (DocumentStyle == LATEX_ARTICLE)
+ {
+ sprintf(buf, "SECTION %d", sectionNo);
+ TexOutput(buf);
+ }
+ else
+ {
+ sprintf(buf, "CHAPTER %d: ", chapterNo);
+ TexOutput(buf);
+ }
+ TexOutput("{\\field{\\*\\fldinst PAGE \\\\* MERGEFORMAT }{\\fldrslt 1}}");
+ TexOutput("}\\par\\pard}");
+
+ // Right header
+ TexOutput("{\\headerr\\fi0 ");
+
+ if (headerRule)
+ TexOutput("\\brdrb\\brdrs\\brdrw15\\brsp20 ");
+
+ TexOutput("{\\i \\qc ");
+ if (DocumentStyle == LATEX_ARTICLE)
+ {
+ sprintf(buf, "SECTION %d", sectionNo);
+ TexOutput(buf);
+ }
+ else
+ {
+ sprintf(buf, "CHAPTER %d", chapterNo);
+ TexOutput(buf);
+ }
+ TexOutput("{\\field{\\*\\fldinst PAGE \\\\* MERGEFORMAT }{\\fldrslt 1}}");
+ TexOutput("}\\par\\pard}");
+ }
+ else
+ {
+ int oldForbidResetPar = forbidResetPar;
+ forbidResetPar = 0;
+
+ if (LeftHeaderEven || CentreHeaderEven || RightHeaderEven)
+ {
+ TexOutput("{\\headerl\\fi0 ");
+
+ if (headerRule)
+ TexOutput("\\brdrb\\brdrs\\brdrw15\\brsp20 ");
+
+ if (LeftHeaderEven)
+ {
+ if (!CentreHeaderEven && !RightHeaderEven)
+ TexOutput("\\ql ");
+ TraverseChildrenFromChunk(LeftHeaderEven);
+ }
+ if (CentreHeaderEven)
+ {
+ if (!LeftHeaderEven && !RightHeaderEven)
+ TexOutput("\\qc ");
+ else
+ TexOutput("\\tab\\tab\\tab ");
+ TraverseChildrenFromChunk(CentreHeaderEven);
+ }
+ if (RightHeaderEven)
+ {
+ if (!LeftHeaderEven && !CentreHeaderEven)
+ TexOutput("\\qr ");
+ else
+ TexOutput("\\tab\\tab\\tab\\tab\\tab\\tab ");
+ TraverseChildrenFromChunk(RightHeaderEven);
+ }
+ TexOutput("\\par\\pard}");
+ }
+
+ if (LeftHeaderOdd || CentreHeaderOdd || RightHeaderOdd)
+ {
+ TexOutput("{\\headerr\\fi0 ");
+
+ if (headerRule)
+ TexOutput("\\brdrb\\brdrs\\brdrw15\\brsp20 ");
+
+ if (LeftHeaderOdd)
+ {
+ if (!CentreHeaderOdd && !RightHeaderOdd)
+ TexOutput("\\ql ");
+ TraverseChildrenFromChunk(LeftHeaderOdd);
+ }
+ if (CentreHeaderOdd)
+ {
+ if (!LeftHeaderOdd && !RightHeaderOdd)
+ TexOutput("\\qc ");
+ else
+ TexOutput("\\tab\\tab\\tab ");
+ TraverseChildrenFromChunk(CentreHeaderOdd);
+ }
+ if (RightHeaderOdd)
+ {
+ if (!LeftHeaderOdd && !CentreHeaderOdd)
+ TexOutput("\\qr ");
+ else
+ TexOutput("\\tab\\tab\\tab\\tab\\tab\\tab ");
+ TraverseChildrenFromChunk(RightHeaderOdd);
+ }
+ TexOutput("\\par\\pard}");
+ }
+ // As an approximation, don't put a header on the first page of a section.
+ // This may not always be desired, but it's a reasonable guess.
+ TexOutput("{\\headerf }");
+
+ forbidResetPar = oldForbidResetPar;
+ }
+}
+
+void OutputRTFFooterCommands(void)
+{
+ if (PageStyle && strcmp(PageStyle, "plain") == 0)
+ {
+ TexOutput("{\\footerl\\fi0 ");
+ if (footerRule)
+ TexOutput("\\brdrt\\brdrs\\brdrw15\\brsp20 ");
+ TexOutput("{\\qc ");
+ TexOutput("{\\field{\\*\\fldinst PAGE \\\\* MERGEFORMAT }{\\fldrslt 1}}");
+ TexOutput("}\\par\\pard}");
+
+ TexOutput("{\\footerr\\fi0 ");
+ if (footerRule)
+ TexOutput("\\brdrt\\brdrs\\brdrw15\\brsp20 ");
+ TexOutput("{\\qc ");
+ TexOutput("{\\field{\\*\\fldinst PAGE \\\\* MERGEFORMAT }{\\fldrslt 1}}");
+ TexOutput("}\\par\\pard}");
+ }
+ else if (PageStyle && strcmp(PageStyle, "empty") == 0)
+ {
+ TexOutput("{\\footerl }{\\footerr }");
+ }
+ else if (PageStyle && strcmp(PageStyle, "headings") == 0)
+ {
+ TexOutput("{\\footerl }{\\footerr }");
+ }
+ else
+ {
+ if (LeftFooterEven || CentreFooterEven || RightFooterEven)
+ {
+ TexOutput("{\\footerl\\fi0 ");
+ if (footerRule)
+ TexOutput("\\brdrt\\brdrs\\brdrw15\\brsp20 ");
+ if (LeftFooterEven)
+ {
+ if (!CentreFooterEven && !RightFooterEven)
+ TexOutput("\\ql ");
+ TraverseChildrenFromChunk(LeftFooterEven);
+ }
+ if (CentreFooterEven)
+ {
+ if (!LeftFooterEven && !RightFooterEven)
+ TexOutput("\\qc ");
+ else
+ TexOutput("\\tab\\tab\\tab ");
+ TraverseChildrenFromChunk(CentreFooterEven);
+ }
+ if (RightFooterEven)
+ {
+ if (!LeftFooterEven && !CentreFooterEven)
+ TexOutput("\\qr ");
+ else
+ TexOutput("\\tab\\tab\\tab\\tab\\tab\\tab ");
+ TraverseChildrenFromChunk(RightFooterEven);
+ }
+ TexOutput("\\par\\pard}");
+ }
+
+ if (LeftFooterOdd || CentreFooterOdd || RightFooterOdd)
+ {
+ TexOutput("{\\footerr\\fi0 ");
+ if (footerRule)
+ TexOutput("\\brdrt\\brdrs\\brdrw15\\brsp20 ");
+ if (LeftFooterOdd)
+ {
+ if (!CentreFooterOdd && !RightFooterOdd)
+ TexOutput("\\ql ");
+ TraverseChildrenFromChunk(LeftFooterOdd);
+ }
+ if (CentreFooterOdd)
+ {
+ if (!LeftFooterOdd && !RightFooterOdd)
+ TexOutput("\\qc ");
+ else
+ TexOutput("\\tab\\tab\\tab ");
+ TraverseChildrenFromChunk(CentreFooterOdd);
+ }
+ if (RightFooterOdd)
+ {
+ if (!LeftFooterOdd && !CentreFooterOdd)
+ TexOutput("\\qr ");
+ else
+ TexOutput("\\tab\\tab\\tab\\tab\\tab\\tab ");
+ TraverseChildrenFromChunk(RightFooterOdd);
+ }
+ TexOutput("\\par\\pard}");
+ }
+
+ // As an approximation, put a footer on the first page of a section.
+ // This may not always be desired, but it's a reasonable guess.
+ if (LeftFooterOdd || CentreFooterOdd || RightFooterOdd)
+ {
+ TexOutput("{\\footerf\\fi0 ");
+ if (LeftFooterOdd)
+ {
+ if (!CentreFooterOdd && !RightFooterOdd)
+ TexOutput("\\ql ");
+ TraverseChildrenFromChunk(LeftFooterOdd);
+ }
+ if (CentreFooterOdd)
+ {
+ if (!LeftFooterOdd && !RightFooterOdd)
+ TexOutput("\\qc ");
+ else
+ TexOutput("\\tab\\tab\\tab ");
+ TraverseChildrenFromChunk(CentreFooterOdd);
+ }
+ if (RightFooterOdd)
+ {
+ if (!LeftFooterOdd && !CentreFooterOdd)
+ TexOutput("\\qr ");
+ else
+ TexOutput("\\tab\\tab\\tab\\tab\\tab\\tab ");
+ TraverseChildrenFromChunk(RightFooterOdd);
+ }
+ TexOutput("\\par\\pard}");
+ }
+ }
+}
+
+// Called on start/end of macro examination
+void RTFOnMacro(int macroId, int no_args, bool start)
+{
+/*
+ char tmpBuf[40];
+ sprintf(tmpBuf, "%d (%d)", macroId, (int)start);
+ OutputDebugString("RTFOnMacro Start "); OutputDebugString(tmpBuf);
+ OutputDebugString("\n"); wxYield();
+*/
+
+ // ltLABEL is included here because after a section but BEFORE
+ // the label is seen, a new paragraph is issued. Don't upset this by
+ // immediately forgetting we've done it.
+ if (start && (macroId != ltPAR && macroId != ltITEMIZE &&
+ macroId != ltENUMERATE && macroId != ltDESCRIPTION &&
+ macroId != ltVERBATIM && macroId != ltLABEL &&
+ macroId != ltSETHEADER && macroId != ltSETFOOTER &&
+ macroId != ltPAGENUMBERING &&
+ (forbidResetPar == 0)))
+ {
+ issuedNewParagraph = 0;
+ }
+
+ char buf[300];
+ switch (macroId)
+ {
+ case ltCHAPTER:
+ case ltCHAPTERSTAR:
+ case ltCHAPTERHEADING:
+ case ltCHAPTERHEADINGSTAR:
+ {
+ if (!start)
+ {
+ sectionNo = 0;
+ figureNo = 0;
+ tableNo = 0;
+ subsectionNo = 0;
+ subsubsectionNo = 0;
+ footnoteCount = 0;
+
+ if (macroId != ltCHAPTERSTAR && macroId != ltCHAPTERHEADINGSTAR)
+ chapterNo ++;
+
+ char *topicName = FindTopicName(GetNextChunk());
+ SetCurrentChapterName(topicName);
+
+ if (winHelpContents && winHelp && !InPopups())
+ {
+ OutputCurrentSectionToString(wxBuffer);
+ WriteWinHelpContentsFileLine(topicName, wxBuffer, 1);
+ }
+ AddTexRef(topicName, NULL, ChapterNameString, chapterNo);
+
+ if (winHelp)
+ {
+ if (!InPopups())
+ fprintf(Contents, "\n{\\uldb ");
+ fprintf(Chapters, "\\page");
+ fprintf(Chapters, "\n${\\footnote ");
+ if (!InPopups())
+ SetCurrentOutputs(Contents, Chapters);
+ else
+ SetCurrentOutput(Chapters);
+ }
+ else
+ {
+ fprintf(Chapters, "\\sect\\pgncont\\titlepg\n");
+
+ // If a non-custom page style, we generate the header now.
+ if (PageStyle && (strcmp(PageStyle, "plain") == 0 ||
+ strcmp(PageStyle, "empty") == 0 ||
+ strcmp(PageStyle, "headings") == 0))
+ {
+ OutputRTFHeaderCommands();
+ OutputRTFFooterCommands();
+ }
+
+ // Need to reset the current numbering style, or RTF forgets it.
+ SetCurrentOutput(Chapters);
+ OutputNumberStyle(currentNumberStyle);
+
+ SetCurrentOutput(Contents);
+
+ if (!InPopups())
+ {
+ if (macroId == ltCHAPTER)
+ {
+ // Section
+ fprintf(Contents, "\\par\n\\pard{\\b %d\\tab ", chapterNo);
+ }
+ else if (macroId == ltCHAPTERHEADING)
+ {
+ fprintf(Contents, "\\par\n\\pard{\\b ");
+ }
+ else SetCurrentOutput(NULL); // No entry in table of contents
+ }
+ }
+
+ startedSections = TRUE;
+
+ // Output heading to contents page
+ if (!InPopups())
+ {
+ OutputCurrentSection();
+
+ if (winHelp)
+ fprintf(Contents, "}{\\v %s}\\par\\pard\n", topicName);
+ else if ((macroId == ltCHAPTER) || (macroId == ltCHAPTERHEADING))
+ fprintf(Contents, "}\\par\\par\\pard\n");
+
+ // From here, just output to chapter
+ SetCurrentOutput(Chapters);
+ }
+
+ if (winHelp)
+ {
+ fprintf(Chapters, "}\n#{\\footnote %s}\n", topicName);
+ fprintf(Chapters, "+{\\footnote %s}\n", GetBrowseString());
+
+ OutputSectionKeyword(Chapters);
+
+ GenerateKeywordsForTopic(topicName);
+ if (useUpButton)
+ {
+ // If we're generating a .cnt file, we don't want to be able
+ // jump up to the old-style contents page, so disable it.
+ if (winHelpContents)
+ fprintf(Chapters, "!{\\footnote DisableButton(\"Up\")}\n");
+ else
+ fprintf(Chapters, "!{\\footnote EnableButton(\"Up\");ChangeButtonBinding(\"Up\", \"JumpId(`%s.hlp', `%s')\")}\n",
+ FileNameFromPath(FileRoot), "Contents");
+ }
+ }
+
+ if (!InPopups())
+ {
+ char *styleCommand = "";
+ if (!winHelp && useHeadingStyles && (macroId == ltCHAPTER || macroId == ltCHAPTERHEADING || macroId == ltCHAPTERHEADINGSTAR))
+ styleCommand = "\\s1";
+ fprintf(Chapters, "\\pard{%s", ((winHelp && !InPopups()) ? "\\keepn\\sa140\\sb140" : styleCommand));
+ WriteHeadingStyle(Chapters, 1); fprintf(Chapters, " ");
+ if (!winHelp)
+ {
+ if (macroId == ltCHAPTER)
+ {
+ if (useWord)
+// fprintf(Chapters, "{\\bkmkstart %s}%d{\\bkmkend %s}. ", topicName, chapterNo,
+ fprintf(Chapters, "{\\bkmkstart %s}{\\bkmkend %s}", topicName, topicName);
+ else
+ fprintf(Chapters, "%d. ", chapterNo);
+ }
+ else if ( useWord )
+ {
+ fprintf(Chapters, "{\\bkmkstart %s}{\\bkmkend %s}", topicName, topicName);
+ }
+ }
+ OutputCurrentSection();
+ TexOutput("\\par\\pard}\\par\n");
+ }
+ issuedNewParagraph = 2;
+ }
+ break;
+ }
+ case ltSECTION:
+ case ltSECTIONSTAR:
+ case ltSECTIONHEADING:
+ case ltSECTIONHEADINGSTAR:
+ case ltGLOSS:
+ {
+ FILE *jumpFrom;
+ if (DocumentStyle == LATEX_ARTICLE)
+ jumpFrom = Contents;
+ else
+ jumpFrom = Chapters;
+
+ if (!start)
+ {
+ subsectionNo = 0;
+ subsubsectionNo = 0;
+ if (DocumentStyle == LATEX_ARTICLE)
+ footnoteCount = 0;
+
+ if (macroId != ltSECTIONSTAR && macroId != ltSECTIONHEADINGSTAR)
+ sectionNo ++;
+
+ char *topicName = FindTopicName(GetNextChunk());
+ SetCurrentSectionName(topicName);
+ NotifyParentHasChildren(1);
+ if (winHelpContents && winHelp && !InPopups())
+ {
+ OutputCurrentSectionToString(wxBuffer);
+ WriteWinHelpContentsFileLine(topicName, wxBuffer, 2);
+ }
+ AddTexRef(topicName, NULL, SectionNameString, chapterNo, sectionNo);
+
+ if (winHelp)
+ {
+ SetCurrentOutputs(jumpFrom, Sections);
+ // Newline for a new section if this is an article
+ if ((DocumentStyle == LATEX_ARTICLE) &&
+ ((macroId == ltSECTION) || (macroId == ltSECTIONSTAR) || (macroId == ltSECTIONHEADINGSTAR)))
+ fprintf(Sections, "\\page\n");
+
+ if (!InPopups())
+ fprintf(jumpFrom, "\n{\\uldb ");
+ }
+ else
+ {
+ if (DocumentStyle == LATEX_ARTICLE)
+ {
+ TexOutput("\\sect\\pgncont\n");
+ // If a non-custom page style, we generate the header now.
+ if (PageStyle && (strcmp(PageStyle, "plain") == 0 ||
+ strcmp(PageStyle, "empty") == 0 ||
+ strcmp(PageStyle, "headings") == 0))
+ {
+ OutputRTFHeaderCommands();
+ OutputRTFFooterCommands();
+ }
+ }
+ SetCurrentOutput(Contents);
+
+ if (macroId == ltSECTION)
+ {
+ if (!InPopups())
+ {
+ if (DocumentStyle == LATEX_REPORT)
+ fprintf(Contents, "\n\\pard{\\tab %d.%d\\tab ", chapterNo, sectionNo);
+ else
+ fprintf(Contents, "\\par\n\\pard{\\b %d\\tab ", sectionNo);
+ }
+ }
+ else if (macroId == ltSECTIONHEADING)
+ {
+ if (!InPopups())
+ {
+ if (DocumentStyle == LATEX_REPORT)
+ fprintf(Contents, "\n\\pard{\\tab "); //, chapterNo, sectionNo);
+ else
+ fprintf(Contents, "\\par\n\\pard{\\b "); //, sectionNo);
+ }
+ }
+ else SetCurrentOutput(NULL);
+ }
+
+ if (startedSections)
+ {
+ if (winHelp)
+ fprintf(Sections, "\\page\n");
+ }
+ startedSections = TRUE;
+
+ if (winHelp)
+ fprintf(Sections, "\n${\\footnote ");
+
+ // Output heading to contents page
+ if (!InPopups())
+ OutputCurrentSection();
+
+ if (winHelp)
+ {
+ if (!InPopups())
+ fprintf(jumpFrom, "}{\\v %s}\\par\\pard\n", topicName);
+ }
+ else if ((macroId != ltSECTIONSTAR) && (macroId != ltGLOSS))
+ {
+ if (DocumentStyle == LATEX_REPORT)
+ fprintf(Contents, "}\\par\\pard\n");
+ else
+ fprintf(Contents, "}\\par\\par\\pard\n");
+ }
+
+ SetCurrentOutput(winHelp ? Sections : Chapters);
+
+ if (winHelp)
+ {
+ fprintf(Sections, "}\n#{\\footnote %s}\n", topicName);
+ fprintf(Sections, "+{\\footnote %s}\n", GetBrowseString());
+ OutputSectionKeyword(Sections);
+ GenerateKeywordsForTopic(topicName);
+ if (useUpButton)
+ {
+ if (DocumentStyle == LATEX_ARTICLE)
+ {
+ fprintf(Sections, "!{\\footnote EnableButton(\"Up\");ChangeButtonBinding(\"Up\", \"JumpId(`%s.hlp', `%s')\")}\n",
+ FileNameFromPath(FileRoot), "Contents");
+ }
+ else if (CurrentChapterName)
+ {
+ fprintf(Sections, "!{\\footnote EnableButton(\"Up\");ChangeButtonBinding(\"Up\", \"JumpId(`%s.hlp', `%s')\")}\n",
+ FileNameFromPath(FileRoot), CurrentChapterName);
+ }
+ }
+ }
+
+ if (!InPopups())
+ {
+ char *styleCommand = "";
+ if (!winHelp && useHeadingStyles && (macroId != ltSECTIONSTAR))
+ {
+ if (DocumentStyle == LATEX_ARTICLE)
+ styleCommand = "\\s1";
+ else
+ styleCommand = "\\s2";
+ }
+ char *keep = "";
+ if (winHelp && (macroId != ltGLOSS) && !InPopups())
+ keep = "\\keepn\\sa140\\sb140";
+
+ fprintf(winHelp ? Sections : Chapters, "\\pard{%s%s",
+ keep, styleCommand);
+
+ WriteHeadingStyle((winHelp ? Sections : Chapters),
+ (DocumentStyle == LATEX_ARTICLE ? 1 : 2));
+ fprintf(winHelp ? Sections : Chapters, " ");
+
+ if (!winHelp)
+ {
+ if ((macroId != ltSECTIONSTAR) && (macroId != ltSECTIONHEADINGSTAR) && (macroId != ltGLOSS))
+ {
+ if (DocumentStyle == LATEX_REPORT)
+ {
+ if (useWord)
+// fprintf(Chapters, "{\\bkmkstart %s}%d.%d{\\bkmkend %s}. ", topicName, chapterNo, sectionNo,
+ fprintf(Chapters, "{\\bkmkstart %s}{\\bkmkend %s}", topicName,
+ topicName);
+ else
+ fprintf(Chapters, "%d.%d. ", chapterNo, sectionNo);
+ }
+ else
+ {
+ if (useWord)
+// fprintf(Chapters, "{\\bkmkstart %s}%d{\\bkmkend %s}. ", topicName, sectionNo,
+ fprintf(Chapters, "{\\bkmkstart %s}{\\bkmkend %s}", topicName,
+ topicName);
+ else
+ fprintf(Chapters, "%d. ", sectionNo);
+ }
+ }
+ else if ( useWord )
+ {
+ fprintf(Chapters, "{\\bkmkstart %s}{\\bkmkend %s}", topicName, topicName);
+ }
+ }
+ OutputCurrentSection();
+ TexOutput("\\par\\pard}\\par\n");
+ }
+ issuedNewParagraph = 2;
+ }
+ break;
+ }
+ case ltSUBSECTION:
+ case ltSUBSECTIONSTAR:
+ case ltMEMBERSECTION:
+ case ltFUNCTIONSECTION:
+ {
+ if (!start)
+ {
+ if (winHelp && !Sections)
+ {
+ OnError("You cannot have a subsection before a section!");
+ }
+ else
+ {
+ subsubsectionNo = 0;
+
+ if (macroId != ltSUBSECTIONSTAR)
+ subsectionNo ++;
+
+ char *topicName = FindTopicName(GetNextChunk());
+ SetCurrentSubsectionName(topicName);
+ NotifyParentHasChildren(2);
+ if (winHelpContents && winHelp && !InPopups())
+ {
+ OutputCurrentSectionToString(wxBuffer);
+ WriteWinHelpContentsFileLine(topicName, wxBuffer, 3);
+ }
+ AddTexRef(topicName, NULL, SectionNameString, chapterNo, sectionNo, subsectionNo);
+
+ if (winHelp)
+ {
+ SetCurrentOutputs(Sections, Subsections);
+ SetCurrentOutputs(Sections, Subsections);
+ if (!InPopups())
+ fprintf(Sections, "\n{\\uldb ");
+ }
+ else
+ {
+ if ((macroId != ltSUBSECTIONSTAR) && (macroId != ltMEMBERSECTION) &&
+ (macroId != ltFUNCTIONSECTION))
+ {
+ SetCurrentOutput(Contents);
+ if (DocumentStyle == LATEX_REPORT)
+ fprintf(Contents, "\n\\pard\\tab\\tab %d.%d.%d\\tab ", chapterNo, sectionNo, subsectionNo);
+ else
+ fprintf(Contents, "\n\\pard\\tab %d.%d\\tab ", sectionNo, subsectionNo);
+ } else SetCurrentOutput(NULL);
+ }
+ if (startedSections)
+ {
+ if (winHelp)
+ {
+ if (!InPopups())
+ fprintf(Subsections, "\\page\n");
+ }
+ else
+ fprintf(Chapters, "\\par\n");
+ }
+ startedSections = TRUE;
+
+ if (winHelp)
+ fprintf(Subsections, "\n${\\footnote ");
+
+ // Output to contents page
+ if (!InPopups())
+ OutputCurrentSection();
+
+ if (winHelp)
+ {
+ if (!InPopups())
+ fprintf(Sections, "}{\\v %s}\\par\\pard\n", topicName);
+ }
+ else if ((macroId != ltSUBSECTIONSTAR) && (macroId != ltMEMBERSECTION) &&
+ (macroId != ltFUNCTIONSECTION))
+ fprintf(Contents, "\\par\\pard\n");
+
+ SetCurrentOutput(winHelp ? Subsections : Chapters);
+ if (winHelp)
+ {
+ fprintf(Subsections, "}\n#{\\footnote %s}\n", topicName);
+ fprintf(Subsections, "+{\\footnote %s}\n", GetBrowseString());
+ OutputSectionKeyword(Subsections);
+ GenerateKeywordsForTopic(topicName);
+ if (useUpButton && CurrentSectionName)
+ {
+ fprintf(Subsections, "!{\\footnote EnableButton(\"Up\");ChangeButtonBinding(\"Up\", \"JumpId(`%s.hlp', `%s')\")}\n",
+ FileNameFromPath(FileRoot), CurrentSectionName);
+ }
+ }
+ if (!winHelp && indexSubsections && useWord)
+ {
+ // Insert index entry for this subsection
+ TexOutput("{\\xe\\v {");
+ OutputCurrentSection();
+ TexOutput("}}");
+ }
+
+ if (!InPopups())
+ {
+ char *styleCommand = "";
+ if (!winHelp && useHeadingStyles && (macroId != ltSUBSECTIONSTAR))
+ {
+ if (DocumentStyle == LATEX_ARTICLE)
+ styleCommand = "\\s2";
+ else
+ styleCommand = "\\s3";
+ }
+ char *keep = "";
+ if (winHelp && !InPopups())
+ keep = "\\keepn\\sa140\\sb140";
+
+ fprintf(winHelp ? Subsections : Chapters, "\\pard{%s%s",
+ keep, styleCommand);
+
+ WriteHeadingStyle((winHelp ? Subsections : Chapters),
+ (DocumentStyle == LATEX_ARTICLE ? 2 : 3));
+ fprintf(winHelp ? Subsections : Chapters, " ");
+
+ if (!winHelp)
+ {
+ if ((macroId != ltSUBSECTIONSTAR) && (macroId != ltMEMBERSECTION) &&
+ (macroId != ltFUNCTIONSECTION))
+ {
+ if (DocumentStyle == LATEX_REPORT)
+ {
+ if (useWord)
+// fprintf(Chapters, "{\\bkmkstart %s}%d.%d.%d{\\bkmkend %s}. ", topicName, chapterNo, sectionNo, subsectionNo,
+ fprintf(Chapters, "{\\bkmkstart %s}{\\bkmkend %s}", topicName,
+ topicName);
+ else
+ fprintf(Chapters, "%d.%d.%d. ", chapterNo, sectionNo, subsectionNo);
+ }
+ else
+ {
+ if (useWord)
+// fprintf(Chapters, "{\\bkmkstart %s}%d.%d{\\bkmkend %s}. ", topicName, sectionNo, subsectionNo,
+ fprintf(Chapters, "{\\bkmkstart %s}{\\bkmkend %s}", topicName,
+ topicName);
+ else
+ fprintf(Chapters, "%d.%d. ", sectionNo, subsectionNo);
+ }
+ }
+ else if ( useWord )
+ {
+ fprintf(Chapters, "{\\bkmkstart %s}{\\bkmkend %s}", topicName, topicName);
+ }
+ }
+ OutputCurrentSection(); // Repeat section header
+ TexOutput("\\par\\pard}\\par\n");
+ }
+ issuedNewParagraph = 2;
+ }
+ }
+ break;
+ }
+ case ltSUBSUBSECTION:
+ case ltSUBSUBSECTIONSTAR:
+ {
+ if (!start)
+ {
+ if (winHelp && !Subsections)
+ {
+ OnError("You cannot have a subsubsection before a subsection!");
+ }
+ else
+ {
+ if (macroId != ltSUBSUBSECTIONSTAR)
+ subsubsectionNo ++;
+
+ char *topicName = FindTopicName(GetNextChunk());
+ SetCurrentTopic(topicName);
+ NotifyParentHasChildren(3);
+ if (winHelpContents && winHelp)
+ {
+ OutputCurrentSectionToString(wxBuffer);
+ WriteWinHelpContentsFileLine(topicName, wxBuffer, 4);
+ }
+ AddTexRef(topicName, NULL, SectionNameString, chapterNo, sectionNo, subsectionNo, subsubsectionNo);
+
+ if (winHelp)
+ {
+ SetCurrentOutputs(Subsections, Subsubsections);
+ fprintf(Subsections, "\n{\\uldb ");
+ }
+ else
+ {
+ if (macroId != ltSUBSUBSECTIONSTAR)
+ {
+ if (DocumentStyle == LATEX_ARTICLE)
+ {
+ SetCurrentOutput(Contents);
+ fprintf(Contents, "\n\\tab\\tab %d.%d.%d\\tab ",
+ sectionNo, subsectionNo, subsubsectionNo);
+ }
+ else
+ SetCurrentOutput(NULL); // Don't write it into the contents, or anywhere else
+ }
+ else
+ SetCurrentOutput(NULL); // Don't write it into the contents, or anywhere else
+ }
+
+ if (startedSections)
+ {
+ if (winHelp)
+ fprintf(Subsubsections, "\\page\n");
+ else
+ fprintf(Chapters, "\\par\n");
+ }
+
+ startedSections = TRUE;
+
+ if (winHelp)
+ fprintf(Subsubsections, "\n${\\footnote ");
+
+ // Output header to contents page
+ OutputCurrentSection();
+
+ if (winHelp)
+ fprintf(Subsections, "}{\\v %s}\\par\\pard\n", topicName);
+ else if ((DocumentStyle == LATEX_ARTICLE) && (macroId != ltSUBSUBSECTIONSTAR))
+ fprintf(Contents, "\\par\\pard\n");
+
+ SetCurrentOutput(winHelp ? Subsubsections : Chapters);
+ if (winHelp)
+ {
+ fprintf(Subsubsections, "}\n#{\\footnote %s}\n", topicName);
+ fprintf(Subsubsections, "+{\\footnote %s}\n", GetBrowseString());
+ OutputSectionKeyword(Subsubsections);
+ GenerateKeywordsForTopic(topicName);
+ if (useUpButton && CurrentSubsectionName)
+ {
+ fprintf(Subsubsections, "!{\\footnote EnableButton(\"Up\");ChangeButtonBinding(\"Up\", \"JumpId(`%s.hlp', `%s')\")}\n",
+ FileNameFromPath(FileRoot), CurrentSubsectionName);
+ }
+ }
+ if (!winHelp && indexSubsections && useWord)
+ {
+ // Insert index entry for this subsubsection
+ TexOutput("{\\xe\\v {");
+ OutputCurrentSection();
+ TexOutput("}}");
+ }
+
+ char *styleCommand = "";
+ if (!winHelp && useHeadingStyles && (macroId != ltSUBSUBSECTIONSTAR))
+ {
+ if (DocumentStyle == LATEX_ARTICLE)
+ styleCommand = "\\s3";
+ else
+ styleCommand = "\\s4";
+ }
+ char *keep = "";
+ if (winHelp)
+ keep = "\\keepn\\sa140\\sb140";
+
+ fprintf(winHelp ? Subsubsections : Chapters, "\\pard{%s%s",
+ keep, styleCommand);
+
+ WriteHeadingStyle((winHelp ? Subsubsections : Chapters),
+ (DocumentStyle == LATEX_ARTICLE ? 3 : 4));
+ fprintf(winHelp ? Subsubsections : Chapters, " ");
+
+ if (!winHelp)
+ {
+ if ((macroId != ltSUBSUBSECTIONSTAR))
+ {
+ if (DocumentStyle == LATEX_ARTICLE)
+ {
+ if (useWord)
+// fprintf(Chapters, "{\\bkmkstart %s}%d.%d.%d{\\bkmkend %s}. ", topicName, sectionNo, subsectionNo, subsubsectionNo,
+ fprintf(Chapters, "{\\bkmkstart %s}{\\bkmkend %s}", topicName,
+ topicName);
+ else
+ fprintf(Chapters, "%d.%d.%d. ", sectionNo, subsectionNo, subsubsectionNo);
+ }
+ else
+ {
+ if (useWord)
+// fprintf(Chapters, "{\\bkmkstart %s}%d.%d.%d.%d{\\bkmkend %s}. ", topicName, chapterNo, sectionNo, subsectionNo, subsubsectionNo,
+ fprintf(Chapters, "{\\bkmkstart %s}{\\bkmkend %s}", topicName,
+ topicName);
+ else
+ fprintf(Chapters, "%d.%d.%d.%d. ", chapterNo, sectionNo, subsectionNo, subsubsectionNo);
+ }
+ }
+ else if ( useWord )
+ {
+ fprintf(Chapters, "{\\bkmkstart %s}{\\bkmkend %s}", topicName, topicName);
+ }
+ }
+ OutputCurrentSection(); // Repeat section header
+ TexOutput("\\par\\pard}\\par\n");
+ issuedNewParagraph = 2;
+// if (winHelp) TexOutput("\\pard");
+ }
+ }
+ break;
+ }
+ case ltCAPTION:
+ case ltCAPTIONSTAR:
+ {
+ if (!start)
+ {
+ char *topicName = FindTopicName(GetNextChunk());
+ SetCurrentTopic(topicName);
+
+ TexOutput("\\pard\\par");
+ char figBuf[200];
+
+ if (inFigure)
+ {
+ figureNo ++;
+
+ if (winHelp || !useWord)
+ {
+ if (DocumentStyle != LATEX_ARTICLE)
+ sprintf(figBuf, "%s %d.%d: ", FigureNameString, chapterNo, figureNo);
+ else
+ sprintf(figBuf, "%s %d: ", FigureNameString, figureNo);
+ }
+ else
+ {
+ sprintf(figBuf, "%s {\\field\\flddirty{\\*\\fldinst SEQ Figure \\\\* ARABIC }{\\fldrslt {\\bkmkstart %s}??{\\bkmkend %s}}}: ",
+ FigureNameString, topicName, topicName);
+ }
+ }
+ else
+ {
+ tableNo ++;
+
+ if (winHelp || !useWord)
+ {
+ if (DocumentStyle != LATEX_ARTICLE)
+ sprintf(figBuf, "%s %d.%d: ", TableNameString, chapterNo, tableNo);
+ else
+ sprintf(figBuf, "%s %d: ", TableNameString, tableNo);
+ }
+ else
+ {
+ sprintf(figBuf, "%s {\\field\\flddirty{\\*\\fldinst SEQ Table \\\\* ARABIC }{\\fldrslt {\\bkmkstart %s}??{\\bkmkend %s}}}: ",
+ TableNameString, topicName, topicName);
+ }
+ }
+
+ int n = (inTable ? tableNo : figureNo);
+ AddTexRef(topicName, NULL, NULL,
+ ((DocumentStyle != LATEX_ARTICLE) ? chapterNo : n),
+ ((DocumentStyle != LATEX_ARTICLE) ? n : 0));
+
+ if (winHelp)
+ TexOutput("\\qc{\\b ");
+ else
+ TexOutput("\\ql{\\b ");
+ TexOutput(figBuf);
+
+ OutputCurrentSection();
+
+ TexOutput("}\\par\\pard\n");
+ WriteEnvironmentStyles();
+ }
+ break;
+ }
+ case ltFUNC:
+ case ltPFUNC:
+ {
+// SetCurrentOutput(winHelp ? Subsections : Chapters);
+ if (start)
+ {
+ TexOutput("{");
+ }
+ else
+ {
+ TexOutput("}\n");
+ if (winHelp)
+ {
+ TexOutput("K{\\footnote {K} ");
+ suppressNameDecoration = TRUE;
+ TraverseChildrenFromChunk(currentMember);
+ suppressNameDecoration = FALSE;
+ TexOutput("}\n");
+ }
+ if (!winHelp && useWord)
+ {
+ // Insert index entry for this function
+ TexOutput("{\\xe\\v {");
+ suppressNameDecoration = TRUE; // Necessary so don't print "(\\bf" etc.
+ TraverseChildrenFromChunk(currentMember);
+ suppressNameDecoration = FALSE;
+ TexOutput("}}");
+ }
+ }
+ break;
+ }
+ case ltCLIPSFUNC:
+ {
+// SetCurrentOutput(winHelp ? Subsections : Chapters);
+ if (start)
+ {
+ TexOutput("{");
+ }
+ else
+ {
+ TexOutput("}\n");
+ if (winHelp)
+ {
+ TexOutput("K{\\footnote {K} ");
+ suppressNameDecoration = TRUE; // Necessary so don't print "(\\bf" etc.
+ TraverseChildrenFromChunk(currentMember);
+ suppressNameDecoration = FALSE;
+ TexOutput("}\n");
+ }
+ if (!winHelp && useWord)
+ {
+ // Insert index entry for this function
+ TexOutput("{\\xe\\v {");
+ suppressNameDecoration = TRUE; // Necessary so don't print "(\\bf" etc.
+ TraverseChildrenFromChunk(currentMember);
+ suppressNameDecoration = FALSE;
+ TexOutput("}}");
+ }
+ }
+ break;
+ }
+ case ltMEMBER:
+ {
+// SetCurrentOutput(winHelp ? Subsections : Chapters);
+ if (start)
+ {
+ TexOutput("{\\b ");
+ }
+ else
+ {
+ TexOutput("}\n");
+ if (winHelp)
+ {
+ TexOutput("K{\\footnote {K} ");
+ TraverseChildrenFromChunk(currentMember);
+ TexOutput("}\n");
+ }
+ if (!winHelp && useWord)
+ {
+ // Insert index entry for this function
+ TexOutput("{\\xe\\v {");
+ suppressNameDecoration = TRUE; // Necessary so don't print "(\\bf" etc.
+ TraverseChildrenFromChunk(currentMember);
+ suppressNameDecoration = FALSE;
+ TexOutput("}}");
+ }
+ }
+ break;
+ }
+ case ltDOCUMENT:
+ {
+ if (start)
+ SetCurrentOutput(Chapters);
+ break;
+ }
+ case ltTABLEOFCONTENTS:
+ {
+ if (start)
+ {
+ if (!winHelp && useWord)
+ {
+ // Insert Word for Windows table of contents
+ TexOutput("\\par\\pard\\pgnrestart\\sect\\titlepg");
+
+ // In linear RTF, same as chapter headings.
+ sprintf(buf, "{\\b\\fs%d %s}\\par\\par\\pard\n\n", chapterFont*2, ContentsNameString);
+
+ TexOutput(buf);
+ sprintf(buf, "{\\field{\\*\\fldinst TOC \\\\o \"1-%d\" }{\\fldrslt PRESS F9 TO REFORMAT CONTENTS}}\n", contentsDepth);
+ TexOutput(buf);
+// TexOutput("\\sect\\sectd");
+ }
+ else
+ {
+ FILE *fd = fopen(ContentsName, "r");
+ if (fd)
+ {
+ int ch = getc(fd);
+ while (ch != EOF)
+ {
+ putc(ch, Chapters);
+ ch = getc(fd);
+ }
+ fclose(fd);
+ }
+ else
+ {
+ TexOutput("{\\i RUN TEX2RTF AGAIN FOR CONTENTS PAGE}\\par\n");
+ OnInform("Run Tex2RTF again to include contents page.");
+ }
+ }
+ }
+ break;
+ }
+ case ltVOID:
+ {
+// if (start)
+// TexOutput("{\\b void}");
+ break;
+ }
+ case ltHARDY:
+ {
+ if (start)
+ TexOutput("{\\scaps HARDY}");
+ break;
+ }
+ case ltWXCLIPS:
+ {
+ if (start)
+ TexOutput("wxCLIPS");
+ break;
+ }
+ case ltSPECIALAMPERSAND:
+ {
+ if (start)
+ {
+ if (inTabular)
+ TexOutput("\\cell ");
+ else
+ TexOutput("&");
+ }
+ break;
+ }
+ case ltSPECIALTILDE:
+ {
+ if (start)
+ {
+ if (inVerbatim)
+ TexOutput("~");
+ else
+ TexOutput(" ");
+ }
+ break;
+ }
+ case ltBACKSLASHCHAR:
+ {
+ if (start)
+ {
+ if (inTabular)
+ {
+// TexOutput("\\cell\\row\\trowd\\trgaph108\\trleft-108\n");
+ TexOutput("\\cell\\row\\trowd\\trgaph108\n");
+ int currentWidth = 0;
+ for (int i = 0; i < noColumns; i++)
+ {
+ currentWidth += TableData[i].width;
+ if (TableData[i].rightBorder)
+ TexOutput("\\clbrdrr\\brdrs\\brdrw15");
+
+ if (TableData[i].leftBorder)
+ TexOutput("\\clbrdrl\\brdrs\\brdrw15");
+
+ sprintf(buf, "\\cellx%d", currentWidth);
+ TexOutput(buf);
+ }
+ TexOutput("\\pard\\intbl\n");
+ }
+ else
+ TexOutput("\\line\n");
+ }
+ break;
+ }
+ case ltRANGLEBRA:
+ {
+ if (start)
+ TexOutput("\tab ");
+ break;
+ }
+ case ltRTFSP: // Explicit space, RTF only
+ {
+ if (start)
+ TexOutput(" ");
+ break;
+ }
+ case ltITEMIZE:
+ case ltENUMERATE:
+ case ltDESCRIPTION:
+ {
+ if (start)
+ {
+ if (indentLevel > 0)
+ {
+ TexOutput("\\par\\par\n");
+ issuedNewParagraph = 2;
+ }
+ else
+ {
+ // Top-level list: issue a new paragraph if we haven't
+ // just done so
+ if (!issuedNewParagraph)
+ {
+ TexOutput("\\par\\pard");
+ WriteEnvironmentStyles();
+ issuedNewParagraph = 1;
+ }
+ else issuedNewParagraph = 0;
+ }
+ indentLevel ++;
+ TexOutput("\\fi0\n");
+ int listType;
+ if (macroId == ltENUMERATE)
+ listType = LATEX_ENUMERATE;
+ else if (macroId == ltITEMIZE)
+ listType = LATEX_ITEMIZE;
+ else
+ listType = LATEX_DESCRIPTION;
+
+ int oldIndent = 0;
+ wxNode *node = itemizeStack.First();
+ if (node)
+ oldIndent = ((ItemizeStruc *)node->Data())->indentation;
+
+ int indentSize1 = oldIndent + 20*labelIndentTab;
+ int indentSize2 = oldIndent + 20*itemIndentTab;
+
+ ItemizeStruc *struc = new ItemizeStruc(listType, indentSize2, indentSize1);
+ itemizeStack.Insert(struc);
+
+ sprintf(buf, "\\tx%d\\tx%d\\li%d", indentSize1, indentSize2, indentSize2);
+ PushEnvironmentStyle(buf);
+ }
+ else
+ {
+ currentItemSep = 8; // Reset to the default
+ indentLevel --;
+ PopEnvironmentStyle();
+
+ if (itemizeStack.First())
+ {
+ ItemizeStruc *struc = (ItemizeStruc *)itemizeStack.First()->Data();
+ delete struc;
+ delete itemizeStack.First();
+ }
+/* Change 18/7/97 - don't know why we wish to do this
+ if (itemizeStack.Number() == 0)
+ {
+ OnMacro(ltPAR, 0, TRUE);
+ OnMacro(ltPAR, 0, FALSE);
+ issuedNewParagraph = 2;
+ }
+*/
+ }
+ break;
+ }
+ case ltTWOCOLLIST:
+ {
+ if (start)
+ {
+ indentLevel ++;
+ int oldIndent = 0;
+ wxNode *node = itemizeStack.First();
+ if (node)
+ oldIndent = ((ItemizeStruc *)node->Data())->indentation;
+
+ int indentSize = oldIndent + TwoColWidthA;
+
+ ItemizeStruc *struc = new ItemizeStruc(LATEX_TWOCOL, indentSize);
+ itemizeStack.Insert(struc);
+
+// sprintf(buf, "\\tx%d\\li%d\\ri%d", indentSize, indentSize, TwoColWidthA+TwoColWidthB+oldIndent);
+ sprintf(buf, "\\tx%d\\li%d", indentSize, indentSize);
+ PushEnvironmentStyle(buf);
+ }
+ else
+ {
+ indentLevel --;
+ PopEnvironmentStyle();
+ if (itemizeStack.First())
+ {
+ ItemizeStruc *struc = (ItemizeStruc *)itemizeStack.First()->Data();
+ delete struc;
+ delete itemizeStack.First();
+ }
+/*
+ // JACS June 1997
+ TexOutput("\\pard\n");
+ WriteEnvironmentStyles();
+*/
+/* why do we need this? */
+ if (itemizeStack.Number() == 0)
+ {
+ issuedNewParagraph = 0;
+ OnMacro(ltPAR, 0, TRUE);
+ OnMacro(ltPAR, 0, FALSE);
+ }
+ }
+ break;
+ }
+ case ltITEM:
+ {
+ wxNode *node = itemizeStack.First();
+ if (node)
+ {
+ ItemizeStruc *struc = (ItemizeStruc *)node->Data();
+ if (!start)
+ {
+ struc->currentItem += 1;
+ char indentBuf[60];
+
+ int indentSize1 = struc->labelIndentation;
+ int indentSize2 = struc->indentation;
+
+ TexOutput("\n");
+ if (struc->currentItem > 1)
+ {
+ if (currentItemSep > 0)
+ TexOutput("\\par");
+
+ TexOutput("\\par");
+// WriteEnvironmentStyles();
+ }
+
+ sprintf(buf, "\\tx%d\\tx%d\\li%d\\fi-%d\n", indentSize1, indentSize2,
+ indentSize2, 20*itemIndentTab);
+ TexOutput(buf);
+
+ switch (struc->listType)
+ {
+ case LATEX_ENUMERATE:
+ {
+ if (descriptionItemArg)
+ {
+ TexOutput("\\tab{ ");
+ TraverseChildrenFromChunk(descriptionItemArg);
+ TexOutput("}\\tab");
+ descriptionItemArg = NULL;
+ }
+ else
+ {
+ sprintf(indentBuf, "\\tab{\\b %d.}\\tab", struc->currentItem);
+ TexOutput(indentBuf);
+ }
+ break;
+ }
+ case LATEX_ITEMIZE:
+ {
+ if (descriptionItemArg)
+ {
+ TexOutput("\\tab{ ");
+ TraverseChildrenFromChunk(descriptionItemArg);
+ TexOutput("}\\tab");
+ descriptionItemArg = NULL;
+ }
+ else
+ {
+ if (bulletFile && winHelp)
+ {
+ if (winHelpVersion > 3) // Transparent bitmap
+ sprintf(indentBuf, "\\tab\\{bmct %s\\}\\tab", bulletFile);
+ else
+ sprintf(indentBuf, "\\tab\\{bmc %s\\}\\tab", bulletFile);
+ }
+ else if (winHelp)
+ sprintf(indentBuf, "\\tab{\\b o}\\tab");
+ else
+ sprintf(indentBuf, "\\tab{\\f1\\'b7}\\tab");
+ TexOutput(indentBuf);
+ }
+ break;
+ }
+ default:
+ case LATEX_DESCRIPTION:
+ {
+ if (descriptionItemArg)
+ {
+ TexOutput("\\tab{\\b ");
+ TraverseChildrenFromChunk(descriptionItemArg);
+ TexOutput("} ");
+ descriptionItemArg = NULL;
+ }
+ break;
+ }
+ }
+ }
+ }
+ break;
+ }
+ case ltTWOCOLITEM:
+ case ltTWOCOLITEMRULED:
+ {
+ wxNode *node = itemizeStack.First();
+ if (node)
+ {
+ ItemizeStruc *struc = (ItemizeStruc *)node->Data();
+ if (start)
+ {
+ struc->currentItem += 1;
+
+ int indentSize = struc->indentation;
+ int oldIndent = 0;
+ wxNode *node2 = NULL;
+ if (itemizeStack.Number() > 1) // TODO: do I actually mean Nth(0) here??
+ node2 = itemizeStack.Nth(1);
+ if (node2)
+ oldIndent = ((ItemizeStruc *)node2->Data())->indentation;
+
+ TexOutput("\n");
+ if (struc->currentItem > 1)
+ {
+ if (currentItemSep > 0)
+ TexOutput("\\par");
+
+// WriteEnvironmentStyles();
+ }
+
+// sprintf(buf, "\\tx%d\\li%d\\fi-%d\\ri%d\n", TwoColWidthA,
+// TwoColWidthA, TwoColWidthA, TwoColWidthA+TwoColWidthB+oldIndent);
+/*
+ sprintf(buf, "\\tx%d\\li%d\\fi-%d\n", TwoColWidthA,
+ TwoColWidthA, TwoColWidthA);
+*/
+ sprintf(buf, "\\tx%d\\li%d\\fi-%d\n", TwoColWidthA + oldIndent,
+ TwoColWidthA + oldIndent, TwoColWidthA);
+ TexOutput(buf);
+ }
+ }
+ break;
+ }
+ case ltVERBATIM:
+ case ltVERB:
+ {
+ if (start)
+ {
+ if (macroId == ltVERBATIM)
+ {
+ if (!issuedNewParagraph)
+ {
+ TexOutput("\\par\\pard");
+ WriteEnvironmentStyles();
+ issuedNewParagraph = 1;
+ }
+ else issuedNewParagraph = 0;
+ }
+ sprintf(buf, "{\\f3\\fs20 ");
+ TexOutput(buf);
+ }
+ else
+ {
+ TexOutput("}");
+ if (macroId == ltVERBATIM)
+ {
+ TexOutput("\\pard\n");
+// issuedNewParagraph = 1;
+ WriteEnvironmentStyles();
+ }
+ }
+ break;
+ }
+ case ltCENTERLINE:
+ case ltCENTER:
+ {
+ if (start)
+ {
+ TexOutput("\\fi0\\qc ");
+ forbidParindent ++;
+ PushEnvironmentStyle("\\qc");
+ }
+ else
+ {
+ TexOutput("\\par\\pard\n");
+ issuedNewParagraph = 1;
+ forbidParindent --;
+ PopEnvironmentStyle();
+ WriteEnvironmentStyles();
+ }
+ break;
+ }
+ case ltFLUSHLEFT:
+ {
+ if (start)
+ {
+ TexOutput("\\fi0\\ql ");
+ forbidParindent ++;
+ PushEnvironmentStyle("\\ql");
+ }
+ else
+ {
+ TexOutput("\\par\\pard\n");
+ issuedNewParagraph = 1;
+ forbidParindent --;
+ PopEnvironmentStyle();
+ WriteEnvironmentStyles();
+ }
+ break;
+ }
+ case ltFLUSHRIGHT:
+ {
+ if (start)
+ {
+ TexOutput("\\fi0\\qr ");
+ forbidParindent ++;
+ PushEnvironmentStyle("\\qr");
+ }
+ else
+ {
+ TexOutput("\\par\\pard\n");
+ issuedNewParagraph = 1;
+ forbidParindent --;
+ PopEnvironmentStyle();
+ WriteEnvironmentStyles();
+ }
+ break;
+ }
+ case ltSMALL:
+ case ltFOOTNOTESIZE:
+ {
+ if (start)
+ {
+ sprintf(buf, "{\\fs%d\n", smallFont*2);
+ TexOutput(buf);
+ }
+ else TexOutput("}\n");
+ break;
+ }
+ case ltTINY:
+ case ltSCRIPTSIZE:
+ {
+ if (start)
+ {
+ sprintf(buf, "{\\fs%d\n", tinyFont*2);
+ TexOutput(buf);
+ }
+ else TexOutput("}\n");
+ break;
+ }
+ case ltNORMALSIZE:
+ {
+ if (start)
+ {
+ sprintf(buf, "{\\fs%d\n", normalFont*2);
+ TexOutput(buf);
+ }
+ else TexOutput("}\n");
+ break;
+ }
+ case ltlarge:
+ {
+ if (start)
+ {
+ sprintf(buf, "{\\fs%d\n", largeFont1*2);
+ TexOutput(buf);
+ }
+ else TexOutput("}\n");
+ break;
+ }
+ case ltLarge:
+ {
+ if (start)
+ {
+ sprintf(buf, "{\\fs%d\n", LargeFont2*2);
+ TexOutput(buf);
+ }
+ else TexOutput("}\n");
+ break;
+ }
+ case ltLARGE:
+ {
+ if (start)
+ {
+ sprintf(buf, "{\\fs%d\n", LARGEFont3*2);
+ TexOutput(buf);
+ }
+ else TexOutput("}\n");
+ break;
+ }
+ case lthuge:
+ {
+ if (start)
+ {
+ sprintf(buf, "{\\fs%d\n", hugeFont1*2);
+ TexOutput(buf);
+ }
+ else TexOutput("}\n");
+ break;
+ }
+ case ltHuge:
+ {
+ if (start)
+ {
+ sprintf(buf, "{\\fs%d\n", HugeFont2*2);
+ TexOutput(buf);
+ }
+ else TexOutput("}\n");
+ break;
+ }
+ case ltHUGE:
+ {
+ if (start)
+ {
+ sprintf(buf, "{\\fs%d\n", HUGEFont3*2);
+ TexOutput(buf);
+ }
+ else TexOutput("}\n");
+ break;
+ }
+ case ltTEXTBF:
+ case ltBFSERIES:
+ case ltBF:
+ {
+ if (start)
+ {
+ TexOutput("{\\b ");
+ }
+ else TexOutput("}");
+ break;
+ }
+ case ltUNDERLINE:
+ {
+ if (start)
+ {
+ TexOutput("{\\ul ");
+ }
+ else TexOutput("}");
+ break;
+ }
+ case ltTEXTIT:
+ case ltITSHAPE:
+ case ltIT:
+ case ltEMPH:
+ case ltEM:
+ {
+ if (start)
+ {
+ TexOutput("{\\i ");
+ }
+ else TexOutput("}");
+ break;
+ }
+ // Roman font: do nothing. Should really switch between
+ // fonts.
+ case ltTEXTRM:
+ case ltRMFAMILY:
+ case ltRM:
+ {
+/*
+ if (start)
+ {
+ TexOutput("{\\plain ");
+ }
+ else TexOutput("}");
+ */
+ break;
+ }
+ // Medium-weight font. Unbolden...
+ case ltMDSERIES:
+ {
+ if (start)
+ {
+ TexOutput("{\\b0 ");
+ }
+ else TexOutput("}");
+ break;
+ }
+ // Upright (un-italic or slant)
+ case ltUPSHAPE:
+ {
+ if (start)
+ {
+ TexOutput("{\\i0 ");
+ }
+ else TexOutput("}");
+ break;
+ }
+ case ltTEXTSC:
+ case ltSCSHAPE:
+ case ltSC:
+ {
+ if (start)
+ {
+ TexOutput("{\\scaps ");
+ }
+ else TexOutput("}");
+ break;
+ }
+ case ltTEXTTT:
+ case ltTTFAMILY:
+ case ltTT:
+ {
+ if (start)
+ {
+ TexOutput("{\\f3 ");
+ }
+ else TexOutput("}");
+ break;
+ }
+ case ltLBRACE:
+ {
+ if (start)
+ TexOutput("\\{");
+ break;
+ }
+ case ltRBRACE:
+ {
+ if (start)
+ TexOutput("\\}");
+ break;
+ }
+ case ltBACKSLASH:
+ {
+ if (start)
+ TexOutput("\\\\");
+ break;
+ }
+ case ltPAR:
+ {
+ if (start)
+ {
+ if ( issuedNewParagraph == 0 )
+ {
+ TexOutput("\\par\\pard");
+ issuedNewParagraph ++;
+
+ // Extra par if parskip is more than zero (usually looks best.)
+ if (!inTabular && (ParSkip > 0))
+ {
+ TexOutput("\\par");
+ issuedNewParagraph ++;
+ }
+ WriteEnvironmentStyles();
+ }
+ // 1 is a whole paragraph if ParSkip == 0,
+ // half a paragraph if ParSkip > 0
+ else if ( issuedNewParagraph == 1 )
+ {
+ // Don't need a par at all if we've already had one,
+ // and ParSkip == 0.
+
+ // Extra par if parskip is more than zero (usually looks best.)
+ if (!inTabular && (ParSkip > 0))
+ {
+ TexOutput("\\par");
+ issuedNewParagraph ++;
+ }
+ WriteEnvironmentStyles();
+ }
+/*
+ if (!issuedNewParagraph || (issuedNewParagraph > 1))
+ {
+ TexOutput("\\par\\pard");
+
+ // Extra par if parskip is more than zero (usually looks best.)
+ if (!inTabular && (ParSkip > 0))
+ TexOutput("\\par");
+ WriteEnvironmentStyles();
+ }
+*/
+
+ TexOutput("\n");
+ }
+ break;
+ }
+ case ltNEWPAGE:
+ {
+ // In Windows Help, no newpages until we've started some chapters or sections
+ if (!(winHelp && !startedSections))
+ if (start)
+ TexOutput("\\page\n");
+ break;
+ }
+ case ltMAKETITLE:
+ {
+ if (start && DocumentTitle)
+ {
+ TexOutput("\\par\\pard");
+ if (!winHelp)
+ TexOutput("\\par");
+ sprintf(buf, "\\qc{\\fs%d\\b ", titleFont*2);
+ TexOutput(buf);
+ TraverseChildrenFromChunk(DocumentTitle);
+ TexOutput("}\\par\\pard\n");
+
+ if (DocumentAuthor)
+ {
+ if (!winHelp)
+ TexOutput("\\par");
+ sprintf(buf, "\\par\\qc{\\fs%d ", authorFont*2);
+ TexOutput(buf);
+ TraverseChildrenFromChunk(DocumentAuthor);
+ TexOutput("}");
+ TexOutput("\\par\\pard\n");
+ }
+ if (DocumentDate)
+ {
+ TexOutput("\\par");
+ sprintf(buf, "\\qc{\\fs%d ", authorFont*2);
+ TexOutput(buf);
+ TraverseChildrenFromChunk(DocumentDate);
+ TexOutput("}\\par\\pard\n");
+ }
+ // If linear RTF, we want this titlepage to be in a separate
+ // section with its own (blank) header and footer
+ if (!winHelp && (DocumentStyle != LATEX_ARTICLE))
+ {
+ TexOutput("{\\header }{\\footer }\n");
+ // Not sure about this: we get too many sections.
+// TexOutput("\\sect");
+ }
+ }
+ break;
+ }
+ case ltADDCONTENTSLINE:
+ {
+ if (!start)
+ {
+ if (contentsLineSection && contentsLineValue)
+ {
+ if (strcmp(contentsLineSection, "chapter") == 0)
+ {
+ fprintf(Contents, "\\par\n{\\b %s}\\par\n", contentsLineValue);
+ }
+ else if (strcmp(contentsLineSection, "section") == 0)
+ {
+ if (DocumentStyle != LATEX_ARTICLE)
+ fprintf(Contents, "\n\\tab%s\\par\n", contentsLineValue);
+ else
+ fprintf(Contents, "\\par\n{\\b %s}\\par\n", contentsLineValue);
+ }
+ }
+ }
+ break;
+ }
+ case ltHRULE:
+ {
+ if (start)
+ {
+ TexOutput("\\brdrb\\brdrs\\par\\pard\n");
+ issuedNewParagraph = 1;
+ WriteEnvironmentStyles();
+ }
+ break;
+ }
+ case ltRULE:
+ {
+ if (start)
+ {
+ TexOutput("\\brdrb\\brdrs\\par\\pard\n");
+ issuedNewParagraph = 1;
+ WriteEnvironmentStyles();
+ }
+ break;
+ }
+ case ltHLINE:
+ {
+ if (start)
+ ruleTop ++;
+ break;
+ }
+ case ltNUMBEREDBIBITEM:
+ {
+ if (start)
+ TexOutput("\\li260\\fi-260 "); // Indent from 2nd line
+ else
+ TexOutput("\\par\\pard\\par\n\n");
+ break;
+ }
+ case ltTHEPAGE:
+ {
+ if (start)
+ {
+ TexOutput("{\\field{\\*\\fldinst PAGE \\\\* MERGEFORMAT }{\\fldrslt 1}}");
+ }
+ break;
+ }
+ case ltTHECHAPTER:
+ {
+ if (start)
+ {
+// TexOutput("{\\field{\\*\\fldinst SECTION \\\\* MERGEFORMAT }{\\fldrslt 1}}");
+ sprintf(buf, "%d", chapterNo);
+ TexOutput(buf);
+ }
+ break;
+ }
+ case ltTHESECTION:
+ {
+ if (start)
+ {
+// TexOutput("{\\field{\\*\\fldinst SECTION \\\\* MERGEFORMAT }{\\fldrslt 1}}");
+ sprintf(buf, "%d", sectionNo);
+ TexOutput(buf);
+ }
+ break;
+ }
+ case ltTWOCOLUMN:
+ {
+ if (!start && !winHelp)
+ {
+ TexOutput("\\cols2\n");
+ }
+ break;
+ }
+ case ltONECOLUMN:
+ {
+ if (!start && !winHelp)
+ {
+ TexOutput("\\cols1\n");
+ }
+ break;
+ }
+ case ltPRINTINDEX:
+ {
+ if (start && useWord && !winHelp)
+ {
+ FakeCurrentSection("Index");
+ OnMacro(ltPAR, 0, TRUE);
+ OnMacro(ltPAR, 0, FALSE);
+ TexOutput("\\par{\\field{\\*\\fldinst INDEX \\\\h \"\\emdash A\\emdash \"\\\\c \"2\"}{\\fldrslt PRESS F9 TO REFORMAT INDEX}}\n");
+ }
+ break;
+ }
+ case ltLISTOFFIGURES:
+ {
+ if (start && useWord && !winHelp)
+ {
+ FakeCurrentSection(FiguresNameString, FALSE);
+ OnMacro(ltPAR, 0, TRUE);
+ OnMacro(ltPAR, 0, FALSE);
+ OnMacro(ltPAR, 0, TRUE);
+ OnMacro(ltPAR, 0, FALSE);
+ char buf[200];
+ sprintf(buf, "{\\field\\fldedit{\\*\\fldinst TOC \\\\c \"%s\" }{\\fldrslt PRESS F9 TO REFORMAT LIST OF FIGURES}}\n",
+ FigureNameString);
+ TexOutput(buf);
+ }
+ break;
+ }
+ case ltLISTOFTABLES:
+ {
+ if (start && useWord && !winHelp)
+ {
+ FakeCurrentSection(TablesNameString, FALSE);
+ OnMacro(ltPAR, 0, TRUE);
+ OnMacro(ltPAR, 0, FALSE);
+ OnMacro(ltPAR, 0, TRUE);
+ OnMacro(ltPAR, 0, FALSE);
+ char buf[200];
+ sprintf(buf, "{\\field\\fldedit{\\*\\fldinst TOC \\\\c \"%s\" }{\\fldrslt PRESS F9 TO REFORMAT LIST OF TABLES}}\n",
+ TablesNameString);
+ TexOutput(buf);
+ }
+ break;
+ }
+ // Symbols
+ case ltALPHA:
+ if (start) TexOutput("{\\f1\\'61}");
+ break;
+ case ltBETA:
+ if (start) TexOutput("{\\f1\\'62}");
+ break;
+ case ltGAMMA:
+ if (start) TexOutput("{\\f1\\'63}");
+ break;
+ case ltDELTA:
+ if (start) TexOutput("{\\f1\\'64}");
+ break;
+ case ltEPSILON:
+ case ltVAREPSILON:
+ if (start) TexOutput("{\\f1\\'65}");
+ break;
+ case ltZETA:
+ if (start) TexOutput("{\\f1\\'7A}");
+ break;
+ case ltETA:
+ if (start) TexOutput("{\\f1\\'68}");
+ break;
+ case ltTHETA:
+ case ltVARTHETA:
+ if (start) TexOutput("{\\f1\\'71}");
+ break;
+ case ltIOTA:
+ if (start) TexOutput("{\\f1\\'69}");
+ break;
+ case ltKAPPA:
+ if (start) TexOutput("{\\f1\\'6B}");
+ break;
+ case ltLAMBDA:
+ if (start) TexOutput("{\\f1\\'6C}");
+ break;
+ case ltMU:
+ if (start) TexOutput("{\\f1\\'6D}");
+ break;
+ case ltNU:
+ if (start) TexOutput("{\\f1\\'6E}");
+ break;
+ case ltXI:
+ if (start) TexOutput("{\\f1\\'78}");
+ break;
+ case ltPI:
+ if (start) TexOutput("{\\f1\\'70}");
+ break;
+ case ltVARPI:
+ if (start) TexOutput("{\\f1\\'76}");
+ break;
+ case ltRHO:
+ case ltVARRHO:
+ if (start) TexOutput("{\\f1\\'72}");
+ break;
+ case ltSIGMA:
+ if (start) TexOutput("{\\f1\\'73}");
+ break;
+ case ltVARSIGMA:
+ if (start) TexOutput("{\\f1\\'56}");
+ break;
+ case ltTAU:
+ if (start) TexOutput("{\\f1\\'74}");
+ break;
+ case ltUPSILON:
+ if (start) TexOutput("{\\f1\\'75}");
+ break;
+ case ltPHI:
+ case ltVARPHI:
+ if (start) TexOutput("{\\f1\\'66}");
+ break;
+ case ltCHI:
+ if (start) TexOutput("{\\f1\\'63}");
+ break;
+ case ltPSI:
+ if (start) TexOutput("{\\f1\\'79}");
+ break;
+ case ltOMEGA:
+ if (start) TexOutput("{\\f1\\'77}");
+ break;
+ case ltCAP_GAMMA:
+ if (start) TexOutput("{\\f1\\'47}");
+ break;
+ case ltCAP_DELTA:
+ if (start) TexOutput("{\\f1\\'44}");
+ break;
+ case ltCAP_THETA:
+ if (start) TexOutput("{\\f1\\'51}");
+ break;
+ case ltCAP_LAMBDA:
+ if (start) TexOutput("{\\f1\\'4C}");
+ break;
+ case ltCAP_XI:
+ if (start) TexOutput("{\\f1\\'58}");
+ break;
+ case ltCAP_PI:
+ if (start) TexOutput("{\\f1\\'50}");
+ break;
+ case ltCAP_SIGMA:
+ if (start) TexOutput("{\\f1\\'53}");
+ break;
+ case ltCAP_UPSILON:
+ if (start) TexOutput("{\\f1\\'54}");
+ break;
+ case ltCAP_PHI:
+ if (start) TexOutput("{\\f1\\'46}");
+ break;
+ case ltCAP_PSI:
+ if (start) TexOutput("{\\f1\\'59}");
+ break;
+ case ltCAP_OMEGA:
+ if (start) TexOutput("{\\f1\\'57}");
+ break;
+ // Binary operation symbols
+ case ltLE:
+ case ltLEQ:
+ if (start) TexOutput("{\\f1\\'A3}");
+ break;
+ case ltLL:
+ if (start) TexOutput("<<");
+ break;
+ case ltSUBSET:
+ if (start) TexOutput("{\\f1\\'CC}");
+ break;
+ case ltSUBSETEQ:
+ if (start) TexOutput("{\\f1\\'CD}");
+ break;
+ case ltIN:
+ if (start) TexOutput("{\\f1\\'CE}");
+ break;
+ case ltGE:
+ case ltGEQ:
+ if (start) TexOutput("{\\f1\\'B3}");
+ break;
+ case ltGG:
+ if (start) TexOutput(">>");
+ break;
+ case ltSUPSET:
+ if (start) TexOutput("{\\f1\\'C9}");
+ break;
+ case ltSUPSETEQ:
+ if (start) TexOutput("{\\f1\\'CD}");
+ break;
+ case ltNI:
+ if (start) TexOutput("{\\f1\\'27}");
+ break;
+ case ltPERP:
+ if (start) TexOutput("{\\f1\\'5E}");
+ break;
+ case ltNEQ:
+ if (start) TexOutput("{\\f1\\'B9}");
+ break;
+ case ltAPPROX:
+ if (start) TexOutput("{\\f1\\'BB}");
+ break;
+ case ltCONG:
+ if (start) TexOutput("{\\f1\\'40}");
+ break;
+ case ltEQUIV:
+ if (start) TexOutput("{\\f1\\'BA}");
+ break;
+ case ltPROPTO:
+ if (start) TexOutput("{\\f1\\'B5}");
+ break;
+ case ltSIM:
+ if (start) TexOutput("{\\f1\\'7E}");
+ break;
+ case ltSMILE:
+ if (start) TexOutput("{\\f4\\'4A}");
+ break;
+ case ltFROWN:
+ if (start) TexOutput("{\\f4\\'4C}");
+ break;
+ case ltMID:
+ if (start) TexOutput("|");
+ break;
+
+ // Negated relation symbols
+ case ltNOTEQ:
+ if (start) TexOutput("{\\f1\\'B9}");
+ break;
+ case ltNOTIN:
+ if (start) TexOutput("{\\f1\\'CF}");
+ break;
+ case ltNOTSUBSET:
+ if (start) TexOutput("{\\f1\\'CB}");
+ break;
+
+ // Arrows
+ case ltLEFTARROW:
+ if (start) TexOutput("{\\f1\\'AC}");
+ break;
+ case ltLEFTARROW2:
+ if (start) TexOutput("{\\f1\\'DC}");
+ break;
+ case ltRIGHTARROW:
+ if (start) TexOutput("{\\f1\\'AE}");
+ break;
+ case ltRIGHTARROW2:
+ if (start) TexOutput("{\\f1\\'DE}");
+ break;
+ case ltLEFTRIGHTARROW:
+ if (start) TexOutput("{\\f1\\'AB}");
+ break;
+ case ltLEFTRIGHTARROW2:
+ if (start) TexOutput("{\\f1\\'DB}");
+ break;
+ case ltUPARROW:
+ if (start) TexOutput("{\\f1\\'AD}");
+ break;
+ case ltUPARROW2:
+ if (start) TexOutput("{\\f1\\'DD}");
+ break;
+ case ltDOWNARROW:
+ if (start) TexOutput("{\\f1\\'AF}");
+ break;
+ case ltDOWNARROW2:
+ if (start) TexOutput("{\\f1\\'DF}");
+ break;
+
+ // Miscellaneous symbols
+ case ltALEPH:
+ if (start) TexOutput("{\\f1\\'CO}");
+ break;
+ case ltWP:
+ if (start) TexOutput("{\\f1\\'C3}");
+ break;
+ case ltRE:
+ if (start) TexOutput("{\\f1\\'C2}");
+ break;
+ case ltIM:
+ if (start) TexOutput("{\\f1\\'C1}");
+ break;
+ case ltEMPTYSET:
+ if (start) TexOutput("{\\f1\\'C6}");
+ break;
+ case ltNABLA:
+ if (start) TexOutput("{\\f1\\'D1}");
+ break;
+ case ltSURD:
+ if (start) TexOutput("{\\f1\\'D6}");
+ break;
+ case ltPARTIAL:
+ if (start) TexOutput("{\\f1\\'B6}");
+ break;
+ case ltBOT:
+ if (start) TexOutput("{\\f1\\'5E}");
+ break;
+ case ltFORALL:
+ if (start) TexOutput("{\\f1\\'22}");
+ break;
+ case ltEXISTS:
+ if (start) TexOutput("{\\f1\\'24}");
+ break;
+ case ltNEG:
+ if (start) TexOutput("{\\f1\\'D8}");
+ break;
+ case ltSHARP:
+ if (start) TexOutput("{\\f1\\'23}");
+ break;
+ case ltANGLE:
+ if (start) TexOutput("{\\f1\\'D0}");
+ break;
+ case ltTRIANGLE:
+ if (start) TexOutput("{\\f5\\'73}");
+ break;
+ case ltCLUBSUIT:
+ if (start) TexOutput("{\\f5\\'A8}");
+ break;
+ case ltDIAMONDSUIT:
+ if (start) TexOutput("{\\f5\\'A9}");
+ break;
+ case ltHEARTSUIT:
+ if (start) TexOutput("{\\f5\\'AA}");
+ break;
+ case ltSPADESUIT:
+ if (start) TexOutput("{\\f5\\'AB}");
+ break;
+ case ltINFTY:
+ if (start) TexOutput("{\\f1\\'A5}");
+ break;
+ case ltCOPYRIGHT:
+ if (start) TexOutput("{\\f0\\'A9}");
+ break;
+ case ltREGISTERED:
+ if (start) TexOutput("{\\f0\\'AE}");
+ break;
+ case ltPM:
+ if (start) TexOutput("{\\f1\\'B1}");
+ break;
+ case ltMP:
+ if (start) TexOutput("{\\f1\\'B1}");
+ break;
+ case ltTIMES:
+ if (start) TexOutput("{\\f1\\'B4}");
+ break;
+ case ltDIV:
+ if (start) TexOutput("{\\f1\\'B8}");
+ break;
+ case ltCDOT:
+ if (start) TexOutput("{\\f1\\'D7}");
+ break;
+ case ltAST:
+ if (start) TexOutput("{\\f1\\'2A}");
+ break;
+ case ltSTAR:
+ if (start) TexOutput("{\\f5\\'AB}");
+ break;
+ case ltCAP:
+ if (start) TexOutput("{\\f1\\'C7}");
+ break;
+ case ltCUP:
+ if (start) TexOutput("{\\f1\\'C8}");
+ break;
+ case ltVEE:
+ if (start) TexOutput("{\\f1\\'DA}");
+ break;
+ case ltWEDGE:
+ if (start) TexOutput("{\\f1\\'D9}");
+ break;
+ case ltCIRC:
+ if (start) TexOutput("{\\f1\\'B0}");
+ break;
+ case ltBULLET:
+ if (start) TexOutput("{\\f1\\'B7}");
+ break;
+ case ltDIAMOND:
+ if (start) TexOutput("{\\f1\\'E0}");
+ break;
+ case ltBOX:
+ if (start) TexOutput("{\\f1\\'C6}");
+ break;
+ case ltDIAMOND2:
+ if (start) TexOutput("{\\f1\\'E0}");
+ break;
+ case ltBIGTRIANGLEDOWN:
+ if (start) TexOutput("{\\f1\\'D1}");
+ break;
+ case ltOPLUS:
+ if (start) TexOutput("{\\f1\\'C5}");
+ break;
+ case ltOTIMES:
+ if (start) TexOutput("{\\f1\\'C4}");
+ break;
+ case ltSS:
+ if (start) TexOutput("{\\'DF}");
+ break;
+ case ltFIGURE:
+ {
+ if (start) inFigure = TRUE;
+ else inFigure = FALSE;
+ break;
+ }
+ case ltTABLE:
+ {
+ if (start) inTable = TRUE;
+ else inTable = FALSE;
+ break;
+ }
+ default:
+ {
+ DefaultOnMacro(macroId, no_args, start);
+ break;
+ }
+ }
+}
+
+// Called on start/end of argument examination
+bool RTFOnArgument(int macroId, int arg_no, bool start)
+{
+ char buf[300];
+ switch (macroId)
+ {
+ case ltCHAPTER:
+ case ltCHAPTERSTAR:
+ case ltCHAPTERHEADING:
+ case ltSECTION:
+ case ltSECTIONSTAR:
+ case ltSECTIONHEADING:
+ case ltSUBSECTION:
+ case ltSUBSECTIONSTAR:
+ case ltSUBSUBSECTION:
+ case ltSUBSUBSECTIONSTAR:
+ case ltGLOSS:
+ case ltMEMBERSECTION:
+ case ltFUNCTIONSECTION:
+ case ltCAPTION:
+ case ltCAPTIONSTAR:
+ {
+ if (!start && (arg_no == 1))
+ currentSection = GetArgChunk();
+ return FALSE;
+ break;
+ }
+ case ltFUNC:
+ {
+ if (start && (arg_no == 1))
+ TexOutput("\\pard\\li600\\fi-600{\\b ");
+
+ if (!start && (arg_no == 1))
+ TexOutput("} ");
+
+ if (start && (arg_no == 2))
+ {
+ if (!suppressNameDecoration) TexOutput("{\\b ");
+ currentMember = GetArgChunk();
+ }
+ if (!start && (arg_no == 2))
+ {
+ if (!suppressNameDecoration) TexOutput("}");
+ }
+
+ if (start && (arg_no == 3))
+ TexOutput("(");
+ if (!start && (arg_no == 3))
+ {
+// TexOutput(")\\li0\\fi0");
+// TexOutput(")\\par\\pard\\li0\\fi0");
+// issuedNewParagraph = 1;
+ TexOutput(")");
+ WriteEnvironmentStyles();
+ }
+ break;
+ }
+ case ltCLIPSFUNC:
+ {
+ if (start && (arg_no == 1))
+ TexOutput("\\pard\\li260\\fi-260{\\b ");
+ if (!start && (arg_no == 1))
+ TexOutput("} ");
+
+ if (start && (arg_no == 2))
+ {
+ if (!suppressNameDecoration) TexOutput("({\\b ");
+ currentMember = GetArgChunk();
+ }
+ if (!start && (arg_no == 2))
+ {
+ if (!suppressNameDecoration) TexOutput("}");
+ }
+
+ if (!start && (arg_no == 3))
+ {
+ TexOutput(")\\li0\\fi0");
+ WriteEnvironmentStyles();
+ }
+ break;
+ }
+ case ltPFUNC:
+ {
+ if (start && (arg_no == 1))
+ TexOutput("\\pard\\li260\\fi-260");
+
+ if (!start && (arg_no == 1))
+ TexOutput(" ");
+
+ if (start && (arg_no == 2))
+ TexOutput("(*");
+ if (!start && (arg_no == 2))
+ TexOutput(")");
+
+ if (start && (arg_no == 2))
+ currentMember = GetArgChunk();
+
+ if (start && (arg_no == 3))
+ TexOutput("(");
+ if (!start && (arg_no == 3))
+ {
+ TexOutput(")\\li0\\fi0");
+ WriteEnvironmentStyles();
+ }
+ break;
+ }
+ case ltPARAM:
+ {
+ if (start && (arg_no == 1))
+ TexOutput("{\\b ");
+ if (!start && (arg_no == 1))
+ TexOutput("}");
+ if (start && (arg_no == 2))
+ {
+ TexOutput("{\\i ");
+ }
+ if (!start && (arg_no == 2))
+ {
+ TexOutput("}");
+ }
+ break;
+ }
+ case ltCPARAM:
+ {
+ if (start && (arg_no == 1))
+ TexOutput("{\\b ");
+ if (!start && (arg_no == 1))
+ TexOutput("} "); // This is the difference from param - one space!
+ if (start && (arg_no == 2))
+ {
+ TexOutput("{\\i ");
+ }
+ if (!start && (arg_no == 2))
+ {
+ TexOutput("}");
+ }
+ break;
+ }
+ case ltMEMBER:
+ {
+ if (!start && (arg_no == 1))
+ TexOutput(" ");
+
+ if (start && (arg_no == 2))
+ currentMember = GetArgChunk();
+ break;
+ }
+ case ltREF:
+ {
+ if (start)
+ {
+ char *sec = NULL;
+ char *secName = NULL;
+
+ char *refName = GetArgData();
+ if (winHelp || !useWord)
+ {
+ if (refName)
+ {
+ TexRef *texRef = FindReference(refName);
+ if (texRef)
+ {
+ sec = texRef->sectionNumber;
+ secName = texRef->sectionName;
+ }
+ }
+ if (sec)
+ {
+ TexOutput(sec);
+ }
+ }
+ else
+ {
+ fprintf(Chapters, "{\\field{\\*\\fldinst REF %s \\\\* MERGEFORMAT }{\\fldrslt ??}}",
+ refName);
+ }
+ return FALSE;
+ }
+ break;
+ }
+ case ltHELPREF:
+ case ltHELPREFN:
+ {
+ if (winHelp)
+ {
+ if ((GetNoArgs() - arg_no) == 1)
+ {
+ if (start)
+ TexOutput("{\\uldb ");
+ else
+ TexOutput("}");
+ }
+ if ((GetNoArgs() - arg_no) == 0) // Arg = 2, or 3 if first is optional
+ {
+ if (start)
+ {
+ TexOutput("{\\v ");
+
+ // Remove green colour/underlining if specified
+ if (!hotSpotUnderline && !hotSpotColour)
+ TexOutput("%");
+ else if (!hotSpotColour)
+ TexOutput("*");
+ }
+ else TexOutput("}");
+ }
+ }
+ else // If a linear document, must resolve the references ourselves
+ {
+ if ((GetNoArgs() - arg_no) == 1)
+ {
+ // In a linear document we display the anchor text in italic plus
+ // the page number.
+ if (start)
+ TexOutput("{\\i ");
+ else
+ TexOutput("}");
+ return TRUE;
+ }
+ else if ((GetNoArgs() - arg_no) == 0) // Arg = 2, or 3 if first is optional
+ {
+ if (macroId != ltHELPREFN)
+ {
+ if (start)
+ {
+ TexOutput(" (");
+ char *refName = GetArgData();
+ if (refName)
+ {
+ if (useWord)
+ {
+ char *s = GetArgData();
+ TexOutput("p. ");
+ TexOutput("{\\field{\\*\\fldinst PAGEREF ");
+ TexOutput(refName);
+ TexOutput(" \\\\* MERGEFORMAT }{\\fldrslt ??}}");
+ }
+ else
+ {
+ // Only print section name if we're not in Word mode,
+ // so can't do page references
+ TexRef *texRef = FindReference(refName);
+ if (texRef)
+ {
+ TexOutput(texRef->sectionName) ; TexOutput(" "); TexOutput(texRef->sectionNumber);
+ }
+ else
+ {
+ TexOutput("??");
+ sprintf(buf, "Warning: unresolved reference %s.", refName);
+ OnInform(buf);
+ }
+ }
+ }
+ else TexOutput("??");
+ }
+ else TexOutput(")");
+ }
+ return FALSE;
+ }
+ }
+ break;
+ }
+ case ltURLREF:
+ {
+ if (arg_no == 1)
+ {
+ return TRUE;
+ }
+ else if (arg_no == 2)
+ {
+ if (start)
+ {
+ inVerbatim = TRUE;
+ TexOutput(" ({\\f3 ");
+ }
+ else
+ {
+ TexOutput("})");
+ inVerbatim = FALSE;
+ }
+ return TRUE;
+ }
+ break;
+ }
+ case ltPOPREF:
+ {
+ if (winHelp)
+ {
+ if ((GetNoArgs() - arg_no) == 1)
+ {
+ if (start)
+ TexOutput("{\\ul ");
+ else
+ TexOutput("}");
+ }
+ if ((GetNoArgs() - arg_no) == 0) // Arg = 2, or 3 if first is optional
+ {
+ if (start)
+ {
+ TexOutput("{\\v ");
+
+ // Remove green colour/underlining if specified
+ if (!hotSpotUnderline && !hotSpotColour)
+ TexOutput("%");
+ else if (!hotSpotColour)
+ TexOutput("*");
+ }
+ else TexOutput("}");
+ }
+ }
+ else // A linear document...
+ {
+ if ((GetNoArgs() - arg_no) == 1)
+ {
+ // In a linear document we just display the anchor text in italic
+ if (start)
+ TexOutput("{\\i ");
+ else
+ TexOutput("}");
+ return TRUE;
+ }
+ else return FALSE;
+ }
+ break;
+ }
+ case ltADDCONTENTSLINE:
+ {
+ if (start && !winHelp)
+ {
+ if (arg_no == 2)
+ contentsLineSection = copystring(GetArgData());
+ else if (arg_no == 3)
+ contentsLineValue = copystring(GetArgData());
+ return FALSE;
+ }
+ else return FALSE;
+ break;
+ }
+ case ltIMAGE:
+ case ltIMAGEL:
+ case ltIMAGER:
+ case ltIMAGEMAP:
+ case ltPSBOXTO:
+ {
+ if (arg_no == 3)
+ return FALSE;
+
+ static int imageWidth = 0;
+ static int imageHeight = 0;
+
+ if (start && (arg_no == 1))
+ {
+ char *imageDimensions = copystring(GetArgData());
+ char buf1[50];
+ strcpy(buf1, imageDimensions);
+ char *tok1 = strtok(buf1, ";:");
+ char *tok2 = strtok(NULL, ";:");
+ // Convert points to TWIPS (1 twip = 1/20th of point)
+ imageWidth = (int)(20*(tok1 ? ParseUnitArgument(tok1) : 0));
+ imageHeight = (int)(20*(tok2 ? ParseUnitArgument(tok2) : 0));
+ return FALSE;
+ }
+ else if (start && (arg_no == 2 ))
+ {
+ char *filename = copystring(GetArgData());
+ wxString f = "";
+ if ((winHelp || (strcmp(bitmapMethod, "includepicture") == 0) || (strcmp(bitmapMethod, "import") == 0)) && useWord)
+ {
+ if (f == "") // Try for a .shg (segmented hypergraphics file)
+ {
+ strcpy(buf, filename);
+ StripExtension(buf);
+ strcat(buf, ".shg");
+ f = TexPathList.FindValidPath(buf);
+ }
+ if (f == "") // Try for a .bmp
+ {
+ strcpy(buf, filename);
+ StripExtension(buf);
+ strcat(buf, ".bmp");
+ f = TexPathList.FindValidPath(buf);
+ }
+ if (f == "") // Try for a metafile instead
+ {
+ strcpy(buf, filename);
+ StripExtension(buf);
+ strcat(buf, ".wmf");
+ f = TexPathList.FindValidPath(buf);
+ }
+ if (f != "")
+ {
+ if (winHelp)
+ {
+ if (bitmapTransparency && (winHelpVersion > 3))
+ TexOutput("\\{bmct ");
+ else
+ TexOutput("\\{bmc ");
+ wxString str = wxFileNameFromPath(f);
+ TexOutput((char*) (const char*) str);
+ TexOutput("\\}");
+ }
+ else
+ {
+ // Microsoft Word method
+ if (strcmp(bitmapMethod, "import") == 0)
+ TexOutput("{\\field{\\*\\fldinst IMPORT ");
+ else
+ TexOutput("{\\field{\\*\\fldinst INCLUDEPICTURE ");
+
+ // Full path appears not to be valid!
+ wxString str = wxFileNameFromPath(f);
+ TexOutput((char*)(const char*) str);
+/*
+ int len = strlen(f);
+ char smallBuf[2]; smallBuf[1] = 0;
+ for (int i = 0; i < len; i++)
+ {
+ smallBuf[0] = f[i];
+ TexOutput(smallBuf);
+ if (smallBuf[0] == '\\')
+ TexOutput(smallBuf);
+ }
+*/
+ TexOutput("}{\\fldrslt PRESS F9 TO FORMAT PICTURE}}");
+ }
+ }
+ else
+ {
+ TexOutput("[No BMP or WMF for image file ");
+ TexOutput(filename);
+ TexOutput("]");
+ sprintf(buf, "Warning: could not find a BMP or WMF equivalent for %s.", filename);
+ OnInform(buf);
+ }
+ }
+ else // linear RTF
+ {
+ if (f == "") // Try for a .bmp
+ {
+ strcpy(buf, filename);
+ StripExtension(buf);
+ strcat(buf, ".bmp");
+ f = TexPathList.FindValidPath(buf);
+ }
+ if (f != "")
+ {
+ FILE *fd = fopen(f, "rb");
+ if (OutputBitmapHeader(fd, winHelp))
+ OutputBitmapData(fd);
+ else
+ {
+ sprintf(buf, "Could not read bitmap %s.\nMay be in wrong format (needs RGB-encoded Windows BMP).", (const char*) f);
+ OnError(buf);
+ }
+ fclose(fd);
+ }
+ else // Try for a metafile instead
+ {
+#ifdef __WXMSW__
+ strcpy(buf, filename);
+ StripExtension(buf);
+ strcat(buf, ".wmf");
+ f = TexPathList.FindValidPath(buf);
+ if (f != "")
+ {
+ // HFILE handle = _lopen(f, READ);
+ FILE *fd = fopen(f, "rb");
+ if (OutputMetafileHeader(fd, winHelp, imageWidth, imageHeight))
+ {
+ OutputMetafileData(fd);
+ }
+ else
+ {
+ sprintf(buf, "Could not read metafile %s. Perhaps it's not a placeable metafile?", f);
+ OnError(buf);
+ }
+ fclose(fd);
+ }
+ else
+ {
+#endif
+ TexOutput("[No BMP or WMF for image file ");
+ TexOutput(filename);
+ TexOutput("]");
+ sprintf(buf, "Warning: could not find a BMP or WMF equivalent for %s.", filename);
+ OnInform(buf);
+#ifdef __WXMSW__
+ }
+#endif
+ }
+ }
+ return FALSE;
+ }
+ else
+ return FALSE;
+ break;
+ }
+ case ltTABULAR:
+ case ltSUPERTABULAR:
+ {
+ if (arg_no == 1)
+ {
+ if (start)
+ {
+ currentRowNumber = 0;
+ inTabular = TRUE;
+ startRows = TRUE;
+ tableVerticalLineLeft = FALSE;
+ tableVerticalLineRight = FALSE;
+ int currentWidth = 0;
+
+ char *alignString = copystring(GetArgData());
+ ParseTableArgument(alignString);
+
+// TexOutput("\\trowd\\trgaph108\\trleft-108");
+ TexOutput("\\trowd\\trgaph108");
+
+ // Write the first row formatting for compatibility
+ // with standard Latex
+ if (compatibilityMode)
+ {
+ for (int i = 0; i < noColumns; i++)
+ {
+ currentWidth += TableData[i].width;
+ sprintf(buf, "\\cellx%d", currentWidth);
+ TexOutput(buf);
+ }
+ TexOutput("\\pard\\intbl\n");
+ }
+ delete[] alignString;
+
+ return FALSE;
+ }
+ }
+ else if (arg_no == 2 && !start)
+ {
+ TexOutput("\\pard\n");
+ WriteEnvironmentStyles();
+ inTabular = FALSE;
+ }
+ break;
+ }
+
+ case ltQUOTE:
+ case ltVERSE:
+ {
+ if (start)
+ {
+ TexOutput("\\li360\n");
+ forbidParindent ++;
+ PushEnvironmentStyle("\\li360");
+ }
+ else
+ {
+ forbidParindent --;
+ PopEnvironmentStyle();
+ OnMacro(ltPAR, 0, TRUE);
+ OnMacro(ltPAR, 0, FALSE);
+ }
+ break;
+ }
+ case ltQUOTATION:
+ {
+ if (start)
+ {
+ TexOutput("\\li360\n");
+ PushEnvironmentStyle("\\li360");
+ }
+ else
+ {
+ PopEnvironmentStyle();
+ OnMacro(ltPAR, 0, TRUE);
+ OnMacro(ltPAR, 0, FALSE);
+ }
+ break;
+ }
+ case ltBOXIT:
+ case ltFRAMEBOX:
+ case ltFBOX:
+ case ltNORMALBOX:
+ case ltNORMALBOXD:
+ {
+ if (start)
+ {
+ sprintf(buf, "\\box\\trgaph108%s\n", ((macroId == ltNORMALBOXD) ? "\\brdrdb" : "\\brdrs"));
+ TexOutput(buf);
+ PushEnvironmentStyle(buf);
+ }
+ else
+ {
+ PopEnvironmentStyle();
+ OnMacro(ltPAR, 0, TRUE);
+ OnMacro(ltPAR, 0, FALSE);
+ }
+ break;
+ }
+ case ltHELPFONTSIZE:
+ {
+ if (start)
+ {
+ char *data = GetArgData();
+ if (strcmp(data, "10") == 0)
+ SetFontSizes(10);
+ else if (strcmp(data, "11") == 0)
+ SetFontSizes(11);
+ else if (strcmp(data, "12") == 0)
+ SetFontSizes(12);
+ sprintf(buf, "\\fs%d\n", normalFont*2);
+ TexOutput(buf);
+ TexOutput(buf);
+ return FALSE;
+ }
+ break;
+ }
+ case ltHELPFONTFAMILY:
+ {
+ if (start)
+ {
+ char *data = GetArgData();
+ if (strcmp(data, "Swiss") == 0)
+ TexOutput("\\f2\n");
+ else if (strcmp(data, "Symbol") == 0)
+ TexOutput("\\f1\n");
+ else if (strcmp(data, "Times") == 0)
+ TexOutput("\\f0\n");
+
+ return FALSE;
+ }
+ break;
+ }
+ case ltPARINDENT:
+ {
+ if (start && arg_no == 1)
+ {
+ char *data = GetArgData();
+ ParIndent = ParseUnitArgument(data);
+ if (ParIndent == 0 || forbidParindent == 0)
+ {
+ sprintf(buf, "\\fi%d\n", ParIndent*20);
+ TexOutput(buf);
+ }
+ return FALSE;
+ }
+ break;
+ }
+ case ltITEM:
+ {
+ if (start && IsArgOptional())
+ {
+ descriptionItemArg = GetArgChunk();
+ return FALSE;
+ }
+ break;
+ }
+ case ltTWOCOLITEM:
+ case ltTWOCOLITEMRULED:
+ {
+ switch (arg_no)
+ {
+ case 1:
+ {
+ if (!start)
+ TexOutput("\\tab ");
+ break;
+ }
+ case 2:
+ {
+ if (!start)
+ {
+ if (macroId == ltTWOCOLITEMRULED)
+ TexOutput("\\brdrb\\brdrs\\brdrw15\\brsp20 ");
+ TexOutput("\\par\\pard\n");
+ issuedNewParagraph = 1;
+ WriteEnvironmentStyles();
+ }
+ break;
+ }
+ }
+ return TRUE;
+ break;
+ }
+ /*
+ * Accents
+ *
+ */
+ case ltACCENT_GRAVE:
+ {
+ if (start)
+ {
+ char *val = GetArgData();
+ if (val)
+ {
+ switch (val[0])
+ {
+ case 'a':
+ TexOutput("\\'e0");
+ break;
+ case 'e':
+ TexOutput("\\'e8");
+ break;
+ case 'i':
+ TexOutput("\\'ec");
+ break;
+ case 'o':
+ TexOutput("\\'f2");
+ break;
+ case 'u':
+ TexOutput("\\'f9");
+ break;
+ case 'A':
+ TexOutput("\\'c0");
+ break;
+ case 'E':
+ TexOutput("\\'c8");
+ break;
+ case 'I':
+ TexOutput("\\'cc");
+ break;
+ case 'O':
+ TexOutput("\\'d2");
+ break;
+ case 'U':
+ TexOutput("\\'d9");
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ return FALSE;
+ break;
+ }
+ case ltACCENT_ACUTE:
+ {
+ if (start)
+ {
+ char *val = GetArgData();
+ if (val)
+ {
+ switch (val[0])
+ {
+ case 'a':
+ TexOutput("\\'e1");
+ break;
+ case 'e':
+ TexOutput("\\'e9");
+ break;
+ case 'i':
+ TexOutput("\\'ed");
+ break;
+ case 'o':
+ TexOutput("\\'f3");
+ break;
+ case 'u':
+ TexOutput("\\'fa");
+ break;
+ case 'y':
+ TexOutput("\\'fd");
+ break;
+ case 'A':
+ TexOutput("\\'c1");
+ break;
+ case 'E':
+ TexOutput("\\'c9");
+ break;
+ case 'I':
+ TexOutput("\\'cd");
+ break;
+ case 'O':
+ TexOutput("\\'d3");
+ break;
+ case 'U':
+ TexOutput("\\'da");
+ break;
+ case 'Y':
+ TexOutput("\\'dd");
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ return FALSE;
+ break;
+ }
+ case ltACCENT_CARET:
+ {
+ if (start)
+ {
+ char *val = GetArgData();
+ if (val)
+ {
+ switch (val[0])
+ {
+ case 'a':
+ TexOutput("\\'e2");
+ break;
+ case 'e':
+ TexOutput("\\'ea");
+ break;
+ case 'i':
+ TexOutput("\\'ee");
+ break;
+ case 'o':
+ TexOutput("\\'f4");
+ break;
+ case 'u':
+ TexOutput("\\'fb");
+ break;
+ case 'A':
+ TexOutput("\\'c2");
+ break;
+ case 'E':
+ TexOutput("\\'ca");
+ break;
+ case 'I':
+ TexOutput("\\'ce");
+ break;
+ case 'O':
+ TexOutput("\\'d4");
+ break;
+ case 'U':
+ TexOutput("\\'db");
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ return FALSE;
+ break;
+ }
+ case ltACCENT_TILDE:
+ {
+ if (start)
+ {
+ char *val = GetArgData();
+ if (val)
+ {
+ switch (val[0])
+ {
+ case 'a':
+ TexOutput("\\'e3");
+ break;
+ case ' ':
+ TexOutput("~");
+ break;
+ case 'n':
+ TexOutput("\\'f1");
+ break;
+ case 'o':
+ TexOutput("\\'f5");
+ break;
+ case 'A':
+ TexOutput("\\'c3");
+ break;
+ case 'N':
+ TexOutput("\\'d1");
+ break;
+ case 'O':
+ TexOutput("\\'d5");
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ return FALSE;
+ break;
+ }
+ case ltACCENT_UMLAUT:
+ {
+ if (start)
+ {
+ char *val = GetArgData();
+ if (val)
+ {
+ switch (val[0])
+ {
+ case 'a':
+ TexOutput("\\'e4");
+ break;
+ case 'e':
+ TexOutput("\\'eb");
+ break;
+ case 'i':
+ TexOutput("\\'ef");
+ break;
+ case 'o':
+ TexOutput("\\'f6");
+ break;
+ case 'u':
+ TexOutput("\\'fc");
+ break;
+ case 's':
+ TexOutput("\\'df");
+ break;
+ case 'y':
+ TexOutput("\\'ff");
+ break;
+ case 'A':
+ TexOutput("\\'c4");
+ break;
+ case 'E':
+ TexOutput("\\'cb");
+ break;
+ case 'I':
+ TexOutput("\\'cf");
+ break;
+ case 'O':
+ TexOutput("\\'d6");
+ break;
+ case 'U':
+ TexOutput("\\'dc");
+ break;
+ case 'Y':
+ TexOutput("\\'df");
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ return FALSE;
+ break;
+ }
+ case ltACCENT_DOT:
+ {
+ if (start)
+ {
+ char *val = GetArgData();
+ if (val)
+ {
+ switch (val[0])
+ {
+ case 'a':
+ TexOutput("\\'e5");
+ break;
+ case 'A':
+ TexOutput("\\'c5");
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ return FALSE;
+ break;
+ }
+ case ltACCENT_CADILLA:
+ {
+ if (start)
+ {
+ char *val = GetArgData();
+ if (val)
+ {
+ switch (val[0])
+ {
+ case 'c':
+ TexOutput("\\'e7");
+ break;
+ case 'C':
+ TexOutput("\\'c7");
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ return FALSE;
+ break;
+ }
+ case ltFOOTNOTE:
+ {
+ static char *helpTopic = NULL;
+ static FILE *savedOutput = NULL;
+ if (winHelp)
+ {
+ if (arg_no == 1)
+ {
+ if (start)
+ {
+ OnInform("Consider using \\footnotepopup instead of \\footnote.");
+ footnoteCount ++;
+ char footBuf[20];
+ sprintf(footBuf, "(%d)", footnoteCount);
+
+ TexOutput(" {\\ul ");
+ TexOutput(footBuf);
+ TexOutput("}");
+ helpTopic = FindTopicName(NULL);
+ TexOutput("{\\v ");
+
+ // Remove green colour/underlining if specified
+ if (!hotSpotUnderline && !hotSpotColour)
+ TexOutput("%");
+ else if (!hotSpotColour)
+ TexOutput("*");
+
+ TexOutput(helpTopic);
+ TexOutput("}");
+
+ fprintf(Popups, "\\page\n");
+// fprintf(Popups, "\n${\\footnote }"); // No title
+ fprintf(Popups, "\n#{\\footnote %s}\n", helpTopic);
+ fprintf(Popups, "+{\\footnote %s}\n", GetBrowseString());
+ savedOutput = CurrentOutput1;
+ SetCurrentOutput(Popups);
+ }
+ else
+ {
+ SetCurrentOutput(savedOutput);
+ }
+ return TRUE;
+ }
+ return TRUE;
+ }
+ else
+ {
+ if (start)
+ {
+ TexOutput(" {\\super \\chftn{\\footnote \\fs20 {\\super \\chftn}", TRUE);
+ }
+ else
+ {
+ TexOutput("}}", TRUE);
+ }
+ return TRUE;
+ }
+ break;
+ }
+ case ltFOOTNOTEPOPUP:
+ {
+ static char *helpTopic = NULL;
+ static FILE *savedOutput = NULL;
+ if (winHelp)
+ {
+ if (arg_no == 1)
+ {
+ if (start)
+ {
+ TexOutput("{\\ul ");
+ }
+ else TexOutput("}");
+ return TRUE;
+ }
+ else if (arg_no == 2)
+ {
+ if (start)
+ {
+ helpTopic = FindTopicName(NULL);
+ TexOutput("{\\v ");
+
+ // Remove green colour/underlining if specified
+ if (!hotSpotUnderline && !hotSpotColour)
+ TexOutput("%");
+ else if (!hotSpotColour)
+ TexOutput("*");
+
+ TexOutput(helpTopic);
+ TexOutput("}");
+
+ fprintf(Popups, "\\page\n");
+// fprintf(Popups, "\n${\\footnote }"); // No title
+ fprintf(Popups, "\n#{\\footnote %s}\n", helpTopic);
+ fprintf(Popups, "+{\\footnote %s}\n", GetBrowseString());
+ savedOutput = CurrentOutput1;
+ SetCurrentOutput(Popups);
+ }
+ else
+ {
+ SetCurrentOutput(savedOutput);
+ }
+ return TRUE;
+ }
+ }
+ else
+ {
+ if (arg_no == 1)
+ return TRUE;
+ if (start)
+ {
+ TexOutput(" {\\super \\chftn{\\footnote \\fs20 {\\super \\chftn}", TRUE);
+ }
+ else
+ {
+ TexOutput("}}", TRUE);
+ }
+ return TRUE;
+ }
+ break;
+ }
+ case ltFANCYPLAIN:
+ {
+ if (start && (arg_no == 1))
+ return FALSE;
+ else
+ return TRUE;
+ break;
+ }
+ case ltSETHEADER:
+ {
+ if (start)
+ forbidResetPar ++;
+ else
+ forbidResetPar --;
+
+ if (winHelp) return FALSE;
+ if (start)
+ {
+ switch (arg_no)
+ {
+ case 1:
+ LeftHeaderEven = GetArgChunk();
+ if (strlen(GetArgData(LeftHeaderEven)) == 0)
+ LeftHeaderEven = NULL;
+ break;
+ case 2:
+ CentreHeaderEven = GetArgChunk();
+ if (strlen(GetArgData(CentreHeaderEven)) == 0)
+ CentreHeaderEven = NULL;
+ break;
+ case 3:
+ RightHeaderEven = GetArgChunk();
+ if (strlen(GetArgData(RightHeaderEven)) == 0)
+ RightHeaderEven = NULL;
+ break;
+ case 4:
+ LeftHeaderOdd = GetArgChunk();
+ if (strlen(GetArgData(LeftHeaderOdd)) == 0)
+ LeftHeaderOdd = NULL;
+ break;
+ case 5:
+ CentreHeaderOdd = GetArgChunk();
+ if (strlen(GetArgData(CentreHeaderOdd)) == 0)
+ CentreHeaderOdd = NULL;
+ break;
+ case 6:
+ RightHeaderOdd = GetArgChunk();
+ if (strlen(GetArgData(RightHeaderOdd)) == 0)
+ RightHeaderOdd = NULL;
+ OutputRTFHeaderCommands();
+ break;
+ default:
+ break;
+ }
+ }
+ return FALSE;
+ break;
+ }
+ case ltSETFOOTER:
+ {
+ if (start)
+ forbidResetPar ++;
+ else
+ forbidResetPar --;
+
+ if (winHelp) return FALSE;
+ if (start)
+ {
+ switch (arg_no)
+ {
+ case 1:
+ LeftFooterEven = GetArgChunk();
+ if (strlen(GetArgData(LeftFooterEven)) == 0)
+ LeftFooterEven = NULL;
+ break;
+ case 2:
+ CentreFooterEven = GetArgChunk();
+ if (strlen(GetArgData(CentreFooterEven)) == 0)
+ CentreFooterEven = NULL;
+ break;
+ case 3:
+ RightFooterEven = GetArgChunk();
+ if (strlen(GetArgData(RightFooterEven)) == 0)
+ RightFooterEven = NULL;
+ break;
+ case 4:
+ LeftFooterOdd = GetArgChunk();
+ if (strlen(GetArgData(LeftFooterOdd)) == 0)
+ LeftFooterOdd = NULL;
+ break;
+ case 5:
+ CentreFooterOdd = GetArgChunk();
+ if (strlen(GetArgData(CentreFooterOdd)) == 0)
+ CentreFooterOdd = NULL;
+ break;
+ case 6:
+ RightFooterOdd = GetArgChunk();
+ if (strlen(GetArgData(RightFooterOdd)) == 0)
+ RightFooterOdd = NULL;
+ OutputRTFFooterCommands();
+ break;
+ default:
+ break;
+ }
+ }
+ return FALSE;
+ break;
+ }
+ case ltMARKRIGHT:
+ {
+ if (winHelp) return FALSE;
+ // Fake a SetHeader command
+ if (start)
+ {
+ LeftHeaderOdd = NULL;
+ CentreHeaderOdd = NULL;
+ RightHeaderOdd = NULL;
+ LeftHeaderEven = NULL;
+ CentreHeaderEven = NULL;
+ RightHeaderEven = NULL;
+ OnInform("Consider using setheader/setfooter rather than markright.");
+ }
+ RTFOnArgument(ltSETHEADER, 4, start);
+ if (!start)
+ OutputRTFHeaderCommands();
+ return FALSE;
+ break;
+ }
+ case ltMARKBOTH:
+ {
+ if (winHelp) return FALSE;
+ // Fake a SetHeader command
+ switch (arg_no)
+ {
+ case 1:
+ {
+ if (start)
+ {
+ LeftHeaderOdd = NULL;
+ CentreHeaderOdd = NULL;
+ RightHeaderOdd = NULL;
+ LeftHeaderEven = NULL;
+ CentreHeaderEven = NULL;
+ RightHeaderEven = NULL;
+ OnInform("Consider using setheader/setfooter rather than markboth.");
+ }
+ return RTFOnArgument(ltSETHEADER, 1, start);
+ break;
+ }
+ case 2:
+ {
+ RTFOnArgument(ltSETHEADER, 4, start);
+ if (!start)
+ OutputRTFHeaderCommands();
+ return FALSE;
+ break;
+ }
+ }
+ break;
+ }
+ case ltPAGENUMBERING:
+ {
+ if (start)
+ forbidResetPar ++;
+ else
+ forbidResetPar --;
+
+ if (winHelp) return FALSE;
+ if (start)
+ {
+ TexOutput("\\pgnrestart");
+ char *data = GetArgData();
+ if (currentNumberStyle) delete[] currentNumberStyle;
+ currentNumberStyle = copystring(data);
+ OutputNumberStyle(currentNumberStyle);
+
+ TexOutput("\n");
+ }
+ return FALSE;
+ break;
+ }
+ case ltTWOCOLUMN:
+ {
+ if (winHelp) return FALSE;
+ if (start)
+ return TRUE;
+ break;
+ }
+ case ltITEMSEP:
+ {
+ if (start)
+ {
+ char *val = GetArgData();
+ currentItemSep = ParseUnitArgument(val);
+ return FALSE;
+ }
+ break;
+ }
+ case ltEVENSIDEMARGIN:
+ {
+ return FALSE;
+ break;
+ }
+ case ltODDSIDEMARGIN:
+ {
+ if (start)
+ {
+ char *val = GetArgData();
+ int twips = (int)(20*ParseUnitArgument(val));
+ // Add an inch since in LaTeX it's specified minus an inch
+ twips += 1440;
+ CurrentLeftMarginOdd = twips;
+ sprintf(buf, "\\margl%d\n", twips);
+ TexOutput(buf);
+
+ CurrentMarginParX = CurrentLeftMarginOdd + CurrentTextWidth + CurrentMarginParSep;
+ }
+ return FALSE;
+ }
+ case ltMARGINPARWIDTH:
+ {
+ if (start)
+ {
+ char *val = GetArgData();
+ int twips = (int)(20*ParseUnitArgument(val));
+ CurrentMarginParWidth = twips;
+ }
+ return FALSE;
+ }
+ case ltMARGINPARSEP:
+ {
+ if (start)
+ {
+ char *val = GetArgData();
+ int twips = (int)(20*ParseUnitArgument(val));
+ CurrentMarginParSep = twips;
+ CurrentMarginParX = CurrentLeftMarginOdd + CurrentTextWidth + CurrentMarginParSep;
+ }
+ return FALSE;
+ }
+ case ltTEXTWIDTH:
+ {
+ if (start)
+ {
+ char *val = GetArgData();
+ int twips = (int)(20*ParseUnitArgument(val));
+ CurrentTextWidth = twips;
+
+ // Need to set an implicit right margin
+ CurrentRightMarginOdd = PageWidth - CurrentTextWidth - CurrentLeftMarginOdd;
+ CurrentRightMarginEven = PageWidth - CurrentTextWidth - CurrentLeftMarginEven;
+ CurrentMarginParX = CurrentLeftMarginOdd + CurrentTextWidth + CurrentMarginParSep;
+ sprintf(buf, "\\margr%d\n", CurrentRightMarginOdd);
+ TexOutput(buf);
+ }
+ return FALSE;
+ }
+ case ltMARGINPAR:
+ case ltMARGINPARODD:
+ {
+ if (start)
+ {
+ if (winHelp)
+ {
+ TexOutput("\\box\n");
+ PushEnvironmentStyle("\\box");
+ }
+ else
+ {
+ sprintf(buf, "\\phpg\\posx%d\\absw%d\n", CurrentMarginParX, CurrentMarginParWidth);
+ TexOutput(buf);
+ }
+ return TRUE;
+ }
+ else
+ {
+ if (winHelp)
+ {
+ TexOutput("\\par\\pard\n");
+ PopEnvironmentStyle();
+ WriteEnvironmentStyles();
+ }
+ else
+ TexOutput("\\par\\pard\n");
+ issuedNewParagraph = 1;
+ }
+ return FALSE;
+ }
+ case ltMARGINPAREVEN:
+ {
+ if (start)
+ {
+ if (winHelp)
+ {
+ TexOutput("\\box\n");
+ PushEnvironmentStyle("\\box");
+ }
+ else
+ {
+ if (mirrorMargins)
+ {
+ // Have to calculate what the margins are changed to in WfW margin
+ // mirror mode, on an even (left-hand) page.
+ int x = PageWidth - CurrentRightMarginOdd - CurrentMarginParWidth - CurrentMarginParSep
+ - CurrentTextWidth + GutterWidth;
+ sprintf(buf, "\\phpg\\posx%d\\absw%d\n", x, CurrentMarginParWidth);
+ TexOutput(buf);
+ }
+ else
+ {
+ sprintf(buf, "\\phpg\\posx%d\\absw%d\n", CurrentMarginParX, CurrentMarginParWidth);
+ TexOutput(buf);
+ }
+ }
+ return TRUE;
+ }
+ else
+ {
+ if (winHelp)
+ {
+ TexOutput("\\par\\pard\n");
+ PopEnvironmentStyle();
+ WriteEnvironmentStyles();
+ }
+ else
+ issuedNewParagraph = 1;
+ TexOutput("\\par\\pard\n");
+ }
+ return FALSE;
+ }
+ case ltTWOCOLWIDTHA:
+ {
+ if (start)
+ {
+ char *val = GetArgData();
+ int twips = (int)(20*ParseUnitArgument(val));
+ TwoColWidthA = twips;
+ }
+ return FALSE;
+ break;
+ }
+ case ltTWOCOLWIDTHB:
+ {
+ if (start)
+ {
+ char *val = GetArgData();
+ int twips = (int)(20*ParseUnitArgument(val));
+ TwoColWidthB = twips;
+ }
+ return FALSE;
+ break;
+ }
+ case ltROW:
+ case ltRULEDROW:
+ {
+ if (start)
+ {
+ int currentWidth = 0;
+
+ if (!compatibilityMode || (currentRowNumber > 0))
+ {
+ TexOutput("\\pard\\intbl");
+
+ if (macroId == ltRULEDROW)
+ ruleBottom = 1;
+ for (int i = 0; i < noColumns; i++)
+ {
+ currentWidth += TableData[i].width;
+ if (ruleTop == 1)
+ {
+ TexOutput("\\clbrdrt\\brdrs\\brdrw15");
+ }
+ else if (ruleTop > 1)
+ {
+ TexOutput("\\clbrdrt\\brdrdb\\brdrw15");
+ }
+ if (ruleBottom == 1)
+ {
+ TexOutput("\\clbrdrb\\brdrs\\brdrw15");
+ }
+ else if (ruleBottom > 1)
+ {
+ TexOutput("\\clbrdrb\\brdrdb\\brdrw15");
+ }
+
+ if (TableData[i].rightBorder)
+ TexOutput("\\clbrdrr\\brdrs\\brdrw15");
+
+ if (TableData[i].leftBorder)
+ TexOutput("\\clbrdrl\\brdrs\\brdrw15");
+
+ sprintf(buf, "\\cellx%d", currentWidth);
+ TexOutput(buf);
+ }
+ TexOutput("\\pard\\intbl\n");
+ }
+ ruleTop = 0;
+ ruleBottom = 0;
+ currentRowNumber ++;
+ return TRUE;
+ }
+ else
+ {
+// TexOutput("\\cell\\row\\trowd\\trgaph108\\trleft-108\n");
+ TexOutput("\\cell\\row\\trowd\\trgaph108\n");
+ }
+ break;
+ }
+ case ltMULTICOLUMN:
+ {
+ static int noMultiColumns = 0;
+ if (start)
+ {
+ switch (arg_no)
+ {
+ case 1:
+ {
+ noMultiColumns = atoi(GetArgData());
+ return FALSE;
+ break;
+ }
+ case 2:
+ {
+ return FALSE;
+ }
+ case 3:
+ {
+ return TRUE;
+ }
+ }
+ }
+ else
+ {
+ if (arg_no == 3)
+ {
+ for (int i = 1; i < noMultiColumns; i ++)
+ TexOutput("\\cell");
+ }
+ }
+ break;
+ }
+ case ltINDENTED:
+ {
+ if (start && (arg_no == 1))
+ {
+// indentLevel ++;
+// TexOutput("\\fi0\n");
+ int oldIndent = 0;
+ wxNode *node = itemizeStack.First();
+ if (node)
+ oldIndent = ((ItemizeStruc *)node->Data())->indentation;
+
+ int indentValue = 20*ParseUnitArgument(GetArgData());
+ int indentSize = indentValue + oldIndent;
+
+ ItemizeStruc *struc = new ItemizeStruc(LATEX_INDENT, indentSize);
+ itemizeStack.Insert(struc);
+
+ sprintf(buf, "\\tx%d\\li%d ", indentSize, indentSize);
+ PushEnvironmentStyle(buf);
+ TexOutput(buf);
+ return FALSE;
+ }
+ if (!start && (arg_no == 2))
+ {
+ PopEnvironmentStyle();
+ if (itemizeStack.First())
+ {
+ ItemizeStruc *struc = (ItemizeStruc *)itemizeStack.First()->Data();
+ delete struc;
+ delete itemizeStack.First();
+ }
+ if (itemizeStack.Number() == 0)
+ {
+ TexOutput("\\par\\pard\n");
+ issuedNewParagraph = 1;
+ WriteEnvironmentStyles();
+ }
+ }
+ return TRUE;
+ break;
+ }
+/*
+ case ltSIZEDBOX:
+ case ltSIZEDBOXD:
+ {
+ if (start && (arg_no == 1))
+ {
+ int oldIndent = 0;
+ wxNode *node = itemizeStack.First();
+ if (node)
+ oldIndent = ((ItemizeStruc *)node->Data())->indentation;
+
+ int boxWidth = 20*ParseUnitArgument(GetArgData());
+
+ int indentValue = (int)((CurrentTextWidth - oldIndent - boxWidth)/2.0);
+ int indentSize = indentValue + oldIndent;
+ int indentSizeRight = indentSize + boxWidth;
+
+ ItemizeStruc *struc = new ItemizeStruc(LATEX_INDENT, indentSize);
+ itemizeStack.Insert(struc);
+
+ sprintf(buf, "\\tx%d\\li%d\\lr%d\\box%s ", indentSize, indentSize, indentSizeRight,
+ ((macroId == ltCENTEREDBOX) ? "\\brdrs" : "\\brdrdb"));
+ PushEnvironmentStyle(buf);
+ TexOutput(buf);
+ return FALSE;
+ }
+ if (!start && (arg_no == 2))
+ {
+ PopEnvironmentStyle();
+ if (itemizeStack.First())
+ {
+ ItemizeStruc *struc = (ItemizeStruc *)itemizeStack.First()->Data();
+ delete struc;
+ delete itemizeStack.First();
+ }
+ if (itemizeStack.Number() == 0)
+ {
+ TexOutput("\\par\\pard\n");
+ issuedNewParagraph = 1;
+ WriteEnvironmentStyles();
+ }
+ }
+ return TRUE;
+ break;
+ }
+*/
+ case ltDOCUMENTSTYLE:
+ {
+ DefaultOnArgument(macroId, arg_no, start);
+ if (!start && !IsArgOptional())
+ {
+ if (MinorDocumentStyleString)
+ {
+ if (StringMatch("twoside", MinorDocumentStyleString))
+ // Mirror margins, switch on odd/even headers & footers, and break sections at odd pages
+ TexOutput("\\margmirror\\facingp\\sbkodd");
+ if (StringMatch("twocolumn", MinorDocumentStyleString))
+ TexOutput("\\cols2");
+ }
+ TexOutput("\n");
+ }
+ return FALSE;
+ }
+ case ltSETHOTSPOTCOLOUR:
+ case ltSETHOTSPOTCOLOR:
+ {
+ if (!start)
+ {
+ char *text = GetArgData();
+ if (strcmp(text, "yes") == 0 || strcmp(text, "on") == 0 || strcmp(text, "ok") == 0)
+ hotSpotColour = TRUE;
+ else
+ hotSpotColour = FALSE;
+ }
+ return FALSE;
+ }
+ case ltSETTRANSPARENCY:
+ {
+ if (!start)
+ {
+ char *text = GetArgData();
+ if (strcmp(text, "yes") == 0 || strcmp(text, "on") == 0 || strcmp(text, "ok") == 0)
+ bitmapTransparency = TRUE;
+ else
+ bitmapTransparency = FALSE;
+ }
+ return FALSE;
+ }
+ case ltSETHOTSPOTUNDERLINE:
+ {
+ if (!start)
+ {
+ char *text = GetArgData();
+ if (strcmp(text, "yes") == 0 || strcmp(text, "on") == 0 || strcmp(text, "ok") == 0)
+ hotSpotUnderline = TRUE;
+ else
+ hotSpotUnderline = FALSE;
+ }
+ return FALSE;
+ }
+ case ltBIBITEM:
+ {
+ if (arg_no == 1 && start)
+ {
+ char *citeKey = GetArgData();
+ TexRef *ref = (TexRef *)TexReferences.Get(citeKey);
+ if (ref)
+ {
+ if (ref->sectionNumber) delete[] ref->sectionNumber;
+ sprintf(buf, "[%d]", citeCount);
+ ref->sectionNumber = copystring(buf);
+ }
+
+ TexOutput("\\li260\\fi-260 "); // Indent from 2nd line
+ sprintf(buf, "{\\b [%d]} ", citeCount);
+ TexOutput(buf);
+ citeCount ++;
+ return FALSE;
+ }
+ if (arg_no == 2 && !start)
+ TexOutput("\\par\\pard\\par\n\n");
+ return TRUE;
+ break;
+ }
+ case ltTHEBIBLIOGRAPHY:
+ {
+ if (start && (arg_no == 1))
+ {
+ citeCount = 1;
+ if (winHelp)
+ SetCurrentOutputs(Contents, Chapters);
+
+ if (!winHelp)
+ {
+ fprintf(Chapters, "\\sect\\pgncont\\titlepg\n");
+
+ // If a non-custom page style, we generate the header now.
+ if (PageStyle && (strcmp(PageStyle, "plain") == 0 ||
+ strcmp(PageStyle, "empty") == 0 ||
+ strcmp(PageStyle, "headings") == 0))
+ {
+ OutputRTFHeaderCommands();
+ OutputRTFFooterCommands();
+ }
+
+ // Need to reset the current numbering style, or RTF forgets it.
+ OutputNumberStyle(currentNumberStyle);
+ SetCurrentOutput(Contents);
+ }
+ else
+ fprintf(Chapters, "\\page\n");
+
+ if (winHelp)
+ fprintf(Contents, "\n{\\uldb %s}", ReferencesNameString);
+ else
+ fprintf(Contents, "\\par\n\\pard{\\b %s}", ReferencesNameString);
+
+ startedSections = TRUE;
+
+ if (winHelp)
+ fprintf(Chapters, "\n${\\footnote %s}", ReferencesNameString);
+
+ char *topicName = "bibliography";
+
+ if (winHelp)
+ fprintf(Contents, "{\\v %s}\\par\\pard\n", topicName);
+ else
+ fprintf(Contents, "\\par\\par\\pard\n");
+
+ if (winHelp)
+ {
+ fprintf(Chapters, "\n#{\\footnote %s}\n", topicName);
+ fprintf(Chapters, "+{\\footnote %s}\n", GetBrowseString());
+ fprintf(Chapters, "K{\\footnote {K} %s}\n", ReferencesNameString);
+ GenerateKeywordsForTopic(topicName);
+ if (useUpButton)
+ {
+ fprintf(Chapters, "!{\\footnote EnableButton(\"Up\");ChangeButtonBinding(\"Up\", \"JumpId(`%s.hlp', `%s')\")}\n",
+ FileNameFromPath(FileRoot), "Contents");
+ }
+ }
+
+ SetCurrentOutput(Chapters);
+ char *styleCommand = "";
+ if (!winHelp && useHeadingStyles)
+ styleCommand = "\\s1";
+ fprintf(Chapters, "\\pard{%s", (winHelp ? "\\keepn\\sa140\\sb140" : styleCommand));
+ WriteHeadingStyle(Chapters, 1); fprintf(Chapters, " References\\par\\pard}\n");
+
+ return FALSE;
+ }
+ return TRUE;
+ break;
+ }
+ case ltINDEX:
+ {
+ /*
+ * In Windows help, all keywords should be at the start of the
+ * topic, but Latex \index commands can be anywhere in the text.
+ * So we're going to have to build up lists of keywords for a topic,
+ * and insert them on the second pass.
+ *
+ * In linear RTF, we can embed the index entry now.
+ *
+ */
+ if (start)
+ {
+// char *entry = GetArgData();
+ char buf[300];
+ OutputChunkToString(GetArgChunk(), buf);
+ if (winHelp)
+ {
+ if (CurrentTopic)
+ {
+ AddKeyWordForTopic(CurrentTopic, buf);
+ }
+ }
+ else GenerateIndexEntry(buf);
+ }
+ return FALSE;
+ break;
+ }
+ case ltFCOL:
+ case ltBCOL:
+ {
+ if (start)
+ {
+ switch (arg_no)
+ {
+ case 1:
+ {
+ char *name = GetArgData();
+ int pos = FindColourPosition(name);
+ if (pos > -1)
+ {
+ sprintf(buf, "{%s%d ", ((macroId == ltFCOL) ? "\\cf" : "\\cb"), pos);
+ TexOutput(buf);
+ }
+ else
+ {
+ sprintf(buf, "Could not find colour name %s", name);
+ OnError(buf);
+ }
+ break;
+ }
+ case 2:
+ {
+ return TRUE;
+ break;
+ }
+ default:
+ break;
+ }
+ }
+ else
+ {
+ if (arg_no == 2) TexOutput("}");
+ }
+ return FALSE;
+ break;
+ }
+ case ltLABEL:
+ {
+ if (start && !winHelp && useWord)
+ {
+ char *s = GetArgData();
+ // Only insert a bookmark here if it's not just been inserted
+ // in a section heading.
+ if ( !CurrentTopic || !(strcmp(CurrentTopic, s) == 0) )
+/*
+ if ( (!CurrentChapterName || !(CurrentChapterName && (strcmp(CurrentChapterName, s) == 0))) &&
+ (!CurrentSectionName || !(CurrentSectionName && (strcmp(CurrentSectionName, s) == 0))) &&
+ (!CurrentSubsectionName || !(CurrentSubsectionName && (strcmp(CurrentSubsectionName, s) == 0)))
+ )
+*/
+ {
+ fprintf(Chapters, "{\\bkmkstart %s}{\\bkmkend %s}", s,s);
+ }
+ }
+ return FALSE;
+ break;
+ }
+ case ltPAGEREF:
+ {
+ if (start && useWord && !winHelp)
+ {
+ char *s = GetArgData();
+ fprintf(Chapters, "{\\field{\\*\\fldinst PAGEREF %s \\\\* MERGEFORMAT }{\\fldrslt ??}}",
+ s);
+ }
+ return FALSE;
+ break;
+ }
+ case ltPOPREFONLY:
+ {
+ if (start)
+ inPopRefSection = TRUE;
+ else
+ inPopRefSection = FALSE;
+ break;
+ }
+ case ltINSERTATLEVEL:
+ {
+ // This macro allows you to insert text at a different level
+ // from the current level, e.g. into the Sections from within a subsubsection.
+ if (!winHelp & useWord)
+ return FALSE;
+ static int currentLevelNo = 1;
+ static FILE* oldLevelFile = Chapters;
+ if (start)
+ {
+ switch (arg_no)
+ {
+ case 1:
+ {
+ oldLevelFile = CurrentOutput1;
+
+ char *str = GetArgData();
+ currentLevelNo = atoi(str);
+ FILE* outputFile;
+ // TODO: cope with article style (no chapters)
+ switch (currentLevelNo)
+ {
+ case 1:
+ {
+ outputFile = Chapters;
+ break;
+ }
+ case 2:
+ {
+ outputFile = Sections;
+ break;
+ }
+ case 3:
+ {
+ outputFile = Subsections;
+ break;
+ }
+ case 4:
+ {
+ outputFile = Subsubsections;
+ break;
+ }
+ default:
+ {
+ outputFile = NULL;
+ break;
+ }
+ }
+ if (outputFile)
+ CurrentOutput1 = outputFile;
+ return FALSE;
+ break;
+ }
+ case 2:
+ {
+ return TRUE;
+ break;
+ }
+ default:
+ break;
+ }
+ return TRUE;
+ }
+ else
+ {
+ if (arg_no == 2)
+ {
+ CurrentOutput1 = oldLevelFile;
+ }
+ return TRUE;
+ }
+ break;
+ }
+ default:
+ {
+ return DefaultOnArgument(macroId, arg_no, start);
+ break;
+ }
+ }
+ return TRUE;
+}
+
+bool RTFGo(void)
+{
+ // Reset variables
+ indentLevel = 0;
+ forbidParindent = 0;
+ contentsLineSection = NULL;
+ contentsLineValue = NULL;
+ descriptionItemArg = NULL;
+ inTabular = FALSE;
+ inTable = FALSE;
+ inFigure = FALSE;
+ startRows = FALSE;
+ tableVerticalLineLeft = FALSE;
+ tableVerticalLineRight = FALSE;
+ noColumns = 0;
+ startedSections = FALSE;
+ inVerbatim = FALSE;
+ browseId = 0;
+
+ if (InputFile && OutputFile)
+ {
+ // Do some RTF-specific transformations on all the strings,
+ // recursively
+ Text2RTF(GetTopLevelChunk());
+
+ Contents = fopen(TmpContentsName, "w");
+ Chapters = fopen("chapters.rtf", "w");
+ if (winHelp)
+ {
+ Sections = fopen("sections.rtf", "w");
+ Subsections = fopen("subsections.rtf", "w");
+ Subsubsections = fopen("subsubsections.rtf", "w");
+ Popups = fopen("popups.rtf", "w");
+ if (winHelpContents)
+ {
+ WinHelpContentsFile = fopen(WinHelpContentsFileName, "w");
+ if (WinHelpContentsFile)
+ fprintf(WinHelpContentsFile, ":Base %s.hlp\n", wxFileNameFromPath(FileRoot));
+ }
+
+ if (!Sections || !Subsections || !Subsubsections || !Popups || (winHelpContents && !WinHelpContentsFile))
+ {
+ OnError("Ouch! Could not open temporary file(s) for writing.");
+ return FALSE;
+ }
+ }
+ if (!Contents || !Chapters)
+ {
+ OnError("Ouch! Could not open temporary file(s) for writing.");
+ return FALSE;
+ }
+
+ if (winHelp)
+ {
+ fprintf(Chapters, "\n#{\\footnote Contents}\n");
+ fprintf(Chapters, "${\\footnote Contents}\n");
+ fprintf(Chapters, "+{\\footnote %s}\n", GetBrowseString());
+ fprintf(Chapters, "K{\\footnote {K} %s}\n", ContentsNameString);
+ fprintf(Chapters, "!{\\footnote DisableButton(\"Up\")}\n");
+ }
+ if (!winHelp)
+ {
+ fprintf(Chapters, "\\titlepg\n");
+ fprintf(Contents, "\\par\\pard\\pgnrestart\\sect\\titlepg");
+ }
+
+ // In WinHelp, Contents title takes font of title.
+ // In linear RTF, same as chapter headings.
+ fprintf(Contents, "{\\b\\fs%d %s}\\par\\par\\pard\n\n",
+ (winHelp ? titleFont : chapterFont)*2, ContentsNameString);
+
+ // By default, Swiss, 10 point.
+ fprintf(Chapters, "\\f2\\fs20\n");
+
+ SetCurrentOutput(Chapters);
+
+ OnInform("Converting...");
+
+ TraverseDocument();
+
+ FILE *Header = fopen("header.rtf", "w");
+ if (!Header)
+ {
+ OnError("Ouch! Could not open temporary file header.rtf for writing.");
+ return FALSE;
+ }
+ WriteRTFHeader(Header);
+ fclose(Header); Header = NULL;
+
+ Tex2RTFYield(TRUE);
+ if (winHelp)
+ {
+// fprintf(Contents, "\\page\n");
+ fprintf(Chapters, "\\page\n");
+ fprintf(Sections, "\\page\n");
+ fprintf(Subsections, "\\page\n");
+ fprintf(Subsubsections, "\\page\n\n");
+ fprintf(Popups, "\\page\n}\n");
+ }
+
+// TexOutput("\n\\info{\\doccomm Document created by Julian Smart's Tex2RTF.}\n");
+ if (!winHelp)
+ TexOutput("}\n");
+ fclose(Contents); Contents = NULL;
+ fclose(Chapters); Chapters = NULL;
+ if (winHelp)
+ {
+ fclose(Sections); Sections = NULL;
+ fclose(Subsections); Subsections = NULL;
+ fclose(Subsubsections); Subsubsections = NULL;
+ fclose(Popups); Popups = NULL;
+ if (winHelpContents)
+ {
+ fclose(WinHelpContentsFile); WinHelpContentsFile = NULL;
+ }
+ }
+
+ if (winHelp)
+ {
+ wxConcatFiles("header.rtf", "chapters.rtf", "tmp1.rtf");
+ Tex2RTFYield(TRUE);
+ wxConcatFiles("tmp1.rtf", "sections.rtf", "tmp2.rtf");
+ Tex2RTFYield(TRUE);
+ wxConcatFiles("tmp2.rtf", "subsections.rtf", "tmp3.rtf");
+ Tex2RTFYield(TRUE);
+ wxConcatFiles("tmp3.rtf", "subsubsections.rtf", "tmp4.rtf");
+ Tex2RTFYield(TRUE);
+ wxConcatFiles("tmp4.rtf", "popups.rtf", OutputFile);
+ Tex2RTFYield(TRUE);
+
+ wxRemoveFile("tmp1.rtf");
+ wxRemoveFile("tmp2.rtf");
+ wxRemoveFile("tmp3.rtf");
+ wxRemoveFile("tmp4.rtf");
+ }
+ else
+ {
+ wxConcatFiles("header.rtf", "chapters.rtf", "tmp1.rtf");
+ Tex2RTFYield(TRUE);
+ if (FileExists(OutputFile)) wxRemoveFile(OutputFile);
+ wxCopyFile("tmp1.rtf", OutputFile);
+ Tex2RTFYield(TRUE);
+ wxRemoveFile("tmp1.rtf");
+ }
+
+ if (FileExists(ContentsName)) wxRemoveFile(ContentsName);
+
+ if (!wxRenameFile(TmpContentsName, ContentsName))
+ {
+ wxCopyFile(TmpContentsName, ContentsName);
+ wxRemoveFile(TmpContentsName);
+ }
+
+ wxRemoveFile("chapters.rtf");
+ wxRemoveFile("header.rtf");
+
+ if (winHelp)
+ {
+ wxRemoveFile("sections.rtf");
+ wxRemoveFile("subsections.rtf");
+ wxRemoveFile("subsubsections.rtf");
+ wxRemoveFile("popups.rtf");
+ }
+ if (winHelp && generateHPJ)
+ WriteHPJ(OutputFile);
+ return TRUE;
+ }
+ return FALSE;
+}
--- /dev/null
+/////////////////////////////////////////////////////////////////////////////
+// Name: rtfutils.h
+// Purpose: RTF-specific code
+// Author: Julian Smart
+// Modified by:
+// Created: 7.9.93
+// RCS-ID: $Id$
+// Copyright: (c) Julian Smart
+// Licence: wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+ /*
+ * Write a suitable RTF header.
+ *
+ */
+
+void WriteRTFHeader(FILE *fd);
+
+/*
+ * Given a TexChunk with a string value, scans through the string
+ * converting Latex-isms into RTF-isms, such as 2 newlines -> \par,
+ * and inserting spaces at the start of lines since in Latex, a newline
+ * implies a space, but not in RTF.
+ *
+ */
+
+void ProcessText2RTF(TexChunk *chunk);
+
+/*
+ * Scan through all chunks starting from the given one,
+ * calling ProcessText2RTF to convert Latex-isms to RTF-isms.
+ * This should be called after Tex2Any has parsed the file,
+ * and before TraverseDocument is called.
+ *
+ */
+
+void Text2RTF(TexChunk *chunk);
+
+
+/*
+ * Keeping track of environments to restore the styles after \pard.
+ * Push strings like "\qc" onto stack.
+ *
+ */
+
+void PushEnvironmentStyle(char *style);
+
+void PopEnvironmentStyle(void);
+
+// Write out the styles, most recent first.
+void WriteEnvironmentStyles(void);
+
+// Called on start/end of macro examination
+void DefaultRtfOnMacro(char *name, int no_args, bool start);
+
+// Called on start/end of argument examination
+bool DefaultRtfOnArgument(char *macro_name, int arg_no, bool start);
+
+// Reset memory of which levels have 'books' (for WinHelp 4 contents file)
+void ResetContentsLevels(int level);
--- /dev/null
+/////////////////////////////////////////////////////////////////////////////
+// Name: table.cpp
+// Purpose: Utilities for manipulating tables
+// Author: Julian Smart
+// Modified by:
+// Created: 01/01/99
+// RCS-ID: $Id$
+// Copyright: (c) Julian Smart
+// Licence: wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+
+#ifndef WX_PRECOMP
+#include "wx/wx.h"
+#endif
+
+
+#include <wx/hash.h>
+
+#if wxUSE_IOSTREAMH
+#include <iostream.h>
+#include <fstream.h>
+#else
+#include <iostream>
+#include <fstream>
+#endif
+
+#include <ctype.h>
+#include "tex2any.h"
+#include "table.h"
+
+ColumnData TableData[40];
+bool inTabular = FALSE;
+
+bool startRows = FALSE;
+bool tableVerticalLineLeft = FALSE;
+bool tableVerticalLineRight = FALSE;
+int noColumns = 0; // Current number of columns in table
+int ruleTop = 0;
+int ruleBottom = 0;
+int currentRowNumber = 0;
+
+/*
+ * Parse table argument
+ *
+ */
+
+bool ParseTableArgument(char *value)
+{
+ noColumns = 0;
+ int i = 0;
+ int len = strlen(value);
+ bool isBorder = FALSE;
+ while (i < len)
+ {
+ int ch = value[i];
+ if (ch == '|')
+ {
+ i ++;
+ isBorder = TRUE;
+ }
+ else if (ch == 'l')
+ {
+ TableData[noColumns].leftBorder = isBorder;
+ TableData[noColumns].rightBorder = FALSE;
+ TableData[noColumns].justification = 'l';
+ TableData[noColumns].width = 2000; // Estimate
+ TableData[noColumns].absWidth = FALSE;
+// TableData[noColumns].spacing = ??
+ noColumns ++;
+ i ++;
+ isBorder = FALSE;
+ }
+ else if (ch == 'c')
+ {
+ TableData[noColumns].leftBorder = isBorder;
+ TableData[noColumns].rightBorder = FALSE;
+ TableData[noColumns].justification = 'c';
+ TableData[noColumns].width = defaultTableColumnWidth; // Estimate
+ TableData[noColumns].absWidth = FALSE;
+// TableData[noColumns].spacing = ??
+ noColumns ++;
+ i ++;
+ isBorder = FALSE;
+ }
+ else if (ch == 'r')
+ {
+ TableData[noColumns].leftBorder = isBorder;
+ TableData[noColumns].rightBorder = FALSE;
+ TableData[noColumns].justification = 'r';
+ TableData[noColumns].width = 2000; // Estimate
+ TableData[noColumns].absWidth = FALSE;
+// TableData[noColumns].spacing = ??
+ noColumns ++;
+ i ++;
+ isBorder = FALSE;
+ }
+ else if (ch == 'p')
+ {
+ i ++;
+ int j = 0;
+ char numberBuf[50];
+ ch = value[i];
+ if (ch == '{')
+ {
+ i++;
+ ch = value[i];
+ }
+
+ while ((i < len) && (isdigit(ch) || ch == '.'))
+ {
+ numberBuf[j] = ch;
+ j ++;
+ i ++;
+ ch = value[i];
+ }
+ // Assume we have 2 characters for units
+ numberBuf[j] = value[i];
+ j ++; i++;
+ numberBuf[j] = value[i];
+ j ++; i++;
+ numberBuf[j] = 0;
+ if (value[i] == '}') i++;
+
+ TableData[noColumns].leftBorder = isBorder;
+ TableData[noColumns].rightBorder = FALSE;
+ TableData[noColumns].justification = 'l';
+ TableData[noColumns].width = 20*ParseUnitArgument(numberBuf);
+ TableData[noColumns].absWidth = TRUE;
+// TableData[noColumns].spacing = ??
+ noColumns ++;
+ isBorder = FALSE;
+ }
+ else
+ {
+ char *buf = new char[strlen(value) + 80];
+ sprintf(buf, "Tabular first argument \"%s\" too complex!", value);
+ OnError(buf);
+ delete[] buf;
+ return FALSE;
+ }
+ }
+ if (isBorder)
+ TableData[noColumns-1].rightBorder = TRUE;
+ return TRUE;
+}
--- /dev/null
+/////////////////////////////////////////////////////////////////////////////
+// Name: table.h
+// Purpose: Table utilities
+// Author: Julian Smart
+// Modified by:
+// Created: 7.9.93
+// RCS-ID: $Id$
+// Copyright: (c) Julian Smart
+// Licence: wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+/*
+ * Table dimensions
+ *
+ */
+
+struct ColumnData
+{
+ char justification; // l, r, c
+ int width; // -1 or a width in twips
+ int spacing; // Space between columns in twips
+ bool leftBorder;
+ bool rightBorder;
+ bool absWidth; // If FALSE (the default), don't use an absolute width if you can help it.
+};
+
+extern ColumnData TableData[];
+extern bool inTabular;
+extern bool startRows;
+extern bool tableVerticalLineLeft;
+extern bool tableVerticalLineRight;
+extern int noColumns; // Current number of columns in table
+extern int ruleTop;
+extern int ruleBottom;
+extern int currentRowNumber;
+extern bool ParseTableArgument(char *value);
--- /dev/null
+/////////////////////////////////////////////////////////////////////////////
+// Name: tex2any.cpp
+// Purpose: Utilities for Latex conversion.
+// Author: Julian Smart
+// Modified by:
+// Created: 01/01/99
+// RCS-ID: $Id$
+// Copyright: (c) Julian Smart
+// Licence: wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+
+#ifndef WX_PRECOMP
+#include "wx/wx.h"
+#endif
+
+#include <ctype.h>
+#include "tex2any.h"
+#include <stdlib.h>
+#include <time.h>
+
+/*
+ * Variables accessible from clients
+ *
+ */
+
+TexChunk * DocumentTitle = NULL;
+TexChunk * DocumentAuthor = NULL;
+TexChunk * DocumentDate = NULL;
+
+// Header/footers/pagestyle
+TexChunk * LeftHeaderEven = NULL;
+TexChunk * LeftFooterEven = NULL;
+TexChunk * CentreHeaderEven = NULL;
+TexChunk * CentreFooterEven = NULL;
+TexChunk * RightHeaderEven = NULL;
+TexChunk * RightFooterEven = NULL;
+TexChunk * LeftHeaderOdd = NULL;
+TexChunk * LeftFooterOdd = NULL;
+TexChunk * CentreHeaderOdd = NULL;
+TexChunk * CentreFooterOdd = NULL;
+TexChunk * RightHeaderOdd = NULL;
+TexChunk * RightFooterOdd = NULL;
+char * PageStyle = copystring("plain");
+
+int DocumentStyle = LATEX_REPORT;
+int MinorDocumentStyle = 0;
+wxPathList TexPathList;
+char * BibliographyStyleString = copystring("plain");
+char * DocumentStyleString = copystring("report");
+char * MinorDocumentStyleString = NULL;
+int ParSkip = 0;
+int ParIndent = 0;
+
+int normalFont = 10;
+int smallFont = 8;
+int tinyFont = 6;
+int largeFont1 = 12;
+int LargeFont2 = 14;
+int LARGEFont3 = 18;
+int hugeFont1 = 20;
+int HugeFont2 = 24;
+int HUGEFont3 = 28;
+
+/*
+ * USER-ADJUSTABLE SETTINGS
+ *
+ */
+
+// Section font sizes
+int chapterFont = 12; // LARGEFont3;
+int sectionFont = 12; // LargeFont2;
+int subsectionFont = 12; // largeFont1;
+int titleFont = LARGEFont3;
+int authorFont = LargeFont2;
+int mirrorMargins = TRUE;
+bool winHelp = FALSE; // Output in Windows Help format if TRUE, linear otherwise
+bool isInteractive = FALSE;
+bool runTwice = FALSE;
+int convertMode = TEX_RTF;
+bool headerRule = FALSE;
+bool footerRule = FALSE;
+bool compatibilityMode = FALSE; // If TRUE, maximum Latex compatibility
+ // (Quality of RTF generation deteriorate)
+bool generateHPJ; // Generate WinHelp Help Project file
+char *winHelpTitle = NULL; // Windows Help title
+int defaultTableColumnWidth = 2000;
+
+int labelIndentTab = 18; // From left indent to item label (points)
+int itemIndentTab = 40; // From left indent to item (points)
+
+bool useUpButton = TRUE;
+int htmlBrowseButtons = HTML_BUTTONS_TEXT;
+
+bool truncateFilenames = FALSE; // Truncate for DOS
+int winHelpVersion = 3; // WinHelp Version (3 for Windows 3.1, 4 for Win95)
+bool winHelpContents = FALSE; // Generate .cnt file for WinHelp 4
+bool htmlIndex = FALSE; // Generate .htx file for HTML
+bool htmlFrameContents = FALSE; // Use frames for HTML contents page
+bool useHeadingStyles = TRUE; // Insert \s1, s2 etc.
+bool useWord = TRUE; // Insert proper Word table of contents, etc etc
+int contentsDepth = 4; // Depth of Word table of contents
+bool indexSubsections = TRUE; // Index subsections in linear RTF
+// Linear RTF method of including bitmaps. Can be "includepicture", "hex"
+char *bitmapMethod = copystring("includepicture");
+bool upperCaseNames = FALSE;
+// HTML background and text colours
+char *backgroundImageString = NULL;
+char *backgroundColourString = copystring("255;255;255");
+char *textColourString = NULL;
+char *linkColourString = NULL;
+char *followedLinkColourString = NULL;
+bool combineSubSections = FALSE;
+
+/*
+ * International support
+ */
+
+// Names to help with internationalisation
+char *ContentsNameString = copystring("Contents");
+char *AbstractNameString = copystring("Abstract");
+char *GlossaryNameString = copystring("Glossary");
+char *ReferencesNameString = copystring("References");
+char *FiguresNameString = copystring("List of Figures");
+char *TablesNameString = copystring("List of Tables");
+char *FigureNameString = copystring("Figure");
+char *TableNameString = copystring("Table");
+char *IndexNameString = copystring("Index");
+char *ChapterNameString = copystring("chapter");
+char *SectionNameString = copystring("section");
+char *SubsectionNameString = copystring("subsection");
+char *SubsubsectionNameString = copystring("subsubsection");
+char *UpNameString = copystring("Up");
+
+/*
+ * Section numbering
+ *
+ */
+
+int chapterNo = 0;
+int sectionNo = 0;
+int subsectionNo = 0;
+int subsubsectionNo = 0;
+int figureNo = 0;
+int tableNo = 0;
+
+/*
+ * Other variables
+ *
+ */
+
+FILE *CurrentOutput1 = NULL;
+FILE *CurrentOutput2 = NULL;
+FILE *Inputs[15];
+int LineNumbers[15];
+char *FileNames[15];
+int CurrentInputIndex = 0;
+
+char *TexFileRoot = NULL;
+char *TexBibName = NULL; // Bibliography output file name
+char *TexTmpBibName = NULL; // Temporary bibliography output file name
+bool isSync = FALSE; // If TRUE, should not yield to other processes.
+bool stopRunning = FALSE; // If TRUE, should abort.
+
+static int currentColumn = 0;
+char *currentArgData = NULL;
+bool haveArgData = FALSE; // If TRUE, we're simulating the data.
+TexChunk *currentArgument = NULL;
+TexChunk *nextChunk = NULL;
+bool isArgOptional = FALSE;
+bool noArgs = 0;
+
+TexChunk *TopLevel = NULL;
+// wxList MacroDefs(wxKEY_STRING);
+wxHashTable MacroDefs(wxKEY_STRING);
+wxStringList IgnorableInputFiles; // Ignorable \input files, e.g. psbox.tex
+char *BigBuffer = NULL; // For reading in large chunks of text
+TexMacroDef *SoloBlockDef = NULL;
+TexMacroDef *VerbatimMacroDef = NULL;
+
+#define IncrementLineNumber() LineNumbers[CurrentInputIndex] ++
+
+void TexOutput(char *s, bool ordinaryText)
+{
+ int len = strlen(s);
+
+ // Update current column, but only if we're guaranteed to
+ // be ordinary text (not mark-up stuff)
+ int i;
+ if (ordinaryText)
+ for (i = 0; i < len; i++)
+ {
+ if (s[i] == 13 || s[i] == 10)
+ currentColumn = 0;
+ else
+ currentColumn ++;
+ }
+
+ if (CurrentOutput1)
+ fprintf(CurrentOutput1, "%s", s);
+ if (CurrentOutput2)
+ fprintf(CurrentOutput2, "%s", s);
+}
+
+/*
+ * Try to find a Latex macro, in one of the following forms:
+ * (1) \begin{} ... \end{}
+ * (2) \macroname{arg1}...{argn}
+ * (3) {\bf arg1}
+ */
+
+void ForbidWarning(TexMacroDef *def)
+{
+ char buf[100];
+ switch (def->forbidden)
+ {
+ case FORBID_WARN:
+ {
+ sprintf(buf, "Warning: it is recommended that command %s is not used.", def->name);
+ OnInform(buf);
+ break;
+ }
+ case FORBID_ABSOLUTELY:
+ {
+ sprintf(buf, "Error: command %s cannot be used and will lead to errors.", def->name);
+ OnInform(buf);
+ break;
+ }
+ default:
+ break;
+ }
+}
+
+TexMacroDef *MatchMacro(char *buffer, int *pos, char **env, bool *parseToBrace)
+{
+ *parseToBrace = TRUE;
+ int i = (*pos);
+ TexMacroDef *def = NULL;
+ char macroBuf[40];
+
+ // First, try to find begin{thing}
+ if (strncmp(buffer+i, "begin{", 6) == 0)
+ {
+ i += 6;
+
+ int j = i;
+ while ((isalpha(buffer[j]) || buffer[j] == '*') && ((j - i) < 39))
+ {
+ macroBuf[j-i] = buffer[j];
+ j ++;
+ }
+ macroBuf[j-i] = 0;
+ def = (TexMacroDef *)MacroDefs.Get(macroBuf);
+
+ if (def)
+ {
+ *pos = j + 1; // BUGBUG Should this be + 1???
+ *env = def->name;
+ ForbidWarning(def);
+ return def;
+ }
+ else return NULL;
+ }
+
+ // Failed, so try to find macro from definition list
+ int j = i;
+
+ // First try getting a one-character macro, but ONLY
+ // if these TWO characters are not both alphabetical (could
+ // be a longer macro)
+ if (!(isalpha(buffer[i]) && isalpha(buffer[i+1])))
+ {
+ macroBuf[0] = buffer[i];
+ macroBuf[1] = 0;
+
+ def = (TexMacroDef *)MacroDefs.Get(macroBuf);
+ if (def) j ++;
+ }
+
+ if (!def)
+ {
+ while ((isalpha(buffer[j]) || buffer[j] == '*') && ((j - i) < 39))
+ {
+ macroBuf[j-i] = buffer[j];
+ j ++;
+ }
+ macroBuf[j-i] = 0;
+ def = (TexMacroDef *)MacroDefs.Get(macroBuf);
+ }
+
+ if (def)
+ {
+ i = j;
+
+ // We want to check whether this is a space-consuming macro
+ // (e.g. {\bf word})
+ // No brace, e.g. \input thing.tex instead of \input{thing};
+ // or a numeric argument, such as \parindent0pt
+ if ((def->no_args > 0) && ((buffer[i] == 32) || (buffer[i] == '=') || (isdigit(buffer[i]))))
+ {
+ if ((buffer[i] == 32) || (buffer[i] == '='))
+ i ++;
+
+ *parseToBrace = FALSE;
+ }
+ *pos = i;
+ ForbidWarning(def);
+ return def;
+ }
+ return NULL;
+}
+
+void EatWhiteSpace(char *buffer, int *pos)
+{
+ int len = strlen(buffer);
+ int j = *pos;
+ bool keepGoing = TRUE;
+ bool moreLines = TRUE;
+ while ((j < len) && keepGoing &&
+ (buffer[j] == 10 || buffer[j] == 13 || buffer[j] == ' ' || buffer[j] == 9))
+ {
+ j ++;
+ if (j >= len)
+ {
+ if (moreLines)
+ {
+ moreLines = read_a_line(buffer);
+ len = strlen(buffer);
+ j = 0;
+ }
+ else
+ keepGoing = FALSE;
+ }
+ }
+ *pos = j;
+}
+
+bool FindEndEnvironment(char *buffer, int *pos, char *env)
+{
+ int i = (*pos);
+
+ // Try to find end{thing}
+ if ((strncmp(buffer+i, "end{", 4) == 0) &&
+ (strncmp(buffer+i+4, env, strlen(env)) == 0))
+ {
+ *pos = i + 5 + strlen(env);
+ return TRUE;
+ }
+ else return FALSE;
+}
+
+bool readingVerbatim = FALSE;
+bool readInVerbatim = FALSE; // Within a verbatim, but not nec. verbatiminput
+
+bool read_a_line(char *buf)
+{
+ if (CurrentInputIndex < 0)
+ {
+ buf[0] = 0;
+ return FALSE;
+ }
+
+ int ch = -2;
+ int i = 0;
+ buf[0] = 0;
+ while (ch != EOF && ch != 10)
+ {
+ if (((i == 14) && (strncmp(buf, "\\end{verbatim}", 14) == 0)) ||
+ ((i == 16) && (strncmp(buf, "\\end{toocomplex}", 16) == 0)))
+ readInVerbatim = FALSE;
+
+ ch = getc(Inputs[CurrentInputIndex]);
+ if (ch != EOF)
+ {
+ // Check for 2 consecutive newlines and replace with \par
+ if (ch == 10 && !readInVerbatim)
+ {
+ int ch1 = getc(Inputs[CurrentInputIndex]);
+ if ((ch1 == 10) || (ch1 == 13))
+ {
+ // Eliminate newline (10) following DOS linefeed
+ if (ch1 == 13) ch1 = getc(Inputs[CurrentInputIndex]);
+ buf[i] = 0;
+ IncrementLineNumber();
+// strcat(buf, "\\par\n");
+// i += 6;
+ strcat(buf, "\\par");
+ i += 5;
+ }
+ else
+ {
+ ungetc(ch1, Inputs[CurrentInputIndex]);
+ buf[i] = ch;
+ i ++;
+ }
+ }
+ else
+ {
+
+ // Convert embedded characters to RTF equivalents
+ switch(ch)
+ {
+ case 0xf6: // ö
+ case 0xe4: // ü
+ case 0xfc: // ü
+ case 0xd6: // Ö
+ case 0xc4: // Ä
+ case 0xdc: // Ü
+ buf[i++]='\\';
+ buf[i++]='"';
+ buf[i++]='{';
+ switch(ch)
+ {
+ case 0xf6:buf[i++]='o';break; // ö
+ case 0xe4:buf[i++]='a';break; // ä
+ case 0xfc:buf[i++]='u';break; // ü
+ case 0xd6:buf[i++]='O';break; // Ö
+ case 0xc4:buf[i++]='A';break; // Ä
+ case 0xdc:buf[i++]='U';break; // Ü
+ }
+ buf[i++]='}';
+ break;
+ case 0xdf: // ß
+ buf[i++]='\\';
+ buf[i++]='s';
+ buf[i++]='s';
+ buf[i++]='\\';
+ buf[i++]='/';
+ break;
+ default:
+ buf[i++] = ch;
+ break;
+ }
+
+ }
+ }
+ else
+ {
+ buf[i] = 0;
+ fclose(Inputs[CurrentInputIndex]);
+ Inputs[CurrentInputIndex] = NULL;
+ if (CurrentInputIndex > 0) ch = ' '; // No real end of file
+ CurrentInputIndex --;
+ if (readingVerbatim)
+ {
+ readingVerbatim = FALSE;
+ readInVerbatim = FALSE;
+ strcat(buf, "\\end{verbatim}\n");
+ return FALSE;
+ }
+ }
+ if (ch == 10)
+ IncrementLineNumber();
+ }
+ buf[i] = 0;
+
+ // Strip out comment environment
+ if (strncmp(buf, "\\begin{comment}", 15) == 0)
+ {
+ while (strncmp(buf, "\\end{comment}", 13) != 0)
+ read_a_line(buf);
+ return read_a_line(buf);
+ }
+ // Read a verbatim input file as if it were a verbatim environment
+ else if (strncmp(buf, "\\verbatiminput", 14) == 0)
+ {
+ int wordLen = 14;
+ char *fileName = buf + wordLen + 1;
+
+ int j = i - 1;
+ buf[j] = 0;
+
+ // thing}\par -- eliminate the \par!
+ if (strncmp((buf + strlen(buf)-5), "\\par", 4) == 0)
+ {
+ j -= 5;
+ buf[j] = 0;
+ }
+
+ if (buf[j-1] == '}') buf[j-1] = 0; // Ignore final brace
+
+ wxString actualFile = TexPathList.FindValidPath(fileName);
+ if (actualFile == "")
+ {
+ char errBuf[300];
+ strcpy(errBuf, "Could not find file: ");
+ strncat(errBuf, fileName, 100);
+ OnError(errBuf);
+ }
+ else
+ {
+ CurrentInputIndex ++;
+ Inputs[CurrentInputIndex] = fopen(actualFile, "r");
+ LineNumbers[CurrentInputIndex] = 1;
+ if (FileNames[CurrentInputIndex])
+ delete[] FileNames[CurrentInputIndex];
+ FileNames[CurrentInputIndex] = copystring(actualFile);
+
+ if (!Inputs[CurrentInputIndex])
+ {
+ CurrentInputIndex --;
+ OnError("Could not open verbatiminput file.");
+ }
+ else
+ {
+ readingVerbatim = TRUE;
+ readInVerbatim = TRUE;
+ strcpy(buf, "\\begin{verbatim}\n");
+ return FALSE;
+ }
+ }
+ return FALSE;
+ }
+ else if (strncmp(buf, "\\input", 6) == 0 || strncmp(buf, "\\helpinput", 10) == 0 ||
+ strncmp(buf, "\\include", 8) == 0)
+ {
+ int wordLen;
+ if (strncmp(buf, "\\input", 6) == 0)
+ wordLen = 6;
+ else
+ if (strncmp(buf, "\\include", 8) == 0)
+ wordLen = 8;
+ else
+ wordLen = 10;
+
+ char *fileName = buf + wordLen + 1;
+
+ int j = i - 1;
+ buf[j] = 0;
+
+ // \input{thing}\par -- eliminate the \par!
+// if (strncmp((buf + strlen(buf)-5), "\\par", 4) == 0)
+ if (strncmp((buf + strlen(buf)-4), "\\par", 4) == 0) // Bug fix 8/2/95 Ulrich Leodolter
+ {
+// j -= 5;
+ j -= 4; // Ditto
+ buf[j] = 0;
+ }
+
+ if (buf[j-1] == '}') buf[j-1] = 0; // Ignore final brace
+
+ // Ignore some types of input files (e.g. macro definition files)
+ char *fileOnly = FileNameFromPath(fileName);
+ if (IgnorableInputFiles.Member(fileOnly))
+ return read_a_line(buf);
+
+ wxString actualFile = TexPathList.FindValidPath(fileName);
+ if (actualFile == "")
+ {
+ char buf2[400];
+ sprintf(buf2, "%s.tex", fileName);
+ actualFile = TexPathList.FindValidPath(buf2);
+ }
+ if (actualFile == "")
+ {
+ char errBuf[300];
+ strcpy(errBuf, "Could not find file: ");
+ strncat(errBuf, fileName, 100);
+ OnError(errBuf);
+ }
+ else
+ {
+ // Ensure that if this file includes another,
+ // then we look in the same directory as this one.
+ TexPathList.EnsureFileAccessible(actualFile);
+
+ CurrentInputIndex ++;
+ Inputs[CurrentInputIndex] = fopen(actualFile, "r");
+ LineNumbers[CurrentInputIndex] = 1;
+ if (FileNames[CurrentInputIndex])
+ delete[] FileNames[CurrentInputIndex];
+ FileNames[CurrentInputIndex] = copystring(actualFile);
+
+ if (!Inputs[CurrentInputIndex])
+ {
+ char errBuf[300];
+ sprintf(errBuf, "Could not open include file %s", (const char*) actualFile);
+ CurrentInputIndex --;
+ OnError(errBuf);
+ }
+ }
+ bool succ = read_a_line(buf);
+ return succ;
+ }
+ if (strncmp(buf, "\\begin{verbatim}", 16) == 0 ||
+ strncmp(buf, "\\begin{toocomplex}", 18) == 0)
+ readInVerbatim = TRUE;
+ else if (strncmp(buf, "\\end{verbatim}", 14) == 0 ||
+ strncmp(buf, "\\end{toocomplex}", 16) == 0)
+ readInVerbatim = FALSE;
+
+ return (ch == EOF);
+}
+
+/*
+ * Parse newcommand
+ *
+ */
+
+bool ParseNewCommand(char *buffer, int *pos)
+{
+ if ((strncmp((buffer+(*pos)), "newcommand", 10) == 0) ||
+ (strncmp((buffer+(*pos)), "renewcommand", 12) == 0))
+ {
+ if (strncmp((buffer+(*pos)), "newcommand", 10) == 0)
+ *pos = *pos + 12;
+ else
+ *pos = *pos + 14;
+
+ char commandName[100];
+ char commandValue[1000];
+ int noArgs = 0;
+ int i = 0;
+ while (buffer[*pos] != '}' && (buffer[*pos] != 0))
+ {
+ commandName[i] = buffer[*pos];
+ *pos += 1;
+ i ++;
+ }
+ commandName[i] = 0;
+ i = 0;
+ *pos += 1;
+ if (buffer[*pos] == '[')
+ {
+ *pos += 1;
+ noArgs = (int)(buffer[*pos]) - 48;
+ *pos += 2; // read past argument and '['
+ }
+ bool end = FALSE;
+ int braceCount = 0;
+ while (!end)
+ {
+ char ch = buffer[*pos];
+ if (ch == '{')
+ braceCount ++;
+ else if (ch == '}')
+ {
+ braceCount --;
+ if (braceCount == 0)
+ end = TRUE;
+ }
+ else if (ch == 0)
+ {
+ if (!read_a_line(buffer))
+ end = TRUE;
+ *pos = 0;
+ break;
+ }
+ commandValue[i] = ch;
+ i ++;
+ *pos += 1;
+ }
+ commandValue[i] = 0;
+
+ CustomMacro *macro = new CustomMacro(commandName, noArgs, NULL);
+ if (strlen(commandValue) > 0)
+ macro->macroBody = copystring(commandValue);
+ if (!CustomMacroList.Find(commandName))
+ {
+ CustomMacroList.Append(commandName, macro);
+ AddMacroDef(ltCUSTOM_MACRO, commandName, noArgs);
+ }
+ return TRUE;
+ }
+ else return FALSE;
+}
+
+void MacroError(char *buffer)
+{
+ char errBuf[300];
+ char macroBuf[200];
+ macroBuf[0] = '\\';
+ int i = 1;
+ char ch;
+ while (((ch = buffer[i-1]) != '\n') && (ch != 0))
+ {
+ macroBuf[i] = ch;
+ i ++;
+ }
+ macroBuf[i] = 0;
+ if (i > 20)
+ macroBuf[20] = 0;
+
+ sprintf(errBuf, "Could not find macro: %s at line %d, file %s",
+ macroBuf, (int)(LineNumbers[CurrentInputIndex]-1), FileNames[CurrentInputIndex]);
+ OnError(errBuf);
+}
+
+/*
+ * Parse an argument.
+ * 'environment' specifies the name of the macro IFF if we're looking for the end
+ * of an environment, e.g. \end{itemize}. Otherwise it's NULL.
+ * 'parseToBrace' is TRUE if the argument should extend to the next right brace,
+ * e.g. in {\bf an argument} as opposed to \vskip 30pt
+ *
+ */
+int ParseArg(TexChunk *thisArg, wxList& children, char *buffer, int pos, char *environment, bool parseToBrace, TexChunk *customMacroArgs)
+{
+ Tex2RTFYield();
+ if (stopRunning) return pos;
+
+ bool eof = FALSE;
+ BigBuffer[0] = 0;
+ int buf_ptr = 0;
+ int len;
+
+/*
+
+ // Consume leading brace or square bracket, but ONLY if not following
+ // a space, because this could be e.g. {\large {\bf thing}} where {\bf thing}
+ // is the argument of \large AS WELL as being a block in its
+ // own right.
+ if (!environment)
+ {
+ if ((pos > 0) && (buffer[pos-1] != ' ') && buffer[pos] == '{')
+ pos ++;
+ else
+
+ if ((pos > 0) && (buffer[pos-1] != ' ') && (buffer[pos] == '[' || buffer[pos] == '('))
+ {
+ isOptional = TRUE;
+ pos ++;
+ }
+ else if ((pos > 1) && (buffer[pos-1] != ' ') && (buffer[pos+1] == '[' || buffer[pos+1] == '('))
+ {
+ isOptional = TRUE;
+ pos += 2;
+ }
+ }
+*/
+
+ // If not parsing to brace, just read the next word
+ // (e.g. \vskip 20pt)
+ if (!parseToBrace)
+ {
+ int ch = buffer[pos];
+ while (!eof && ch != 13 && ch != 32 && ch != 10 &&
+ ch != 0 && ch != '{')
+ {
+ BigBuffer[buf_ptr] = ch;
+ buf_ptr ++;
+ pos ++;
+ ch = buffer[pos];
+ }
+ if (buf_ptr > 0)
+ {
+ TexChunk *chunk = new TexChunk(CHUNK_TYPE_STRING);
+ BigBuffer[buf_ptr] = 0;
+ buf_ptr = 0;
+ chunk->value = copystring(BigBuffer);
+ children.Append((wxObject *)chunk);
+ }
+ return pos;
+ }
+
+ while (!eof)
+ {
+ len = strlen(buffer);
+ if (pos >= len)
+ {
+ if (customMacroArgs) return 0;
+
+ eof = read_a_line(buffer);
+ pos = 0;
+ len = strlen(buffer);
+ // Check for verbatim (or toocomplex, which comes to the same thing)
+ if (strncmp(buffer, "\\begin{verbatim}", 16) == 0 ||
+ strncmp(buffer, "\\begin{toocomplex}", 18) == 0)
+ {
+ if (buf_ptr > 0)
+ {
+ TexChunk *chunk = new TexChunk(CHUNK_TYPE_STRING);
+ BigBuffer[buf_ptr] = 0;
+ buf_ptr = 0;
+ chunk->value = copystring(BigBuffer);
+ children.Append((wxObject *)chunk);
+ }
+ BigBuffer[0] = 0;
+ buf_ptr = 0;
+
+ eof = read_a_line(buffer);
+ while (!eof && (strncmp(buffer, "\\end{verbatim}", 14) != 0) &&
+ (strncmp(buffer, "\\end{toocomplex}", 16) != 0)
+ )
+ {
+ strcat(BigBuffer, buffer);
+ buf_ptr += strlen(buffer);
+ eof = read_a_line(buffer);
+ }
+ eof = read_a_line(buffer);
+ buf_ptr = 0;
+
+ TexChunk *chunk = new TexChunk(CHUNK_TYPE_MACRO, VerbatimMacroDef);
+ chunk->no_args = 1;
+ chunk->macroId = ltVERBATIM;
+ TexChunk *arg = new TexChunk(CHUNK_TYPE_ARG, VerbatimMacroDef);
+ arg->argn = 1;
+ arg->macroId = ltVERBATIM;
+ TexChunk *str = new TexChunk(CHUNK_TYPE_STRING);
+ str->value = copystring(BigBuffer);
+
+ children.Append((wxObject *)chunk);
+ chunk->children.Append((wxObject *)arg);
+ arg->children.Append((wxObject *)str);
+
+ // Also want to include the following newline (is always a newline
+ // after a verbatim): EXCEPT in HTML
+ if (convertMode != TEX_HTML)
+ {
+ TexMacroDef *parDef = (TexMacroDef *)MacroDefs.Get("\\");
+ TexChunk *parChunk = new TexChunk(CHUNK_TYPE_MACRO, parDef);
+ parChunk->no_args = 0;
+ parChunk->macroId = ltBACKSLASHCHAR;
+ children.Append((wxObject *)parChunk);
+ }
+ }
+ }
+
+ char ch = buffer[pos];
+ // End of optional argument -- pretend it's right brace for simplicity
+ if (thisArg->optional && (ch == ']'))
+ ch = '}';
+
+ switch (ch)
+ {
+ case 0:
+ case '}': // End of argument
+ {
+ if (buf_ptr > 0)
+ {
+ TexChunk *chunk = new TexChunk(CHUNK_TYPE_STRING);
+ BigBuffer[buf_ptr] = 0;
+ buf_ptr = 0;
+ chunk->value = copystring(BigBuffer);
+ children.Append((wxObject *)chunk);
+ }
+ if (ch == '}') pos ++;
+ return pos;
+ break;
+ }
+ case '\\':
+ {
+ if (buf_ptr > 0) // Finish off the string we've read so far
+ {
+ TexChunk *chunk = new TexChunk(CHUNK_TYPE_STRING);
+ BigBuffer[buf_ptr] = 0;
+ buf_ptr = 0;
+ chunk->value = copystring(BigBuffer);
+ children.Append((wxObject *)chunk);
+ }
+ pos ++;
+
+
+ // Try matching \end{environment}
+ if (environment && FindEndEnvironment(buffer, &pos, environment))
+ {
+ // Eliminate newline after an \end{} if possible
+ if (buffer[pos] == 13)
+ {
+ pos ++;
+ if (buffer[pos] == 10)
+ pos ++;
+ }
+ return pos;
+ }
+
+ if (ParseNewCommand(buffer, &pos))
+ break;
+
+ if (strncmp(buffer+pos, "special", 7) == 0)
+ {
+ pos += 7;
+
+ // Discard {
+ pos ++;
+ int noBraces = 1;
+
+ wxBuffer[0] = 0;
+ int i = 0;
+ bool end = FALSE;
+ while (!end)
+ {
+ int ch = buffer[pos];
+ if (ch == '}')
+ {
+ noBraces --;
+ if (noBraces == 0)
+ {
+ wxBuffer[i] = 0;
+ end = TRUE;
+ }
+ else
+ {
+ wxBuffer[i] = '}';
+ i ++;
+ }
+ pos ++;
+ }
+ else if (ch == '{')
+ {
+ wxBuffer[i] = '{';
+ i ++;
+ pos ++;
+ }
+ else if (ch == '\\' && buffer[pos+1] == '}')
+ {
+ wxBuffer[i] = '}';
+ pos += 2;
+ i++;
+ }
+ else if (ch == '\\' && buffer[pos+1] == '{')
+ {
+ wxBuffer[i] = '{';
+ pos += 2;
+ i++;
+ }
+ else
+ {
+ wxBuffer[i] = ch;
+ pos ++;
+ i ++;
+ if (ch == 0)
+ end = TRUE;
+ }
+ }
+ TexChunk *chunk = new TexChunk(CHUNK_TYPE_MACRO);
+ chunk->no_args = 1;
+ chunk->macroId = ltSPECIAL;
+ TexMacroDef *specialDef = (TexMacroDef *)MacroDefs.Get("special");
+ chunk->def = specialDef;
+ TexChunk *arg = new TexChunk(CHUNK_TYPE_ARG, specialDef);
+ chunk->children.Append((wxObject *)arg);
+ arg->argn = 1;
+ arg->macroId = chunk->macroId;
+
+ // The value in the first argument.
+ TexChunk *argValue = new TexChunk(CHUNK_TYPE_STRING);
+ arg->children.Append((wxObject *)argValue);
+ argValue->argn = 1;
+ argValue->value = copystring(wxBuffer);
+
+ children.Append((wxObject *)chunk);
+ }
+ else if (strncmp(buffer+pos, "verb", 4) == 0)
+ {
+ pos += 4;
+ if (buffer[pos] == '*')
+ pos ++;
+
+ // Find the delimiter character
+ int ch = buffer[pos];
+ pos ++;
+ // Now at start of verbatim text
+ int j = pos;
+ while ((buffer[pos] != ch) && buffer[pos] != 0)
+ pos ++;
+ char *val = new char[pos - j + 1];
+ int i;
+ for (i = j; i < pos; i++)
+ {
+ val[i-j] = buffer[i];
+ }
+ val[i-j] = 0;
+
+ pos ++;
+
+ TexChunk *chunk = new TexChunk(CHUNK_TYPE_MACRO);
+ chunk->no_args = 1;
+ chunk->macroId = ltVERB;
+ TexMacroDef *verbDef = (TexMacroDef *)MacroDefs.Get("verb");
+ chunk->def = verbDef;
+ TexChunk *arg = new TexChunk(CHUNK_TYPE_ARG, verbDef);
+ chunk->children.Append((wxObject *)arg);
+ arg->argn = 1;
+ arg->macroId = chunk->macroId;
+
+ // The value in the first argument.
+ TexChunk *argValue = new TexChunk(CHUNK_TYPE_STRING);
+ arg->children.Append((wxObject *)argValue);
+ argValue->argn = 1;
+ argValue->value = val;
+
+ children.Append((wxObject *)chunk);
+ }
+ else
+ {
+ char *env = NULL;
+ bool tmpParseToBrace = TRUE;
+ TexMacroDef *def = MatchMacro(buffer, &pos, &env, &tmpParseToBrace);
+ if (def)
+ {
+ CustomMacro *customMacro = FindCustomMacro(def->name);
+
+ TexChunk *chunk = new TexChunk(CHUNK_TYPE_MACRO, def);
+ chunk->no_args = def->no_args;
+// chunk->name = copystring(def->name);
+ chunk->macroId = def->macroId;
+
+ if (!customMacro)
+ children.Append((wxObject *)chunk);
+
+ // Eliminate newline after a \begin{} or a \\ if possible
+ if (env || strcmp(def->name, "\\") == 0)
+ if (buffer[pos] == 13)
+ {
+ pos ++;
+ if (buffer[pos] == 10)
+ pos ++;
+ }
+
+ pos = ParseMacroBody(def->name, chunk, chunk->no_args,
+ buffer, pos, env, tmpParseToBrace, customMacroArgs);
+
+ // If custom macro, parse the body substituting the above found args.
+ if (customMacro)
+ {
+ if (customMacro->macroBody)
+ {
+ char macroBuf[300];
+// strcpy(macroBuf, "{");
+ strcpy(macroBuf, customMacro->macroBody);
+ strcat(macroBuf, "}");
+ ParseArg(thisArg, children, macroBuf, 0, NULL, TRUE, chunk);
+ }
+
+// delete chunk; // Might delete children
+ }
+ }
+ else
+ {
+ MacroError(buffer+pos);
+ }
+ }
+ break;
+ }
+ // Parse constructs like {\bf thing} as if they were
+ // \bf{thing}
+ case '{':
+ {
+ pos ++;
+ if (buffer[pos] == '\\')
+ {
+ if (buf_ptr > 0)
+ {
+ TexChunk *chunk = new TexChunk(CHUNK_TYPE_STRING);
+ BigBuffer[buf_ptr] = 0;
+ buf_ptr = 0;
+ chunk->value = copystring(BigBuffer);
+ children.Append((wxObject *)chunk);
+ }
+ pos ++;
+
+ char *env;
+ bool tmpParseToBrace;
+ TexMacroDef *def = MatchMacro(buffer, &pos, &env, &tmpParseToBrace);
+ if (def)
+ {
+ CustomMacro *customMacro = FindCustomMacro(def->name);
+
+ TexChunk *chunk = new TexChunk(CHUNK_TYPE_MACRO, def);
+ chunk->no_args = def->no_args;
+// chunk->name = copystring(def->name);
+ chunk->macroId = def->macroId;
+ if (!customMacro)
+ children.Append((wxObject *)chunk);
+
+ pos = ParseMacroBody(def->name, chunk, chunk->no_args,
+ buffer, pos, NULL, TRUE, customMacroArgs);
+
+ // If custom macro, parse the body substituting the above found args.
+ if (customMacro)
+ {
+ if (customMacro->macroBody)
+ {
+ char macroBuf[300];
+// strcpy(macroBuf, "{");
+ strcpy(macroBuf, customMacro->macroBody);
+ strcat(macroBuf, "}");
+ ParseArg(thisArg, children, macroBuf, 0, NULL, TRUE, chunk);
+ }
+
+// delete chunk; // Might delete children
+ }
+ }
+ else
+ {
+ MacroError(buffer+pos);
+ }
+ }
+ else
+ {
+ /*
+ * If all else fails, we assume that we have
+ * a pair of braces on their own, so return a `dummy' macro
+ * definition with just one argument to parse.
+ */
+ if (!SoloBlockDef)
+ {
+ SoloBlockDef = new TexMacroDef(ltSOLO_BLOCK, "solo block", 1, FALSE);
+ }
+ // Save text so far
+ if (buf_ptr > 0)
+ {
+ TexChunk *chunk1 = new TexChunk(CHUNK_TYPE_STRING);
+ BigBuffer[buf_ptr] = 0;
+ buf_ptr = 0;
+ chunk1->value = copystring(BigBuffer);
+ children.Append((wxObject *)chunk1);
+ }
+ TexChunk *chunk = new TexChunk(CHUNK_TYPE_MACRO, SoloBlockDef);
+ chunk->no_args = SoloBlockDef->no_args;
+// chunk->name = copystring(SoloBlockDef->name);
+ chunk->macroId = SoloBlockDef->macroId;
+ children.Append((wxObject *)chunk);
+
+ TexChunk *arg = new TexChunk(CHUNK_TYPE_ARG, SoloBlockDef);
+
+ chunk->children.Append((wxObject *)arg);
+// arg->name = copystring(SoloBlockDef->name);
+ arg->argn = 1;
+ arg->macroId = chunk->macroId;
+
+ pos = ParseArg(arg, arg->children, buffer, pos, NULL, TRUE, customMacroArgs);
+ }
+ break;
+ }
+ case '$':
+ {
+ if (buf_ptr > 0)
+ {
+ TexChunk *chunk = new TexChunk(CHUNK_TYPE_STRING);
+ BigBuffer[buf_ptr] = 0;
+ buf_ptr = 0;
+ chunk->value = copystring(BigBuffer);
+ children.Append((wxObject *)chunk);
+ }
+
+ pos ++;
+
+ if (buffer[pos] == '$')
+ {
+ TexChunk *chunk = new TexChunk(CHUNK_TYPE_MACRO);
+ chunk->no_args = 0;
+// chunk->name = copystring("$$");
+ chunk->macroId = ltSPECIALDOUBLEDOLLAR;
+ children.Append((wxObject *)chunk);
+ pos ++;
+ }
+ else
+ {
+ TexChunk *chunk = new TexChunk(CHUNK_TYPE_MACRO);
+ chunk->no_args = 0;
+// chunk->name = copystring("_$");
+ chunk->macroId = ltSPECIALDOLLAR;
+ children.Append((wxObject *)chunk);
+ }
+ break;
+ }
+ case '~':
+ {
+ if (buf_ptr > 0)
+ {
+ TexChunk *chunk = new TexChunk(CHUNK_TYPE_STRING);
+ BigBuffer[buf_ptr] = 0;
+ buf_ptr = 0;
+ chunk->value = copystring(BigBuffer);
+ children.Append((wxObject *)chunk);
+ }
+
+ pos ++;
+ TexChunk *chunk = new TexChunk(CHUNK_TYPE_MACRO);
+ chunk->no_args = 0;
+// chunk->name = copystring("_~");
+ chunk->macroId = ltSPECIALTILDE;
+ children.Append((wxObject *)chunk);
+ break;
+ }
+ case '#': // Either treat as a special TeX character or as a macro arg
+ {
+ if (buf_ptr > 0)
+ {
+ TexChunk *chunk = new TexChunk(CHUNK_TYPE_STRING);
+ BigBuffer[buf_ptr] = 0;
+ buf_ptr = 0;
+ chunk->value = copystring(BigBuffer);
+ children.Append((wxObject *)chunk);
+ }
+
+ pos ++;
+ if (!customMacroArgs)
+ {
+ TexChunk *chunk = new TexChunk(CHUNK_TYPE_MACRO);
+ chunk->no_args = 0;
+// chunk->name = copystring("_#");
+ chunk->macroId = ltSPECIALHASH;
+ children.Append((wxObject *)chunk);
+ }
+ else
+ {
+ if (isdigit(buffer[pos]))
+ {
+ int n = buffer[pos] - 48;
+ pos ++;
+ wxNode *node = customMacroArgs->children.Nth(n-1);
+ if (node)
+ {
+ TexChunk *argChunk = (TexChunk *)node->Data();
+ children.Append((wxObject *)new TexChunk(*argChunk));
+ }
+ }
+ }
+ break;
+ }
+ case '&':
+ {
+ // Remove white space before and after the ampersand,
+ // since this is probably a table column separator with
+ // some convenient -- but useless -- white space in the text.
+ while ((buf_ptr > 0) && ((BigBuffer[buf_ptr-1] == ' ') || (BigBuffer[buf_ptr-1] == 9)))
+ buf_ptr --;
+
+ if (buf_ptr > 0)
+ {
+ TexChunk *chunk = new TexChunk(CHUNK_TYPE_STRING);
+ BigBuffer[buf_ptr] = 0;
+ buf_ptr = 0;
+ chunk->value = copystring(BigBuffer);
+ children.Append((wxObject *)chunk);
+ }
+
+ pos ++;
+
+ while (buffer[pos] == ' ' || buffer[pos] == 9)
+ pos ++;
+
+ TexChunk *chunk = new TexChunk(CHUNK_TYPE_MACRO);
+ chunk->no_args = 0;
+// chunk->name = copystring("_&");
+ chunk->macroId = ltSPECIALAMPERSAND;
+ children.Append((wxObject *)chunk);
+ break;
+ }
+ // Eliminate end-of-line comment
+ case '%':
+ {
+ ch = buffer[pos];
+ while (ch != 10 && ch != 13 && ch != 0)
+ {
+ pos ++;
+ ch = buffer[pos];
+ }
+ if (buffer[pos] == 10 || buffer[pos] == 13)
+ {
+ pos ++;
+ if (buffer[pos] == 10) pos ++; // Eliminate newline following DOS line feed
+ }
+ break;
+ }
+ // Eliminate tab
+ case 9:
+ {
+ BigBuffer[buf_ptr] = ' ';
+ BigBuffer[buf_ptr+1] = 0;
+ buf_ptr ++;
+ pos ++;
+ break;
+ }
+ default:
+ {
+ BigBuffer[buf_ptr] = ch;
+ BigBuffer[buf_ptr+1] = 0;
+ buf_ptr ++;
+ pos ++;
+ break;
+ }
+ }
+ }
+ return pos;
+}
+
+/*
+ * Consume as many arguments as the macro definition specifies
+ *
+ */
+
+int ParseMacroBody(char *macro_name, TexChunk *parent,
+ int no_args, char *buffer, int pos,
+ char *environment, bool parseToBrace,
+ TexChunk *customMacroArgs)
+{
+ Tex2RTFYield();
+ if (stopRunning) return pos;
+
+ // Check for a first optional argument
+ if (buffer[pos] == ' ' && buffer[pos+1] == '[')
+ {
+ // Fool following code into thinking that this is definitely
+ // an optional first argument. (If a space before a non-first argument,
+ // [ is interpreted as a [, not an optional argument.)
+ buffer[pos] = '!';
+ pos ++;
+ no_args ++;
+ }
+ else
+ if (buffer[pos] == '[')
+ no_args ++;
+
+ int maxArgs = 0;
+
+ int i;
+ for (i = 0; i < no_args; i++)
+ {
+ maxArgs ++;
+ TexChunk *arg = new TexChunk(CHUNK_TYPE_ARG, parent->def);
+
+ parent->children.Append((wxObject *)arg);
+// arg->name = copystring(macro_name);
+ arg->argn = maxArgs;
+ arg->macroId = parent->macroId;
+
+ // To parse the first arg of a 2 arg \begin{thing}{arg} ... \end{thing}
+ // have to fool parser into thinking this is a regular kind of block.
+ char *actualEnv;
+ if ((no_args == 2) && (i == 0))
+ actualEnv = NULL;
+ else
+ actualEnv = environment;
+
+ bool isOptional = FALSE;
+
+ // Remove the first { of the argument so it doesn't get recognized as { ... }
+// EatWhiteSpace(buffer, &pos);
+ if (!actualEnv)
+ {
+ // The reason for these tests is to not consume braces that don't
+ // belong to this macro.
+ // E.g. {\bf {\small thing}}
+ if ((pos > 0) && (buffer[pos-1] != ' ') && buffer[pos] == '{')
+ pos ++;
+ else
+ if ((pos > 0) && (buffer[pos-1] != ' ') && (buffer[pos] == '['))
+ {
+ isOptional = TRUE;
+ pos ++;
+ }
+ else if ((pos > 1) && (buffer[pos-1] != ' ') && (buffer[pos+1] == '['))
+ {
+ isOptional = TRUE;
+ pos += 2;
+ }
+ }
+ arg->optional = isOptional;
+
+ pos = ParseArg(arg, arg->children, buffer, pos, actualEnv, parseToBrace, customMacroArgs);
+
+ // If we've encountered an OPTIONAL argument, go another time around
+ // the loop, because we've got more than we thought.
+ // Hopefully optional args don't occur at the end of a macro use
+ // or we might miss it.
+ // Don't increment no of times round loop if the first optional arg
+ // -- we already did it before the loop.
+ if (arg->optional && (i > 0))
+ i --;
+ }
+ parent->no_args = maxArgs;
+
+ // Tell each argument how many args there are (useful when processing an arg)
+ wxNode *node = parent->children.First();
+ while (node)
+ {
+ TexChunk *chunk = (TexChunk *)node->Data();
+ chunk->no_args = maxArgs;
+ node = node->Next();
+ }
+ return pos;
+}
+
+bool TexLoadFile(char *filename)
+{
+ stopRunning = FALSE;
+ strcpy(TexFileRoot, filename);
+ StripExtension(TexFileRoot);
+ sprintf(TexBibName, "%s.bb", TexFileRoot);
+ sprintf(TexTmpBibName, "%s.bb1", TexFileRoot);
+
+ TexPathList.EnsureFileAccessible(filename);
+
+#ifdef __WXMSW__
+ static char *line_buffer = new char[600];
+#else
+ static char *line_buffer = new char[11000];
+#endif
+
+ Inputs[0] = fopen(filename, "r");
+ LineNumbers[0] = 1;
+ FileNames[0] = copystring(filename);
+ if (Inputs[0])
+ {
+ read_a_line(line_buffer);
+ ParseMacroBody("toplevel", TopLevel, 1, line_buffer, 0, NULL, TRUE);
+ if (Inputs[0]) fclose(Inputs[0]);
+ return TRUE;
+ }
+ else return FALSE;
+}
+
+TexMacroDef::TexMacroDef(int the_id, char *the_name, int n, bool ig, bool forbidLevel)
+{
+ name = copystring(the_name);
+ no_args = n;
+ ignore = ig;
+ macroId = the_id;
+ forbidden = forbidLevel;
+}
+
+TexMacroDef::~TexMacroDef(void)
+{
+ if (name) delete[] name;
+}
+
+TexChunk::TexChunk(int the_type, TexMacroDef *the_def)
+{
+ type = the_type;
+ no_args = 0;
+ argn = 0;
+// name = NULL;
+ def = the_def;
+ macroId = 0;
+ value = NULL;
+ optional = FALSE;
+}
+
+TexChunk::TexChunk(TexChunk& toCopy)
+{
+ type = toCopy.type;
+ no_args = toCopy.no_args;
+ argn = toCopy.argn;
+ macroId = toCopy.macroId;
+
+// if (toCopy.name)
+// name = copystring(toCopy.name);
+// else
+// name = NULL;
+ def = toCopy.def;
+
+ if (toCopy.value)
+ value = copystring(toCopy.value);
+ else
+ value = NULL;
+
+ optional = toCopy.optional;
+ wxNode *node = toCopy.children.First();
+ while (node)
+ {
+ TexChunk *child = (TexChunk *)node->Data();
+ children.Append((wxObject *)new TexChunk(*child));
+ node = node->Next();
+ }
+}
+
+TexChunk::~TexChunk(void)
+{
+// if (name) delete[] name;
+ if (value) delete[] value;
+ wxNode *node = children.First();
+ while (node)
+ {
+ TexChunk *child = (TexChunk *)node->Data();
+ delete child;
+ wxNode *next = node->Next();
+ delete node;
+ node = next;
+ }
+}
+
+bool IsArgOptional(void) // Is this argument an optional argument?
+{
+ return isArgOptional;
+}
+
+int GetNoArgs(void) // Number of args for this macro
+{
+ return noArgs;
+}
+
+/* Gets the text of a chunk on request (must be for small arguments
+ * only!)
+ *
+ */
+
+void GetArgData1(TexChunk *chunk)
+{
+ switch (chunk->type)
+ {
+ case CHUNK_TYPE_MACRO:
+ {
+ TexMacroDef *def = chunk->def;
+ if (def && def->ignore)
+ return;
+
+ if (def && (strcmp(def->name, "solo block") != 0))
+ {
+ strcat(currentArgData, "\\");
+ strcat(currentArgData, def->name);
+ }
+
+ wxNode *node = chunk->children.First();
+ while (node)
+ {
+ TexChunk *child_chunk = (TexChunk *)node->Data();
+ strcat(currentArgData, "{");
+ GetArgData1(child_chunk);
+ strcat(currentArgData, "}");
+ node = node->Next();
+ }
+ break;
+ }
+ case CHUNK_TYPE_ARG:
+ {
+ wxNode *node = chunk->children.First();
+ while (node)
+ {
+ TexChunk *child_chunk = (TexChunk *)node->Data();
+ GetArgData1(child_chunk);
+ node = node->Next();
+ }
+ break;
+ }
+ case CHUNK_TYPE_STRING:
+ {
+ if (chunk->value)
+ strcat(currentArgData, chunk->value);
+ break;
+ }
+ }
+}
+
+char *GetArgData(TexChunk *chunk)
+{
+ currentArgData[0] = 0;
+ GetArgData1(currentArgument);
+ haveArgData = FALSE;
+ return currentArgData;
+}
+
+char *GetArgData(void)
+{
+ if (!haveArgData)
+ {
+ currentArgData[0] = 0;
+ GetArgData1(currentArgument);
+ }
+ return currentArgData;
+}
+
+TexChunk *GetArgChunk(void)
+{
+ return currentArgument;
+}
+
+TexChunk *GetNextChunk(void) // Look ahead to the next chunk
+{
+ return nextChunk;
+}
+
+TexChunk *GetTopLevelChunk(void)
+{
+ return TopLevel;
+}
+
+int GetCurrentColumn(void)
+{
+ return currentColumn;
+}
+
+/*
+ * Traverses document calling functions to allow the client to
+ * write out the appropriate stuff
+ */
+
+
+void TraverseFromChunk(TexChunk *chunk, wxNode *thisNode, bool childrenOnly)
+{
+ Tex2RTFYield();
+ if (stopRunning) return;
+
+ switch (chunk->type)
+ {
+ case CHUNK_TYPE_MACRO:
+ {
+ TexMacroDef *def = chunk->def;
+ if (def && def->ignore)
+ return;
+
+ if (!childrenOnly)
+ OnMacro(chunk->macroId, chunk->no_args, TRUE);
+
+ wxNode *node = chunk->children.First();
+ while (node)
+ {
+ TexChunk *child_chunk = (TexChunk *)node->Data();
+ TraverseFromChunk(child_chunk, node);
+ node = node->Next();
+ }
+
+ if (thisNode && thisNode->Next()) nextChunk = (TexChunk *)thisNode->Next()->Data();
+
+ if (!childrenOnly)
+ OnMacro(chunk->macroId, chunk->no_args, FALSE);
+ break;
+ }
+ case CHUNK_TYPE_ARG:
+ {
+ currentArgument = chunk;
+
+ isArgOptional = chunk->optional;
+ noArgs = chunk->no_args;
+
+ // If OnArgument returns FALSE, don't output.
+
+ if (childrenOnly || OnArgument(chunk->macroId, chunk->argn, TRUE))
+ {
+ wxNode *node = chunk->children.First();
+ while (node)
+ {
+ TexChunk *child_chunk = (TexChunk *)node->Data();
+ TraverseFromChunk(child_chunk, node);
+ node = node->Next();
+ }
+ }
+
+ currentArgument = chunk;
+
+ if (thisNode && thisNode->Next()) nextChunk = (TexChunk *)thisNode->Next()->Data();
+
+ isArgOptional = chunk->optional;
+ noArgs = chunk->no_args;
+
+ if (!childrenOnly)
+ (void)OnArgument(chunk->macroId, chunk->argn, FALSE);
+ break;
+ }
+ case CHUNK_TYPE_STRING:
+ {
+ extern int issuedNewParagraph;
+ extern int forbidResetPar;
+ if (chunk->value && (forbidResetPar == 0))
+ {
+ // If non-whitespace text, we no longer have a new paragraph.
+ if (issuedNewParagraph && !((chunk->value[0] == 10 || chunk->value[0] == 13 || chunk->value[0] == 32)
+ && chunk->value[1] == 0))
+ issuedNewParagraph = FALSE;
+ TexOutput(chunk->value, TRUE);
+ }
+ break;
+ }
+ }
+}
+
+void TraverseDocument(void)
+{
+ TraverseFromChunk(TopLevel, NULL);
+}
+
+void SetCurrentOutput(FILE *fd)
+{
+ CurrentOutput1 = fd;
+ CurrentOutput2 = NULL;
+}
+
+void SetCurrentOutputs(FILE *fd1, FILE *fd2)
+{
+ CurrentOutput1 = fd1;
+ CurrentOutput2 = fd2;
+}
+
+void AddMacroDef(int the_id, char *name, int n, bool ignore, bool forbid)
+{
+ MacroDefs.Put(name, new TexMacroDef(the_id, name, n, ignore, forbid));
+}
+
+void TexInitialize(int bufSize)
+{
+ InitialiseColourTable();
+#ifdef __WXMSW__
+ TexPathList.AddEnvList("TEXINPUT");
+#endif
+#ifdef __UNIX__
+ TexPathList.AddEnvList("TEXINPUTS");
+#endif
+ int i;
+ for (i = 0; i < 15; i++)
+ {
+ Inputs[i] = NULL;
+ LineNumbers[i] = 1;
+ FileNames[i] = NULL;
+ }
+
+ IgnorableInputFiles.Add("psbox.tex");
+ BigBuffer = new char[(bufSize*1000)];
+ currentArgData = new char[2000];
+ TexFileRoot = new char[300];
+ TexBibName = new char[300];
+ TexTmpBibName = new char[300];
+ AddMacroDef(ltTOPLEVEL, "toplevel", 1);
+ TopLevel = new TexChunk(CHUNK_TYPE_MACRO);
+// TopLevel->name = copystring("toplevel");
+ TopLevel->macroId = ltTOPLEVEL;
+ TopLevel->no_args = 1;
+ VerbatimMacroDef = (TexMacroDef *)MacroDefs.Get("verbatim");
+}
+
+void TexCleanUp(void)
+{
+ int i;
+ for (i = 0; i < 15; i++)
+ Inputs[i] = NULL;
+
+ chapterNo = 0;
+ sectionNo = 0;
+ subsectionNo = 0;
+ subsubsectionNo = 0;
+ figureNo = 0;
+
+ CurrentOutput1 = NULL;
+ CurrentOutput2 = NULL;
+ CurrentInputIndex = 0;
+ haveArgData = FALSE;
+ noArgs = 0;
+
+ if (TopLevel)
+ delete TopLevel;
+ TopLevel = new TexChunk(CHUNK_TYPE_MACRO);
+// TopLevel->name = copystring("toplevel");
+ TopLevel->macroId = ltTOPLEVEL;
+ TopLevel->no_args = 1;
+
+ DocumentTitle = NULL;
+ DocumentAuthor = NULL;
+ DocumentDate = NULL;
+ DocumentStyle = LATEX_REPORT;
+ MinorDocumentStyle = 0;
+ BibliographyStyleString = copystring("plain");
+ DocumentStyleString = copystring("report");
+ MinorDocumentStyleString = NULL;
+/* Don't want to remove custom macros after each pass.
+ SetFontSizes(10);
+ wxNode *node = CustomMacroList.First();
+ while (node)
+ {
+ CustomMacro *macro = (CustomMacro *)node->Data();
+ delete macro;
+ delete node;
+ node = CustomMacroList.First();
+ }
+*/
+ TexReferences.BeginFind();
+ wxNode *node = TexReferences.Next();
+ while (node)
+ {
+ TexRef *ref = (TexRef *)node->Data();
+ delete ref;
+ node = TexReferences.Next();
+ }
+ TexReferences.Clear();
+
+ node = BibList.First();
+ while (node)
+ {
+ BibEntry *entry = (BibEntry *)node->Data();
+ delete entry;
+ delete node;
+ node = BibList.First();
+ }
+ CitationList.Clear();
+ ResetTopicCounter();
+}
+
+// There is likely to be one set of macros used by all utilities.
+void DefineDefaultMacros(void)
+{
+ // Put names which subsume other names at the TOP
+ // so they get recognized first
+
+ AddMacroDef(ltACCENT_GRAVE, "`", 1);
+ AddMacroDef(ltACCENT_ACUTE, "'", 1);
+ AddMacroDef(ltACCENT_CARET, "^", 1);
+ AddMacroDef(ltACCENT_UMLAUT, "\"", 1);
+ AddMacroDef(ltACCENT_TILDE, "~", 1);
+ AddMacroDef(ltACCENT_DOT, ".", 1);
+ AddMacroDef(ltACCENT_CADILLA, "c", 1);
+ AddMacroDef(ltSMALLSPACE1, ",", 0);
+ AddMacroDef(ltSMALLSPACE2, ";", 0);
+
+ AddMacroDef(ltABSTRACT, "abstract", 1);
+ AddMacroDef(ltADDCONTENTSLINE, "addcontentsline", 3);
+ AddMacroDef(ltADDTOCOUNTER, "addtocounter", 2);
+ AddMacroDef(ltALEPH, "aleph", 0);
+ AddMacroDef(ltALPHA, "alpha", 0);
+ AddMacroDef(ltALPH1, "alph", 1);
+ AddMacroDef(ltALPH2, "Alph", 1);
+ AddMacroDef(ltANGLE, "angle", 0);
+ AddMacroDef(ltAPPENDIX, "appendix", 0);
+ AddMacroDef(ltAPPROX, "approx", 0);
+ AddMacroDef(ltARABIC, "arabic", 1);
+ AddMacroDef(ltARRAY, "array", 1);
+ AddMacroDef(ltAST, "ast", 0);
+ AddMacroDef(ltASYMP, "asymp", 0);
+ AddMacroDef(ltAUTHOR, "author", 1);
+
+ AddMacroDef(ltBACKGROUNDCOLOUR, "backgroundcolour", 1);
+ AddMacroDef(ltBACKGROUNDIMAGE, "backgroundimage", 1);
+ AddMacroDef(ltBACKGROUND, "background", 1);
+ AddMacroDef(ltBACKSLASHRAW, "backslashraw", 0);
+ AddMacroDef(ltBACKSLASH, "backslash", 0);
+ AddMacroDef(ltBASELINESKIP, "baselineskip", 1);
+ AddMacroDef(ltBCOL, "bcol", 2);
+ AddMacroDef(ltBETA, "beta", 0);
+ AddMacroDef(ltBFSERIES, "bfseries", 1);
+ AddMacroDef(ltBF, "bf", 1);
+ AddMacroDef(ltBIBITEM, "bibitem", 2); // For convenience, bibitem has 2 args: label and item.
+ // The Latex syntax permits writing as 2 args.
+ AddMacroDef(ltBIBLIOGRAPHYSTYLE, "bibliographystyle", 1);
+ AddMacroDef(ltBIBLIOGRAPHY, "bibliography", 1);
+ AddMacroDef(ltBIGTRIANGLEDOWN, "bigtriangledown", 0);
+ AddMacroDef(ltBOT, "bot", 0);
+ AddMacroDef(ltBOXIT, "boxit", 1);
+ AddMacroDef(ltBOX, "box", 0);
+ AddMacroDef(ltBRCLEAR, "brclear", 0);
+ AddMacroDef(ltBULLET, "bullet", 0);
+
+ AddMacroDef(ltCAPTIONSTAR, "caption*", 1);
+ AddMacroDef(ltCAPTION, "caption", 1);
+ AddMacroDef(ltCAP, "cap", 0);
+ AddMacroDef(ltCDOTS, "cdots", 0);
+ AddMacroDef(ltCDOT, "cdot", 0);
+ AddMacroDef(ltCENTERLINE, "centerline", 1);
+ AddMacroDef(ltCENTERING, "centering", 0);
+ AddMacroDef(ltCENTER, "center", 1);
+ AddMacroDef(ltCEXTRACT, "cextract", 0);
+ AddMacroDef(ltCHAPTERHEADING, "chapterheading", 1);
+ AddMacroDef(ltCHAPTERSTAR, "chapter*", 1);
+ AddMacroDef(ltCHAPTER, "chapter", 1);
+ AddMacroDef(ltCHI, "chi", 0);
+ AddMacroDef(ltCINSERT, "cinsert", 0);
+ AddMacroDef(ltCIRC, "circ", 0);
+ AddMacroDef(ltCITE, "cite", 1);
+ AddMacroDef(ltCLASS, "class", 1);
+ AddMacroDef(ltCLEARDOUBLEPAGE, "cleardoublepage", 0);
+ AddMacroDef(ltCLEARPAGE, "clearpage", 0);
+ AddMacroDef(ltCLINE, "cline", 1);
+ AddMacroDef(ltCLIPSFUNC, "clipsfunc", 3);
+ AddMacroDef(ltCLUBSUIT, "clubsuit", 0);
+ AddMacroDef(ltCOLUMNSEP, "columnsep", 1);
+ AddMacroDef(ltCOMMENT, "comment", 1, TRUE);
+ AddMacroDef(ltCONG, "cong", 0);
+ AddMacroDef(ltCOPYRIGHT, "copyright", 0);
+ AddMacroDef(ltCPARAM, "cparam", 2);
+ AddMacroDef(ltCHEAD, "chead", 1);
+ AddMacroDef(ltCFOOT, "cfoot", 1);
+ AddMacroDef(ltCUP, "cup", 0);
+
+ AddMacroDef(ltDASHV, "dashv", 0);
+ AddMacroDef(ltDATE, "date", 1);
+ AddMacroDef(ltDELTA, "delta", 0);
+ AddMacroDef(ltCAP_DELTA, "Delta", 0);
+ AddMacroDef(ltDEFINECOLOUR, "definecolour", 4);
+ AddMacroDef(ltDEFINECOLOR, "definecolor", 4);
+ AddMacroDef(ltDESCRIPTION, "description", 1);
+ AddMacroDef(ltDESTRUCT, "destruct", 1);
+ AddMacroDef(ltDIAMOND2, "diamond2", 0);
+ AddMacroDef(ltDIAMOND, "diamond", 0);
+ AddMacroDef(ltDIV, "div", 0);
+ AddMacroDef(ltDOCUMENTCLASS, "documentclass", 1);
+ AddMacroDef(ltDOCUMENTSTYLE, "documentstyle", 1);
+ AddMacroDef(ltDOCUMENT, "document", 1);
+ AddMacroDef(ltDOUBLESPACE, "doublespace", 1);
+ AddMacroDef(ltDOTEQ, "doteq", 0);
+ AddMacroDef(ltDOWNARROW, "downarrow", 0);
+ AddMacroDef(ltDOWNARROW2, "Downarrow", 0);
+
+ AddMacroDef(ltEMPTYSET, "emptyset", 0);
+ AddMacroDef(ltEMPH, "emph", 1);
+ AddMacroDef(ltEM, "em", 1);
+ AddMacroDef(ltENUMERATE, "enumerate", 1);
+ AddMacroDef(ltEPSILON, "epsilon", 0);
+ AddMacroDef(ltEQUATION, "equation", 1);
+ AddMacroDef(ltEQUIV, "equiv", 0);
+ AddMacroDef(ltETA, "eta", 0);
+ AddMacroDef(ltEVENSIDEMARGIN, "evensidemargin", 1);
+ AddMacroDef(ltEXISTS, "exists", 0);
+
+ AddMacroDef(ltFBOX, "fbox", 1);
+ AddMacroDef(ltFCOL, "fcol", 2);
+ AddMacroDef(ltFIGURE, "figure", 1);
+ AddMacroDef(ltFIGURESTAR, "figure*", 1);
+ AddMacroDef(ltFLUSHLEFT, "flushleft", 1);
+ AddMacroDef(ltFLUSHRIGHT, "flushright", 1);
+ AddMacroDef(ltFOLLOWEDLINKCOLOUR, "followedlinkcolour", 1);
+ AddMacroDef(ltFOOTHEIGHT, "footheight", 1);
+ AddMacroDef(ltFOOTNOTEPOPUP, "footnotepopup", 2);
+ AddMacroDef(ltFOOTNOTE, "footnote", 1);
+ AddMacroDef(ltFOOTSKIP, "footskip", 1);
+ AddMacroDef(ltFORALL, "forall", 0);
+ AddMacroDef(ltFRAMEBOX, "framebox", 1);
+ AddMacroDef(ltFROWN, "frown", 0);
+ AddMacroDef(ltFUNCTIONSECTION, "functionsection", 1);
+ AddMacroDef(ltFUNC, "func", 3);
+ AddMacroDef(ltFOOTNOTESIZE, "footnotesize", 0);
+ AddMacroDef(ltFANCYPLAIN, "fancyplain", 2);
+
+ AddMacroDef(ltGAMMA, "gamma", 0);
+ AddMacroDef(ltCAP_GAMMA, "Gamma", 0);
+ AddMacroDef(ltGEQ, "geq", 0);
+ AddMacroDef(ltGE, "ge", 0);
+ AddMacroDef(ltGG, "gg", 0);
+ AddMacroDef(ltGLOSSARY, "glossary", 1);
+ AddMacroDef(ltGLOSS, "gloss", 1);
+
+ AddMacroDef(ltHEADHEIGHT, "headheight", 1);
+ AddMacroDef(ltHEARTSUIT, "heartsuit", 0);
+ AddMacroDef(ltHELPGLOSSARY, "helpglossary", 1);
+ AddMacroDef(ltHELPIGNORE, "helpignore", 1, TRUE);
+ AddMacroDef(ltHELPONLY, "helponly", 1);
+ AddMacroDef(ltHELPINPUT, "helpinput", 1);
+ AddMacroDef(ltHELPFONTFAMILY, "helpfontfamily", 1);
+ AddMacroDef(ltHELPFONTSIZE, "helpfontsize", 1);
+ AddMacroDef(ltHELPREFN, "helprefn", 2);
+ AddMacroDef(ltHELPREF, "helpref", 2);
+ AddMacroDef(ltHFILL, "hfill", 0);
+ AddMacroDef(ltHLINE, "hline", 0);
+ AddMacroDef(ltHRULE, "hrule", 0);
+ AddMacroDef(ltHSPACESTAR, "hspace*", 1);
+ AddMacroDef(ltHSPACE, "hspace", 1);
+ AddMacroDef(ltHSKIPSTAR, "hskip*", 1);
+ AddMacroDef(ltHSKIP, "hskip", 1);
+ AddMacroDef(lthuge, "huge", 1);
+ AddMacroDef(ltHuge, "Huge", 1);
+ AddMacroDef(ltHUGE, "HUGE", 1);
+ AddMacroDef(ltHTMLIGNORE, "htmlignore", 1);
+ AddMacroDef(ltHTMLONLY, "htmlonly", 1);
+
+ AddMacroDef(ltIM, "im", 0);
+ AddMacroDef(ltINCLUDEONLY, "includeonly", 1);
+ AddMacroDef(ltINCLUDE, "include", 1);
+ AddMacroDef(ltINDENTED, "indented", 2);
+ AddMacroDef(ltINDEX, "index", 1);
+ AddMacroDef(ltINPUT, "input", 1, TRUE);
+ AddMacroDef(ltIOTA, "iota", 0);
+ AddMacroDef(ltITEMIZE, "itemize", 1);
+ AddMacroDef(ltITEM, "item", 0);
+ AddMacroDef(ltIMAGEMAP, "imagemap", 3);
+ AddMacroDef(ltIMAGEL, "imagel", 2);
+ AddMacroDef(ltIMAGER, "imager", 2);
+ AddMacroDef(ltIMAGE, "image", 2);
+ AddMacroDef(ltIN, "in", 0);
+ AddMacroDef(ltINFTY, "infty", 0);
+ AddMacroDef(ltITSHAPE, "itshape", 1);
+ AddMacroDef(ltIT, "it", 1);
+ AddMacroDef(ltITEMSEP, "itemsep", 1);
+ AddMacroDef(ltINSERTATLEVEL, "insertatlevel", 2);
+
+ AddMacroDef(ltKAPPA, "kappa", 0);
+ AddMacroDef(ltKILL, "kill", 0);
+
+ AddMacroDef(ltLABEL, "label", 1);
+ AddMacroDef(ltLAMBDA, "lambda", 0);
+ AddMacroDef(ltCAP_LAMBDA, "Lambda", 0);
+ AddMacroDef(ltlarge, "large", 1);
+ AddMacroDef(ltLarge, "Large", 1);
+ AddMacroDef(ltLARGE, "LARGE", 1);
+ AddMacroDef(ltLATEXIGNORE, "latexignore", 1);
+ AddMacroDef(ltLATEXONLY, "latexonly", 1);
+ AddMacroDef(ltLATEX, "LaTeX", 0);
+ AddMacroDef(ltLBOX, "lbox", 1);
+ AddMacroDef(ltLBRACERAW, "lbraceraw", 0);
+ AddMacroDef(ltLDOTS, "ldots", 0);
+ AddMacroDef(ltLEQ, "leq", 0);
+ AddMacroDef(ltLE, "le", 0);
+ AddMacroDef(ltLEFTARROW, "leftarrow", 0);
+ AddMacroDef(ltLEFTRIGHTARROW, "leftrightarrow", 0);
+ AddMacroDef(ltLEFTARROW2, "Leftarrow", 0);
+ AddMacroDef(ltLEFTRIGHTARROW2, "Leftrightarrow", 0);
+ AddMacroDef(ltLINEBREAK, "linebreak", 0);
+ AddMacroDef(ltLINKCOLOUR, "linkcolour", 1);
+ AddMacroDef(ltLISTOFFIGURES, "listoffigures", 0);
+ AddMacroDef(ltLISTOFTABLES, "listoftables", 0);
+ AddMacroDef(ltLHEAD, "lhead", 1);
+ AddMacroDef(ltLFOOT, "lfoot", 1);
+ AddMacroDef(ltLOWERCASE, "lowercase", 1);
+ AddMacroDef(ltLL, "ll", 0);
+
+ AddMacroDef(ltMAKEGLOSSARY, "makeglossary", 0);
+ AddMacroDef(ltMAKEINDEX, "makeindex", 0);
+ AddMacroDef(ltMAKETITLE, "maketitle", 0);
+ AddMacroDef(ltMARKRIGHT, "markright", 1);
+ AddMacroDef(ltMARKBOTH, "markboth", 2);
+ AddMacroDef(ltMARGINPARWIDTH, "marginparwidth", 1);
+ AddMacroDef(ltMARGINPARSEP, "marginparsep", 1);
+ AddMacroDef(ltMARGINPARODD, "marginparodd", 1);
+ AddMacroDef(ltMARGINPAREVEN, "marginpareven", 1);
+ AddMacroDef(ltMARGINPAR, "marginpar", 1);
+ AddMacroDef(ltMBOX, "mbox", 1);
+ AddMacroDef(ltMDSERIES, "mdseries", 1);
+ AddMacroDef(ltMEMBERSECTION, "membersection", 1);
+ AddMacroDef(ltMEMBER, "member", 2);
+ AddMacroDef(ltMID, "mid", 0);
+ AddMacroDef(ltMODELS, "models", 0);
+ AddMacroDef(ltMP, "mp", 0);
+ AddMacroDef(ltMULTICOLUMN, "multicolumn", 3);
+ AddMacroDef(ltMU, "mu", 0);
+
+ AddMacroDef(ltNABLA, "nabla", 0);
+ AddMacroDef(ltNEG, "neg", 0);
+ AddMacroDef(ltNEQ, "neq", 0);
+ AddMacroDef(ltNEWCOUNTER, "newcounter", 1, FALSE, FORBID_ABSOLUTELY);
+ AddMacroDef(ltNEWLINE, "newline", 0);
+ AddMacroDef(ltNEWPAGE, "newpage", 0);
+ AddMacroDef(ltNI, "ni", 0);
+ AddMacroDef(ltNOCITE, "nocite", 1);
+ AddMacroDef(ltNOINDENT, "noindent", 0);
+ AddMacroDef(ltNOLINEBREAK, "nolinebreak", 0);
+ AddMacroDef(ltNOPAGEBREAK, "nopagebreak", 0);
+ AddMacroDef(ltNORMALSIZE, "normalsize", 1);
+ AddMacroDef(ltNORMALBOX, "normalbox", 1);
+ AddMacroDef(ltNORMALBOXD, "normalboxd", 1);
+ AddMacroDef(ltNOTEQ, "noteq", 0);
+ AddMacroDef(ltNOTIN, "notin", 0);
+ AddMacroDef(ltNOTSUBSET, "notsubset", 0);
+ AddMacroDef(ltNU, "nu", 0);
+
+ AddMacroDef(ltODDSIDEMARGIN, "oddsidemargin", 1);
+ AddMacroDef(ltOMEGA, "omega", 0);
+ AddMacroDef(ltCAP_OMEGA, "Omega", 0);
+ AddMacroDef(ltONECOLUMN, "onecolumn", 0);
+ AddMacroDef(ltOPLUS, "oplus", 0);
+ AddMacroDef(ltOSLASH, "oslash", 0);
+ AddMacroDef(ltOTIMES, "otimes", 0);
+
+ AddMacroDef(ltPAGEBREAK, "pagebreak", 0);
+ AddMacroDef(ltPAGEREF, "pageref", 1);
+ AddMacroDef(ltPAGESTYLE, "pagestyle", 1);
+ AddMacroDef(ltPAGENUMBERING, "pagenumbering", 1);
+ AddMacroDef(ltPARAGRAPHSTAR, "paragraph*", 1);
+ AddMacroDef(ltPARAGRAPH, "paragraph", 1);
+ AddMacroDef(ltPARALLEL, "parallel", 0);
+ AddMacroDef(ltPARAM, "param", 2);
+ AddMacroDef(ltPARINDENT, "parindent", 1);
+ AddMacroDef(ltPARSKIP, "parskip", 1);
+ AddMacroDef(ltPARTIAL, "partial", 0);
+ AddMacroDef(ltPARTSTAR, "part*", 1);
+ AddMacroDef(ltPART, "part", 1);
+ AddMacroDef(ltPAR, "par", 0);
+ AddMacroDef(ltPERP, "perp", 0);
+ AddMacroDef(ltPHI, "phi", 0);
+ AddMacroDef(ltCAP_PHI, "Phi", 0);
+ AddMacroDef(ltPFUNC, "pfunc", 3);
+ AddMacroDef(ltPICTURE, "picture", 1);
+ AddMacroDef(ltPI, "pi", 0);
+ AddMacroDef(ltCAP_PI, "Pi", 0);
+ AddMacroDef(ltPM, "pm", 0);
+ AddMacroDef(ltPOPREFONLY, "poprefonly", 1);
+ AddMacroDef(ltPOPREF, "popref", 2);
+ AddMacroDef(ltPOUNDS, "pounds", 0);
+ AddMacroDef(ltPREC, "prec", 0);
+ AddMacroDef(ltPRECEQ, "preceq", 0);
+ AddMacroDef(ltPRINTINDEX, "printindex", 0);
+ AddMacroDef(ltPROPTO, "propto", 0);
+ AddMacroDef(ltPSBOXTO, "psboxto", 1, FALSE, FORBID_ABSOLUTELY);
+ AddMacroDef(ltPSBOX, "psbox", 1, FALSE, FORBID_ABSOLUTELY);
+ AddMacroDef(ltPSI, "psi", 0);
+ AddMacroDef(ltCAP_PSI, "Psi", 0);
+
+ AddMacroDef(ltQUOTE, "quote", 1);
+ AddMacroDef(ltQUOTATION, "quotation", 1);
+
+ AddMacroDef(ltRAGGEDBOTTOM, "raggedbottom", 0);
+ AddMacroDef(ltRAGGEDLEFT, "raggedleft", 0);
+ AddMacroDef(ltRAGGEDRIGHT, "raggedright", 0);
+ AddMacroDef(ltRBRACERAW, "rbraceraw", 0);
+ AddMacroDef(ltREF, "ref", 1);
+ AddMacroDef(ltREGISTERED, "registered", 0);
+ AddMacroDef(ltRE, "we", 0);
+ AddMacroDef(ltRHO, "rho", 0);
+ AddMacroDef(ltRIGHTARROW, "rightarrow", 0);
+ AddMacroDef(ltRIGHTARROW2, "rightarrow2", 0);
+ AddMacroDef(ltRMFAMILY, "rmfamily", 1);
+ AddMacroDef(ltRM, "rm", 1);
+ AddMacroDef(ltROMAN, "roman", 1);
+ AddMacroDef(ltROMAN2, "Roman", 1);
+// AddMacroDef(lt"row", 1);
+ AddMacroDef(ltRTFSP, "rtfsp", 0);
+ AddMacroDef(ltRTFIGNORE, "rtfignore", 1);
+ AddMacroDef(ltRTFONLY, "rtfonly", 1);
+ AddMacroDef(ltRULEDROW, "ruledrow", 1);
+ AddMacroDef(ltDRULED, "druled", 1);
+ AddMacroDef(ltRULE, "rule", 2);
+ AddMacroDef(ltRHEAD, "rhead", 1);
+ AddMacroDef(ltRFOOT, "rfoot", 1);
+ AddMacroDef(ltROW, "row", 1);
+
+ AddMacroDef(ltSCSHAPE, "scshape", 1);
+ AddMacroDef(ltSC, "sc", 1);
+ AddMacroDef(ltSECTIONHEADING, "sectionheading", 1);
+ AddMacroDef(ltSECTIONSTAR, "section*", 1);
+ AddMacroDef(ltSECTION, "section", 1);
+ AddMacroDef(ltSETCOUNTER, "setcounter", 2);
+ AddMacroDef(ltSFFAMILY, "sffamily", 1);
+ AddMacroDef(ltSF, "sf", 1);
+ AddMacroDef(ltSHARP, "sharp", 0);
+ AddMacroDef(ltSHORTCITE, "shortcite", 1);
+ AddMacroDef(ltSIGMA, "sigma", 0);
+ AddMacroDef(ltCAP_SIGMA, "Sigma", 0);
+ AddMacroDef(ltSIM, "sim", 0);
+ AddMacroDef(ltSIMEQ, "simeq", 0);
+ AddMacroDef(ltSINGLESPACE, "singlespace", 1);
+ AddMacroDef(ltSIZEDBOX, "sizedbox", 2);
+ AddMacroDef(ltSIZEDBOXD, "sizedboxd", 2);
+ AddMacroDef(ltSLOPPYPAR, "sloppypar", 1);
+ AddMacroDef(ltSLOPPY, "sloppy", 0);
+ AddMacroDef(ltSLSHAPE, "slshape", 1);
+ AddMacroDef(ltSL, "sl", 1);
+ AddMacroDef(ltSMALL, "small", 1);
+ AddMacroDef(ltSMILE, "smile", 0);
+ AddMacroDef(ltSS, "ss", 0);
+ AddMacroDef(ltSTAR, "star", 0);
+ AddMacroDef(ltSUBITEM, "subitem", 0);
+ AddMacroDef(ltSUBPARAGRAPHSTAR, "subparagraph*", 1);
+ AddMacroDef(ltSUBPARAGRAPH, "subparagraph", 1);
+ AddMacroDef(ltSPECIAL, "special", 1);
+ AddMacroDef(ltSUBSECTIONSTAR, "subsection*", 1);
+ AddMacroDef(ltSUBSECTION, "subsection", 1);
+ AddMacroDef(ltSUBSETEQ, "subseteq", 0);
+ AddMacroDef(ltSUBSET, "subset", 0);
+ AddMacroDef(ltSUCC, "succ", 0);
+ AddMacroDef(ltSUCCEQ, "succeq", 0);
+ AddMacroDef(ltSUPSETEQ, "supseteq", 0);
+ AddMacroDef(ltSUPSET, "supset", 0);
+ AddMacroDef(ltSUBSUBSECTIONSTAR,"subsubsection*", 1);
+ AddMacroDef(ltSUBSUBSECTION, "subsubsection", 1);
+ AddMacroDef(ltSUPERTABULAR, "supertabular", 2, FALSE);
+ AddMacroDef(ltSURD, "surd", 0);
+ AddMacroDef(ltSCRIPTSIZE, "scriptsize", 1);
+ AddMacroDef(ltSETHEADER, "setheader", 6);
+ AddMacroDef(ltSETFOOTER, "setfooter", 6);
+ AddMacroDef(ltSETHOTSPOTCOLOUR, "sethotspotcolour", 1);
+ AddMacroDef(ltSETHOTSPOTCOLOR, "sethotspotcolor", 1);
+ AddMacroDef(ltSETHOTSPOTUNDERLINE, "sethotspotunderline", 1);
+ AddMacroDef(ltSETTRANSPARENCY, "settransparency", 1);
+ AddMacroDef(ltSPADESUIT, "spadesuit", 0);
+
+ AddMacroDef(ltTABBING, "tabbing", 2);
+ AddMacroDef(ltTABLEOFCONTENTS, "tableofcontents", 0);
+ AddMacroDef(ltTABLE, "table", 1);
+ AddMacroDef(ltTABULAR, "tabular", 2, FALSE);
+ AddMacroDef(ltTAB, "tab", 0);
+ AddMacroDef(ltTAU, "tau", 0);
+ AddMacroDef(ltTEXTRM, "textrm", 1);
+ AddMacroDef(ltTEXTSF, "textsf", 1);
+ AddMacroDef(ltTEXTTT, "texttt", 1);
+ AddMacroDef(ltTEXTBF, "textbf", 1);
+ AddMacroDef(ltTEXTIT, "textit", 1);
+ AddMacroDef(ltTEXTSL, "textsl", 1);
+ AddMacroDef(ltTEXTSC, "textsc", 1);
+ AddMacroDef(ltTEXTWIDTH, "textwidth", 1);
+ AddMacroDef(ltTEXTHEIGHT, "textheight", 1);
+ AddMacroDef(ltTEXTCOLOUR, "textcolour", 1);
+ AddMacroDef(ltTEX, "TeX", 0);
+ AddMacroDef(ltTHEBIBLIOGRAPHY, "thebibliography", 2);
+ AddMacroDef(ltTHETA, "theta", 0);
+ AddMacroDef(ltTIMES, "times", 0);
+ AddMacroDef(ltCAP_THETA, "Theta", 0);
+ AddMacroDef(ltTITLEPAGE, "titlepage", 1);
+ AddMacroDef(ltTITLE, "title", 1);
+ AddMacroDef(ltTINY, "tiny", 1);
+ AddMacroDef(ltTODAY, "today", 0);
+ AddMacroDef(ltTOPMARGIN, "topmargin", 1);
+ AddMacroDef(ltTOPSKIP, "topskip", 1);
+ AddMacroDef(ltTRIANGLE, "triangle", 0);
+ AddMacroDef(ltTTFAMILY, "ttfamily", 1);
+ AddMacroDef(ltTT, "tt", 1);
+ AddMacroDef(ltTYPEIN, "typein", 1);
+ AddMacroDef(ltTYPEOUT, "typeout", 1);
+ AddMacroDef(ltTWOCOLWIDTHA, "twocolwidtha", 1);
+ AddMacroDef(ltTWOCOLWIDTHB, "twocolwidthb", 1);
+ AddMacroDef(ltTWOCOLSPACING, "twocolspacing", 1);
+ AddMacroDef(ltTWOCOLITEMRULED, "twocolitemruled", 2);
+ AddMacroDef(ltTWOCOLITEM, "twocolitem", 2);
+ AddMacroDef(ltTWOCOLLIST, "twocollist", 1);
+ AddMacroDef(ltTWOCOLUMN, "twocolumn", 0);
+ AddMacroDef(ltTHEPAGE, "thepage", 0);
+ AddMacroDef(ltTHECHAPTER, "thechapter", 0);
+ AddMacroDef(ltTHESECTION, "thesection", 0);
+ AddMacroDef(ltTHISPAGESTYLE, "thispagestyle", 1);
+
+ AddMacroDef(ltUNDERLINE, "underline", 1);
+ AddMacroDef(ltUPSILON, "upsilon", 0);
+ AddMacroDef(ltCAP_UPSILON, "Upsilon", 0);
+ AddMacroDef(ltUPARROW, "uparrow", 0);
+ AddMacroDef(ltUPARROW2, "Uparrow", 0);
+ AddMacroDef(ltUPPERCASE, "uppercase", 1);
+ AddMacroDef(ltUPSHAPE, "upshape", 1);
+ AddMacroDef(ltURLREF, "urlref", 2);
+ AddMacroDef(ltUSEPACKAGE, "usepackage", 1);
+
+ AddMacroDef(ltVAREPSILON, "varepsilon", 0);
+ AddMacroDef(ltVARPHI, "varphi", 0);
+ AddMacroDef(ltVARPI, "varpi", 0);
+ AddMacroDef(ltVARRHO, "varrho", 0);
+ AddMacroDef(ltVARSIGMA, "varsigma", 0);
+ AddMacroDef(ltVARTHETA, "vartheta", 0);
+ AddMacroDef(ltVDOTS, "vdots", 0);
+ AddMacroDef(ltVEE, "vee", 0);
+ AddMacroDef(ltVERBATIMINPUT, "verbatiminput", 1);
+ AddMacroDef(ltVERBATIM, "verbatim", 1);
+ AddMacroDef(ltVERBSTAR, "verb*", 1);
+ AddMacroDef(ltVERB, "verb", 1);
+ AddMacroDef(ltVERSE, "verse", 1);
+ AddMacroDef(ltVFILL, "vfill", 0);
+ AddMacroDef(ltVLINE, "vline", 0);
+ AddMacroDef(ltVOID, "void", 0);
+ AddMacroDef(ltVDASH, "vdash", 0);
+ AddMacroDef(ltVRULE, "vrule", 0);
+ AddMacroDef(ltVSPACESTAR, "vspace*", 1);
+ AddMacroDef(ltVSKIPSTAR, "vskip*", 1);
+ AddMacroDef(ltVSPACE, "vspace", 1);
+ AddMacroDef(ltVSKIP, "vskip", 1);
+
+ AddMacroDef(ltWEDGE, "wedge", 0);
+ AddMacroDef(ltWXCLIPS, "wxclips", 0);
+ AddMacroDef(ltWINHELPIGNORE, "winhelpignore", 1);
+ AddMacroDef(ltWINHELPONLY, "winhelponly", 1);
+ AddMacroDef(ltWP, "wp", 0);
+
+ AddMacroDef(ltXI, "xi", 0);
+ AddMacroDef(ltCAP_XI, "Xi", 0);
+ AddMacroDef(ltXLPIGNORE, "xlpignore", 1);
+ AddMacroDef(ltXLPONLY, "xlponly", 1);
+
+ AddMacroDef(ltZETA, "zeta", 0);
+
+ AddMacroDef(ltSPACE, " ", 0);
+ AddMacroDef(ltBACKSLASHCHAR, "\\", 0);
+ AddMacroDef(ltPIPE, "|", 0);
+ AddMacroDef(ltFORWARDSLASH, "/", 0);
+ AddMacroDef(ltUNDERSCORE, "_", 0);
+ AddMacroDef(ltAMPERSAND, "&", 0);
+ AddMacroDef(ltPERCENT, "%", 0);
+ AddMacroDef(ltDOLLAR, "$", 0);
+ AddMacroDef(ltHASH, "#", 0);
+ AddMacroDef(ltLPARENTH, "(", 0);
+ AddMacroDef(ltRPARENTH, ")", 0);
+ AddMacroDef(ltLBRACE, "{", 0);
+ AddMacroDef(ltRBRACE, "}", 0);
+// AddMacroDef(ltEQUALS, "=", 0);
+ AddMacroDef(ltRANGLEBRA, ">", 0);
+ AddMacroDef(ltLANGLEBRA, "<", 0);
+ AddMacroDef(ltPLUS, "+", 0);
+ AddMacroDef(ltDASH, "-", 0);
+ AddMacroDef(ltAT_SYMBOL, "@", 0);
+// AddMacroDef(ltSINGLEQUOTE, "'", 0);
+// AddMacroDef(ltBACKQUOTE, "`", 0);
+}
+
+/*
+ * Default behaviour, should be called by client if can't match locally.
+ *
+ */
+
+// Called on start/end of macro examination
+void DefaultOnMacro(int macroId, int no_args, bool start)
+{
+ switch (macroId)
+ {
+ // Default behaviour for abstract
+ case ltABSTRACT:
+ {
+ if (start)
+ {
+ // Write the heading
+ FakeCurrentSection(AbstractNameString);
+ OnMacro(ltPAR, 0, TRUE);
+ OnMacro(ltPAR, 0, FALSE);
+ }
+ else
+ {
+ if (DocumentStyle == LATEX_ARTICLE)
+ sectionNo --;
+ else
+ chapterNo --;
+ }
+ break;
+ }
+
+ // Default behaviour for glossary
+ case ltHELPGLOSSARY:
+ {
+ if (start)
+ {
+ // Write the heading
+ FakeCurrentSection(GlossaryNameString);
+ OnMacro(ltPAR, 0, TRUE);
+ OnMacro(ltPAR, 0, FALSE);
+ if ((convertMode == TEX_RTF) && !winHelp)
+ {
+ OnMacro(ltPAR, 0, TRUE);
+ OnMacro(ltPAR, 0, FALSE);
+ }
+ }
+ break;
+ }
+ case ltSPECIALAMPERSAND:
+ if (start)
+ TexOutput(" ");
+ break;
+
+ case ltCINSERT:
+ if (start)
+ TexOutput("<<", TRUE);
+ break;
+ case ltCEXTRACT:
+ if (start)
+ TexOutput(">>", TRUE);
+ break;
+ case ltDESTRUCT:
+ if (start)
+ TexOutput("~", TRUE);
+ break;
+ case ltTILDE:
+ if (start)
+ TexOutput("~", TRUE);
+ break;
+ case ltSPECIALTILDE:
+ if (start)
+ TexOutput(" ", TRUE);
+ break;
+ case ltUNDERSCORE:
+ if (start)
+ TexOutput("_", TRUE);
+ break;
+ case ltHASH:
+ if (start)
+ TexOutput("#", TRUE);
+ break;
+ case ltAMPERSAND:
+ if (start)
+ TexOutput("&", TRUE);
+ break;
+ case ltSPACE:
+ if (start)
+ TexOutput(" ", TRUE);
+ break;
+ case ltPIPE:
+ if (start)
+ TexOutput("|", TRUE);
+ break;
+ case ltPERCENT:
+ if (start)
+ TexOutput("%", TRUE);
+ break;
+ case ltDOLLAR:
+ if (start)
+ TexOutput("$", TRUE);
+ break;
+ case ltLPARENTH:
+ if (start)
+ TexOutput("", TRUE);
+ break;
+ case ltRPARENTH:
+ if (start)
+ TexOutput("", TRUE);
+ break;
+ case ltLBRACE:
+ if (start)
+ TexOutput("{", TRUE);
+ break;
+ case ltRBRACE:
+ if (start)
+ TexOutput("}", TRUE);
+ break;
+ case ltCOPYRIGHT:
+ if (start)
+ TexOutput("(c)", TRUE);
+ break;
+ case ltREGISTERED:
+ if (start)
+ TexOutput("(r)", TRUE);
+ break;
+ case ltBACKSLASH:
+ if (start)
+ TexOutput("\\", TRUE);
+ break;
+ case ltLDOTS:
+ case ltCDOTS:
+ if (start)
+ TexOutput("...", TRUE);
+ break;
+ case ltVDOTS:
+ if (start)
+ TexOutput("|", TRUE);
+ break;
+ case ltLATEX:
+ if (start)
+ TexOutput("LaTeX", TRUE);
+ break;
+ case ltTEX:
+ if (start)
+ TexOutput("TeX", TRUE);
+ break;
+ case ltPOUNDS:
+ if (start)
+ TexOutput("£", TRUE);
+ break;
+ case ltSPECIALDOUBLEDOLLAR: // Interpret as center
+ OnMacro(ltCENTER, no_args, start);
+ break;
+ case ltEMPH:
+ case ltTEXTSL:
+ case ltSLSHAPE:
+ case ltSL:
+ OnMacro(ltIT, no_args, start);
+ break;
+ case ltPARAGRAPH:
+ case ltPARAGRAPHSTAR:
+ case ltSUBPARAGRAPH:
+ case ltSUBPARAGRAPHSTAR:
+ OnMacro(ltSUBSUBSECTION, no_args, start);
+ break;
+ case ltTODAY:
+ {
+ if (start)
+ {
+ time_t when;
+ (void) time(&when);
+ TexOutput(ctime(&when), TRUE);
+ }
+ break;
+ }
+ case ltNOINDENT:
+ if (start)
+ ParIndent = 0;
+ break;
+
+ // Symbols
+ case ltALPHA:
+ if (start) TexOutput("alpha");
+ break;
+ case ltBETA:
+ if (start) TexOutput("beta");
+ break;
+ case ltGAMMA:
+ if (start) TexOutput("gamma");
+ break;
+ case ltDELTA:
+ if (start) TexOutput("delta");
+ break;
+ case ltEPSILON:
+ case ltVAREPSILON:
+ if (start) TexOutput("epsilon");
+ break;
+ case ltZETA:
+ if (start) TexOutput("zeta");
+ break;
+ case ltETA:
+ if (start) TexOutput("eta");
+ break;
+ case ltTHETA:
+ case ltVARTHETA:
+ if (start) TexOutput("theta");
+ break;
+ case ltIOTA:
+ if (start) TexOutput("iota");
+ break;
+ case ltKAPPA:
+ if (start) TexOutput("kappa");
+ break;
+ case ltLAMBDA:
+ if (start) TexOutput("lambda");
+ break;
+ case ltMU:
+ if (start) TexOutput("mu");
+ break;
+ case ltNU:
+ if (start) TexOutput("nu");
+ break;
+ case ltXI:
+ if (start) TexOutput("xi");
+ break;
+ case ltPI:
+ case ltVARPI:
+ if (start) TexOutput("pi");
+ break;
+ case ltRHO:
+ case ltVARRHO:
+ if (start) TexOutput("rho");
+ break;
+ case ltSIGMA:
+ case ltVARSIGMA:
+ if (start) TexOutput("sigma");
+ break;
+ case ltTAU:
+ if (start) TexOutput("tau");
+ break;
+ case ltUPSILON:
+ if (start) TexOutput("upsilon");
+ break;
+ case ltPHI:
+ case ltVARPHI:
+ if (start) TexOutput("phi");
+ break;
+ case ltCHI:
+ if (start) TexOutput("chi");
+ break;
+ case ltPSI:
+ if (start) TexOutput("psi");
+ break;
+ case ltOMEGA:
+ if (start) TexOutput("omega");
+ break;
+ case ltCAP_GAMMA:
+ if (start) TexOutput("GAMMA");
+ break;
+ case ltCAP_DELTA:
+ if (start) TexOutput("DELTA");
+ break;
+ case ltCAP_THETA:
+ if (start) TexOutput("THETA");
+ break;
+ case ltCAP_LAMBDA:
+ if (start) TexOutput("LAMBDA");
+ break;
+ case ltCAP_XI:
+ if (start) TexOutput("XI");
+ break;
+ case ltCAP_PI:
+ if (start) TexOutput("PI");
+ break;
+ case ltCAP_SIGMA:
+ if (start) TexOutput("SIGMA");
+ break;
+ case ltCAP_UPSILON:
+ if (start) TexOutput("UPSILON");
+ break;
+ case ltCAP_PHI:
+ if (start) TexOutput("PHI");
+ break;
+ case ltCAP_PSI:
+ if (start) TexOutput("PSI");
+ break;
+ case ltCAP_OMEGA:
+ if (start) TexOutput("OMEGA");
+ break;
+
+ // Binary operation symbols
+ case ltLE:
+ case ltLEQ:
+ if (start) TexOutput("<=");
+ break;
+ case ltLL:
+ if (start) TexOutput("<<");
+ break;
+ case ltSUBSET:
+ if (start) TexOutput("SUBSET");
+ break;
+ case ltSUBSETEQ:
+ if (start) TexOutput("SUBSETEQ");
+ break;
+ case ltIN:
+ if (start) TexOutput("IN");
+ break;
+ case ltVDASH:
+ if (start) TexOutput("VDASH");
+ break;
+ case ltMODELS:
+ if (start) TexOutput("MODELS");
+ break;
+ case ltGE:
+ case ltGEQ:
+ if (start) TexOutput(">=");
+ break;
+ case ltGG:
+ if (start) TexOutput(">>");
+ break;
+ case ltSUPSET:
+ if (start) TexOutput("SUPSET");
+ break;
+ case ltSUPSETEQ:
+ if (start) TexOutput("SUPSETEQ");
+ break;
+ case ltNI:
+ if (start) TexOutput("NI");
+ break;
+ case ltDASHV:
+ if (start) TexOutput("DASHV");
+ break;
+ case ltPERP:
+ if (start) TexOutput("PERP");
+ break;
+ case ltNEQ:
+ if (start) TexOutput("NEQ");
+ break;
+ case ltDOTEQ:
+ if (start) TexOutput("DOTEQ");
+ break;
+ case ltAPPROX:
+ if (start) TexOutput("APPROX");
+ break;
+ case ltCONG:
+ if (start) TexOutput("CONG");
+ break;
+ case ltEQUIV:
+ if (start) TexOutput("EQUIV");
+ break;
+ case ltPROPTO:
+ if (start) TexOutput("PROPTO");
+ break;
+ case ltPREC:
+ if (start) TexOutput("PREC");
+ break;
+ case ltPRECEQ:
+ if (start) TexOutput("PRECEQ");
+ break;
+ case ltPARALLEL:
+ if (start) TexOutput("|");
+ break;
+ case ltSIM:
+ if (start) TexOutput("~");
+ break;
+ case ltSIMEQ:
+ if (start) TexOutput("SIMEQ");
+ break;
+ case ltASYMP:
+ if (start) TexOutput("ASYMP");
+ break;
+ case ltSMILE:
+ if (start) TexOutput(":-)");
+ break;
+ case ltFROWN:
+ if (start) TexOutput(":-(");
+ break;
+ case ltSUCC:
+ if (start) TexOutput("SUCC");
+ break;
+ case ltSUCCEQ:
+ if (start) TexOutput("SUCCEQ");
+ break;
+ case ltMID:
+ if (start) TexOutput("|");
+ break;
+
+ // Negated relation symbols
+ case ltNOTEQ:
+ if (start) TexOutput("!=");
+ break;
+ case ltNOTIN:
+ if (start) TexOutput("NOTIN");
+ break;
+ case ltNOTSUBSET:
+ if (start) TexOutput("NOTSUBSET");
+ break;
+
+ // Arrows
+ case ltLEFTARROW:
+ if (start) TexOutput("<--");
+ break;
+ case ltLEFTARROW2:
+ if (start) TexOutput("<==");
+ break;
+ case ltRIGHTARROW:
+ if (start) TexOutput("-->");
+ break;
+ case ltRIGHTARROW2:
+ if (start) TexOutput("==>");
+ break;
+ case ltLEFTRIGHTARROW:
+ if (start) TexOutput("<-->");
+ break;
+ case ltLEFTRIGHTARROW2:
+ if (start) TexOutput("<==>");
+ break;
+ case ltUPARROW:
+ if (start) TexOutput("UPARROW");
+ break;
+ case ltUPARROW2:
+ if (start) TexOutput("UPARROW2");
+ break;
+ case ltDOWNARROW:
+ if (start) TexOutput("DOWNARROW");
+ break;
+ case ltDOWNARROW2:
+ if (start) TexOutput("DOWNARROW2");
+ break;
+ // Miscellaneous symbols
+ case ltALEPH:
+ if (start) TexOutput("ALEPH");
+ break;
+ case ltWP:
+ if (start) TexOutput("WP");
+ break;
+ case ltRE:
+ if (start) TexOutput("RE");
+ break;
+ case ltIM:
+ if (start) TexOutput("IM");
+ break;
+ case ltEMPTYSET:
+ if (start) TexOutput("EMPTYSET");
+ break;
+ case ltNABLA:
+ if (start) TexOutput("NABLA");
+ break;
+ case ltSURD:
+ if (start) TexOutput("SURD");
+ break;
+ case ltPARTIAL:
+ if (start) TexOutput("PARTIAL");
+ break;
+ case ltBOT:
+ if (start) TexOutput("BOT");
+ break;
+ case ltFORALL:
+ if (start) TexOutput("FORALL");
+ break;
+ case ltEXISTS:
+ if (start) TexOutput("EXISTS");
+ break;
+ case ltNEG:
+ if (start) TexOutput("NEG");
+ break;
+ case ltSHARP:
+ if (start) TexOutput("SHARP");
+ break;
+ case ltANGLE:
+ if (start) TexOutput("ANGLE");
+ break;
+ case ltTRIANGLE:
+ if (start) TexOutput("TRIANGLE");
+ break;
+ case ltCLUBSUIT:
+ if (start) TexOutput("CLUBSUIT");
+ break;
+ case ltDIAMONDSUIT:
+ if (start) TexOutput("DIAMONDSUIT");
+ break;
+ case ltHEARTSUIT:
+ if (start) TexOutput("HEARTSUIT");
+ break;
+ case ltSPADESUIT:
+ if (start) TexOutput("SPADESUIT");
+ break;
+ case ltINFTY:
+ if (start) TexOutput("INFTY");
+ break;
+ case ltPM:
+ if (start) TexOutput("PM");
+ break;
+ case ltMP:
+ if (start) TexOutput("MP");
+ break;
+ case ltTIMES:
+ if (start) TexOutput("TIMES");
+ break;
+ case ltDIV:
+ if (start) TexOutput("DIV");
+ break;
+ case ltCDOT:
+ if (start) TexOutput("CDOT");
+ break;
+ case ltAST:
+ if (start) TexOutput("AST");
+ break;
+ case ltSTAR:
+ if (start) TexOutput("STAR");
+ break;
+ case ltCAP:
+ if (start) TexOutput("CAP");
+ break;
+ case ltCUP:
+ if (start) TexOutput("CUP");
+ break;
+ case ltVEE:
+ if (start) TexOutput("VEE");
+ break;
+ case ltWEDGE:
+ if (start) TexOutput("WEDGE");
+ break;
+ case ltCIRC:
+ if (start) TexOutput("CIRC");
+ break;
+ case ltBULLET:
+ if (start) TexOutput("BULLET");
+ break;
+ case ltDIAMOND:
+ if (start) TexOutput("DIAMOND");
+ break;
+ case ltOSLASH:
+ if (start) TexOutput("OSLASH");
+ break;
+ case ltBOX:
+ if (start) TexOutput("BOX");
+ break;
+ case ltDIAMOND2:
+ if (start) TexOutput("DIAMOND2");
+ break;
+ case ltBIGTRIANGLEDOWN:
+ if (start) TexOutput("BIGTRIANGLEDOWN");
+ break;
+ case ltOPLUS:
+ if (start) TexOutput("OPLUS");
+ break;
+ case ltOTIMES:
+ if (start) TexOutput("OTIMES");
+ break;
+ case ltSS:
+ if (start) TexOutput("s");
+ break;
+ case ltBACKSLASHRAW:
+ if (start) TexOutput("\\");
+ break;
+ case ltLBRACERAW:
+ if (start) TexOutput("{");
+ break;
+ case ltRBRACERAW:
+ if (start) TexOutput("}");
+ break;
+ case ltSMALLSPACE1:
+ case ltSMALLSPACE2:
+ if (start) TexOutput(" ");
+ break;
+ default:
+ break;
+ }
+}
+
+// Called on start/end of argument examination
+bool DefaultOnArgument(int macroId, int arg_no, bool start)
+{
+ switch (macroId)
+ {
+ case ltREF:
+ {
+ if (arg_no == 1 && start)
+ {
+ char *refName = GetArgData();
+ if (refName)
+ {
+ TexRef *texRef = FindReference(refName);
+ if (texRef)
+ {
+ // Must strip the 'section' or 'chapter' or 'figure' text
+ // from a normal 'ref' reference
+ char buf[150];
+ strcpy(buf, texRef->sectionNumber);
+ int len = strlen(buf);
+ int i = 0;
+ if (strcmp(buf, "??") != 0)
+ {
+ while (i < len)
+ {
+ if (buf[i] == ' ')
+ {
+ i ++;
+ break;
+ }
+ else i ++;
+ }
+ }
+ TexOutput(texRef->sectionNumber + i, TRUE);
+ }
+ else
+ {
+ char buf[300];
+ TexOutput("??", TRUE);
+ sprintf(buf, "Warning: unresolved reference %s.", refName);
+ OnInform(buf);
+ }
+ }
+ else TexOutput("??", TRUE);
+ return FALSE;
+ }
+ break;
+ }
+ case ltLABEL:
+ {
+ return FALSE;
+ break;
+ }
+ case ltAUTHOR:
+ {
+ if (start && (arg_no == 1))
+ DocumentAuthor = GetArgChunk();
+ return FALSE;
+ break;
+ }
+ case ltDATE:
+ {
+ if (start && (arg_no == 1))
+ DocumentDate = GetArgChunk();
+ return FALSE;
+ break;
+ }
+ case ltTITLE:
+ {
+ if (start && (arg_no == 1))
+ DocumentTitle = GetArgChunk();
+ return FALSE;
+ break;
+ }
+ case ltDOCUMENTCLASS:
+ case ltDOCUMENTSTYLE:
+ {
+ if (start && !IsArgOptional())
+ {
+ DocumentStyleString = copystring(GetArgData());
+ if (strncmp(DocumentStyleString, "art", 3) == 0)
+ DocumentStyle = LATEX_ARTICLE;
+ else if (strncmp(DocumentStyleString, "rep", 3) == 0)
+ DocumentStyle = LATEX_REPORT;
+ else if (strncmp(DocumentStyleString, "book", 4) == 0 ||
+ strncmp(DocumentStyleString, "thesis", 6) == 0)
+ DocumentStyle = LATEX_BOOK;
+ else if (strncmp(DocumentStyleString, "letter", 6) == 0)
+ DocumentStyle = LATEX_LETTER;
+ else if (strncmp(DocumentStyleString, "slides", 6) == 0)
+ DocumentStyle = LATEX_SLIDES;
+
+ if (StringMatch("10", DocumentStyleString))
+ SetFontSizes(10);
+ else if (StringMatch("11", DocumentStyleString))
+ SetFontSizes(11);
+ else if (StringMatch("12", DocumentStyleString))
+ SetFontSizes(12);
+
+ OnMacro(ltHELPFONTSIZE, 1, TRUE);
+ sprintf(currentArgData, "%d", normalFont);
+ haveArgData = TRUE;
+ OnArgument(ltHELPFONTSIZE, 1, TRUE);
+ OnArgument(ltHELPFONTSIZE, 1, FALSE);
+ haveArgData = FALSE;
+ OnMacro(ltHELPFONTSIZE, 1, FALSE);
+ }
+ else if (start && IsArgOptional())
+ {
+ MinorDocumentStyleString = copystring(GetArgData());
+
+ if (StringMatch("10", MinorDocumentStyleString))
+ SetFontSizes(10);
+ else if (StringMatch("11", MinorDocumentStyleString))
+ SetFontSizes(11);
+ else if (StringMatch("12", MinorDocumentStyleString))
+ SetFontSizes(12);
+ }
+ return FALSE;
+ break;
+ }
+ case ltBIBLIOGRAPHYSTYLE:
+ {
+ if (start && !IsArgOptional())
+ BibliographyStyleString = copystring(GetArgData());
+ return FALSE;
+ break;
+ }
+ case ltPAGESTYLE:
+ {
+ if (start && !IsArgOptional())
+ {
+ if (PageStyle) delete[] PageStyle;
+ PageStyle = copystring(GetArgData());
+ }
+ return FALSE;
+ break;
+ }
+/*
+ case ltLHEAD:
+ {
+ if (start && !IsArgOptional())
+ LeftHeader = GetArgChunk();
+ return FALSE;
+ break;
+ }
+ case ltLFOOT:
+ {
+ if (start && !IsArgOptional())
+ LeftFooter = GetArgChunk();
+ return FALSE;
+ break;
+ }
+ case ltCHEAD:
+ {
+ if (start && !IsArgOptional())
+ CentreHeader = GetArgChunk();
+ return FALSE;
+ break;
+ }
+ case ltCFOOT:
+ {
+ if (start && !IsArgOptional())
+ CentreFooter = GetArgChunk();
+ return FALSE;
+ break;
+ }
+ case ltRHEAD:
+ {
+ if (start && !IsArgOptional())
+ RightHeader = GetArgChunk();
+ return FALSE;
+ break;
+ }
+ case ltRFOOT:
+ {
+ if (start && !IsArgOptional())
+ RightFooter = GetArgChunk();
+ return FALSE;
+ break;
+ }
+*/
+ case ltCITE:
+ case ltSHORTCITE:
+ {
+ if (start && !IsArgOptional())
+ {
+ char *citeKeys = GetArgData();
+ int pos = 0;
+ char *citeKey = ParseMultifieldString(citeKeys, &pos);
+ while (citeKey)
+ {
+ AddCitation(citeKey);
+ TexRef *ref = FindReference(citeKey);
+ if (ref)
+ {
+ TexOutput(ref->sectionNumber, TRUE);
+ if (strcmp(ref->sectionNumber, "??") == 0)
+ {
+ char buf[300];
+ sprintf(buf, "Warning: unresolved citation %s.", citeKey);
+ OnInform(buf);
+ }
+ }
+ citeKey = ParseMultifieldString(citeKeys, &pos);
+ if (citeKey)
+ {
+ TexOutput(", ", TRUE);
+ }
+ }
+ return FALSE;
+ }
+ break;
+ }
+ case ltNOCITE:
+ {
+ if (start && !IsArgOptional())
+ {
+ char *citeKey = GetArgData();
+ AddCitation(citeKey);
+ return FALSE;
+ }
+ break;
+ }
+ case ltHELPFONTSIZE:
+ {
+ if (start)
+ {
+ char *data = GetArgData();
+ if (strcmp(data, "10") == 0)
+ SetFontSizes(10);
+ else if (strcmp(data, "11") == 0)
+ SetFontSizes(11);
+ else if (strcmp(data, "12") == 0)
+ SetFontSizes(12);
+ return FALSE;
+ }
+ break;
+ }
+ case ltPAGEREF:
+ {
+ if (start)
+ {
+ TexOutput(" ??", TRUE);
+ return FALSE;
+ }
+ break;
+ }
+ case ltPARSKIP:
+ {
+ if (start && arg_no == 1)
+ {
+ char *data = GetArgData();
+ ParSkip = ParseUnitArgument(data);
+ return FALSE;
+ }
+ break;
+ }
+ case ltPARINDENT:
+ {
+ if (start && arg_no == 1)
+ {
+ char *data = GetArgData();
+ ParIndent = ParseUnitArgument(data);
+ return FALSE;
+ }
+ break;
+ }
+ case ltSL:
+ {
+ return OnArgument(ltIT, arg_no, start);
+ break;
+ }
+ case ltSPECIALDOUBLEDOLLAR:
+ {
+ return OnArgument(ltCENTER, arg_no, start);
+ break;
+ }
+ case ltPARAGRAPH:
+ case ltPARAGRAPHSTAR:
+ case ltSUBPARAGRAPH:
+ case ltSUBPARAGRAPHSTAR:
+ {
+ return OnArgument(ltSUBSUBSECTION, arg_no, start);
+ break;
+ }
+ case ltTYPEOUT:
+ {
+ if (start)
+ OnInform(GetArgData());
+ break;
+ }
+ case ltFOOTNOTE:
+ {
+ if (start)
+ TexOutput(" (", TRUE);
+ else
+ TexOutput(")", TRUE);
+ break;
+ }
+ case ltBIBLIOGRAPHY:
+ {
+ if (start)
+ {
+ FILE *fd;
+ int ch;
+ char smallBuf[2];
+ smallBuf[1] = 0;
+ if ((fd = fopen(TexBibName, "r")))
+ {
+ ch = getc(fd);
+ smallBuf[0] = ch;
+ while (ch != EOF)
+ {
+ TexOutput(smallBuf);
+ ch = getc(fd);
+ smallBuf[0] = ch;
+ }
+ fclose(fd);
+ }
+ else
+ {
+ OnInform("Run Tex2RTF again to include bibliography.");
+ }
+
+ // Read in the .bib file, resolve all known references, write out the RTF.
+ char *allFiles = GetArgData();
+ int pos = 0;
+ char *bibFile = ParseMultifieldString(allFiles, &pos);
+ while (bibFile)
+ {
+ char fileBuf[300];
+ strcpy(fileBuf, bibFile);
+ wxString actualFile = TexPathList.FindValidPath(fileBuf);
+ if (actualFile == "")
+ {
+ strcat(fileBuf, ".bib");
+ actualFile = TexPathList.FindValidPath(fileBuf);
+ }
+ if (actualFile != "")
+ {
+ if (!ReadBib((char*) (const char*) actualFile))
+ {
+ char buf[300];
+ sprintf(buf, ".bib file %s not found or malformed", (const char*) actualFile);
+ OnError(buf);
+ }
+ }
+ else
+ {
+ char buf[300];
+ sprintf(buf, ".bib file %s not found", fileBuf);
+ OnError(buf);
+ }
+ bibFile = ParseMultifieldString(allFiles, &pos);
+ }
+
+ ResolveBibReferences();
+
+ // Write it a new bib section in the appropriate format.
+ FILE *save1 = CurrentOutput1;
+ FILE *save2 = CurrentOutput2;
+ FILE *Biblio = fopen(TexTmpBibName, "w");
+ SetCurrentOutput(Biblio);
+ OutputBib();
+ fclose(Biblio);
+ if (wxFileExists(TexTmpBibName))
+ {
+ if (wxFileExists(TexBibName)) wxRemoveFile(TexBibName);
+ wxRenameFile(TexTmpBibName, TexBibName);
+ }
+ SetCurrentOutputs(save1, save2);
+ return FALSE;
+ }
+ break;
+ }
+ case ltMULTICOLUMN:
+ {
+ if (start && (arg_no == 3))
+ return TRUE;
+ else
+ return FALSE;
+ break;
+ }
+ case ltSCSHAPE:
+ case ltTEXTSC:
+ case ltSC:
+ {
+ if (start && (arg_no == 1))
+ {
+ char *s = GetArgData();
+ if (s)
+ {
+ char *s1 = copystring(s);
+ int i;
+ for (i = 0; i < (int)strlen(s); i++)
+ s1[i] = toupper(s[i]);
+ TexOutput(s1);
+ delete[] s1;
+ return FALSE;
+ }
+ else return TRUE;
+
+ }
+ return TRUE;
+ break;
+ }
+ case ltLOWERCASE:
+ {
+ if (start && (arg_no == 1))
+ {
+ char *s = GetArgData();
+ if (s)
+ {
+ char *s1 = copystring(s);
+ int i;
+ for (i = 0; i < (int)strlen(s); i++)
+ s1[i] = tolower(s[i]);
+ TexOutput(s1);
+ delete[] s1;
+ return FALSE;
+ }
+ else return TRUE;
+
+ }
+ return TRUE;
+ break;
+ }
+ case ltUPPERCASE:
+ {
+ if (start && (arg_no == 1))
+ {
+ char *s = GetArgData();
+ if (s)
+ {
+ char *s1 = copystring(s);
+ int i;
+ for (i = 0; i < (int)strlen(s); i++)
+ s1[i] = toupper(s[i]);
+ TexOutput(s1);
+ delete[] s1;
+ return FALSE;
+ }
+ else return TRUE;
+
+ }
+ return TRUE;
+ break;
+ }
+ case ltPOPREF: // Ignore second argument by default
+ {
+ if (start && (arg_no == 1))
+ return TRUE;
+ else
+ return FALSE;
+ break;
+ }
+ case ltTWOCOLUMN:
+ return TRUE;
+ break;
+ case ltXLPIGNORE:
+ return ((convertMode == TEX_XLP) ? FALSE : TRUE);
+ break;
+ case ltXLPONLY:
+ return ((convertMode != TEX_XLP) ? FALSE : TRUE);
+ break;
+ case ltHTMLIGNORE:
+ return ((convertMode == TEX_HTML) ? FALSE : TRUE);
+ break;
+ case ltHTMLONLY:
+ return ((convertMode != TEX_HTML) ? FALSE : TRUE);
+ break;
+ case ltRTFIGNORE:
+ return (((convertMode == TEX_RTF) && !winHelp) ? FALSE : TRUE);
+ break;
+ case ltRTFONLY:
+ return (!((convertMode == TEX_RTF) && !winHelp) ? FALSE : TRUE);
+ break;
+ case ltWINHELPIGNORE:
+ return (winHelp ? FALSE : TRUE);
+ break;
+ case ltWINHELPONLY:
+ return (!winHelp ? FALSE : TRUE);
+ break;
+ case ltLATEXIGNORE:
+ return TRUE;
+ break;
+ case ltLATEXONLY:
+ return FALSE;
+ break;
+ case ltCLINE:
+ case ltARABIC:
+ case ltALPH1:
+ case ltALPH2:
+ case ltROMAN:
+ case ltROMAN2:
+ case ltSETCOUNTER:
+ case ltADDTOCOUNTER:
+ case ltADDCONTENTSLINE:
+ case ltNEWCOUNTER:
+ case ltTEXTWIDTH:
+ case ltTEXTHEIGHT:
+ case ltBASELINESKIP:
+ case ltVSPACESTAR:
+ case ltHSPACESTAR:
+ case ltVSPACE:
+ case ltHSPACE:
+ case ltVSKIPSTAR:
+ case ltHSKIPSTAR:
+ case ltVSKIP:
+ case ltHSKIP:
+ case ltPAGENUMBERING:
+ case ltTHEPAGE:
+ case ltTHECHAPTER:
+ case ltTHESECTION:
+ case ltITEMSEP:
+ case ltFANCYPLAIN:
+ case ltCHEAD:
+ case ltRHEAD:
+ case ltLHEAD:
+ case ltCFOOT:
+ case ltRFOOT:
+ case ltLFOOT:
+ case ltTHISPAGESTYLE:
+ case ltMARKRIGHT:
+ case ltMARKBOTH:
+ case ltEVENSIDEMARGIN:
+ case ltODDSIDEMARGIN:
+ case ltMARGINPAR:
+ case ltMARGINPARWIDTH:
+ case ltMARGINPARSEP:
+ case ltMARGINPAREVEN:
+ case ltMARGINPARODD:
+ case ltTWOCOLWIDTHA:
+ case ltTWOCOLWIDTHB:
+ case ltTWOCOLSPACING:
+ case ltSETHEADER:
+ case ltSETFOOTER:
+ case ltINDEX:
+ case ltITEM:
+ case ltBCOL:
+ case ltFCOL:
+ case ltSETHOTSPOTCOLOUR:
+ case ltSETHOTSPOTCOLOR:
+ case ltSETHOTSPOTUNDERLINE:
+ case ltSETTRANSPARENCY:
+ case ltUSEPACKAGE:
+ case ltBACKGROUND:
+ case ltBACKGROUNDCOLOUR:
+ case ltBACKGROUNDIMAGE:
+ case ltLINKCOLOUR:
+ case ltFOLLOWEDLINKCOLOUR:
+ case ltTEXTCOLOUR:
+ case ltIMAGE:
+ case ltIMAGEMAP:
+ case ltIMAGEL:
+ case ltIMAGER:
+ case ltPOPREFONLY:
+ case ltINSERTATLEVEL:
+ return FALSE;
+ break;
+ case ltTABULAR:
+ case ltSUPERTABULAR:
+ {
+ if (arg_no == 2)
+ return TRUE;
+ else return FALSE;
+ break;
+ }
+ case ltINDENTED:
+ {
+ if (arg_no == 2) return TRUE;
+ else return FALSE;
+ break;
+ }
+ case ltSIZEDBOX:
+ case ltSIZEDBOXD:
+ {
+ if (arg_no == 2) return TRUE;
+ else return FALSE;
+ break;
+ }
+ case ltDEFINECOLOUR:
+ case ltDEFINECOLOR:
+ {
+ static int redVal = 0;
+ static int greenVal = 0;
+ static int blueVal = 0;
+ static char *colourName = NULL;
+ if (start)
+ {
+ switch (arg_no)
+ {
+ case 1:
+ {
+ if (colourName) delete[] colourName;
+ colourName = copystring(GetArgData());
+ break;
+ }
+ case 2:
+ {
+ redVal = atoi(GetArgData());
+ break;
+ }
+ case 3:
+ {
+ greenVal = atoi(GetArgData());
+ break;
+ }
+ case 4:
+ {
+ blueVal = atoi(GetArgData());
+ AddColour(colourName, redVal, greenVal, blueVal);
+ break;
+ }
+ default:
+ break;
+ }
+ }
+ return FALSE;
+ break;
+ }
+ case ltFIGURE:
+ case ltFIGURESTAR:
+ case ltNORMALBOX:
+ case ltNORMALBOXD:
+ default:
+ {
+ if (IsArgOptional())
+ return FALSE;
+ else
+ return TRUE;
+ break;
+ }
+ }
+ return TRUE;
+}
+
--- /dev/null
+/////////////////////////////////////////////////////////////////////////////
+// Name: tex2any.h
+// Purpose: Latex conversion header
+// Author: Julian Smart
+// Modified by:
+// Created: 7.9.93
+// RCS-ID: $Id$
+// Copyright: (c) Julian Smart
+// Licence: wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#include <stdio.h>
+#include "wx/wx.h"
+#include "wx/utils.h"
+#include "wx/list.h"
+#include "wx/hash.h"
+#include "wxhlpblk.h"
+
+/*
+ * Conversion modes
+ *
+ */
+
+#define TEX_RTF 1
+#define TEX_XLP 2
+#define TEX_HTML 3
+
+/*
+ * We have a list of macro definitions which we must define
+ * in advance to enable the parsing to recognize macros.
+ */
+
+#define FORBID_OK 0
+#define FORBID_WARN 1
+#define FORBID_ABSOLUTELY 2
+
+class TexMacroDef: public wxObject
+{
+ public:
+ int no_args;
+ char *name;
+ bool ignore;
+ int forbidden;
+ int macroId;
+
+ TexMacroDef(int the_id, char *the_name, int n, bool ig, bool forbidLevel = FORBID_OK);
+ ~TexMacroDef(void);
+};
+
+#define CHUNK_TYPE_MACRO 1
+#define CHUNK_TYPE_ARG 2
+#define CHUNK_TYPE_STRING 3
+
+/*
+ We have nested lists to represent the Tex document.
+ Each element of a list of chunks can be one of:
+ - a plain string
+ - a macro with/without arguments. Arguments are lists of TexChunks.
+
+Example (\toplevel is implicit but made explicit here):
+
+AddMacroDef(ltMYMAT, "mymat", 2);
+
+\toplevel{The cat sat on the \mymat{very coarse and {\it cheap}}{mat}}.
+
+Parsed as:
+
+TexChunk: type = macro, name = toplevel, no_args = 1
+ Children:
+
+ TexChunk: type = argument
+
+ Children:
+ TexChunk: type = string, value = "The cat sat on the "
+ TexChunk: type = macro, name = mymat, no_args = 2
+
+ Children:
+ TexChunk: type = argument
+
+ Children:
+ TexChunk: type = string, value = "very coarse and "
+ TexChunk: type = macro, name = it, no_args = 1
+
+ Children:
+ TexChunk: type = argument
+
+ Children:
+ TexChunk: type = string, value = "cheap"
+
+ TexChunk: type = argument
+
+ Children:
+ TexChunk: type = string, value = mat
+ */
+
+class TexChunk
+{
+ public:
+ int type;
+// char *name;
+ TexMacroDef *def;
+ char *value;
+ int macroId;
+ int no_args;
+ int argn;
+ bool optional; // Is an optional argument
+
+ wxList children;
+ TexChunk(int the_type, TexMacroDef *the_def = NULL);
+ TexChunk(TexChunk& toCopy);
+ virtual ~TexChunk(void);
+};
+
+// Represents a topic, used for generating a table of contents file (.cnt).
+// Also for storing keywords found in a topic, a list of which is then inserted
+// into the topic in the next pass.
+class TexTopic: public wxObject
+{
+ public:
+ // This flag is set to indicate that the topic has children.
+ // If this is the case, we know to insert a 'book' icon at this level,
+ // not just a 'page' icon. We don't want to have to open a book only
+ // to find there's only one page in it. We might force a book to be used if
+ // a top-level topic has no children (?)
+ bool hasChildren;
+ char *filename;
+ wxStringList *keywords;
+ TexTopic(char *f = NULL);
+ ~TexTopic(void);
+};
+extern wxHashTable TopicTable;
+void AddKeyWordForTopic(char *topic, char *entry, char *filename = NULL);
+void ClearKeyWordTable(void);
+
+extern TexChunk *TopLevel;
+extern wxHashTable MacroDefs;
+extern wxStringList IgnorableInputFiles; // Ignorable \input files, e.g. psbox.tex
+
+bool read_a_line(char *buf);
+bool TexLoadFile(char *filename);
+int ParseArg(TexChunk *thisArg, wxList& children, char *buffer, int pos,
+ char *environment = NULL, bool parseArgToBrace = TRUE, TexChunk *customMacroArgs = NULL);
+int ParseMacroBody(char *macro_name, TexChunk *parent, int no_args,
+ char *buffer, int pos, char *environment = NULL, bool parseArgToBrace = TRUE, TexChunk *customMacroArgs = NULL);
+void TraverseDocument(void);
+void TraverseFromChunk(TexChunk *chunk, wxNode *thisNode = NULL, bool childrenOnly = FALSE);
+#define TraverseChildrenFromChunk(arg) TraverseFromChunk(arg, NULL, TRUE)
+void SetCurrentOutput(FILE *fd);
+void SetCurrentOutputs(FILE *fd1, FILE *fd2);
+extern FILE *CurrentOutput1;
+extern FILE *CurrentOutput2;
+void AddMacroDef(int the_id, char *name, int n, bool ignore = FALSE, bool forbidden = FALSE);
+void TexInitialize(int bufSize);
+void TexCleanUp(void);
+void TexOutput(char *s, bool ordinaryText = FALSE);
+char *GetArgData(TexChunk *chunk);
+char *GetArgData(void); // Get the string for the current argument
+int GetNoArgs(void); // Get the number of arguments for the current macro
+TexChunk *GetArgChunk(void); // Get the chunk for the current argument
+TexChunk *GetTopLevelChunk(void); // Get the chunk for the top level
+TexChunk *GetNextChunk(void); // Look ahead to the next chunk
+bool IsArgOptional(void); // Is this argument an optional argument?
+void DefineDefaultMacros(void); // Optional set of default macros
+int GetCurrentColumn(void); // number of characters on current line
+char *ConvertCase(char *s); // Convert case, according to upperCaseNames setting.
+extern wxPathList TexPathList; // Path list, can be used for file searching.
+
+// Define a variable value from the .ini file
+char *RegisterSetting(char *settingName, char *settingValue, bool interactive = TRUE);
+
+// Major document styles
+#define LATEX_REPORT 1
+#define LATEX_ARTICLE 2
+#define LATEX_LETTER 3
+#define LATEX_BOOK 4
+#define LATEX_SLIDES 5
+
+extern TexChunk *DocumentTitle;
+extern TexChunk *DocumentAuthor;
+extern TexChunk *DocumentDate;
+extern int DocumentStyle;
+extern int MinorDocumentStyle;
+extern char *BibliographyStyleString;
+extern char *DocumentStyleString;
+extern char *MinorDocumentStyleString;
+
+extern int normalFont;
+extern int smallFont;
+extern int tinyFont;
+extern int largeFont1;
+extern int LargeFont2;
+extern int LARGEFont3;
+extern int hugeFont1;
+extern int HugeFont2;
+extern int HUGEFont3;
+
+/*
+ * USER-ADJUSTABLE SETTINGS
+ *
+ */
+
+// Section font sizes
+extern int chapterFont;
+extern int sectionFont;
+extern int subsectionFont;
+extern int titleFont;
+extern int authorFont;
+extern bool winHelp; // Output in Windows Help format if TRUE, linear otherwise
+extern bool isInteractive;
+extern bool runTwice;
+extern int convertMode;
+extern bool stopRunning;
+extern int mirrorMargins;
+extern bool headerRule;
+extern bool footerRule;
+extern int labelIndentTab; // From left indent to item label (points)
+extern int itemIndentTab; // From left indent to item (points)
+extern bool useUpButton;
+extern int htmlBrowseButtons;
+extern bool useHeadingStyles; // Insert \s1, s2 etc.
+extern bool useWord; // Insert Word table of contents, etc. etc.
+extern bool indexSubsections; // put subsections in index
+extern bool compatibilityMode;
+extern bool generateHPJ; // Generate WinHelp HPJ file
+extern char *winHelpTitle; // Title for Windows Help file
+extern int defaultTableColumnWidth;
+extern char *bitmapMethod;
+extern bool truncateFilenames; // Truncate for DOS
+extern int winHelpVersion; // Version e.g. 4 for Win95
+extern bool winHelpContents; // Generate .cnt file
+extern bool htmlIndex; // Generate .htx HTML index file
+extern bool htmlFrameContents; // Use frames for HTML contents page
+extern int contentsDepth; // Depth of contents for linear RTF files
+extern bool upperCaseNames; // Filenames; default is lower case
+extern char *backgroundImageString; // HTML background image
+extern char *backgroundColourString; // HTML background colour
+extern char *textColourString; // HTML text colour
+extern char *linkColourString; // HTML link colour
+extern char *followedLinkColourString; // HTML followed link colour
+extern bool combineSubSections; // Stop splitting files below section
+
+// Names to help with internationalisation
+extern char *ContentsNameString;
+extern char *AbstractNameString;
+extern char *GlossaryNameString;
+extern char *ReferencesNameString;
+extern char *FiguresNameString;
+extern char *TablesNameString;
+extern char *FigureNameString;
+extern char *TableNameString;
+extern char *IndexNameString;
+extern char *ChapterNameString;
+extern char *SectionNameString;
+extern char *SubsectionNameString;
+extern char *SubsubsectionNameString;
+extern char *UpNameString;
+
+/*
+ * HTML button identifiers: what kind of browse buttons
+ * are placed in HTML files, if any.
+ *
+ */
+
+#define HTML_BUTTONS_NONE 0
+#define HTML_BUTTONS_BITMAP 1
+#define HTML_BUTTONS_TEXT 2
+
+/*
+ * Section numbering
+ *
+ */
+
+extern int chapterNo;
+extern int sectionNo;
+extern int subsectionNo;
+extern int subsubsectionNo;
+extern int figureNo;
+extern int tableNo;
+
+extern int ParSkip;
+extern int ParIndent;
+
+extern bool isSync;
+
+// Set by client and by Tex2Any
+extern TexChunk *currentSection;
+
+// Header/footers/pagestyle
+extern TexChunk * LeftHeaderOdd;
+extern TexChunk * LeftFooterOdd;
+extern TexChunk * CentreHeaderOdd;
+extern TexChunk * CentreFooterOdd;
+extern TexChunk * RightHeaderOdd;
+extern TexChunk * RightFooterOdd;
+extern TexChunk * LeftHeaderEven;
+extern TexChunk * LeftFooterEven;
+extern TexChunk * CentreHeaderEven;
+extern TexChunk * CentreFooterEven;
+extern TexChunk * RightHeaderEven;
+extern TexChunk * RightFooterEven;
+extern char * PageStyle;
+
+// Repeat the currentSection, either real (Chapter) or simulated (References)
+extern void OutputCurrentSection(void);
+extern void OutputCurrentSectionToString(char *buf);
+extern void OutputChunkToString(TexChunk *chunk, char *buf);
+
+extern char *fakeCurrentSection;
+
+// Called by Tex2Any to simulate a section
+extern void FakeCurrentSection(char *fakeSection, bool addToContents = TRUE);
+
+/*
+ * Local to Tex2Any library
+ *
+ */
+
+extern char *currentArgData;
+extern bool haveArgData; // If TRUE, we're simulating the data.
+void StartSimulateArgument(char *data);
+void EndSimulateArgument(void);
+
+/*
+ * Client-defined
+ *
+ */
+
+// Called on start/end of macro examination
+void OnMacro(int macroId, int no_args, bool start);
+
+// Called on start/end of argument examination.
+// Return TRUE at the start of an argument to traverse
+// (output) the argument.
+bool OnArgument(int macroId, int arg_no, bool start);
+
+// Default: library-defined
+void DefaultOnMacro(int macroId, int no_args, bool start);
+
+// Default: library-defined
+bool DefaultOnArgument(int macroId, int arg_no, bool start);
+
+// Called on error
+void OnError(char *msg);
+
+// Called for information
+void OnInform(char *msg);
+
+// Special yield wrapper
+void Tex2RTFYield(bool force = FALSE);
+
+/*
+ * Useful utilities
+ *
+ */
+
+// Look for \label macro, use this ref name if found or
+// make up a topic name otherwise.
+char *FindTopicName(TexChunk *chunk);
+// Force the current topic to be this (e.g. force 'references' label).
+void ForceTopicName(char *name);
+void ResetTopicCounter(void);
+
+// Parse unit eg. 14, 12pt, 34cm and return value in points.
+int ParseUnitArgument(char *unitArg);
+
+// Set small, large, normal etc. point sizes for reference size
+void SetFontSizes(int pointSize);
+
+/*
+ * Strip off any extension (dot something) from end of file,
+ * IF one exists. Inserts zero into buffer.
+ *
+ */
+
+void StripExtension(char *buffer);
+
+/*
+ * Reference structure
+ *
+ */
+
+class TexRef: public wxObject
+{
+ public:
+ char *refLabel; // Reference label
+ char *refFile; // Reference filename (can be NULL)
+ char *sectionNumber; // Section or figure number (as a string)
+ char *sectionName; // name e.g. 'section'
+ TexRef(char *label, char *file, char *section, char *sectionN = NULL)
+ {
+ refLabel = copystring(label);
+ refFile = file ? copystring(file) : (char*) NULL;
+ sectionNumber = section ? copystring(section) : copystring("??");
+ sectionName = sectionN ? copystring(sectionN) : copystring("??");
+ }
+ ~TexRef(void)
+ {
+ delete[] refLabel; delete[] refFile; delete[] sectionNumber; delete[] sectionName;
+ }
+};
+
+extern wxHashTable TexReferences;
+
+/*
+ * Add a reference
+ *
+ */
+
+void AddTexRef(char *name, char *file = NULL, char *sectionName = NULL,
+ int chapter = 0, int section = 0, int subsection = 0, int subsubsection = 0);
+
+/*
+ * Read and write reference file (.ref), to resolve refs for second pass.
+ *
+ */
+void WriteTexReferences(char *filename);
+void ReadTexReferences(char *filename);
+
+/*
+ * Bibliography stuff
+ *
+ */
+
+class BibEntry: public wxObject
+{
+ public:
+ char *key;
+
+ /*
+ * book, inbook, article, phdthesis, inproceedings, techreport
+ */
+ char *type;
+
+ /*
+ * Possible fields
+ *
+ */
+ char *editor;
+ char *title;
+ char *booktitle;
+ char *author;
+ char *journal;
+ char *volume;
+ char *number;
+ char *year;
+ char *month;
+ char *pages;
+ char *chapter;
+ char *publisher;
+ char *address;
+ char *institution;
+ char *organization;
+ char *comment;
+
+ inline BibEntry(void)
+ {
+ key = NULL;
+ type = NULL;
+ editor = NULL;
+ title = NULL;
+ booktitle = NULL;
+ author = NULL;
+ journal = NULL;
+ volume = NULL;
+ number = NULL;
+ chapter = NULL;
+ year = NULL;
+ month = NULL;
+ pages = NULL;
+ publisher = NULL;
+ address = NULL;
+ institution = NULL;
+ organization = NULL;
+ comment = NULL;
+ }
+};
+
+extern wxList BibList;
+extern wxStringList CitationList;
+
+bool ReadBib(char *filename);
+void OutputBib(void);
+void ResolveBibReferences(void);
+void AddCitation(char *citeKey);
+TexRef *FindReference(char *key);
+
+/*
+ * Ability to customize, or at least suppress unknown macro errors
+ *
+ */
+
+extern wxList CustomMacroList;
+
+#define CUSTOM_MACRO_IGNORE 0
+#define CUSTOM_MACRO_OUTPUT 1
+#define CUSTOM_MACRO_MARK 2
+
+class CustomMacro: public wxObject
+{
+ public:
+ char *macroName;
+ char *macroBody;
+ int noArgs;
+ inline CustomMacro(char *name, int args, char *body)
+ {
+ noArgs = args;
+ macroName = copystring(name);
+ if (body)
+ macroBody = copystring(body);
+ else
+ macroBody = NULL;
+ }
+};
+
+bool ReadCustomMacros(char *filename);
+void ShowCustomMacros(void);
+CustomMacro *FindCustomMacro(char *name);
+char *ParseMultifieldString(char *s, int *pos);
+
+/*
+ * Colour table stuff
+ *
+ */
+
+class ColourTableEntry: public wxObject
+{
+ public:
+ char *name;
+ unsigned int red;
+ unsigned int green;
+ unsigned int blue;
+
+ ColourTableEntry(char *theName, unsigned int r, unsigned int g, unsigned int b);
+ ~ColourTableEntry(void);
+};
+
+extern wxList ColourTable;
+extern void AddColour(char *theName, unsigned int r, unsigned int g, unsigned int b);
+extern int FindColourPosition(char *theName);
+// Converts e.g. "red" -> "#FF0000"
+extern bool FindColourHTMLString(char *theName, char *buf);
+extern void InitialiseColourTable(void);
+
+#define ltABSTRACT 1
+#define ltADDCONTENTSLINE 2
+#define ltADDTOCOUNTER 3
+#define ltALPH1 4
+#define ltALPH2 5
+#define ltAPPENDIX 6
+#define ltARABIC 7
+#define ltARRAY 8
+#define ltAUTHOR 9
+
+#define ltBACKSLASH 30
+#define ltBASELINESKIP 31
+#define ltBF 32
+#define ltBIBITEM 33
+#define ltBIBLIOGRAPHYSTYLE 34
+#define ltBIBLIOGRAPHY 35
+#define ltBOXIT 36
+#define ltBACKSLASHRAW 37
+#define ltBACKGROUND 38
+#define ltBACKGROUNDCOLOUR 39
+#define ltBACKGROUNDIMAGE 40
+#define ltBRCLEAR 41
+
+#define ltCAPTIONSTAR 50
+#define ltCAPTION 51
+#define ltCDOTS 52
+#define ltCENTERLINE 53
+#define ltCENTERING 54
+#define ltCENTER 55
+#define ltCEXTRACT 56
+#define ltCHAPTERHEADING 57
+#define ltCHAPTERSTAR 58
+#define ltCHAPTER 59
+#define ltCINSERT 60
+#define ltCITE 61
+#define ltCLASS 62
+#define ltCLEARDOUBLEPAGE 63
+#define ltCLEARPAGE 64
+#define ltCLINE 65
+#define ltCLIPSFUNC 66
+#define ltCOLUMNSEP 67
+#define ltCOMMENT 68
+#define ltCOPYRIGHT 69
+#define ltCPARAM 70
+
+#define ltCHEAD 71
+#define ltCFOOT 72
+
+#define ltCHAPTERHEADINGSTAR 73
+
+#define ltDATE 90
+#define ltDESCRIPTION 91
+#define ltDESTRUCT 92
+#define ltDOCUMENTSTYLE 93
+#define ltDOCUMENT 94
+#define ltDOUBLESPACE 95
+#define ltDEFINECOLOUR 96
+#define ltDEFINECOLOR 97
+
+#define ltEM 120
+#define ltENUMERATE 121
+#define ltEQUATION 122
+#define ltEVENSIDEMARGIN 123
+
+#define ltFBOX 150
+#define ltFIGURE 151
+#define ltFLUSHLEFT 152
+#define ltFLUSHRIGHT 153
+#define ltFOOTHEIGHT 154
+#define ltFOOTNOTE 155
+#define ltFOOTSKIP 156
+#define ltFRAMEBOX 157
+#define ltFUNCTIONSECTION 158
+#define ltFUNC 159
+#define ltFIGURESTAR 160
+#define ltFOOTNOTESIZE 161
+#define ltFOOTNOTEPOPUP 162
+#define ltFANCYPLAIN 163
+#define ltFCOL 164
+#define ltBCOL 165
+#define ltFOLLOWEDLINKCOLOUR 166
+
+#define ltGLOSSARY 180
+#define ltGLOSS 181
+
+#define ltHEADHEIGHT 200
+#define ltHELPGLOSSARY 201
+#define ltHELPIGNORE 202
+#define ltHELPONLY 203
+#define ltHELPINPUT 204
+#define ltHELPFONTFAMILY 205
+#define ltHELPFONTSIZE 206
+#define ltHELPREFN 207
+#define ltHELPREF 208
+#define ltHFILL 209
+#define ltHLINE 210
+#define ltHRULE 211
+#define ltHSPACESTAR 212
+#define ltHSPACE 213
+#define ltHSKIPSTAR 214
+#define ltHSKIP 215
+#define lthuge 216
+#define ltHuge 217
+#define ltHUGE 218
+#define ltHTMLIGNORE 219
+#define ltHTMLONLY 220
+
+#define ltINCLUDEONLY 240
+#define ltINCLUDE 241
+#define ltINDEX 242
+#define ltINPUT 243
+#define ltITEMIZE 244
+#define ltITEM 245
+#define ltIMAGE 246
+#define ltIT 247
+#define ltITEMSEP 248
+#define ltINDENTED 249
+#define ltIMAGEMAP 250
+#define ltIMAGER 251
+#define ltIMAGEL 252
+#define ltINSERTATLEVEL 253
+
+#define ltKILL 260
+
+#define ltLABEL 280
+#define ltlarge 281
+#define ltLarge 282
+#define ltLARGE 283
+#define ltLATEX 284
+#define ltLBOX 285
+#define ltLDOTS 286
+#define ltLINEBREAK 287
+#define ltLISTOFFIGURES 288
+#define ltLISTOFTABLES 289
+#define ltLHEAD 290
+#define ltLFOOT 291
+#define ltLATEXIGNORE 292
+#define ltLATEXONLY 293
+#define ltLOWERCASE 294
+#define ltLBRACERAW 295
+#define ltLINKCOLOUR 296
+
+#define ltMAKEGLOSSARY 300
+#define ltMAKEINDEX 301
+#define ltMAKETITLE 302
+#define ltMARKRIGHT 303
+#define ltMARKBOTH 304
+#define ltMARGINPARWIDTH 305
+#define ltMARGINPAR 306
+#define ltMARGINPARODD 307
+#define ltMARGINPAREVEN 308
+#define ltMBOX 309
+#define ltMEMBERSECTION 310
+#define ltMEMBER 311
+#define ltMULTICOLUMN 312
+#define ltMARGINPARSEP 313
+
+#define ltNEWCOUNTER 330
+#define ltNEWLINE 331
+#define ltNEWPAGE 332
+#define ltNOCITE 333
+#define ltNOINDENT 334
+#define ltNOLINEBREAK 335
+#define ltNOPAGEBREAK 336
+#define ltNORMALSIZE 337
+#define ltNORMALBOX 338
+#define ltNORMALBOXD 339
+#define ltNUMBEREDBIBITEM 340
+
+#define ltONECOLUMN 360
+#define ltODDSIDEMARGIN 361
+
+#define ltPAGEBREAK 380
+#define ltPAGEREF 381
+#define ltPAGESTYLE 382
+#define ltPAGENUMBERING 383
+#define ltPARAGRAPHSTAR 384
+#define ltPARAGRAPH 385
+#define ltPARAM 386
+#define ltPARINDENT 387
+#define ltPARSKIP 388
+#define ltPARTSTAR 389
+#define ltPART 390
+#define ltPAR 391
+#define ltPFUNC 392
+#define ltPICTURE 393
+#define ltPOPREF 394
+#define ltPOUNDS 395
+#define ltPRINTINDEX 396
+#define ltPSBOXTO 397
+#define ltPSBOX 398
+#define ltPOPREFONLY 399
+
+#define ltQUOTE 420
+#define ltQUOTATION 421
+
+#define ltRAGGEDBOTTOM 440
+#define ltRAGGEDLEFT 441
+#define ltRAGGEDRIGHT 442
+#define ltREF 443
+#define ltRM 444
+#define ltROMAN 445
+#define ltROMAN2 446
+#define ltRTFSP 447
+#define ltRULE 448
+#define ltRULEDROW 449
+#define ltDRULED 450
+#define ltRHEAD 451
+#define ltRFOOT 452
+#define ltROW 453
+#define ltRTFIGNORE 454
+#define ltRTFONLY 455
+#define ltRBRACERAW 456
+#define ltREGISTERED 457
+
+#define ltSC 470
+#define ltSECTIONHEADING 471
+#define ltSECTIONSTAR 472
+#define ltSECTION 473
+#define ltSETCOUNTER 474
+#define ltSF 475
+#define ltSHORTCITE 476
+#define ltSINGLESPACE 477
+#define ltSLOPPYPAR 478
+#define ltSLOPPY 479
+#define ltSL 480
+#define ltSMALL 481
+#define ltSUBITEM 482
+#define ltSUBPARAGRAPHSTAR 483
+#define ltSUBPARAGRAPH 484
+#define ltSPECIAL 485
+#define ltSUBSECTIONSTAR 486
+#define ltSUBSECTION 487
+#define ltSUBSUBSECTIONSTAR 488
+#define ltSUBSUBSECTION 489
+#define ltSCRIPTSIZE 490
+#define ltSETHEADER 491
+#define ltSETFOOTER 492
+#define ltSIZEDBOX 493
+#define ltSIZEDBOXD 494
+#define ltSECTIONHEADINGSTAR 495
+#define ltSS 496
+#define ltSETHOTSPOTCOLOUR 497
+#define ltSETHOTSPOTCOLOR 498
+#define ltSETHOTSPOTUNDERLINE 499
+#define ltSETTRANSPARENCY 500
+
+#define ltTABBING 510
+#define ltTABLEOFCONTENTS 511
+#define ltTABLE 512
+#define ltTABULAR 513
+#define ltTAB 514
+#define ltTEX 515
+#define ltTEXTWIDTH 516
+#define ltTEXTHEIGHT 517
+#define ltTHEBIBLIOGRAPHY 518
+#define ltTITLEPAGE 519
+#define ltTITLE 520
+#define ltTINY 521
+#define ltTODAY 522
+#define ltTOPMARGIN 523
+#define ltTOPSKIP 524
+#define ltTT 525
+#define ltTYPEIN 526
+#define ltTYPEOUT 527
+#define ltTWOCOLUMN 528
+#define ltTHEPAGE 529
+#define ltTHECHAPTER 530
+#define ltTHESECTION 531
+#define ltTHISPAGESTYLE 532
+
+#define ltTWOCOLWIDTHA 533
+#define ltTWOCOLWIDTHB 534
+#define ltTWOCOLSPACING 535
+#define ltTWOCOLITEM 536
+#define ltTWOCOLITEMRULED 537
+#define ltTWOCOLLIST 538
+#define ltTEXTCOLOUR 539
+
+#define ltUNDERLINE 550
+#define ltURLREF 551
+#define ltUPPERCASE 552
+#define ltUSEPACKAGE 553
+
+#define ltVDOTS 570
+#define ltVERBATIMINPUT 571
+#define ltVERBATIM 572
+#define ltVERB 573
+#define ltVERSE 574
+#define ltVFILL 575
+#define ltVLINE 576
+#define ltVOID 577
+#define ltVRULE 578
+#define ltVSPACESTAR 579
+#define ltVSKIPSTAR 580
+#define ltVSPACE 581
+#define ltVSKIP 582
+#define ltVERBSTAR 583
+
+#define ltWXCLIPS 600
+#define ltWINHELPIGNORE 601
+#define ltWINHELPONLY 602
+
+#define ltXLPIGNORE 603
+#define ltXLPONLY 604
+
+#define ltSPACE 620
+#define ltBACKSLASHCHAR 621
+#define ltPIPE 622
+#define ltFORWARDSLASH 623
+#define ltUNDERSCORE 624
+#define ltAMPERSAND 625
+#define ltPERCENT 626
+#define ltDOLLAR 627
+#define ltHASH 628
+#define ltLPARENTH 629
+#define ltRPARENTH 630
+#define ltLBRACE 631
+#define ltRBRACE 632
+#define ltEQUALS 633
+#define ltRANGLEBRA 634
+#define ltLANGLEBRA 635
+#define ltPLUS 636
+#define ltDASH 637
+#define ltSINGLEQUOTE 638
+#define ltBACKQUOTE 639
+#define ltTILDE 640
+#define ltAT_SYMBOL 641
+
+// Characters, not macros but with special Latex significance
+#define ltSPECIALDOLLAR 660
+#define ltSPECIALDOUBLEDOLLAR 661
+#define ltSPECIALTILDE 662
+#define ltSPECIALHASH 663
+#define ltSPECIALAMPERSAND 664
+#define ltSUPERTABULAR 665
+
+// Accents
+#define ltACCENT_GRAVE 700
+#define ltACCENT_ACUTE 701
+#define ltACCENT_CARET 702
+#define ltACCENT_UMLAUT 703
+#define ltACCENT_TILDE 704
+#define ltACCENT_DOT 705
+#define ltACCENT_CADILLA 706
+
+// Symbols
+#define ltALPHA 800
+#define ltBETA 801
+#define ltGAMMA 802
+#define ltDELTA 803
+#define ltEPSILON 804
+#define ltVAREPSILON 805
+#define ltZETA 806
+#define ltETA 807
+#define ltTHETA 808
+#define ltVARTHETA 809
+#define ltIOTA 810
+#define ltKAPPA 811
+#define ltLAMBDA 812
+#define ltMU 813
+#define ltNU 814
+#define ltXI 815
+#define ltPI 816
+#define ltVARPI 817
+#define ltRHO 818
+#define ltVARRHO 819
+#define ltSIGMA 820
+#define ltVARSIGMA 821
+#define ltTAU 822
+#define ltUPSILON 823
+#define ltPHI 824
+#define ltVARPHI 825
+#define ltCHI 826
+#define ltPSI 827
+#define ltOMEGA 828
+
+#define ltCAP_GAMMA 830
+#define ltCAP_DELTA 831
+#define ltCAP_THETA 832
+#define ltCAP_LAMBDA 833
+#define ltCAP_XI 834
+#define ltCAP_PI 835
+#define ltCAP_SIGMA 836
+#define ltCAP_UPSILON 837
+#define ltCAP_PHI 838
+#define ltCAP_PSI 839
+#define ltCAP_OMEGA 840
+
+// Binary operation symbols
+#define ltLE 850
+#define ltLEQ 851
+#define ltLL 852
+#define ltSUBSET 853
+#define ltSUBSETEQ 854
+#define ltSQSUBSET 855
+#define ltSQSUBSETEQ 856
+#define ltIN 857
+#define ltVDASH 858
+#define ltMODELS 859
+#define ltGE 860
+#define ltGEQ 861
+#define ltGG 862
+#define ltSUPSET 863
+#define ltSUPSETEQ 864
+#define ltSQSUPSET 865
+#define ltSQSUPSETEQ 866
+#define ltNI 867
+#define ltDASHV 868
+#define ltPERP 869
+#define ltNEQ 870
+#define ltDOTEQ 871
+#define ltAPPROX 872
+#define ltCONG 873
+#define ltEQUIV 874
+#define ltPROPTO 875
+#define ltPREC 876
+#define ltPRECEQ 877
+#define ltPARALLEL 878
+#define ltSIM 879
+#define ltSIMEQ 880
+#define ltASYMP 881
+#define ltSMILE 882
+#define ltFROWN 883
+#define ltBOWTIE 884
+#define ltSUCC 885
+#define ltSUCCEQ 886
+#define ltMID 887
+
+// Negated relation symbols (selected)
+#define ltNOTEQ 890
+#define ltNOTIN 891
+#define ltNOTSUBSET 892
+
+// Arrows
+#define ltLEFTARROW 900
+#define ltLEFTARROW2 901
+#define ltRIGHTARROW 902
+#define ltRIGHTARROW2 903
+#define ltLEFTRIGHTARROW 904
+#define ltLEFTRIGHTARROW2 905
+#define ltUPARROW 906
+#define ltUPARROW2 907
+#define ltDOWNARROW 908
+#define ltDOWNARROW2 909
+
+// Miscellaneous symbols
+#define ltALEPH 1000
+#define ltWP 1001
+#define ltRE 1002
+#define ltIM 1003
+#define ltEMPTYSET 1004
+#define ltNABLA 1005
+#define ltSURD 1006
+#define ltPARTIAL 1007
+#define ltBOT 1008
+#define ltFORALL 1009
+#define ltEXISTS 1010
+#define ltNEG 1011
+#define ltSHARP 1012
+#define ltANGLE 1013
+#define ltTRIANGLE 1014
+#define ltCLUBSUIT 1015
+#define ltDIAMONDSUIT 1016
+#define ltHEARTSUIT 1017
+#define ltSPADESUIT 1018
+#define ltINFTY 1019
+
+// Binary operation symbols
+#define ltPM 1030
+#define ltMP 1031
+#define ltTIMES 1032
+#define ltDIV 1033
+#define ltCDOT 1034
+#define ltAST 1035
+#define ltSTAR 1036
+#define ltCAP 1037
+#define ltCUP 1038
+#define ltVEE 1039
+#define ltWEDGE 1040
+#define ltCIRC 1041
+#define ltBULLET 1042
+#define ltDIAMOND 1043
+#define ltOSLASH 1044
+#define ltBOX 1045
+#define ltDIAMOND2 1046
+#define ltBIGTRIANGLEDOWN 1047
+#define ltOPLUS 1048
+#define ltOTIMES 1049
+
+// Latex2e commands
+#define ltRMFAMILY 1200
+#define ltSFFAMILY 1201
+#define ltTTFAMILY 1202
+#define ltBFSERIES 1203
+#define ltITSHAPE 1204
+#define ltSLSHAPE 1205
+#define ltSCSHAPE 1206
+
+#define ltMDSERIES 1207
+#define ltUPSHAPE 1208
+
+#define ltTEXTRM 1209
+#define ltTEXTSF 1210
+#define ltTEXTTT 1211
+#define ltTEXTBF 1212
+#define ltTEXTIT 1213
+#define ltTEXTSL 1214
+#define ltTEXTSC 1215
+#define ltEMPH 1216
+
+#define ltDOCUMENTCLASS 1217
+
+// Space macros
+#define ltSMALLSPACE1 1250
+#define ltSMALLSPACE2 1251
+
+// Pseudo-macros
+#define ltTOPLEVEL 15000
+#define ltCUSTOM_MACRO 15001
+#define ltSOLO_BLOCK 15002
+
+
+
--- /dev/null
+/////////////////////////////////////////////////////////////////////////////
+// Name: tex2rtf.cpp
+// Purpose: Converts Latex to linear/WinHelp RTF, HTML, wxHelp.
+// Author: Julian Smart
+// Modified by:
+// Created: 7.9.93
+// RCS-ID: $Id$
+// Copyright: (c) Julian Smart
+// Licence: wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+
+#ifndef WX_PRECOMP
+#include "wx/wx.h"
+#endif
+
+#ifndef NO_GUI
+#include <wx/help.h>
+#include <wx/timer.h>
+#endif
+
+#ifdef NO_GUI
+#if wxUSE_IOSTREAMH
+#include <iostream.h>
+#include <fstream.h>
+#else
+#include <iostream>
+#include <fstream>
+#endif
+#endif
+
+#include <ctype.h>
+#include <stdlib.h>
+#include "tex2any.h"
+#include "tex2rtf.h"
+#include "rtfutils.h"
+
+#if (defined(__WXGTK__) || defined(__WXMOTIF__)) && !defined(NO_GUI)
+#include "tex2rtf.xpm"
+#endif
+
+const float versionNo = 2.0;
+
+TexChunk *currentMember = NULL;
+bool startedSections = FALSE;
+char *contentsString = NULL;
+bool suppressNameDecoration = FALSE;
+bool OkToClose = TRUE;
+int passNumber = 1;
+
+#ifndef NO_GUI
+wxHelpController *HelpInstance = NULL;
+
+#ifdef __WXMSW__
+static char *ipc_buffer = NULL;
+static char Tex2RTFLastStatus[100];
+Tex2RTFServer *TheTex2RTFServer = NULL;
+#endif
+#endif
+
+char *bulletFile = NULL;
+
+FILE *Contents = NULL; // Contents page
+FILE *Chapters = NULL; // Chapters (WinHelp RTF) or rest of file (linear RTF)
+FILE *Sections = NULL;
+FILE *Subsections = NULL;
+FILE *Subsubsections = NULL;
+FILE *Popups = NULL;
+FILE *WinHelpContentsFile = NULL;
+
+char *InputFile = NULL;
+char *OutputFile = NULL;
+char *MacroFile = copystring("tex2rtf.ini");
+
+char *FileRoot = NULL;
+char *ContentsName = NULL; // Contents page from last time around
+char *TmpContentsName = NULL; // Current contents page
+char *TmpFrameContentsName = NULL; // Current frame contents page
+char *WinHelpContentsFileName = NULL; // WinHelp .cnt file
+char *RefName = NULL; // Reference file name
+
+char *RTFCharset = copystring("ansi");
+
+#ifdef __WXMSW__
+int BufSize = 100; // Size of buffer in K
+#else
+int BufSize = 500;
+#endif
+
+bool Go(void);
+void ShowOptions(void);
+
+#ifdef NO_GUI
+int main(int argc, char **argv)
+#else
+wxMenuBar *menuBar = NULL;
+MyFrame *frame = NULL;
+
+// DECLARE_APP(MyApp)
+IMPLEMENT_APP(MyApp)
+
+// `Main program' equivalent, creating windows and returning main app frame
+bool MyApp::OnInit()
+#endif
+{
+ // Use default list of macros defined in tex2any.cc
+ DefineDefaultMacros();
+ AddMacroDef(ltHARDY, "hardy", 0);
+
+ FileRoot = new char[300];
+ ContentsName = new char[300];
+ TmpContentsName = new char[300];
+ TmpFrameContentsName = new char[300];
+ WinHelpContentsFileName = new char[300];
+ RefName = new char[300];
+
+ int n = 1;
+
+ // Read input/output files
+ if (argc > 1)
+ {
+ if (argv[1][0] != '-')
+ {
+ InputFile = argv[1];
+ n ++;
+
+ if (argc > 2)
+ {
+ if (argv[2][0] != '-')
+ {
+ OutputFile = argv[2];
+ n ++;
+ }
+ }
+ }
+ }
+
+#ifdef NO_GUI
+ if (!InputFile || !OutputFile)
+ {
+ cout << "Tex2RTF: input or output file is missing.\n";
+ ShowOptions();
+ exit(1);
+ }
+#endif
+ if (InputFile)
+ {
+ TexPathList.EnsureFileAccessible(InputFile);
+ }
+ if (!InputFile || !OutputFile)
+ isInteractive = TRUE;
+
+ for (int i = n; i < argc;)
+ {
+ if (strcmp(argv[i], "-winhelp") == 0)
+ {
+ i ++;
+ convertMode = TEX_RTF;
+ winHelp = TRUE;
+ }
+#ifndef NO_GUI
+ else if (strcmp(argv[i], "-interactive") == 0)
+ {
+ i ++;
+ isInteractive = TRUE;
+ }
+#endif
+ else if (strcmp(argv[i], "-sync") == 0) // Don't yield
+ {
+ i ++;
+ isSync = TRUE;
+ }
+ else if (strcmp(argv[i], "-rtf") == 0)
+ {
+ i ++;
+ convertMode = TEX_RTF;
+ }
+ else if (strcmp(argv[i], "-html") == 0)
+ {
+ i ++;
+ convertMode = TEX_HTML;
+ }
+ else if (strcmp(argv[i], "-xlp") == 0)
+ {
+ i ++;
+ convertMode = TEX_XLP;
+ }
+ else if (strcmp(argv[i], "-twice") == 0)
+ {
+ i ++;
+ runTwice = TRUE;
+ }
+ else if (strcmp(argv[i], "-macros") == 0)
+ {
+ i ++;
+ if (i < argc)
+ {
+ MacroFile = copystring(argv[i]);
+ i ++;
+ }
+ }
+ else if (strcmp(argv[i], "-bufsize") == 0)
+ {
+ i ++;
+ if (i < argc)
+ {
+ BufSize = atoi(argv[i]);
+ i ++;
+ }
+ }
+ else if (strcmp(argv[i], "-charset") == 0)
+ {
+ i ++;
+ if (i < argc)
+ {
+ char *s = argv[i];
+ i ++;
+ if (strcmp(s, "ansi") == 0 || strcmp(s, "pc") == 0 || strcmp(s, "mac") == 0 ||
+ strcmp(s, "pca") == 0)
+ RTFCharset = copystring(s);
+ else
+ {
+ OnError("Incorrect argument for -charset");
+ }
+ }
+ }
+ else
+ {
+ char buf[100];
+ sprintf(buf, "Invalid switch %s.\n", argv[i]);
+ OnError(buf);
+ i++;
+#ifdef NO_GUI
+ ShowOptions();
+ exit(1);
+#endif
+ }
+ }
+
+#if defined(__WXMSW__) && !defined(NO_GUI)
+ wxDDEInitialize();
+ Tex2RTFLastStatus[0] = 0; // DDE connection return value
+ TheTex2RTFServer = new Tex2RTFServer;
+ TheTex2RTFServer->Create("TEX2RTF");
+#endif
+
+#if defined(__WXMSW__) && defined(__WIN16__)
+ // Limit to max Windows array size
+ if (BufSize > 64) BufSize = 64;
+#endif
+
+ TexInitialize(BufSize);
+ ResetContentsLevels(0);
+
+#ifndef NO_GUI
+
+ if (isInteractive)
+ {
+ char buf[100];
+
+ // Create the main frame window
+ frame = new MyFrame(NULL, -1, "Tex2RTF", wxPoint(-1, -1), wxSize(400, 300));
+ frame->CreateStatusBar(2);
+
+ // Give it an icon
+ // TODO: uncomment this when we have tex2rtf.xpm
+ frame->SetIcon(wxICON(tex2rtf));
+
+ if (InputFile)
+ {
+ sprintf(buf, "Tex2RTF [%s]", FileNameFromPath(InputFile));
+ frame->SetTitle(buf);
+ }
+
+ // Make a menubar
+ wxMenu *file_menu = new wxMenu;
+ file_menu->Append(TEX_GO, "&Go", "Run converter");
+ file_menu->Append(TEX_SET_INPUT, "Set &Input File", "Set the LaTeX input file");
+ file_menu->Append(TEX_SET_OUTPUT, "Set &Output File", "Set the output file");
+ file_menu->AppendSeparator();
+ file_menu->Append(TEX_VIEW_LATEX, "View &LaTeX File", "View the LaTeX input file");
+ file_menu->Append(TEX_VIEW_OUTPUT, "View Output &File", "View output file");
+ file_menu->Append(TEX_SAVE_FILE, "&Save log file", "Save displayed text into file");
+ file_menu->AppendSeparator();
+ file_menu->Append(TEX_QUIT, "E&xit", "Exit Tex2RTF");
+
+ wxMenu *macro_menu = new wxMenu;
+
+ macro_menu->Append(TEX_LOAD_CUSTOM_MACROS, "&Load Custom Macros", "Load custom LaTeX macro file");
+ macro_menu->Append(TEX_VIEW_CUSTOM_MACROS, "View &Custom Macros", "View custom LaTeX macros");
+
+ wxMenu *mode_menu = new wxMenu;
+
+ mode_menu->Append(TEX_MODE_RTF, "Output linear &RTF", "Wordprocessor-compatible RTF");
+ mode_menu->Append(TEX_MODE_WINHELP, "Output &WinHelp RTF", "WinHelp-compatible RTF");
+ mode_menu->Append(TEX_MODE_HTML, "Output &HTML", "HTML World Wide Web hypertext file");
+ mode_menu->Append(TEX_MODE_XLP, "Output &XLP", "wxHelp hypertext help file");
+
+ wxMenu *help_menu = new wxMenu;
+
+ help_menu->Append(TEX_HELP, "&Help", "Tex2RTF Contents Page");
+ help_menu->Append(TEX_ABOUT, "&About Tex2RTF", "About Tex2RTF");
+
+ menuBar = new wxMenuBar;
+ menuBar->Append(file_menu, "&File");
+ menuBar->Append(macro_menu, "&Macros");
+ menuBar->Append(mode_menu, "&Conversion Mode");
+ menuBar->Append(help_menu, "&Help");
+
+ frame->SetMenuBar(menuBar);
+ frame->textWindow = new wxTextCtrl(frame, -1, "", wxPoint(-1, -1), wxSize(-1, -1), wxTE_READONLY|wxTE_MULTILINE);
+
+ (*frame->textWindow) << "Welcome to Julian Smart's LaTeX to RTF converter.\n";
+// ShowOptions();
+
+ HelpInstance = new wxHelpController();
+ HelpInstance->Initialize("tex2rtf");
+
+ /*
+ * Read macro/initialisation file
+ *
+ */
+
+ wxString path;
+ if ((path = TexPathList.FindValidPath(MacroFile)) != "")
+ ReadCustomMacros((char*) (const char*) path);
+
+ strcpy(buf, "In ");
+
+ if (winHelp && (convertMode == TEX_RTF))
+ strcat(buf, "WinHelp RTF");
+ else if (!winHelp && (convertMode == TEX_RTF))
+ strcat(buf, "linear RTF");
+ else if (convertMode == TEX_HTML) strcat(buf, "HTML");
+ else if (convertMode == TEX_XLP) strcat(buf, "XLP");
+ strcat(buf, " mode.");
+ frame->SetStatusText(buf, 1);
+
+ frame->Show(TRUE);
+ return TRUE;
+ }
+ else
+#endif // NO_GUI
+ {
+ /*
+ * Read macro/initialisation file
+ *
+ */
+
+ wxString path;
+ if ((path = TexPathList.FindValidPath(MacroFile)) != "")
+ ReadCustomMacros((char*) (const char*) path);
+
+ Go();
+ if (runTwice) Go();
+#ifdef NO_GUI
+ return 0;
+#else
+ return NULL;
+#endif
+ }
+
+#ifndef NO_GUI
+ // Return the main frame window
+ return TRUE;
+#else
+ return FALSE;
+#endif
+}
+
+int MyApp::OnExit()
+{
+ wxNode *node = CustomMacroList.First();
+ while (node)
+ {
+ CustomMacro *macro = (CustomMacro *)node->Data();
+ delete macro;
+ delete node;
+ node = CustomMacroList.First();
+ }
+ MacroDefs.BeginFind();
+ node = MacroDefs.Next();
+ while (node)
+ {
+ TexMacroDef* def = (TexMacroDef*) node->Data();
+ delete def;
+ node = MacroDefs.Next();
+ }
+ MacroDefs.Clear();
+#ifdef __WXMSW__
+ delete TheTex2RTFServer;
+#endif
+ delete HelpInstance;
+
+ // TODO: this simulates zero-memory leaks!
+ // Otherwise there are just too many...
+ wxDebugContext::SetCheckpoint();
+
+ return 0;
+}
+
+void ShowOptions(void)
+{
+ char buf[100];
+ sprintf(buf, "Tex2RTF version %.2f", versionNo);
+ OnInform(buf);
+ OnInform("Usage: tex2rtf [input] [output] [switches]\n");
+ OnInform("where valid switches are");
+ OnInform(" -interactive");
+ OnInform(" -bufsize <size in K>");
+ OnInform(" -charset <pc | pca | ansi | mac> (default ansi)");
+ OnInform(" -twice");
+ OnInform(" -sync");
+ OnInform(" -macros <filename>");
+ OnInform(" -winhelp");
+ OnInform(" -rtf");
+ OnInform(" -html");
+ OnInform(" -xlp\n");
+}
+
+#ifndef NO_GUI
+
+BEGIN_EVENT_TABLE(MyFrame, wxFrame)
+ EVT_CLOSE(MyFrame::OnCloseWindow)
+ EVT_MENU(TEX_QUIT, MyFrame::OnExit)
+ EVT_MENU(TEX_GO, MyFrame::OnGo)
+ EVT_MENU(TEX_SET_INPUT, MyFrame::OnSetInput)
+ EVT_MENU(TEX_SET_OUTPUT, MyFrame::OnSetOutput)
+ EVT_MENU(TEX_SAVE_FILE, MyFrame::OnSaveFile)
+ EVT_MENU(TEX_VIEW_LATEX, MyFrame::OnViewLatex)
+ EVT_MENU(TEX_VIEW_OUTPUT, MyFrame::OnViewOutput)
+ EVT_MENU(TEX_VIEW_CUSTOM_MACROS, MyFrame::OnShowMacros)
+ EVT_MENU(TEX_LOAD_CUSTOM_MACROS, MyFrame::OnLoadMacros)
+ EVT_MENU(TEX_MODE_RTF, MyFrame::OnModeRTF)
+ EVT_MENU(TEX_MODE_WINHELP, MyFrame::OnModeWinHelp)
+ EVT_MENU(TEX_MODE_HTML, MyFrame::OnModeHTML)
+ EVT_MENU(TEX_MODE_XLP, MyFrame::OnModeXLP)
+ EVT_MENU(TEX_HELP, MyFrame::OnHelp)
+ EVT_MENU(TEX_ABOUT, MyFrame::OnAbout)
+END_EVENT_TABLE()
+
+// My frame constructor
+MyFrame::MyFrame(wxFrame *frame, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size):
+ wxFrame(frame, id, title, pos, size)
+{}
+
+void MyFrame::OnCloseWindow(wxCloseEvent& event)
+{
+ if (!stopRunning && !OkToClose)
+ {
+ stopRunning = TRUE;
+ runTwice = FALSE;
+ return;
+ }
+ else if (OkToClose)
+ {
+#ifdef __WXMSW__
+ delete TheTex2RTFServer;
+ wxDDECleanUp();
+#endif
+ this->Destroy();
+ }
+}
+
+void MyFrame::OnExit(wxCommandEvent& event)
+{
+ this->Destroy();
+}
+
+void MyFrame::OnGo(wxCommandEvent& event)
+{
+ menuBar->EnableTop(0, FALSE);
+ menuBar->EnableTop(1, FALSE);
+ menuBar->EnableTop(2, FALSE);
+ menuBar->EnableTop(3, FALSE);
+ textWindow->Clear();
+ Tex2RTFYield(TRUE);
+ Go();
+
+ if (runTwice)
+ {
+ Tex2RTFYield(TRUE);
+ Go();
+ }
+ menuBar->EnableTop(0, TRUE);
+ menuBar->EnableTop(1, TRUE);
+ menuBar->EnableTop(2, TRUE);
+ menuBar->EnableTop(3, TRUE);
+}
+
+void MyFrame::OnSetInput(wxCommandEvent& event)
+{
+ ChooseInputFile(TRUE);
+}
+
+void MyFrame::OnSetOutput(wxCommandEvent& event)
+{
+ ChooseOutputFile(TRUE);
+}
+
+void MyFrame::OnSaveFile(wxCommandEvent& event)
+{
+ wxString s = wxFileSelector("Save text to file", "", "", "txt", "*.txt");
+ if (s != "")
+ {
+ textWindow->SaveFile(s);
+ char buf[350];
+ sprintf(buf, "Saved text to %s", (const char*) s);
+ frame->SetStatusText(buf, 0);
+ }
+}
+
+void MyFrame::OnViewOutput(wxCommandEvent& event)
+{
+ ChooseOutputFile();
+ if (OutputFile && wxFileExists(OutputFile))
+ {
+ textWindow->LoadFile(OutputFile);
+ char buf[300];
+ wxString str(wxFileNameFromPath(OutputFile));
+ sprintf(buf, "Tex2RTF [%s]", (const char*) str);
+ frame->SetTitle(buf);
+ }
+}
+
+void MyFrame::OnViewLatex(wxCommandEvent& event)
+{
+ ChooseInputFile();
+ if (InputFile && wxFileExists(InputFile))
+ {
+ textWindow->LoadFile(InputFile);
+ char buf[300];
+ wxString str(wxFileNameFromPath(OutputFile));
+ sprintf(buf, "Tex2RTF [%s]", (const char*) str);
+ frame->SetTitle(buf);
+ }
+}
+
+void MyFrame::OnLoadMacros(wxCommandEvent& event)
+{
+ textWindow->Clear();
+ wxString s = wxFileSelector("Choose custom macro file", wxPathOnly(MacroFile), wxFileNameFromPath(MacroFile), "ini", "*.ini");
+ if (s != "" && wxFileExists(s))
+ {
+ MacroFile = copystring(s);
+ ReadCustomMacros((char*) (const char*) s);
+ ShowCustomMacros();
+ }
+}
+
+void MyFrame::OnShowMacros(wxCommandEvent& event)
+{
+ textWindow->Clear();
+ Tex2RTFYield(TRUE);
+ ShowCustomMacros();
+}
+
+void MyFrame::OnModeRTF(wxCommandEvent& event)
+{
+ convertMode = TEX_RTF;
+ winHelp = FALSE;
+ InputFile = NULL;
+ OutputFile = NULL;
+ SetStatusText("In linear RTF mode.", 1);
+}
+
+void MyFrame::OnModeWinHelp(wxCommandEvent& event)
+{
+ convertMode = TEX_RTF;
+ winHelp = TRUE;
+ InputFile = NULL;
+ OutputFile = NULL;
+ SetStatusText("In WinHelp RTF mode.", 1);
+}
+
+void MyFrame::OnModeHTML(wxCommandEvent& event)
+{
+ convertMode = TEX_HTML;
+ winHelp = FALSE;
+ InputFile = NULL;
+ OutputFile = NULL;
+ SetStatusText("In HTML mode.", 1);
+}
+
+void MyFrame::OnModeXLP(wxCommandEvent& event)
+{
+ convertMode = TEX_XLP;
+ InputFile = NULL;
+ OutputFile = NULL;
+ SetStatusText("In XLP mode.", 1);
+}
+
+void MyFrame::OnHelp(wxCommandEvent& event)
+{
+ HelpInstance->LoadFile();
+ HelpInstance->DisplayContents();
+}
+
+void MyFrame::OnAbout(wxCommandEvent& event)
+{
+ char buf[300];
+#ifdef __WIN32__
+ char *platform = " (32-bit)";
+#else
+#ifdef __WXMSW__
+ char *platform = " (16-bit)";
+#else
+ char *platform = "";
+#endif
+#endif
+ sprintf(buf, "Tex2RTF Version %.2f%s\nLaTeX to RTF, WinHelp, HTML and wxHelp Conversion\n\n(c) Julian Smart 1999", versionNo, platform);
+ wxMessageBox(buf, "About Tex2RTF");
+}
+
+void ChooseInputFile(bool force)
+{
+ if (force || !InputFile)
+ {
+ wxString s = wxFileSelector("Choose LaTeX input file", wxPathOnly(InputFile), wxFileNameFromPath(InputFile), "tex", "*.tex");
+ if (s != "")
+ {
+ // Different file, so clear index entries.
+ ClearKeyWordTable();
+ ResetContentsLevels(0);
+ passNumber = 1;
+ char buf[300];
+ InputFile = copystring(s);
+ wxString str = wxFileNameFromPath(InputFile);
+ sprintf(buf, "Tex2RTF [%s]", (const char*) str);
+ frame->SetTitle(buf);
+ OutputFile = NULL;
+ }
+ }
+}
+
+void ChooseOutputFile(bool force)
+{
+ char extensionBuf[10];
+ char wildBuf[10];
+ strcpy(wildBuf, "*.");
+ char *path = NULL;
+ if (OutputFile)
+ path = wxPathOnly(OutputFile);
+ else if (InputFile)
+ path = wxPathOnly(InputFile);
+
+ switch (convertMode)
+ {
+ case TEX_RTF:
+ {
+ strcpy(extensionBuf, "rtf");
+ strcat(wildBuf, "rtf");
+ break;
+ }
+ case TEX_XLP:
+ {
+ strcpy(extensionBuf, "xlp");
+ strcat(wildBuf, "xlp");
+ break;
+ }
+ case TEX_HTML:
+ {
+#if defined(__WXMSW__) && defined(__WIN16__)
+ strcpy(extensionBuf, "htm");
+ strcat(wildBuf, "htm");
+#else
+ strcpy(extensionBuf, "html");
+ strcat(wildBuf, "html");
+#endif
+ break;
+ }
+ }
+ if (force || !OutputFile)
+ {
+ wxString s = wxFileSelector("Choose output file", path, wxFileNameFromPath(OutputFile),
+ extensionBuf, wildBuf);
+ if (s != "")
+ OutputFile = copystring(s);
+ }
+}
+#endif
+
+bool Go(void)
+{
+#ifndef NO_GUI
+ ChooseInputFile();
+ ChooseOutputFile();
+#endif
+
+ if (!InputFile || !OutputFile)
+ return FALSE;
+
+#ifndef NO_GUI
+ if (isInteractive)
+ {
+ char buf[300];
+ wxString str = wxFileNameFromPath(InputFile);
+
+ sprintf(buf, "Tex2RTF [%s]", (const char*) str);
+ frame->SetTitle(buf);
+ }
+
+ wxStartTimer();
+#endif
+
+ // Find extension-less filename
+ strcpy(FileRoot, OutputFile);
+ StripExtension(FileRoot);
+
+ if (truncateFilenames && convertMode == TEX_HTML)
+ {
+ // Truncate to five characters. This ensures that
+ // we can generate DOS filenames such as thing999. But 1000 files
+ // may not be enough, of course...
+ char* sName = wxFileNameFromPath( FileRoot); // this Julian's method is non-destructive reference
+
+ if(sName)
+ if(strlen( sName) > 5)
+ sName[5] = '\0'; // that should do!
+ }
+
+ sprintf(ContentsName, "%s.con", FileRoot);
+ sprintf(TmpContentsName, "%s.cn1", FileRoot);
+ sprintf(TmpFrameContentsName, "%s.frc", FileRoot);
+ sprintf(WinHelpContentsFileName, "%s.cnt", FileRoot);
+ sprintf(RefName, "%s.ref", FileRoot);
+
+ TexPathList.EnsureFileAccessible(InputFile);
+ if (!bulletFile)
+ {
+ wxString s = TexPathList.FindValidPath("bullet.bmp");
+ if (s != "")
+ {
+ wxString str = wxFileNameFromPath(s);
+ bulletFile = copystring(str);
+ }
+ }
+
+ if (wxFileExists(RefName))
+ ReadTexReferences(RefName);
+
+ bool success = FALSE;
+
+ if (InputFile && OutputFile)
+ {
+ if (!FileExists(InputFile))
+ {
+ OnError("Cannot open input file!");
+ TexCleanUp();
+ return FALSE;
+ }
+#ifndef NO_GUI
+ if (isInteractive)
+ {
+ char buf[50];
+ sprintf(buf, "Working, pass %d...", passNumber);
+ frame->SetStatusText(buf);
+ }
+#endif
+ OkToClose = FALSE;
+ OnInform("Reading LaTeX file...");
+ TexLoadFile(InputFile);
+
+ switch (convertMode)
+ {
+ case TEX_RTF:
+ {
+ success = RTFGo();
+ break;
+ }
+ case TEX_XLP:
+ {
+ success = XLPGo();
+ break;
+ }
+ case TEX_HTML:
+ {
+ success = HTMLGo();
+ break;
+ }
+ }
+ }
+ if (stopRunning)
+ {
+ OnInform("*** Aborted by user.");
+ success = FALSE;
+ stopRunning = FALSE;
+ }
+
+ if (success)
+ {
+ WriteTexReferences(RefName);
+ TexCleanUp();
+ startedSections = FALSE;
+
+ char buf[100];
+#ifndef NO_GUI
+ long tim = wxGetElapsedTime();
+ sprintf(buf, "Finished in %ld seconds.", (long)(tim/1000.0));
+ OnInform(buf);
+ if (isInteractive)
+ {
+ sprintf(buf, "Done, %d %s.", passNumber, (passNumber > 1) ? "passes" : "pass");
+ frame->SetStatusText(buf);
+ }
+#else
+ sprintf(buf, "Done, %d %s.", passNumber, (passNumber > 1) ? "passes" : "pass");
+ OnInform(buf);
+#endif
+ passNumber ++;
+ OkToClose = TRUE;
+ return TRUE;
+ }
+
+ TexCleanUp();
+ startedSections = FALSE;
+
+ OnInform("Sorry, unsuccessful.");
+ OkToClose = TRUE;
+ return FALSE;
+}
+
+void OnError(char *msg)
+{
+#ifdef NO_GUI
+ cerr << "Error: " << msg << "\n";
+ cerr.flush();
+#else
+ if (isInteractive)
+ (*frame->textWindow) << "Error: " << msg << "\n";
+ else
+#ifdef __UNIX__
+ {
+ cerr << "Error: " << msg << "\n";
+ cerr.flush();
+ }
+#endif
+#ifdef __WXMSW__
+ wxError(msg);
+#endif
+ Tex2RTFYield(TRUE);
+#endif // NO_GUI
+}
+
+void OnInform(char *msg)
+{
+#ifdef NO_GUI
+ cout << msg << "\n";
+ cout.flush();
+#else
+ if (isInteractive)
+ (*frame->textWindow) << msg << "\n";
+ else
+#ifdef __WXMSW__
+ {
+ cout << msg << "\n";
+ cout.flush();
+ }
+#endif
+#ifdef __WXMSW__
+ {}
+#endif
+ if (isInteractive)
+ {
+ Tex2RTFYield(TRUE);
+ }
+#endif // NO_GUI
+}
+
+void OnMacro(int macroId, int no_args, bool start)
+{
+ switch (convertMode)
+ {
+ case TEX_RTF:
+ {
+ RTFOnMacro(macroId, no_args, start);
+ break;
+ }
+ case TEX_XLP:
+ {
+ XLPOnMacro(macroId, no_args, start);
+ break;
+ }
+ case TEX_HTML:
+ {
+ HTMLOnMacro(macroId, no_args, start);
+ break;
+ }
+ }
+}
+
+bool OnArgument(int macroId, int arg_no, bool start)
+{
+ switch (convertMode)
+ {
+ case TEX_RTF:
+ {
+ return RTFOnArgument(macroId, arg_no, start);
+ break;
+ }
+ case TEX_XLP:
+ {
+ return XLPOnArgument(macroId, arg_no, start);
+ break;
+ }
+ case TEX_HTML:
+ {
+ return HTMLOnArgument(macroId, arg_no, start);
+ break;
+ }
+ }
+ return TRUE;
+}
+
+/*
+ * DDE Stuff
+ */
+#if defined(__WXMSW__) && !defined(NO_GUI)
+
+/*
+ * Server
+ */
+
+wxConnectionBase *Tex2RTFServer::OnAcceptConnection(const wxString& topic)
+{
+ if (topic == "TEX2RTF")
+ {
+ if (!ipc_buffer)
+ ipc_buffer = new char[1000];
+
+ return new Tex2RTFConnection(ipc_buffer, 4000);
+ }
+ else
+ return NULL;
+}
+
+ /*
+ * Connection
+ */
+
+Tex2RTFConnection::Tex2RTFConnection(char *buf, int size):wxDDEConnection(buf, size)
+{
+}
+
+Tex2RTFConnection::~Tex2RTFConnection(void)
+{
+}
+
+bool SplitCommand(char *data, char *firstArg, char *secondArg)
+{
+ firstArg[0] = 0;
+ secondArg[0] = 0;
+ int i = 0;
+ int len = strlen(data);
+ bool stop = FALSE;
+ // Find first argument (command name)
+ while (!stop)
+ {
+ if (data[i] == ' ' || data[i] == 0)
+ stop = TRUE;
+ else
+ {
+ firstArg[i] = data[i];
+ i ++;
+ }
+ }
+ firstArg[i] = 0;
+ if (data[i] == ' ')
+ {
+ // Find second argument
+ i ++;
+ int j = 0;
+ while (data[i] != 0)
+ {
+ secondArg[j] = data[i];
+ i ++;
+ j ++;
+ }
+ secondArg[j] = 0;
+ }
+ return TRUE;
+}
+
+bool Tex2RTFConnection::OnExecute(const wxString& topic, char *data, int size, int format)
+{
+ strcpy(Tex2RTFLastStatus, "OK");
+
+ char firstArg[50];
+ char secondArg[300];
+ if (SplitCommand(data, firstArg, secondArg))
+ {
+ bool hasArg = (strlen(secondArg) > 0);
+ if (strcmp(firstArg, "INPUT") == 0 && hasArg)
+ {
+ if (InputFile) delete[] InputFile;
+ InputFile = copystring(secondArg);
+ if (frame)
+ {
+ char buf[100];
+ wxString str = wxFileNameFromPath(InputFile);
+ sprintf(buf, "Tex2RTF [%s]", (const char*) str);
+ frame->SetTitle(buf);
+ }
+ }
+ else if (strcmp(firstArg, "OUTPUT") == 0 && hasArg)
+ {
+ if (OutputFile) delete[] OutputFile;
+ OutputFile = copystring(secondArg);
+ }
+ else if (strcmp(firstArg, "GO") == 0)
+ {
+ strcpy(Tex2RTFLastStatus, "WORKING");
+ if (!Go())
+ strcpy(Tex2RTFLastStatus, "CONVERSION ERROR");
+ else
+ strcpy(Tex2RTFLastStatus, "OK");
+ }
+ else if (strcmp(firstArg, "EXIT") == 0)
+ {
+ if (frame && frame->OnClose())
+ delete frame;
+ }
+ else if (strcmp(firstArg, "MINIMIZE") == 0 || strcmp(firstArg, "ICONIZE") == 0)
+ {
+ if (frame)
+ frame->Iconize(TRUE);
+ }
+ else if (strcmp(firstArg, "SHOW") == 0 || strcmp(firstArg, "RESTORE") == 0)
+ {
+ if (frame)
+ {
+ frame->Iconize(FALSE);
+ frame->Show(TRUE);
+ }
+ }
+ else
+ {
+ // Try for a setting
+ strcpy(Tex2RTFLastStatus, RegisterSetting(firstArg, secondArg, FALSE));
+#ifndef NO_GUI
+ if (frame && strcmp(firstArg, "conversionMode") == 0)
+ {
+ char buf[100];
+ strcpy(buf, "In ");
+
+ if (winHelp && (convertMode == TEX_RTF))
+ strcat(buf, "WinHelp RTF");
+ else if (!winHelp && (convertMode == TEX_RTF))
+ strcat(buf, "linear RTF");
+ else if (convertMode == TEX_HTML) strcat(buf, "HTML");
+ else if (convertMode == TEX_XLP) strcat(buf, "XLP");
+ strcat(buf, " mode.");
+ frame->SetStatusText(buf, 1);
+ }
+#endif
+ }
+ }
+ return TRUE;
+}
+
+char *Tex2RTFConnection::OnRequest(const wxString& topic, const wxString& item, int *size, int format)
+{
+ return Tex2RTFLastStatus;
+}
+
+#endif
+
--- /dev/null
+NAME TEX2RTF
+DESCRIPTION 'Tex2Rtf'
+EXETYPE WINDOWS
+STUB 'WINSTUB.EXE'
+CODE PRELOAD MOVEABLE DISCARDABLE
+DATA PRELOAD MOVEABLE MULTIPLE
+HEAPSIZE 3000
+STACKSIZE 20000
--- /dev/null
+/////////////////////////////////////////////////////////////////////////////
+// Name: tex2any.h
+// Purpose: tex2RTF conversion header
+// Author: Julian Smart
+// Modified by:
+// Created: 7.9.93
+// RCS-ID: $Id$
+// Copyright: (c) Julian Smart
+// Licence: wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifndef NO_GUI
+// Define a new application type
+class MyApp: public wxApp
+{ public:
+ bool OnInit();
+ int OnExit();
+};
+
+// Define a new frame type
+class MyFrame: public wxFrame
+{ public:
+ wxTextCtrl *textWindow;
+ MyFrame(wxFrame *frame, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size);
+ void OnMenuCommand(int id);
+
+ void OnCloseWindow(wxCloseEvent& event);
+ void OnExit(wxCommandEvent& event);
+ void OnGo(wxCommandEvent& event);
+ void OnSetInput(wxCommandEvent& event);
+ void OnSetOutput(wxCommandEvent& event);
+ void OnSaveFile(wxCommandEvent& event);
+ void OnViewOutput(wxCommandEvent& event);
+ void OnViewLatex(wxCommandEvent& event);
+ void OnLoadMacros(wxCommandEvent& event);
+ void OnShowMacros(wxCommandEvent& event);
+ void OnModeRTF(wxCommandEvent& event);
+ void OnModeWinHelp(wxCommandEvent& event);
+ void OnModeHTML(wxCommandEvent& event);
+ void OnModeXLP(wxCommandEvent& event);
+ void OnHelp(wxCommandEvent& event);
+ void OnAbout(wxCommandEvent& event);
+
+DECLARE_EVENT_TABLE()
+};
+
+#ifdef __WXMSW__
+#include "wx/dde.h"
+
+class Tex2RTFConnection: public wxDDEConnection
+{
+ public:
+ Tex2RTFConnection(char *buf, int size);
+ ~Tex2RTFConnection(void);
+ bool OnExecute(const wxString& topic, char *data, int size, int format);
+ char *OnRequest(const wxString& topic, const wxString& item, int *size, int format);
+};
+
+class Tex2RTFServer: public wxDDEServer
+{
+ public:
+ wxConnectionBase *OnAcceptConnection(const wxString& topic);
+};
+
+#endif // __WXMSW__
+
+#endif // NO_GUI
+
+/*
+ * Itemize/enumerate structure: put on a stack for
+ * getting the indentation right
+ *
+ */
+
+#define LATEX_ENUMERATE 1
+#define LATEX_ITEMIZE 2
+#define LATEX_DESCRIPTION 3
+#define LATEX_TWOCOL 5
+#define LATEX_INDENT 6
+
+class ItemizeStruc: public wxObject
+{
+ public:
+ int listType;
+ int currentItem;
+ int indentation;
+ int labelIndentation;
+ inline ItemizeStruc(int lType, int indent = 0, int labIndent = 0)
+ { listType = lType; currentItem = 0;
+ indentation = indent; labelIndentation = labIndent; }
+};
+
+// ID for the menu quit command
+#define TEX_QUIT 1
+#define TEX_GO 2
+
+#define TEX_SET_INPUT 3
+#define TEX_SET_OUTPUT 4
+
+#define TEX_VIEW_LATEX 5
+#define TEX_VIEW_OUTPUT 6
+
+#define TEX_VIEW_CUSTOM_MACROS 7
+#define TEX_LOAD_CUSTOM_MACROS 8
+
+#define TEX_MODE_RTF 9
+#define TEX_MODE_WINHELP 10
+#define TEX_MODE_HTML 11
+#define TEX_MODE_XLP 12
+
+#define TEX_HELP 13
+#define TEX_ABOUT 14
+#define TEX_SAVE_FILE 15
+
+extern TexChunk *currentMember;
+extern bool startedSections;
+extern char *contentsString;
+extern bool suppressNameDecoration;
+extern wxList itemizeStack;
+
+extern FILE *Contents;
+extern FILE *Chapters;
+extern FILE *Sections;
+extern FILE *Subsections;
+extern FILE *Subsubsections;
+
+extern char *InputFile;
+extern char *OutputFile;
+extern char *MacroFile;
+
+extern char *FileRoot;
+extern char *ContentsName; // Contents page from last time around
+extern char *TmpContentsName; // Current contents page
+extern char *TmpFrameContentsName; // Current frame contents page
+extern char *WinHelpContentsFileName; // WinHelp .cnt file
+extern char *RefName; // Reference file name
+extern char *bulletFile;
+
+#ifndef NO_GUI
+void ChooseOutputFile(bool force = FALSE);
+void ChooseInputFile(bool force = FALSE);
+#endif
+
+void RTFOnMacro(int macroId, int no_args, bool start);
+bool RTFOnArgument(int macroId, int arg_no, bool start);
+
+void HTMLOnMacro(int macroId, int no_args, bool start);
+bool HTMLOnArgument(int macroId, int arg_no, bool start);
+
+void XLPOnMacro(int macroId, int no_args, bool start);
+bool XLPOnArgument(int macroId, int arg_no, bool start);
+
+bool RTFGo(void);
+bool HTMLGo(void);
+bool XLPGo(void);
+
+#define ltHARDY 10000
--- /dev/null
+runTwice = yes
+titleFontSize = 12
+authorFontSize = 10
+chapterFontSize = 12
+sectionFontSize = 12
+subsectionFontSize = 12
+; RTF only
+headerRule = yes
+footerRule = yes
+useHeadingStyles = yes
+listItemIndent=40
+truncateFilenames = FALSE
+winHelpContents = yes
+winHelpVersion = 4 ; 3 for Windows 3.x, 4 for Windows 95
+generateHPJ = true
+\overview [2] { \image{}{books.bmp}\helpref{#1}{#2}}
+; Some stuff
\ No newline at end of file
--- /dev/null
+aaa ICON "tex2rtf.ico"
+tex2rtf ICON "tex2rtf.ico"
+#include "wx/msw/wx.rc"
+
--- /dev/null
+/* XPM */
+static char *tex2rtf_xpm[] = {
+/* width height num_colors chars_per_pixel */
+" 32 32 3 1",
+/* colors */
+". c #000000",
+"# c #c0c0c0",
+"a c #ffffff",
+/* pixels */
+"aaaaaaaaaaaaaaaaaaaaa.aaaaaaa..a",
+"aaaaaaaaaaaaaaaaaaaaa..aaaaa.aa.",
+"aaaaaaaaaaaaaaaaaaaa#.a.aaaa.aa.",
+"aaaaaaaaaaaaaaaaaaaa#..a.aaaaa.a",
+"aaaaaaaaaaaaaaaaaaaa#...a.aaaa.a",
+"aaaaaaaaaaaaaaaaa........a.aaaaa",
+"aaaaaaaaaaaaa....aaaa.....a.aa.a",
+"aaaaaaaaaaa..aaaa..........a.aaa",
+"aaaaaaaaa..aa...............a.aa",
+"aaaaaaaa.aa..................a.a",
+"aaaaaaa.a.....................#a",
+"aaaaaa.a.....................###",
+"aaaaa.a.....................###a",
+"aaaa.......................###aa",
+"aaaa..............###.....###aaa",
+"aaa...........#######....###aaaa",
+"aaa.........#####aaa#...###aaaaa",
+"aa........###aaaaaaaa..a##aaaaaa",
+"aa.......##aaaaaaaaaa.aa#aaaaaaa",
+"aa......##aaaaaaaaaaaaaaaaaaaaaa",
+"a......##aaaaaaaaaaaaaaaaaaaaaaa",
+"a.....##aaaaaaaaaaaaaaaaaaaaaaaa",
+"a.....#aaaaaaaaaaaaaaaaaaaaaaaaa",
+"a....#aaaaaaaaaaaaaaaaaaaaaaaaaa",
+"a....aaaa.aaaaaaaaaaaaaaaaaaaaaa",
+"a......a.a.a...aaa..a..aaaaaaaaa",
+"a...a.aa...aa.aaaaa.a.aaaaaaaaaa",
+"a...a.a.aaa.a.....aa.aaaaaaaaaaa",
+"aa.aa.aa.aaaa.a.aaa.a.aaaaaaaaaa",
+"aa.a.....aaaa.a..a..a..aaaaaaaaa",
+"aaaaaaaaaaaaaaa.aaaaaaaaaaaaaaaa",
+"aaaaaaaaaaaaaa....aaaaaaaaaaaaaa"
+};
--- /dev/null
+/////////////////////////////////////////////////////////////////////////////
+// Name: texutils.cpp
+// Purpose: Miscellaneous utilities
+// Author: Julian Smart
+// Modified by:
+// Created: 7.9.93
+// RCS-ID: $Id$
+// Copyright: (c) Julian Smart
+// Licence: wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+
+#ifndef WX_PRECOMP
+#include "wx/wx.h"
+#endif
+
+#include <wx/hash.h>
+
+#if wxUSE_IOSTREAMH
+#include <iostream.h>
+#include <fstream.h>
+#else
+#include <iostream>
+#include <fstream>
+#endif
+
+#include <ctype.h>
+#include "tex2any.h"
+
+wxHashTable TexReferences(wxKEY_STRING);
+wxList BibList(wxKEY_STRING);
+wxStringList CitationList;
+wxList ColourTable(wxKEY_STRING);
+wxHashTable BibStringTable(wxKEY_STRING);
+wxList CustomMacroList(wxKEY_STRING);
+TexChunk *currentSection = NULL;
+char *fakeCurrentSection = NULL;
+
+static long BibLine = 1;
+
+void OutputCurrentSection(void)
+{
+ if (fakeCurrentSection)
+ TexOutput(fakeCurrentSection);
+ else if (currentSection)
+ TraverseChildrenFromChunk(currentSection);
+}
+
+// Nasty but the way things are done now, necessary,
+// in order to output a chunk properly to a string (macros and all).
+void OutputCurrentSectionToString(char *buf)
+{
+ if (fakeCurrentSection)
+ strcpy(buf, fakeCurrentSection);
+ else
+ OutputChunkToString(currentSection, buf);
+}
+
+void OutputChunkToString(TexChunk *chunk, char *buf)
+{
+ FILE *tempfd = fopen("tmp.tmp", "w");
+ if (!tempfd)
+ return;
+
+ FILE *old1 = CurrentOutput1;
+ FILE *old2 = CurrentOutput2;
+
+ CurrentOutput1 = tempfd;
+ CurrentOutput2 = NULL;
+
+ TraverseChildrenFromChunk(chunk);
+
+ CurrentOutput1 = old1;
+ CurrentOutput2 = old2;
+
+ fclose(tempfd);
+
+ // Read from file into string
+ tempfd = fopen("tmp.tmp", "r");
+ if (!tempfd)
+ return;
+
+ buf[0] = 0;
+ int ch = -2;
+ int i = 0;
+ while (ch != EOF)
+ {
+ ch = getc(tempfd);
+ if (ch == EOF)
+ buf[i] = 0;
+ else
+ {
+ buf[i] = ch;
+ i ++;
+ }
+ }
+ fclose(tempfd);
+ wxRemoveFile("tmp.tmp");
+}
+
+// Called by Tex2Any to simulate a section
+void FakeCurrentSection(char *fakeSection, bool addToContents)
+{
+ currentSection = NULL;
+ if (fakeCurrentSection) delete[] fakeCurrentSection;
+ fakeCurrentSection = copystring(fakeSection);
+
+ if (DocumentStyle == LATEX_ARTICLE)
+ {
+ int mac = ltSECTIONHEADING;
+ if (!addToContents)
+ mac = ltSECTIONHEADINGSTAR;
+ OnMacro(mac, 0, TRUE);
+ OnMacro(mac, 0, FALSE);
+ }
+ else
+ {
+ int mac = ltCHAPTERHEADING;
+ if (!addToContents)
+ mac = ltCHAPTERHEADINGSTAR;
+ OnMacro(mac, 0, TRUE);
+ OnMacro(mac, 0, FALSE);
+ }
+ if (fakeCurrentSection) delete[] fakeCurrentSection;
+ fakeCurrentSection = NULL;
+}
+
+// Look for \label macro, use this ref name if found or
+// make up a topic name otherwise.
+static long topicCounter = 0;
+
+void ResetTopicCounter(void)
+{
+ topicCounter = 0;
+}
+
+static char *forceTopicName = NULL;
+
+void ForceTopicName(char *name)
+{
+ if (forceTopicName)
+ delete[] forceTopicName;
+ if (name)
+ forceTopicName = copystring(name);
+ else
+ forceTopicName = NULL;
+}
+
+char *FindTopicName(TexChunk *chunk)
+{
+ if (forceTopicName)
+ return forceTopicName;
+
+ char *topicName = NULL;
+ static char topicBuf[100];
+
+ if (chunk && (chunk->type == CHUNK_TYPE_MACRO) &&
+ (chunk->macroId == ltLABEL))
+ {
+ wxNode *node = chunk->children.First();
+ if (node)
+ {
+ TexChunk *child = (TexChunk *)node->Data();
+ if (child->type == CHUNK_TYPE_ARG)
+ {
+ wxNode *snode = child->children.First();
+ if (snode)
+ {
+ TexChunk *schunk = (TexChunk *)snode->Data();
+ if (schunk->type == CHUNK_TYPE_STRING)
+ topicName = schunk->value;
+ }
+ }
+ }
+ }
+ if (topicName)
+ return topicName;
+ else
+ {
+ sprintf(topicBuf, "topic%ld", topicCounter);
+ topicCounter ++;
+ return topicBuf;
+ }
+}
+
+/*
+ * Simulate argument data, so we can 'drive' clients which implement
+ * certain basic formatting behaviour.
+ * Snag is that some save a TexChunk, so don't use yet...
+ *
+ */
+
+void StartSimulateArgument(char *data)
+{
+ strcpy(currentArgData, data);
+ haveArgData = TRUE;
+}
+
+void EndSimulateArgument(void)
+{
+ haveArgData = FALSE;
+}
+
+/*
+ * Parse and convert unit arguments to points
+ *
+ */
+
+int ParseUnitArgument(char *unitArg)
+{
+ float conversionFactor = 1.0;
+ float unitValue = 0.0;
+ int len = strlen(unitArg);
+ // Get rid of any accidentally embedded commands
+ for (int i = 0; i < len; i++)
+ if (unitArg[i] == '\\')
+ unitArg[i] = 0;
+ len = strlen(unitArg);
+
+ if (unitArg && (len > 0) && (isdigit(unitArg[0]) || unitArg[0] == '-'))
+ {
+ sscanf(unitArg, "%f", &unitValue);
+ if (len > 1)
+ {
+ char units[3];
+ units[0] = unitArg[len-2];
+ units[1] = unitArg[len-1];
+ units[2] = 0;
+ if (strcmp(units, "in") == 0)
+ conversionFactor = 72.0;
+ else if (strcmp(units, "cm") == 0)
+ conversionFactor = 72.0/2.51;
+ else if (strcmp(units, "mm") == 0)
+ conversionFactor = 72.0/25.1;
+ else if (strcmp(units, "pt") == 0)
+ conversionFactor = 1;
+ }
+ return (int)(unitValue*conversionFactor);
+ }
+ else return 0;
+}
+
+/*
+ * Strip off any extension (dot something) from end of file,
+ * IF one exists. Inserts zero into buffer.
+ *
+ */
+
+void StripExtension(char *buffer)
+{
+ int len = strlen(buffer);
+ int i = len-1;
+ while (i > 0)
+ {
+ if (buffer[i] == '.')
+ {
+ buffer[i] = 0;
+ break;
+ }
+ i --;
+ }
+}
+
+/*
+ * Latex font setting
+ *
+ */
+
+void SetFontSizes(int pointSize)
+{
+ switch (pointSize)
+ {
+ case 12:
+ {
+ normalFont = 12;
+ smallFont = 10;
+ tinyFont = 8;
+ largeFont1 = 14;
+ LargeFont2 = 16;
+ LARGEFont3 = 20;
+ hugeFont1 = 24;
+ HugeFont2 = 28;
+ HUGEFont3 = 32;
+ break;
+ }
+ case 11:
+ {
+ normalFont = 11;
+ smallFont = 9;
+ tinyFont = 7;
+ largeFont1 = 13;
+ LargeFont2 = 16;
+ LARGEFont3 = 19;
+ hugeFont1 = 22;
+ HugeFont2 = 26;
+ HUGEFont3 = 30;
+ break;
+ }
+ case 10:
+ {
+ normalFont = 10;
+ smallFont = 8;
+ tinyFont = 6;
+ largeFont1 = 12;
+ LargeFont2 = 14;
+ LARGEFont3 = 18;
+ hugeFont1 = 20;
+ HugeFont2 = 24;
+ HUGEFont3 = 28;
+ break;
+ }
+ }
+}
+
+
+/*
+ * Latex references
+ *
+ */
+
+void AddTexRef(char *name, char *file, char *sectionName,
+ int chapter, int section, int subsection, int subsubsection)
+{
+ TexRef *texRef = (TexRef *)TexReferences.Get(name);
+ if (texRef) TexReferences.Delete(name);
+
+ char buf[100];
+ buf[0] = 0;
+/*
+ if (sectionName)
+ {
+ strcat(buf, sectionName);
+ strcat(buf, " ");
+ }
+*/
+ if (chapter)
+ {
+ char buf2[10];
+ sprintf(buf2, "%d", chapter);
+ strcat(buf, buf2);
+ }
+ if (section)
+ {
+ char buf2[10];
+ if (chapter)
+ strcat(buf, ".");
+
+ sprintf(buf2, "%d", section);
+ strcat(buf, buf2);
+ }
+ if (subsection)
+ {
+ char buf2[10];
+ strcat(buf, ".");
+ sprintf(buf2, "%d", subsection);
+ strcat(buf, buf2);
+ }
+ if (subsubsection)
+ {
+ char buf2[10];
+ strcat(buf, ".");
+ sprintf(buf2, "%d", subsubsection);
+ strcat(buf, buf2);
+ }
+ char *tmp = ((strlen(buf) > 0) ? buf : (char *)NULL);
+ TexReferences.Put(name, new TexRef(name, file, tmp, sectionName));
+}
+
+void WriteTexReferences(char *filename)
+{
+ ofstream ostr(filename);
+ if (ostr.bad()) return;
+ char buf[200];
+
+ TexReferences.BeginFind();
+ wxNode *node = TexReferences.Next();
+ while (node)
+ {
+ Tex2RTFYield();
+ TexRef *ref = (TexRef *)node->Data();
+ ostr << ref->refLabel << " " << (ref->refFile ? ref->refFile : "??") << " ";
+ ostr << (ref->sectionName ? ref->sectionName : "??") << " ";
+ ostr << (ref->sectionNumber ? ref->sectionNumber : "??") << "\n";
+ if (!ref->sectionNumber || (strcmp(ref->sectionNumber, "??") == 0 && strcmp(ref->sectionName, "??") == 0))
+ {
+ sprintf(buf, "Warning: reference %s not resolved.", ref->refLabel);
+ OnInform(buf);
+ }
+ node = TexReferences.Next();
+ }
+}
+
+void ReadTexReferences(char *filename)
+{
+ ifstream istr(filename, ios::nocreate | ios::in);
+ if (istr.bad()) return;
+
+ char label[100];
+ char file[400];
+ char section[100];
+ char sectionName[100];
+
+ while (!istr.eof())
+ {
+ istr >> label;
+ if (!istr.eof())
+ {
+ istr >> file;
+ istr >> sectionName;
+ char ch;
+ istr.get(ch); // Read past space
+ istr.get(ch);
+ int i = 0;
+ while (ch != '\n' && !istr.eof())
+ {
+ section[i] = ch;
+ i ++;
+ istr.get(ch);
+ }
+ section[i] = 0;
+ TexReferences.Put(label, new TexRef(label, file, section, sectionName));
+ }
+ }
+}
+
+
+/*
+ * Bibliography-handling code
+ *
+ */
+
+void BibEatWhiteSpace(istream& str)
+{
+ char ch = str.peek();
+
+ while (!str.eof() && (ch == ' ' || ch == '\t' || ch == 13 || ch == 10 || ch == EOF))
+ {
+ if (ch == 10)
+ BibLine ++;
+ str.get(ch);
+ if ((ch == EOF) || str.eof()) return;
+ ch = str.peek();
+ }
+
+ // Ignore end-of-line comments
+ if (ch == '%' || ch == ';' || ch == '#')
+ {
+ str.get(ch);
+ ch = str.peek();
+ while (ch != 10 && ch != 13 && !str.eof())
+ {
+ str.get(ch);
+ ch = str.peek();
+ }
+ BibEatWhiteSpace(str);
+ }
+}
+
+// Read word up to { or , or space
+void BibReadWord(istream& istr, char *buffer)
+{
+ int i = 0;
+ buffer[i] = 0;
+ char ch = istr.peek();
+ while (!istr.eof() && ch != ' ' && ch != '{' && ch != '(' && ch != 13 && ch != 10 && ch != '\t' &&
+ ch != ',' && ch != '=')
+ {
+ istr.get(ch);
+ buffer[i] = ch;
+ i ++;
+ ch = istr.peek();
+ }
+ buffer[i] = 0;
+}
+
+// Read string (double-quoted or not) to end quote or EOL
+void BibReadToEOL(istream& istr, char *buffer)
+{
+ int i = 0;
+ buffer[i] = 0;
+ char ch = istr.peek();
+ bool inQuotes = FALSE;
+ if (ch == '"')
+ {
+ istr.get(ch);
+ ch = istr.peek();
+ inQuotes = TRUE;
+ }
+ // If in quotes, read white space too. If not,
+ // stop at white space or comment.
+ while (!istr.eof() && ch != 13 && ch != 10 && ch != '"' &&
+ (inQuotes || ((ch != ' ') && (ch != 9) &&
+ (ch != ';') && (ch != '%') && (ch != '#'))))
+ {
+ istr.get(ch);
+ buffer[i] = ch;
+ i ++;
+ ch = istr.peek();
+ }
+ if (ch == '"')
+ istr.get(ch);
+ buffer[i] = 0;
+}
+
+// Read }-terminated value, taking nested braces into account.
+void BibReadValue(istream& istr, char *buffer, bool ignoreBraces = TRUE,
+ bool quotesMayTerminate = TRUE)
+{
+ int braceCount = 1;
+ int i = 0;
+ buffer[i] = 0;
+ char ch = istr.peek();
+ bool stopping = FALSE;
+ while (!istr.eof() && !stopping)
+ {
+// i ++;
+ if (i >= 2000)
+ {
+ char buf[100];
+ sprintf(buf, "Sorry, value > 2000 chars in bib file at line %ld, terminating.", BibLine);
+ wxFatalError(buf, "Tex2RTF Fatal Error");
+ }
+ istr.get(ch);
+
+ if (ch == '{')
+ braceCount ++;
+
+ if (ch == '}')
+ {
+ braceCount --;
+ if (braceCount == 0)
+ {
+ stopping = TRUE;
+ break;
+ }
+ }
+ else if (quotesMayTerminate && ch == '"')
+ {
+ stopping = TRUE;
+ break;
+ }
+ if (!stopping)
+ {
+ if (!ignoreBraces || (ch != '{' && ch != '}'))
+ {
+ buffer[i] = ch;
+ i ++;
+ }
+ }
+ if (ch == 10)
+ BibLine ++;
+ }
+ buffer[i] = 0;
+}
+
+bool ReadBib(char *filename)
+{
+ char buf[300];
+ ifstream istr(filename, ios::nocreate | ios::in);
+ if (istr.bad()) return FALSE;
+
+ BibLine = 1;
+
+ OnInform("Reading .bib file...");
+
+ char ch;
+ char fieldValue[2000];
+ char recordType[100];
+ char recordKey[100];
+ char recordField[100];
+ while (!istr.eof())
+ {
+ Tex2RTFYield();
+
+ BibEatWhiteSpace(istr);
+ istr.get(ch);
+ if (ch != '@')
+ {
+ sprintf(buf, "Expected @: malformed bib file at line %ld (%s)", BibLine, filename);
+ OnError(buf);
+ return FALSE;
+ }
+ BibReadWord(istr, recordType);
+ BibEatWhiteSpace(istr);
+ istr.get(ch);
+ if (ch != '{' && ch != '(')
+ {
+ sprintf(buf, "Expected { or ( after record type: malformed .bib file at line %ld (%s)", BibLine, filename);
+ OnError(buf);
+ return FALSE;
+ }
+ BibEatWhiteSpace(istr);
+ if (StringMatch(recordType, "string", FALSE, TRUE))
+ {
+ BibReadWord(istr, recordType);
+ BibEatWhiteSpace(istr);
+ istr.get(ch);
+ if (ch != '=')
+ {
+ sprintf(buf, "Expected = after string key: malformed .bib file at line %ld (%s)", BibLine, filename);
+ OnError(buf);
+ return FALSE;
+ }
+ BibEatWhiteSpace(istr);
+ istr.get(ch);
+ if (ch != '"' && ch != '{')
+ {
+ sprintf(buf, "Expected = after string key: malformed .bib file at line %ld (%s)", BibLine, filename);
+ OnError(buf);
+ return FALSE;
+ }
+ BibReadValue(istr, fieldValue);
+
+ // Now put in hash table if necesary
+ if (!BibStringTable.Get(recordType))
+ BibStringTable.Put(recordType, (wxObject *)copystring(fieldValue));
+
+ // Read closing ) or }
+ BibEatWhiteSpace(istr);
+ istr.get(ch);
+ BibEatWhiteSpace(istr);
+ }
+ else
+ {
+ BibReadWord(istr, recordKey);
+
+ BibEntry *bibEntry = new BibEntry;
+ bibEntry->key = copystring(recordKey);
+ bibEntry->type = copystring(recordType);
+
+ bool moreRecords = TRUE;
+ while (moreRecords && !istr.eof())
+ {
+ BibEatWhiteSpace(istr);
+ istr.get(ch);
+ if (ch == '}' || ch == ')')
+ {
+ moreRecords = FALSE;
+ }
+ else if (ch == ',')
+ {
+ BibEatWhiteSpace(istr);
+ BibReadWord(istr, recordField);
+ BibEatWhiteSpace(istr);
+ istr.get(ch);
+ if (ch != '=')
+ {
+ sprintf(buf, "Expected = after field type: malformed .bib file at line %ld (%s)", BibLine, filename);
+ OnError(buf);
+ return FALSE;
+ }
+ BibEatWhiteSpace(istr);
+ istr.get(ch);
+ if (ch != '{' && ch != '"')
+ {
+ fieldValue[0] = ch;
+ BibReadWord(istr, fieldValue+1);
+
+ // If in the table of strings, replace with string from table.
+ char *s = (char *)BibStringTable.Get(fieldValue);
+ if (s)
+ {
+ strcpy(fieldValue, s);
+ }
+ }
+ else
+ BibReadValue(istr, fieldValue, TRUE, (ch == '"' ? TRUE : FALSE));
+
+ // Now we can add a field
+ if (StringMatch(recordField, "author", FALSE, TRUE))
+ bibEntry->author = copystring(fieldValue);
+ else if (StringMatch(recordField, "key", FALSE, TRUE))
+ {}
+ else if (StringMatch(recordField, "annotate", FALSE, TRUE))
+ {}
+ else if (StringMatch(recordField, "abstract", FALSE, TRUE))
+ {}
+ else if (StringMatch(recordField, "edition", FALSE, TRUE))
+ {}
+ else if (StringMatch(recordField, "howpublished", FALSE, TRUE))
+ {}
+ else if (StringMatch(recordField, "note", FALSE, TRUE) || StringMatch(recordField, "notes", FALSE, TRUE))
+ {}
+ else if (StringMatch(recordField, "series", FALSE, TRUE))
+ {}
+ else if (StringMatch(recordField, "type", FALSE, TRUE))
+ {}
+ else if (StringMatch(recordField, "keywords", FALSE, TRUE))
+ {}
+ else if (StringMatch(recordField, "editor", FALSE, TRUE) || StringMatch(recordField, "editors", FALSE, TRUE))
+ bibEntry->editor= copystring(fieldValue);
+ else if (StringMatch(recordField, "title", FALSE, TRUE))
+ bibEntry->title= copystring(fieldValue);
+ else if (StringMatch(recordField, "booktitle", FALSE, TRUE))
+ bibEntry->booktitle= copystring(fieldValue);
+ else if (StringMatch(recordField, "journal", FALSE, TRUE))
+ bibEntry->journal= copystring(fieldValue);
+ else if (StringMatch(recordField, "volume", FALSE, TRUE))
+ bibEntry->volume= copystring(fieldValue);
+ else if (StringMatch(recordField, "number", FALSE, TRUE))
+ bibEntry->number= copystring(fieldValue);
+ else if (StringMatch(recordField, "year", FALSE, TRUE))
+ bibEntry->year= copystring(fieldValue);
+ else if (StringMatch(recordField, "month", FALSE, TRUE))
+ bibEntry->month= copystring(fieldValue);
+ else if (StringMatch(recordField, "pages", FALSE, TRUE))
+ bibEntry->pages= copystring(fieldValue);
+ else if (StringMatch(recordField, "publisher", FALSE, TRUE))
+ bibEntry->publisher= copystring(fieldValue);
+ else if (StringMatch(recordField, "address", FALSE, TRUE))
+ bibEntry->address= copystring(fieldValue);
+ else if (StringMatch(recordField, "institution", FALSE, TRUE) || StringMatch(recordField, "school", FALSE, TRUE))
+ bibEntry->institution= copystring(fieldValue);
+ else if (StringMatch(recordField, "organization", FALSE, TRUE) || StringMatch(recordField, "organisation", FALSE, TRUE))
+ bibEntry->organization= copystring(fieldValue);
+ else if (StringMatch(recordField, "comment", FALSE, TRUE) || StringMatch(recordField, "comments", FALSE, TRUE))
+ bibEntry->comment= copystring(fieldValue);
+ else if (StringMatch(recordField, "annote", FALSE, TRUE))
+ bibEntry->comment= copystring(fieldValue);
+ else if (StringMatch(recordField, "chapter", FALSE, TRUE))
+ bibEntry->chapter= copystring(fieldValue);
+ else
+ {
+ sprintf(buf, "Unrecognised bib field type %s at line %ld (%s)", recordField, BibLine, filename);
+ OnError(buf);
+ }
+ }
+ }
+ BibList.Append(recordKey, bibEntry);
+ BibEatWhiteSpace(istr);
+ }
+ }
+ return TRUE;
+}
+
+void OutputBibItem(TexRef *ref, BibEntry *bib)
+{
+ Tex2RTFYield();
+
+ OnMacro(ltNUMBEREDBIBITEM, 2, TRUE);
+ OnArgument(ltNUMBEREDBIBITEM, 1, TRUE);
+ TexOutput(ref->sectionNumber);
+ OnArgument(ltNUMBEREDBIBITEM, 1, FALSE);
+ OnArgument(ltNUMBEREDBIBITEM, 2, TRUE);
+
+ TexOutput(" ");
+ OnMacro(ltBF, 1, TRUE);
+ OnArgument(ltBF, 1, TRUE);
+ if (bib->author)
+ TexOutput(bib->author);
+ OnArgument(ltBF, 1, FALSE);
+ OnMacro(ltBF, 1, FALSE);
+ if (bib->author && (strlen(bib->author) > 0) && (bib->author[strlen(bib->author) - 1] != '.'))
+ TexOutput(". ");
+ else
+ TexOutput(" ");
+
+ if (bib->year)
+ {
+ TexOutput(bib->year);
+ }
+ if (bib->month)
+ {
+ TexOutput(" (");
+ TexOutput(bib->month);
+ TexOutput(")");
+ }
+ if (bib->year || bib->month)
+ TexOutput(". ");
+
+ if (StringMatch(bib->type, "article", FALSE, TRUE))
+ {
+ if (bib->title)
+ {
+ TexOutput(bib->title);
+ TexOutput(". ");
+ }
+ if (bib->journal)
+ {
+ OnMacro(ltIT, 1, TRUE);
+ OnArgument(ltIT, 1, TRUE);
+ TexOutput(bib->journal);
+ OnArgument(ltIT, 1, FALSE);
+ OnMacro(ltIT, 1, FALSE);
+ }
+ if (bib->volume)
+ {
+ TexOutput(", ");
+ OnMacro(ltBF, 1, TRUE);
+ OnArgument(ltBF, 1, TRUE);
+ TexOutput(bib->volume);
+ OnArgument(ltBF, 1, FALSE);
+ OnMacro(ltBF, 1, FALSE);
+ }
+ if (bib->number)
+ {
+ TexOutput("(");
+ TexOutput(bib->number);
+ TexOutput(")");
+ }
+ if (bib->pages)
+ {
+ TexOutput(", pages ");
+ TexOutput(bib->pages);
+ }
+ TexOutput(".");
+ }
+ else if (StringMatch(bib->type, "book", FALSE, TRUE) ||
+ StringMatch(bib->type, "unpublished", FALSE, TRUE) ||
+ StringMatch(bib->type, "manual", FALSE, TRUE) ||
+ StringMatch(bib->type, "phdthesis", FALSE, TRUE) ||
+ StringMatch(bib->type, "mastersthesis", FALSE, TRUE) ||
+ StringMatch(bib->type, "misc", FALSE, TRUE) ||
+ StringMatch(bib->type, "techreport", FALSE, TRUE) ||
+ StringMatch(bib->type, "booklet", FALSE, TRUE))
+ {
+ if (bib->title || bib->booktitle)
+ {
+ OnMacro(ltIT, 1, TRUE);
+ OnArgument(ltIT, 1, TRUE);
+ TexOutput(bib->title ? bib->title : bib->booktitle);
+ TexOutput(". ");
+ OnArgument(ltIT, 1, FALSE);
+ OnMacro(ltIT, 1, FALSE);
+ }
+ if (StringMatch(bib->type, "phdthesis", FALSE, TRUE))
+ TexOutput("PhD thesis. ");
+ if (StringMatch(bib->type, "techreport", FALSE, TRUE))
+ TexOutput("Technical report. ");
+ if (bib->editor)
+ {
+ TexOutput("Ed. ");
+ TexOutput(bib->editor);
+ TexOutput(". ");
+ }
+ if (bib->institution)
+ {
+ TexOutput(bib->institution);
+ TexOutput(". ");
+ }
+ if (bib->organization)
+ {
+ TexOutput(bib->organization);
+ TexOutput(". ");
+ }
+ if (bib->publisher)
+ {
+ TexOutput(bib->publisher);
+ TexOutput(". ");
+ }
+ if (bib->address)
+ {
+ TexOutput(bib->address);
+ TexOutput(". ");
+ }
+ }
+ else if (StringMatch(bib->type, "inbook", FALSE, TRUE) ||
+ StringMatch(bib->type, "inproceedings", FALSE, TRUE) ||
+ StringMatch(bib->type, "incollection", FALSE, TRUE) ||
+ StringMatch(bib->type, "conference", FALSE, TRUE))
+ {
+ if (bib->title)
+ {
+ TexOutput(bib->title);
+ }
+ if (bib->booktitle)
+ {
+ TexOutput(", from ");
+ OnMacro(ltIT, 1, TRUE);
+ OnArgument(ltIT, 1, TRUE);
+ TexOutput(bib->booktitle);
+ TexOutput(".");
+ OnArgument(ltIT, 1, FALSE);
+ OnMacro(ltIT, 1, FALSE);
+ }
+ if (bib->editor)
+ {
+ TexOutput(", ed. ");
+ TexOutput(bib->editor);
+ }
+ if (bib->publisher)
+ {
+ TexOutput(" ");
+ TexOutput(bib->publisher);
+ }
+ if (bib->address)
+ {
+ if (bib->publisher) TexOutput(", ");
+ else TexOutput(" ");
+ TexOutput(bib->address);
+ }
+ if (bib->publisher || bib->address)
+ TexOutput(".");
+
+ if (bib->volume)
+ {
+ TexOutput(" ");
+ OnMacro(ltBF, 1, TRUE);
+ OnArgument(ltBF, 1, TRUE);
+ TexOutput(bib->volume);
+ OnArgument(ltBF, 1, FALSE);
+ OnMacro(ltBF, 1, FALSE);
+ }
+ if (bib->number)
+ {
+ if (bib->volume)
+ {
+ TexOutput("(");
+ TexOutput(bib->number);
+ TexOutput(").");
+ }
+ else
+ {
+ TexOutput(" Number ");
+ TexOutput(bib->number);
+ TexOutput(".");
+ }
+ }
+ if (bib->chapter)
+ {
+ TexOutput(" Chap. "); TexOutput(bib->chapter);
+ }
+ if (bib->pages)
+ {
+ if (bib->chapter) TexOutput(", pages ");
+ else TexOutput(" Pages ");
+ TexOutput(bib->pages);
+ TexOutput(".");
+ }
+ }
+ OnArgument(ltNUMBEREDBIBITEM, 2, FALSE);
+ OnMacro(ltNUMBEREDBIBITEM, 2, FALSE);
+}
+
+void OutputBib(void)
+{
+ // Write the heading
+ ForceTopicName("bibliography");
+ FakeCurrentSection(ReferencesNameString);
+ ForceTopicName(NULL);
+
+ OnMacro(ltPAR, 0, TRUE);
+ OnMacro(ltPAR, 0, FALSE);
+
+ if ((convertMode == TEX_RTF) && !winHelp)
+ {
+ OnMacro(ltPAR, 0, TRUE);
+ OnMacro(ltPAR, 0, FALSE);
+ }
+
+ wxNode *node = CitationList.First();
+ while (node)
+ {
+ char *citeKey = (char *)node->Data();
+// wxNode *texNode = TexReferences.Find(citeKey);
+ TexRef *ref = (TexRef *)TexReferences.Get(citeKey);
+ wxNode *bibNode = BibList.Find(citeKey);
+ if (bibNode && ref)
+ {
+ BibEntry *entry = (BibEntry *)bibNode->Data();
+ OutputBibItem(ref, entry);
+ }
+ node = node->Next();
+ }
+}
+
+static int citeCount = 1;
+
+void ResolveBibReferences(void)
+{
+ if (CitationList.Number() > 0)
+ OnInform("Resolving bibliographic references...");
+
+ citeCount = 1;
+ char buf[200];
+ wxNode *node = CitationList.First();
+ while (node)
+ {
+ Tex2RTFYield();
+ char *citeKey = (char *)node->Data();
+// wxNode *texNode = TexReferences.Find(citeKey);
+ TexRef *ref = (TexRef *)TexReferences.Get(citeKey);
+ wxNode *bibNode = BibList.Find(citeKey);
+ if (bibNode && ref)
+ {
+ // Unused Variable
+ //BibEntry *entry = (BibEntry *)bibNode->Data();
+ if (ref->sectionNumber) delete[] ref->sectionNumber;
+ sprintf(buf, "[%d]", citeCount);
+ ref->sectionNumber = copystring(buf);
+ citeCount ++;
+ }
+ else
+ {
+ sprintf(buf, "Warning: bib ref %s not resolved.", citeKey);
+ OnInform(buf);
+ }
+ node = node->Next();
+ }
+}
+
+// Remember we need to resolve this citation
+void AddCitation(char *citeKey)
+{
+ if (!CitationList.Member(citeKey))
+ CitationList.Add(citeKey);
+
+ if (!TexReferences.Get(citeKey))
+ {
+ TexReferences.Put(citeKey, new TexRef(citeKey, "??", NULL));
+ }
+}
+
+TexRef *FindReference(char *key)
+{
+ return (TexRef *)TexReferences.Get(key);
+}
+
+/*
+ * Custom macro stuff
+ *
+ */
+
+bool StringTobool(char *val)
+{
+ if (strncmp(val, "yes", 3) == 0 || strncmp(val, "YES", 3) == 0 ||
+ strncmp(val, "on", 2) == 0 || strncmp(val, "ON", 2) == 0 ||
+ strncmp(val, "true", 4) == 0 || strncmp(val, "TRUE", 4) == 0 ||
+ strncmp(val, "ok", 2) == 0 || strncmp(val, "OK", 2) == 0 ||
+ strncmp(val, "1", 1) == 0)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+// Define a variable value from the .ini file
+char *RegisterSetting(char *settingName, char *settingValue, bool interactive)
+{
+ static char errorCode[100];
+ strcpy(errorCode, "OK");
+ if (StringMatch(settingName, "chapterName", FALSE, TRUE))
+ {
+ delete[] ChapterNameString;
+ ChapterNameString = copystring(settingValue);
+ }
+ else if (StringMatch(settingName, "sectionName", FALSE, TRUE))
+ {
+ delete[] SectionNameString;
+ SectionNameString = copystring(settingValue);
+ }
+ else if (StringMatch(settingName, "subsectionName", FALSE, TRUE))
+ {
+ delete[] SubsectionNameString;
+ SubsectionNameString = copystring(settingValue);
+ }
+ else if (StringMatch(settingName, "subsubsectionName", FALSE, TRUE))
+ {
+ delete[] SubsubsectionNameString;
+ SubsubsectionNameString = copystring(settingValue);
+ }
+ else if (StringMatch(settingName, "indexName", FALSE, TRUE))
+ {
+ delete[] IndexNameString;
+ IndexNameString = copystring(settingValue);
+ }
+ else if (StringMatch(settingName, "contentsName", FALSE, TRUE))
+ {
+ delete[] ContentsNameString;
+ ContentsNameString = copystring(settingValue);
+ }
+ else if (StringMatch(settingName, "glossaryName", FALSE, TRUE))
+ {
+ delete[] GlossaryNameString;
+ GlossaryNameString = copystring(settingValue);
+ }
+ else if (StringMatch(settingName, "referencesName", FALSE, TRUE))
+ {
+ delete[] ReferencesNameString;
+ ReferencesNameString = copystring(settingValue);
+ }
+ else if (StringMatch(settingName, "tablesName", FALSE, TRUE))
+ {
+ delete[] TablesNameString;
+ TablesNameString = copystring(settingValue);
+ }
+ else if (StringMatch(settingName, "figuresName", FALSE, TRUE))
+ {
+ delete[] FiguresNameString;
+ FiguresNameString = copystring(settingValue);
+ }
+ else if (StringMatch(settingName, "tableName", FALSE, TRUE))
+ {
+ delete[] TableNameString;
+ TableNameString = copystring(settingValue);
+ }
+ else if (StringMatch(settingName, "figureName", FALSE, TRUE))
+ {
+ delete[] FigureNameString;
+ FigureNameString = copystring(settingValue);
+ }
+ else if (StringMatch(settingName, "abstractName", FALSE, TRUE))
+ {
+ delete[] AbstractNameString;
+ AbstractNameString = copystring(settingValue);
+ }
+ else if (StringMatch(settingName, "chapterFontSize", FALSE, TRUE))
+ StringToInt(settingValue, &chapterFont);
+ else if (StringMatch(settingName, "sectionFontSize", FALSE, TRUE))
+ StringToInt(settingValue, §ionFont);
+ else if (StringMatch(settingName, "subsectionFontSize", FALSE, TRUE))
+ StringToInt(settingValue, &subsectionFont);
+ else if (StringMatch(settingName, "titleFontSize", FALSE, TRUE))
+ StringToInt(settingValue, &titleFont);
+ else if (StringMatch(settingName, "authorFontSize", FALSE, TRUE))
+ StringToInt(settingValue, &authorFont);
+ else if (StringMatch(settingName, "ignoreInput", FALSE, TRUE))
+ IgnorableInputFiles.Add(FileNameFromPath(settingValue));
+ else if (StringMatch(settingName, "mirrorMargins", FALSE, TRUE))
+ mirrorMargins = StringTobool(settingValue);
+ else if (StringMatch(settingName, "runTwice", FALSE, TRUE))
+ runTwice = StringTobool(settingValue);
+ else if (StringMatch(settingName, "isInteractive", FALSE, TRUE))
+ isInteractive = StringTobool(settingValue);
+ else if (StringMatch(settingName, "headerRule", FALSE, TRUE))
+ headerRule = StringTobool(settingValue);
+ else if (StringMatch(settingName, "footerRule", FALSE, TRUE))
+ footerRule = StringTobool(settingValue);
+ else if (StringMatch(settingName, "combineSubSections", FALSE, TRUE))
+ combineSubSections = StringTobool(settingValue);
+ else if (StringMatch(settingName, "listLabelIndent", FALSE, TRUE))
+ StringToInt(settingValue, &labelIndentTab);
+ else if (StringMatch(settingName, "listItemIndent", FALSE, TRUE))
+ StringToInt(settingValue, &itemIndentTab);
+ else if (StringMatch(settingName, "useUpButton", FALSE, TRUE))
+ useUpButton = StringTobool(settingValue);
+ else if (StringMatch(settingName, "useHeadingStyles", FALSE, TRUE))
+ useHeadingStyles = StringTobool(settingValue);
+ else if (StringMatch(settingName, "useWord", FALSE, TRUE))
+ useWord = StringTobool(settingValue);
+ else if (StringMatch(settingName, "contentsDepth", FALSE, TRUE))
+ StringToInt(settingValue, &contentsDepth);
+ else if (StringMatch(settingName, "generateHPJ", FALSE, TRUE))
+ generateHPJ = StringTobool(settingValue);
+ else if (StringMatch(settingName, "truncateFilenames", FALSE, TRUE))
+ truncateFilenames = StringTobool(settingValue);
+ else if (StringMatch(settingName, "winHelpVersion", FALSE, TRUE))
+ StringToInt(settingValue, &winHelpVersion);
+ else if (StringMatch(settingName, "winHelpContents", FALSE, TRUE))
+ winHelpContents = StringTobool(settingValue);
+ else if (StringMatch(settingName, "htmlIndex", FALSE, TRUE))
+ htmlIndex = StringTobool(settingValue);
+ else if (StringMatch(settingName, "htmlFrameContents", FALSE, TRUE))
+ htmlFrameContents = StringTobool(settingValue);
+ else if (StringMatch(settingName, "upperCaseNames", FALSE, TRUE))
+ upperCaseNames = StringTobool(settingValue);
+ else if (StringMatch(settingName, "winHelpTitle", FALSE, TRUE))
+ {
+ if (winHelpTitle)
+ delete[] winHelpTitle;
+ winHelpTitle = copystring(settingValue);
+ }
+ else if (StringMatch(settingName, "indexSubsections", FALSE, TRUE))
+ indexSubsections = StringTobool(settingValue);
+ else if (StringMatch(settingName, "compatibility", FALSE, TRUE))
+ compatibilityMode = StringTobool(settingValue);
+ else if (StringMatch(settingName, "defaultColumnWidth", FALSE, TRUE))
+ {
+ StringToInt(settingValue, &defaultTableColumnWidth);
+ defaultTableColumnWidth = 20*defaultTableColumnWidth;
+ }
+ else if (StringMatch(settingName, "bitmapMethod", FALSE, TRUE))
+ {
+ if ((strcmp(settingValue, "includepicture") != 0) && (strcmp(settingValue, "hex") != 0) &&
+ (strcmp(settingValue, "import") != 0))
+ {
+ if (interactive)
+ OnError("Unknown bitmapMethod");
+ strcpy(errorCode, "Unknown bitmapMethod");
+ }
+ else
+ {
+ delete[] bitmapMethod;
+ bitmapMethod = copystring(settingValue);
+ }
+ }
+ else if (StringMatch(settingName, "htmlBrowseButtons", FALSE, TRUE))
+ {
+ if (strcmp(settingValue, "none") == 0)
+ htmlBrowseButtons = HTML_BUTTONS_NONE;
+ else if (strcmp(settingValue, "bitmap") == 0)
+ htmlBrowseButtons = HTML_BUTTONS_BITMAP;
+ else if (strcmp(settingValue, "text") == 0)
+ htmlBrowseButtons = HTML_BUTTONS_TEXT;
+ else
+ {
+ if (interactive)
+ OnInform("Initialisation file error: htmlBrowseButtons must be one of none, bitmap, or text.");
+ strcpy(errorCode, "Initialisation file error: htmlBrowseButtons must be one of none, bitmap, or text.");
+ }
+ }
+ else if (StringMatch(settingName, "backgroundImage", FALSE, TRUE))
+ {
+ backgroundImageString = copystring(settingValue);
+ }
+ else if (StringMatch(settingName, "backgroundColour", FALSE, TRUE))
+ {
+ delete[] backgroundColourString;
+ backgroundColourString = copystring(settingValue);
+ }
+ else if (StringMatch(settingName, "textColour", FALSE, TRUE))
+ {
+ textColourString = copystring(settingValue);
+ }
+ else if (StringMatch(settingName, "linkColour", FALSE, TRUE))
+ {
+ linkColourString = copystring(settingValue);
+ }
+ else if (StringMatch(settingName, "followedLinkColour", FALSE, TRUE))
+ {
+ followedLinkColourString = copystring(settingValue);
+ }
+ else if (StringMatch(settingName, "conversionMode", FALSE, TRUE))
+ {
+ if (StringMatch(settingValue, "RTF", FALSE, TRUE))
+ {
+ winHelp = FALSE; convertMode = TEX_RTF;
+ }
+ else if (StringMatch(settingValue, "WinHelp", FALSE, TRUE))
+ {
+ winHelp = TRUE; convertMode = TEX_RTF;
+ }
+ else if (StringMatch(settingValue, "XLP", FALSE, TRUE) ||
+ StringMatch(settingValue, "wxHelp", FALSE, TRUE))
+ {
+ convertMode = TEX_XLP;
+ }
+ else if (StringMatch(settingValue, "HTML", FALSE, TRUE))
+ {
+ convertMode = TEX_HTML;
+ }
+ else
+ {
+ if (interactive)
+ OnInform("Initialisation file error: conversionMode must be one of\nRTF, WinHelp, XLP (or wxHelp), HTML.");
+ strcpy(errorCode, "Initialisation file error: conversionMode must be one of\nRTF, WinHelp, XLP (or wxHelp), HTML.");
+ }
+ }
+ else if (StringMatch(settingName, "documentFontSize", FALSE, TRUE))
+ {
+ int n;
+ StringToInt(settingValue, &n);
+ if (n == 10 || n == 11 || n == 12)
+ SetFontSizes(n);
+ else
+ {
+ char buf[200];
+ sprintf(buf, "Initialisation file error: nonstandard document font size %d.", n);
+ if (interactive)
+ OnInform(buf);
+ strcpy(errorCode, buf);
+ }
+ }
+ else
+ {
+ char buf[200];
+ sprintf(buf, "Initialisation file error: unrecognised setting %s.", settingName);
+ if (interactive)
+ OnInform(buf);
+ strcpy(errorCode, buf);
+ }
+ return errorCode;
+}
+
+bool ReadCustomMacros(char *filename)
+{
+ ifstream istr(filename, ios::nocreate | ios::in);
+ if (istr.bad()) return FALSE;
+
+ CustomMacroList.Clear();
+ char ch;
+ char macroName[100];
+ char macroBody[1000];
+ int noArgs;
+
+ while (!istr.eof())
+ {
+ BibEatWhiteSpace(istr);
+ istr.get(ch);
+ if (istr.eof())
+ break;
+
+ if (ch != '\\') // Not a macro definition, so must be NAME=VALUE
+ {
+ char settingName[100];
+ settingName[0] = ch;
+ BibReadWord(istr, (settingName+1));
+ BibEatWhiteSpace(istr);
+ istr.get(ch);
+ if (ch != '=')
+ {
+ OnError("Expected = following name: malformed tex2rtf.ini file.");
+ return FALSE;
+ }
+ else
+ {
+ char settingValue[200];
+ BibEatWhiteSpace(istr);
+ BibReadToEOL(istr, settingValue);
+ RegisterSetting(settingName, settingValue);
+ }
+ }
+ else
+ {
+ BibReadWord(istr, macroName);
+ BibEatWhiteSpace(istr);
+ istr.get(ch);
+ if (ch != '[')
+ {
+ OnError("Expected [ followed by number of arguments: malformed tex2rtf.ini file.");
+ return FALSE;
+ }
+ istr >> noArgs;
+ istr.get(ch);
+ if (ch != ']')
+ {
+ OnError("Expected ] following number of arguments: malformed tex2rtf.ini file.");
+ return FALSE;
+ }
+ BibEatWhiteSpace(istr);
+ istr.get(ch);
+ if (ch != '{')
+ {
+ OnError("Expected { followed by macro body: malformed tex2rtf.ini file.");
+ return FALSE;
+ }
+ CustomMacro *macro = new CustomMacro(macroName, noArgs, NULL);
+ BibReadValue(istr, macroBody, FALSE, FALSE); // Don't ignore extra braces
+ if (strlen(macroBody) > 0)
+ macro->macroBody = copystring(macroBody);
+
+ BibEatWhiteSpace(istr);
+ CustomMacroList.Append(macroName, macro);
+ AddMacroDef(ltCUSTOM_MACRO, macroName, noArgs);
+ }
+ }
+ char mbuf[200];
+ sprintf(mbuf, "Read initialization file %s.", filename);
+ OnInform(mbuf);
+ return TRUE;
+}
+
+CustomMacro *FindCustomMacro(char *name)
+{
+ wxNode *node = CustomMacroList.Find(name);
+ if (node)
+ {
+ CustomMacro *macro = (CustomMacro *)node->Data();
+ return macro;
+ }
+ return NULL;
+}
+
+// Display custom macros
+void ShowCustomMacros(void)
+{
+ wxNode *node = CustomMacroList.First();
+ if (!node)
+ {
+ OnInform("No custom macros loaded.\n");
+ return;
+ }
+
+ char buf[400];
+ while (node)
+ {
+ CustomMacro *macro = (CustomMacro *)node->Data();
+ sprintf(buf, "\\%s[%d]\n {%s}", macro->macroName, macro->noArgs,
+ macro->macroBody ? macro->macroBody : "");
+ OnInform(buf);
+ node = node->Next();
+ }
+}
+
+// Parse a string into several comma-separated fields
+char *ParseMultifieldString(char *allFields, int *pos)
+{
+ static char buffer[300];
+ int i = 0;
+ int fieldIndex = *pos;
+ int len = strlen(allFields);
+ int oldPos = *pos;
+ bool keepGoing = TRUE;
+ while ((fieldIndex <= len) && keepGoing)
+ {
+ if (allFields[fieldIndex] == ' ')
+ {
+ // Skip
+ fieldIndex ++;
+ }
+ else if (allFields[fieldIndex] == ',')
+ {
+ *pos = fieldIndex + 1;
+ keepGoing = FALSE;
+ }
+ else if (allFields[fieldIndex] == 0)
+ {
+ *pos = fieldIndex + 1;
+ keepGoing = FALSE;
+ }
+ else
+ {
+ buffer[i] = allFields[fieldIndex];
+ fieldIndex ++;
+ i++;
+ }
+ }
+ buffer[i] = 0;
+ if (oldPos == (*pos))
+ *pos = len + 1;
+
+ if (i == 0)
+ return NULL;
+ else
+ return buffer;
+}
+
+/*
+ * Colour tables
+ *
+ */
+
+ColourTableEntry::ColourTableEntry(char *theName, unsigned int r, unsigned int g, unsigned int b)
+{
+ name = copystring(theName);
+ red = r;
+ green = g;
+ blue = b;
+}
+
+ColourTableEntry::~ColourTableEntry(void)
+{
+ delete[] name;
+}
+
+void AddColour(char *theName, unsigned int r, unsigned int g, unsigned int b)
+{
+ wxNode *node = ColourTable.Find(theName);
+ if (node)
+ {
+ ColourTableEntry *entry = (ColourTableEntry *)node->Data();
+ if (entry->red == r || entry->green == g || entry->blue == b)
+ return;
+ else
+ {
+ delete entry;
+ delete node;
+ }
+ }
+ ColourTableEntry *entry = new ColourTableEntry(theName, r, g, b);
+ ColourTable.Append(theName, entry);
+}
+
+int FindColourPosition(char *theName)
+{
+ int i = 0;
+ wxNode *node = ColourTable.First();
+ while (node)
+ {
+ ColourTableEntry *entry = (ColourTableEntry *)node->Data();
+ if (strcmp(theName, entry->name) == 0)
+ return i;
+ i ++;
+ node = node->Next();
+ }
+ return -1;
+}
+
+// Converts e.g. "red" -> "#FF0000"
+extern void DecToHex(int, char *);
+bool FindColourHTMLString(char *theName, char *buf)
+{
+ int i = 0;
+ wxNode *node = ColourTable.First();
+ while (node)
+ {
+ ColourTableEntry *entry = (ColourTableEntry *)node->Data();
+ if (strcmp(theName, entry->name) == 0)
+ {
+ strcpy(buf, "#");
+
+ char buf2[3];
+ DecToHex(entry->red, buf2);
+ strcat(buf, buf2);
+ DecToHex(entry->green, buf2);
+ strcat(buf, buf2);
+ DecToHex(entry->blue, buf2);
+ strcat(buf, buf2);
+
+ return TRUE;
+ }
+ i ++;
+ node = node->Next();
+ }
+ return FALSE;
+}
+
+
+void InitialiseColourTable(void)
+{
+ // \\red0\\green0\\blue0;
+ AddColour("black", 0,0,0);
+
+ // \\red0\\green0\\blue255;\\red0\\green255\\blue255;\n");
+ AddColour("cyan", 0,255,255);
+
+ // \\red0\\green255\\blue0;
+ AddColour("green", 0,255,0);
+
+ // \\red255\\green0\\blue255;
+ AddColour("magenta", 255,0,255);
+
+ // \\red255\\green0\\blue0;
+ AddColour("red", 255,0,0);
+
+ // \\red255\\green255\\blue0;
+ AddColour("yellow", 255,255,0);
+
+ // \\red255\\green255\\blue255;}");
+ AddColour("white", 255,255,255);
+}
+
+/*
+ * The purpose of this is to reduce the number of times wxYield is
+ * called, since under Windows this can slow things down.
+ */
+
+static int yieldCount = 0;
+
+void Tex2RTFYield(bool force)
+{
+#ifdef __WXMSW__
+ if (isSync)
+ return;
+
+ if (force)
+ yieldCount = 0;
+ if (yieldCount == 0)
+ {
+ wxYield();
+ yieldCount = 10;
+ }
+ yieldCount --;
+#endif
+}
+
+// In both RTF generation and HTML generation for wxHelp version 2,
+// we need to associate \indexed keywords with the current filename/topics.
+
+// Hash table for lists of keywords for topics (WinHelp).
+wxHashTable TopicTable(wxKEY_STRING);
+void AddKeyWordForTopic(char *topic, char *entry, char *filename)
+{
+ TexTopic *texTopic = (TexTopic *)TopicTable.Get(topic);
+ if (!texTopic)
+ {
+ texTopic = new TexTopic(filename);
+ texTopic->keywords = new wxStringList;
+ TopicTable.Put(topic, texTopic);
+ }
+
+ if (!texTopic->keywords->Member(entry))
+ texTopic->keywords->Add(entry);
+}
+
+void ClearKeyWordTable(void)
+{
+ TopicTable.BeginFind();
+ wxNode *node = TopicTable.Next();
+ while (node)
+ {
+ TexTopic *texTopic = (TexTopic *)node->Data();
+ delete texTopic;
+ node = TopicTable.Next();
+ }
+ TopicTable.Clear();
+}
+
+
+/*
+ * TexTopic structure
+ */
+
+TexTopic::TexTopic(char *f)
+{
+ if (f)
+ filename = copystring(f);
+ else
+ filename = NULL;
+ hasChildren = FALSE;
+ keywords = NULL;
+}
+
+TexTopic::~TexTopic(void)
+{
+ if (keywords)
+ delete keywords;
+ if (filename)
+ delete[] filename;
+}
+
+// Convert case, according to upperCaseNames setting.
+char *ConvertCase(char *s)
+{
+ static char buf[256];
+ int len = strlen(s);
+ int i;
+ if (upperCaseNames)
+ for (i = 0; i < len; i ++)
+ buf[i] = wxToUpper(s[i]);
+ else
+ for (i = 0; i < len; i ++)
+ buf[i] = wxToLower(s[i]);
+ buf[i] = 0;
+ return buf;
+}
--- /dev/null
+/*
+ * File: wxhlpblk.h
+ * Purpose: Text blocks used in wxHelp
+ * Author: Julian Smart
+ * Created: 1993
+ * Updated:
+ * Copyright: (c) 1993, AIAI, University of Edinburgh
+ */
+
+/* sccsid[] = "%W% %G%" */
+
+#ifndef wxhlpblkh
+#define wxhlpblkh
+
+#define hyBLOCK_NORMAL 1
+#define hyBLOCK_RED 2
+#define hyBLOCK_BLUE 3
+#define hyBLOCK_GREEN 4
+#define hyBLOCK_LARGE_HEADING 5
+#define hyBLOCK_SMALL_HEADING 6
+#define hyBLOCK_ITALIC 7
+#define hyBLOCK_BOLD 8
+#define hyBLOCK_INVISIBLE_SECTION 9
+#define hyBLOCK_LARGE_VISIBLE_SECTION 10
+#define hyBLOCK_SMALL_VISIBLE_SECTION 11
+#define hyBLOCK_SMALL_TEXT 12
+#define hyBLOCK_RED_ITALIC 13
+#define hyBLOCK_TELETYPE 14
+
+#endif // wxhlpblkh
--- /dev/null
+/////////////////////////////////////////////////////////////////////////////
+// Name: xlputils.cpp
+// Purpose: Converts Latex to obsolete XLP format
+// Author: Julian Smart
+// Modified by:
+// Created: 7.9.93
+// RCS-ID: $Id$
+// Copyright: (c) Julian Smart
+// Licence: wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+
+#ifndef WX_PRECOMP
+#include "wx/wx.h"
+#endif
+
+#include "tex2any.h"
+#include "tex2rtf.h"
+#include <ctype.h>
+
+long currentBlockId = -1;
+static TexChunk *descriptionItemArg = NULL;
+static int indentLevel = 0;
+static int noColumns = 0;
+static int currentTab = 0;
+static bool tableVerticalLineLeft = FALSE;
+static bool tableVerticalLineRight = FALSE;
+static bool inTable = FALSE;
+static int citeCount = 1;
+wxList hyperLinks(wxKEY_INTEGER);
+wxList hyperLabels(wxKEY_STRING);
+FILE *Index = NULL;
+
+void PadToTab(int tabPos)
+{
+ int currentCol = GetCurrentColumn();
+ for (int i = currentCol; i < tabPos; i++)
+ TexOutput(" ", TRUE);
+}
+
+static long xlpBlockId = 0;
+long NewBlockId(void)
+{
+ return xlpBlockId ++;
+}
+
+// Called on start/end of macro examination
+void XLPOnMacro(int macroId, int no_args, bool start)
+{
+ char buf[100];
+ switch (macroId)
+ {
+ case ltCHAPTER:
+ case ltCHAPTERSTAR:
+ case ltCHAPTERHEADING:
+ {
+ if (!start)
+ {
+ sectionNo = 0;
+ figureNo = 0;
+ subsectionNo = 0;
+ subsubsectionNo = 0;
+ if (macroId != ltCHAPTERSTAR)
+ chapterNo ++;
+
+ SetCurrentOutputs(Contents, Chapters);
+ long id1 = NewBlockId();
+ currentBlockId = NewBlockId();
+
+ startedSections = TRUE;
+ fprintf(Contents, "\\hy-%d{%ld}{", hyBLOCK_SMALL_HEADING, id1);
+ fprintf(Chapters, "\n\\hy-%d{%ld}{", hyBLOCK_LARGE_VISIBLE_SECTION, currentBlockId);
+ fprintf(Index, "%ld %ld\n", id1, currentBlockId);
+
+ OutputCurrentSection(); // Repeat section header
+
+ fprintf(Contents, "}\n\n");
+ fprintf(Chapters, "}\n\n");
+ SetCurrentOutput(Chapters);
+ char *topicName = FindTopicName(GetNextChunk());
+ hyperLabels.Append(topicName, (wxObject *)currentBlockId);
+ }
+ break;
+ }
+ case ltSECTION:
+ case ltSECTIONSTAR:
+ case ltSECTIONHEADING:
+ case ltGLOSS:
+ {
+ if (!start)
+ {
+ subsectionNo = 0;
+ subsubsectionNo = 0;
+
+ if (macroId != ltSECTIONSTAR)
+ sectionNo ++;
+
+ SetCurrentOutputs(Chapters, Sections);
+ long id1 = NewBlockId();
+ currentBlockId = NewBlockId();
+
+ startedSections = TRUE;
+
+ if (DocumentStyle == LATEX_ARTICLE)
+ fprintf(Contents, "\\hy-%d{%ld}{", hyBLOCK_LARGE_HEADING, id1);
+ else
+ fprintf(Chapters, "\\hy-%d{%ld}{", hyBLOCK_BOLD, id1);
+ fprintf(Sections, "\n\\hy-%d{%ld}{", hyBLOCK_LARGE_VISIBLE_SECTION, currentBlockId);
+ fprintf(Index, "%ld %ld\n", id1, currentBlockId);
+
+ OutputCurrentSection(); // Repeat section header
+
+ if (DocumentStyle == LATEX_ARTICLE)
+ fprintf(Contents, "}\n\n");
+ else
+ fprintf(Chapters, "}\n\n");
+ fprintf(Sections, "}\n\n");
+ SetCurrentOutput(Sections);
+ char *topicName = FindTopicName(GetNextChunk());
+ hyperLabels.Append(topicName, (wxObject *)currentBlockId);
+ }
+ break;
+ }
+ case ltSUBSECTION:
+ case ltSUBSECTIONSTAR:
+ case ltMEMBERSECTION:
+ case ltFUNCTIONSECTION:
+ {
+ if (!start)
+ {
+ subsubsectionNo = 0;
+
+ if (macroId != ltSUBSECTIONSTAR)
+ subsectionNo ++;
+
+ SetCurrentOutputs(Sections, Subsections);
+ long id1 = NewBlockId();
+ currentBlockId = NewBlockId();
+ fprintf(Sections, "\\hy-%d{%ld}{", hyBLOCK_BOLD, id1);
+ fprintf(Subsections, "\n\\hy-%d{%ld}{", hyBLOCK_LARGE_VISIBLE_SECTION, currentBlockId);
+ fprintf(Index, "%ld %ld\n", id1, currentBlockId);
+
+ OutputCurrentSection(); // Repeat section header
+
+ fprintf(Sections, "}\n\n");
+ fprintf(Subsections, "}\n\n");
+ SetCurrentOutput(Subsections);
+ char *topicName = FindTopicName(GetNextChunk());
+ hyperLabels.Append(topicName, (wxObject *)currentBlockId);
+ }
+ break;
+ }
+ case ltSUBSUBSECTION:
+ case ltSUBSUBSECTIONSTAR:
+ {
+ if (!start)
+ {
+ if (macroId != ltSUBSUBSECTIONSTAR)
+ subsubsectionNo ++;
+
+ SetCurrentOutputs(Subsections, Subsubsections);
+ long id1 = NewBlockId();
+ currentBlockId = NewBlockId();
+ fprintf(Subsections, "\\hy-%d{%ld}{", hyBLOCK_BOLD, id1);
+ fprintf(Subsubsections, "\n\\hy-%d{%ld}{", hyBLOCK_LARGE_VISIBLE_SECTION, currentBlockId);
+ fprintf(Index, "%ld %ld\n", id1, currentBlockId);
+
+ OutputCurrentSection(); // Repeat section header
+
+ fprintf(Subsections, "}\n\n");
+ fprintf(Subsubsections, "}\n\n");
+ SetCurrentOutput(Subsubsections);
+ char *topicName = FindTopicName(GetNextChunk());
+ hyperLabels.Append(topicName, (wxObject *)currentBlockId);
+ }
+ break;
+ }
+ case ltFUNC:
+ case ltPFUNC:
+ case ltMEMBER:
+ {
+ SetCurrentOutput(Subsections);
+ if (start)
+ {
+ long id = NewBlockId();
+ fprintf(Subsections, "\\hy-%d{%ld}{", hyBLOCK_BOLD, id);
+ }
+ else
+ fprintf(Subsections, "}");
+ break;
+ }
+ case ltVOID:
+// if (start)
+// TexOutput("void", TRUE);
+ break;
+ case ltBACKSLASHCHAR:
+ if (start)
+ TexOutput("\n", TRUE);
+ break;
+ case ltPAR:
+ {
+ if (start)
+ {
+ if (ParSkip > 0)
+ TexOutput("\n", TRUE);
+ TexOutput("\n", TRUE);
+ }
+ break;
+ }
+ case ltRMFAMILY:
+ case ltTEXTRM:
+ case ltRM:
+ {
+ break;
+ }
+ case ltTEXTBF:
+ case ltBFSERIES:
+ case ltBF:
+ {
+ if (start)
+ {
+ char buf[100];
+ long id = NewBlockId();
+ sprintf(buf, "\\hy-%d{%ld}{", hyBLOCK_BOLD, id);
+ TexOutput(buf);
+ }
+ else TexOutput("}");
+ break;
+ }
+ case ltTEXTIT:
+ case ltITSHAPE:
+ case ltIT:
+ {
+ if (start)
+ {
+ char buf[100];
+ long id = NewBlockId();
+ sprintf(buf, "\\hy-%d{%ld}{", hyBLOCK_ITALIC, id);
+ TexOutput(buf);
+ }
+ else TexOutput("}");
+ break;
+ }
+ case ltTTFAMILY:
+ case ltTEXTTT:
+ case ltTT:
+ {
+ if (start)
+ {
+ long id = NewBlockId();
+ sprintf(buf, "\\hy-%d{%ld}{", hyBLOCK_TELETYPE, id);
+ TexOutput(buf);
+ }
+ else TexOutput("}");
+ break;
+ }
+ case ltSMALL:
+ {
+ if (start)
+ {
+ sprintf(buf, "\\hy-%d{%ld}{", hyBLOCK_SMALL_TEXT, NewBlockId());
+ TexOutput(buf);
+ }
+ else TexOutput("}");
+ break;
+ }
+ case ltTINY:
+ {
+ if (start)
+ {
+ sprintf(buf, "\\hy-%d{%ld}{", hyBLOCK_SMALL_TEXT, NewBlockId());
+ TexOutput(buf);
+ }
+ else TexOutput("}");
+ break;
+ }
+ case ltNORMALSIZE:
+ {
+ if (start)
+ {
+ sprintf(buf, "\\hy-%d{%ld}{", hyBLOCK_NORMAL, NewBlockId());
+ TexOutput(buf);
+ }
+ else TexOutput("}");
+ break;
+ }
+ case ltlarge:
+ {
+ if (start)
+ {
+ sprintf(buf, "\\hy-%d{%ld}{", hyBLOCK_SMALL_HEADING, NewBlockId());
+ TexOutput(buf);
+ }
+ else TexOutput("}\n");
+ break;
+ }
+ case ltLARGE:
+ {
+ if (start)
+ {
+ sprintf(buf, "\\hy-%d{%ld}{", hyBLOCK_LARGE_HEADING, NewBlockId());
+ TexOutput(buf);
+ }
+ else TexOutput("}\n");
+ break;
+ }
+ case ltITEMIZE:
+ case ltENUMERATE:
+ case ltDESCRIPTION:
+ case ltTWOCOLLIST:
+ {
+ if (start)
+ {
+// tabCount ++;
+
+// if (indentLevel > 0)
+// TexOutput("\\par\\par\n");
+ indentLevel ++;
+ int listType;
+ if (macroId == ltENUMERATE)
+ listType = LATEX_ENUMERATE;
+ else if (macroId == ltITEMIZE)
+ listType = LATEX_ITEMIZE;
+ else
+ listType = LATEX_DESCRIPTION;
+ itemizeStack.Insert(new ItemizeStruc(listType));
+
+ }
+ else
+ {
+ indentLevel --;
+
+ if (itemizeStack.First())
+ {
+ ItemizeStruc *struc = (ItemizeStruc *)itemizeStack.First()->Data();
+ delete struc;
+ delete itemizeStack.First();
+ }
+ }
+ break;
+ }
+ case ltITEM:
+ {
+ wxNode *node = itemizeStack.First();
+ if (node)
+ {
+ ItemizeStruc *struc = (ItemizeStruc *)node->Data();
+ if (!start)
+ {
+ struc->currentItem += 1;
+ char indentBuf[30];
+
+ switch (struc->listType)
+ {
+ case LATEX_ENUMERATE:
+ {
+ sprintf(indentBuf, "\\hy-%d{%ld}{%d.} ",
+ hyBLOCK_BOLD, NewBlockId(), struc->currentItem);
+ TexOutput(indentBuf);
+ break;
+ }
+ case LATEX_ITEMIZE:
+ {
+ sprintf(indentBuf, "\\hy-%d{%ld}{o} ",
+ hyBLOCK_BOLD, NewBlockId());
+ TexOutput(indentBuf);
+ break;
+ }
+ default:
+ case LATEX_DESCRIPTION:
+ {
+ if (descriptionItemArg)
+ {
+ sprintf(indentBuf, "\\hy-%d{%ld}{",
+ hyBLOCK_BOLD, NewBlockId());
+ TexOutput(indentBuf);
+ TraverseChildrenFromChunk(descriptionItemArg);
+ TexOutput("} ");
+ descriptionItemArg = NULL;
+ }
+ break;
+ }
+ }
+ }
+ }
+ break;
+ }
+ case ltMAKETITLE:
+ {
+ if (start && DocumentTitle && DocumentAuthor)
+ {
+ sprintf(buf, "\\hy-%d{%ld}{", hyBLOCK_LARGE_HEADING, NewBlockId());
+ TexOutput(buf);
+ TraverseChildrenFromChunk(DocumentTitle);
+ TexOutput("}\n\n");
+ sprintf(buf, "\\hy-%d{%ld}{", hyBLOCK_SMALL_HEADING, NewBlockId());
+ TexOutput(buf);
+ TraverseChildrenFromChunk(DocumentAuthor);
+ TexOutput("}\n\n");
+ if (DocumentDate)
+ {
+ TraverseChildrenFromChunk(DocumentDate);
+ TexOutput("\n");
+ }
+ }
+ break;
+ }
+ case ltTABLEOFCONTENTS:
+ {
+ if (start)
+ {
+ FILE *fd = fopen(ContentsName, "r");
+ if (fd)
+ {
+ int ch = getc(fd);
+ while (ch != EOF)
+ {
+ putc(ch, Chapters);
+ ch = getc(fd);
+ }
+ fclose(fd);
+ }
+ else
+ {
+ TexOutput("RUN TEX2RTF AGAIN FOR CONTENTS PAGE\n");
+ OnInform("Run Tex2RTF again to include contents page.");
+ }
+ }
+ break;
+ }
+ case ltHARDY:
+ {
+ if (start)
+ TexOutput("HARDY", TRUE);
+ break;
+ }
+ case ltWXCLIPS:
+ {
+ if (start)
+ TexOutput("wxCLIPS", TRUE);
+ break;
+ }
+ case ltVERBATIM:
+ {
+ if (start)
+ {
+ char buf[100];
+ long id = NewBlockId();
+ sprintf(buf, "\\hy-%d{%ld}{", hyBLOCK_TELETYPE, id);
+ TexOutput(buf);
+ }
+ else TexOutput("}");
+ break;
+ }
+ case ltHRULE:
+ {
+ if (start)
+ {
+ TexOutput("\n------------------------------------------------------------------", TRUE);
+ }
+ break;
+ }
+ case ltHLINE:
+ {
+ if (start)
+ {
+ TexOutput("--------------------------------------------------------------------------------", TRUE);
+ }
+ break;
+ }
+ case ltSPECIALAMPERSAND:
+ {
+ if (start)
+ {
+ currentTab ++;
+ int tabPos = (80/noColumns)*currentTab;
+ PadToTab(tabPos);
+ }
+ break;
+ }
+ case ltTABULAR:
+ case ltSUPERTABULAR:
+ {
+ if (start)
+ {
+ sprintf(buf, "\\hy-%d{%ld}{", hyBLOCK_TELETYPE, NewBlockId());
+ TexOutput(buf);
+ }
+ else
+ TexOutput("}");
+ break;
+ }
+ case ltNUMBEREDBIBITEM:
+ {
+ if (!start)
+ TexOutput("\n\n", TRUE);
+ break;
+ }
+ case ltCAPTION:
+ case ltCAPTIONSTAR:
+ {
+ if (start)
+ {
+ figureNo ++;
+
+ char figBuf[40];
+ if (DocumentStyle != LATEX_ARTICLE)
+ sprintf(figBuf, "Figure %d.%d: ", chapterNo, figureNo);
+ else
+ sprintf(figBuf, "Figure %d: ", figureNo);
+
+ TexOutput(figBuf);
+ }
+ else
+ {
+ char *topicName = FindTopicName(GetNextChunk());
+
+ AddTexRef(topicName, NULL, NULL,
+ ((DocumentStyle != LATEX_ARTICLE) ? chapterNo : figureNo),
+ ((DocumentStyle != LATEX_ARTICLE) ? figureNo : 0));
+ }
+ break;
+ }
+ default:
+ {
+ DefaultOnMacro(macroId, no_args, start);
+ break;
+ }
+ }
+}
+
+bool XLPOnArgument(int macroId, int arg_no, bool start)
+{
+ char buf[300];
+ switch (macroId)
+ {
+ case ltCHAPTER:
+ case ltCHAPTERSTAR:
+ case ltCHAPTERHEADING:
+ case ltSECTION:
+ case ltSECTIONSTAR:
+ case ltSECTIONHEADING:
+ case ltSUBSECTION:
+ case ltSUBSECTIONSTAR:
+ case ltSUBSUBSECTION:
+ case ltSUBSUBSECTIONSTAR:
+ case ltGLOSS:
+ case ltMEMBERSECTION:
+ case ltFUNCTIONSECTION:
+ {
+ if (!start && (arg_no == 1))
+ currentSection = GetArgChunk();
+ return FALSE;
+ break;
+ }
+ case ltFUNC:
+ {
+ if (!start && (arg_no == 1))
+ TexOutput(" ", TRUE);
+ if (start && (arg_no == 3))
+ TexOutput("(", TRUE);
+ if (!start && (arg_no == 3))
+ TexOutput(")", TRUE);
+ break;
+ }
+ case ltPFUNC:
+ {
+ if (!start && (arg_no == 1))
+ TexOutput(" ", TRUE);
+
+ if (start && (arg_no == 2))
+ TexOutput("(*", TRUE);
+ if (!start && (arg_no == 2))
+ TexOutput(")", TRUE);
+
+ if (start && (arg_no == 3))
+ TexOutput("(", TRUE);
+ if (!start && (arg_no == 3))
+ TexOutput(")", TRUE);
+ break;
+ }
+ case ltCLIPSFUNC:
+ {
+ if (!start && (arg_no == 1))
+ TexOutput(" ", TRUE);
+ if (start && (arg_no == 2))
+ {
+ TexOutput("(", TRUE);
+ long id = NewBlockId();
+ sprintf(buf, "\\hy-%d{%ld}{", hyBLOCK_BOLD, id);
+ TexOutput(buf);
+ }
+ if (!start && (arg_no == 2))
+ {
+ TexOutput("}");
+ }
+ if (!start && (arg_no == 3))
+ TexOutput(")", TRUE);
+ break;
+ }
+ case ltPARAM:
+ {
+ if (start && (arg_no == 2))
+ {
+ long id = NewBlockId();
+ sprintf(buf, " \\hy-%d{%ld}{", hyBLOCK_BOLD, id);
+ TexOutput(buf);
+ }
+ if (!start && (arg_no == 2))
+ {
+ TexOutput("}");
+ }
+ break;
+ }
+ case ltCPARAM:
+ {
+ if (start && (arg_no == 2))
+ {
+ long id = NewBlockId();
+ sprintf(buf, " \\hy-%d{%ld}{", hyBLOCK_BOLD, id);
+ TexOutput(buf);
+ }
+ if (!start && (arg_no == 2))
+ {
+ TexOutput("}");
+ }
+ break;
+ }
+ case ltMEMBER:
+ {
+ if (!start && (arg_no == 1))
+ TexOutput(" ", TRUE);
+ break;
+ }
+ case ltLABEL:
+ {
+ return FALSE;
+ break;
+ }
+ case ltREF:
+ {
+ if (start)
+ {
+ char *sec = NULL;
+
+ char *refName = GetArgData();
+ if (refName)
+ {
+ TexRef *texRef = FindReference(refName);
+ if (texRef)
+ {
+ sec = texRef->sectionNumber;
+ }
+ }
+ if (sec)
+ {
+ TexOutput(sec);
+ }
+ return FALSE;
+ }
+ break;
+ }
+ case ltHELPREF:
+ case ltHELPREFN:
+ case ltPOPREF:
+ {
+ if (arg_no == 1)
+ {
+ if (start)
+ {
+ currentBlockId = NewBlockId();
+ sprintf(buf, "\\hy-%d{%ld}{", hyBLOCK_RED_ITALIC, currentBlockId);
+ TexOutput(buf);
+ }
+ else TexOutput("}");
+ }
+ if (arg_no == 2)
+ {
+ if (start)
+ {
+ char *label = GetArgData();
+ hyperLinks.Append(currentBlockId, (wxObject *)copystring(label));
+ }
+
+ return FALSE;
+ }
+ break;
+ }
+ case ltURLREF:
+ {
+ if (arg_no == 1)
+ {
+ return TRUE;
+ }
+ else if (arg_no == 2)
+ {
+ if (start)
+ TexOutput(" (");
+ else
+ TexOutput(")");
+ return TRUE;
+ }
+ break;
+ }
+ case ltITEM:
+ {
+ if (start && IsArgOptional())
+ {
+ descriptionItemArg = GetArgChunk();
+ return FALSE;
+ }
+ break;
+ }
+ case ltTABULAR:
+ case ltSUPERTABULAR:
+ {
+ if (arg_no == 1)
+ {
+ if (start)
+ {
+ inTable = TRUE;
+ tableVerticalLineLeft = FALSE;
+ tableVerticalLineRight = FALSE;
+
+ char *alignString = copystring(GetArgData());
+
+ // Count the number of columns
+ noColumns = 0;
+ int len = strlen(alignString);
+ if (len > 0)
+ {
+ if (alignString[0] == '|')
+ tableVerticalLineLeft = TRUE;
+ if (alignString[len-1] == '|')
+ tableVerticalLineRight = TRUE;
+ }
+
+ for (int i = 0; i < len; i++)
+ if (isalpha(alignString[i]))
+ noColumns ++;
+
+/*
+ // Experimental
+ TexOutput("\\brdrt\\brdrs");
+ if (tableVerticalLineLeft)
+ TexOutput("\\brdrl\\brdrs");
+ if (tableVerticalLineRight)
+ TexOutput("\\brdrr\\brdrs");
+*/
+
+ // Calculate a rough size for each column
+// int tabPos = 80/noColumns;
+ currentTab = 0;
+
+ return FALSE;
+ }
+ }
+ else if (arg_no == 2 && !start)
+ {
+ inTable = FALSE;
+ }
+ else if (arg_no == 2 && start)
+ return TRUE;
+ break;
+ }
+ case ltMARGINPAR:
+ case ltMARGINPAREVEN:
+ case ltMARGINPARODD:
+ case ltNORMALBOX:
+ case ltNORMALBOXD:
+ {
+ if (start)
+ {
+ TexOutput("----------------------------------------------------------------------\n", TRUE);
+ return TRUE;
+ }
+ else
+ TexOutput("\n----------------------------------------------------------------------\n", TRUE);
+ break;
+ }
+ case ltBIBITEM:
+ {
+ char buf[100];
+ if (arg_no == 1 && start)
+ {
+ char *citeKey = GetArgData();
+ TexRef *ref = (TexRef *)TexReferences.Get(citeKey);
+ if (ref)
+ {
+ if (ref->sectionNumber) delete[] ref->sectionNumber;
+ sprintf(buf, "[%d]", citeCount);
+ ref->sectionNumber = copystring(buf);
+ }
+
+ sprintf(buf, "\\hy-%d{%ld}{[%d]} ", hyBLOCK_BOLD, NewBlockId(), citeCount);
+ TexOutput(buf);
+ citeCount ++;
+ return FALSE;
+ }
+ return TRUE;
+ break;
+ }
+ case ltTHEBIBLIOGRAPHY:
+ {
+ if (start && (arg_no == 1))
+ {
+ citeCount = 1;
+
+ SetCurrentOutput(Chapters);
+
+ SetCurrentOutputs(Contents, Chapters);
+ long id1 = NewBlockId();
+ long id2 = NewBlockId();
+ fprintf(Contents, "\\hy-%d{%ld}{%s}\n", hyBLOCK_SMALL_HEADING, id1, ReferencesNameString);
+ fprintf(Chapters, "\\hy-%d{%ld}{%s}\n\n\n", hyBLOCK_LARGE_VISIBLE_SECTION, id2, ReferencesNameString);
+ fprintf(Index, "%ld %ld\n", id1, id2);
+
+ SetCurrentOutput(Chapters);
+ return FALSE;
+ }
+ if (!start && (arg_no == 2))
+ {
+ }
+ return TRUE;
+ break;
+ }
+ case ltTWOCOLITEM:
+ case ltTWOCOLITEMRULED:
+ {
+ if (start && (arg_no == 2))
+ TexOutput("\n ");
+
+ if (!start && (arg_no == 2))
+ TexOutput("\n");
+ return TRUE;
+ }
+ /*
+ * Accents
+ *
+ */
+ case ltACCENT_GRAVE:
+ {
+ if (start)
+ {
+ char *val = GetArgData();
+ if (val)
+ {
+ switch (val[0])
+ {
+ case 'a':
+ TexOutput("a");
+ break;
+ case 'e':
+ TexOutput("e");
+ break;
+ case 'i':
+ TexOutput("i");
+ break;
+ case 'o':
+ TexOutput("o");
+ break;
+ case 'u':
+ TexOutput("u");
+ break;
+ case 'A':
+ TexOutput("a");
+ break;
+ case 'E':
+ TexOutput("E");
+ break;
+ case 'I':
+ TexOutput("I");
+ break;
+ case 'O':
+ TexOutput("O");
+ break;
+ case 'U':
+ TexOutput("U");
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ return FALSE;
+ break;
+ }
+ case ltACCENT_ACUTE:
+ {
+ if (start)
+ {
+ char *val = GetArgData();
+ if (val)
+ {
+ switch (val[0])
+ {
+ case 'a':
+ TexOutput("a");
+ break;
+ case 'e':
+ TexOutput("e");
+ break;
+ case 'i':
+ TexOutput("i");
+ break;
+ case 'o':
+ TexOutput("o");
+ break;
+ case 'u':
+ TexOutput("u");
+ break;
+ case 'y':
+ TexOutput("y");
+ break;
+ case 'A':
+ TexOutput("A");
+ break;
+ case 'E':
+ TexOutput("E");
+ break;
+ case 'I':
+ TexOutput("I");
+ break;
+ case 'O':
+ TexOutput("O");
+ break;
+ case 'U':
+ TexOutput("U");
+ break;
+ case 'Y':
+ TexOutput("Y");
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ return FALSE;
+ break;
+ }
+ case ltACCENT_CARET:
+ {
+ if (start)
+ {
+ char *val = GetArgData();
+ if (val)
+ {
+ switch (val[0])
+ {
+ case 'a':
+ TexOutput("a");
+ break;
+ case 'e':
+ TexOutput("e");
+ break;
+ case 'i':
+ TexOutput("i");
+ break;
+ case 'o':
+ TexOutput("o");
+ break;
+ case 'u':
+ TexOutput("u");
+ break;
+ case 'A':
+ TexOutput("A");
+ break;
+ case 'E':
+ TexOutput("E");
+ break;
+ case 'I':
+ TexOutput("I");
+ break;
+ case 'O':
+ TexOutput("O");
+ break;
+ case 'U':
+ TexOutput("U");
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ return FALSE;
+ break;
+ }
+ case ltACCENT_TILDE:
+ {
+ if (start)
+ {
+ char *val = GetArgData();
+ if (val)
+ {
+ switch (val[0])
+ {
+ case 'a':
+ TexOutput("a");
+ break;
+ case ' ':
+ TexOutput("~");
+ break;
+ case 'n':
+ TexOutput("n");
+ break;
+ case 'o':
+ TexOutput("o");
+ break;
+ case 'A':
+ TexOutput("A");
+ break;
+ case 'N':
+ TexOutput("N");
+ break;
+ case 'O':
+ TexOutput("O");
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ return FALSE;
+ break;
+ }
+ case ltACCENT_UMLAUT:
+ {
+ if (start)
+ {
+ char *val = GetArgData();
+ if (val)
+ {
+ switch (val[0])
+ {
+ case 'a':
+ TexOutput("a");
+ break;
+ case 'e':
+ TexOutput("e");
+ break;
+ case 'i':
+ TexOutput("i");
+ break;
+ case 'o':
+ TexOutput("o");
+ break;
+ case 'u':
+ TexOutput("u");
+ break;
+ case 'y':
+ TexOutput("y");
+ break;
+ case 'A':
+ TexOutput("A");
+ break;
+ case 'E':
+ TexOutput("E");
+ break;
+ case 'I':
+ TexOutput("I");
+ break;
+ case 'O':
+ TexOutput("O");
+ break;
+ case 'U':
+ TexOutput("U");
+ break;
+ case 'Y':
+ TexOutput("Y");
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ return FALSE;
+ break;
+ }
+ case ltACCENT_DOT:
+ {
+ if (start)
+ {
+ char *val = GetArgData();
+ if (val)
+ {
+ switch (val[0])
+ {
+ case 'a':
+ TexOutput("a");
+ break;
+ case 'A':
+ TexOutput("A");
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ return FALSE;
+ break;
+ }
+ case ltACCENT_CADILLA:
+ {
+ if (start)
+ {
+ char *val = GetArgData();
+ if (val)
+ {
+ switch (val[0])
+ {
+ case 'c':
+ TexOutput("c");
+ break;
+ case 'C':
+ TexOutput("C");
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ return FALSE;
+ break;
+ }
+ default:
+ {
+ return DefaultOnArgument(macroId, arg_no, start);
+ break;
+ }
+ }
+ return TRUE;
+}
+
+bool XLPGo(void)
+{
+ xlpBlockId = 0;
+
+ if (InputFile && OutputFile)
+ {
+ Contents = fopen(TmpContentsName, "w");
+ Chapters = fopen("chapters.xlp", "w");
+ Sections = fopen("sections.xlp", "w");
+ Subsections = fopen("subsections.xlp", "w");
+ Subsubsections = fopen("subsubsections.xlp", "w");
+ Index = fopen("index.xlp", "w");
+
+ // Insert invisible section marker at beginning
+ fprintf(Chapters, "\\hy-%d{%ld}{%s}\n",
+ hyBLOCK_INVISIBLE_SECTION, NewBlockId(), "\n");
+
+ fprintf(Contents, "\\hy-%d{%ld}{%s}\n\n",
+// hyBLOCK_LARGE_HEADING, NewBlockId(), "\n\n%s\n\n", ContentsNameString);
+ hyBLOCK_LARGE_HEADING, NewBlockId(), ContentsNameString);
+
+ SetCurrentOutput(Chapters);
+
+ fprintf(Index, "\n\\hyindex{\n\"%s\"\n",
+ contentsString ? contentsString : "WXHELPCONTENTS");
+ TraverseDocument();
+
+ wxNode *node = hyperLinks.First();
+ while (node)
+ {
+ long from = node->GetKeyInteger();
+ char *label = (char *)node->Data();
+ wxNode *otherNode = hyperLabels.Find(label);
+ if (otherNode)
+ {
+ long to = (long)otherNode->Data();
+ fprintf(Index, "%ld %ld\n", from, to);
+ }
+ node = node->Next();
+ }
+
+ fprintf(Index, "}\n");
+
+ fclose(Contents); Contents = NULL;
+ fclose(Chapters); Chapters = NULL;
+ fclose(Sections); Sections = NULL;
+ fclose(Subsections); Subsections = NULL;
+ fclose(Subsubsections); Subsubsections = NULL;
+ fclose(Index); Index = NULL;
+
+ if (FileExists(ContentsName)) wxRemoveFile(ContentsName);
+
+ if (!wxRenameFile(TmpContentsName, ContentsName))
+ {
+ wxCopyFile(TmpContentsName, ContentsName);
+ wxRemoveFile(TmpContentsName);
+ }
+
+ wxConcatFiles("chapters.xlp", "sections.xlp", "tmp2.xlp");
+ wxConcatFiles("tmp2.xlp", "subsections.xlp", "tmp1.xlp");
+ wxConcatFiles("tmp1.xlp", "subsubsections.xlp", "tmp2.xlp");
+ wxConcatFiles("tmp2.xlp", "index.xlp", OutputFile);
+
+ wxRemoveFile("tmp1.xlp");
+ wxRemoveFile("tmp2.xlp");
+
+ wxRemoveFile("chapters.xlp");
+ wxRemoveFile("sections.xlp");
+ wxRemoveFile("subsections.xlp");
+ wxRemoveFile("subsubsections.xlp");
+ wxRemoveFile("index.xlp");
+ return TRUE;
+ }
+ return FALSE;
+}
+