]> git.saurik.com Git - wxWidgets.git/blob - utils/tex2rtf/src/htmlutil.cpp
changed version number
[wxWidgets.git] / utils / tex2rtf / src / htmlutil.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: htmlutil.cpp
3 // Purpose: Converts Latex to HTML
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 "table.h"
30
31
32 extern wxHashTable TexReferences;
33
34
35 extern void DecToHex(int, char *);
36 void GenerateHTMLIndexFile(char *fname);
37
38 void GenerateHTMLWorkshopFiles(char *fname);
39 void HTMLWorkshopAddToContents(int level, char *s, char *file);
40 void HTMLWorkshopStartContents();
41 void HTMLWorkshopEndContents();
42
43 void OutputContentsFrame(void);
44
45 #include "readshg.h" // Segmented hypergraphics parsing
46
47 char *ChaptersName = NULL;
48 char *SectionsName = NULL;
49 char *SubsectionsName = NULL;
50 char *SubsubsectionsName = NULL;
51 char *TitlepageName = NULL;
52 char *lastFileName = NULL;
53 char *lastTopic = NULL;
54 char *currentFileName = NULL;
55 char *contentsFrameName = NULL;
56
57 static TexChunk *descriptionItemArg = NULL;
58 static TexChunk *helpRefFilename = NULL;
59 static TexChunk *helpRefText = NULL;
60 static int indentLevel = 0;
61 static int citeCount = 1;
62 extern FILE *Contents;
63 FILE *FrameContents = NULL;
64 FILE *Titlepage = NULL;
65 // FILE *FrameTitlepage = NULL;
66 int fileId = 0;
67 bool subsectionStarted = FALSE;
68
69 // Which column of a row are we in? (Assumes no nested tables, of course)
70 int currentColumn = 0;
71
72 // Are we in verbatim mode? If so, format differently.
73 static bool inVerbatim = FALSE;
74
75 // Need to know whether we're in a table or figure for benefit
76 // of listoffigures/listoftables
77 static bool inFigure = FALSE;
78 static bool inTable = FALSE;
79
80 // This is defined in the Tex2Any library.
81 extern char *BigBuffer;
82
83 // DHS Two-column table dimensions.
84 static int TwoColWidthA = -1;
85 static int TwoColWidthB = -1;
86
87
88 class HyperReference: public wxObject
89 {
90 public:
91 char *refName;
92 char *refFile;
93 HyperReference(char *name, char *file)
94 {
95 if (name) refName = copystring(name);
96 if (file) refFile = copystring(file);
97 }
98 };
99
100 class TexNextPage: public wxObject
101 {
102 public:
103 char *label;
104 char *filename;
105 TexNextPage(char *theLabel, char *theFile)
106 {
107 label = copystring(theLabel);
108 filename = copystring(theFile);
109 }
110 ~TexNextPage(void)
111 {
112 delete[] label;
113 delete[] filename;
114 }
115 };
116
117 wxHashTable TexNextPages(wxKEY_STRING);
118
119 static char *CurrentChapterName = NULL;
120 static char *CurrentChapterFile = NULL;
121 static char *CurrentSectionName = NULL;
122 static char *CurrentSectionFile = NULL;
123 static char *CurrentSubsectionName = NULL;
124 static char *CurrentSubsectionFile = NULL;
125 static char *CurrentSubsubsectionName = NULL;
126 static char *CurrentSubsubsectionFile = NULL;
127 static char *CurrentTopic = NULL;
128
129 static void SetCurrentTopic(char *s)
130 {
131 if (CurrentTopic) delete[] CurrentTopic;
132 CurrentTopic = copystring(s);
133 }
134
135 void SetCurrentChapterName(char *s, char *file)
136 {
137 if (CurrentChapterName) delete[] CurrentChapterName;
138 CurrentChapterName = copystring(s);
139 if (CurrentChapterFile) delete[] CurrentChapterFile;
140 CurrentChapterFile = copystring(file);
141
142 currentFileName = CurrentChapterFile;
143
144 SetCurrentTopic(s);
145 }
146 void SetCurrentSectionName(char *s, char *file)
147 {
148 if (CurrentSectionName) delete[] CurrentSectionName;
149 CurrentSectionName = copystring(s);
150 if (CurrentSectionFile) delete[] CurrentSectionFile;
151 CurrentSectionFile = copystring(file);
152
153 currentFileName = CurrentSectionFile;
154 SetCurrentTopic(s);
155 }
156 void SetCurrentSubsectionName(char *s, char *file)
157 {
158 if (CurrentSubsectionName) delete[] CurrentSubsectionName;
159 CurrentSubsectionName = copystring(s);
160 if (CurrentSubsectionFile) delete[] CurrentSubsectionFile;
161 CurrentSubsectionFile = copystring(file);
162 currentFileName = CurrentSubsectionFile;
163 SetCurrentTopic(s);
164 }
165 void SetCurrentSubsubsectionName(char *s, char *file)
166 {
167 if (CurrentSubsubsectionName) delete[] CurrentSubsubsectionName;
168 CurrentSubsubsectionName = copystring(s);
169 if (CurrentSubsubsectionFile) delete[] CurrentSubsubsectionFile;
170 CurrentSubsubsectionFile = copystring(file);
171 currentFileName = CurrentSubsubsectionFile;
172 SetCurrentTopic(s);
173 }
174
175 /*
176 * Close former filedescriptor and reopen using another filename.
177 *
178 */
179
180 void ReopenFile(FILE **fd, char **fileName)
181 {
182 if (*fd)
183 {
184 fprintf(*fd, "\n</BODY></HTML>\n");
185 fclose(*fd);
186 }
187 fileId ++;
188 char buf[400];
189 if (truncateFilenames)
190 sprintf(buf, "%s%d.htm", FileRoot, fileId);
191 else
192 sprintf(buf, "%s%d.html", FileRoot, fileId);
193 if (*fileName) delete[] *fileName;
194 *fileName = copystring(FileNameFromPath(buf));
195 *fd = fopen(buf, "w");
196 fprintf(*fd, "<HTML>\n");
197 }
198
199 /*
200 * Reopen section contents file, i.e. the index appended to each section
201 * in subsectionCombine mode
202 */
203
204 static char *SectionContentsFilename = NULL;
205 static FILE *SectionContentsFD = NULL;
206
207 void ReopenSectionContentsFile(void)
208 {
209 if ( SectionContentsFD )
210 {
211 fclose(SectionContentsFD);
212 }
213 if ( SectionContentsFilename )
214 delete[] SectionContentsFilename;
215 SectionContentsFD = NULL;
216 SectionContentsFilename = NULL;
217
218 // Create the name from the current section filename
219 if ( CurrentSectionFile )
220 {
221 char buf[256];
222 strcpy(buf, CurrentSectionFile);
223 wxStripExtension(buf);
224 strcat(buf, ".con");
225 SectionContentsFilename = copystring(buf);
226
227 SectionContentsFD = fopen(SectionContentsFilename, "w");
228 }
229 }
230
231
232 /*
233 * Given a TexChunk with a string value, scans through the string
234 * converting Latex-isms into HTML-isms, such as 2 newlines -> <P>.
235 *
236 */
237
238 void ProcessText2HTML(TexChunk *chunk)
239 {
240 bool changed = FALSE;
241 int ptr = 0;
242 int i = 0;
243 char ch = 1;
244 int len = strlen(chunk->value);
245 while (ch != 0)
246 {
247 ch = chunk->value[i];
248
249 // 2 newlines means \par
250 if (!inVerbatim && chunk->value[i] == 10 && ((len > i+1 && chunk->value[i+1] == 10) ||
251 ((len > i+1 && chunk->value[i+1] == 13) &&
252 (len > i+2 && chunk->value[i+2] == 10))))
253 {
254 BigBuffer[ptr] = 0; strcat(BigBuffer, "<P>\n\n"); ptr += 5;
255 i += 2;
256 changed = TRUE;
257 }
258 else if (!inVerbatim && ch == '`' && (len >= i+1 && chunk->value[i+1] == '`'))
259 {
260 BigBuffer[ptr] = '"'; ptr ++;
261 i += 2;
262 changed = TRUE;
263 }
264 else if (!inVerbatim && ch == '`') // Change ` to '
265 {
266 BigBuffer[ptr] = 39; ptr ++;
267 i += 1;
268 changed = TRUE;
269 }
270 else if (ch == '<') // Change < to &lt
271 {
272 BigBuffer[ptr] = 0;
273 strcat(BigBuffer, "&lt;");
274 ptr += 4;
275 i += 1;
276 changed = TRUE;
277 }
278 else if (ch == '>') // Change > to &gt
279 {
280 BigBuffer[ptr] = 0;
281 strcat(BigBuffer, "&gt;");
282 ptr += 4;
283 i += 1;
284 changed = TRUE;
285 }
286 else
287 {
288 BigBuffer[ptr] = ch;
289 i ++;
290 ptr ++;
291 }
292 }
293 BigBuffer[ptr] = 0;
294
295 if (changed)
296 {
297 delete chunk->value;
298 chunk->value = copystring(BigBuffer);
299 }
300 }
301
302 /*
303 * Scan through all chunks starting from the given one,
304 * calling ProcessText2HTML to convert Latex-isms to RTF-isms.
305 * This should be called after Tex2Any has parsed the file,
306 * and before TraverseDocument is called.
307 *
308 */
309
310 void Text2HTML(TexChunk *chunk)
311 {
312 Tex2RTFYield();
313 if (stopRunning) return;
314
315 switch (chunk->type)
316 {
317 case CHUNK_TYPE_MACRO:
318 {
319 TexMacroDef *def = chunk->def;
320
321 if (def && def->ignore)
322 return;
323
324 if (def && (def->macroId == ltVERBATIM || def->macroId == ltVERB || def->macroId == ltSPECIAL))
325 inVerbatim = TRUE;
326
327 wxNode *node = chunk->children.First();
328 while (node)
329 {
330 TexChunk *child_chunk = (TexChunk *)node->Data();
331 Text2HTML(child_chunk);
332 node = node->Next();
333 }
334
335 if (def && (def->macroId == ltVERBATIM || def->macroId == ltVERB || def->macroId == ltSPECIAL))
336 inVerbatim = FALSE;
337
338 break;
339 }
340 case CHUNK_TYPE_ARG:
341 {
342 wxNode *node = chunk->children.First();
343 while (node)
344 {
345 TexChunk *child_chunk = (TexChunk *)node->Data();
346 Text2HTML(child_chunk);
347 node = node->Next();
348 }
349
350 break;
351 }
352 case CHUNK_TYPE_STRING:
353 {
354 if (chunk->value)
355 ProcessText2HTML(chunk);
356 break;
357 }
358 }
359 }
360
361 /*
362 * Add appropriate browse buttons to this page.
363 *
364 */
365
366 void AddBrowseButtons(char *upLabel, char *upFilename,
367 char *previousLabel, char *previousFilename,
368 char *thisLabel, char *thisFilename)
369 {
370 char contentsReferenceBuf[80];
371 char upReferenceBuf[80];
372 char backReferenceBuf[80];
373 char forwardReferenceBuf[80];
374 if (htmlBrowseButtons == HTML_BUTTONS_NONE)
375 return;
376
377 char *contentsReference = NULL;
378 if (htmlBrowseButtons == HTML_BUTTONS_TEXT)
379 contentsReference = ContentsNameString;
380 else
381 {
382 // contentsReference = "<img align=center src=\"contents.gif\" BORDER=0 ALT=\"Contents\">";
383 contentsReference = contentsReferenceBuf;
384 sprintf(contentsReference, "<img align=center src=\"%s\" BORDER=0 ALT=\"Contents\">", ConvertCase("contents.gif"));
385 }
386
387 char *upReference = NULL;
388 if (htmlBrowseButtons == HTML_BUTTONS_TEXT)
389 upReference = UpNameString;
390 else
391 {
392 // upReference = "<img align=center src=\"up.gif\" ALT=\"Up\">";
393 upReference = upReferenceBuf;
394 sprintf(upReference, "<img align=center src=\"%s\" BORDER=0 ALT=\"Up\">", ConvertCase("up.gif"));
395 }
396
397 char *backReference = NULL;
398 if (htmlBrowseButtons == HTML_BUTTONS_TEXT)
399 backReference = "&lt;&lt;";
400 else
401 {
402 // backReference = "<img align=center src=\"back.gif\" ALT=\"Previous\">";
403 backReference = backReferenceBuf;
404 sprintf(backReference, "<img align=center src=\"%s\" BORDER=0 ALT=\"Previous\">", ConvertCase("back.gif"));
405 }
406
407 char *forwardReference = NULL;
408 if (htmlBrowseButtons == HTML_BUTTONS_TEXT)
409 forwardReference = "&gt;&gt;";
410 else
411 {
412 // forwardReference = "<img align=center src=\"forward.gif\" ALT=\"Next\">";
413 forwardReference = forwardReferenceBuf;
414 sprintf(forwardReference, "<img align=center src=\"%s\" BORDER=0 ALT=\"Next\">", ConvertCase("forward.gif"));
415 }
416
417 TexOutput("<CENTER>");
418
419 char buf[200];
420
421 /*
422 * Contents button
423 *
424 */
425
426 if (truncateFilenames)
427 {
428 char buf1[80];
429 strcpy(buf1, ConvertCase(FileNameFromPath(FileRoot)));
430 sprintf(buf, "\n<A HREF=\"%s.%s\">%s</A> ", buf1, ConvertCase("htm"), contentsReference);
431 }
432 else
433 {
434 char buf1[80];
435 strcpy(buf1, ConvertCase(FileNameFromPath(FileRoot)));
436 sprintf(buf, "\n<A HREF=\"%s%s\">%s</A> ", buf1, ConvertCase("_contents.html"), contentsReference);
437 }
438 // TexOutput("<NOFRAMES>");
439 TexOutput(buf);
440 // TexOutput("</NOFRAMES>");
441
442 /*
443 * Up button
444 *
445 */
446
447 if (upLabel && upFilename)
448 {
449 if (strlen(upLabel) > 0)
450 sprintf(buf, "<A HREF=\"%s#%s\">%s</A> ", ConvertCase(upFilename), upLabel, upReference);
451 else
452 sprintf(buf, "<A HREF=\"%s\">%s</A> ", ConvertCase(upFilename), upReference);
453 if (strcmp(upLabel, "contents") == 0)
454 {
455 // TexOutput("<NOFRAMES>");
456 TexOutput(buf);
457 // TexOutput("</NOFRAMES>");
458 }
459 else
460 TexOutput(buf);
461 }
462
463 /*
464 * << button
465 *
466 */
467
468 if (previousLabel && previousFilename)
469 {
470 sprintf(buf, "<A HREF=\"%s#%s\">%s</A> ", ConvertCase(previousFilename), previousLabel, backReference);
471 if (strcmp(previousLabel, "contents") == 0)
472 {
473 // TexOutput("<NOFRAMES>");
474 TexOutput(buf);
475 // TexOutput("</NOFRAMES>");
476 }
477 else
478 TexOutput(buf);
479 }
480 else
481 {
482 // A placeholder so the buttons don't keep moving position
483 sprintf(buf, "%s ", backReference);
484 TexOutput(buf);
485 }
486
487 char *nextLabel = NULL;
488 char *nextFilename = NULL;
489
490 // Get the next page, and record the previous page's 'next' page
491 // (i.e. this page)
492 TexNextPage *nextPage = (TexNextPage *)TexNextPages.Get(thisLabel);
493 if (nextPage)
494 {
495 nextLabel = nextPage->label;
496 nextFilename = nextPage->filename;
497 }
498 if (previousLabel && previousFilename)
499 {
500 TexNextPage *oldNextPage = (TexNextPage *)TexNextPages.Get(previousLabel);
501 if (oldNextPage)
502 {
503 delete oldNextPage;
504 TexNextPages.Delete(previousLabel);
505 }
506 TexNextPage *newNextPage = new TexNextPage(thisLabel, thisFilename);
507 TexNextPages.Put(previousLabel, newNextPage);
508 }
509
510 /*
511 * >> button
512 *
513 */
514
515 if (nextLabel && nextFilename)
516 {
517 sprintf(buf, "<A HREF=\"%s#%s\">%s</A> ", ConvertCase(nextFilename), nextLabel, forwardReference);
518 TexOutput(buf);
519 }
520 else
521 {
522 // A placeholder so the buttons don't keep moving position
523 sprintf(buf, "%s ", forwardReference);
524 TexOutput(buf);
525 }
526
527 /*
528 * Horizontal rule to finish it off nicely.
529 *
530 */
531 TexOutput("</CENTER>");
532 TexOutput("<HR>\n");
533
534 // Update last topic/filename
535 if (lastFileName)
536 delete[] lastFileName;
537 lastFileName = copystring(thisFilename);
538 if (lastTopic)
539 delete[] lastTopic;
540 lastTopic = copystring(thisLabel);
541 }
542
543 // A colour string is either 3 numbers separated by semicolons (RGB),
544 // or a reference to a GIF. Return the filename or a hex string like #934CE8
545 char *ParseColourString(char *bkStr, bool *isPicture)
546 {
547 static char resStr[300];
548 strcpy(resStr, bkStr);
549 char *tok1 = strtok(resStr, ";");
550 char *tok2 = strtok(NULL, ";");
551 if (tok1)
552 {
553 if (!tok2)
554 {
555 *isPicture = TRUE;
556 return resStr;
557 }
558 else
559 {
560 *isPicture = FALSE;
561 char *tok3 = strtok(NULL, ";");
562 if (tok3)
563 {
564 // Now convert 3 strings into decimal numbers, and then hex numbers.
565 int red = atoi(tok1);
566 int green = atoi(tok2);
567 int blue = atoi(tok3);
568
569 strcpy(resStr, "#");
570
571 char buf[3];
572 DecToHex(red, buf);
573 strcat(resStr, buf);
574 DecToHex(green, buf);
575 strcat(resStr, buf);
576 DecToHex(blue, buf);
577 strcat(resStr, buf);
578 return resStr;
579 }
580 else return NULL;
581 }
582 }
583 else return NULL;
584 }
585
586 // Output start of <BODY> block
587 void OutputBodyStart(void)
588 {
589 TexOutput("\n<BODY");
590 if (backgroundImageString)
591 {
592 bool isPicture = FALSE;
593 char *s = ParseColourString(backgroundImageString, &isPicture);
594 if (s)
595 {
596 TexOutput(" BACKGROUND=\""); TexOutput(s); TexOutput("\"");
597 }
598 }
599 if (backgroundColourString)
600 {
601 bool isPicture = FALSE;
602 char *s = ParseColourString(backgroundColourString, &isPicture);
603 if (s)
604 {
605 TexOutput(" BGCOLOR="); TexOutput(s);
606 }
607 }
608
609 // Set foreground text colour, if one is specified
610 if (textColourString)
611 {
612 bool isPicture = FALSE;
613 char *s = ParseColourString(textColourString, &isPicture);
614 if (s)
615 {
616 TexOutput(" TEXT="); TexOutput(s);
617 }
618 }
619 // Set link text colour, if one is specified
620 if (linkColourString)
621 {
622 bool isPicture = FALSE;
623 char *s = ParseColourString(linkColourString, &isPicture);
624 if (s)
625 {
626 TexOutput(" LINK="); TexOutput(s);
627 }
628 }
629 // Set followed link text colour, if one is specified
630 if (followedLinkColourString)
631 {
632 bool isPicture = FALSE;
633 char *s = ParseColourString(followedLinkColourString, &isPicture);
634 if (s)
635 {
636 TexOutput(" VLINK="); TexOutput(s);
637 }
638 }
639 TexOutput(">\n");
640 }
641
642 // Called on start/end of macro examination
643 void HTMLOnMacro(int macroId, int no_args, bool start)
644 {
645 switch (macroId)
646 {
647 case ltCHAPTER:
648 case ltCHAPTERSTAR:
649 case ltCHAPTERHEADING:
650 {
651 if (!start)
652 {
653 sectionNo = 0;
654 figureNo = 0;
655 subsectionNo = 0;
656 subsubsectionNo = 0;
657 if (macroId != ltCHAPTERSTAR)
658 chapterNo ++;
659
660 SetCurrentOutput(NULL);
661 startedSections = TRUE;
662
663 char *topicName = FindTopicName(GetNextChunk());
664 ReopenFile(&Chapters, &ChaptersName);
665 AddTexRef(topicName, ChaptersName, ChapterNameString);
666
667 SetCurrentChapterName(topicName, ChaptersName);
668 if (htmlWorkshopFiles) HTMLWorkshopAddToContents(0, topicName, ChaptersName);
669
670 SetCurrentOutput(Chapters);
671
672 TexOutput("<head><title>");
673 OutputCurrentSection(); // Repeat section header
674 TexOutput("</title></head>\n");
675 OutputBodyStart();
676
677 char titleBuf[200];
678 if (truncateFilenames)
679 sprintf(titleBuf, "%s.htm", FileNameFromPath(FileRoot));
680 else
681 sprintf(titleBuf, "%s_contents.html", FileNameFromPath(FileRoot));
682
683 fprintf(Chapters, "<A NAME=\"%s\"></A>", topicName);
684
685 AddBrowseButtons("", titleBuf, // Up
686 lastTopic, lastFileName, // Last topic
687 topicName, ChaptersName); // This topic
688
689 fprintf(Contents, "\n<LI><A HREF=\"%s#%s\">", ConvertCase(ChaptersName), topicName);
690
691 if (htmlFrameContents && FrameContents)
692 {
693 SetCurrentOutput(FrameContents);
694 fprintf(FrameContents, "\n<LI><A HREF=\"%s#%s\" TARGET=\"mainwindow\">", ConvertCase(ChaptersName), topicName);
695 OutputCurrentSection();
696 fprintf(FrameContents, "</A>\n");
697 }
698
699 SetCurrentOutputs(Contents, Chapters);
700 fprintf(Chapters, "\n<H2>");
701 OutputCurrentSection();
702 fprintf(Contents, "</A>\n");
703 fprintf(Chapters, "</H2>\n");
704
705 SetCurrentOutput(Chapters);
706
707 // Add this section title to the list of keywords
708 if (htmlIndex)
709 {
710 OutputCurrentSectionToString(wxBuffer);
711 AddKeyWordForTopic(topicName, wxBuffer, ConvertCase(currentFileName));
712 }
713 }
714 break;
715 }
716 case ltSECTION:
717 case ltSECTIONSTAR:
718 case ltSECTIONHEADING:
719 case ltGLOSS:
720 {
721 if (!start)
722 {
723 subsectionNo = 0;
724 subsubsectionNo = 0;
725 subsectionStarted = FALSE;
726
727 if (macroId != ltSECTIONSTAR)
728 sectionNo ++;
729
730 SetCurrentOutput(NULL);
731 startedSections = TRUE;
732
733 char *topicName = FindTopicName(GetNextChunk());
734 ReopenFile(&Sections, &SectionsName);
735 AddTexRef(topicName, SectionsName, SectionNameString);
736
737 SetCurrentSectionName(topicName, SectionsName);
738 if (htmlWorkshopFiles) HTMLWorkshopAddToContents(1, topicName, SectionsName);
739
740 SetCurrentOutput(Sections);
741 TexOutput("<head><title>");
742 OutputCurrentSection();
743 TexOutput("</title></head>\n");
744 OutputBodyStart();
745
746 fprintf(Sections, "<A NAME=\"%s\"></A>", topicName);
747 AddBrowseButtons(CurrentChapterName, CurrentChapterFile, // Up
748 lastTopic, lastFileName, // Last topic
749 topicName, SectionsName); // This topic
750
751 FILE *jumpFrom = ((DocumentStyle == LATEX_ARTICLE) ? Contents : Chapters);
752
753 SetCurrentOutputs(jumpFrom, Sections);
754 if (DocumentStyle == LATEX_ARTICLE)
755 fprintf(jumpFrom, "\n<LI><A HREF=\"%s#%s\">", ConvertCase(SectionsName), topicName);
756 else
757 fprintf(jumpFrom, "\n<A HREF=\"%s#%s\"><B>", ConvertCase(SectionsName), topicName);
758
759 fprintf(Sections, "\n<H2>");
760 OutputCurrentSection();
761
762 if (DocumentStyle == LATEX_ARTICLE)
763 fprintf(jumpFrom, "</A>\n");
764 else
765 fprintf(jumpFrom, "</B></A><BR>\n");
766 fprintf(Sections, "</H2>\n");
767
768 SetCurrentOutput(Sections);
769 // Add this section title to the list of keywords
770 if (htmlIndex)
771 {
772 OutputCurrentSectionToString(wxBuffer);
773 AddKeyWordForTopic(topicName, wxBuffer, currentFileName);
774 }
775 }
776 break;
777 }
778 case ltSUBSECTION:
779 case ltSUBSECTIONSTAR:
780 case ltMEMBERSECTION:
781 case ltFUNCTIONSECTION:
782 {
783 if (!start)
784 {
785 if (!Sections)
786 {
787 OnError("You cannot have a subsection before a section!");
788 }
789 else
790 {
791 subsubsectionNo = 0;
792
793 if (macroId != ltSUBSECTIONSTAR)
794 subsectionNo ++;
795
796 if ( combineSubSections && !subsectionStarted )
797 {
798 // Read old .con file in at this point
799 char buf[256];
800 strcpy(buf, CurrentSectionFile);
801 wxStripExtension(buf);
802 strcat(buf, ".con");
803 FILE *fd = fopen(buf, "r");
804 if ( fd )
805 {
806 int ch = getc(fd);
807 while (ch != EOF)
808 {
809 putc(ch, Sections);
810 ch = getc(fd);
811 }
812 fclose(fd);
813 }
814 fprintf(Sections, "<P>\n");
815
816 // Close old file, create a new file for the sub(sub)section contents entries
817 ReopenSectionContentsFile();
818 }
819
820 startedSections = TRUE;
821 subsectionStarted = TRUE;
822
823 char *topicName = FindTopicName(GetNextChunk());
824
825 if ( !combineSubSections )
826 {
827 SetCurrentOutput(NULL);
828 ReopenFile(&Subsections, &SubsectionsName);
829 AddTexRef(topicName, SubsectionsName, SubsectionNameString);
830 SetCurrentSubsectionName(topicName, SubsectionsName);
831 if (htmlWorkshopFiles) HTMLWorkshopAddToContents(2, topicName, SubsectionsName);
832 SetCurrentOutput(Subsections);
833
834 TexOutput("<head><title>");
835 OutputCurrentSection();
836 TexOutput("</title></head>\n");
837 OutputBodyStart();
838
839 fprintf(Subsections, "<A NAME=\"%s\"></A>", topicName);
840 AddBrowseButtons(CurrentSectionName, CurrentSectionFile, // Up
841 lastTopic, lastFileName, // Last topic
842 topicName, SubsectionsName); // This topic
843
844 SetCurrentOutputs(Sections, Subsections);
845 fprintf(Sections, "\n<A HREF=\"%s#%s\"><B>", ConvertCase(SubsectionsName), topicName);
846
847 fprintf(Subsections, "\n<H3>");
848 OutputCurrentSection();
849 fprintf(Sections, "</B></A><BR>\n");
850 fprintf(Subsections, "</H3>\n");
851
852 SetCurrentOutput(Subsections);
853 }
854 else
855 {
856 AddTexRef(topicName, SectionsName, SubsectionNameString);
857 SetCurrentSubsectionName(topicName, SectionsName);
858
859 // if ( subsectionNo != 0 )
860 fprintf(Sections, "\n<HR>\n");
861
862 // We're putting everything into the section file
863 fprintf(Sections, "<A NAME=\"%s\"></A>", topicName);
864 fprintf(Sections, "\n<H3>");
865 OutputCurrentSection();
866 fprintf(Sections, "</H3>\n");
867
868 SetCurrentOutput(SectionContentsFD);
869 fprintf(SectionContentsFD, "<A HREF=\"#%s\">", topicName);
870 OutputCurrentSection();
871 TexOutput("</A><BR>\n");
872
873 if (htmlWorkshopFiles) HTMLWorkshopAddToContents(2, topicName, SectionsName);
874 SetCurrentOutput(Sections);
875 }
876 // Add this section title to the list of keywords
877 if (htmlIndex)
878 {
879 OutputCurrentSectionToString(wxBuffer);
880 AddKeyWordForTopic(topicName, wxBuffer, currentFileName);
881 }
882
883 }
884 }
885 break;
886 }
887 case ltSUBSUBSECTION:
888 case ltSUBSUBSECTIONSTAR:
889 {
890 if (!start)
891 {
892 if (!Subsections && !combineSubSections)
893 {
894 OnError("You cannot have a subsubsection before a subsection!");
895 }
896 else
897 {
898 if (macroId != ltSUBSUBSECTIONSTAR)
899 subsubsectionNo ++;
900
901 startedSections = TRUE;
902
903 char *topicName = FindTopicName(GetNextChunk());
904
905 if ( !combineSubSections )
906 {
907 SetCurrentOutput(NULL);
908 ReopenFile(&Subsubsections, &SubsubsectionsName);
909 AddTexRef(topicName, SubsubsectionsName, SubsubsectionNameString);
910 SetCurrentSubsubsectionName(topicName, SubsubsectionsName);
911 if (htmlWorkshopFiles) HTMLWorkshopAddToContents(3, topicName, SubsubsectionsName);
912
913 SetCurrentOutput(Subsubsections);
914 TexOutput("<head><title>");
915 OutputCurrentSection();
916 TexOutput("</title></head>\n");
917 OutputBodyStart();
918
919 fprintf(Subsubsections, "<A NAME=\"%s\"></A>", topicName);
920
921 AddBrowseButtons(CurrentSubsectionName, CurrentSubsectionFile, // Up
922 lastTopic, lastFileName, // Last topic
923 topicName, SubsubsectionsName); // This topic
924
925 SetCurrentOutputs(Subsections, Subsubsections);
926 fprintf(Subsections, "\n<A HREF=\"%s#%s\"><B>", ConvertCase(SubsubsectionsName), topicName);
927
928 fprintf(Subsubsections, "\n<H3>");
929 OutputCurrentSection();
930 fprintf(Subsections, "</B></A><BR>\n");
931 fprintf(Subsubsections, "</H3>\n");
932 }
933 else
934 {
935 AddTexRef(topicName, SectionsName, SubsubsectionNameString);
936 SetCurrentSubsectionName(topicName, SectionsName);
937 fprintf(Sections, "\n<HR>\n");
938
939 // We're putting everything into the section file
940 fprintf(Sections, "<A NAME=\"%s\"></A>", topicName);
941 fprintf(Sections, "\n<H3>");
942 OutputCurrentSection();
943 fprintf(Sections, "</H3>\n");
944 /* TODO: where do we put subsubsection contents entry - indented, with subsection entries?
945 SetCurrentOutput(SectionContentsFD);
946 fprintf(SectionContentsFD, "<A HREF=\"#%s\">", topicName);
947 OutputCurrentSection();
948 TexOutput("</A><BR>");
949 */
950 if (htmlWorkshopFiles) HTMLWorkshopAddToContents(2, topicName, SectionsName);
951 SetCurrentOutput(Sections);
952 }
953
954 // Add this section title to the list of keywords
955 if (htmlIndex)
956 {
957 OutputCurrentSectionToString(wxBuffer);
958 AddKeyWordForTopic(topicName, wxBuffer, currentFileName);
959 }
960 }
961 }
962 break;
963 }
964 case ltFUNC:
965 case ltPFUNC:
966 {
967 if ( !combineSubSections )
968 SetCurrentOutput(Subsections);
969 else
970 SetCurrentOutput(Sections);
971 if (start)
972 {
973 }
974 else
975 {
976 }
977 break;
978 }
979 case ltCLIPSFUNC:
980 {
981 if ( !combineSubSections )
982 SetCurrentOutput(Subsections);
983 else
984 SetCurrentOutput(Sections);
985 if (start)
986 {
987 }
988 else
989 {
990 }
991 break;
992 }
993 case ltMEMBER:
994 {
995 if ( !combineSubSections )
996 SetCurrentOutput(Subsections);
997 else
998 SetCurrentOutput(Sections);
999 if (start)
1000 {
1001 }
1002 else
1003 {
1004 }
1005 break;
1006 }
1007 case ltVOID:
1008 // if (start)
1009 // TexOutput("<B>void</B>");
1010 break;
1011 case ltHARDY:
1012 if (start)
1013 TexOutput("HARDY");
1014 break;
1015 case ltWXCLIPS:
1016 if (start)
1017 TexOutput("wxCLIPS");
1018 break;
1019 case ltAMPERSAND:
1020 if (start)
1021 TexOutput("&amp;");
1022 break;
1023 case ltSPECIALAMPERSAND:
1024 {
1025 if (start)
1026 {
1027 if (inTabular)
1028 {
1029 // End cell, start cell
1030 TexOutput("</TD>");
1031
1032 // Start new row and cell, setting alignment for the first cell.
1033 if (currentColumn < noColumns)
1034 currentColumn ++;
1035
1036 char buf[100];
1037 if (TableData[currentColumn].justification == 'c')
1038 sprintf(buf, "\n<TD ALIGN=CENTER>");
1039 else if (TableData[currentColumn].justification == 'r')
1040 sprintf(buf, "\n<TD ALIGN=RIGHT>");
1041 else if (TableData[currentColumn].absWidth)
1042 {
1043 // Convert from points * 20 into pixels.
1044 int points = TableData[currentColumn].width / 20;
1045
1046 // Say the display is 100 DPI (dots/pixels per inch).
1047 // There are 72 pts to the inch. So 1pt = 1/72 inch, or 100 * 1/72 dots.
1048 int pixels = (int)(points * 100.0 / 72.0);
1049 sprintf(buf, "<TD ALIGN=CENTER WIDTH=%d>", pixels);
1050 }
1051 else
1052 sprintf(buf, "\n<TD ALIGN=LEFT>");
1053 TexOutput(buf);
1054 }
1055 else
1056 TexOutput("&amp;");
1057 }
1058 break;
1059 }
1060 case ltBACKSLASHCHAR:
1061 {
1062 if (start)
1063 {
1064 if (inTabular)
1065 {
1066 // End row. In fact, tables without use of \row or \ruledrow isn't supported for
1067 // HTML: the syntax is too different (e.g. how do we know where to put the first </TH>
1068 // if we've ended the last row?). So normally you wouldn't use \\ to end a row.
1069 TexOutput("</TR>\n");
1070 }
1071 else
1072 TexOutput("<BR>\n");
1073 }
1074 break;
1075 }
1076 case ltROW:
1077 case ltRULEDROW:
1078 {
1079 if (start)
1080 {
1081 currentColumn = 0;
1082
1083 // Start new row and cell, setting alignment for the first cell.
1084 char buf[100];
1085 if (TableData[currentColumn].justification == 'c')
1086 sprintf(buf, "<TR>\n<TD ALIGN=CENTER>");
1087 else if (TableData[currentColumn].justification == 'r')
1088 sprintf(buf, "<TR>\n<TD ALIGN=RIGHT>");
1089 else if (TableData[currentColumn].absWidth)
1090 {
1091 // Convert from points * 20 into pixels.
1092 int points = TableData[currentColumn].width / 20;
1093
1094 // Say the display is 100 DPI (dots/pixels per inch).
1095 // There are 72 pts to the inch. So 1pt = 1/72 inch, or 100 * 1/72 dots.
1096 int pixels = (int)(points * 100.0 / 72.0);
1097 sprintf(buf, "<TR>\n<TD ALIGN=CENTER WIDTH=%d>", pixels);
1098 }
1099 else
1100 sprintf(buf, "<TR>\n<TD ALIGN=LEFT>");
1101 TexOutput(buf);
1102 }
1103 else
1104 {
1105 // End cell and row
1106 // Start new row and cell
1107 TexOutput("</TD>\n</TR>\n");
1108 }
1109 break;
1110 }
1111 // HTML-only: break until the end of the picture (both margins are clear).
1112 case ltBRCLEAR:
1113 {
1114 if (start)
1115 TexOutput("<BR CLEAR=ALL>");
1116 break;
1117 }
1118 case ltRTFSP: // Explicit space, RTF only
1119 break;
1120 case ltSPECIALTILDE:
1121 {
1122 if (start)
1123 {
1124 if (inVerbatim)
1125 TexOutput("~");
1126 else
1127 TexOutput(" ");
1128 }
1129 break;
1130 }
1131 case ltINDENTED :
1132 {
1133 if ( start )
1134 TexOutput("<UL><UL>\n");
1135 else
1136 TexOutput("</UL></UL>\n");
1137 break;
1138 }
1139 case ltITEMIZE:
1140 case ltENUMERATE:
1141 case ltDESCRIPTION:
1142 // case ltTWOCOLLIST:
1143 {
1144 if (start)
1145 {
1146 indentLevel ++;
1147
1148 int listType;
1149 if (macroId == ltENUMERATE)
1150 listType = LATEX_ENUMERATE;
1151 else if (macroId == ltITEMIZE)
1152 listType = LATEX_ITEMIZE;
1153 else
1154 listType = LATEX_DESCRIPTION;
1155
1156 itemizeStack.Insert(new ItemizeStruc(listType));
1157 switch (listType)
1158 {
1159 case LATEX_ITEMIZE:
1160 TexOutput("<UL>\n");
1161 break;
1162 case LATEX_ENUMERATE:
1163 TexOutput("<OL>\n");
1164 break;
1165 case LATEX_DESCRIPTION:
1166 default:
1167 TexOutput("<DL>\n");
1168 break;
1169 }
1170 }
1171 else
1172 {
1173 indentLevel --;
1174 if (itemizeStack.First())
1175 {
1176 ItemizeStruc *struc = (ItemizeStruc *)itemizeStack.First()->Data();
1177 switch (struc->listType)
1178 {
1179 case LATEX_ITEMIZE:
1180 TexOutput("</UL>\n");
1181 break;
1182 case LATEX_ENUMERATE:
1183 TexOutput("</OL>\n");
1184 break;
1185 case LATEX_DESCRIPTION:
1186 default:
1187 TexOutput("</DL>\n");
1188 break;
1189 }
1190
1191 delete struc;
1192 delete itemizeStack.First();
1193 }
1194 }
1195 break;
1196 }
1197 case ltTWOCOLLIST :
1198 {
1199 if ( start )
1200 TexOutput("\n<TABLE>\n");
1201 else {
1202 TexOutput("\n</TABLE>\n");
1203 // DHS
1204 TwoColWidthA = -1;
1205 TwoColWidthB = -1;
1206 }
1207 break;
1208 }
1209 case ltPAR:
1210 {
1211 if (start)
1212 TexOutput("<P>\n");
1213 break;
1214 }
1215 /* For footnotes we need to output the text at the bottom of the page and
1216 * insert a reference to it. Is it worth the trouble...
1217 case ltFOOTNOTE:
1218 case ltFOOTNOTEPOPUP:
1219 {
1220 if (start)
1221 {
1222 TexOutput("<FN>);
1223 }
1224 else TexOutput("</FN>");
1225 break;
1226 }
1227 */
1228 case ltVERB:
1229 {
1230 if (start)
1231 TexOutput("<TT>");
1232 else TexOutput("</TT>");
1233 break;
1234 }
1235 case ltVERBATIM:
1236 {
1237 if (start)
1238 {
1239 char buf[100];
1240 sprintf(buf, "<PRE>\n");
1241 TexOutput(buf);
1242 }
1243 else TexOutput("</PRE>\n");
1244 break;
1245 }
1246 case ltCENTERLINE:
1247 case ltCENTER:
1248 {
1249 if (start)
1250 {
1251 TexOutput("<CENTER>");
1252 }
1253 else TexOutput("</CENTER>");
1254 break;
1255 }
1256 case ltFLUSHLEFT:
1257 {
1258 /*
1259 if (start)
1260 {
1261 TexOutput("{\\ql ");
1262 }
1263 else TexOutput("}\\par\\pard\n");
1264 */
1265 break;
1266 }
1267 case ltFLUSHRIGHT:
1268 {
1269 /*
1270 if (start)
1271 {
1272 TexOutput("{\\qr ");
1273 }
1274 else TexOutput("}\\par\\pard\n");
1275 */
1276 break;
1277 }
1278 case ltSMALL:
1279 {
1280 if (start)
1281 {
1282 // Netscape extension
1283 TexOutput("<FONT SIZE=2>");
1284 }
1285 else TexOutput("</FONT>");
1286 break;
1287 }
1288 case ltTINY:
1289 {
1290 if (start)
1291 {
1292 // Netscape extension
1293 TexOutput("<FONT SIZE=1>");
1294 }
1295 else TexOutput("</FONT>");
1296 break;
1297 }
1298 case ltNORMALSIZE:
1299 {
1300 if (start)
1301 {
1302 // Netscape extension
1303 TexOutput("<FONT SIZE=3>");
1304 }
1305 else TexOutput("</FONT>");
1306 break;
1307 }
1308 case ltlarge:
1309 {
1310 if (start)
1311 {
1312 // Netscape extension
1313 TexOutput("<FONT SIZE=4>");
1314 }
1315 else TexOutput("</FONT>");
1316 break;
1317 }
1318 case ltLarge:
1319 {
1320 if (start)
1321 {
1322 // Netscape extension
1323 TexOutput("<FONT SIZE=5>");
1324 }
1325 else TexOutput("</FONT>");
1326 break;
1327 }
1328 case ltLARGE:
1329 {
1330 if (start)
1331 {
1332 // Netscape extension
1333 TexOutput("<FONT SIZE=6>");
1334 }
1335 else TexOutput("</FONT>");
1336 break;
1337 }
1338 case ltBFSERIES:
1339 case ltTEXTBF:
1340 case ltBF:
1341 {
1342 if (start)
1343 {
1344 TexOutput("<B>");
1345 }
1346 else TexOutput("</B>");
1347 break;
1348 }
1349 case ltITSHAPE:
1350 case ltTEXTIT:
1351 case ltIT:
1352 {
1353 if (start)
1354 {
1355 TexOutput("<I>");
1356 }
1357 else TexOutput("</I>");
1358 break;
1359 }
1360 case ltEMPH:
1361 case ltEM:
1362 {
1363 if (start)
1364 {
1365 TexOutput("<EM>");
1366 }
1367 else TexOutput("</EM>");
1368 break;
1369 }
1370 case ltUNDERLINE:
1371 {
1372 if (start)
1373 {
1374 TexOutput("<UL>");
1375 }
1376 else TexOutput("</UL>");
1377 break;
1378 }
1379 case ltTTFAMILY:
1380 case ltTEXTTT:
1381 case ltTT:
1382 {
1383 if (start)
1384 {
1385 TexOutput("<TT>");
1386 }
1387 else TexOutput("</TT>");
1388 break;
1389 }
1390 case ltCOPYRIGHT:
1391 {
1392 if (start)
1393 TexOutput("&copy;", TRUE);
1394 break;
1395 }
1396 case ltREGISTERED:
1397 {
1398 if (start)
1399 TexOutput("&reg;", TRUE);
1400 break;
1401 }
1402 // Arrows
1403 case ltLEFTARROW:
1404 {
1405 if (start) TexOutput("&lt;--");
1406 break;
1407 }
1408 case ltLEFTARROW2:
1409 {
1410 if (start) TexOutput("&lt;==");
1411 break;
1412 }
1413 case ltRIGHTARROW:
1414 {
1415 if (start) TexOutput("--&gt;");
1416 break;
1417 }
1418 case ltRIGHTARROW2:
1419 {
1420 if (start) TexOutput("==&gt;");
1421 break;
1422 }
1423 case ltLEFTRIGHTARROW:
1424 {
1425 if (start) TexOutput("&lt;--&gt;");
1426 break;
1427 }
1428 case ltLEFTRIGHTARROW2:
1429 {
1430 if (start) TexOutput("&lt;==&gt;");
1431 break;
1432 }
1433 /*
1434 case ltSC:
1435 {
1436 break;
1437 }
1438 */
1439 case ltITEM:
1440 {
1441 if (!start)
1442 {
1443 wxNode *node = itemizeStack.First();
1444 if (node)
1445 {
1446 ItemizeStruc *struc = (ItemizeStruc *)node->Data();
1447 struc->currentItem += 1;
1448 if (struc->listType == LATEX_DESCRIPTION)
1449 {
1450 if (descriptionItemArg)
1451 {
1452 TexOutput("<DT> ");
1453 TraverseChildrenFromChunk(descriptionItemArg);
1454 TexOutput("\n");
1455 descriptionItemArg = NULL;
1456 }
1457 TexOutput("<DD>");
1458 }
1459 else
1460 TexOutput("<LI>");
1461 }
1462 }
1463 break;
1464 }
1465 case ltMAKETITLE:
1466 {
1467 if (start && DocumentTitle && DocumentAuthor)
1468 {
1469 // Add a special label for the contents page.
1470 // TexOutput("<CENTER>\n");
1471 TexOutput("<A NAME=\"contents\">");
1472 TexOutput("<H2 ALIGN=CENTER>\n");
1473 TraverseChildrenFromChunk(DocumentTitle);
1474 TexOutput("</H2>");
1475 TexOutput("<P>");
1476 TexOutput("</A>\n");
1477 TexOutput("<P>\n\n");
1478 TexOutput("<H3 ALIGN=CENTER>");
1479 TraverseChildrenFromChunk(DocumentAuthor);
1480 TexOutput("</H3><P>\n\n");
1481 if (DocumentDate)
1482 {
1483 TexOutput("<H3 ALIGN=CENTER>");
1484 TraverseChildrenFromChunk(DocumentDate);
1485 TexOutput("</H3><P>\n\n");
1486 }
1487 // TexOutput("\n</CENTER>\n");
1488 TexOutput("\n<P><HR><P>\n");
1489
1490 /*
1491 // Now do optional frame contents page
1492 if (htmlFrameContents && FrameContents)
1493 {
1494 SetCurrentOutput(FrameContents);
1495
1496 // Add a special label for the contents page.
1497 TexOutput("<CENTER>\n");
1498 TexOutput("<H3>\n");
1499 TraverseChildrenFromChunk(DocumentTitle);
1500 TexOutput("</H3>");
1501 TexOutput("<P>");
1502 TexOutput("</A>\n");
1503 TexOutput("<P>\n\n");
1504 TexOutput("<H3>");
1505 TraverseChildrenFromChunk(DocumentAuthor);
1506 TexOutput("</H3><P>\n\n");
1507 if (DocumentDate)
1508 {
1509 TexOutput("<H4>");
1510 TraverseChildrenFromChunk(DocumentDate);
1511 TexOutput("</H4><P>\n\n");
1512 }
1513 TexOutput("\n</CENTER>\n");
1514 TexOutput("<P><HR><P>\n");
1515
1516 SetCurrentOutput(Titlepage);
1517 }
1518 */
1519 }
1520 break;
1521 }
1522 case ltHELPREF:
1523 case ltHELPREFN:
1524 case ltPOPREF:
1525 case ltURLREF:
1526 {
1527 if (start)
1528 {
1529 helpRefFilename = NULL;
1530 helpRefText = NULL;
1531 }
1532 break;
1533 }
1534 case ltBIBLIOGRAPHY:
1535 {
1536 if (start)
1537 {
1538 DefaultOnMacro(macroId, no_args, start);
1539 }
1540 else
1541 {
1542 DefaultOnMacro(macroId, no_args, start);
1543 TexOutput("</DL>\n");
1544 }
1545 break;
1546 }
1547 case ltHRULE:
1548 {
1549 if (start)
1550 {
1551 TexOutput("<HR>\n");
1552 }
1553 break;
1554 }
1555 case ltRULE:
1556 {
1557 if (start)
1558 {
1559 TexOutput("<HR>\n");
1560 }
1561 break;
1562 }
1563 case ltTABLEOFCONTENTS:
1564 {
1565 if (start)
1566 {
1567 FILE *fd = fopen(ContentsName, "r");
1568 if (fd)
1569 {
1570 int ch = getc(fd);
1571 while (ch != EOF)
1572 {
1573 putc(ch, Titlepage);
1574 ch = getc(fd);
1575 }
1576 fclose(fd);
1577 }
1578 else
1579 {
1580 TexOutput("RUN TEX2RTF AGAIN FOR CONTENTS PAGE\n");
1581 OnInform("Run Tex2RTF again to include contents page.");
1582 }
1583 }
1584 break;
1585 }
1586 case ltLANGLEBRA:
1587 {
1588 if (start)
1589 TexOutput("&lt;");
1590 break;
1591 }
1592 case ltRANGLEBRA:
1593 {
1594 if (start)
1595 TexOutput("&gt;");
1596 break;
1597 }
1598 case ltQUOTE:
1599 case ltQUOTATION:
1600 {
1601 if (start)
1602 TexOutput("<BLOCKQUOTE>");
1603 else
1604 TexOutput("</BLOCKQUOTE>");
1605 break;
1606 }
1607 case ltCAPTION:
1608 case ltCAPTIONSTAR:
1609 {
1610 if (start)
1611 {
1612 if (inTabular)
1613 TexOutput("\n<CAPTION>");
1614
1615 char figBuf[40];
1616
1617 if ( inFigure )
1618 {
1619 figureNo ++;
1620
1621 if (DocumentStyle != LATEX_ARTICLE)
1622 sprintf(figBuf, "%s %d.%d: ", FigureNameString, chapterNo, figureNo);
1623 else
1624 sprintf(figBuf, "%s %d: ", FigureNameString, figureNo);
1625 }
1626 else
1627 {
1628 tableNo ++;
1629
1630 if (DocumentStyle != LATEX_ARTICLE)
1631 sprintf(figBuf, "%s %d.%d: ", TableNameString, chapterNo, tableNo);
1632 else
1633 sprintf(figBuf, "%s %d: ", TableNameString, tableNo);
1634 }
1635
1636 TexOutput(figBuf);
1637 }
1638 else
1639 {
1640 if (inTabular)
1641 TexOutput("\n</CAPTION>\n");
1642
1643 char *topicName = FindTopicName(GetNextChunk());
1644
1645 int n = inFigure ? figureNo : tableNo;
1646
1647 AddTexRef(topicName, NULL, NULL,
1648 ((DocumentStyle != LATEX_ARTICLE) ? chapterNo : n),
1649 ((DocumentStyle != LATEX_ARTICLE) ? n : 0));
1650 }
1651 break;
1652 }
1653 case ltSS:
1654 {
1655 if (start) TexOutput("&szlig;");
1656 break;
1657 }
1658 case ltFIGURE:
1659 {
1660 if (start) inFigure = TRUE;
1661 else inFigure = FALSE;
1662 break;
1663 }
1664 case ltTABLE:
1665 {
1666 if (start) inTable = TRUE;
1667 else inTable = FALSE;
1668 break;
1669 }
1670 default:
1671 DefaultOnMacro(macroId, no_args, start);
1672 break;
1673 }
1674 }
1675
1676 // Called on start/end of argument examination
1677 bool HTMLOnArgument(int macroId, int arg_no, bool start)
1678 {
1679 switch (macroId)
1680 {
1681 case ltCHAPTER:
1682 case ltCHAPTERSTAR:
1683 case ltCHAPTERHEADING:
1684 case ltSECTION:
1685 case ltSECTIONSTAR:
1686 case ltSECTIONHEADING:
1687 case ltSUBSECTION:
1688 case ltSUBSECTIONSTAR:
1689 case ltSUBSUBSECTION:
1690 case ltSUBSUBSECTIONSTAR:
1691 case ltGLOSS:
1692 case ltMEMBERSECTION:
1693 case ltFUNCTIONSECTION:
1694 {
1695 if (!start && (arg_no == 1))
1696 currentSection = GetArgChunk();
1697 return FALSE;
1698 break;
1699 }
1700 case ltFUNC:
1701 {
1702 if (start && (arg_no == 1))
1703 TexOutput("<B>");
1704
1705 if (!start && (arg_no == 1))
1706 TexOutput("</B> ");
1707
1708 if (start && (arg_no == 2))
1709 {
1710 if (!suppressNameDecoration) TexOutput("<B>");
1711 currentMember = GetArgChunk();
1712 }
1713 if (!start && (arg_no == 2))
1714 {
1715 if (!suppressNameDecoration) TexOutput("</B>");
1716 }
1717
1718 if (start && (arg_no == 3))
1719 TexOutput("(");
1720 if (!start && (arg_no == 3))
1721 TexOutput(")");
1722 break;
1723 }
1724 case ltCLIPSFUNC:
1725 {
1726 if (start && (arg_no == 1))
1727 TexOutput("<B>");
1728 if (!start && (arg_no == 1))
1729 TexOutput("</B> ");
1730
1731 if (start && (arg_no == 2))
1732 {
1733 if (!suppressNameDecoration) TexOutput("( ");
1734 currentMember = GetArgChunk();
1735 }
1736 if (!start && (arg_no == 2))
1737 {
1738 }
1739
1740 if (!start && (arg_no == 3))
1741 TexOutput(")");
1742 break;
1743 }
1744 case ltPFUNC:
1745 {
1746 if (!start && (arg_no == 1))
1747 TexOutput(" ");
1748
1749 if (start && (arg_no == 2))
1750 TexOutput("(*");
1751 if (!start && (arg_no == 2))
1752 TexOutput(")");
1753
1754 if (start && (arg_no == 2))
1755 currentMember = GetArgChunk();
1756
1757 if (start && (arg_no == 3))
1758 TexOutput("(");
1759 if (!start && (arg_no == 3))
1760 TexOutput(")");
1761 break;
1762 }
1763 case ltPARAM:
1764 {
1765 if (start && (arg_no == 1))
1766 TexOutput("<B>");
1767 if (!start && (arg_no == 1))
1768 TexOutput("</B>");
1769 if (start && (arg_no == 2))
1770 {
1771 TexOutput("<I>");
1772 }
1773 if (!start && (arg_no == 2))
1774 {
1775 TexOutput("</I>");
1776 }
1777 break;
1778 }
1779 case ltCPARAM:
1780 {
1781 if (start && (arg_no == 1))
1782 TexOutput("<B>");
1783 if (!start && (arg_no == 1))
1784 TexOutput("</B> "); // This is the difference from param - one space!
1785 if (start && (arg_no == 2))
1786 {
1787 TexOutput("<I>");
1788 }
1789 if (!start && (arg_no == 2))
1790 {
1791 TexOutput("</I>");
1792 }
1793 break;
1794 }
1795 case ltMEMBER:
1796 {
1797 if (!start && (arg_no == 1))
1798 TexOutput(" ");
1799
1800 if (start && (arg_no == 2))
1801 currentMember = GetArgChunk();
1802 break;
1803 }
1804 case ltREF:
1805 {
1806 if (start)
1807 {
1808 char *sec = NULL;
1809
1810 char *refName = GetArgData();
1811 if (refName)
1812 {
1813 TexRef *texRef = FindReference(refName);
1814 if (texRef)
1815 {
1816 sec = texRef->sectionNumber;
1817 }
1818 }
1819 if (sec)
1820 {
1821 TexOutput(sec);
1822 }
1823 return FALSE;
1824 }
1825 break;
1826 }
1827 case ltURLREF:
1828 {
1829 if (IsArgOptional())
1830 return FALSE;
1831 else if ((GetNoArgs() - arg_no) == 1)
1832 {
1833 if (start)
1834 helpRefText = GetArgChunk();
1835 return FALSE;
1836 }
1837 else if ((GetNoArgs() - arg_no) == 0) // Arg = 2, or 3 if first is optional
1838 {
1839 if (start)
1840 {
1841 TexChunk *ref = GetArgChunk();
1842 TexOutput("<A HREF=\"");
1843 inVerbatim = TRUE;
1844 TraverseChildrenFromChunk(ref);
1845 inVerbatim = FALSE;
1846 TexOutput("\">");
1847 if (helpRefText)
1848 TraverseChildrenFromChunk(helpRefText);
1849 TexOutput("</A>");
1850 }
1851 return FALSE;
1852 }
1853 break;
1854 }
1855 case ltHELPREF:
1856 case ltHELPREFN:
1857 case ltPOPREF:
1858 {
1859 if (IsArgOptional())
1860 {
1861 if (start)
1862 helpRefFilename = GetArgChunk();
1863 return FALSE;
1864 }
1865 if ((GetNoArgs() - arg_no) == 1)
1866 {
1867 if (start)
1868 helpRefText = GetArgChunk();
1869 return FALSE;
1870 }
1871 else if ((GetNoArgs() - arg_no) == 0) // Arg = 2, or 3 if first is optional
1872 {
1873 if (start)
1874 {
1875 char *refName = GetArgData();
1876 char *refFilename = NULL;
1877
1878 if (refName)
1879 {
1880 TexRef *texRef = FindReference(refName);
1881 if (texRef)
1882 {
1883 if (texRef->refFile && strcmp(texRef->refFile, "??") != 0)
1884 refFilename = texRef->refFile;
1885
1886 TexOutput("<A HREF=\"");
1887 // If a filename is supplied, use it, otherwise try to
1888 // use the filename associated with the reference (from this document).
1889 if (helpRefFilename)
1890 {
1891 TraverseChildrenFromChunk(helpRefFilename);
1892 TexOutput("#");
1893 }
1894 else if (refFilename)
1895 {
1896 TexOutput(ConvertCase(refFilename));
1897 TexOutput("#");
1898 }
1899 TexOutput(refName);
1900 TexOutput("\">");
1901 if (helpRefText)
1902 TraverseChildrenFromChunk(helpRefText);
1903 TexOutput("</A>");
1904 }
1905 else
1906 {
1907 if (helpRefText)
1908 TraverseChildrenFromChunk(helpRefText);
1909 TexOutput(" (REF NOT FOUND)");
1910 }
1911 }
1912 else TexOutput("??");
1913 }
1914 return FALSE;
1915 }
1916 break;
1917 }
1918 case ltIMAGE:
1919 case ltIMAGEL:
1920 case ltIMAGER:
1921 case ltPSBOXTO:
1922 {
1923 if (arg_no == 2)
1924 {
1925 if (start)
1926 {
1927 char *alignment = "";
1928 if (macroId == ltIMAGEL)
1929 alignment = " align=left";
1930 else if (macroId == ltIMAGER)
1931 alignment = " align=right";
1932
1933 // Try to find an XBM or GIF image first.
1934 char *filename = copystring(GetArgData());
1935 char buf[500];
1936
1937 strcpy(buf, filename);
1938 StripExtension(buf);
1939 strcat(buf, ".xbm");
1940 wxString f = TexPathList.FindValidPath(buf);
1941
1942 if (f == "") // Try for a GIF instead
1943 {
1944 strcpy(buf, filename);
1945 StripExtension(buf);
1946 strcat(buf, ".gif");
1947 f = TexPathList.FindValidPath(buf);
1948 }
1949
1950 if (f == "") // Try for a JPEG instead
1951 {
1952 strcpy(buf, filename);
1953 StripExtension(buf);
1954 strcat(buf, ".jpg");
1955 f = TexPathList.FindValidPath(buf);
1956 }
1957
1958 if (f == "") // Try for a PNG instead
1959 {
1960 strcpy(buf, filename);
1961 StripExtension(buf);
1962 strcat(buf, ".png");
1963 f = TexPathList.FindValidPath(buf);
1964 }
1965
1966 if (f != "")
1967 {
1968 char *inlineFilename = copystring(f);
1969 #if 0
1970 char *originalFilename = TexPathList.FindValidPath(filename);
1971 // If we have found the existing filename, make the inline
1972 // image point to the original file (could be PS, for example)
1973 if (originalFilename && (strcmp(inlineFilename, originalFilename) != 0))
1974 {
1975 TexOutput("<A HREF=\"");
1976 TexOutput(ConvertCase(originalFilename));
1977 TexOutput("\">");
1978 TexOutput("<img src=\"");
1979 TexOutput(ConvertCase(wxFileNameFromPath(inlineFilename)));
1980 TexOutput("\""); TexOutput(alignment); TexOutput("></A>");
1981 }
1982 else
1983 #endif
1984 {
1985 TexOutput("<img src=\"");
1986 TexOutput(ConvertCase(wxFileNameFromPath(inlineFilename)));
1987 TexOutput("\""); TexOutput(alignment); TexOutput("></A>");
1988 delete[] inlineFilename;
1989 }
1990 }
1991 else
1992 {
1993 // Last resort - a link to a PS file.
1994 TexOutput("<A HREF=\"");
1995 TexOutput(ConvertCase(wxFileNameFromPath(filename)));
1996 TexOutput("\">Picture</A>\n");
1997 sprintf(buf, "Warning: could not find an inline XBM/GIF for %s.", filename);
1998 OnInform(buf);
1999 }
2000 }
2001 }
2002 return FALSE;
2003 break;
2004 }
2005 // First arg is PSBOX spec (ignored), second is image file, third is map name.
2006 case ltIMAGEMAP:
2007 {
2008 static char *imageFile = NULL;
2009 if (start && (arg_no == 2))
2010 {
2011 // Try to find an XBM or GIF image first.
2012 char *filename = copystring(GetArgData());
2013 char buf[500];
2014
2015 strcpy(buf, filename);
2016 StripExtension(buf);
2017 strcat(buf, ".xbm");
2018 wxString f = TexPathList.FindValidPath(buf);
2019
2020 if (f == "") // Try for a GIF instead
2021 {
2022 strcpy(buf, filename);
2023 StripExtension(buf);
2024 strcat(buf, ".gif");
2025 f = TexPathList.FindValidPath(buf);
2026 }
2027 if (f == "")
2028 {
2029 char buf[300];
2030 sprintf(buf, "Warning: could not find an inline XBM/GIF for %s.", filename);
2031 OnInform(buf);
2032 }
2033 delete[] filename;
2034 if (imageFile)
2035 delete[] imageFile;
2036 imageFile = NULL;
2037 if (!f.IsEmpty())
2038 {
2039 imageFile = copystring(f);
2040 }
2041 }
2042 else if (start && (arg_no == 3))
2043 {
2044 if (imageFile)
2045 {
2046 // First, try to find a .shg (segmented hypergraphics file)
2047 // that we can convert to a map file
2048 char buf[256];
2049 strcpy(buf, imageFile);
2050 StripExtension(buf);
2051 strcat(buf, ".shg");
2052 wxString f = TexPathList.FindValidPath(buf);
2053
2054 if (f != "")
2055 {
2056 // The default HTML file to go to is THIS file (so a no-op)
2057 SHGToMap((char*) (const char*) f, currentFileName);
2058 }
2059
2060 char *mapName = GetArgData();
2061 TexOutput("<A HREF=\"/cgi-bin/imagemap/");
2062 if (mapName)
2063 TexOutput(mapName);
2064 else
2065 TexOutput("unknown");
2066 TexOutput("\">");
2067 TexOutput("<img src=\"");
2068 TexOutput(ConvertCase(wxFileNameFromPath(imageFile)));
2069 TexOutput("\" ISMAP></A><P>");
2070 delete[] imageFile;
2071 imageFile = NULL;
2072 }
2073 }
2074 return FALSE;
2075 break;
2076 }
2077 case ltINDENTED :
2078 {
2079 if ( arg_no == 1 )
2080 return FALSE;
2081 else
2082 {
2083 return TRUE;
2084 }
2085 }
2086 case ltITEM:
2087 {
2088 if (start)
2089 {
2090 descriptionItemArg = GetArgChunk();
2091 return FALSE;
2092 }
2093 }
2094 case ltTWOCOLITEM:
2095 case ltTWOCOLITEMRULED:
2096 {
2097 /*
2098 if (start && (arg_no == 1))
2099 TexOutput("\n<DT> ");
2100 if (start && (arg_no == 2))
2101 TexOutput("<DD> ");
2102 */
2103 if (arg_no == 1)
2104 {
2105 if ( start ) {
2106 // DHS
2107 if (TwoColWidthA > -1) {
2108 char buf[100];
2109 sprintf(buf,"\n<TR><TD VALIGN=TOP WIDTH=%d>\n",TwoColWidthA);
2110 TexOutput(buf);
2111 } else
2112 TexOutput("\n<TR><TD VALIGN=TOP>\n");
2113 } else
2114 TexOutput("\n</TD>\n");
2115 }
2116 if (arg_no == 2)
2117 {
2118 // DHS
2119 if ( start ) {
2120 if (TwoColWidthB > -1) {
2121 char buf[100];
2122 sprintf(buf,"\n<TD VALIGN=TOP WIDTH=%d>\n",TwoColWidthB);
2123 TexOutput(buf);
2124 } else
2125 TexOutput("\n<TD VALIGN=TOP>\n");
2126 } else
2127 TexOutput("\n</TD></TR>\n");
2128 }
2129 return TRUE;
2130 break;
2131 }
2132 case ltNUMBEREDBIBITEM:
2133 {
2134 if (arg_no == 1 && start)
2135 {
2136 TexOutput("\n<DT> ");
2137 }
2138 if (arg_no == 2 && !start)
2139 TexOutput("<P>\n");
2140 break;
2141 }
2142 case ltBIBITEM:
2143 {
2144 char buf[100];
2145 if (arg_no == 1 && start)
2146 {
2147 char *citeKey = GetArgData();
2148 TexRef *ref = (TexRef *)TexReferences.Get(citeKey);
2149 if (ref)
2150 {
2151 if (ref->sectionNumber) delete[] ref->sectionNumber;
2152 sprintf(buf, "[%d]", citeCount);
2153 ref->sectionNumber = copystring(buf);
2154 }
2155
2156 sprintf(buf, "\n<DT> [%d] ", citeCount);
2157 TexOutput(buf);
2158 citeCount ++;
2159 return FALSE;
2160 }
2161 if (arg_no == 2 && !start)
2162 TexOutput("<P>\n");
2163 return TRUE;
2164 break;
2165 }
2166 case ltMARGINPAR:
2167 case ltMARGINPARODD:
2168 case ltMARGINPAREVEN:
2169 case ltNORMALBOX:
2170 case ltNORMALBOXD:
2171 {
2172 if (start)
2173 {
2174 TexOutput("<HR>\n");
2175 return TRUE;
2176 }
2177 else
2178 TexOutput("<HR><P>\n");
2179 break;
2180 }
2181 // DHS
2182 case ltTWOCOLWIDTHA:
2183 {
2184 if (start)
2185 {
2186 char *val = GetArgData();
2187 float points = ParseUnitArgument(val);
2188 TwoColWidthA = (int)((points * 100.0) / 72.0);
2189 }
2190 return FALSE;
2191 break;
2192 }
2193 // DHS
2194 case ltTWOCOLWIDTHB:
2195 {
2196 if (start)
2197 {
2198 char *val = GetArgData();
2199 float points = ParseUnitArgument(val);
2200 TwoColWidthB = (int)((points * 100.0) / 72.0);
2201 }
2202 return FALSE;
2203 break;
2204 }
2205 /*
2206 * Accents
2207 *
2208 */
2209 case ltACCENT_GRAVE:
2210 {
2211 if (start)
2212 {
2213 char *val = GetArgData();
2214 if (val)
2215 {
2216 switch (val[0])
2217 {
2218 case 'a':
2219 TexOutput("&agrave;");
2220 break;
2221 case 'e':
2222 TexOutput("&egrave;");
2223 break;
2224 case 'i':
2225 TexOutput("&igrave;");
2226 break;
2227 case 'o':
2228 TexOutput("&ograve;");
2229 break;
2230 case 'u':
2231 TexOutput("&ugrave;");
2232 break;
2233 case 'A':
2234 TexOutput("&Agrave;");
2235 break;
2236 case 'E':
2237 TexOutput("&Egrave;");
2238 break;
2239 case 'I':
2240 TexOutput("&Igrave;");
2241 break;
2242 case 'O':
2243 TexOutput("&Ograve;");
2244 break;
2245 case 'U':
2246 TexOutput("&Igrave;");
2247 break;
2248 default:
2249 break;
2250 }
2251 }
2252 }
2253 return FALSE;
2254 break;
2255 }
2256 case ltACCENT_ACUTE:
2257 {
2258 if (start)
2259 {
2260 char *val = GetArgData();
2261 if (val)
2262 {
2263 switch (val[0])
2264 {
2265 case 'a':
2266 TexOutput("&aacute;");
2267 break;
2268 case 'e':
2269 TexOutput("&eacute;");
2270 break;
2271 case 'i':
2272 TexOutput("&iacute;");
2273 break;
2274 case 'o':
2275 TexOutput("&oacute;");
2276 break;
2277 case 'u':
2278 TexOutput("&uacute;");
2279 break;
2280 case 'y':
2281 TexOutput("&yacute;");
2282 break;
2283 case 'A':
2284 TexOutput("&Aacute;");
2285 break;
2286 case 'E':
2287 TexOutput("&Eacute;");
2288 break;
2289 case 'I':
2290 TexOutput("&Iacute;");
2291 break;
2292 case 'O':
2293 TexOutput("&Oacute;");
2294 break;
2295 case 'U':
2296 TexOutput("&Uacute;");
2297 break;
2298 case 'Y':
2299 TexOutput("&Yacute;");
2300 break;
2301 default:
2302 break;
2303 }
2304 }
2305 }
2306 return FALSE;
2307 break;
2308 }
2309 case ltACCENT_CARET:
2310 {
2311 if (start)
2312 {
2313 char *val = GetArgData();
2314 if (val)
2315 {
2316 switch (val[0])
2317 {
2318 case 'a':
2319 TexOutput("&acirc;");
2320 break;
2321 case 'e':
2322 TexOutput("&ecirc;");
2323 break;
2324 case 'i':
2325 TexOutput("&icirc;");
2326 break;
2327 case 'o':
2328 TexOutput("&ocirc;");
2329 break;
2330 case 'u':
2331 TexOutput("&ucirc;");
2332 break;
2333 case 'A':
2334 TexOutput("&Acirc;");
2335 break;
2336 case 'E':
2337 TexOutput("&Ecirc;");
2338 break;
2339 case 'I':
2340 TexOutput("&Icirc;");
2341 break;
2342 case 'O':
2343 TexOutput("&Ocirc;");
2344 break;
2345 case 'U':
2346 TexOutput("&Icirc;");
2347 break;
2348 default:
2349 break;
2350 }
2351 }
2352 }
2353 return FALSE;
2354 break;
2355 }
2356 case ltACCENT_TILDE:
2357 {
2358 if (start)
2359 {
2360 char *val = GetArgData();
2361 if (val)
2362 {
2363 switch (val[0])
2364 {
2365 case ' ':
2366 TexOutput("~");
2367 break;
2368 case 'a':
2369 TexOutput("&atilde;");
2370 break;
2371 case 'n':
2372 TexOutput("&ntilde;");
2373 break;
2374 case 'o':
2375 TexOutput("&otilde;");
2376 break;
2377 case 'A':
2378 TexOutput("&Atilde;");
2379 break;
2380 case 'N':
2381 TexOutput("&Ntilde;");
2382 break;
2383 case 'O':
2384 TexOutput("&Otilde;");
2385 break;
2386 default:
2387 break;
2388 }
2389 }
2390 }
2391 return FALSE;
2392 break;
2393 }
2394 case ltACCENT_UMLAUT:
2395 {
2396 if (start)
2397 {
2398 char *val = GetArgData();
2399 if (val)
2400 {
2401 switch (val[0])
2402 {
2403 case 'a':
2404 TexOutput("&auml;");
2405 break;
2406 case 'e':
2407 TexOutput("&euml;");
2408 break;
2409 case 'i':
2410 TexOutput("&iuml;");
2411 break;
2412 case 'o':
2413 TexOutput("&ouml;");
2414 break;
2415 case 'u':
2416 TexOutput("&uuml;");
2417 break;
2418 case 'y':
2419 TexOutput("&yuml;");
2420 break;
2421 case 'A':
2422 TexOutput("&Auml;");
2423 break;
2424 case 'E':
2425 TexOutput("&Euml;");
2426 break;
2427 case 'I':
2428 TexOutput("&Iuml;");
2429 break;
2430 case 'O':
2431 TexOutput("&Ouml;");
2432 break;
2433 case 'U':
2434 TexOutput("&Uuml;");
2435 break;
2436 case 'Y':
2437 TexOutput("&Yuml;");
2438 break;
2439 default:
2440 break;
2441 }
2442 }
2443 }
2444 return FALSE;
2445 break;
2446 }
2447 case ltACCENT_DOT:
2448 {
2449 if (start)
2450 {
2451 char *val = GetArgData();
2452 if (val)
2453 {
2454 switch (val[0])
2455 {
2456 case 'a':
2457 TexOutput("&aring;");
2458 break;
2459 case 'A':
2460 TexOutput("&Aring;");
2461 break;
2462 default:
2463 break;
2464 }
2465 }
2466 }
2467 return FALSE;
2468 break;
2469 }
2470 case ltBACKGROUND:
2471 {
2472 if (start)
2473 {
2474 char *val = GetArgData();
2475 if (val)
2476 {
2477 bool isPicture = FALSE;
2478 char *s = ParseColourString(val, &isPicture);
2479 if (isPicture)
2480 {
2481 if (backgroundImageString)
2482 delete[] backgroundImageString;
2483 backgroundImageString = copystring(val);
2484 }
2485 else
2486 {
2487 if (backgroundColourString)
2488 delete[] backgroundColourString;
2489 backgroundColourString = copystring(val);
2490 }
2491 }
2492 }
2493 return FALSE;
2494 break;
2495 }
2496 case ltBACKGROUNDIMAGE:
2497 {
2498 if (start)
2499 {
2500 char *val = GetArgData();
2501 if (val)
2502 {
2503 if (backgroundImageString)
2504 delete[] backgroundImageString;
2505 backgroundImageString = copystring(val);
2506 }
2507 }
2508 return FALSE;
2509 break;
2510 }
2511 case ltBACKGROUNDCOLOUR:
2512 {
2513 if (start)
2514 {
2515 char *val = GetArgData();
2516 if (val)
2517 {
2518 if (backgroundColourString)
2519 delete[] backgroundColourString;
2520 backgroundColourString = copystring(val);
2521 }
2522 }
2523 return FALSE;
2524 break;
2525 }
2526 case ltTEXTCOLOUR:
2527 {
2528 if (start)
2529 {
2530 char *val = GetArgData();
2531 if (val)
2532 {
2533 if (textColourString)
2534 delete[] textColourString;
2535 textColourString = copystring(val);
2536 }
2537 }
2538 return FALSE;
2539 break;
2540 }
2541 case ltLINKCOLOUR:
2542 {
2543 if (start)
2544 {
2545 char *val = GetArgData();
2546 if (val)
2547 {
2548 if (linkColourString)
2549 delete[] linkColourString;
2550 linkColourString = copystring(val);
2551 }
2552 }
2553 return FALSE;
2554 break;
2555 }
2556 case ltFOLLOWEDLINKCOLOUR:
2557 {
2558 if (start)
2559 {
2560 char *val = GetArgData();
2561 if (val)
2562 {
2563 if (followedLinkColourString)
2564 delete[] followedLinkColourString;
2565 followedLinkColourString = copystring(val);
2566 }
2567 }
2568 return FALSE;
2569 break;
2570 }
2571 case ltACCENT_CADILLA:
2572 {
2573 if (start)
2574 {
2575 char *val = GetArgData();
2576 if (val)
2577 {
2578 switch (val[0])
2579 {
2580 case 'c':
2581 TexOutput("&ccedil;");
2582 break;
2583 case 'C':
2584 TexOutput("&Ccedil;");
2585 break;
2586 default:
2587 break;
2588 }
2589 }
2590 }
2591 return FALSE;
2592 break;
2593 }
2594 /*
2595 case ltFOOTNOTE:
2596 case ltFOOTNOTEPOPUP:
2597 {
2598 if (arg_no == 1)
2599 return TRUE;
2600 else
2601 return FALSE;
2602 break;
2603 }
2604 */
2605 case ltTABULAR:
2606 case ltSUPERTABULAR:
2607 {
2608 if (arg_no == 1)
2609 {
2610 if (start)
2611 {
2612 currentRowNumber = 0;
2613 inTabular = TRUE;
2614 startRows = TRUE;
2615 tableVerticalLineLeft = FALSE;
2616 tableVerticalLineRight = FALSE;
2617 int currentWidth = 0;
2618
2619 char *alignString = copystring(GetArgData());
2620 ParseTableArgument(alignString);
2621
2622 TexOutput("<TABLE BORDER>\n");
2623
2624 // Write the first row formatting for compatibility
2625 // with standard Latex
2626 if (compatibilityMode)
2627 {
2628 TexOutput("<TR>\n<TD>");
2629 /*
2630 for (int i = 0; i < noColumns; i++)
2631 {
2632 currentWidth += TableData[i].width;
2633 sprintf(buf, "\\cellx%d", currentWidth);
2634 TexOutput(buf);
2635 }
2636 TexOutput("\\pard\\intbl\n");
2637 */
2638 }
2639 delete[] alignString;
2640
2641 return FALSE;
2642 }
2643 }
2644 else if (arg_no == 2 && !start)
2645 {
2646 TexOutput("</TABLE>\n");
2647 inTabular = FALSE;
2648 }
2649 break;
2650 }
2651 case ltTHEBIBLIOGRAPHY:
2652 {
2653 if (start && (arg_no == 1))
2654 {
2655 ReopenFile(&Chapters, &ChaptersName);
2656 AddTexRef("bibliography", ChaptersName, "bibliography");
2657 SetCurrentSubsectionName("bibliography", ChaptersName);
2658
2659 citeCount = 1;
2660
2661 SetCurrentOutput(Chapters);
2662
2663 char titleBuf[150];
2664 if (truncateFilenames)
2665 sprintf(titleBuf, "%s.htm", FileNameFromPath(FileRoot));
2666 else
2667 sprintf(titleBuf, "%s_contents.html", FileNameFromPath(FileRoot));
2668
2669 TexOutput("<head><title>");
2670 TexOutput(ReferencesNameString);
2671 TexOutput("</title></head>\n");
2672 OutputBodyStart();
2673
2674 fprintf(Chapters, "<A NAME=\"%s\">\n<H2>%s", "bibliography", ReferencesNameString);
2675 AddBrowseButtons("contents", titleBuf, // Up
2676 lastTopic, lastFileName, // Last topic
2677 "bibliography", ChaptersName); // This topic
2678
2679 SetCurrentOutputs(Contents, Chapters);
2680 fprintf(Contents, "\n<LI><A HREF=\"%s#%s\">", ConvertCase(ChaptersName), "bibliography");
2681
2682 fprintf(Contents, "%s</A>\n", ReferencesNameString);
2683 fprintf(Chapters, "</H2>\n</A>\n");
2684
2685 SetCurrentOutput(Chapters);
2686 return FALSE;
2687 }
2688 if (!start && (arg_no == 2))
2689 {
2690 }
2691 return TRUE;
2692 break;
2693 }
2694 case ltINDEX:
2695 {
2696 /* Build up list of keywords associated with topics */
2697 if (start)
2698 {
2699 // char *entry = GetArgData();
2700 char buf[300];
2701 OutputChunkToString(GetArgChunk(), buf);
2702 if (CurrentTopic)
2703 {
2704 AddKeyWordForTopic(CurrentTopic, buf, currentFileName);
2705 }
2706 }
2707 return FALSE;
2708 break;
2709 }
2710 case ltFCOL:
2711 // case ltBCOL:
2712 {
2713 if (start)
2714 {
2715 switch (arg_no)
2716 {
2717 case 1:
2718 {
2719 char *name = GetArgData();
2720 char buf2[10];
2721 if (!FindColourHTMLString(name, buf2))
2722 {
2723 strcpy(buf2, "#000000");
2724 char buf[100];
2725 sprintf(buf, "Could not find colour name %s", name);
2726 OnError(buf);
2727 }
2728 TexOutput("<FONT COLOR=\"");
2729 TexOutput(buf2);
2730 TexOutput("\">");
2731 break;
2732 }
2733 case 2:
2734 {
2735 return TRUE;
2736 break;
2737 }
2738 default:
2739 break;
2740 }
2741 }
2742 else
2743 {
2744 if (arg_no == 2) TexOutput("</FONT>");
2745 }
2746 return FALSE;
2747 break;
2748 }
2749 case ltINSERTATLEVEL:
2750 {
2751 // This macro allows you to insert text at a different level
2752 // from the current level, e.g. into the Sections from within a subsubsection.
2753 if (useWord)
2754 return FALSE;
2755 static int currentLevelNo = 1;
2756 static FILE* oldLevelFile = Chapters;
2757 if (start)
2758 {
2759 switch (arg_no)
2760 {
2761 case 1:
2762 {
2763 oldLevelFile = CurrentOutput1;
2764
2765 char *str = GetArgData();
2766 currentLevelNo = atoi(str);
2767 FILE* outputFile;
2768 // TODO: cope with article style (no chapters)
2769 switch (currentLevelNo)
2770 {
2771 case 1:
2772 {
2773 outputFile = Chapters;
2774 break;
2775 }
2776 case 2:
2777 {
2778 outputFile = Sections;
2779 break;
2780 }
2781 case 3:
2782 {
2783 outputFile = Subsections;
2784 break;
2785 }
2786 case 4:
2787 {
2788 outputFile = Subsubsections;
2789 break;
2790 }
2791 default:
2792 {
2793 outputFile = NULL;
2794 break;
2795 }
2796 }
2797 if (outputFile)
2798 CurrentOutput1 = outputFile;
2799 return FALSE;
2800 break;
2801 }
2802 case 2:
2803 {
2804 return TRUE;
2805 break;
2806 }
2807 default:
2808 break;
2809 }
2810 return TRUE;
2811 }
2812 else
2813 {
2814 if (arg_no == 2)
2815 {
2816 CurrentOutput1 = oldLevelFile;
2817 }
2818 return TRUE;
2819 }
2820 }
2821 default:
2822 return DefaultOnArgument(macroId, arg_no, start);
2823 break;
2824 }
2825 return TRUE;
2826 }
2827
2828 bool HTMLGo(void)
2829 {
2830 fileId = 0;
2831 inVerbatim = FALSE;
2832 indentLevel = 0;
2833 inTabular = FALSE;
2834 startRows = FALSE;
2835 tableVerticalLineLeft = FALSE;
2836 tableVerticalLineRight = FALSE;
2837 noColumns = 0;
2838
2839 if (InputFile && OutputFile)
2840 {
2841 // Do some HTML-specific transformations on all the strings,
2842 // recursively
2843 Text2HTML(GetTopLevelChunk());
2844
2845 char buf[300];
2846 if (truncateFilenames)
2847 sprintf(buf, "%s.htm", FileRoot);
2848 else
2849 sprintf(buf, "%s_contents.html", FileRoot);
2850 if (TitlepageName) delete[] TitlepageName;
2851 TitlepageName = copystring(buf);
2852 Titlepage = fopen(buf, "w");
2853
2854 if (truncateFilenames)
2855 sprintf(buf, "%s_fc.htm", FileRoot);
2856 else
2857 sprintf(buf, "%s_fcontents.html", FileRoot);
2858
2859 contentsFrameName = copystring(buf);
2860
2861 Contents = fopen(TmpContentsName, "w");
2862
2863 if (htmlFrameContents)
2864 {
2865 // FrameContents = fopen(TmpFrameContentsName, "w");
2866 FrameContents = fopen(contentsFrameName, "w");
2867 fprintf(FrameContents, "<HTML>\n<UL>\n");
2868 }
2869
2870 if (!Titlepage || !Contents)
2871 {
2872 OnError("Cannot open output file!");
2873 return FALSE;
2874 }
2875 AddTexRef("contents", FileNameFromPath(TitlepageName), ContentsNameString);
2876
2877 fprintf(Contents, "<P><P><H2>%s</H2><P><P>\n", ContentsNameString);
2878
2879 fprintf(Contents, "<UL>\n");
2880
2881 SetCurrentOutput(Titlepage);
2882 if (htmlWorkshopFiles) HTMLWorkshopStartContents();
2883 OnInform("Converting...");
2884
2885 TraverseDocument();
2886 fprintf(Contents, "</UL>\n\n");
2887
2888 // SetCurrentOutput(Titlepage);
2889 fclose(Titlepage);
2890
2891 if (Contents)
2892 {
2893 // fprintf(Titlepage, "\n</BODY></HTML>\n");
2894 fclose(Contents);
2895 Contents = NULL;
2896 }
2897
2898 if (FrameContents)
2899 {
2900 fprintf(FrameContents, "\n</UL>\n");
2901 fprintf(FrameContents, "</HTML>\n");
2902 fclose(FrameContents);
2903 FrameContents = NULL;
2904 }
2905
2906 if (Chapters)
2907 {
2908 fprintf(Chapters, "\n</BODY></HTML>\n");
2909 fclose(Chapters);
2910 Chapters = NULL;
2911 }
2912 if (Sections)
2913 {
2914 fprintf(Sections, "\n</BODY></HTML>\n");
2915 fclose(Sections);
2916 Sections = NULL;
2917 }
2918 if (Subsections && !combineSubSections)
2919 {
2920 fprintf(Subsections, "\n</BODY></HTML>\n");
2921 fclose(Subsections);
2922 Subsections = NULL;
2923 }
2924 if (Subsubsections && !combineSubSections)
2925 {
2926 fprintf(Subsubsections, "\n</BODY></HTML>\n");
2927 fclose(Subsubsections);
2928 Subsubsections = NULL;
2929 }
2930 if ( SectionContentsFD )
2931 {
2932 fclose(SectionContentsFD);
2933 SectionContentsFD = NULL;
2934 }
2935
2936 // Create a temporary file for the title page header, add some info,
2937 // and concat the titlepage just generated.
2938 // This is necessary in order to put the title of the document
2939 // at the TOP of the file within <HEAD>, even though we only find out
2940 // what it is later on.
2941 FILE *tmpTitle = fopen("title.tmp", "w");
2942 if (tmpTitle)
2943 {
2944 if (DocumentTitle)
2945 {
2946 SetCurrentOutput(tmpTitle);
2947 TexOutput("\n<HTML>\n<HEAD><TITLE>");
2948 TraverseChildrenFromChunk(DocumentTitle);
2949 TexOutput("</TITLE></HEAD>\n");
2950 }
2951 else
2952 {
2953 SetCurrentOutput(tmpTitle);
2954 if (contentsString)
2955 fprintf(tmpTitle, "<HEAD><TITLE>%s</TITLE></HEAD>\n\n", contentsString);
2956 else
2957 fprintf(tmpTitle, "<HEAD><TITLE>%s</TITLE></HEAD>\n\n", FileNameFromPath(FileRoot));
2958 }
2959
2960 // Output frame information
2961 if (htmlFrameContents)
2962 {
2963 char firstFileName[300];
2964 if (truncateFilenames)
2965 sprintf(firstFileName, "%s1.htm", FileRoot);
2966 else
2967 sprintf(firstFileName, "%s1.html", FileRoot);
2968
2969 fprintf(tmpTitle, "<FRAMESET COLS=\"30%%,70%%\">\n");
2970
2971 fprintf(tmpTitle, "<FRAME SRC=\"%s\">\n", ConvertCase(FileNameFromPath(contentsFrameName)));
2972 fprintf(tmpTitle, "<FRAME SRC=\"%s\" NAME=\"mainwindow\">\n", ConvertCase(FileNameFromPath(firstFileName)));
2973 fprintf(tmpTitle, "</FRAMESET>\n");
2974
2975 fprintf(tmpTitle, "<NOFRAMES>\n");
2976 }
2977
2978 // Output <BODY...> to temporary title page
2979 OutputBodyStart();
2980
2981 // Concat titlepage
2982 FILE *fd = fopen(TitlepageName, "r");
2983 if (fd)
2984 {
2985 int ch = getc(fd);
2986 while (ch != EOF)
2987 {
2988 putc(ch, tmpTitle);
2989 ch = getc(fd);
2990 }
2991 fclose(fd);
2992 }
2993
2994 fprintf(tmpTitle, "\n</BODY>\n");
2995
2996 if (htmlFrameContents)
2997 {
2998 fprintf(tmpTitle, "\n</NOFRAMES>\n");
2999 }
3000 fprintf(tmpTitle, "\n</HTML>\n");
3001
3002 fclose(tmpTitle);
3003 if (FileExists(TitlepageName)) wxRemoveFile(TitlepageName);
3004 if (!wxRenameFile("title.tmp", TitlepageName))
3005 {
3006 wxCopyFile("title.tmp", TitlepageName);
3007 wxRemoveFile("title.tmp");
3008 }
3009 }
3010
3011 if (lastFileName) delete[] lastFileName;
3012 lastFileName = NULL;
3013 if (lastTopic) delete[] lastTopic;
3014 lastTopic = NULL;
3015
3016 if (FileExists(ContentsName)) wxRemoveFile(ContentsName);
3017
3018 if (!wxRenameFile(TmpContentsName, ContentsName))
3019 {
3020 wxCopyFile(TmpContentsName, ContentsName);
3021 wxRemoveFile(TmpContentsName);
3022 }
3023
3024 // Generate .htx file if requested
3025 if (htmlIndex)
3026 {
3027 char htmlIndexName[300];
3028 sprintf(htmlIndexName, "%s.htx", FileRoot);
3029 GenerateHTMLIndexFile(htmlIndexName);
3030 }
3031
3032 // Generate HTML Help Workshop files if requested
3033 if (htmlWorkshopFiles)
3034 {
3035 HTMLWorkshopEndContents();
3036 GenerateHTMLWorkshopFiles(FileRoot);
3037 }
3038
3039
3040 return TRUE;
3041 }
3042
3043 return FALSE;
3044 }
3045
3046 // Output .htx index file
3047 void GenerateHTMLIndexFile(char *fname)
3048 {
3049 FILE *fd = fopen(fname, "w");
3050 if (!fd)
3051 return;
3052
3053 TopicTable.BeginFind();
3054 wxNode *node = NULL;
3055 while ((node = TopicTable.Next()))
3056 {
3057 TexTopic *texTopic = (TexTopic *)node->Data();
3058 const char *topicName = node->GetKeyString();
3059 if (texTopic->filename && texTopic->keywords)
3060 {
3061 wxNode *node1 = texTopic->keywords->First();
3062 while (node1)
3063 {
3064 char *s = (char *)node1->Data();
3065 fprintf(fd, "%s|%s|%s\n", topicName, texTopic->filename, s);
3066 node1 = node1->Next();
3067 }
3068 }
3069 }
3070 fclose(fd);
3071 }
3072
3073
3074
3075
3076
3077
3078
3079 // output .hpp, .hhc and .hhk files:
3080
3081
3082 void GenerateHTMLWorkshopFiles(char *fname)
3083 {
3084 FILE *f;
3085 char buf[300];
3086
3087 /* Generate project file : */
3088
3089 sprintf(buf, "%s.hhp", fname);
3090 f = fopen(buf, "wt");
3091 fprintf(f,
3092 "[OPTIONS]\n"
3093 "Compatibility=1.1\n"
3094 "Full-text search=Yes\n"
3095 "Contents file=%s.hhc\n"
3096 "Compiled file=%s.chm\n"
3097 "Default Window=%sHelp\n"
3098 "Default topic=%s\n"
3099 "Index file=%s.hhk\n"
3100 "Title=",
3101 FileNameFromPath(fname),
3102 FileNameFromPath(fname),
3103 FileNameFromPath(fname),
3104 FileNameFromPath(TitlepageName),
3105 FileNameFromPath(fname)
3106 );
3107
3108 if (DocumentTitle) {
3109 SetCurrentOutput(f);
3110 TraverseChildrenFromChunk(DocumentTitle);
3111 }
3112 else fprintf(f, "(unknown)");
3113
3114 fprintf(f, "\n\n[WINDOWS]\n"
3115 "%sHelp=,\"%s.hhc\",\"%s.hhk\",\"%s\",,,,,,0x2420,,0x380e,,,,,0,,,",
3116 FileNameFromPath(fname),
3117 FileNameFromPath(fname),
3118 FileNameFromPath(fname),
3119 FileNameFromPath(TitlepageName));
3120
3121
3122 fprintf(f, "\n\n[FILES]\n");
3123 fprintf(f, "%s\n", FileNameFromPath(TitlepageName));
3124 for (int i = 1; i <= fileId; i++) {
3125 if (truncateFilenames)
3126 sprintf(buf, "%s%d.htm", FileNameFromPath(FileRoot), i);
3127 else
3128 sprintf(buf, "%s%d.html", FileNameFromPath(FileRoot), i);
3129 fprintf(f, "%s\n", buf);
3130 }
3131 fclose(f);
3132
3133 /* Generate index file : */
3134
3135 sprintf(buf, "%s.hhk", fname);
3136 f = fopen(buf, "wt");
3137
3138 fprintf(f,
3139 "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML//EN\">\n"
3140 "<HTML>\n"
3141 "<HEAD>\n"
3142 "<meta name=\"GENERATOR\" content=\"tex2rtf\">\n"
3143 "<!-- Sitemap 1.0 -->\n"
3144 "</HEAD><BODY>\n"
3145 "<OBJECT type=\"text/site properties\">\n"
3146 " <param name=\"ImageType\" value=\"Folder\">\n"
3147 "</OBJECT>\n"
3148 "<UL>\n");
3149
3150 TopicTable.BeginFind();
3151 wxNode *node = NULL;
3152 while ((node = TopicTable.Next()))
3153 {
3154 TexTopic *texTopic = (TexTopic *)node->Data();
3155 const char *topicName = node->GetKeyString();
3156 if (texTopic->filename && texTopic->keywords)
3157 {
3158 wxNode *node1 = texTopic->keywords->First();
3159 while (node1)
3160 {
3161 char *s = (char *)node1->Data();
3162 fprintf(f,
3163 " <LI> <OBJECT type=\"text/sitemap\">\n"
3164 " <param name=\"Local\" value=\"%s#%s\">\n"
3165 " <param name=\"Name\" value=\"%s\">\n"
3166 " </OBJECT>\n",
3167 texTopic->filename, topicName, s);
3168 node1 = node1->Next();
3169 }
3170 }
3171 }
3172
3173 fprintf(f, "</UL>\n");
3174 fclose(f);
3175 }
3176
3177
3178
3179 static FILE *HTMLWorkshopContents = NULL;
3180 static int HTMLWorkshopLastLevel = 0;
3181
3182 void HTMLWorkshopAddToContents(int level, char *s, char *file)
3183 {
3184 int i;
3185
3186 if (level > HTMLWorkshopLastLevel)
3187 for (i = HTMLWorkshopLastLevel; i < level; i++)
3188 fprintf(HTMLWorkshopContents, "<UL>");
3189 if (level < HTMLWorkshopLastLevel)
3190 for (i = level; i < HTMLWorkshopLastLevel; i++)
3191 fprintf(HTMLWorkshopContents, "</UL>");
3192
3193 SetCurrentOutput(HTMLWorkshopContents);
3194 fprintf(HTMLWorkshopContents,
3195 " <LI> <OBJECT type=\"text/sitemap\">\n"
3196 " <param name=\"Local\" value=\"%s#%s\">\n"
3197 " <param name=\"Name\" value=\"",
3198 file, s);
3199 OutputCurrentSection();
3200 fprintf(HTMLWorkshopContents,
3201 "\">\n"
3202 " </OBJECT>\n");
3203 HTMLWorkshopLastLevel = level;
3204 }
3205
3206
3207 void HTMLWorkshopStartContents()
3208 {
3209 char buf[300];
3210 sprintf(buf, "%s.hhc", FileRoot);
3211 HTMLWorkshopContents = fopen(buf, "wt");
3212 HTMLWorkshopLastLevel = 0;
3213
3214 fprintf(HTMLWorkshopContents,
3215 "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML//EN\">\n"
3216 "<HTML>\n"
3217 "<HEAD>\n"
3218 "<meta name=\"GENERATOR\" content=\"tex2rtf\">\n"
3219 "<!-- Sitemap 1.0 -->\n"
3220 "</HEAD><BODY>\n"
3221 "<OBJECT type=\"text/site properties\">\n"
3222 " <param name=\"ImageType\" value=\"Folder\">\n"
3223 "</OBJECT>\n"
3224 "<UL>\n"
3225 "<LI> <OBJECT type=\"text/sitemap\">\n"
3226 "<param name=\"Local\" value=\"%s\">\n"
3227 "<param name=\"Name\" value=\"Contents\">\n</OBJECT>\n",
3228 FileNameFromPath(TitlepageName)
3229 );
3230
3231 }
3232
3233
3234 void HTMLWorkshopEndContents()
3235 {
3236 for (int i = HTMLWorkshopLastLevel; i >= 0; i--)
3237 fprintf(HTMLWorkshopContents, "</UL>\n");
3238 fclose(HTMLWorkshopContents);
3239 }