diff --git a/distrib/msw/generic.rsp b/distrib/msw/generic.rsp index 37a5f1f542..4be8358cfd 100644 --- a/distrib/msw/generic.rsp +++ b/distrib/msw/generic.rsp @@ -98,25 +98,6 @@ utils/wxhelp/src/*.ico 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* diff --git a/distrib/msw/zipdist.bat b/distrib/msw/zipdist.bat index d8c4e4deda..f6d91e089b 100755 --- a/distrib/msw/zipdist.bat +++ b/distrib/msw/zipdist.bat @@ -35,6 +35,9 @@ zip32 -@ %dest\wx200cw.zip < %src\distrib\msw\cw.rsp 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. diff --git a/docs/latex/wx/window.tex b/docs/latex/wx/window.tex index b5ef3bc1e0..de69d259e3 100644 --- a/docs/latex/wx/window.tex +++ b/docs/latex/wx/window.tex @@ -20,7 +20,7 @@ window class. 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.} diff --git a/samples/bombs/makefile.unx b/samples/bombs/makefile.unx index 118dabbfd4..340c83b517 100644 --- a/samples/bombs/makefile.unx +++ b/samples/bombs/makefile.unx @@ -13,5 +13,5 @@ PROGRAM=bombs OBJECTS = bombs.o bombs1.o game.o -include ../../src/makeprog.env +include ../../../src/makeprog.env diff --git a/src/common/memory.cpp b/src/common/memory.cpp index 55a2a2b341..046c703af2 100644 --- a/src/common/memory.cpp +++ b/src/common/memory.cpp @@ -909,7 +909,7 @@ int wxDebugContext::CountObjectsLeft(bool sinceCheckpoint) 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) diff --git a/utils/tex2rtf/docs/back.gif b/utils/tex2rtf/docs/back.gif new file mode 100644 index 0000000000..8a61076d3b Binary files /dev/null and b/utils/tex2rtf/docs/back.gif differ diff --git a/utils/tex2rtf/docs/books.gif b/utils/tex2rtf/docs/books.gif new file mode 100644 index 0000000000..26ff394df6 Binary files /dev/null and b/utils/tex2rtf/docs/books.gif differ diff --git a/utils/tex2rtf/docs/bullet.bmp b/utils/tex2rtf/docs/bullet.bmp new file mode 100644 index 0000000000..aad8fc793e Binary files /dev/null and b/utils/tex2rtf/docs/bullet.bmp differ diff --git a/utils/tex2rtf/docs/contents.gif b/utils/tex2rtf/docs/contents.gif new file mode 100644 index 0000000000..3dddfa3dd5 Binary files /dev/null and b/utils/tex2rtf/docs/contents.gif differ diff --git a/utils/tex2rtf/docs/fancyhea.sty b/utils/tex2rtf/docs/fancyhea.sty new file mode 100644 index 0000000000..83914fa63c --- /dev/null +++ b/utils/tex2rtf/docs/fancyhea.sty @@ -0,0 +1,145 @@ +% 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} + diff --git a/utils/tex2rtf/docs/forward.gif b/utils/tex2rtf/docs/forward.gif new file mode 100644 index 0000000000..9c81e8c92f Binary files /dev/null and b/utils/tex2rtf/docs/forward.gif differ diff --git a/utils/tex2rtf/docs/install.txt b/utils/tex2rtf/docs/install.txt new file mode 100644 index 0000000000..6224eec7ec --- /dev/null +++ b/utils/tex2rtf/docs/install.txt @@ -0,0 +1,43 @@ +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 diff --git a/utils/tex2rtf/docs/makeidx.sty b/utils/tex2rtf/docs/makeidx.sty new file mode 100644 index 0000000000..4fbb9aed3a --- /dev/null +++ b/utils/tex2rtf/docs/makeidx.sty @@ -0,0 +1,11 @@ +% 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}} + diff --git a/utils/tex2rtf/docs/mysober.sty b/utils/tex2rtf/docs/mysober.sty new file mode 100644 index 0000000000..a6f73a654d --- /dev/null +++ b/utils/tex2rtf/docs/mysober.sty @@ -0,0 +1,154 @@ +% 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 : ()() +% +% 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} + + diff --git a/utils/tex2rtf/docs/mytitle.sty b/utils/tex2rtf/docs/mytitle.sty new file mode 100644 index 0000000000..4a20d7b2c8 --- /dev/null +++ b/utils/tex2rtf/docs/mytitle.sty @@ -0,0 +1,33 @@ +% 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} diff --git a/utils/tex2rtf/docs/notes.txt b/utils/tex2rtf/docs/notes.txt new file mode 100644 index 0000000000..6e830c5baa --- /dev/null +++ b/utils/tex2rtf/docs/notes.txt @@ -0,0 +1,140 @@ +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). diff --git a/utils/tex2rtf/docs/psbox.tex b/utils/tex2rtf/docs/psbox.tex new file mode 100644 index 0000000000..b7438f4f29 --- /dev/null +++ b/utils/tex2rtf/docs/psbox.tex @@ -0,0 +1,520 @@ +% +% %%%%%%% %%%%% %%%%%% %%%%% % % +% % % % % % % % % % +% % % % % % % % % % +% %%%%%%% %%%%% %%%%%% % % % +% % % % % % % % % +% % % % % % % % % +% % %%%%%% %%%%%% %%%%% % % +% +% 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). diff --git a/utils/tex2rtf/docs/readme.txt b/utils/tex2rtf/docs/readme.txt new file mode 100644 index 0000000000..6709d2eafc --- /dev/null +++ b/utils/tex2rtf/docs/readme.txt @@ -0,0 +1,81 @@ + ++++++ 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 + + + diff --git a/utils/tex2rtf/docs/refs.bib b/utils/tex2rtf/docs/refs.bib new file mode 100644 index 0000000000..0d145e5a8f --- /dev/null +++ b/utils/tex2rtf/docs/refs.bib @@ -0,0 +1,35 @@ +@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} +} + diff --git a/utils/tex2rtf/docs/screen.bmp b/utils/tex2rtf/docs/screen.bmp new file mode 100644 index 0000000000..5dacb0924a Binary files /dev/null and b/utils/tex2rtf/docs/screen.bmp differ diff --git a/utils/tex2rtf/docs/screen.gif b/utils/tex2rtf/docs/screen.gif new file mode 100644 index 0000000000..be8d929bb0 Binary files /dev/null and b/utils/tex2rtf/docs/screen.gif differ diff --git a/utils/tex2rtf/docs/screen.shg b/utils/tex2rtf/docs/screen.shg new file mode 100644 index 0000000000..5ec685cf9d Binary files /dev/null and b/utils/tex2rtf/docs/screen.shg differ diff --git a/utils/tex2rtf/docs/tex2rtf.hpj b/utils/tex2rtf/docs/tex2rtf.hpj new file mode 100644 index 0000000000..1cd112a064 --- /dev/null +++ b/utils/tex2rtf/docs/tex2rtf.hpj @@ -0,0 +1,17 @@ +[OPTIONS] +BMROOT=. +TITLE=Tex2RTF Manual +CONTENTS=Contents +COMPRESS=HIGH + +[FILES] +tex2rtf.rtf + +[CONFIG] +CreateButton("Up", "&Up", "JumpId(`tex2rtf.hlp', `Contents')") +BrowseButtons() + +[MAP] + +[BITMAPS] + diff --git a/utils/tex2rtf/docs/tex2rtf.ini b/utils/tex2rtf/docs/tex2rtf.ini new file mode 100644 index 0000000000..fae52d1baf --- /dev/null +++ b/utils/tex2rtf/docs/tex2rtf.ini @@ -0,0 +1,21 @@ +; 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 diff --git a/utils/tex2rtf/docs/tex2rtf.tex b/utils/tex2rtf/docs/tex2rtf.tex new file mode 100644 index 0000000000..014c3e2648 --- /dev/null +++ b/utils/tex2rtf/docs/tex2rtf.tex @@ -0,0 +1,3299 @@ +\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 +\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} + +

+\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} diff --git a/utils/tex2rtf/docs/tex2rtf.wmf b/utils/tex2rtf/docs/tex2rtf.wmf new file mode 100644 index 0000000000..2a17268454 Binary files /dev/null and b/utils/tex2rtf/docs/tex2rtf.wmf differ diff --git a/utils/tex2rtf/docs/texhelp.sty b/utils/tex2rtf/docs/texhelp.sty new file mode 100644 index 0000000000..df04b586d7 --- /dev/null +++ b/utils/tex2rtf/docs/texhelp.sty @@ -0,0 +1,282 @@ +% 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}.} diff --git a/utils/tex2rtf/docs/up.gif b/utils/tex2rtf/docs/up.gif new file mode 100644 index 0000000000..316d0d2a14 Binary files /dev/null and b/utils/tex2rtf/docs/up.gif differ diff --git a/utils/tex2rtf/docs/verbatim.sty b/utils/tex2rtf/docs/verbatim.sty new file mode 100644 index 0000000000..462c3299b0 --- /dev/null +++ b/utils/tex2rtf/docs/verbatim.sty @@ -0,0 +1,212 @@ +%% +%% 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: +%% +\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'. diff --git a/utils/tex2rtf/src/bmputils.h b/utils/tex2rtf/src/bmputils.h new file mode 100644 index 0000000000..0f8b07a453 --- /dev/null +++ b/utils/tex2rtf/src/bmputils.h @@ -0,0 +1,227 @@ +///////////////////////////////////////////////////////////////////////////// +// 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 + diff --git a/utils/tex2rtf/src/books.bmp b/utils/tex2rtf/src/books.bmp new file mode 100644 index 0000000000..cf1e148734 Binary files /dev/null and b/utils/tex2rtf/src/books.bmp differ diff --git a/utils/tex2rtf/src/dos.def b/utils/tex2rtf/src/dos.def new file mode 100644 index 0000000000..00b503b084 --- /dev/null +++ b/utils/tex2rtf/src/dos.def @@ -0,0 +1,10 @@ +NAME TEX2RTF +DESCRIPTION 'Tex2Rtf' +; +EXETYPE DOS +; +CODE PRELOAD MOVEABLE DISCARDABLE +DATA PRELOAD MOVEABLE MULTIPLE +; +HEAPSIZE 1024 +STACKSIZE 8192 diff --git a/utils/tex2rtf/src/htmlutil.cpp b/utils/tex2rtf/src/htmlutil.cpp new file mode 100644 index 0000000000..a67bc10be4 --- /dev/null +++ b/utils/tex2rtf/src/htmlutil.cpp @@ -0,0 +1,2982 @@ +///////////////////////////////////////////////////////////////////////////// +// 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\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, "\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 ->

. + * + */ + +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, "

