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