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