1/////////////////////////////////////////////////////////////////////////////
2// Name:        rtfutils.cpp
3// Purpose:     Converts Latex to Word RTF/WinHelp RTF
4// Author:      Julian Smart
5// Modified by: Wlodzimiez ABX Skiba 2003/2004 Unicode support
6//              Ron Lee
7// Created:     7.9.93
8// RCS-ID:      $Id: rtfutils.cpp 36101 2005-11-07 13:27:09Z ABX $
9// Copyright:   (c) Julian Smart
10// Licence:     wxWindows licence
11/////////////////////////////////////////////////////////////////////////////
12
13// For compilers that support precompilation, includes "wx.h".
14#include "wx/wxprec.h"
15
16#ifdef __BORLANDC__
17#pragma hdrstop
18#endif
19
20#ifndef WX_PRECOMP
21#endif
22
23#include "tex2any.h"
24#include "tex2rtf.h"
25#include <ctype.h>
26#include <stdlib.h>
27#include <stdio.h>
28
29#ifdef __WIN32__
30#include <windows.h>
31#endif
32
33#include "bmputils.h"
34#include "table.h"
35
36#if !WXWIN_COMPATIBILITY_2_4
37static inline wxChar* copystring(const wxChar* s)
38    { return wxStrcpy(new wxChar[wxStrlen(s) + 1], s); }
39#endif
40
41wxList itemizeStack;
42static int indentLevel = 0;
43static int forbidParindent = 0; // if > 0, no parindent (e.g. in center environment)
44int forbidResetPar = 0; // If > 0, don't reset memory of having output a new par
45
46static wxChar *contentsLineSection = NULL;
47static wxChar *contentsLineValue = NULL;
48static TexChunk *descriptionItemArg = NULL;
49static wxStringList environmentStack; // Stack of paragraph styles we need to remember
50static int footnoteCount = 0;
51static int citeCount = 1;
52extern bool winHelp;
53extern bool startedSections;
54extern FILE *Contents;
55extern FILE *Chapters;
56extern FILE *Popups;
57extern FILE *WinHelpContentsFile;
58extern wxChar *RTFCharset;
59// This is defined in the Tex2Any library and isn't in use after parsing
60extern wxChar *BigBuffer;
61
62extern wxHashTable TexReferences;
63
64// Are we in verbatim mode? If so, format differently.
65static bool inVerbatim = false;
66
67// We're in a series of PopRef topics, so don't output section headings
68bool inPopRefSection = false;
69
70// Green colour?
71static bool hotSpotColour = true;
72static bool hotSpotUnderline = true;
73
74// Transparency (WHITE = transparent)
75static bool bitmapTransparency = true;
76
77// Linear RTF requires us to set the style per section.
78static wxChar *currentNumberStyle = NULL;
79static int currentItemSep = 8;
80static int CurrentTextWidth = 8640; // Say, six inches
81static int CurrentLeftMarginOdd = 400;
82static int CurrentLeftMarginEven = 1440;
83static int CurrentRightMarginOdd = 1440;
84static int CurrentRightMarginEven = 400;
85static int CurrentMarginParWidth = 2000;
86static int CurrentMarginParSep = 400;  // Gap between marginpar and text
87static int CurrentMarginParX = CurrentLeftMarginOdd + CurrentTextWidth + CurrentMarginParSep;
88static int GutterWidth = 2300;
89
90// Two-column table dimensions, in twips
91static int TwoColWidthA = 1500;
92static int TwoColWidthB = 3000;
93
94const int PageWidth = 12242; // 8.25 inches wide for A4
95
96// Remember the anchor in a helpref
97static TexChunk *helpRefText = NULL;
98
99/*
100 * Flag to say we've just issued a \par\pard command, so don't
101 * repeat this unnecessarily.
102 *
103 */
104
105int issuedNewParagraph = 0;
106
107// Need to know whether we're in a table or figure for benefit
108// of listoffigures/listoftables
109static bool inFigure = false;
110static bool inTable = false;
111
112/*
113 * Current topics
114 *
115 */
116static wxChar *CurrentChapterName = NULL;
117static wxChar *CurrentSectionName = NULL;
118static wxChar *CurrentSubsectionName = NULL;
119static wxChar *CurrentTopic = NULL;
120
121static bool InPopups()
122{
123  if (CurrentChapterName && (wxStrcmp(CurrentChapterName, _T("popups")) == 0))
124    return true;
125  if (CurrentSectionName && (wxStrcmp(CurrentSectionName, _T("popups")) == 0))
126    return true;
127  return false;
128}
129
130static void SetCurrentTopic(wxChar *s)
131{
132  if (CurrentTopic) delete[] CurrentTopic;
133  CurrentTopic = copystring(s);
134}
135
136void SetCurrentChapterName(wxChar *s)
137{
138  if (CurrentChapterName) delete[] CurrentChapterName;
139  CurrentChapterName = copystring(s);
140  SetCurrentTopic(s);
141}
142void SetCurrentSectionName(wxChar *s)
143{
144  if (CurrentSectionName) delete[] CurrentSectionName;
145  CurrentSectionName = copystring(s);
146  SetCurrentTopic(s);
147}
148void SetCurrentSubsectionName(wxChar *s)
149{
150  if (CurrentSubsectionName) delete[] CurrentSubsectionName;
151  CurrentSubsectionName = copystring(s);
152  SetCurrentTopic(s);
153}
154
155// Indicate that a parent topic at level 'level' has children.
156// Level 1 is a chapter, 2 is a section, etc.
157void NotifyParentHasChildren(int parentLevel)
158{
159  wxChar *parentTopic = NULL;
160  switch (parentLevel)
161  {
162    case 1:
163    {
164      parentTopic = CurrentChapterName;
165      break;
166    }
167    case 2:
168    {
169      parentTopic = CurrentSectionName;
170      break;
171    }
172    case 3:
173    {
174      parentTopic = CurrentSubsectionName;
175      break;
176    }
177    default:
178    {
179      break;
180    }
181  }
182  if (parentTopic)
183  {
184    TexTopic *texTopic = (TexTopic *)TopicTable.Get(parentTopic);
185    if (!texTopic)
186    {
187      texTopic = new TexTopic;
188      TopicTable.Put(parentTopic, texTopic);
189    }
190    texTopic->hasChildren = true;
191  }
192}
193
194// Have to keep a count of what levels are books, what are pages,
195// in order to correct for a Win95 bug which means that if you
196// have a book at level n, and then a page at level n, the page
197// ends up on level n + 1.
198
199bool ContentsLevels[5];
200
201// Reset below this level (starts from 1)
202void ResetContentsLevels(int l)
203{
204  int i;
205  for (i = l; i < 5; i++)
206    ContentsLevels[i] = false;
207
208  // There are always books on the top level
209  ContentsLevels[0] = true;
210}
211
212// Output a WinHelp section as a keyword, substituting
213// : for space.
214void OutputSectionKeyword(FILE *fd)
215{
216  OutputCurrentSectionToString(wxTex2RTFBuffer);
217
218  unsigned int i;
219  for (i = 0; i < wxStrlen(wxTex2RTFBuffer); i++)
220    if (wxTex2RTFBuffer[i] == ':')
221      wxTex2RTFBuffer[i] = ' ';
222    // Don't write to index if there's some RTF in the string
223    else if ( wxTex2RTFBuffer[i] == '{' )
224        return;
225
226  wxFprintf(fd, _T("K{\\footnote {K} "));
227  wxFprintf(fd, _T("%s"), wxTex2RTFBuffer);
228
229  wxFprintf(fd, _T("}\n"));
230}
231
232// Write a line for the .cnt file, if we're doing this.
233void WriteWinHelpContentsFileLine(wxChar *topicName, wxChar *xitle, int level)
234{
235  // First, convert any RTF characters to ASCII
236  wxChar title[255];
237  int s=0;
238  int d=0;
239  // assuming iso-8859-1 here even in Unicode build (FIXME?)
240  while ( (xitle[s]!=0)&&(d<255) )
241  {
242    wxChar ch=wxChar(xitle[s]&0xff);
243    if (ch==0x5c) {
244      wxChar ch1=wxChar(xitle[s+1]&0xff);
245      wxChar ch2=wxChar(xitle[s+2]&0xff);
246      wxChar ch3=wxChar(xitle[s+3]&0xff);
247      s+=4; // next character
248      if ((ch1==0x27)&&(ch2==0x66)&&(ch3==0x36)) { title[d++]=wxChar('�');  }
249      if ((ch1==0x27)&&(ch2==0x65)&&(ch3==0x34)) { title[d++]=wxChar('�');  }
250      if ((ch1==0x27)&&(ch2==0x66)&&(ch3==0x63)) { title[d++]=wxChar('�');  }
251      if ((ch1==0x27)&&(ch2==0x64)&&(ch3==0x36)) { title[d++]=wxChar('�');  }
252      if ((ch1==0x27)&&(ch2==0x63)&&(ch3==0x34)) { title[d++]=wxChar('�');  }
253      if ((ch1==0x27)&&(ch2==0x64)&&(ch3==0x63)) { title[d++]=wxChar('�');  }
254    } else {
255      title[d++]=ch;
256      s++;
257    }
258  }
259  title[d]=0;
260
261  // Section (2) becomes level 1 if it's an article.
262  if (DocumentStyle == LATEX_ARTICLE)
263    level --;
264
265  if (level == 0) // Means we had a Chapter in an article, oops.
266    return;
267
268  ResetContentsLevels(level);
269
270  if (winHelp && winHelpContents && WinHelpContentsFile)
271  {
272    TexTopic *texTopic = (TexTopic *)TopicTable.Get(topicName);
273    if (texTopic)
274    {
275      // If a previous section at this level was a book, we *have* to have a
276      // book not a page, because of a bug in WHC (or WinHelp 4).
277      if (texTopic->hasChildren || level == 1 || ContentsLevels[level-1])
278      {
279        // At this level, we have a pointer to a further hierarchy.
280        // So we need a 'book' consisting of (say) Chapter 1.
281        wxFprintf(WinHelpContentsFile, _T("%d %s\n"), level, title);
282
283        // Then we have a 'page' consisting of the text for this chapter
284        wxFprintf(WinHelpContentsFile, _T("%d %s=%s\n"), level+1, title, topicName);
285
286        // Then we'll be writing out further pages or books at level + 1...
287
288        // Remember that at this level, we had a book and *must* for the
289        // remainder of sections at this level.
290        ContentsLevels[level-1] = true;
291      }
292      else
293      {
294        wxFprintf(WinHelpContentsFile, _T("%d %s=%s\n"), level, title, topicName);
295      }
296    }
297    else
298    {
299      if (level == 1 || ContentsLevels[level-1])
300      {
301        // Always have a book at level 1
302        wxFprintf(WinHelpContentsFile, _T("%d %s\n"), level, title);
303        wxFprintf(WinHelpContentsFile, _T("%d %s=%s\n"), level+1, title, topicName);
304        ContentsLevels[level-1] = true;
305      }
306      else
307        // Probably doesn't have children if it hasn't been added to the topic table
308        wxFprintf(WinHelpContentsFile, _T("%d %s=%s\n"), level, title, topicName);
309    }
310  }
311}
312
313void SplitIndexEntry(wxChar *entry, wxChar *buf1, wxChar *buf2)
314{
315  int len = wxStrlen(entry); int i = 0;
316  while ((i < len) && entry[i] != '!')
317  { buf1[i] = entry[i]; i ++; }
318  buf1[i] = 0; buf2[0] = 0; int j = 0;
319
320  if (entry[i] == '!')
321  {
322    i ++;
323    while (i < len) { buf2[j] = entry[i]; i ++; j++; }
324    buf2[j] = 0;
325  }
326}
327
328/*
329 * Output topic index entries in WinHelp RTF
330 *
331 */
332void GenerateKeywordsForTopic(wxChar *topic)
333{
334  TexTopic *texTopic = (TexTopic *)TopicTable.Get(topic);
335  if (!texTopic)
336    return;
337
338  wxStringList *list = texTopic->keywords;
339  if (list)
340  {
341    wxStringListNode *node = list->GetFirst();
342    while (node)
343    {
344      wxChar *s = (wxChar *)node->GetData();
345
346      // Must separate out main entry form subentry (only 1 subentry allowed)
347      wxChar buf1[100]; wxChar buf2[100];
348      SplitIndexEntry(s, buf1, buf2);
349
350      // Check for ':' which messes up index
351      unsigned int i;
352      for (i = 0; i < wxStrlen(buf1) ; i++)
353        if (buf1[i] == ':')
354          buf1[i] = ' ';
355      for (i = 0; i < wxStrlen(buf2) ; i++)
356        if (buf2[i] == ':')
357          buf2[i] = ' ';
358
359      // {K} is a strange fix to prevent words beginning with K not
360      // being indexed properly
361      TexOutput(_T("K{\\footnote {K} "));
362      TexOutput(buf1);
363      if (wxStrlen(buf2) > 0)
364      {
365        // Output subentry
366        TexOutput(_T(", "));
367        TexOutput(buf2);
368      }
369      TexOutput(_T("}\n"));
370      node = node->GetNext();
371    }
372  }
373}
374
375/*
376 * Output index entry in linear RTF
377 *
378 */
379
380void GenerateIndexEntry(wxChar *entry)
381{
382  if (useWord)
383  {
384    wxChar buf1[100]; wxChar buf2[100];
385    SplitIndexEntry(entry, buf1, buf2);
386
387    TexOutput(_T("{\\xe\\v {"));
388    TexOutput(buf1);
389    if (wxStrlen(buf2) > 0)
390    {
391      TexOutput(_T("\\:"));
392      TexOutput(buf2);
393    }
394    TexOutput(_T("}}"));
395  }
396}
397
398 /*
399  * Write a suitable RTF header.
400  *
401  */
402
403void WriteColourTable(FILE *fd)
404{
405  wxFprintf(fd, _T("{\\colortbl"));
406  wxNode *node = ColourTable.GetFirst();
407  while (node)
408  {
409    ColourTableEntry *entry = (ColourTableEntry *)node->GetData();
410    wxFprintf(fd, _T("\\red%d\\green%d\\blue%d;\n"), entry->red, entry->green, entry->blue);
411    node = node->GetNext();
412  }
413  wxFprintf(fd, _T("}"));
414}
415
416/*
417 * Write heading style
418 *
419 */
420
421void WriteHeadingStyle(FILE *fd, int heading)
422{
423  switch (heading)
424  {
425    case 1:
426    {
427      wxFprintf(fd, _T("\\sb300\\sa260\\f2\\b\\fs%d"), chapterFont*2);
428      break;
429    }
430    case 2:
431    {
432      wxFprintf(fd, _T("\\sb200\\sa240\\f2\\b\\fs%d"), sectionFont*2);
433      break;
434    }
435    case 3:
436    {
437      wxFprintf(fd, _T("\\sb120\\sa240\\f2\\b\\fs%d"), subsectionFont*2);
438      break;
439    }
440    case 4:
441    {
442      wxFprintf(fd, _T("\\sb120\\sa240\\f2\\b\\fs%d"), subsectionFont*2);
443      break;
444    }
445    default:
446      break;
447  }
448}
449
450void WriteRTFHeader(FILE *fd)
451{
452  wxFprintf(fd, _T("{\\rtf1\\%s \\deff0\n"), RTFCharset);
453  wxFprintf(fd, _T("{\\fonttbl{\\f0\\froman Times New Roman;}{\\f1\\ftech Symbol;}{\\f2\\fswiss Arial;}\n"));
454  wxFprintf(fd, _T("{\\f3\\fmodern Courier New;}{\\f4\\ftech Wingdings;}{\\f5\\ftech Monotype Sorts;}\n}"));
455  /*
456   * Style sheet
457   */
458  wxFprintf(fd, _T("{\\stylesheet{\\f2\\fs22\\sa200 \\snext0 Normal;}\n"));
459  // Headings
460  wxFprintf(fd, _T("{\\s1 ")); WriteHeadingStyle(fd, 1); wxFprintf(fd, _T("\\sbasedon0\\snext0 heading 1;}\n"));
461  wxFprintf(fd, _T("{\\s2 ")); WriteHeadingStyle(fd, 2); wxFprintf(fd, _T("\\sbasedon0\\snext0 heading 2;}\n"));
462  wxFprintf(fd, _T("{\\s3 ")); WriteHeadingStyle(fd, 3); wxFprintf(fd, _T("\\sbasedon0\\snext0 heading 3;}\n"));
463  wxFprintf(fd, _T("{\\s4 ")); WriteHeadingStyle(fd, 4); wxFprintf(fd, _T("\\sbasedon0\\snext0 heading 4;}\n"));
464
465  // Code style
466  wxFprintf(fd, _T("{\\s10\\ql \\li720\\ri0\\nowidctlpar\\faauto\\rin0\\lin720\\itap0 \\cbpat17\
467\\f2\\fs20 \\sbasedon0 \\snext24 Code;}\n"));
468
469  // Table of contents styles
470  wxFprintf(fd, _T("{\\s20\\sb300\\tqr\\tldot\\tx8640 \\b\\f2 \\sbasedon0\\snext0 toc 1;}\n"));
471
472  wxFprintf(fd, _T("{\\s21\\sb90\\tqr\\tldot\\li400\\tqr\\tx8640 \\f2\\fs20\\sbasedon0\\snext0 toc 2;}\n"));
473  wxFprintf(fd, _T("{\\s22\\sb90\\tqr\\tldot\\li800\\tx8640 \\f2\\fs20 \\sbasedon0\\snext0 toc 3;}\n"));
474  wxFprintf(fd, _T("{\\s23\\sb90\\tqr\\tldot\\li1200\\tx8640 \\f2\\fs20 \\sbasedon0\\snext0 toc 4;}\n"));
475
476  // Index styles
477  wxFprintf(fd, _T("{\\s30\\fi-200\\li200\\tqr\\tx3960 \\f2\\fs18 \\sbasedon0\\snext0 index 1;}\n"));
478  wxFprintf(fd, _T("{\\s31\\fi-200\\li400\\tqr\\tx3960 \\f2\\fs18 \\sbasedon0\\snext0 index 2;}\n"));
479  wxFprintf(fd, _T("{\\s32\\fi-200\\li600\\tqr\\tx3960 \\f2\\fs18 \\sbasedon0\\snext0 index 3;}\n"));
480  wxFprintf(fd, _T("{\\s33\\fi-200\\li800\\tqr\\tx3960 \\f2\\fs18 \\sbasedon0\\snext0 index 4;}\n"));
481  wxFprintf(fd, _T("{\\s35\\qc\\sb240\\sa120 \\b\\f2\\fs26 \\sbasedon0\\snext30 index heading;}\n"));
482  wxFprintf(fd, _T("}\n"));
483
484  WriteColourTable(fd);
485  wxFprintf(fd, _T("\n\\ftnbj\\ftnrestart")); // Latex default is footnotes at bottom of page, not section.
486  wxFprintf(fd, _T("\n"));
487}
488
489void OutputNumberStyle(wxChar *numberStyle)
490{
491  if (numberStyle)
492  {
493    if (wxStrcmp(numberStyle, _T("arabic")) == 0)
494    {
495      TexOutput(_T("\\pgndec"));
496    }
497    else if (wxStrcmp(numberStyle, _T("roman")) == 0)
498    {
499      TexOutput(_T("\\pgnlcrm"));
500    }
501    else if (wxStrcmp(numberStyle, _T("Roman")) == 0)
502    {
503      TexOutput(_T("\\pgnucrm"));
504    }
505    else if (wxStrcmp(numberStyle, _T("alph")) == 0)
506    {
507      TexOutput(_T("\\pgnlcltr"));
508    }
509    else if (wxStrcmp(numberStyle, _T("Alph")) == 0)
510    {
511      TexOutput(_T("\\pgnucltr"));
512    }
513  }
514}
515
516/*
517 * Write a Windows help project file
518 */
519
520bool WriteHPJ(const wxString& filename)
521{
522    wxChar hpjFilename[256];
523    wxChar helpFile[50];
524    wxChar rtfFile[50];
525    wxStrcpy(hpjFilename, filename);
526    StripExtension(hpjFilename);
527    wxStrcat(hpjFilename, _T(".hpj"));
528
529    wxStrcpy(helpFile, wxFileNameFromPath(filename));
530    StripExtension(helpFile);
531    wxStrcpy(rtfFile, helpFile);
532    wxStrcat(helpFile, _T(".hlp"));
533    wxStrcat(rtfFile, _T(".rtf"));
534
535    FILE *fd = wxFopen(hpjFilename, _T("w"));
536    if (!fd)
537        return false;
538
539    wxChar *helpTitle = winHelpTitle;
540    if (!helpTitle)
541        helpTitle = _T("Untitled");
542
543    wxString thePath = wxPathOnly(InputFile);
544    if (thePath.empty())
545        thePath = _T(".");
546    wxFprintf(fd, _T("[OPTIONS]\n"));
547    wxFprintf(fd, _T("BMROOT=%s ; Assume that bitmaps are where the source is\n"), thePath.c_str());
548    wxFprintf(fd, _T("TITLE=%s\n"), helpTitle);
549    wxFprintf(fd, _T("CONTENTS=Contents\n"));
550
551    if (winHelpVersion > 3)
552    {
553        wxFprintf(fd, _T("; COMPRESS=12 Hall Zeck ; Max compression, but needs lots of memory\n"));
554        wxFprintf(fd, _T("COMPRESS=8 Zeck\n"));
555        wxFprintf(fd, _T("LCID=0x809 0x0 0x0 ;English (British)\n"));
556        wxFprintf(fd, _T("HLP=.\\%s.hlp\n"), wxFileNameFromPath(FileRoot));
557    }
558    else
559    {
560        wxFprintf(fd, _T("COMPRESS=HIGH\n"));
561    }
562    wxFprintf(fd, _T("\n"));
563
564    if (winHelpVersion > 3)
565    {
566        wxFprintf(fd, _T("[WINDOWS]\n"));
567        wxFprintf(fd, _T("Main=\"\",(553,102,400,600),20736,(r14876671),(r12632256),f3\n"));
568        wxFprintf(fd, _T("\n"));
569    }
570
571    wxFprintf(fd, _T("[FILES]\n%s\n\n"), rtfFile);
572    wxFprintf(fd, _T("[CONFIG]\n"));
573    if (useUpButton)
574        wxFprintf(fd, _T("CreateButton(\"Up\", \"&Up\", \"JumpId(`%s', `Contents')\")\n"), helpFile);
575    wxFprintf(fd, _T("BrowseButtons()\n\n"));
576    wxFprintf(fd, _T("[MAP]\n\n[BITMAPS]\n\n"));
577    fclose(fd);
578    return true;
579}
580
581
582/*
583 * Given a TexChunk with a string value, scans through the string
584 * converting Latex-isms into RTF-isms, such as 2 newlines -> \par,
585 * and inserting spaces at the start of lines since in Latex, a newline
586 * implies a space, but not in RTF.
587 *
588 */
589
590void ProcessText2RTF(TexChunk *chunk)
591{
592  bool changed = false;
593  int ptr = 0;
594  int i = 0;
595  wxChar ch = 1;
596  int len = wxStrlen(chunk->value);
597  while (ch != 0)
598  {
599    ch = chunk->value[i];
600
601    if (ch == 10)
602    {
603      if (inVerbatim)
604      {
605        BigBuffer[ptr] = 0; wxStrcat(BigBuffer, _T("\\par\n")); ptr += 5;
606//        BigBuffer[ptr] = 0; wxStrcat(BigBuffer, _T("\\par{\\v this was verbatim}\n")); ptr += 5;
607        i ++;
608        changed = true;
609      }
610      else
611      {
612        // If the first character of the next line is ASCII,
613        // put a space in. Implicit in Latex, not in RTF.
614        /*
615          The reason this is difficult is that you don't really know
616          where a space would be appropriate. If you always put in a space
617          when you find a newline, unwanted spaces appear in the text.
618         */
619        if ((i > 0) && (len > i+1 && isascii(chunk->value[i+1]) &&
620                  !isspace(chunk->value[i+1])) ||
621            ((len > i+1 && chunk->value[i+1] == 13) &&
622             (len > i+2 && isascii(chunk->value[i+2]) &&
623              !isspace(chunk->value[i+2]))))
624//        if (true)
625        {
626          // DOS files have a 13 after the 10
627          BigBuffer[ptr] = 10;
628          ptr ++;
629          i ++;
630          if (chunk->value[i] == 13)
631          {
632            BigBuffer[ptr] = 13;
633            ptr ++;
634            i ++;
635          }
636
637          BigBuffer[ptr] = ' ';
638          ptr ++;
639
640          // Note that the actual ASCII character seen is dealt with in the next
641          // iteration
642          changed = true;
643        }
644        else
645        {
646          BigBuffer[ptr] = ch;
647          i ++;
648        }
649      }
650    }
651    else if (!inVerbatim && ch == '`' && (len >= i+1 && chunk->value[i+1] == '`'))
652    {
653      BigBuffer[ptr] = '"'; ptr ++;
654      i += 2;
655      changed = true;
656    }
657    else if (!inVerbatim && ch == '`') // Change ` to '
658    {
659      BigBuffer[ptr] = 39; ptr ++;
660      i += 1;
661      changed = true;
662    }
663    else if (inVerbatim && ch == '\\') // Change backslash to two backslashes
664    {
665      BigBuffer[ptr] = '\\'; ptr ++;
666      BigBuffer[ptr] = '\\'; ptr ++;
667      i += 1;
668      changed = true;
669    }
670    else if (inVerbatim && (ch == '{' || ch == '}')) // Escape the curly bracket
671    {
672      BigBuffer[ptr] = '\\'; ptr ++;
673      BigBuffer[ptr] = ch; ptr ++;
674      i += 1;
675      changed = true;
676    }
677    else
678    {
679      BigBuffer[ptr] = ch;
680      i ++;
681      ptr ++;
682    }
683  }
684  BigBuffer[ptr] = 0;
685
686  if (changed)
687  {
688    delete[] chunk->value;
689    chunk->value = copystring(BigBuffer);
690  }
691}
692
693/*
694 * Scan through all chunks starting from the given one,
695 * calling ProcessText2RTF to convert Latex-isms to RTF-isms.
696 * This should be called after Tex2Any has parsed the file,
697 * and before TraverseDocument is called.
698 *
699 */
700
701void Text2RTF(TexChunk *chunk)
702{
703  Tex2RTFYield();
704  if (stopRunning) return;
705
706  switch (chunk->type)
707  {
708    case CHUNK_TYPE_MACRO:
709    {
710      TexMacroDef *def = chunk->def;
711      if (def && def->ignore)
712        return;
713
714      if (def && (def->macroId == ltVERBATIM || def->macroId == ltVERB))
715        inVerbatim = true;
716
717      wxNode *node = chunk->children.GetFirst();
718      while (node)
719      {
720        TexChunk *child_chunk = (TexChunk *)node->GetData();
721        Text2RTF(child_chunk);
722        node = node->GetNext();
723      }
724
725      if (def && (def->macroId == ltVERBATIM || def->macroId == ltVERB))
726        inVerbatim = false;
727
728      break;
729    }
730    case CHUNK_TYPE_ARG:
731    {
732      wxNode *node = chunk->children.GetFirst();
733      while (node)
734      {
735        TexChunk *child_chunk = (TexChunk *)node->GetData();
736        Text2RTF(child_chunk);
737        node = node->GetNext();
738      }
739
740      break;
741    }
742    case CHUNK_TYPE_STRING:
743    {
744      if (chunk->value)
745        ProcessText2RTF(chunk);
746      break;
747    }
748  }
749}
750
751/*
752 * Not used yet
753 *
754 */
755
756wxChar browseBuf[10];
757static long browseId = 0;
758wxChar *GetBrowseString(void)
759{
760  wxChar buf[10];
761  browseId ++;
762  wxSnprintf(buf, sizeof(buf), _T("%ld"), browseId);
763  int noZeroes = 5-wxStrlen(buf);
764  wxStrcpy(browseBuf, _T("browse"));
765  for (int i = 0; i < noZeroes; i++)
766    wxStrcat(browseBuf, _T("0"));
767  wxStrcat(browseBuf, buf);
768  return browseBuf;
769}
770
771/*
772 * Keeping track of environments to restore the styles after \pard.
773 * Push strings like "\qc" onto stack.
774 *
775 */
776
777void PushEnvironmentStyle(wxChar *style)
778{
779  environmentStack.Add(style);
780}
781
782void PopEnvironmentStyle(void)
783{
784  wxStringListNode *node = environmentStack.GetLast();
785  if (node)
786  {
787    wxChar *val = (wxChar *)node->GetData();
788    delete[] val;
789    delete node;
790  }
791}
792
793// Write out the styles, most recent first.
794void WriteEnvironmentStyles(void)
795{
796  wxStringListNode *node = environmentStack.GetLast();
797  while (node)
798  {
799    wxChar *val = (wxChar *)node->GetData();
800    TexOutput(val);
801    node = node->GetNext();
802  }
803  if (!inTabular && (ParIndent > 0) && (forbidParindent == 0))
804  {
805    wxChar buf[15];
806    wxSnprintf(buf, sizeof(buf), _T("\\fi%d"), ParIndent*20); // Convert points to TWIPS
807    TexOutput(buf);
808  }
809  if (environmentStack.GetCount() > 0 || (ParIndent > 0))
810    TexOutput(_T("\n"));
811}
812
813
814/*
815 * Output a header
816 *
817 */
818
819void OutputRTFHeaderCommands(void)
820{
821  wxChar buf[300];
822  if (PageStyle && wxStrcmp(PageStyle, _T("plain")) == 0)
823  {
824    TexOutput(_T("{\\headerl }{\\headerr }"));
825  }
826  else if (PageStyle && wxStrcmp(PageStyle, _T("empty")) == 0)
827  {
828    TexOutput(_T("{\\headerl }{\\headerr }"));
829  }
830  else if (PageStyle && wxStrcmp(PageStyle, _T("headings")) == 0)
831  {
832    // Left header
833    TexOutput(_T("{\\headerl\\fi0 "));
834
835    if (headerRule)
836      TexOutput(_T("\\brdrb\\brdrs\\brdrw15\\brsp20 "));
837
838    TexOutput(_T("{\\i \\qr "));
839    if (DocumentStyle == LATEX_ARTICLE)
840    {
841      wxSnprintf(buf, sizeof(buf), _T("SECTION %d"), sectionNo);
842      TexOutput(buf);
843    }
844    else
845    {
846      wxSnprintf(buf, sizeof(buf), _T("CHAPTER %d: "), chapterNo);
847      TexOutput(buf);
848    }
849    TexOutput(_T("{\\field{\\*\\fldinst PAGE \\\\* MERGEFORMAT }{\\fldrslt 1}}"));
850    TexOutput(_T("}\\par\\pard}"));
851
852    // Right header
853    TexOutput(_T("{\\headerr\\fi0 "));
854
855    if (headerRule)
856      TexOutput(_T("\\brdrb\\brdrs\\brdrw15\\brsp20 "));
857
858    TexOutput(_T("{\\i \\qc "));
859    if (DocumentStyle == LATEX_ARTICLE)
860    {
861      wxSnprintf(buf, sizeof(buf), _T("SECTION %d"), sectionNo);
862      TexOutput(buf);
863    }
864    else
865    {
866      wxSnprintf(buf, sizeof(buf), _T("CHAPTER %d"), chapterNo);
867      TexOutput(buf);
868    }
869    TexOutput(_T("{\\field{\\*\\fldinst PAGE \\\\* MERGEFORMAT }{\\fldrslt 1}}"));
870    TexOutput(_T("}\\par\\pard}"));
871  }
872  else
873  {
874    int oldForbidResetPar = forbidResetPar;
875    forbidResetPar = 0;
876
877    if (LeftHeaderEven || CentreHeaderEven || RightHeaderEven)
878    {
879      TexOutput(_T("{\\headerl\\fi0 "));
880
881      if (headerRule)
882        TexOutput(_T("\\brdrb\\brdrs\\brdrw15\\brsp20 "));
883
884      if (LeftHeaderEven)
885      {
886        if (!CentreHeaderEven && !RightHeaderEven)
887          TexOutput(_T("\\ql "));
888        TraverseChildrenFromChunk(LeftHeaderEven);
889      }
890      if (CentreHeaderEven)
891      {
892        if (!LeftHeaderEven && !RightHeaderEven)
893          TexOutput(_T("\\qc "));
894        else
895          TexOutput(_T("\\tab\\tab\\tab "));
896        TraverseChildrenFromChunk(CentreHeaderEven);
897      }
898      if (RightHeaderEven)
899      {
900        if (!LeftHeaderEven && !CentreHeaderEven)
901          TexOutput(_T("\\qr "));
902        else
903          TexOutput(_T("\\tab\\tab\\tab\\tab\\tab\\tab "));
904        TraverseChildrenFromChunk(RightHeaderEven);
905      }
906      TexOutput(_T("\\par\\pard}"));
907    }
908
909    if (LeftHeaderOdd || CentreHeaderOdd || RightHeaderOdd)
910    {
911      TexOutput(_T("{\\headerr\\fi0 "));
912
913      if (headerRule)
914        TexOutput(_T("\\brdrb\\brdrs\\brdrw15\\brsp20 "));
915
916      if (LeftHeaderOdd)
917      {
918        if (!CentreHeaderOdd && !RightHeaderOdd)
919          TexOutput(_T("\\ql "));
920        TraverseChildrenFromChunk(LeftHeaderOdd);
921      }
922      if (CentreHeaderOdd)
923      {
924        if (!LeftHeaderOdd && !RightHeaderOdd)
925          TexOutput(_T("\\qc "));
926        else
927          TexOutput(_T("\\tab\\tab\\tab "));
928        TraverseChildrenFromChunk(CentreHeaderOdd);
929      }
930      if (RightHeaderOdd)
931      {
932        if (!LeftHeaderOdd && !CentreHeaderOdd)
933          TexOutput(_T("\\qr "));
934        else
935          TexOutput(_T("\\tab\\tab\\tab\\tab\\tab\\tab "));
936        TraverseChildrenFromChunk(RightHeaderOdd);
937      }
938      TexOutput(_T("\\par\\pard}"));
939    }
940    // As an approximation, don't put a header on the first page of a section.
941    // This may not always be desired, but it's a reasonable guess.
942    TexOutput(_T("{\\headerf }"));
943
944    forbidResetPar = oldForbidResetPar;
945  }
946}
947
948void OutputRTFFooterCommands(void)
949{
950  if (PageStyle && wxStrcmp(PageStyle, _T("plain")) == 0)
951  {
952    TexOutput(_T("{\\footerl\\fi0 "));
953    if (footerRule)
954      TexOutput(_T("\\brdrt\\brdrs\\brdrw15\\brsp20 "));
955    TexOutput(_T("{\\qc "));
956    TexOutput(_T("{\\field{\\*\\fldinst PAGE \\\\* MERGEFORMAT }{\\fldrslt 1}}"));
957    TexOutput(_T("}\\par\\pard}"));
958
959    TexOutput(_T("{\\footerr\\fi0 "));
960    if (footerRule)
961      TexOutput(_T("\\brdrt\\brdrs\\brdrw15\\brsp20 "));
962    TexOutput(_T("{\\qc "));
963    TexOutput(_T("{\\field{\\*\\fldinst PAGE \\\\* MERGEFORMAT }{\\fldrslt 1}}"));
964    TexOutput(_T("}\\par\\pard}"));
965  }
966  else if (PageStyle && wxStrcmp(PageStyle, _T("empty")) == 0)
967  {
968    TexOutput(_T("{\\footerl }{\\footerr }"));
969  }
970  else if (PageStyle && wxStrcmp(PageStyle, _T("headings")) == 0)
971  {
972    TexOutput(_T("{\\footerl }{\\footerr }"));
973  }
974  else
975  {
976    if (LeftFooterEven || CentreFooterEven || RightFooterEven)
977    {
978      TexOutput(_T("{\\footerl\\fi0 "));
979      if (footerRule)
980        TexOutput(_T("\\brdrt\\brdrs\\brdrw15\\brsp20 "));
981      if (LeftFooterEven)
982      {
983        if (!CentreFooterEven && !RightFooterEven)
984          TexOutput(_T("\\ql "));
985        TraverseChildrenFromChunk(LeftFooterEven);
986      }
987      if (CentreFooterEven)
988      {
989        if (!LeftFooterEven && !RightFooterEven)
990          TexOutput(_T("\\qc "));
991        else
992          TexOutput(_T("\\tab\\tab\\tab "));
993        TraverseChildrenFromChunk(CentreFooterEven);
994      }
995      if (RightFooterEven)
996      {
997        if (!LeftFooterEven && !CentreFooterEven)
998          TexOutput(_T("\\qr "));
999        else
1000          TexOutput(_T("\\tab\\tab\\tab\\tab\\tab\\tab "));
1001        TraverseChildrenFromChunk(RightFooterEven);
1002      }
1003      TexOutput(_T("\\par\\pard}"));
1004    }
1005
1006    if (LeftFooterOdd || CentreFooterOdd || RightFooterOdd)
1007    {
1008      TexOutput(_T("{\\footerr\\fi0 "));
1009      if (footerRule)
1010        TexOutput(_T("\\brdrt\\brdrs\\brdrw15\\brsp20 "));
1011      if (LeftFooterOdd)
1012      {
1013        if (!CentreFooterOdd && !RightFooterOdd)
1014          TexOutput(_T("\\ql "));
1015        TraverseChildrenFromChunk(LeftFooterOdd);
1016      }
1017      if (CentreFooterOdd)
1018      {
1019        if (!LeftFooterOdd && !RightFooterOdd)
1020          TexOutput(_T("\\qc "));
1021        else
1022          TexOutput(_T("\\tab\\tab\\tab "));
1023        TraverseChildrenFromChunk(CentreFooterOdd);
1024      }
1025      if (RightFooterOdd)
1026      {
1027        if (!LeftFooterOdd && !CentreFooterOdd)
1028          TexOutput(_T("\\qr "));
1029        else
1030          TexOutput(_T("\\tab\\tab\\tab\\tab\\tab\\tab "));
1031        TraverseChildrenFromChunk(RightFooterOdd);
1032      }
1033      TexOutput(_T("\\par\\pard}"));
1034    }
1035
1036    // As an approximation, put a footer on the first page of a section.
1037    // This may not always be desired, but it's a reasonable guess.
1038    if (LeftFooterOdd || CentreFooterOdd || RightFooterOdd)
1039    {
1040      TexOutput(_T("{\\footerf\\fi0 "));
1041      if (LeftFooterOdd)
1042      {
1043        if (!CentreFooterOdd && !RightFooterOdd)
1044          TexOutput(_T("\\ql "));
1045        TraverseChildrenFromChunk(LeftFooterOdd);
1046      }
1047      if (CentreFooterOdd)
1048      {
1049        if (!LeftFooterOdd && !RightFooterOdd)
1050          TexOutput(_T("\\qc "));
1051        else
1052          TexOutput(_T("\\tab\\tab\\tab "));
1053        TraverseChildrenFromChunk(CentreFooterOdd);
1054      }
1055      if (RightFooterOdd)
1056      {
1057        if (!LeftFooterOdd && !CentreFooterOdd)
1058          TexOutput(_T("\\qr "));
1059        else
1060          TexOutput(_T("\\tab\\tab\\tab\\tab\\tab\\tab "));
1061        TraverseChildrenFromChunk(RightFooterOdd);
1062      }
1063      TexOutput(_T("\\par\\pard}"));
1064    }
1065  }
1066}
1067
1068// Called on start/end of macro examination
1069void RTFOnMacro(int macroId, int no_args, bool start)
1070{
1071/*
1072  wxChar tmpBuf[40];
1073  wxSnprintf(tmpBuf, sizeof(tmpBuf), _T("%d (%d)"), macroId, (int)start);
1074  OutputDebugString("RTFOnMacro Start "); OutputDebugString(tmpBuf);
1075  OutputDebugString("\n"); wxYield();
1076*/
1077
1078  // ltLABEL is included here because after a section but BEFORE
1079  // the label is seen, a new paragraph is issued. Don't upset this by
1080  // immediately forgetting we've done it.
1081  if (start && (macroId != ltPAR && macroId != ltITEMIZE &&
1082                        macroId != ltENUMERATE && macroId != ltDESCRIPTION &&
1083                        macroId != ltVERBATIM && macroId != ltLABEL &&
1084                        macroId != ltSETHEADER && macroId != ltSETFOOTER &&
1085                        macroId != ltPAGENUMBERING &&
1086                        (forbidResetPar == 0)))
1087  {
1088    issuedNewParagraph = 0;
1089  }
1090
1091  wxChar buf[300];
1092  switch (macroId)
1093  {
1094  case ltCHAPTER:
1095  case ltCHAPTERSTAR:
1096  case ltCHAPTERHEADING:
1097  case ltCHAPTERHEADINGSTAR:
1098  {
1099    if (!start)
1100    {
1101      sectionNo = 0;
1102      figureNo = 0;
1103      tableNo = 0;
1104      subsectionNo = 0;
1105      subsubsectionNo = 0;
1106      footnoteCount = 0;
1107
1108      if (macroId != ltCHAPTERSTAR && macroId != ltCHAPTERHEADINGSTAR)
1109        chapterNo ++;
1110
1111      wxChar *topicName = FindTopicName(GetNextChunk());
1112      SetCurrentChapterName(topicName);
1113
1114      if (winHelpContents && winHelp && !InPopups())
1115      {
1116        OutputCurrentSectionToString(wxTex2RTFBuffer);
1117        WriteWinHelpContentsFileLine(topicName, wxTex2RTFBuffer, 1);
1118      }
1119      AddTexRef(topicName, NULL, ChapterNameString, chapterNo);
1120
1121      if (winHelp)
1122      {
1123        if (!InPopups())
1124          wxFprintf(Contents, _T("\n{\\uldb "));
1125        wxFprintf(Chapters, _T("\\page"));
1126        wxFprintf(Chapters, _T("\n${\\footnote "));
1127        if (!InPopups())
1128          SetCurrentOutputs(Contents, Chapters);
1129        else
1130          SetCurrentOutput(Chapters);
1131      }
1132      else
1133      {
1134        wxFprintf(Chapters, _T("\\sect\\pgncont\\titlepg\n"));
1135
1136        // If a non-custom page style, we generate the header now.
1137        if (PageStyle && (wxStrcmp(PageStyle, _T("plain")) == 0 ||
1138                          wxStrcmp(PageStyle, _T("empty")) == 0 ||
1139                          wxStrcmp(PageStyle, _T("headings")) == 0))
1140        {
1141          OutputRTFHeaderCommands();
1142          OutputRTFFooterCommands();
1143        }
1144
1145        // Need to reset the current numbering style, or RTF forgets it.
1146        SetCurrentOutput(Chapters);
1147        OutputNumberStyle(currentNumberStyle);
1148
1149        SetCurrentOutput(Contents);
1150
1151        if (!InPopups())
1152        {
1153          if (macroId == ltCHAPTER)
1154          {
1155            // Section
1156            wxFprintf(Contents, _T("\\par\n\\pard{\\b %d\\tab "), chapterNo);
1157          }
1158          else if (macroId == ltCHAPTERHEADING)
1159          {
1160            wxFprintf(Contents, _T("\\par\n\\pard{\\b "));
1161          }
1162          else SetCurrentOutput(NULL); // No entry in table of contents
1163        }
1164      }
1165
1166      startedSections = true;
1167
1168      // Output heading to contents page
1169      if (!InPopups())
1170      {
1171        OutputCurrentSection();
1172
1173        if (winHelp)
1174        {
1175          wxFprintf(Contents, _T("}{\\v %s}\\pard\\par\n"), topicName);
1176          //WriteEnvironmentStyles();
1177        }
1178        else if ((macroId == ltCHAPTER) || (macroId == ltCHAPTERHEADING))
1179          wxFprintf(Contents, _T("}\\par\\par\\pard\n"));
1180
1181        // From here, just output to chapter
1182        SetCurrentOutput(Chapters);
1183      }
1184
1185      if (winHelp)
1186      {
1187        wxFprintf(Chapters, _T("}\n#{\\footnote %s}\n"), topicName);
1188        wxFprintf(Chapters, _T("+{\\footnote %s}\n"), GetBrowseString());
1189
1190        OutputSectionKeyword(Chapters);
1191
1192        GenerateKeywordsForTopic(topicName);
1193        if (useUpButton)
1194        {
1195          // If we're generating a .cnt file, we don't want to be able
1196          // jump up to the old-style contents page, so disable it.
1197          if (winHelpContents)
1198            wxFprintf(Chapters, _T("!{\\footnote DisableButton(\"Up\")}\n"));
1199          else
1200            wxFprintf(Chapters, _T("!{\\footnote EnableButton(\"Up\");ChangeButtonBinding(\"Up\", \"JumpId(`%s.hlp', `%s')\")}\n"),
1201               wxFileNameFromPath(FileRoot), _T("Contents"));
1202        }
1203      }
1204
1205      if (!InPopups())
1206      {
1207      wxChar *styleCommand = _T("");
1208      if (!winHelp && useHeadingStyles && (macroId == ltCHAPTER || macroId == ltCHAPTERHEADING || macroId == ltCHAPTERHEADINGSTAR))
1209        styleCommand = _T("\\s1");
1210      wxFprintf(Chapters, _T("\\pard{%s"), ((winHelp && !InPopups()) ? _T("\\keepn\\sa140\\sb140") : styleCommand));
1211      WriteHeadingStyle(Chapters, 1);  wxFprintf(Chapters, _T(" "));
1212      if (!winHelp)
1213      {
1214        if (macroId == ltCHAPTER)
1215        {
1216          if (useWord)
1217//            wxFprintf(Chapters, "{\\bkmkstart %s}%d{\\bkmkend %s}. ", topicName, chapterNo,
1218            wxFprintf(Chapters, _T("{\\bkmkstart %s}{\\bkmkend %s}"), topicName, topicName);
1219          else
1220            wxFprintf(Chapters, _T("%d. "), chapterNo);
1221        }
1222        else if ( useWord )
1223        {
1224              wxFprintf(Chapters, _T("{\\bkmkstart %s}{\\bkmkend %s}"), topicName, topicName);
1225        }
1226      }
1227      OutputCurrentSection();
1228      TexOutput(_T("\\par\\pard}\n"));
1229      }
1230      issuedNewParagraph = 1;
1231      WriteEnvironmentStyles();
1232    }
1233    break;
1234  }
1235  case ltSECTION:
1236  case ltSECTIONSTAR:
1237  case ltSECTIONHEADING:
1238  case ltSECTIONHEADINGSTAR:
1239  case ltGLOSS:
1240  {
1241    FILE *jumpFrom;
1242    if (DocumentStyle == LATEX_ARTICLE)
1243      jumpFrom = Contents;
1244    else
1245      jumpFrom = Chapters;
1246
1247    if (!start)
1248    {
1249      subsectionNo = 0;
1250      subsubsectionNo = 0;
1251      if (DocumentStyle == LATEX_ARTICLE)
1252        footnoteCount = 0;
1253
1254      if (macroId != ltSECTIONSTAR && macroId != ltSECTIONHEADINGSTAR)
1255        sectionNo ++;
1256
1257      wxChar *topicName = FindTopicName(GetNextChunk());
1258      SetCurrentSectionName(topicName);
1259      NotifyParentHasChildren(1);
1260      if (winHelpContents && winHelp && !InPopups())
1261      {
1262        OutputCurrentSectionToString(wxTex2RTFBuffer);
1263        WriteWinHelpContentsFileLine(topicName, wxTex2RTFBuffer, 2);
1264      }
1265      AddTexRef(topicName, NULL, SectionNameString, chapterNo, sectionNo);
1266
1267      if (winHelp)
1268      {
1269        SetCurrentOutputs(jumpFrom, Sections);
1270        // Newline for a new section if this is an article
1271        if ((DocumentStyle == LATEX_ARTICLE) &&
1272            ((macroId == ltSECTION) || (macroId == ltSECTIONSTAR) || (macroId == ltSECTIONHEADINGSTAR)))
1273          wxFprintf(Sections, _T("\\page\n"));
1274
1275        if (!InPopups())
1276          wxFprintf(jumpFrom, _T("\n{\\uldb "));
1277      }
1278      else
1279      {
1280        if (DocumentStyle == LATEX_ARTICLE)
1281        {
1282          TexOutput(_T("\\sect\\pgncont\n"));
1283          // If a non-custom page style, we generate the header now.
1284          if (PageStyle && (wxStrcmp(PageStyle, _T("plain")) == 0 ||
1285                            wxStrcmp(PageStyle, _T("empty")) == 0 ||
1286                            wxStrcmp(PageStyle, _T("headings")) == 0))
1287          {
1288            OutputRTFHeaderCommands();
1289            OutputRTFFooterCommands();
1290          }
1291        }
1292        SetCurrentOutput(Contents);
1293
1294        if (macroId == ltSECTION)
1295        {
1296          if (!InPopups())
1297          {
1298            if (DocumentStyle == LATEX_REPORT)
1299              wxFprintf(Contents, _T("\n\\pard{\\tab %d.%d\\tab "), chapterNo, sectionNo);
1300            else
1301              wxFprintf(Contents, _T("\\par\n\\pard{\\b %d\\tab "), sectionNo);
1302          }
1303        }
1304        else if (macroId == ltSECTIONHEADING)
1305        {
1306          if (!InPopups())
1307          {
1308            if (DocumentStyle == LATEX_REPORT)
1309              wxFprintf(Contents, _T("\n\\pard{\\tab ")); //, chapterNo, sectionNo);
1310            else
1311              wxFprintf(Contents, _T("\\par\n\\pard{\\b ")); //, sectionNo);
1312          }
1313        }
1314        else SetCurrentOutput(NULL);
1315      }
1316
1317      if (startedSections)
1318      {
1319        if (winHelp)
1320          wxFprintf(Sections, _T("\\page\n"));
1321      }
1322      startedSections = true;
1323
1324      if (winHelp)
1325        wxFprintf(Sections, _T("\n${\\footnote "));
1326
1327      // Output heading to contents page
1328      if (!InPopups())
1329        OutputCurrentSection();
1330
1331      if (winHelp)
1332      {
1333        if (!InPopups())
1334        {
1335          wxFprintf(jumpFrom, _T("}{\\v %s}\\pard\\par\n"), topicName);
1336          //WriteEnvironmentStyles();
1337        }
1338      }
1339      else if ((macroId != ltSECTIONSTAR) && (macroId != ltGLOSS))
1340      {
1341        if (DocumentStyle == LATEX_REPORT)
1342          wxFprintf(Contents, _T("}\\par\\pard\n"));
1343        else
1344          wxFprintf(Contents, _T("}\\par\\par\\pard\n"));
1345      }
1346
1347      SetCurrentOutput(winHelp ? Sections : Chapters);
1348
1349      if (winHelp)
1350      {
1351        wxFprintf(Sections, _T("}\n#{\\footnote %s}\n"), topicName);
1352        wxFprintf(Sections, _T("+{\\footnote %s}\n"), GetBrowseString());
1353        OutputSectionKeyword(Sections);
1354        GenerateKeywordsForTopic(topicName);
1355        if (useUpButton)
1356        {
1357          if (DocumentStyle == LATEX_ARTICLE)
1358          {
1359            wxFprintf(Sections, _T("!{\\footnote EnableButton(\"Up\");ChangeButtonBinding(\"Up\", \"JumpId(`%s.hlp', `%s')\")}\n"),
1360               wxFileNameFromPath(FileRoot), _T("Contents"));
1361          }
1362          else if (CurrentChapterName)
1363          {
1364            wxFprintf(Sections, _T("!{\\footnote EnableButton(\"Up\");ChangeButtonBinding(\"Up\", \"JumpId(`%s.hlp', `%s')\")}\n"),
1365               wxFileNameFromPath(FileRoot), CurrentChapterName);
1366          }
1367        }
1368      }
1369
1370      if (!InPopups())
1371      {
1372      wxChar *styleCommand = _T("");
1373      if (!winHelp && useHeadingStyles && (macroId != ltSECTIONSTAR))
1374      {
1375        if (DocumentStyle == LATEX_ARTICLE)
1376          styleCommand = _T("\\s1");
1377        else
1378          styleCommand = _T("\\s2");
1379      }
1380      wxChar *keep = _T("");
1381      if (winHelp && (macroId != ltGLOSS) && !InPopups())
1382        keep = _T("\\keepn\\sa140\\sb140");
1383
1384      wxFprintf(winHelp ? Sections : Chapters, _T("\\pard{%s%s"),
1385         keep, styleCommand);
1386
1387      WriteHeadingStyle((winHelp ? Sections : Chapters),
1388                        (DocumentStyle == LATEX_ARTICLE ? 1 : 2));
1389      wxFprintf(winHelp ? Sections : Chapters, _T(" "));
1390
1391      if (!winHelp)
1392      {
1393        if ((macroId != ltSECTIONSTAR) && (macroId != ltSECTIONHEADINGSTAR) && (macroId != ltGLOSS))
1394        {
1395          if (DocumentStyle == LATEX_REPORT)
1396          {
1397            if (useWord)
1398//              wxFprintf(Chapters, _T("{\\bkmkstart %s}%d.%d{\\bkmkend %s}. "), topicName, chapterNo, sectionNo,
1399              wxFprintf(Chapters, _T("{\\bkmkstart %s}{\\bkmkend %s}"), topicName,
1400                  topicName);
1401            else
1402              wxFprintf(Chapters, _T("%d.%d. "), chapterNo, sectionNo);
1403          }
1404          else
1405          {
1406            if (useWord)
1407//              wxFprintf(Chapters, "{\\bkmkstart %s}%d{\\bkmkend %s}. ", topicName, sectionNo,
1408              wxFprintf(Chapters, _T("{\\bkmkstart %s}{\\bkmkend %s}"), topicName,
1409                 topicName);
1410            else
1411              wxFprintf(Chapters, _T("%d. "), sectionNo);
1412          }
1413        }
1414        else if ( useWord )
1415        {
1416              wxFprintf(Chapters, _T("{\\bkmkstart %s}{\\bkmkend %s}"), topicName, topicName);
1417        }
1418      }
1419      OutputCurrentSection();
1420      TexOutput(_T("\\par\\pard}\n"));
1421//      TexOutput(_T("\\par\\pard}\\par\n"));
1422      }
1423      issuedNewParagraph = 1;
1424      WriteEnvironmentStyles();
1425//      issuedNewParagraph = 2;
1426    }
1427    break;
1428  }
1429  case ltSUBSECTION:
1430  case ltSUBSECTIONSTAR:
1431  case ltMEMBERSECTION:
1432  case ltFUNCTIONSECTION:
1433  {
1434    if (!start)
1435    {
1436      if (winHelp && !Sections)
1437      {
1438        OnError(_T("You cannot have a subsection before a section!"));
1439      }
1440      else
1441      {
1442      subsubsectionNo = 0;
1443
1444      if (macroId != ltSUBSECTIONSTAR)
1445        subsectionNo ++;
1446
1447      wxChar *topicName = FindTopicName(GetNextChunk());
1448      SetCurrentSubsectionName(topicName);
1449      NotifyParentHasChildren(2);
1450      if (winHelpContents && winHelp && !InPopups())
1451      {
1452        OutputCurrentSectionToString(wxTex2RTFBuffer);
1453        WriteWinHelpContentsFileLine(topicName, wxTex2RTFBuffer, 3);
1454      }
1455      AddTexRef(topicName, NULL, SectionNameString, chapterNo, sectionNo, subsectionNo);
1456
1457      if (winHelp)
1458      {
1459        SetCurrentOutputs(Sections, Subsections);
1460        SetCurrentOutputs(Sections, Subsections);
1461        if (!InPopups())
1462          wxFprintf(Sections, _T("\n{\\uldb "));
1463      }
1464      else
1465      {
1466        if ((macroId != ltSUBSECTIONSTAR) && (macroId != ltMEMBERSECTION) &&
1467            (macroId != ltFUNCTIONSECTION))
1468        {
1469          SetCurrentOutput(Contents);
1470          if (DocumentStyle == LATEX_REPORT)
1471            wxFprintf(Contents, _T("\n\\pard\\tab\\tab %d.%d.%d\\tab "), chapterNo, sectionNo, subsectionNo);
1472          else
1473            wxFprintf(Contents, _T("\n\\pard\\tab %d.%d\\tab "), sectionNo, subsectionNo);
1474        } else SetCurrentOutput(NULL);
1475      }
1476      if (startedSections)
1477      {
1478        if (winHelp)
1479        {
1480          if (!InPopups())
1481            wxFprintf(Subsections, _T("\\page\n"));
1482        }
1483        // Experimental JACS 2004-02-21
1484#if 0
1485        else
1486          wxFprintf(Chapters, _T("\\par\n"));
1487#endif
1488      }
1489      startedSections = true;
1490
1491      if (winHelp)
1492        wxFprintf(Subsections, _T("\n${\\footnote "));
1493
1494      // Output to contents page
1495      if (!InPopups())
1496        OutputCurrentSection();
1497
1498      if (winHelp)
1499      {
1500        if (!InPopups())
1501        {
1502          wxFprintf(Sections, _T("}{\\v %s}\\pard\\par\n"), topicName);
1503          //WriteEnvironmentStyles();
1504        }
1505      }
1506      else if ((macroId != ltSUBSECTIONSTAR) && (macroId != ltMEMBERSECTION) &&
1507         (macroId != ltFUNCTIONSECTION))
1508        wxFprintf(Contents, _T("\\par\\pard\n"));
1509
1510      SetCurrentOutput(winHelp ? Subsections : Chapters);
1511      if (winHelp)
1512      {
1513        wxFprintf(Subsections, _T("}\n#{\\footnote %s}\n"), topicName);
1514        wxFprintf(Subsections, _T("+{\\footnote %s}\n"), GetBrowseString());
1515        OutputSectionKeyword(Subsections);
1516        GenerateKeywordsForTopic(topicName);
1517        if (useUpButton && CurrentSectionName)
1518        {
1519          wxFprintf(Subsections, _T("!{\\footnote EnableButton(\"Up\");ChangeButtonBinding(\"Up\", \"JumpId(`%s.hlp', `%s')\")}\n"),
1520             wxFileNameFromPath(FileRoot), CurrentSectionName);
1521        }
1522      }
1523      if (!winHelp && indexSubsections && useWord)
1524      {
1525        // Insert index entry for this subsection
1526        TexOutput(_T("{\\xe\\v {"));
1527        OutputCurrentSection();
1528        TexOutput(_T("}}"));
1529      }
1530
1531      if (!InPopups())
1532      {
1533      wxChar *styleCommand = _T("");
1534      if (!winHelp && useHeadingStyles && (macroId != ltSUBSECTIONSTAR))
1535      {
1536        if (DocumentStyle == LATEX_ARTICLE)
1537          styleCommand = _T("\\s2");
1538        else
1539          styleCommand = _T("\\s3");
1540      }
1541      wxChar *keep = _T("");
1542      if (winHelp && !InPopups())
1543        keep = _T("\\keepn\\sa140\\sb140");
1544
1545      wxFprintf(winHelp ? Subsections : Chapters, _T("\\pard{%s%s"),
1546         keep, styleCommand);
1547
1548      WriteHeadingStyle((winHelp ? Subsections : Chapters),
1549                        (DocumentStyle == LATEX_ARTICLE ? 2 : 3));
1550      wxFprintf(winHelp ? Subsections : Chapters, _T(" "));
1551
1552      if (!winHelp)
1553      {
1554        if ((macroId != ltSUBSECTIONSTAR) && (macroId != ltMEMBERSECTION) &&
1555         (macroId != ltFUNCTIONSECTION))
1556        {
1557          if (DocumentStyle == LATEX_REPORT)
1558          {
1559            if (useWord)
1560//              wxFprintf(Chapters, _T("{\\bkmkstart %s}%d.%d.%d{\\bkmkend %s}. "), topicName, chapterNo, sectionNo, subsectionNo,
1561              wxFprintf(Chapters, _T("{\\bkmkstart %s}{\\bkmkend %s}"), topicName,
1562                       topicName);
1563            else
1564              wxFprintf(Chapters, _T("%d.%d.%d. "), chapterNo, sectionNo, subsectionNo);
1565          }
1566          else
1567          {
1568            if (useWord)
1569//              wxFprintf(Chapters, _T("{\\bkmkstart %s}%d.%d{\\bkmkend %s}. "), topicName, sectionNo, subsectionNo,
1570              wxFprintf(Chapters, _T("{\\bkmkstart %s}{\\bkmkend %s}"), topicName,
1571                       topicName);
1572            else
1573              wxFprintf(Chapters, _T("%d.%d. "), sectionNo, subsectionNo);
1574          }
1575        }
1576        else if ( useWord )
1577        {
1578              wxFprintf(Chapters, _T("{\\bkmkstart %s}{\\bkmkend %s}"), topicName, topicName);
1579        }
1580      }
1581      OutputCurrentSection(); // Repeat section header
1582
1583      // Experimental JACS
1584      TexOutput(_T("\\par\\pard}\n"));
1585      // TexOutput(_T("\\par\\pard}\\par\n"));
1586      }
1587      issuedNewParagraph = 1;
1588      WriteEnvironmentStyles();
1589    }
1590    }
1591    break;
1592  }
1593  case ltSUBSUBSECTION:
1594  case ltSUBSUBSECTIONSTAR:
1595  {
1596    if (!start)
1597    {
1598      if (winHelp && !Subsections)
1599      {
1600        OnError(_T("You cannot have a subsubsection before a subsection!"));
1601      }
1602      else
1603      {
1604      if (macroId != ltSUBSUBSECTIONSTAR)
1605        subsubsectionNo ++;
1606
1607      wxChar *topicName = FindTopicName(GetNextChunk());
1608      SetCurrentTopic(topicName);
1609      NotifyParentHasChildren(3);
1610      if (winHelpContents && winHelp)
1611      {
1612        OutputCurrentSectionToString(wxTex2RTFBuffer);
1613        WriteWinHelpContentsFileLine(topicName, wxTex2RTFBuffer, 4);
1614      }
1615      AddTexRef(topicName, NULL, SectionNameString, chapterNo, sectionNo, subsectionNo, subsubsectionNo);
1616
1617      if (winHelp)
1618      {
1619        SetCurrentOutputs(Subsections, Subsubsections);
1620        wxFprintf(Subsections, _T("\n{\\uldb "));
1621      }
1622      else
1623      {
1624        if (macroId != ltSUBSUBSECTIONSTAR)
1625        {
1626          if (DocumentStyle == LATEX_ARTICLE)
1627          {
1628            SetCurrentOutput(Contents);
1629            wxFprintf(Contents, _T("\n\\tab\\tab %d.%d.%d\\tab "),
1630                               sectionNo, subsectionNo, subsubsectionNo);
1631          }
1632          else
1633            SetCurrentOutput(NULL); // Don't write it into the contents, or anywhere else
1634        }
1635        else
1636          SetCurrentOutput(NULL); // Don't write it into the contents, or anywhere else
1637      }
1638
1639      if (startedSections)
1640      {
1641        if (winHelp)
1642          wxFprintf(Subsubsections, _T("\\page\n"));
1643        // Experimental JACS 2004-02-21
1644#if 0
1645        else
1646          wxFprintf(Chapters, _T("\\par\n"));
1647#endif
1648      }
1649
1650      startedSections = true;
1651
1652      if (winHelp)
1653        wxFprintf(Subsubsections, _T("\n${\\footnote "));
1654
1655      // Output header to contents page
1656      OutputCurrentSection();
1657
1658      if (winHelp)
1659      {
1660        wxFprintf(Subsections, _T("}{\\v %s}\\pard\\par\n"), topicName);
1661        //WriteEnvironmentStyles();
1662      }
1663      else if ((DocumentStyle == LATEX_ARTICLE) && (macroId != ltSUBSUBSECTIONSTAR))
1664        wxFprintf(Contents, _T("\\par\\pard\n"));
1665
1666      SetCurrentOutput(winHelp ? Subsubsections : Chapters);
1667      if (winHelp)
1668      {
1669        wxFprintf(Subsubsections, _T("}\n#{\\footnote %s}\n"), topicName);
1670        wxFprintf(Subsubsections, _T("+{\\footnote %s}\n"), GetBrowseString());
1671        OutputSectionKeyword(Subsubsections);
1672        GenerateKeywordsForTopic(topicName);
1673        if (useUpButton && CurrentSubsectionName)
1674        {
1675          wxFprintf(Subsubsections, _T("!{\\footnote EnableButton(\"Up\");ChangeButtonBinding(\"Up\", \"JumpId(`%s.hlp', `%s')\")}\n"),
1676             wxFileNameFromPath(FileRoot), CurrentSubsectionName);
1677        }
1678      }
1679      if (!winHelp && indexSubsections && useWord)
1680      {
1681        // Insert index entry for this subsubsection
1682        TexOutput(_T("{\\xe\\v {"));
1683        OutputCurrentSection();
1684        TexOutput(_T("}}"));
1685      }
1686
1687      wxChar *styleCommand = _T("");
1688      if (!winHelp && useHeadingStyles && (macroId != ltSUBSUBSECTIONSTAR))
1689      {
1690        if (DocumentStyle == LATEX_ARTICLE)
1691          styleCommand = _T("\\s3");
1692        else
1693          styleCommand = _T("\\s4");
1694      }
1695      wxChar *keep = _T("");
1696      if (winHelp)
1697        keep = _T("\\keepn\\sa140\\sb140");
1698
1699      wxFprintf(winHelp ? Subsubsections : Chapters, _T("\\pard{%s%s"),
1700         keep, styleCommand);
1701
1702      WriteHeadingStyle((winHelp ? Subsubsections : Chapters),
1703                        (DocumentStyle == LATEX_ARTICLE ? 3 : 4));
1704      wxFprintf(winHelp ? Subsubsections : Chapters, _T(" "));
1705
1706      if (!winHelp)
1707      {
1708        if ((macroId != ltSUBSUBSECTIONSTAR))
1709        {
1710          if (DocumentStyle == LATEX_ARTICLE)
1711          {
1712            if (useWord)
1713//              wxFprintf(Chapters, _T("{\\bkmkstart %s}%d.%d.%d{\\bkmkend %s}. "), topicName, sectionNo, subsectionNo, subsubsectionNo,
1714              wxFprintf(Chapters, _T("{\\bkmkstart %s}{\\bkmkend %s}"), topicName,
1715                     topicName);
1716            else
1717              wxFprintf(Chapters, _T("%d.%d.%d. "), sectionNo, subsectionNo, subsubsectionNo);
1718          }
1719          else
1720          {
1721            if (useWord)
1722//              wxFprintf(Chapters, _T("{\\bkmkstart %s}%d.%d.%d.%d{\\bkmkend %s}. "), topicName, chapterNo, sectionNo, subsectionNo, subsubsectionNo,
1723              wxFprintf(Chapters, _T("{\\bkmkstart %s}{\\bkmkend %s}"), topicName,
1724                      topicName);
1725            else
1726              wxFprintf(Chapters, _T("%d.%d.%d.%d. "), chapterNo, sectionNo, subsectionNo, subsubsectionNo);
1727          }
1728        }
1729        else if ( useWord )
1730        {
1731              wxFprintf(Chapters, _T("{\\bkmkstart %s}{\\bkmkend %s}"), topicName, topicName);
1732        }
1733      }
1734      OutputCurrentSection(); // Repeat section header
1735      TexOutput(_T("\\par\\pard}\n"));
1736      issuedNewParagraph = 1;
1737      WriteEnvironmentStyles();
1738//      TexOutput(_T("\\par\\pard}\\par\n"));
1739//      issuedNewParagraph = 2;
1740    }
1741    }
1742    break;
1743  }
1744  case ltCAPTION:
1745  case ltCAPTIONSTAR:
1746  {
1747    if (!start)
1748    {
1749      wxChar *topicName = FindTopicName(GetNextChunk());
1750      SetCurrentTopic(topicName);
1751
1752      TexOutput(_T("\\pard\\par"));
1753      wxChar figBuf[200];
1754
1755      if (inFigure)
1756      {
1757        figureNo ++;
1758
1759        if (winHelp || !useWord)
1760        {
1761          if (DocumentStyle != LATEX_ARTICLE)
1762            wxSnprintf(figBuf, sizeof(figBuf), _T("%s %d.%d: "), FigureNameString, chapterNo, figureNo);
1763          else
1764            wxSnprintf(figBuf, sizeof(figBuf), _T("%s %d: "), FigureNameString, figureNo);
1765        }
1766        else
1767        {
1768          wxSnprintf(figBuf, sizeof(figBuf), _T("%s {\\field\\flddirty{\\*\\fldinst  SEQ Figure \\\\* ARABIC }{\\fldrslt {\\bkmkstart %s}??{\\bkmkend %s}}}: "),
1769               FigureNameString, topicName, topicName);
1770        }
1771      }
1772      else
1773      {
1774        tableNo ++;
1775
1776        if (winHelp || !useWord)
1777        {
1778          if (DocumentStyle != LATEX_ARTICLE)
1779            wxSnprintf(figBuf, sizeof(figBuf), _T("%s %d.%d: "), TableNameString, chapterNo, tableNo);
1780          else
1781            wxSnprintf(figBuf, sizeof(figBuf), _T("%s %d: "), TableNameString, tableNo);
1782        }
1783        else
1784        {
1785          wxSnprintf(figBuf, sizeof(figBuf), _T("%s {\\field\\flddirty{\\*\\fldinst  SEQ Table \\\\* ARABIC }{\\fldrslt {\\bkmkstart %s}??{\\bkmkend %s}}}: "),
1786               TableNameString, topicName, topicName);
1787        }
1788      }
1789
1790      int n = (inTable ? tableNo : figureNo);
1791      AddTexRef(topicName, NULL, NULL,
1792           ((DocumentStyle != LATEX_ARTICLE) ? chapterNo : n),
1793            ((DocumentStyle != LATEX_ARTICLE) ? n : 0));
1794
1795      if (winHelp)
1796        TexOutput(_T("\\qc{\\b "));
1797      else
1798        TexOutput(_T("\\ql{\\b "));
1799      TexOutput(figBuf);
1800
1801      OutputCurrentSection();
1802
1803      TexOutput(_T("}\\par\\pard\n"));
1804      WriteEnvironmentStyles();
1805    }
1806    break;
1807  }
1808  case ltFUNC:
1809  case ltPFUNC:
1810  {
1811//    SetCurrentOutput(winHelp ? Subsections : Chapters);
1812    if (start)
1813    {
1814      TexOutput(_T("{"));
1815    }
1816    else
1817    {
1818      TexOutput(_T("}\n"));
1819      if (winHelp)
1820      {
1821        TexOutput(_T("K{\\footnote {K} "));
1822        suppressNameDecoration = true;
1823        TraverseChildrenFromChunk(currentMember);
1824        suppressNameDecoration = false;
1825        TexOutput(_T("}\n"));
1826      }
1827      if (!winHelp && useWord)
1828      {
1829        // Insert index entry for this function
1830        TexOutput(_T("{\\xe\\v {"));
1831        suppressNameDecoration = true;  // Necessary so don't print "(\\bf" etc.
1832        TraverseChildrenFromChunk(currentMember);
1833        suppressNameDecoration = false;
1834        TexOutput(_T("}}"));
1835      }
1836    }
1837    break;
1838  }
1839  case ltCLIPSFUNC:
1840  {
1841//    SetCurrentOutput(winHelp ? Subsections : Chapters);
1842    if (start)
1843    {
1844      TexOutput(_T("{"));
1845    }
1846    else
1847    {
1848      TexOutput(_T("}\n"));
1849      if (winHelp)
1850      {
1851        TexOutput(_T("K{\\footnote {K} "));
1852        suppressNameDecoration = true;  // Necessary so don't print "(\\bf" etc.
1853        TraverseChildrenFromChunk(currentMember);
1854        suppressNameDecoration = false;
1855        TexOutput(_T("}\n"));
1856      }
1857      if (!winHelp && useWord)
1858      {
1859        // Insert index entry for this function
1860        TexOutput(_T("{\\xe\\v {"));
1861        suppressNameDecoration = true;  // Necessary so don't print "(\\bf" etc.
1862        TraverseChildrenFromChunk(currentMember);
1863        suppressNameDecoration = false;
1864        TexOutput(_T("}}"));
1865      }
1866    }
1867    break;
1868  }
1869  case ltMEMBER:
1870  {
1871//    SetCurrentOutput(winHelp ? Subsections : Chapters);
1872    if (start)
1873    {
1874      TexOutput(_T("{\\b "));
1875    }
1876    else
1877    {
1878      TexOutput(_T("}\n"));
1879      if (winHelp)
1880      {
1881        TexOutput(_T("K{\\footnote {K} "));
1882        TraverseChildrenFromChunk(currentMember);
1883        TexOutput(_T("}\n"));
1884      }
1885      if (!winHelp && useWord)
1886      {
1887        // Insert index entry for this function
1888        TexOutput(_T("{\\xe\\v {"));
1889        suppressNameDecoration = true;  // Necessary so don't print "(\\bf" etc.
1890        TraverseChildrenFromChunk(currentMember);
1891        suppressNameDecoration = false;
1892        TexOutput(_T("}}"));
1893      }
1894    }
1895    break;
1896  }
1897  case ltDOCUMENT:
1898  {
1899    if (start)
1900      SetCurrentOutput(Chapters);
1901    break;
1902  }
1903  case ltTABLEOFCONTENTS:
1904  {
1905    if (start)
1906    {
1907      if (!winHelp && useWord)
1908      {
1909        // Insert Word for Windows table of contents
1910        TexOutput(_T("\\par\\pard\\pgnrestart\\sect\\titlepg"));
1911
1912       // In linear RTF, same as chapter headings.
1913        wxSnprintf(buf, sizeof(buf), _T("{\\b\\fs%d %s}\\par\\par\\pard\n\n"), chapterFont*2, ContentsNameString);
1914
1915        TexOutput(buf);
1916        wxSnprintf(buf, sizeof(buf), _T("{\\field{\\*\\fldinst TOC \\\\o \"1-%d\" }{\\fldrslt PRESS F9 TO REFORMAT CONTENTS}}\n"), contentsDepth);
1917        TexOutput(buf);
1918//        TexOutput(_T("\\sect\\sectd"));
1919      }
1920      else
1921      {
1922        FILE *fd = wxFopen(ContentsName, _T("r"));
1923        if (fd)
1924        {
1925          int ch = getc(fd);
1926          while (ch != EOF)
1927          {
1928            wxPutc(ch, Chapters);
1929            ch = getc(fd);
1930          }
1931          fclose(fd);
1932        }
1933        else
1934        {
1935          TexOutput(_T("{\\i RUN TEX2RTF AGAIN FOR CONTENTS PAGE}\\par\n"));
1936          OnInform(_T("Run Tex2RTF again to include contents page."));
1937        }
1938      }
1939    }
1940    break;
1941  }
1942  case ltVOID:
1943  {
1944//    if (start)
1945//      TexOutput(_T("{\\b void}"));
1946    break;
1947  }
1948  case ltHARDY:
1949  {
1950    if (start)
1951      TexOutput(_T("{\\scaps HARDY}"));
1952    break;
1953  }
1954  case ltWXCLIPS:
1955  {
1956    if (start)
1957      TexOutput(_T("wxCLIPS"));
1958    break;
1959  }
1960  case ltSPECIALAMPERSAND:
1961  {
1962    if (start)
1963    {
1964      if (inTabular)
1965        TexOutput(_T("\\cell "));
1966      else
1967        TexOutput(_T("&"));
1968    }
1969    break;
1970  }
1971  case ltSPECIALTILDE:
1972  {
1973    if (start)
1974    {
1975      #if 1 // if(inVerbatim)
1976        TexOutput(_T("~"));
1977      #else
1978        TexOutput(_T(" "));
1979      #endif
1980    }
1981    break;
1982  }
1983  case ltBACKSLASHCHAR:
1984  {
1985    if (start)
1986    {
1987      if (inTabular)
1988      {
1989//        TexOutput(_T("\\cell\\row\\trowd\\trgaph108\\trleft-108\n"));
1990        TexOutput(_T("\\cell\\row\\trowd\\trgaph108\n"));
1991        int currentWidth = 0;
1992        for (int i = 0; i < noColumns; i++)
1993        {
1994          currentWidth += TableData[i].width;
1995          if (TableData[i].rightBorder)
1996            TexOutput(_T("\\clbrdrr\\brdrs\\brdrw15"));
1997
1998          if (TableData[i].leftBorder)
1999            TexOutput(_T("\\clbrdrl\\brdrs\\brdrw15"));
2000
2001          wxSnprintf(buf, sizeof(buf), _T("\\cellx%d"), currentWidth);
2002          TexOutput(buf);
2003        }
2004        TexOutput(_T("\\pard\\intbl\n"));
2005      }
2006      else
2007        TexOutput(_T("\\line\n"));
2008    }
2009    break;
2010  }
2011  case ltRANGLEBRA:
2012  {
2013    if (start)
2014      TexOutput(_T("\tab "));
2015    break;
2016  }
2017  case ltRTFSP:  // Explicit space, RTF only
2018  {
2019    if (start)
2020      TexOutput(_T(" "));
2021   break;
2022  }
2023  case ltITEMIZE:
2024  case ltENUMERATE:
2025  case ltDESCRIPTION:
2026  {
2027    if (start)
2028    {
2029      if (indentLevel > 0)
2030      {
2031        // Experimental JACS 2004-02-21
2032        TexOutput(_T("\\par\n"));
2033        issuedNewParagraph = 1;
2034//        TexOutput(_T("\\par\\par\n"));
2035//        issuedNewParagraph = 2;
2036      }
2037      else
2038      {
2039        // Top-level list: issue a new paragraph if we haven't
2040        // just done so
2041        if (!issuedNewParagraph)
2042        {
2043          TexOutput(_T("\\par\\pard"));
2044          WriteEnvironmentStyles();
2045          issuedNewParagraph = 1;
2046        }
2047        else issuedNewParagraph = 0;
2048      }
2049      indentLevel ++;
2050      TexOutput(_T("\\fi0\n"));
2051      int listType;
2052      if (macroId == ltENUMERATE)
2053        listType = LATEX_ENUMERATE;
2054      else if (macroId == ltITEMIZE)
2055        listType = LATEX_ITEMIZE;
2056      else
2057        listType = LATEX_DESCRIPTION;
2058
2059      int oldIndent = 0;
2060      wxNode *node = itemizeStack.GetFirst();
2061      if (node)
2062        oldIndent = ((ItemizeStruc *)node->GetData())->indentation;
2063
2064      int indentSize1 = oldIndent + 20*labelIndentTab;
2065      int indentSize2 = oldIndent + 20*itemIndentTab;
2066
2067      ItemizeStruc *struc = new ItemizeStruc(listType, indentSize2, indentSize1);
2068      itemizeStack.Insert(struc);
2069
2070      wxSnprintf(buf, sizeof(buf), _T("\\tx%d\\tx%d\\li%d\\sa200"), indentSize1, indentSize2, indentSize2);
2071      PushEnvironmentStyle(buf);
2072    }
2073    else
2074    {
2075      currentItemSep = 8; // Reset to the default
2076      indentLevel --;
2077      PopEnvironmentStyle();
2078
2079      if (itemizeStack.GetFirst())
2080      {
2081        ItemizeStruc *struc = (ItemizeStruc *)itemizeStack.GetFirst()->GetData();
2082        delete struc;
2083        delete itemizeStack.GetFirst();
2084      }
2085/* Change 18/7/97 - don't know why we wish to do this
2086      if (itemizeStack.Number() == 0)
2087      {
2088        OnMacro(ltPAR, 0, true);
2089        OnMacro(ltPAR, 0, false);
2090        issuedNewParagraph = 2;
2091      }
2092*/
2093    }
2094    break;
2095  }
2096  case ltTWOCOLLIST:
2097  {
2098    if (start)
2099    {
2100      indentLevel ++;
2101      int oldIndent = 0;
2102      wxNode *node = itemizeStack.GetFirst();
2103      if (node)
2104        oldIndent = ((ItemizeStruc *)node->GetData())->indentation;
2105
2106      int indentSize = oldIndent + TwoColWidthA;
2107
2108      ItemizeStruc *struc = new ItemizeStruc(LATEX_TWOCOL, indentSize);
2109      itemizeStack.Insert(struc);
2110
2111//      wxSnprintf(buf, sizeof(buf), _T("\\tx%d\\li%d\\ri%d"), indentSize, indentSize, TwoColWidthA+TwoColWidthB+oldIndent);
2112      wxSnprintf(buf, sizeof(buf), _T("\\tx%d\\li%d\\sa200"), indentSize, indentSize);
2113      PushEnvironmentStyle(buf);
2114    }
2115    else
2116    {
2117      indentLevel --;
2118      PopEnvironmentStyle();
2119      if (itemizeStack.GetFirst())
2120      {
2121        ItemizeStruc *struc = (ItemizeStruc *)itemizeStack.GetFirst()->GetData();
2122        delete struc;
2123        delete itemizeStack.GetFirst();
2124      }
2125/*
2126      // JACS June 1997
2127      TexOutput(_T("\\pard\n"));
2128      WriteEnvironmentStyles();
2129*/
2130/* why do we need this? */
2131// Experimental
2132      TexOutput(_T("\\pard\n"));
2133#if 0
2134      if (itemizeStack.GetCount() == 0)
2135      {
2136        issuedNewParagraph = 0;
2137        OnMacro(ltPAR, 0, true);
2138        OnMacro(ltPAR, 0, false);
2139      }
2140#endif
2141    }
2142    break;
2143  }
2144  case ltITEM:
2145  {
2146    wxNode *node = itemizeStack.GetFirst();
2147    if (node)
2148    {
2149      ItemizeStruc *struc = (ItemizeStruc *)node->GetData();
2150      if (!start)
2151      {
2152        struc->currentItem += 1;
2153        wxChar indentBuf[60];
2154
2155        int indentSize1 = struc->labelIndentation;
2156        int indentSize2 = struc->indentation;
2157
2158        TexOutput(_T("\n"));
2159        if (struc->currentItem > 1 && issuedNewParagraph == 0)
2160        {
2161            // JACS
2162//          if (currentItemSep > 0)
2163//            TexOutput(_T("\\par"));
2164
2165          TexOutput(_T("\\par"));
2166          issuedNewParagraph = 1;
2167//          WriteEnvironmentStyles();
2168        }
2169
2170        wxSnprintf(buf, sizeof(buf), _T("\\tx%d\\tx%d\\li%d\\fi-%d\n"), indentSize1, indentSize2,
2171                  indentSize2, 20*itemIndentTab);
2172        TexOutput(buf);
2173
2174        switch (struc->listType)
2175        {
2176          case LATEX_ENUMERATE:
2177          {
2178            if (descriptionItemArg)
2179            {
2180              TexOutput(_T("\\tab{ "));
2181              TraverseChildrenFromChunk(descriptionItemArg);
2182              TexOutput(_T("}\\tab"));
2183              descriptionItemArg = NULL;
2184            }
2185            else
2186            {
2187              wxSnprintf(indentBuf, sizeof(indentBuf), _T("\\tab{\\b %d.}\\tab"), struc->currentItem);
2188              TexOutput(indentBuf);
2189            }
2190            break;
2191          }
2192          case LATEX_ITEMIZE:
2193          {
2194            if (descriptionItemArg)
2195            {
2196              TexOutput(_T("\\tab{ "));
2197              TraverseChildrenFromChunk(descriptionItemArg);
2198              TexOutput(_T("}\\tab"));
2199              descriptionItemArg = NULL;
2200            }
2201          else
2202            {
2203              if (bulletFile && winHelp)
2204              {
2205                if (winHelpVersion > 3) // Transparent bitmap
2206                  wxSnprintf(indentBuf, sizeof(indentBuf), _T("\\tab\\{bmct %s\\}\\tab"), bulletFile);
2207                else
2208                  wxSnprintf(indentBuf, sizeof(indentBuf), _T("\\tab\\{bmc %s\\}\\tab"), bulletFile);
2209              }
2210              else if (winHelp)
2211                wxSnprintf(indentBuf, sizeof(indentBuf), _T("\\tab{\\b o}\\tab"));
2212              else
2213                wxSnprintf(indentBuf, sizeof(indentBuf), _T("\\tab{\\f1\\'b7}\\tab"));
2214              TexOutput(indentBuf);
2215            }
2216            break;
2217          }
2218          default:
2219          case LATEX_DESCRIPTION:
2220          {
2221            if (descriptionItemArg)
2222            {
2223              TexOutput(_T("\\tab{\\b "));
2224              TraverseChildrenFromChunk(descriptionItemArg);
2225              TexOutput(_T("}  "));
2226              descriptionItemArg = NULL;
2227            }
2228            break;
2229          }
2230        }
2231      }
2232    }
2233    break;
2234  }
2235  case ltTWOCOLITEM:
2236  case ltTWOCOLITEMRULED:
2237  {
2238    wxNode *node = itemizeStack.GetFirst();
2239    if (node)
2240    {
2241      ItemizeStruc *struc = (ItemizeStruc *)node->GetData();
2242      if (start)
2243      {
2244        struc->currentItem += 1;
2245
2246        int oldIndent = 0;
2247        wxNode *node2 = NULL;
2248        if (itemizeStack.GetCount() > 1) // TODO: do I actually mean Nth(0) here??
2249            node2 = itemizeStack.Item(1);
2250        if (node2)
2251          oldIndent = ((ItemizeStruc *)node2->GetData())->indentation;
2252
2253        TexOutput(_T("\n"));
2254        // JACS
2255#if 0
2256        if (struc->currentItem > 1)
2257        {
2258          if (currentItemSep > 0)
2259            TexOutput(_T("\\par"));
2260
2261//          WriteEnvironmentStyles();
2262        }
2263#endif
2264
2265//        wxSnprintf(buf, sizeof(buf), _T("\\tx%d\\li%d\\fi-%d\\ri%d\n"), TwoColWidthA,
2266//             TwoColWidthA, TwoColWidthA, TwoColWidthA+TwoColWidthB+oldIndent);
2267/*
2268        wxSnprintf(buf, sizeof(buf), _T("\\tx%d\\li%d\\fi-%d\n"), TwoColWidthA,
2269             TwoColWidthA, TwoColWidthA);
2270*/
2271        wxSnprintf(buf, sizeof(buf), _T("\\tx%d\\li%d\\fi-%d\n"), TwoColWidthA + oldIndent,
2272             TwoColWidthA + oldIndent, TwoColWidthA);
2273        TexOutput(buf);
2274      }
2275    }
2276    break;
2277  }
2278  case ltVERBATIM:
2279  case ltVERB:
2280  {
2281    if (start)
2282    {
2283        // JACS
2284#if 0
2285      if (macroId == ltVERBATIM)
2286      {
2287        if (!issuedNewParagraph)
2288        {
2289          TexOutput(_T("\\par\\pard"));
2290          WriteEnvironmentStyles();
2291          issuedNewParagraph = 1;
2292        }
2293        else issuedNewParagraph = 0;
2294      }
2295#endif
2296
2297      if (macroId == ltVERBATIM)
2298        wxSnprintf(buf, sizeof(buf), _T("{\\f3\\s10\\fs20\\li720\\sa0 "));
2299      else
2300        wxSnprintf(buf, sizeof(buf), _T("{\\f3\\fs20 "));
2301      TexOutput(buf);
2302    }
2303    else
2304    {
2305      TexOutput(_T("}"));
2306      if (macroId == ltVERBATIM)
2307      {
2308        TexOutput(_T("\\pard\n"));
2309        WriteEnvironmentStyles();
2310        // JACS
2311#if 0
2312        TexOutput(_T("\\par\n"));
2313        issuedNewParagraph = 1;
2314#endif
2315      }
2316    }
2317    break;
2318  }
2319  case ltCENTERLINE:
2320  case ltCENTER:
2321  {
2322    if (start)
2323    {
2324      TexOutput(_T("\\qc "));
2325      forbidParindent ++;
2326      PushEnvironmentStyle(_T("\\qc\\sa200"));
2327    }
2328    else
2329    {
2330      TexOutput(_T("\\par\\pard\n"));
2331      issuedNewParagraph = 1;
2332      forbidParindent --;
2333      PopEnvironmentStyle();
2334      WriteEnvironmentStyles();
2335    }
2336    break;
2337  }
2338  case ltFLUSHLEFT:
2339  {
2340    if (start)
2341    {
2342      TexOutput(_T("\\ql\\sa200 "));
2343      forbidParindent ++;
2344      PushEnvironmentStyle(_T("\\ql"));
2345    }
2346    else
2347    {
2348      TexOutput(_T("\\par\\pard\n"));
2349      issuedNewParagraph = 1;
2350      forbidParindent --;
2351      PopEnvironmentStyle();
2352      WriteEnvironmentStyles();
2353    }
2354    break;
2355  }
2356  case ltFLUSHRIGHT:
2357  {
2358    if (start)
2359    {
2360      TexOutput(_T("\\qr\\sa200 "));
2361      forbidParindent ++;
2362      PushEnvironmentStyle(_T("\\qr"));
2363    }
2364    else
2365    {
2366      TexOutput(_T("\\par\\pard\n"));
2367      issuedNewParagraph = 1;
2368      forbidParindent --;
2369      PopEnvironmentStyle();
2370      WriteEnvironmentStyles();
2371    }
2372    break;
2373  }
2374  case ltSMALL:
2375  case ltFOOTNOTESIZE:
2376  {
2377    if (start)
2378    {
2379      wxSnprintf(buf, sizeof(buf), _T("{\\fs%d\n"), smallFont*2);
2380      TexOutput(buf);
2381    }
2382    else TexOutput(_T("}\n"));
2383    break;
2384  }
2385  case ltTINY:
2386  case ltSCRIPTSIZE:
2387  {
2388    if (start)
2389    {
2390      wxSnprintf(buf, sizeof(buf), _T("{\\fs%d\n"), tinyFont*2);
2391      TexOutput(buf);
2392    }
2393    else TexOutput(_T("}\n"));
2394    break;
2395  }
2396  case ltNORMALSIZE:
2397  {
2398    if (start)
2399    {
2400      wxSnprintf(buf, sizeof(buf), _T("{\\fs%d\n"), normalFont*2);
2401      TexOutput(buf);
2402    }
2403    else TexOutput(_T("}\n"));
2404    break;
2405  }
2406  case ltlarge:
2407  {
2408    if (start)
2409    {
2410      wxSnprintf(buf, sizeof(buf), _T("{\\fs%d\n"), largeFont1*2);
2411      TexOutput(buf);
2412    }
2413    else TexOutput(_T("}\n"));
2414    break;
2415  }
2416  case ltLarge:
2417  {
2418    if (start)
2419    {
2420      wxSnprintf(buf, sizeof(buf), _T("{\\fs%d\n"), LargeFont2*2);
2421      TexOutput(buf);
2422    }
2423    else TexOutput(_T("}\n"));
2424    break;
2425  }
2426  case ltLARGE:
2427  {
2428    if (start)
2429    {
2430      wxSnprintf(buf, sizeof(buf), _T("{\\fs%d\n"), LARGEFont3*2);
2431      TexOutput(buf);
2432    }
2433    else TexOutput(_T("}\n"));
2434    break;
2435  }
2436  case lthuge:
2437  {
2438    if (start)
2439    {
2440      wxSnprintf(buf, sizeof(buf), _T("{\\fs%d\n"), hugeFont1*2);
2441      TexOutput(buf);
2442    }
2443    else TexOutput(_T("}\n"));
2444    break;
2445  }
2446  case ltHuge:
2447  {
2448    if (start)
2449    {
2450      wxSnprintf(buf, sizeof(buf), _T("{\\fs%d\n"), HugeFont2*2);
2451      TexOutput(buf);
2452    }
2453    else TexOutput(_T("}\n"));
2454    break;
2455  }
2456  case ltHUGE:
2457  {
2458    if (start)
2459    {
2460      wxSnprintf(buf, sizeof(buf), _T("{\\fs%d\n"), HUGEFont3*2);
2461      TexOutput(buf);
2462    }
2463    else TexOutput(_T("}\n"));
2464    break;
2465  }
2466  case ltTEXTBF:
2467  case ltBFSERIES:
2468  case ltBF:
2469  {
2470    if (start)
2471    {
2472      TexOutput(_T("{\\b "));
2473    }
2474    else TexOutput(_T("}"));
2475    break;
2476  }
2477  case ltUNDERLINE:
2478  {
2479    if (start)
2480    {
2481      TexOutput(_T("{\\ul "));
2482    }
2483    else TexOutput(_T("}"));
2484    break;
2485  }
2486  case ltTEXTIT:
2487  case ltITSHAPE:
2488  case ltIT:
2489  case ltEMPH:
2490  case ltEM:
2491  {
2492    if (start)
2493    {
2494      TexOutput(_T("{\\i "));
2495    }
2496    else TexOutput(_T("}"));
2497    break;
2498  }
2499  // Roman font: do nothing. Should really switch between
2500  // fonts.
2501  case ltTEXTRM:
2502  case ltRMFAMILY:
2503  case ltRM:
2504  {
2505/*
2506    if (start)
2507    {
2508      TexOutput(_T("{\\plain "));
2509    }
2510    else TexOutput(_T("}"));
2511 */
2512    break;
2513  }
2514  // Medium-weight font. Unbolden...
2515  case ltMDSERIES:
2516  {
2517    if (start)
2518    {
2519      TexOutput(_T("{\\b0 "));
2520    }
2521    else TexOutput(_T("}"));
2522    break;
2523  }
2524  // Upright (un-italic or slant)
2525  case ltUPSHAPE:
2526  {
2527    if (start)
2528    {
2529      TexOutput(_T("{\\i0 "));
2530    }
2531    else TexOutput(_T("}"));
2532    break;
2533  }
2534  case ltTEXTSC:
2535  case ltSCSHAPE:
2536  case ltSC:
2537  {
2538    if (start)
2539    {
2540      TexOutput(_T("{\\scaps "));
2541    }
2542    else TexOutput(_T("}"));
2543    break;
2544  }
2545  case ltTEXTTT:
2546  case ltTTFAMILY:
2547  case ltTT:
2548  {
2549    if (start)
2550    {
2551      TexOutput(_T("{\\f3 "));
2552    }
2553    else TexOutput(_T("}"));
2554    break;
2555  }
2556  case ltLBRACE:
2557  {
2558    if (start)
2559      TexOutput(_T("\\{"));
2560    break;
2561  }
2562  case ltRBRACE:
2563  {
2564    if (start)
2565      TexOutput(_T("\\}"));
2566    break;
2567  }
2568  case ltBACKSLASH:
2569  {
2570    if (start)
2571      TexOutput(_T("\\\\"));
2572    break;
2573  }
2574  case ltPAR:
2575  {
2576    if (start)
2577    {
2578      if ( issuedNewParagraph == 0 )
2579      {
2580          TexOutput(_T("\\par\\pard"));
2581          issuedNewParagraph ++;
2582
2583          // Extra par if parskip is more than zero (usually looks best.)
2584          // N.B. JACS 2004-02-21: shouldn't need this for linear RTF if
2585          // we have a suitable set of styles.
2586#if 0
2587          if (winHelp && !inTabular && (ParSkip > 0))
2588          {
2589            TexOutput(_T("\\par"));
2590            issuedNewParagraph ++;
2591          }
2592#endif
2593          WriteEnvironmentStyles();
2594      }
2595      // 1 is a whole paragraph if ParSkip == 0,
2596      // half a paragraph if ParSkip > 0
2597      else if ( issuedNewParagraph == 1 )
2598      {
2599        // Don't need a par at all if we've already had one,
2600        // and ParSkip == 0.
2601#if 0
2602          // Extra par if parskip is more than zero (usually looks best.)
2603          if (winHelp && !inTabular && (ParSkip > 0))
2604          {
2605            TexOutput(_T("\\par"));
2606            issuedNewParagraph ++;
2607          }
2608#endif
2609          WriteEnvironmentStyles();
2610      }
2611/*
2612      if (!issuedNewParagraph || (issuedNewParagraph > 1))
2613      {
2614        TexOutput(_T("\\par\\pard"));
2615
2616        // Extra par if parskip is more than zero (usually looks best.)
2617        if (!inTabular && (ParSkip > 0))
2618          TexOutput(_T("\\par"));
2619        WriteEnvironmentStyles();
2620      }
2621*/
2622
2623      TexOutput(_T("\n"));
2624    }
2625    break;
2626  }
2627  case ltNEWPAGE:
2628  {
2629    // In Windows Help, no newpages until we've started some chapters or sections
2630    if (!(winHelp && !startedSections))
2631      if (start)
2632        TexOutput(_T("\\page\n"));
2633    break;
2634  }
2635  case ltMAKETITLE:
2636  {
2637    if (start && DocumentTitle)
2638    {
2639      TexOutput(_T("\\par\\pard"));
2640      if (!winHelp)
2641        TexOutput(_T("\\par"));
2642      wxSnprintf(buf, sizeof(buf), _T("\\qc{\\fs%d\\b "), titleFont*2);
2643      TexOutput(buf);
2644      TraverseChildrenFromChunk(DocumentTitle);
2645      TexOutput(_T("}\\par\\pard\n"));
2646
2647      if (DocumentAuthor)
2648      {
2649        if (!winHelp)
2650          TexOutput(_T("\\par"));
2651        wxSnprintf(buf, sizeof(buf), _T("\\par\\qc{\\fs%d "), authorFont*2);
2652        TexOutput(buf);
2653        TraverseChildrenFromChunk(DocumentAuthor);
2654        TexOutput(_T("}"));
2655        TexOutput(_T("\\par\\pard\n"));
2656      }
2657      if (DocumentDate)
2658      {
2659        TexOutput(_T("\\par"));
2660        wxSnprintf(buf, sizeof(buf), _T("\\qc{\\fs%d "), authorFont*2);
2661        TexOutput(buf);
2662        TraverseChildrenFromChunk(DocumentDate);
2663        TexOutput(_T("}\\par\\pard\n"));
2664      }
2665      // If linear RTF, we want this titlepage to be in a separate
2666      // section with its own (blank) header and footer
2667      if (!winHelp && (DocumentStyle != LATEX_ARTICLE))
2668      {
2669        TexOutput(_T("{\\header }{\\footer }\n"));
2670        // Not sure about this: we get too many sections.
2671//        TexOutput(_T("\\sect"));
2672      }
2673    }
2674    break;
2675  }
2676  case ltADDCONTENTSLINE:
2677  {
2678    if (!start)
2679    {
2680    if (contentsLineSection && contentsLineValue)
2681    {
2682      if (wxStrcmp(contentsLineSection, _T("chapter")) == 0)
2683      {
2684        wxFprintf(Contents, _T("\\par\n{\\b %s}\\par\n"), contentsLineValue);
2685      }
2686      else if (wxStrcmp(contentsLineSection, _T("section")) == 0)
2687      {
2688        if (DocumentStyle != LATEX_ARTICLE)
2689          wxFprintf(Contents, _T("\n\\tab%s\\par\n"), contentsLineValue);
2690        else
2691          wxFprintf(Contents, _T("\\par\n{\\b %s}\\par\n"), contentsLineValue);
2692      }
2693    }
2694    }
2695    break;
2696  }
2697  case ltHRULE:
2698  {
2699    if (start)
2700    {
2701      TexOutput(_T("\\brdrb\\brdrs\\par\\pard\n"));
2702      issuedNewParagraph = 1;
2703      WriteEnvironmentStyles();
2704    }
2705    break;
2706  }
2707  case ltRULE:
2708  {
2709    if (start)
2710    {
2711      TexOutput(_T("\\brdrb\\brdrs\\par\\pard\n"));
2712      issuedNewParagraph = 1;
2713      WriteEnvironmentStyles();
2714    }
2715    break;
2716  }
2717  case ltHLINE:
2718  {
2719    if (start)
2720      ruleTop ++;
2721    break;
2722  }
2723  case ltNUMBEREDBIBITEM:
2724  {
2725    if (start)
2726      TexOutput(_T("\\li260\\fi-260 ")); // Indent from 2nd line
2727    else
2728      TexOutput(_T("\\par\\pard\\par\n\n"));
2729    break;
2730  }
2731  case ltTHEPAGE:
2732  {
2733    if (start)
2734    {
2735      TexOutput(_T("{\\field{\\*\\fldinst PAGE \\\\* MERGEFORMAT }{\\fldrslt 1}}"));
2736    }
2737    break;
2738  }
2739  case ltTHECHAPTER:
2740  {
2741    if (start)
2742    {
2743//      TexOutput(_T("{\\field{\\*\\fldinst SECTION \\\\* MERGEFORMAT }{\\fldrslt 1}}"));
2744      wxSnprintf(buf, sizeof(buf), _T("%d"), chapterNo);
2745      TexOutput(buf);
2746    }
2747    break;
2748  }
2749  case ltTHESECTION:
2750  {
2751    if (start)
2752    {
2753//      TexOutput(_T("{\\field{\\*\\fldinst SECTION \\\\* MERGEFORMAT }{\\fldrslt 1}}"));
2754      wxSnprintf(buf, sizeof(buf), _T("%d"), sectionNo);
2755      TexOutput(buf);
2756    }
2757    break;
2758  }
2759  case ltTWOCOLUMN:
2760  {
2761    if (!start && !winHelp)
2762    {
2763      TexOutput(_T("\\cols2\n"));
2764    }
2765    break;
2766  }
2767  case ltONECOLUMN:
2768  {
2769    if (!start && !winHelp)
2770    {
2771      TexOutput(_T("\\cols1\n"));
2772    }
2773    break;
2774  }
2775  case ltPRINTINDEX:
2776  {
2777    if (start && useWord && !winHelp)
2778    {
2779      FakeCurrentSection(_T("Index"));
2780      OnMacro(ltPAR, 0, true);
2781      OnMacro(ltPAR, 0, false);
2782      TexOutput(_T("\\par{\\field{\\*\\fldinst INDEX \\\\h \"\\emdash A\\emdash \"\\\\c \"2\"}{\\fldrslt PRESS F9 TO REFORMAT INDEX}}\n"));
2783    }
2784    break;
2785  }
2786  case ltLISTOFFIGURES:
2787  {
2788    if (start && useWord && !winHelp)
2789    {
2790      FakeCurrentSection(FiguresNameString, false);
2791      OnMacro(ltPAR, 0, true);
2792      OnMacro(ltPAR, 0, false);
2793      OnMacro(ltPAR, 0, true);
2794      OnMacro(ltPAR, 0, false);
2795      wxChar buf[200];
2796      wxSnprintf(buf, sizeof(buf), _T("{\\field\\fldedit{\\*\\fldinst  TOC \\\\c \"%s\" }{\\fldrslt PRESS F9 TO REFORMAT LIST OF FIGURES}}\n"),
2797               FigureNameString);
2798      TexOutput(buf);
2799    }
2800    break;
2801  }
2802  case ltLISTOFTABLES:
2803  {
2804    if (start && useWord && !winHelp)
2805    {
2806      FakeCurrentSection(TablesNameString, false);
2807      OnMacro(ltPAR, 0, true);
2808      OnMacro(ltPAR, 0, false);
2809      OnMacro(ltPAR, 0, true);
2810      OnMacro(ltPAR, 0, false);
2811      wxChar buf[200];
2812      wxSnprintf(buf, sizeof(buf), _T("{\\field\\fldedit{\\*\\fldinst  TOC \\\\c \"%s\" }{\\fldrslt PRESS F9 TO REFORMAT LIST OF TABLES}}\n"),
2813                TablesNameString);
2814      TexOutput(buf);
2815    }
2816    break;
2817  }
2818  // Symbols
2819  case ltALPHA:
2820    if (start) TexOutput(_T("{\\f1\\'61}"));
2821    break;
2822  case ltBETA:
2823    if (start) TexOutput(_T("{\\f1\\'62}"));
2824    break;
2825  case ltGAMMA:
2826    if (start) TexOutput(_T("{\\f1\\'63}"));
2827    break;
2828  case ltDELTA:
2829    if (start) TexOutput(_T("{\\f1\\'64}"));
2830    break;
2831  case ltEPSILON:
2832  case ltVAREPSILON:
2833    if (start) TexOutput(_T("{\\f1\\'65}"));
2834    break;
2835  case ltZETA:
2836    if (start) TexOutput(_T("{\\f1\\'7A}"));
2837    break;
2838  case ltETA:
2839    if (start) TexOutput(_T("{\\f1\\'68}"));
2840    break;
2841  case ltTHETA:
2842  case ltVARTHETA:
2843    if (start) TexOutput(_T("{\\f1\\'71}"));
2844    break;
2845  case ltIOTA:
2846    if (start) TexOutput(_T("{\\f1\\'69}"));
2847    break;
2848  case ltKAPPA:
2849    if (start) TexOutput(_T("{\\f1\\'6B}"));
2850    break;
2851  case ltLAMBDA:
2852    if (start) TexOutput(_T("{\\f1\\'6C}"));
2853    break;
2854  case ltMU:
2855    if (start) TexOutput(_T("{\\f1\\'6D}"));
2856    break;
2857  case ltNU:
2858    if (start) TexOutput(_T("{\\f1\\'6E}"));
2859    break;
2860  case ltXI:
2861    if (start) TexOutput(_T("{\\f1\\'78}"));
2862    break;
2863  case ltPI:
2864    if (start) TexOutput(_T("{\\f1\\'70}"));
2865    break;
2866  case ltVARPI:
2867    if (start) TexOutput(_T("{\\f1\\'76}"));
2868    break;
2869  case ltRHO:
2870  case ltVARRHO:
2871    if (start) TexOutput(_T("{\\f1\\'72}"));
2872    break;
2873  case ltSIGMA:
2874    if (start) TexOutput(_T("{\\f1\\'73}"));
2875    break;
2876  case ltVARSIGMA:
2877    if (start) TexOutput(_T("{\\f1\\'56}"));
2878    break;
2879  case ltTAU:
2880    if (start) TexOutput(_T("{\\f1\\'74}"));
2881    break;
2882  case ltUPSILON:
2883    if (start) TexOutput(_T("{\\f1\\'75}"));
2884    break;
2885  case ltPHI:
2886  case ltVARPHI:
2887    if (start) TexOutput(_T("{\\f1\\'66}"));
2888    break;
2889  case ltCHI:
2890    if (start) TexOutput(_T("{\\f1\\'63}"));
2891    break;
2892  case ltPSI:
2893    if (start) TexOutput(_T("{\\f1\\'79}"));
2894    break;
2895  case ltOMEGA:
2896    if (start) TexOutput(_T("{\\f1\\'77}"));
2897    break;
2898  case ltCAP_GAMMA:
2899    if (start) TexOutput(_T("{\\f1\\'47}"));
2900    break;
2901  case ltCAP_DELTA:
2902    if (start) TexOutput(_T("{\\f1\\'44}"));
2903    break;
2904  case ltCAP_THETA:
2905    if (start) TexOutput(_T("{\\f1\\'51}"));
2906    break;
2907  case ltCAP_LAMBDA:
2908    if (start) TexOutput(_T("{\\f1\\'4C}"));
2909    break;
2910  case ltCAP_XI:
2911    if (start) TexOutput(_T("{\\f1\\'58}"));
2912    break;
2913  case ltCAP_PI:
2914    if (start) TexOutput(_T("{\\f1\\'50}"));
2915    break;
2916  case ltCAP_SIGMA:
2917    if (start) TexOutput(_T("{\\f1\\'53}"));
2918    break;
2919  case ltCAP_UPSILON:
2920    if (start) TexOutput(_T("{\\f1\\'54}"));
2921    break;
2922  case ltCAP_PHI:
2923    if (start) TexOutput(_T("{\\f1\\'46}"));
2924    break;
2925  case ltCAP_PSI:
2926    if (start) TexOutput(_T("{\\f1\\'59}"));
2927    break;
2928  case ltCAP_OMEGA:
2929    if (start) TexOutput(_T("{\\f1\\'57}"));
2930    break;
2931  // Binary operation symbols
2932  case ltLE:
2933  case ltLEQ:
2934    if (start) TexOutput(_T("{\\f1\\'A3}"));
2935    break;
2936  case ltLL:
2937    if (start) TexOutput(_T("<<"));
2938    break;
2939  case ltSUBSET:
2940    if (start) TexOutput(_T("{\\f1\\'CC}"));
2941    break;
2942  case ltSUBSETEQ:
2943    if (start) TexOutput(_T("{\\f1\\'CD}"));
2944    break;
2945  case ltIN:
2946    if (start) TexOutput(_T("{\\f1\\'CE}"));
2947    break;
2948  case ltGE:
2949  case ltGEQ:
2950    if (start) TexOutput(_T("{\\f1\\'B3}"));
2951    break;
2952  case ltGG:
2953    if (start) TexOutput(_T(">>"));
2954    break;
2955  case ltSUPSET:
2956    if (start) TexOutput(_T("{\\f1\\'C9}"));
2957    break;
2958  case ltSUPSETEQ:
2959    if (start) TexOutput(_T("{\\f1\\'CD}"));
2960    break;
2961  case ltNI:
2962    if (start) TexOutput(_T("{\\f1\\'27}"));
2963    break;
2964  case ltPERP:
2965    if (start) TexOutput(_T("{\\f1\\'5E}"));
2966    break;
2967  case ltNEQ:
2968    if (start) TexOutput(_T("{\\f1\\'B9}"));
2969    break;
2970  case ltAPPROX:
2971    if (start) TexOutput(_T("{\\f1\\'BB}"));
2972    break;
2973  case ltCONG:
2974    if (start) TexOutput(_T("{\\f1\\'40}"));
2975    break;
2976  case ltEQUIV:
2977    if (start) TexOutput(_T("{\\f1\\'BA}"));
2978    break;
2979  case ltPROPTO:
2980    if (start) TexOutput(_T("{\\f1\\'B5}"));
2981    break;
2982  case ltSIM:
2983    if (start) TexOutput(_T("{\\f1\\'7E}"));
2984    break;
2985  case ltSMILE:
2986    if (start) TexOutput(_T("{\\f4\\'4A}"));
2987    break;
2988  case ltFROWN:
2989    if (start) TexOutput(_T("{\\f4\\'4C}"));
2990    break;
2991  case ltMID:
2992    if (start) TexOutput(_T("|"));
2993    break;
2994
2995  // Negated relation symbols
2996  case ltNOTEQ:
2997    if (start) TexOutput(_T("{\\f1\\'B9}"));
2998    break;
2999  case ltNOTIN:
3000    if (start) TexOutput(_T("{\\f1\\'CF}"));
3001    break;
3002  case ltNOTSUBSET:
3003    if (start) TexOutput(_T("{\\f1\\'CB}"));
3004    break;
3005
3006  // Arrows
3007  case ltLEFTARROW:
3008     if (start) TexOutput(_T("{\\f1\\'AC}"));
3009    break;
3010  case ltLEFTARROW2:
3011    if (start) TexOutput(_T("{\\f1\\'DC}"));
3012    break;
3013  case ltRIGHTARROW:
3014    if (start) TexOutput(_T("{\\f1\\'AE}"));
3015    break;
3016  case ltRIGHTARROW2:
3017    if (start) TexOutput(_T("{\\f1\\'DE}"));
3018    break;
3019  case ltLEFTRIGHTARROW:
3020    if (start) TexOutput(_T("{\\f1\\'AB}"));
3021    break;
3022  case ltLEFTRIGHTARROW2:
3023    if (start) TexOutput(_T("{\\f1\\'DB}"));
3024    break;
3025  case ltUPARROW:
3026    if (start) TexOutput(_T("{\\f1\\'AD}"));
3027    break;
3028  case ltUPARROW2:
3029    if (start) TexOutput(_T("{\\f1\\'DD}"));
3030    break;
3031  case ltDOWNARROW:
3032    if (start) TexOutput(_T("{\\f1\\'AF}"));
3033    break;
3034  case ltDOWNARROW2:
3035    if (start) TexOutput(_T("{\\f1\\'DF}"));
3036    break;
3037
3038  // Miscellaneous symbols
3039  case ltALEPH:
3040    if (start) TexOutput(_T("{\\f1\\'CO}"));
3041    break;
3042  case ltWP:
3043    if (start) TexOutput(_T("{\\f1\\'C3}"));
3044    break;
3045  case ltRE:
3046    if (start) TexOutput(_T("{\\f1\\'C2}"));
3047    break;
3048  case ltIM:
3049    if (start) TexOutput(_T("{\\f1\\'C1}"));
3050    break;
3051  case ltEMPTYSET:
3052    if (start) TexOutput(_T("{\\f1\\'C6}"));
3053    break;
3054  case ltNABLA:
3055    if (start) TexOutput(_T("{\\f1\\'D1}"));
3056    break;
3057  case ltSURD:
3058    if (start) TexOutput(_T("{\\f1\\'D6}"));
3059    break;
3060  case ltPARTIAL:
3061    if (start) TexOutput(_T("{\\f1\\'B6}"));
3062    break;
3063  case ltBOT:
3064    if (start) TexOutput(_T("{\\f1\\'5E}"));
3065    break;
3066  case ltFORALL:
3067    if (start) TexOutput(_T("{\\f1\\'22}"));
3068    break;
3069  case ltEXISTS:
3070    if (start) TexOutput(_T("{\\f1\\'24}"));
3071    break;
3072  case ltNEG:
3073    if (start) TexOutput(_T("{\\f1\\'D8}"));
3074    break;
3075  case ltSHARP:
3076    if (start) TexOutput(_T("{\\f1\\'23}"));
3077    break;
3078  case ltANGLE:
3079    if (start) TexOutput(_T("{\\f1\\'D0}"));
3080    break;
3081  case ltTRIANGLE:
3082    if (start) TexOutput(_T("{\\f5\\'73}"));
3083    break;
3084  case ltCLUBSUIT:
3085    if (start) TexOutput(_T("{\\f5\\'A8}"));
3086    break;
3087  case ltDIAMONDSUIT:
3088    if (start) TexOutput(_T("{\\f5\\'A9}"));
3089    break;
3090  case ltHEARTSUIT:
3091    if (start) TexOutput(_T("{\\f5\\'AA}"));
3092    break;
3093  case ltSPADESUIT:
3094    if (start) TexOutput(_T("{\\f5\\'AB}"));
3095    break;
3096  case ltINFTY:
3097    if (start) TexOutput(_T("{\\f1\\'A5}"));
3098    break;
3099  case ltCOPYRIGHT:
3100    if (start) TexOutput(_T("{\\f0\\'A9}"));
3101    break;
3102  case ltREGISTERED:
3103    if (start) TexOutput(_T("{\\f0\\'AE}"));
3104    break;
3105  case ltPM:
3106    if (start) TexOutput(_T("{\\f1\\'B1}"));
3107    break;
3108  case ltMP:
3109    if (start) TexOutput(_T("{\\f1\\'B1}"));
3110    break;
3111  case ltTIMES:
3112    if (start) TexOutput(_T("{\\f1\\'B4}"));
3113    break;
3114  case ltDIV:
3115    if (start) TexOutput(_T("{\\f1\\'B8}"));
3116    break;
3117  case ltCDOT:
3118    if (start) TexOutput(_T("{\\f1\\'D7}"));
3119    break;
3120  case ltAST:
3121    if (start) TexOutput(_T("{\\f1\\'2A}"));
3122    break;
3123  case ltSTAR:
3124    if (start) TexOutput(_T("{\\f5\\'AB}"));
3125    break;
3126  case ltCAP:
3127    if (start) TexOutput(_T("{\\f1\\'C7}"));
3128    break;
3129  case ltCUP:
3130    if (start) TexOutput(_T("{\\f1\\'C8}"));
3131    break;
3132  case ltVEE:
3133    if (start) TexOutput(_T("{\\f1\\'DA}"));
3134    break;
3135  case ltWEDGE:
3136    if (start) TexOutput(_T("{\\f1\\'D9}"));
3137    break;
3138  case ltCIRC:
3139    if (start) TexOutput(_T("{\\f1\\'B0}"));
3140    break;
3141  case ltBULLET:
3142    if (start) TexOutput(_T("{\\f1\\'B7}"));
3143    break;
3144  case ltDIAMOND:
3145    if (start) TexOutput(_T("{\\f1\\'E0}"));
3146    break;
3147  case ltBOX:
3148    if (start) TexOutput(_T("{\\f1\\'C6}"));
3149    break;
3150  case ltDIAMOND2:
3151    if (start) TexOutput(_T("{\\f1\\'E0}"));
3152    break;
3153  case ltBIGTRIANGLEDOWN:
3154    if (start) TexOutput(_T("{\\f1\\'D1}"));
3155    break;
3156  case ltOPLUS:
3157    if (start) TexOutput(_T("{\\f1\\'C5}"));
3158    break;
3159  case ltOTIMES:
3160    if (start) TexOutput(_T("{\\f1\\'C4}"));
3161    break;
3162  case ltSS:
3163    if (start) TexOutput(_T("{\\'DF}"));
3164    break;
3165  case ltFIGURE:
3166  {
3167    if (start) inFigure = true;
3168    else inFigure = false;
3169    break;
3170  }
3171  case ltTABLE:
3172  {
3173    if (start) inTable = true;
3174    else inTable = false;
3175    break;
3176  }
3177  default:
3178  {
3179    DefaultOnMacro(macroId, no_args, start);
3180    break;
3181  }
3182  }
3183}
3184
3185// Called on start/end of argument examination
3186bool RTFOnArgument(int macroId, int arg_no, bool start)
3187{
3188  wxChar buf[300];
3189  switch (macroId)
3190  {
3191  case ltCHAPTER:
3192  case ltCHAPTERSTAR:
3193  case ltCHAPTERHEADING:
3194  case ltSECTION:
3195  case ltSECTIONSTAR:
3196  case ltSECTIONHEADING:
3197  case ltSUBSECTION:
3198  case ltSUBSECTIONSTAR:
3199  case ltSUBSUBSECTION:
3200  case ltSUBSUBSECTIONSTAR:
3201  case ltGLOSS:
3202  case ltMEMBERSECTION:
3203  case ltFUNCTIONSECTION:
3204  case ltCAPTION:
3205  case ltCAPTIONSTAR:
3206  {
3207    if (!start && (arg_no == 1))
3208      currentSection = GetArgChunk();
3209    return false;
3210  }
3211  case ltFUNC:
3212  {
3213    if (start && (arg_no == 1))
3214      TexOutput(_T("\\pard\\li600\\fi-600{\\b "));
3215
3216    if (!start && (arg_no == 1))
3217      TexOutput(_T("} "));
3218
3219    if (start && (arg_no == 2))
3220    {
3221      if (!suppressNameDecoration) TexOutput(_T("{\\b "));
3222      currentMember = GetArgChunk();
3223    }
3224    if (!start && (arg_no == 2))
3225    {
3226      if (!suppressNameDecoration) TexOutput(_T("}"));
3227    }
3228
3229    if (start && (arg_no == 3))
3230      TexOutput(_T("("));
3231    if (!start && (arg_no == 3))
3232    {
3233//      TexOutput(_T(")\\li0\\fi0"));
3234//      TexOutput(_T(")\\par\\pard\\li0\\fi0"));
3235//      issuedNewParagraph = 1;
3236      TexOutput(_T(")"));
3237      WriteEnvironmentStyles();
3238    }
3239    break;
3240  }
3241  case ltCLIPSFUNC:
3242  {
3243    if (start && (arg_no == 1))
3244      TexOutput(_T("\\pard\\li260\\fi-260{\\b "));
3245    if (!start && (arg_no == 1))
3246      TexOutput(_T("} "));
3247
3248    if (start && (arg_no == 2))
3249    {
3250      if (!suppressNameDecoration) TexOutput(_T("({\\b "));
3251      currentMember = GetArgChunk();
3252    }
3253    if (!start && (arg_no == 2))
3254    {
3255      if (!suppressNameDecoration) TexOutput(_T("}"));
3256    }
3257
3258    if (!start && (arg_no == 3))
3259    {
3260      TexOutput(_T(")\\li0\\fi0"));
3261      WriteEnvironmentStyles();
3262    }
3263    break;
3264  }
3265  case ltPFUNC:
3266  {
3267    if (start && (arg_no == 1))
3268      TexOutput(_T("\\pard\\li260\\fi-260"));
3269
3270    if (!start && (arg_no == 1))
3271      TexOutput(_T(" "));
3272
3273    if (start && (arg_no == 2))
3274      TexOutput(_T("(*"));
3275    if (!start && (arg_no == 2))
3276      TexOutput(_T(")"));
3277
3278    if (start && (arg_no == 2))
3279      currentMember = GetArgChunk();
3280
3281    if (start && (arg_no == 3))
3282      TexOutput(_T("("));
3283    if (!start && (arg_no == 3))
3284    {
3285      TexOutput(_T(")\\li0\\fi0"));
3286      WriteEnvironmentStyles();
3287    }
3288    break;
3289  }
3290  case ltPARAM:
3291  {
3292    if (start && (arg_no == 1))
3293      TexOutput(_T("{\\b "));
3294    if (!start && (arg_no == 1))
3295      TexOutput(_T("}"));
3296    if (start && (arg_no == 2))
3297    {
3298      TexOutput(_T("{\\i "));
3299    }
3300    if (!start && (arg_no == 2))
3301    {
3302      TexOutput(_T("}"));
3303    }
3304    break;
3305  }
3306  case ltCPARAM:
3307  {
3308    if (start && (arg_no == 1))
3309      TexOutput(_T("{\\b "));
3310    if (!start && (arg_no == 1))
3311      TexOutput(_T("} "));  // This is the difference from param - one space!
3312    if (start && (arg_no == 2))
3313    {
3314      TexOutput(_T("{\\i "));
3315    }
3316    if (!start && (arg_no == 2))
3317    {
3318      TexOutput(_T("}"));
3319    }
3320    break;
3321  }
3322  case ltMEMBER:
3323  {
3324    if (!start && (arg_no == 1))
3325      TexOutput(_T(" "));
3326
3327    if (start && (arg_no == 2))
3328      currentMember = GetArgChunk();
3329    break;
3330  }
3331  case ltREF:
3332  {
3333    if (start)
3334    {
3335      wxChar *sec = NULL;
3336
3337      wxChar *refName = GetArgData();
3338      if (winHelp || !useWord)
3339      {
3340        if (refName)
3341        {
3342          TexRef *texRef = FindReference(refName);
3343          if (texRef)
3344          {
3345            sec = texRef->sectionNumber;
3346          }
3347        }
3348        if (sec)
3349        {
3350          TexOutput(sec);
3351        }
3352      }
3353      else
3354      {
3355        wxFprintf(Chapters, _T("{\\field{\\*\\fldinst  REF %s \\\\* MERGEFORMAT }{\\fldrslt ??}}"),
3356                refName);
3357      }
3358      return false;
3359    }
3360    break;
3361  }
3362  case ltHELPREF:
3363  case ltHELPREFN:
3364  {
3365    if (winHelp)
3366    {
3367        if ((GetNoArgs() - arg_no) == 1)
3368        {
3369          if (start)
3370            TexOutput(_T("{\\uldb "));
3371          else
3372            TexOutput(_T("}"));
3373        }
3374        if ((GetNoArgs() - arg_no) == 0) // Arg = 2, or 3 if first is optional
3375        {
3376          if (start)
3377          {
3378            TexOutput(_T("{\\v "));
3379
3380            // Remove green colour/underlining if specified
3381            if (!hotSpotUnderline && !hotSpotColour)
3382              TexOutput(_T("%"));
3383            else if (!hotSpotColour)
3384              TexOutput(_T("*"));
3385          }
3386          else TexOutput(_T("}"));
3387        }
3388    }
3389    else // If a linear document, must resolve the references ourselves
3390    {
3391      if ((GetNoArgs() - arg_no) == 1)
3392      {
3393        // In a linear document we display the anchor text in italic plus
3394        // the page number.
3395        if (start)
3396          TexOutput(_T("{\\i "));
3397        else
3398          TexOutput(_T("}"));
3399
3400        if (start)
3401          helpRefText = GetArgChunk();
3402
3403        return true;
3404      }
3405      else if ((GetNoArgs() - arg_no) == 0) // Arg = 2, or 3 if first is optional
3406      {
3407        if (macroId != ltHELPREFN)
3408        {
3409          wxChar *refName = GetArgData();
3410          TexRef *texRef = NULL;
3411          if (refName)
3412            texRef = FindReference(refName);
3413          if (start)
3414          {
3415            if (texRef || !ignoreBadRefs)
3416              TexOutput(_T(" ("));
3417            if (refName)
3418            {
3419                if (texRef || !ignoreBadRefs)
3420                {
3421                  if (useWord)
3422                  {
3423                      TexOutput(_T("p. "));
3424                      TexOutput(_T("{\\field{\\*\\fldinst  PAGEREF "));
3425                      TexOutput(refName);
3426                      TexOutput(_T(" \\\\* MERGEFORMAT }{\\fldrslt ??}}"));
3427                  }
3428                  else
3429                  {
3430                    // Only print section name if we're not in Word mode,
3431                    // so can't do page references
3432                    if (texRef)
3433                    {
3434                      TexOutput(texRef->sectionName);
3435                      TexOutput(_T(" "));
3436                      TexOutput(texRef->sectionNumber);
3437                    }
3438                    else
3439                    {
3440                      if (!ignoreBadRefs)
3441                        TexOutput(_T("??"));
3442                      wxSnprintf(buf, sizeof(buf), _T("Warning: unresolved reference '%s'"), refName);
3443                      OnInform(buf);
3444                    }
3445                  }
3446                }
3447            }
3448            else TexOutput(_T("??"));
3449          }
3450          else
3451          {
3452            if (texRef || !ignoreBadRefs)
3453              TexOutput(_T(")"));
3454          }
3455        }
3456        return false;
3457      }
3458    }
3459    break;
3460  }
3461  case ltURLREF:
3462  {
3463    if (arg_no == 1)
3464    {
3465      return true;
3466    }
3467    else if (arg_no == 2)
3468    {
3469      if (start)
3470      {
3471        inVerbatim = true;
3472        TexOutput(_T(" ({\\f3 "));
3473      }
3474      else
3475      {
3476        TexOutput(_T("})"));
3477        inVerbatim = false;
3478      }
3479      return true;
3480    }
3481    break;
3482  }
3483  case ltPOPREF:
3484  {
3485    if (winHelp)
3486    {
3487      if ((GetNoArgs() - arg_no) == 1)
3488      {
3489        if (start)
3490          TexOutput(_T("{\\ul "));
3491        else
3492          TexOutput(_T("}"));
3493      }
3494      if ((GetNoArgs() - arg_no) == 0) // Arg = 2, or 3 if first is optional
3495      {
3496        if (start)
3497        {
3498          TexOutput(_T("{\\v "));
3499
3500          // Remove green colour/underlining if specified
3501          if (!hotSpotUnderline && !hotSpotColour)
3502            TexOutput(_T("%"));
3503          else if (!hotSpotColour)
3504            TexOutput(_T("*"));
3505        }
3506        else TexOutput(_T("}"));
3507      }
3508    }
3509    else // A linear document...
3510    {
3511      if ((GetNoArgs() - arg_no) == 1)
3512      {
3513        // In a linear document we just display the anchor text in italic
3514        if (start)
3515          TexOutput(_T("{\\i "));
3516        else
3517          TexOutput(_T("}"));
3518        return true;
3519      }
3520      else return false;
3521    }
3522    break;
3523  }
3524  case ltADDCONTENTSLINE:
3525  {
3526    if (start && !winHelp)
3527    {
3528      if (arg_no == 2)
3529        contentsLineSection = copystring(GetArgData());
3530      else if (arg_no == 3)
3531        contentsLineValue = copystring(GetArgData());
3532      return false;
3533    }
3534    else return false;
3535  }
3536  case ltIMAGE:
3537  case ltIMAGEL:
3538  case ltIMAGER:
3539  case ltIMAGEMAP:
3540  case ltPSBOXTO:
3541  {
3542    if (arg_no == 3)
3543      return false;
3544
3545    static int imageWidth = 0;
3546    static int imageHeight = 0;
3547
3548    if (start && (arg_no == 1))
3549    {
3550      wxChar *imageDimensions = copystring(GetArgData());
3551
3552      // imageWidth - Convert points to TWIPS (1 twip = 1/20th of point)
3553      wxStringTokenizer tok(imageDimensions, _T(";:"), wxTOKEN_STRTOK);
3554      if(tok.HasMoreTokens())
3555      {
3556        wxString token = tok.GetNextToken();
3557        imageWidth = (int)(20*ParseUnitArgument((wxChar*)token.c_str()));
3558      }
3559      else
3560      {
3561        imageWidth = 0;
3562      }
3563
3564      // imageHeight - Convert points to TWIPS (1 twip = 1/20th of point)
3565      if(tok.HasMoreTokens())
3566      {
3567        wxString token = tok.GetNextToken();
3568        imageHeight = (int)(20*ParseUnitArgument((wxChar*)token.c_str()));
3569      }
3570      else
3571      {
3572        imageHeight = 0;
3573      }
3574
3575      if (imageDimensions)  // glt
3576          delete [] imageDimensions;
3577      return false;
3578    }
3579    else if (start && (arg_no == 2 ))
3580    {
3581      wxChar *filename = copystring(GetArgData());
3582      wxString f = _T("");
3583      if ((winHelp || (wxStrcmp(bitmapMethod, _T("includepicture")) == 0)  || (wxStrcmp(bitmapMethod, _T("import")) == 0)) && useWord)
3584      {
3585        if (f == _T("")) // Try for a .shg (segmented hypergraphics file)
3586        {
3587          wxStrcpy(buf, filename);
3588          StripExtension(buf);
3589          wxStrcat(buf, _T(".shg"));
3590          f = TexPathList.FindValidPath(buf);
3591        }
3592        if (f == _T("")) // Try for a .bmp
3593        {
3594          wxStrcpy(buf, filename);
3595          StripExtension(buf);
3596          wxStrcat(buf, _T(".bmp"));
3597          f = TexPathList.FindValidPath(buf);
3598        }
3599        if (f == _T("")) // Try for a metafile instead
3600        {
3601          wxStrcpy(buf, filename);
3602          StripExtension(buf);
3603          wxStrcat(buf, _T(".wmf"));
3604          f = TexPathList.FindValidPath(buf);
3605        }
3606        if (f != _T(""))
3607        {
3608          if (winHelp)
3609          {
3610            if (bitmapTransparency && (winHelpVersion > 3))
3611              TexOutput(_T("\\{bmct "));
3612            else
3613              TexOutput(_T("\\{bmc "));
3614            wxString str = wxFileNameFromPath(f);
3615            TexOutput((wxChar*) (const wxChar*) str);
3616            TexOutput(_T("\\}"));
3617          }
3618          else
3619          {
3620            // Microsoft Word method
3621            if (wxStrcmp(bitmapMethod, _T("import")) == 0)
3622              TexOutput(_T("{\\field{\\*\\fldinst IMPORT "));
3623            else
3624              TexOutput(_T("{\\field{\\*\\fldinst INCLUDEPICTURE "));
3625
3626            // Full path appears not to be valid!
3627            wxString str = wxFileNameFromPath(f);
3628            TexOutput((wxChar*)(const wxChar*) str);
3629/*
3630            int len = wxStrlen(f);
3631            wxChar smallBuf[2]; smallBuf[1] = 0;
3632            for (int i = 0; i < len; i++)
3633            {
3634              smallBuf[0] = f[i];
3635              TexOutput(smallBuf);
3636              if (smallBuf[0] == '\\')
3637                TexOutput(smallBuf);
3638            }
3639*/
3640            TexOutput(_T("}{\\fldrslt PRESS F9 TO FORMAT PICTURE}}"));
3641          }
3642        }
3643        else
3644        {
3645          TexOutput(_T("[No BMP or WMF for image file "));
3646          TexOutput(filename);
3647          TexOutput(_T("]"));
3648          wxSnprintf(buf, sizeof(buf), _T("Warning: could not find a BMP or WMF equivalent for %s."), filename);
3649          OnInform(buf);
3650        }
3651        if (filename)  // glt
3652            delete [] filename;
3653      }
3654      else // linear RTF
3655      {
3656          if (f == _T("")) // Try for a .bmp
3657          {
3658            wxStrcpy(buf, filename);
3659            StripExtension(buf);
3660            wxStrcat(buf, _T(".bmp"));
3661            f = TexPathList.FindValidPath(buf);
3662          }
3663          if (f != _T(""))
3664          {
3665            FILE *fd = wxFopen(f, _T("rb"));
3666            if (OutputBitmapHeader(fd, winHelp))
3667              OutputBitmapData(fd);
3668            else
3669            {
3670              wxSnprintf(buf, sizeof(buf), _T("Could not read bitmap %s.\nMay be in wrong format (needs RGB-encoded Windows BMP)."), f.c_str());
3671              OnError(buf);
3672            }
3673            fclose(fd);
3674          }
3675          else // Try for a metafile instead
3676          {
3677#ifdef __WXMSW__
3678            wxStrcpy(buf, filename);
3679            StripExtension(buf);
3680            wxStrcat(buf, _T(".wmf"));
3681            f = TexPathList.FindValidPath(buf);
3682            if (f != _T(""))
3683            {
3684  //            HFILE handle = _lopen(f, READ);
3685              FILE *fd = wxFopen(f, _T("rb"));
3686              if (OutputMetafileHeader(fd, winHelp, imageWidth, imageHeight))
3687              {
3688                OutputMetafileData(fd);
3689              }
3690              else
3691              {
3692                wxSnprintf(buf, sizeof(buf), _T("Could not read metafile %s. Perhaps it's not a placeable metafile?"), f.c_str());
3693                OnError(buf);
3694              }
3695              fclose(fd);
3696            }
3697            else
3698            {
3699#endif
3700              TexOutput(_T("[No BMP or WMF for image file "));
3701              TexOutput(filename);
3702              TexOutput(_T("]"));
3703              wxSnprintf(buf, sizeof(buf), _T("Warning: could not find a BMP or WMF equivalent for %s."), filename);
3704              OnInform(buf);
3705#ifdef __WXMSW__
3706            }
3707#endif
3708        }
3709      }
3710      return false;
3711    }
3712    else
3713      return false;
3714  }
3715  case ltTABULAR:
3716  case ltSUPERTABULAR:
3717  {
3718    if (arg_no == 1)
3719    {
3720      if (start)
3721      {
3722        currentRowNumber = 0;
3723        inTabular = true;
3724        startRows = true;
3725        tableVerticalLineLeft = false;
3726        tableVerticalLineRight = false;
3727        int currentWidth = 0;
3728
3729        wxChar *alignString = copystring(GetArgData());
3730        ParseTableArgument(alignString);
3731
3732//        TexOutput(_T("\\trowd\\trgaph108\\trleft-108"));
3733        TexOutput(_T("\\trowd\\trgaph108"));
3734
3735        // Write the first row formatting for compatibility
3736        // with standard Latex
3737        if (compatibilityMode)
3738        {
3739          for (int i = 0; i < noColumns; i++)
3740          {
3741            currentWidth += TableData[i].width;
3742            wxSnprintf(buf, sizeof(buf), _T("\\cellx%d"), currentWidth);
3743            TexOutput(buf);
3744          }
3745          TexOutput(_T("\\pard\\intbl\n"));
3746        }
3747        delete[] alignString;
3748
3749        return false;
3750      }
3751    }
3752    else if (arg_no == 2 && !start)
3753    {
3754      TexOutput(_T("\\pard\n"));
3755      WriteEnvironmentStyles();
3756      inTabular = false;
3757    }
3758    break;
3759  }
3760
3761  case ltQUOTE:
3762  case ltVERSE:
3763  {
3764    if (start)
3765    {
3766      TexOutput(_T("\\li360\n"));
3767      forbidParindent ++;
3768      PushEnvironmentStyle(_T("\\li360\\sa200"));
3769    }
3770    else
3771    {
3772      forbidParindent --;
3773      PopEnvironmentStyle();
3774      OnMacro(ltPAR, 0, true);
3775      OnMacro(ltPAR, 0, false);
3776    }
3777    break;
3778  }
3779  case ltQUOTATION:
3780  {
3781    if (start)
3782    {
3783      TexOutput(_T("\\li360\n"));
3784      PushEnvironmentStyle(_T("\\li360\\sa200"));
3785    }
3786    else
3787    {
3788      PopEnvironmentStyle();
3789      OnMacro(ltPAR, 0, true);
3790      OnMacro(ltPAR, 0, false);
3791    }
3792    break;
3793  }
3794  case ltBOXIT:
3795  case ltFRAMEBOX:
3796  case ltFBOX:
3797  case ltNORMALBOX:
3798  case ltNORMALBOXD:
3799  {
3800    if (start)
3801    {
3802      wxSnprintf(buf, sizeof(buf), _T("\\sa200\\box\\trgaph108%s\n"), ((macroId == ltNORMALBOXD) ? _T("\\brdrdb") : _T("\\brdrs")));
3803      TexOutput(buf);
3804      PushEnvironmentStyle(buf);
3805    }
3806    else
3807    {
3808      PopEnvironmentStyle();
3809      OnMacro(ltPAR, 0, true);
3810      OnMacro(ltPAR, 0, false);
3811    }
3812    break;
3813  }
3814  case ltHELPFONTSIZE:
3815  {
3816    if (start)
3817    {
3818      wxChar *data = GetArgData();
3819      if (wxStrcmp(data, _T("10")) == 0)
3820        SetFontSizes(10);
3821      else if (wxStrcmp(data, _T("11")) == 0)
3822        SetFontSizes(11);
3823      else if (wxStrcmp(data, _T("12")) == 0)
3824        SetFontSizes(12);
3825      wxSnprintf(buf, sizeof(buf), _T("\\fs%d\n"), normalFont*2);
3826      TexOutput(buf);
3827      TexOutput(buf);
3828      return false;
3829    }
3830    break;
3831  }
3832  case ltHELPFONTFAMILY:
3833  {
3834    if (start)
3835    {
3836      wxChar *data = GetArgData();
3837      if (wxStrcmp(data, _T("Swiss")) == 0)
3838        TexOutput(_T("\\f2\n"));
3839      else if (wxStrcmp(data, _T("Symbol")) == 0)
3840        TexOutput(_T("\\f1\n"));
3841      else if (wxStrcmp(data, _T("Times")) == 0)
3842        TexOutput(_T("\\f0\n"));
3843
3844      return false;
3845    }
3846    break;
3847  }
3848  case ltPARINDENT:
3849  {
3850    if (start && arg_no == 1)
3851    {
3852      wxChar *data = GetArgData();
3853      ParIndent = ParseUnitArgument(data);
3854      if (ParIndent == 0 || forbidParindent == 0)
3855      {
3856        wxSnprintf(buf, sizeof(buf), _T("\\fi%d\n"), ParIndent*20);
3857        TexOutput(buf);
3858      }
3859      return false;
3860    }
3861    break;
3862  }
3863  case ltITEM:
3864  {
3865    if (start && IsArgOptional())
3866    {
3867      descriptionItemArg = GetArgChunk();
3868      return false;
3869    }
3870    break;
3871  }
3872  case ltTWOCOLITEM:
3873  case ltTWOCOLITEMRULED:
3874  {
3875    switch (arg_no)
3876    {
3877      case 1:
3878      {
3879        if (!start)
3880          TexOutput(_T("\\tab "));
3881        break;
3882      }
3883      case 2:
3884      {
3885        if (!start)
3886        {
3887          if (macroId == ltTWOCOLITEMRULED)
3888            TexOutput(_T("\\brdrb\\brdrs\\brdrw15\\brsp20 "));
3889          TexOutput(_T("\\par\\pard\n"));
3890          issuedNewParagraph = 1;
3891          WriteEnvironmentStyles();
3892        }
3893        break;
3894      }
3895    }
3896    return true;
3897  }
3898  /*
3899   * Accents
3900   *
3901   */
3902  case ltACCENT_GRAVE:
3903  {
3904    if (start)
3905    {
3906      wxChar *val = GetArgData();
3907      if (val)
3908      {
3909        switch (val[0])
3910        {
3911          case 'a':
3912           TexOutput(_T("\\'e0"));
3913           break;
3914          case 'e':
3915           TexOutput(_T("\\'e8"));
3916           break;
3917          case 'i':
3918           TexOutput(_T("\\'ec"));
3919           break;
3920          case 'o':
3921           TexOutput(_T("\\'f2"));
3922           break;
3923          case 'u':
3924           TexOutput(_T("\\'f9"));
3925           break;
3926          case 'A':
3927           TexOutput(_T("\\'c0"));
3928           break;
3929          case 'E':
3930           TexOutput(_T("\\'c8"));
3931           break;
3932          case 'I':
3933           TexOutput(_T("\\'cc"));
3934           break;
3935          case 'O':
3936           TexOutput(_T("\\'d2"));
3937           break;
3938          case 'U':
3939           TexOutput(_T("\\'d9"));
3940           break;
3941          default:
3942           break;
3943        }
3944      }
3945    }
3946    return false;
3947  }
3948  case ltACCENT_ACUTE:
3949  {
3950    if (start)
3951    {
3952      wxChar *val = GetArgData();
3953      if (val)
3954      {
3955        switch (val[0])
3956        {
3957          case 'a':
3958           TexOutput(_T("\\'e1"));
3959           break;
3960          case 'e':
3961           TexOutput(_T("\\'e9"));
3962           break;
3963          case 'i':
3964           TexOutput(_T("\\'ed"));
3965           break;
3966          case 'o':
3967           TexOutput(_T("\\'f3"));
3968           break;
3969          case 'u':
3970           TexOutput(_T("\\'fa"));
3971           break;
3972          case 'y':
3973           TexOutput(_T("\\'fd"));
3974           break;
3975          case 'A':
3976           TexOutput(_T("\\'c1"));
3977           break;
3978          case 'E':
3979           TexOutput(_T("\\'c9"));
3980           break;
3981          case 'I':
3982           TexOutput(_T("\\'cd"));
3983           break;
3984          case 'O':
3985           TexOutput(_T("\\'d3"));
3986           break;
3987          case 'U':
3988           TexOutput(_T("\\'da"));
3989           break;
3990          case 'Y':
3991           TexOutput(_T("\\'dd"));
3992           break;
3993          default:
3994           break;
3995        }
3996      }
3997    }
3998    return false;
3999  }
4000  case ltACCENT_CARET:
4001  {
4002    if (start)
4003    {
4004      wxChar *val = GetArgData();
4005      if (val)
4006      {
4007        switch (val[0])
4008        {
4009          case 'a':
4010           TexOutput(_T("\\'e2"));
4011           break;
4012          case 'e':
4013           TexOutput(_T("\\'ea"));
4014           break;
4015          case 'i':
4016           TexOutput(_T("\\'ee"));
4017           break;
4018          case 'o':
4019           TexOutput(_T("\\'f4"));
4020           break;
4021          case 'u':
4022           TexOutput(_T("\\'fb"));
4023           break;
4024          case 'A':
4025           TexOutput(_T("\\'c2"));
4026           break;
4027          case 'E':
4028           TexOutput(_T("\\'ca"));
4029           break;
4030          case 'I':
4031           TexOutput(_T("\\'ce"));
4032           break;
4033          case 'O':
4034           TexOutput(_T("\\'d4"));
4035           break;
4036          case 'U':
4037           TexOutput(_T("\\'db"));
4038           break;
4039          default:
4040           break;
4041        }
4042      }
4043    }
4044    return false;
4045  }
4046  case ltACCENT_TILDE:
4047  {
4048    if (start)
4049    {
4050      wxChar *val = GetArgData();
4051      if (val)
4052      {
4053        switch (val[0])
4054        {
4055          case 'a':
4056           TexOutput(_T("\\'e3"));
4057           break;
4058          case ' ':
4059           TexOutput(_T("~"));
4060           break;
4061          case 'n':
4062           TexOutput(_T("\\'f1"));
4063           break;
4064          case 'o':
4065           TexOutput(_T("\\'f5"));
4066           break;
4067          case 'A':
4068           TexOutput(_T("\\'c3"));
4069           break;
4070          case 'N':
4071           TexOutput(_T("\\'d1"));
4072           break;
4073          case 'O':
4074           TexOutput(_T("\\'d5"));
4075           break;
4076          default:
4077           break;
4078        }
4079      }
4080    }
4081    return false;
4082  }
4083  case ltACCENT_UMLAUT:
4084  {
4085    if (start)
4086    {
4087      wxChar *val = GetArgData();
4088      if (val)
4089      {
4090        switch (val[0])
4091        {
4092          case 'a':
4093           TexOutput(_T("\\'e4"));
4094           break;
4095          case 'e':
4096           TexOutput(_T("\\'eb"));
4097           break;
4098          case 'i':
4099           TexOutput(_T("\\'ef"));
4100           break;
4101          case 'o':
4102           TexOutput(_T("\\'f6"));
4103           break;
4104          case 'u':
4105           TexOutput(_T("\\'fc"));
4106           break;
4107          case 's':
4108           TexOutput(_T("\\'df"));
4109           break;
4110          case 'y':
4111           TexOutput(_T("\\'ff"));
4112           break;
4113          case 'A':
4114           TexOutput(_T("\\'c4"));
4115           break;
4116          case 'E':
4117           TexOutput(_T("\\'cb"));
4118           break;
4119          case 'I':
4120           TexOutput(_T("\\'cf"));
4121           break;
4122          case 'O':
4123           TexOutput(_T("\\'d6"));
4124           break;
4125          case 'U':
4126           TexOutput(_T("\\'dc"));
4127           break;
4128          case 'Y':
4129           TexOutput(_T("\\'df"));
4130           break;
4131          default:
4132           break;
4133        }
4134      }
4135    }
4136    return false;
4137  }
4138  case ltACCENT_DOT:
4139  {
4140    if (start)
4141    {
4142      wxChar *val = GetArgData();
4143      if (val)
4144      {
4145        switch (val[0])
4146        {
4147          case 'a':
4148           TexOutput(_T("\\'e5"));
4149           break;
4150          case 'A':
4151           TexOutput(_T("\\'c5"));
4152           break;
4153          default:
4154           break;
4155        }
4156      }
4157    }
4158    return false;
4159  }
4160  case ltACCENT_CADILLA:
4161  {
4162    if (start)
4163    {
4164      wxChar *val = GetArgData();
4165      if (val)
4166      {
4167        switch (val[0])
4168        {
4169          case 'c':
4170           TexOutput(_T("\\'e7"));
4171           break;
4172          case 'C':
4173           TexOutput(_T("\\'c7"));
4174           break;
4175          default:
4176           break;
4177        }
4178      }
4179    }
4180    return false;
4181  }
4182  case ltFOOTNOTE:
4183  {
4184    static wxChar *helpTopic = NULL;
4185    static FILE *savedOutput = NULL;
4186    if (winHelp)
4187    {
4188      if (arg_no == 1)
4189      {
4190        if (start)
4191        {
4192          OnInform(_T("Consider using \\footnotepopup instead of \\footnote."));
4193          footnoteCount ++;
4194          wxChar footBuf[20];
4195          wxSnprintf(footBuf, sizeof(footBuf), _T("(%d)"), footnoteCount);
4196
4197          TexOutput(_T(" {\\ul "));
4198          TexOutput(footBuf);
4199          TexOutput(_T("}"));
4200          helpTopic = FindTopicName(NULL);
4201          TexOutput(_T("{\\v "));
4202
4203          // Remove green colour/underlining if specified
4204          if (!hotSpotUnderline && !hotSpotColour)
4205            TexOutput(_T("%"));
4206          else if (!hotSpotColour)
4207            TexOutput(_T("*"));
4208
4209          TexOutput(helpTopic);
4210          TexOutput(_T("}"));
4211
4212          wxFprintf(Popups, _T("\\page\n"));
4213//          wxFprintf(Popups, _T("\n${\\footnote }")); // No title
4214          wxFprintf(Popups, _T("\n#{\\footnote %s}\n"), helpTopic);
4215          wxFprintf(Popups, _T("+{\\footnote %s}\n"), GetBrowseString());
4216          savedOutput = CurrentOutput1;
4217          SetCurrentOutput(Popups);
4218      }
4219      else
4220      {
4221          SetCurrentOutput(savedOutput);
4222      }
4223        return true;
4224      }
4225      return true;
4226    }
4227    else
4228    {
4229      if (start)
4230      {
4231        TexOutput(_T(" {\\super \\chftn{\\footnote \\fs20 {\\super \\chftn}"), true);
4232      }
4233      else
4234      {
4235        TexOutput(_T("}}"), true);
4236      }
4237      return true;
4238    }
4239  }
4240  case ltFOOTNOTEPOPUP:
4241  {
4242    static wxChar *helpTopic = NULL;
4243    static FILE *savedOutput = NULL;
4244    if (winHelp)
4245    {
4246      if (arg_no == 1)
4247      {
4248        if (start)
4249        {
4250          TexOutput(_T("{\\ul "));
4251      }
4252        else
4253        {
4254          TexOutput(_T("}"));
4255        }
4256        return true;
4257      }
4258      else if (arg_no == 2)
4259      {
4260        if (start)
4261        {
4262          helpTopic = FindTopicName(NULL);
4263          TexOutput(_T("{\\v "));
4264
4265          // Remove green colour/underlining if specified
4266          if (!hotSpotUnderline && !hotSpotColour)
4267            TexOutput(_T("%"));
4268          else if (!hotSpotColour)
4269            TexOutput(_T("*"));
4270
4271          TexOutput(helpTopic);
4272          TexOutput(_T("}"));
4273
4274          wxFprintf(Popups, _T("\\page\n"));
4275//          wxFprintf(Popups, _T("\n${\\footnote }")); // No title
4276          wxFprintf(Popups, _T("\n#{\\footnote %s}\n"), helpTopic);
4277          wxFprintf(Popups, _T("+{\\footnote %s}\n"), GetBrowseString());
4278          savedOutput = CurrentOutput1;
4279          SetCurrentOutput(Popups);
4280        }
4281        else
4282        {
4283          SetCurrentOutput(savedOutput);
4284        }
4285        return true;
4286      }
4287    }
4288    else
4289    {
4290      if (arg_no == 1)
4291        return true;
4292      if (start)
4293      {
4294        TexOutput(_T(" {\\super \\chftn{\\footnote \\fs20 {\\super \\chftn}"), true);
4295      }
4296      else
4297      {
4298        TexOutput(_T("}}"), true);
4299      }
4300      return true;
4301    }
4302    break;
4303  }
4304  case ltFANCYPLAIN:
4305  {
4306    if (start && (arg_no == 1))
4307      return false;
4308    else
4309      return true;
4310  }
4311  case ltSETHEADER:
4312  {
4313    if (start)
4314      forbidResetPar ++;
4315    else
4316      forbidResetPar --;
4317
4318    if (winHelp) return false;
4319    if (start)
4320    {
4321      switch (arg_no)
4322      {
4323        case 1:
4324          LeftHeaderEven = GetArgChunk();
4325          if (wxStrlen(GetArgData(LeftHeaderEven)) == 0)
4326            LeftHeaderEven = NULL;
4327          break;
4328        case 2:
4329          CentreHeaderEven = GetArgChunk();
4330          if (wxStrlen(GetArgData(CentreHeaderEven)) == 0)
4331            CentreHeaderEven = NULL;
4332          break;
4333        case 3:
4334          RightHeaderEven = GetArgChunk();
4335          if (wxStrlen(GetArgData(RightHeaderEven)) == 0)
4336            RightHeaderEven = NULL;
4337          break;
4338        case 4:
4339          LeftHeaderOdd = GetArgChunk();
4340          if (wxStrlen(GetArgData(LeftHeaderOdd)) == 0)
4341            LeftHeaderOdd = NULL;
4342          break;
4343        case 5:
4344          CentreHeaderOdd = GetArgChunk();
4345          if (wxStrlen(GetArgData(CentreHeaderOdd)) == 0)
4346            CentreHeaderOdd = NULL;
4347          break;
4348        case 6:
4349          RightHeaderOdd = GetArgChunk();
4350          if (wxStrlen(GetArgData(RightHeaderOdd)) == 0)
4351            RightHeaderOdd = NULL;
4352          OutputRTFHeaderCommands();
4353          break;
4354        default:
4355          break;
4356      }
4357    }
4358    return false;
4359  }
4360  case ltSETFOOTER:
4361  {
4362    if (start)
4363      forbidResetPar ++;
4364    else
4365      forbidResetPar --;
4366
4367    if (winHelp) return false;
4368    if (start)
4369    {
4370      switch (arg_no)
4371      {
4372        case 1:
4373          LeftFooterEven = GetArgChunk();
4374          if (wxStrlen(GetArgData(LeftFooterEven)) == 0)
4375            LeftFooterEven = NULL;
4376          break;
4377        case 2:
4378          CentreFooterEven = GetArgChunk();
4379          if (wxStrlen(GetArgData(CentreFooterEven)) == 0)
4380            CentreFooterEven = NULL;
4381          break;
4382        case 3:
4383          RightFooterEven = GetArgChunk();
4384          if (wxStrlen(GetArgData(RightFooterEven)) == 0)
4385            RightFooterEven = NULL;
4386          break;
4387        case 4:
4388          LeftFooterOdd = GetArgChunk();
4389          if (wxStrlen(GetArgData(LeftFooterOdd)) == 0)
4390            LeftFooterOdd = NULL;
4391          break;
4392        case 5:
4393          CentreFooterOdd = GetArgChunk();
4394          if (wxStrlen(GetArgData(CentreFooterOdd)) == 0)
4395            CentreFooterOdd = NULL;
4396          break;
4397        case 6:
4398          RightFooterOdd = GetArgChunk();
4399          if (wxStrlen(GetArgData(RightFooterOdd)) == 0)
4400            RightFooterOdd = NULL;
4401          OutputRTFFooterCommands();
4402          break;
4403        default:
4404          break;
4405      }
4406    }
4407    return false;
4408  }
4409  case ltMARKRIGHT:
4410  {
4411    if (winHelp) return false;
4412    // Fake a SetHeader command
4413    if (start)
4414    {
4415      LeftHeaderOdd = NULL;
4416      CentreHeaderOdd = NULL;
4417      RightHeaderOdd = NULL;
4418      LeftHeaderEven = NULL;
4419      CentreHeaderEven = NULL;
4420      RightHeaderEven = NULL;
4421      OnInform(_T("Consider using setheader/setfooter rather than markright."));
4422    }
4423    RTFOnArgument(ltSETHEADER, 4, start);
4424    if (!start)
4425      OutputRTFHeaderCommands();
4426    return false;
4427  }
4428  case ltMARKBOTH:
4429  {
4430    if (winHelp) return false;
4431    // Fake a SetHeader command
4432    switch (arg_no)
4433    {
4434      case 1:
4435      {
4436        if (start)
4437        {
4438          LeftHeaderOdd = NULL;
4439          CentreHeaderOdd = NULL;
4440          RightHeaderOdd = NULL;
4441          LeftHeaderEven = NULL;
4442          CentreHeaderEven = NULL;
4443          RightHeaderEven = NULL;
4444          OnInform(_T("Consider using setheader/setfooter rather than markboth."));
4445        }
4446        return RTFOnArgument(ltSETHEADER, 1, start);
4447      }
4448      case 2:
4449      {
4450        RTFOnArgument(ltSETHEADER, 4, start);
4451        if (!start)
4452          OutputRTFHeaderCommands();
4453        return false;
4454      }
4455    }
4456    break;
4457  }
4458  case ltPAGENUMBERING:
4459  {
4460    if (start)
4461      forbidResetPar ++;
4462    else
4463      forbidResetPar --;
4464
4465    if (winHelp) return false;
4466    if (start)
4467    {
4468      TexOutput(_T("\\pgnrestart"));
4469      wxChar *data = GetArgData();
4470      if (currentNumberStyle) delete[] currentNumberStyle;
4471      currentNumberStyle = copystring(data);
4472      OutputNumberStyle(currentNumberStyle);
4473
4474      TexOutput(_T("\n"));
4475    }
4476    return false;
4477  }
4478  case ltTWOCOLUMN:
4479  {
4480    if (winHelp) return false;
4481    if (start)
4482      return true;
4483    break;
4484  }
4485  case ltITEMSEP:
4486  {
4487    if (start)
4488    {
4489      wxChar *val = GetArgData();
4490      currentItemSep = ParseUnitArgument(val);
4491      return false;
4492    }
4493    break;
4494  }
4495  case ltEVENSIDEMARGIN:
4496  {
4497    return false;
4498  }
4499  case ltODDSIDEMARGIN:
4500  {
4501    if (start)
4502    {
4503      wxChar *val = GetArgData();
4504      int twips = (int)(20*ParseUnitArgument(val));
4505      // Add an inch since in LaTeX it's specified minus an inch
4506      twips += 1440;
4507      CurrentLeftMarginOdd = twips;
4508      wxSnprintf(buf, sizeof(buf), _T("\\margl%d\n"), twips);
4509      TexOutput(buf);
4510
4511      CurrentMarginParX = CurrentLeftMarginOdd + CurrentTextWidth + CurrentMarginParSep;
4512    }
4513    return false;
4514  }
4515  case ltMARGINPARWIDTH:
4516  {
4517    if (start)
4518    {
4519      wxChar *val = GetArgData();
4520      int twips = (int)(20*ParseUnitArgument(val));
4521      CurrentMarginParWidth = twips;
4522    }
4523    return false;
4524  }
4525  case ltMARGINPARSEP:
4526  {
4527    if (start)
4528    {
4529      wxChar *val = GetArgData();
4530      int twips = (int)(20*ParseUnitArgument(val));
4531      CurrentMarginParSep = twips;
4532      CurrentMarginParX = CurrentLeftMarginOdd + CurrentTextWidth + CurrentMarginParSep;
4533    }
4534    return false;
4535  }
4536  case ltTEXTWIDTH:
4537  {
4538    if (start)
4539    {
4540      wxChar *val = GetArgData();
4541      int twips = (int)(20*ParseUnitArgument(val));
4542      CurrentTextWidth = twips;
4543
4544      // Need to set an implicit right margin
4545      CurrentRightMarginOdd = PageWidth - CurrentTextWidth - CurrentLeftMarginOdd;
4546      CurrentRightMarginEven = PageWidth - CurrentTextWidth - CurrentLeftMarginEven;
4547      CurrentMarginParX = CurrentLeftMarginOdd + CurrentTextWidth + CurrentMarginParSep;
4548      wxSnprintf(buf, sizeof(buf), _T("\\margr%d\n"), CurrentRightMarginOdd);
4549      TexOutput(buf);
4550    }
4551    return false;
4552  }
4553  case ltMARGINPAR:
4554  case ltMARGINPARODD:
4555  {
4556    if (start)
4557    {
4558      if (winHelp)
4559      {
4560        TexOutput(_T("\\sa200\\box\n"));
4561        PushEnvironmentStyle(_T("\\sa200\\box"));
4562      }
4563      else
4564      {
4565        wxSnprintf(buf, sizeof(buf), _T("\\phpg\\posx%d\\absw%d\n"), CurrentMarginParX, CurrentMarginParWidth);
4566        TexOutput(buf);
4567      }
4568      return true;
4569    }
4570    else
4571    {
4572      if (winHelp)
4573      {
4574        TexOutput(_T("\\par\\pard\n"));
4575        PopEnvironmentStyle();
4576        WriteEnvironmentStyles();
4577      }
4578      else
4579        TexOutput(_T("\\par\\pard\n"));
4580      issuedNewParagraph = 1;
4581    }
4582    return false;
4583  }
4584  case ltMARGINPAREVEN:
4585  {
4586    if (start)
4587    {
4588      if (winHelp)
4589      {
4590        TexOutput(_T("\\sa200\\box\n"));
4591        PushEnvironmentStyle(_T("\\sa200\\box"));
4592      }
4593      else
4594      {
4595        if (mirrorMargins)
4596        {
4597          // Have to calculate what the margins are changed to in WfW margin
4598          // mirror mode, on an even (left-hand) page.
4599          int x = PageWidth - CurrentRightMarginOdd - CurrentMarginParWidth - CurrentMarginParSep
4600                    - CurrentTextWidth + GutterWidth;
4601          wxSnprintf(buf, sizeof(buf), _T("\\phpg\\posx%d\\absw%d\n"), x, CurrentMarginParWidth);
4602          TexOutput(buf);
4603        }
4604        else
4605        {
4606          wxSnprintf(buf, sizeof(buf), _T("\\phpg\\posx%d\\absw%d\n"), CurrentMarginParX, CurrentMarginParWidth);
4607          TexOutput(buf);
4608        }
4609      }
4610      return true;
4611    }
4612    else
4613    {
4614      if (winHelp)
4615      {
4616        TexOutput(_T("\\par\\pard\n"));
4617        PopEnvironmentStyle();
4618        WriteEnvironmentStyles();
4619      }
4620      else
4621        issuedNewParagraph = 1;
4622      TexOutput(_T("\\par\\pard\n"));
4623    }
4624    return false;
4625  }
4626  case ltTWOCOLWIDTHA:
4627  {
4628    if (start)
4629    {
4630      wxChar *val = GetArgData();
4631      int twips = (int)(20*ParseUnitArgument(val));
4632      TwoColWidthA = twips;
4633    }
4634    return false;
4635  }
4636  case ltTWOCOLWIDTHB:
4637  {
4638    if (start)
4639    {
4640      wxChar *val = GetArgData();
4641      int twips = (int)(20*ParseUnitArgument(val));
4642      TwoColWidthB = twips;
4643    }
4644    return false;
4645  }
4646  case ltROW:
4647  case ltRULEDROW:
4648  {
4649    if (start)
4650    {
4651      int currentWidth = 0;
4652
4653      if (!compatibilityMode || (currentRowNumber > 0))
4654      {
4655      TexOutput(_T("\\pard\\intbl"));
4656
4657      if (macroId == ltRULEDROW)
4658        ruleBottom = 1;
4659      for (int i = 0; i < noColumns; i++)
4660      {
4661        currentWidth += TableData[i].width;
4662        if (ruleTop == 1)
4663        {
4664          TexOutput(_T("\\clbrdrt\\brdrs\\brdrw15"));
4665        }
4666        else if (ruleTop > 1)
4667        {
4668          TexOutput(_T("\\clbrdrt\\brdrdb\\brdrw15"));
4669        }
4670        if (ruleBottom == 1)
4671        {
4672          TexOutput(_T("\\clbrdrb\\brdrs\\brdrw15"));
4673        }
4674        else if (ruleBottom > 1)
4675        {
4676          TexOutput(_T("\\clbrdrb\\brdrdb\\brdrw15"));
4677        }
4678
4679        if (TableData[i].rightBorder)
4680          TexOutput(_T("\\clbrdrr\\brdrs\\brdrw15"));
4681
4682        if (TableData[i].leftBorder)
4683          TexOutput(_T("\\clbrdrl\\brdrs\\brdrw15"));
4684
4685        wxSnprintf(buf, sizeof(buf), _T("\\cellx%d"), currentWidth);
4686        TexOutput(buf);
4687      }
4688      TexOutput(_T("\\pard\\intbl\n"));
4689      }
4690      ruleTop = 0;
4691      ruleBottom = 0;
4692      currentRowNumber ++;
4693      return true;
4694    }
4695    else
4696    {
4697//      TexOutput(_T("\\cell\\row\\trowd\\trgaph108\\trleft-108\n"));
4698      TexOutput(_T("\\cell\\row\\trowd\\trgaph108\n"));
4699    }
4700    break;
4701  }
4702  case ltMULTICOLUMN:
4703  {
4704    static int noMultiColumns = 0;
4705    if (start)
4706    {
4707      switch (arg_no)
4708      {
4709        case 1:
4710        {
4711          noMultiColumns = wxAtoi(GetArgData());
4712          return false;
4713        }
4714        case 2:
4715        {
4716          return false;
4717        }
4718        case 3:
4719        {
4720          return true;
4721        }
4722      }
4723    }
4724    else
4725    {
4726      if (arg_no == 3)
4727      {
4728        for (int i = 1; i < noMultiColumns; i ++)
4729          TexOutput(_T("\\cell"));
4730      }
4731    }
4732    break;
4733  }
4734  case ltINDENTED:
4735  {
4736    if (start && (arg_no == 1))
4737    {
4738//      indentLevel ++;
4739//      TexOutput(_T("\\fi0\n"));
4740      int oldIndent = 0;
4741      wxNode *node = itemizeStack.GetFirst();
4742      if (node)
4743        oldIndent = ((ItemizeStruc *)node->GetData())->indentation;
4744
4745      int indentValue = 20*ParseUnitArgument(GetArgData());
4746      int indentSize = indentValue + oldIndent;
4747
4748      ItemizeStruc *struc = new ItemizeStruc(LATEX_INDENT, indentSize);
4749      itemizeStack.Insert(struc);
4750
4751      wxSnprintf(buf, sizeof(buf), _T("\\tx%d\\li%d\\sa200 "), indentSize, indentSize);
4752      PushEnvironmentStyle(buf);
4753      TexOutput(buf);
4754      return false;
4755    }
4756    if (!start && (arg_no == 2))
4757    {
4758      PopEnvironmentStyle();
4759      if (itemizeStack.GetFirst())
4760      {
4761        ItemizeStruc *struc = (ItemizeStruc *)itemizeStack.GetFirst()->GetData();
4762        delete struc;
4763        delete itemizeStack.GetFirst();
4764      }
4765      if (itemizeStack.GetCount() == 0)
4766      {
4767        TexOutput(_T("\\par\\pard\n"));
4768        issuedNewParagraph = 1;
4769        WriteEnvironmentStyles();
4770      }
4771    }
4772    return true;
4773  }
4774/*
4775  case ltSIZEDBOX:
4776  case ltSIZEDBOXD:
4777  {
4778    if (start && (arg_no == 1))
4779    {
4780      int oldIndent = 0;
4781      wxNode *node = itemizeStack.GetFirst();
4782      if (node)
4783        oldIndent = ((ItemizeStruc *)node->GetData())->indentation;
4784
4785      int boxWidth = 20*ParseUnitArgument(GetArgData());
4786
4787      int indentValue = (int)((CurrentTextWidth - oldIndent - boxWidth)/2.0);
4788      int indentSize = indentValue + oldIndent;
4789      int indentSizeRight = indentSize + boxWidth;
4790
4791      ItemizeStruc *struc = new ItemizeStruc(LATEX_INDENT, indentSize);
4792      itemizeStack.Insert(struc);
4793
4794      wxSnprintf(buf, sizeof(buf), _T("\\tx%d\\li%d\\lr%d\\sa200\\box%s "), indentSize, indentSize, indentSizeRight,
4795        ((macroId == ltCENTEREDBOX) ? _T("\\brdrs") : _T("\\brdrdb")));
4796      PushEnvironmentStyle(buf);
4797      TexOutput(buf);
4798      return false;
4799    }
4800    if (!start && (arg_no == 2))
4801    {
4802      PopEnvironmentStyle();
4803      if (itemizeStack.GetFirst())
4804      {
4805        ItemizeStruc *struc = (ItemizeStruc *)itemizeStack.GetFirst()->GetData();
4806        delete struc;
4807        delete itemizeStack.GetFirst();
4808      }
4809      if (itemizeStack.Number() == 0)
4810      {
4811        TexOutput(_T("\\par\\pard\n"));
4812        issuedNewParagraph = 1;
4813        WriteEnvironmentStyles();
4814      }
4815    }
4816    return true;
4817    break;
4818  }
4819*/
4820  case ltDOCUMENTSTYLE:
4821  {
4822    DefaultOnArgument(macroId, arg_no, start);
4823    if (!start && !IsArgOptional())
4824    {
4825      if (MinorDocumentStyleString)
4826      {
4827        if (StringMatch(_T("twoside"), MinorDocumentStyleString))
4828          // Mirror margins, switch on odd/even headers & footers, and break sections at odd pages
4829          TexOutput(_T("\\margmirror\\facingp\\sbkodd"));
4830        if (StringMatch(_T("twocolumn"), MinorDocumentStyleString))
4831          TexOutput(_T("\\cols2"));
4832      }
4833      TexOutput(_T("\n"));
4834    }
4835    return false;
4836  }
4837  case ltSETHOTSPOTCOLOUR:
4838  case ltSETHOTSPOTCOLOR:
4839  {
4840    if (!start)
4841    {
4842      wxChar *text = GetArgData();
4843      if (wxStrcmp(text, _T("yes")) == 0 || wxStrcmp(text, _T("on")) == 0 || wxStrcmp(text, _T("ok")) == 0)
4844        hotSpotColour = true;
4845      else
4846        hotSpotColour = false;
4847    }
4848    return false;
4849  }
4850  case ltSETTRANSPARENCY:
4851  {
4852    if (!start)
4853    {
4854      wxChar *text = GetArgData();
4855      if (wxStrcmp(text, _T("yes")) == 0 || wxStrcmp(text, _T("on")) == 0 || wxStrcmp(text, _T("ok")) == 0)
4856        bitmapTransparency = true;
4857      else
4858        bitmapTransparency = false;
4859    }
4860    return false;
4861  }
4862  case ltSETHOTSPOTUNDERLINE:
4863  {
4864    if (!start)
4865    {
4866      wxChar *text = GetArgData();
4867      if (wxStrcmp(text, _T("yes")) == 0 || wxStrcmp(text, _T("on")) == 0 || wxStrcmp(text, _T("ok")) == 0)
4868        hotSpotUnderline = true;
4869      else
4870        hotSpotUnderline = false;
4871    }
4872    return false;
4873  }
4874  case ltBIBITEM:
4875  {
4876    if (arg_no == 1 && start)
4877    {
4878      wxChar *citeKey = GetArgData();
4879      TexRef *ref = (TexRef *)TexReferences.Get(citeKey);
4880      if (ref)
4881      {
4882        if (ref->sectionNumber) delete[] ref->sectionNumber;
4883        wxSnprintf(buf, sizeof(buf), _T("[%d]"), citeCount);
4884        ref->sectionNumber = copystring(buf);
4885      }
4886
4887      TexOutput(_T("\\li260\\fi-260 ")); // Indent from 2nd line
4888      wxSnprintf(buf, sizeof(buf), _T("{\\b [%d]} "), citeCount);
4889      TexOutput(buf);
4890      citeCount ++;
4891      return false;
4892    }
4893    if (arg_no == 2 && !start)
4894      TexOutput(_T("\\par\\pard\\par\n\n"));
4895    return true;
4896  }
4897  case ltTHEBIBLIOGRAPHY:
4898  {
4899    if (start && (arg_no == 1))
4900    {
4901      citeCount = 1;
4902      if (winHelp)
4903        SetCurrentOutputs(Contents, Chapters);
4904
4905      if (!winHelp)
4906      {
4907        wxFprintf(Chapters, _T("\\sect\\pgncont\\titlepg\n"));
4908
4909        // If a non-custom page style, we generate the header now.
4910        if (PageStyle && (wxStrcmp(PageStyle, _T("plain")) == 0 ||
4911                          wxStrcmp(PageStyle, _T("empty")) == 0 ||
4912                          wxStrcmp(PageStyle, _T("headings")) == 0))
4913        {
4914          OutputRTFHeaderCommands();
4915          OutputRTFFooterCommands();
4916        }
4917
4918        // Need to reset the current numbering style, or RTF forgets it.
4919        OutputNumberStyle(currentNumberStyle);
4920        SetCurrentOutput(Contents);
4921      }
4922      else
4923        wxFprintf(Chapters, _T("\\page\n"));
4924
4925      if (winHelp)
4926        wxFprintf(Contents, _T("\n{\\uldb %s}"), ReferencesNameString);
4927      else
4928        wxFprintf(Contents, _T("\\par\n\\pard{\\b %s}"), ReferencesNameString);
4929
4930      startedSections = true;
4931
4932      if (winHelp)
4933        wxFprintf(Chapters, _T("\n${\\footnote %s}"), ReferencesNameString);
4934
4935      wxChar *topicName = _T("bibliography");
4936
4937      if (winHelp)
4938      {
4939        wxFprintf(Contents, _T("{\\v %s}\\par\\pard\n"), topicName);
4940        WriteEnvironmentStyles();
4941      }
4942      else
4943        wxFprintf(Contents, _T("\\par\\par\\pard\n"));
4944
4945      if (winHelp)
4946      {
4947        wxFprintf(Chapters, _T("\n#{\\footnote %s}\n"), topicName);
4948        wxFprintf(Chapters, _T("+{\\footnote %s}\n"), GetBrowseString());
4949        wxFprintf(Chapters, _T("K{\\footnote {K} %s}\n"), ReferencesNameString);
4950        GenerateKeywordsForTopic(topicName);
4951        if (useUpButton)
4952        {
4953          wxFprintf(Chapters, _T("!{\\footnote EnableButton(\"Up\");ChangeButtonBinding(\"Up\", \"JumpId(`%s.hlp', `%s')\")}\n"),
4954               wxFileNameFromPath(FileRoot), "Contents");
4955        }
4956      }
4957
4958      SetCurrentOutput(Chapters);
4959      wxChar *styleCommand = _T("");
4960      if (!winHelp && useHeadingStyles)
4961        styleCommand = _T("\\s1");
4962      wxFprintf(Chapters, _T("\\pard{%s"), (winHelp ? _T("\\keepn\\sa140\\sb140") : styleCommand));
4963      WriteHeadingStyle(Chapters, 1);  wxFprintf(Chapters, _T(" References\\par\\pard}\n"));
4964
4965      return false;
4966    }
4967    return true;
4968  }
4969  case ltINDEX:
4970  {
4971    /*
4972     * In Windows help, all keywords should be at the start of the
4973     * topic, but Latex \index commands can be anywhere in the text.
4974     * So we're going to have to build up lists of keywords for a topic,
4975     * and insert them on the second pass.
4976     *
4977     * In linear RTF, we can embed the index entry now.
4978     *
4979     */
4980    if (start)
4981    {
4982//      wxChar *entry = GetArgData();
4983      wxChar buf[300];
4984      OutputChunkToString(GetArgChunk(), buf);
4985      if (winHelp)
4986      {
4987        if (CurrentTopic)
4988        {
4989          AddKeyWordForTopic(CurrentTopic, buf);
4990        }
4991      }
4992      else GenerateIndexEntry(buf);
4993    }
4994    return false;
4995  }
4996  case ltFCOL:
4997  case ltBCOL:
4998  {
4999    if (start)
5000    {
5001      switch (arg_no)
5002      {
5003        case 1:
5004        {
5005          wxChar *name = GetArgData();
5006          int pos = FindColourPosition(name);
5007          if (pos > -1)
5008          {
5009            wxSnprintf(buf, sizeof(buf), _T("{%s%d "), ((macroId == ltFCOL) ? _T("\\cf") : _T("\\cb")), pos);
5010            TexOutput(buf);
5011          }
5012          else
5013          {
5014            wxSnprintf(buf, sizeof(buf), _T("Could not find colour name %s"), name);
5015            OnError(buf);
5016          }
5017          break;
5018        }
5019        case 2:
5020        {
5021          return true;
5022        }
5023        default:
5024          break;
5025      }
5026    }
5027    else
5028    {
5029      if (arg_no == 2) TexOutput(_T("}"));
5030    }
5031    return false;
5032  }
5033  case ltLABEL:
5034  {
5035    if (start && !winHelp && useWord)
5036    {
5037      wxChar *s = GetArgData();
5038      // Only insert a bookmark here if it's not just been inserted
5039      // in a section heading.
5040      if ( !CurrentTopic || !(wxStrcmp(CurrentTopic, s) == 0) )
5041/*
5042      if ( (!CurrentChapterName || !(CurrentChapterName && (wxStrcmp(CurrentChapterName, s) == 0))) &&
5043           (!CurrentSectionName || !(CurrentSectionName && (wxStrcmp(CurrentSectionName, s) == 0))) &&
5044           (!CurrentSubsectionName || !(CurrentSubsectionName && (wxStrcmp(CurrentSubsectionName, s) == 0)))
5045         )
5046*/
5047      {
5048          wxFprintf(Chapters, _T("{\\bkmkstart %s}{\\bkmkend %s}"), s,s);
5049      }
5050    }
5051    return false;
5052  }
5053  case ltPAGEREF:
5054  {
5055    if (start && useWord && !winHelp)
5056    {
5057      wxChar *s = GetArgData();
5058      wxFprintf(Chapters, _T("{\\field{\\*\\fldinst  PAGEREF %s \\\\* MERGEFORMAT }{\\fldrslt ??}}"),
5059              s);
5060    }
5061    return false;
5062  }
5063  case ltPOPREFONLY:
5064  {
5065    if (start)
5066      inPopRefSection = true;
5067    else
5068      inPopRefSection = false;
5069    break;
5070  }
5071  case ltINSERTATLEVEL:
5072  {
5073    // This macro allows you to insert text at a different level
5074    // from the current level, e.g. into the Sections from within a subsubsection.
5075    if (!winHelp & useWord)
5076        return false;
5077    static int currentLevelNo = 1;
5078    static FILE* oldLevelFile = Chapters;
5079    if (start)
5080    {
5081      switch (arg_no)
5082      {
5083        case 1:
5084        {
5085          oldLevelFile = CurrentOutput1;
5086
5087          wxChar *str = GetArgData();
5088          currentLevelNo = wxAtoi(str);
5089          FILE* outputFile;
5090          // TODO: cope with article style (no chapters)
5091          switch (currentLevelNo)
5092          {
5093            case 1:
5094            {
5095                outputFile = Chapters;
5096                break;
5097            }
5098            case 2:
5099            {
5100                outputFile = Sections;
5101                break;
5102            }
5103            case 3:
5104            {
5105                outputFile = Subsections;
5106                break;
5107            }
5108            case 4:
5109            {
5110                outputFile = Subsubsections;
5111                break;
5112            }
5113            default:
5114            {
5115                outputFile = NULL;
5116                break;
5117            }
5118          }
5119          if (outputFile)
5120            CurrentOutput1 = outputFile;
5121          return false;
5122        }
5123        case 2:
5124        {
5125          return true;
5126        }
5127        default:
5128          break;
5129      }
5130      return true;
5131    }
5132    else
5133    {
5134        if (arg_no == 2)
5135        {
5136            CurrentOutput1 = oldLevelFile;
5137        }
5138        return true;
5139    }
5140  }
5141  default:
5142    return DefaultOnArgument(macroId, arg_no, start);
5143  }
5144  return true;
5145}
5146
5147bool RTFGo(void)
5148{
5149    if (stopRunning)
5150        return false;
5151
5152    // Reset variables
5153    indentLevel = 0;
5154    forbidParindent = 0;
5155    contentsLineSection = NULL;
5156    contentsLineValue = NULL;
5157    descriptionItemArg = NULL;
5158    inTabular = false;
5159    inTable = false;
5160    inFigure = false;
5161    startRows = false;
5162    tableVerticalLineLeft = false;
5163    tableVerticalLineRight = false;
5164    noColumns = 0;
5165    startedSections = false;
5166    inVerbatim = false;
5167    browseId = 0;
5168
5169    if (!InputFile.empty() && !OutputFile.empty())
5170    {
5171        // Do some RTF-specific transformations on all the strings,
5172        // recursively
5173        Text2RTF(GetTopLevelChunk());
5174
5175        Contents = wxFopen(TmpContentsName, _T("w"));
5176        Chapters = wxFopen(_T("chapters.rtf"), _T("w"));
5177        if (winHelp)
5178        {
5179            Sections = wxFopen(_T("sections.rtf"), _T("w"));
5180            Subsections = wxFopen(_T("subsections.rtf"), _T("w"));
5181            Subsubsections = wxFopen(_T("subsubsections.rtf"), _T("w"));
5182            Popups = wxFopen(_T("popups.rtf"), _T("w"));
5183            if (winHelpContents)
5184            {
5185                WinHelpContentsFile = wxFopen(WinHelpContentsFileName, _T("w"));
5186                if (WinHelpContentsFile)
5187                    wxFprintf(WinHelpContentsFile, _T(":Base %s.hlp\n"), wxFileNameFromPath(FileRoot));
5188            }
5189
5190            if (!Sections || !Subsections || !Subsubsections || !Popups || (winHelpContents && !WinHelpContentsFile))
5191            {
5192                OnError(_T("Ouch! Could not open temporary file(s) for writing."));
5193                return false;
5194            }
5195        }
5196        if (!Contents || !Chapters)
5197        {
5198            OnError(_T("Ouch! Could not open temporary file(s) for writing."));
5199            return false;
5200        }
5201
5202        if (winHelp)
5203        {
5204            wxFprintf(Chapters, _T("\n#{\\footnote Contents}\n"));
5205            wxFprintf(Chapters, _T("${\\footnote Contents}\n"));
5206            wxFprintf(Chapters, _T("+{\\footnote %s}\n"), GetBrowseString());
5207            wxFprintf(Chapters, _T("K{\\footnote {K} %s}\n"), ContentsNameString);
5208            wxFprintf(Chapters, _T("!{\\footnote DisableButton(\"Up\")}\n"));
5209        }
5210        if (!winHelp)
5211        {
5212            wxFprintf(Chapters, _T("\\titlepg\n"));
5213            wxFprintf(Contents, _T("\\par\\pard\\pgnrestart\\sect\\titlepg"));
5214        }
5215
5216        // In WinHelp, Contents title takes font of title.
5217        // In linear RTF, same as chapter headings.
5218        wxFprintf(Contents, _T("{\\b\\fs%d %s}\\par\\par\\pard\n\n"),
5219            (winHelp ? titleFont : chapterFont)*2, ContentsNameString);
5220
5221        // By default, Swiss, 11 point.
5222        wxFprintf(Chapters, _T("\\f2\\fs22\n"));
5223
5224        PushEnvironmentStyle(_T("\\f2\\fs22\\sa200"));
5225
5226        SetCurrentOutput(Chapters);
5227
5228        if (stopRunning)
5229            return false;
5230
5231        OnInform(_T("Converting..."));
5232
5233        TraverseDocument();
5234
5235        FILE *Header = wxFopen(_T("header.rtf"), _T("w"));
5236        if (!Header)
5237        {
5238            OnError(_T("Ouch! Could not open temporary file header.rtf for writing."));
5239            return false;
5240        }
5241        WriteRTFHeader(Header);
5242        fclose(Header);
5243
5244        PopEnvironmentStyle();
5245
5246        Tex2RTFYield(true);
5247        if (winHelp)
5248        {
5249//          wxFprintf(Contents, _T("\\page\n"));
5250            wxFprintf(Chapters, _T("\\page\n"));
5251            wxFprintf(Sections, _T("\\page\n"));
5252            wxFprintf(Subsections, _T("\\page\n"));
5253            wxFprintf(Subsubsections, _T("\\page\n\n"));
5254            wxFprintf(Popups, _T("\\page\n}\n"));
5255        }
5256
5257//      TexOutput(_T("\n\\info{\\doccomm Document created by Julian Smart's Tex2RTF.}\n"));
5258        if (!winHelp)
5259            TexOutput(_T("}\n"));
5260        fclose(Contents); Contents = NULL;
5261        fclose(Chapters); Chapters = NULL;
5262        if (winHelp)
5263        {
5264            fclose(Sections); Sections = NULL;
5265            fclose(Subsections); Subsections = NULL;
5266            fclose(Subsubsections); Subsubsections = NULL;
5267            fclose(Popups); Popups = NULL;
5268            if (winHelpContents)
5269            {
5270                fclose(WinHelpContentsFile); WinHelpContentsFile = NULL;
5271            }
5272        }
5273
5274        if (winHelp)
5275        {
5276            wxConcatFiles(_T("header.rtf"), _T("chapters.rtf"), _T("tmp1.rtf"));
5277            Tex2RTFYield(true);
5278            wxConcatFiles(_T("tmp1.rtf"), _T("sections.rtf"), _T("tmp2.rtf"));
5279            Tex2RTFYield(true);
5280            wxConcatFiles(_T("tmp2.rtf"), _T("subsections.rtf"), _T("tmp3.rtf"));
5281            Tex2RTFYield(true);
5282            wxConcatFiles(_T("tmp3.rtf"), _T("subsubsections.rtf"), _T("tmp4.rtf"));
5283            Tex2RTFYield(true);
5284            wxConcatFiles(_T("tmp4.rtf"), _T("popups.rtf"), OutputFile);
5285            Tex2RTFYield(true);
5286
5287            wxRemoveFile(_T("tmp1.rtf"));
5288            wxRemoveFile(_T("tmp2.rtf"));
5289            wxRemoveFile(_T("tmp3.rtf"));
5290            wxRemoveFile(_T("tmp4.rtf"));
5291        }
5292        else
5293        {
5294            wxConcatFiles(_T("header.rtf"), _T("chapters.rtf"), _T("tmp1.rtf"));
5295            Tex2RTFYield(true);
5296            if (wxFileExists(OutputFile))
5297                wxRemoveFile(OutputFile);
5298
5299            wxString cwdStr = wxGetCwd();
5300
5301            wxString outputDirStr = wxPathOnly(OutputFile);
5302
5303            // Determine if the temp file and the output file are in the same directory,
5304            // and if they are, then just rename the temp file rather than copying
5305            // it, as this is much faster when working with large (multi-megabyte files)
5306            if ((outputDirStr.empty()) ||  // no path specified on output file
5307                (cwdStr != outputDirStr)) // paths do not match
5308            {
5309                wxRenameFile(_T("tmp1.rtf"), OutputFile);
5310            }
5311            else
5312            {
5313                wxCopyFile(_T("tmp1.rtf"), OutputFile);
5314            }
5315            Tex2RTFYield(true);
5316            wxRemoveFile(_T("tmp1.rtf"));
5317        }
5318
5319        if (wxFileExists(ContentsName)) wxRemoveFile(ContentsName);
5320
5321        if (!wxRenameFile(TmpContentsName, ContentsName))
5322        {
5323            wxCopyFile(TmpContentsName, ContentsName);
5324            wxRemoveFile(TmpContentsName);
5325        }
5326
5327        wxRemoveFile(_T("chapters.rtf"));
5328        wxRemoveFile(_T("header.rtf"));
5329
5330        if (winHelp)
5331        {
5332            wxRemoveFile(_T("sections.rtf"));
5333            wxRemoveFile(_T("subsections.rtf"));
5334            wxRemoveFile(_T("subsubsections.rtf"));
5335            wxRemoveFile(_T("popups.rtf"));
5336        }
5337        if (winHelp && generateHPJ)
5338            WriteHPJ(OutputFile);
5339        return true;
5340    }
5341    return false;
5342}
5343