\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 = "\"Contents\""; + contentsReference = contentsReferenceBuf; + sprintf(contentsReference, "\"Contents\"", ConvertCase("contents.gif")); + } + + char *upReference = NULL; + if (htmlBrowseButtons == HTML_BUTTONS_TEXT) + upReference = UpNameString; + else + { +// upReference = "\"Up\""; + upReference = upReferenceBuf; + sprintf(upReference, "\"Up\"", ConvertCase("up.gif")); + } + + char *backReference = NULL; + if (htmlBrowseButtons == HTML_BUTTONS_TEXT) + backReference = "<<"; + else + { +// backReference = "\"Previous\""; + backReference = backReferenceBuf; + sprintf(backReference, "\"Previous\"", ConvertCase("back.gif")); + } + + char *forwardReference = NULL; + if (htmlBrowseButtons == HTML_BUTTONS_TEXT) + forwardReference = ">>"; + else + { +// forwardReference = "\"Next\""; + forwardReference = forwardReferenceBuf; + sprintf(forwardReference, "\"Next\"", ConvertCase("forward.gif")); + } + + TexOutput("

"); + + char buf[200]; + + /* + * Contents button + * + */ + + if (truncateFilenames) + { + char buf1[80]; + strcpy(buf1, ConvertCase(FileNameFromPath(FileRoot))); + sprintf(buf, "\n%s ", buf1, ConvertCase("htm"), contentsReference); + } + else + { + char buf1[80]; + strcpy(buf1, ConvertCase(FileNameFromPath(FileRoot))); + sprintf(buf, "\n%s ", buf1, ConvertCase("_contents.html"), contentsReference); + } +// TexOutput(""); + TexOutput(buf); +// TexOutput(""); + + /* + * Up button + * + */ + + if (upLabel && upFilename) + { + if (strlen(upLabel) > 0) + sprintf(buf, "%s ", ConvertCase(upFilename), upLabel, upReference); + else + sprintf(buf, "%s ", ConvertCase(upFilename), upReference); + if (strcmp(upLabel, "contents") == 0) + { +// TexOutput(""); + TexOutput(buf); +// TexOutput(""); + } + else + TexOutput(buf); + } + + /* + * << button + * + */ + + if (previousLabel && previousFilename) + { + sprintf(buf, "%s ", ConvertCase(previousFilename), previousLabel, backReference); + if (strcmp(previousLabel, "contents") == 0) + { +// TexOutput(""); + TexOutput(buf); +// TexOutput(""); + } + 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, "%s ", 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("
"); + TexOutput("
\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 block +void OutputBodyStart(void) +{ + TexOutput("\n\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(""); + OutputCurrentSection(); // Repeat section header + TexOutput("\n"); + OutputBodyStart(); + + char titleBuf[200]; + if (truncateFilenames) + sprintf(titleBuf, "%s.htm", FileNameFromPath(FileRoot)); + else + sprintf(titleBuf, "%s_contents.html", FileNameFromPath(FileRoot)); + + fprintf(Chapters, "", topicName); + + AddBrowseButtons("", titleBuf, // Up + lastTopic, lastFileName, // Last topic + topicName, ChaptersName); // This topic + + fprintf(Contents, "\n
  • ", ConvertCase(ChaptersName), topicName); + + if (htmlFrameContents && FrameContents) + { + SetCurrentOutput(FrameContents); + fprintf(FrameContents, "\n
  • ", ConvertCase(ChaptersName), topicName); + OutputCurrentSection(); + fprintf(FrameContents, "\n"); + } + + SetCurrentOutputs(Contents, Chapters); + fprintf(Chapters, "\n

    "); + OutputCurrentSection(); + fprintf(Contents, "\n"); + fprintf(Chapters, "

    \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(""); + OutputCurrentSection(); + TexOutput("\n"); + OutputBodyStart(); + + fprintf(Sections, "", 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
  • ", ConvertCase(SectionsName), topicName); + else + fprintf(jumpFrom, "\n", ConvertCase(SectionsName), topicName); + + fprintf(Sections, "\n

    "); + OutputCurrentSection(); + + if (DocumentStyle == LATEX_ARTICLE) + fprintf(jumpFrom, "\n"); + else + fprintf(jumpFrom, "
    \n"); + fprintf(Sections, "

    \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, "

    \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(""); + OutputCurrentSection(); + TexOutput("\n"); + OutputBodyStart(); + + fprintf(Subsections, "", topicName); + AddBrowseButtons(CurrentSectionName, CurrentSectionFile, // Up + lastTopic, lastFileName, // Last topic + topicName, SubsectionsName); // This topic + + SetCurrentOutputs(Sections, Subsections); + fprintf(Sections, "\n", ConvertCase(SubsectionsName), topicName); + + fprintf(Subsections, "\n

    "); + OutputCurrentSection(); + fprintf(Sections, "
    \n"); + fprintf(Subsections, "

    \n"); + + SetCurrentOutput(Subsections); + } + else + { + AddTexRef(topicName, SectionsName, SubsectionNameString); + SetCurrentSubsectionName(topicName, SectionsName); +// if ( subsectionNo != 0 ) + fprintf(Sections, "\n
    \n"); + + // We're putting everything into the section file + fprintf(Sections, "", topicName); + fprintf(Sections, "\n

    "); + OutputCurrentSection(); + fprintf(Sections, "

    \n"); + + SetCurrentOutput(SectionContentsFD); + fprintf(SectionContentsFD, "", topicName); + OutputCurrentSection(); + TexOutput("
    \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(""); + OutputCurrentSection(); + TexOutput("\n"); + OutputBodyStart(); + + fprintf(Subsubsections, "", topicName); + + AddBrowseButtons(CurrentSubsectionName, CurrentSubsectionFile, // Up + lastTopic, lastFileName, // Last topic + topicName, SubsubsectionsName); // This topic + + SetCurrentOutputs(Subsections, Subsubsections); + fprintf(Subsections, "\n", ConvertCase(SubsubsectionsName), topicName); + + fprintf(Subsubsections, "\n

    "); + OutputCurrentSection(); + fprintf(Subsections, "
    \n"); + fprintf(Subsubsections, "

    \n"); + } + else + { + AddTexRef(topicName, SectionsName, SubsubsectionNameString); + SetCurrentSubsectionName(topicName, SectionsName); + fprintf(Sections, "\n
    \n"); + + // We're putting everything into the section file + fprintf(Sections, "", topicName); + fprintf(Sections, "\n

    "); + OutputCurrentSection(); + fprintf(Sections, "

    \n"); +/* TODO: where do we put subsubsection contents entry - indented, with subsection entries? + SetCurrentOutput(SectionContentsFD); + fprintf(SectionContentsFD, "", topicName); + OutputCurrentSection(); + TexOutput("
    "); +*/ + 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("void"); + 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(""); + + // 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"); + else if (TableData[currentColumn].justification == 'r') + sprintf(buf, "\n"); + 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, "", pixels); + } + else + sprintf(buf, "\n"); + 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 + // if we've ended the last row?). So normally you wouldn't use \\ to end a row. + TexOutput("\n"); + } + else + TexOutput("
    \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, "\n"); + else if (TableData[currentColumn].justification == 'r') + sprintf(buf, "\n"); + 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, "\n", pixels); + } + else + sprintf(buf, "\n"); + TexOutput(buf); + } + else + { + // End cell and row + // Start new row and cell + TexOutput("\n\n"); + } + break; + } + // HTML-only: break until the end of the picture (both margins are clear). + case ltBRCLEAR: + { + if (start) + TexOutput("
    "); + break; + } + case ltRTFSP: // Explicit space, RTF only + break; + case ltSPECIALTILDE: + { + if (start) + { + if (inVerbatim) + TexOutput("~"); + else + TexOutput(" "); + } + break; + } + case ltINDENTED : + { + if ( start ) + TexOutput("
        \n"); + else + TexOutput("
    \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("
      \n"); + break; + case LATEX_ENUMERATE: + TexOutput("
        \n"); + break; + case LATEX_DESCRIPTION: + default: + TexOutput("
        \n"); + break; + } + } + else + { + indentLevel --; + if (itemizeStack.First()) + { + ItemizeStruc *struc = (ItemizeStruc *)itemizeStack.First()->Data(); + switch (struc->listType) + { + case LATEX_ITEMIZE: + TexOutput("
    \n"); + break; + case LATEX_ENUMERATE: + TexOutput("\n"); + break; + case LATEX_DESCRIPTION: + default: + TexOutput("\n"); + break; + } + + delete struc; + delete itemizeStack.First(); + } + } + break; + } + case ltTWOCOLLIST : + { + if ( start ) + TexOutput("\n\n"); + else + TexOutput("\n
    \n"); + break; + } + case ltPAR: + { + if (start) + TexOutput("

    \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("); + } + else TexOutput(""); + break; + } +*/ + case ltVERB: + { + if (start) + TexOutput(""); + else TexOutput(""); + break; + } + case ltVERBATIM: + { + if (start) + { + char buf[100]; + sprintf(buf, "

    \n");
    +      TexOutput(buf);
    +    }
    +    else TexOutput("
    \n"); + break; + } + case ltCENTERLINE: + case ltCENTER: + { + if (start) + { + TexOutput("
    "); + } + else TexOutput("
    "); + 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(""); + } + else TexOutput(""); + break; + } + case ltTINY: + { + if (start) + { + // Netscape extension + TexOutput(""); + } + else TexOutput(""); + break; + } + case ltNORMALSIZE: + { + if (start) + { + // Netscape extension + TexOutput(""); + } + else TexOutput(""); + break; + } + case ltlarge: + { + if (start) + { + // Netscape extension + TexOutput(""); + } + else TexOutput(""); + break; + } + case ltLarge: + { + if (start) + { + // Netscape extension + TexOutput(""); + } + else TexOutput(""); + break; + } + case ltLARGE: + { + if (start) + { + // Netscape extension + TexOutput(""); + } + else TexOutput(""); + break; + } + case ltBFSERIES: + case ltTEXTBF: + case ltBF: + { + if (start) + { + TexOutput(""); + } + else TexOutput(""); + break; + } + case ltITSHAPE: + case ltTEXTIT: + case ltIT: + { + if (start) + { + TexOutput(""); + } + else TexOutput(""); + break; + } + case ltEMPH: + case ltEM: + { + if (start) + { + TexOutput(""); + } + else TexOutput(""); + break; + } + case ltUNDERLINE: + { + if (start) + { + TexOutput("
      "); + } + else TexOutput("
    "); + break; + } + case ltTTFAMILY: + case ltTEXTTT: + case ltTT: + { + if (start) + { + TexOutput(""); + } + else TexOutput(""); + 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("
    "); + TraverseChildrenFromChunk(descriptionItemArg); + TexOutput("\n"); + descriptionItemArg = NULL; + } + TexOutput("
    "); + } + else + TexOutput("
  • "); + } + } + break; + } + case ltMAKETITLE: + { + if (start && DocumentTitle && DocumentAuthor) + { + // Add a special label for the contents page. +// TexOutput("
    \n"); + TexOutput(""); + TexOutput("

    \n"); + TraverseChildrenFromChunk(DocumentTitle); + TexOutput("

    "); + TexOutput("

    "); + TexOutput("\n"); + TexOutput("

    \n\n"); + TexOutput("

    "); + TraverseChildrenFromChunk(DocumentAuthor); + TexOutput("

    \n\n"); + if (DocumentDate) + { + TexOutput("

    "); + TraverseChildrenFromChunk(DocumentDate); + TexOutput("

    \n\n"); + } +// TexOutput("\n

    \n"); + TexOutput("\n


    \n"); + +/* + // Now do optional frame contents page + if (htmlFrameContents && FrameContents) + { + SetCurrentOutput(FrameContents); + + // Add a special label for the contents page. + TexOutput("

    \n"); + TexOutput("

    \n"); + TraverseChildrenFromChunk(DocumentTitle); + TexOutput("

    "); + TexOutput("

    "); + TexOutput("\n"); + TexOutput("

    \n\n"); + TexOutput("

    "); + TraverseChildrenFromChunk(DocumentAuthor); + TexOutput("

    \n\n"); + if (DocumentDate) + { + TexOutput("

    "); + TraverseChildrenFromChunk(DocumentDate); + TexOutput("

    \n\n"); + } + TexOutput("\n

    \n"); + TexOutput("


    \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("\n"); + } + break; + } + case ltHRULE: + { + if (start) + { + TexOutput("


    \n"); + } + break; + } + case ltRULE: + { + if (start) + { + TexOutput("
    \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("
    "); + else + TexOutput("
    "); + break; + } + case ltCAPTION: + case ltCAPTIONSTAR: + { + if (start) + { + if (inTabular) + TexOutput("\n"); + + 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\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(""); + + if (!start && (arg_no == 1)) + TexOutput(" "); + + if (start && (arg_no == 2)) + { + if (!suppressNameDecoration) TexOutput(""); + currentMember = GetArgChunk(); + } + if (!start && (arg_no == 2)) + { + if (!suppressNameDecoration) TexOutput(""); + } + + if (start && (arg_no == 3)) + TexOutput("("); + if (!start && (arg_no == 3)) + TexOutput(")"); + break; + } + case ltCLIPSFUNC: + { + if (start && (arg_no == 1)) + TexOutput(""); + if (!start && (arg_no == 1)) + TexOutput(" "); + + 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(""); + if (!start && (arg_no == 1)) + TexOutput(""); + if (start && (arg_no == 2)) + { + TexOutput(""); + } + if (!start && (arg_no == 2)) + { + TexOutput(""); + } + break; + } + case ltCPARAM: + { + if (start && (arg_no == 1)) + TexOutput(""); + if (!start && (arg_no == 1)) + TexOutput(" "); // This is the difference from param - one space! + if (start && (arg_no == 2)) + { + TexOutput(""); + } + 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 *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(""); + if (helpRefText) + TraverseChildrenFromChunk(helpRefText); + TexOutput(""); + } + 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(""); + if (helpRefText) + TraverseChildrenFromChunk(helpRefText); + TexOutput(""); + } + 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(""); + TexOutput(""); + } + else +#endif + { + TexOutput(""); + delete[] inlineFilename; + } + } + else + { + // Last resort - a link to a PS file. + TexOutput("Picture\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(""); + TexOutput("

    "); + 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

    "); + if (start && (arg_no == 2)) + TexOutput("
    "); +*/ + if (arg_no == 1) + { + if ( start ) + TexOutput("\n\n"); + else + TexOutput("\n\n"); + } + if (arg_no == 2) + { + if ( start ) + TexOutput("\n\n"); + else + TexOutput("\n\n"); + } + return TRUE; + break; + } + case ltNUMBEREDBIBITEM: + { + if (arg_no == 1 && start) + { + TexOutput("\n
    "); + } + if (arg_no == 2 && !start) + TexOutput("

    \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

    [%d] ", citeCount); + TexOutput(buf); + citeCount ++; + return FALSE; + } + if (arg_no == 2 && !start) + TexOutput("

    \n"); + return TRUE; + break; + } + case ltMARGINPAR: + case ltMARGINPARODD: + case ltMARGINPAREVEN: + case ltNORMALBOX: + case ltNORMALBOXD: + { + if (start) + { + TexOutput("


    \n"); + return TRUE; + } + else + TexOutput("

    \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("\n"); + + // Write the first row formatting for compatibility + // with standard Latex + if (compatibilityMode) + { + TexOutput("\n
    "); +/* + 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("
    \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(""); + TexOutput(ReferencesNameString); + TexOutput("\n"); + OutputBodyStart(); + + fprintf(Chapters, "\n

    %s", "bibliography", ReferencesNameString); + AddBrowseButtons("contents", titleBuf, // Up + lastTopic, lastFileName, // Last topic + "bibliography", ChaptersName); // This topic + + SetCurrentOutputs(Contents, Chapters); + fprintf(Contents, "\n
  • ", ConvertCase(ChaptersName), "bibliography"); + + fprintf(Contents, "%s\n", ReferencesNameString); + fprintf(Chapters, "
  • \n\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(""); + break; + } + case 2: + { + return TRUE; + break; + } + default: + break; + } + } + else + { + if (arg_no == 2) TexOutput(""); + } + 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, "\n
      \n"); + } + + if (!Titlepage || !Contents) + { + OnError("Cannot open output file!"); + return FALSE; + } + AddTexRef("contents", FileNameFromPath(TitlepageName), ContentsNameString); + + fprintf(Contents, "

      %s

      \n", ContentsNameString); + + fprintf(Contents, "

        \n"); + + SetCurrentOutput(Titlepage); + OnInform("Converting..."); + + TraverseDocument(); + fprintf(Contents, "
      \n\n"); + +// SetCurrentOutput(Titlepage); + fclose(Titlepage); + + if (Contents) + { +// fprintf(Titlepage, "\n\n"); + fclose(Contents); + Contents = NULL; + } + + if (FrameContents) + { + fprintf(FrameContents, "\n
    \n"); + fprintf(FrameContents, "\n"); + fclose(FrameContents); + FrameContents = NULL; + } + + if (Chapters) + { + fprintf(Chapters, "\n\n"); + fclose(Chapters); + Chapters = NULL; + } + if (Sections) + { + fprintf(Sections, "\n\n"); + fclose(Sections); + Sections = NULL; + } + if (Subsections && !combineSubSections) + { + fprintf(Subsections, "\n\n"); + fclose(Subsections); + Subsections = NULL; + } + if (Subsubsections && !combineSubSections) + { + fprintf(Subsubsections, "\n\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 , 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\n"); + TraverseChildrenFromChunk(DocumentTitle); + TexOutput("\n"); + } + else + { + SetCurrentOutput(tmpTitle); + if (contentsString) + fprintf(tmpTitle, "%s\n\n", contentsString); + else + fprintf(tmpTitle, "%s\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, "\n"); + + fprintf(tmpTitle, "\n", ConvertCase(FileNameFromPath(contentsFrameName))); + fprintf(tmpTitle, "\n", ConvertCase(FileNameFromPath(firstFileName))); + fprintf(tmpTitle, "\n"); + + fprintf(tmpTitle, "\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\n"); + } + fprintf(tmpTitle, "\n\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); +} diff --git a/utils/tex2rtf/src/makefile.b32 b/utils/tex2rtf/src/makefile.b32 new file mode 100644 index 0000000000..e22b1345f3 --- /dev/null +++ b/utils/tex2rtf/src/makefile.b32 @@ -0,0 +1,62 @@ +# +# 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 + diff --git a/utils/tex2rtf/src/makefile.bcc b/utils/tex2rtf/src/makefile.bcc new file mode 100644 index 0000000000..c2dc7a474a --- /dev/null +++ b/utils/tex2rtf/src/makefile.bcc @@ -0,0 +1,19 @@ +# +# 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 + diff --git a/utils/tex2rtf/src/makefile.dos b/utils/tex2rtf/src/makefile.dos new file mode 100644 index 0000000000..3cf9947f1a --- /dev/null +++ b/utils/tex2rtf/src/makefile.dos @@ -0,0 +1,17 @@ +# +# 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 + diff --git a/utils/tex2rtf/src/makefile.g95 b/utils/tex2rtf/src/makefile.g95 new file mode 100644 index 0000000000..d5a033d7c4 --- /dev/null +++ b/utils/tex2rtf/src/makefile.g95 @@ -0,0 +1,61 @@ +# +# 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 diff --git a/utils/tex2rtf/src/makefile.nt b/utils/tex2rtf/src/makefile.nt new file mode 100644 index 0000000000..03e71beca4 --- /dev/null +++ b/utils/tex2rtf/src/makefile.nt @@ -0,0 +1,141 @@ +# +# 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) + + diff --git a/utils/tex2rtf/src/makefile.unx b/utils/tex2rtf/src/makefile.unx new file mode 100644 index 0000000000..082f482dfe --- /dev/null +++ b/utils/tex2rtf/src/makefile.unx @@ -0,0 +1,17 @@ +# +# 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 + diff --git a/utils/tex2rtf/src/makefile.wat b/utils/tex2rtf/src/makefile.wat new file mode 100644 index 0000000000..053db94965 --- /dev/null +++ b/utils/tex2rtf/src/makefile.wat @@ -0,0 +1,14 @@ +# +# 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 + + diff --git a/utils/tex2rtf/src/makengui.nt b/utils/tex2rtf/src/makengui.nt new file mode 100644 index 0000000000..a4de8c23ca --- /dev/null +++ b/utils/tex2rtf/src/makengui.nt @@ -0,0 +1,98 @@ +# 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 + + diff --git a/utils/tex2rtf/src/maths.cpp b/utils/tex2rtf/src/maths.cpp new file mode 100644 index 0000000000..e951fea6a0 --- /dev/null +++ b/utils/tex2rtf/src/maths.cpp @@ -0,0 +1,23 @@ +/* + * 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 +#endif + +#include +#include "tex2any.h" +#include +#include + diff --git a/utils/tex2rtf/src/readshg.cpp b/utils/tex2rtf/src/readshg.cpp new file mode 100644 index 0000000000..2a62d48bc5 --- /dev/null +++ b/utils/tex2rtf/src/readshg.cpp @@ -0,0 +1,163 @@ +///////////////////////////////////////////////////////////////////////////// +// 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 +#include + +#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; +} + diff --git a/utils/tex2rtf/src/readshg.h b/utils/tex2rtf/src/readshg.h new file mode 100644 index 0000000000..b26d4fea09 --- /dev/null +++ b/utils/tex2rtf/src/readshg.h @@ -0,0 +1,64 @@ +///////////////////////////////////////////////////////////////////////////// +// 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 +#include + +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 + diff --git a/utils/tex2rtf/src/rtfutils.cpp b/utils/tex2rtf/src/rtfutils.cpp new file mode 100644 index 0000000000..d58191aa95 --- /dev/null +++ b/utils/tex2rtf/src/rtfutils.cpp @@ -0,0 +1,5250 @@ +///////////////////////////////////////////////////////////////////////////// +// 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 +#include +#include + +#ifdef __WIN32__ +#include +#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; +} diff --git a/utils/tex2rtf/src/rtfutils.h b/utils/tex2rtf/src/rtfutils.h new file mode 100644 index 0000000000..9f2cf955db --- /dev/null +++ b/utils/tex2rtf/src/rtfutils.h @@ -0,0 +1,60 @@ +///////////////////////////////////////////////////////////////////////////// +// 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); diff --git a/utils/tex2rtf/src/table.cpp b/utils/tex2rtf/src/table.cpp new file mode 100644 index 0000000000..4dc88ee028 --- /dev/null +++ b/utils/tex2rtf/src/table.cpp @@ -0,0 +1,156 @@ +///////////////////////////////////////////////////////////////////////////// +// 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 + +#if wxUSE_IOSTREAMH +#include +#include +#else +#include +#include +#endif + +#include +#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; +} diff --git a/utils/tex2rtf/src/table.h b/utils/tex2rtf/src/table.h new file mode 100644 index 0000000000..d2235f2394 --- /dev/null +++ b/utils/tex2rtf/src/table.h @@ -0,0 +1,36 @@ +///////////////////////////////////////////////////////////////////////////// +// 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); diff --git a/utils/tex2rtf/src/tex2any.cpp b/utils/tex2rtf/src/tex2any.cpp new file mode 100644 index 0000000000..40e159eeae --- /dev/null +++ b/utils/tex2rtf/src/tex2any.cpp @@ -0,0 +1,3482 @@ +///////////////////////////////////////////////////////////////////////////// +// 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 +#include "tex2any.h" +#include +#include + +/* + * 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; +} + diff --git a/utils/tex2rtf/src/tex2any.h b/utils/tex2rtf/src/tex2any.h new file mode 100644 index 0000000000..db5b1914de --- /dev/null +++ b/utils/tex2rtf/src/tex2any.h @@ -0,0 +1,1067 @@ +///////////////////////////////////////////////////////////////////////////// +// 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 +#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 + + + diff --git a/utils/tex2rtf/src/tex2rtf.cpp b/utils/tex2rtf/src/tex2rtf.cpp new file mode 100644 index 0000000000..2ad1a396f5 --- /dev/null +++ b/utils/tex2rtf/src/tex2rtf.cpp @@ -0,0 +1,1077 @@ +///////////////////////////////////////////////////////////////////////////// +// 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 +#include +#endif + +#ifdef NO_GUI +#if wxUSE_IOSTREAMH +#include +#include +#else +#include +#include +#endif +#endif + +#include +#include +#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 "); + OnInform(" -charset (default ansi)"); + OnInform(" -twice"); + OnInform(" -sync"); + OnInform(" -macros "); + 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 + diff --git a/utils/tex2rtf/src/tex2rtf.def b/utils/tex2rtf/src/tex2rtf.def new file mode 100644 index 0000000000..6a6a2f1c76 --- /dev/null +++ b/utils/tex2rtf/src/tex2rtf.def @@ -0,0 +1,8 @@ +NAME TEX2RTF +DESCRIPTION 'Tex2Rtf' +EXETYPE WINDOWS +STUB 'WINSTUB.EXE' +CODE PRELOAD MOVEABLE DISCARDABLE +DATA PRELOAD MOVEABLE MULTIPLE +HEAPSIZE 3000 +STACKSIZE 20000 diff --git a/utils/tex2rtf/src/tex2rtf.h b/utils/tex2rtf/src/tex2rtf.h new file mode 100644 index 0000000000..70f2156b6d --- /dev/null +++ b/utils/tex2rtf/src/tex2rtf.h @@ -0,0 +1,157 @@ +///////////////////////////////////////////////////////////////////////////// +// 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 diff --git a/utils/tex2rtf/src/tex2rtf.ico b/utils/tex2rtf/src/tex2rtf.ico new file mode 100644 index 0000000000..b68125570f Binary files /dev/null and b/utils/tex2rtf/src/tex2rtf.ico differ diff --git a/utils/tex2rtf/src/tex2rtf.ini b/utils/tex2rtf/src/tex2rtf.ini new file mode 100644 index 0000000000..48800d37db --- /dev/null +++ b/utils/tex2rtf/src/tex2rtf.ini @@ -0,0 +1,17 @@ +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 diff --git a/utils/tex2rtf/src/tex2rtf.rc b/utils/tex2rtf/src/tex2rtf.rc new file mode 100644 index 0000000000..b97ff28e70 --- /dev/null +++ b/utils/tex2rtf/src/tex2rtf.rc @@ -0,0 +1,4 @@ +aaa ICON "tex2rtf.ico" +tex2rtf ICON "tex2rtf.ico" +#include "wx/msw/wx.rc" + diff --git a/utils/tex2rtf/src/tex2rtf.xpm b/utils/tex2rtf/src/tex2rtf.xpm new file mode 100644 index 0000000000..20e566f048 --- /dev/null +++ b/utils/tex2rtf/src/tex2rtf.xpm @@ -0,0 +1,42 @@ +/* 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" +}; diff --git a/utils/tex2rtf/src/texutils.cpp b/utils/tex2rtf/src/texutils.cpp new file mode 100644 index 0000000000..5de8abcae7 --- /dev/null +++ b/utils/tex2rtf/src/texutils.cpp @@ -0,0 +1,1635 @@ +///////////////////////////////////////////////////////////////////////////// +// 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 + +#if wxUSE_IOSTREAMH +#include +#include +#else +#include +#include +#endif + +#include +#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; +} diff --git a/utils/tex2rtf/src/wxhlpblk.h b/utils/tex2rtf/src/wxhlpblk.h new file mode 100644 index 0000000000..6cfeb75e41 --- /dev/null +++ b/utils/tex2rtf/src/wxhlpblk.h @@ -0,0 +1,30 @@ +/* + * 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 diff --git a/utils/tex2rtf/src/xlputils.cpp b/utils/tex2rtf/src/xlputils.cpp new file mode 100644 index 0000000000..bcbc4a0fb7 --- /dev/null +++ b/utils/tex2rtf/src/xlputils.cpp @@ -0,0 +1,1219 @@ +///////////////////////////////////////////////////////////////////////////// +// 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 + +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; +} +