]> git.saurik.com Git - wxWidgets.git/blob - utils/tex2rtf/src/htmlutil.cpp
Since wxConditionInternal is a friend of wxMutex and wxMutex has copy
[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(wxTex2RTFBuffer);
724 AddKeyWordForTopic(topicName, wxTex2RTFBuffer, 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(wxTex2RTFBuffer);
786 AddKeyWordForTopic(topicName, wxTex2RTFBuffer, 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(wxTex2RTFBuffer);
893 AddKeyWordForTopic(topicName, wxTex2RTFBuffer, 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(wxTex2RTFBuffer);
971 AddKeyWordForTopic(topicName, wxTex2RTFBuffer, 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 return TRUE;
2114 }
2115 case ltTWOCOLITEM:
2116 case ltTWOCOLITEMRULED:
2117 {
2118 /*
2119 if (start && (arg_no == 1))
2120 TexOutput("\n<DT> ");
2121 if (start && (arg_no == 2))
2122 TexOutput("<DD> ");
2123 */
2124 if (arg_no == 1)
2125 {
2126 if ( start ) {
2127 // DHS
2128 if (TwoColWidthA > -1) {
2129 char buf[100];
2130 sprintf(buf,"\n<TR><TD VALIGN=TOP WIDTH=%d>\n",TwoColWidthA);
2131 TexOutput(buf);
2132 } else
2133 TexOutput("\n<TR><TD VALIGN=TOP>\n");
2134 OutputFont();
2135 } else
2136 TexOutput("\n</FONT></TD>\n");
2137 }
2138 if (arg_no == 2)
2139 {
2140 // DHS
2141 if ( start ) {
2142 if (TwoColWidthB > -1) {
2143 char buf[100];
2144 sprintf(buf,"\n<TD VALIGN=TOP WIDTH=%d>\n",TwoColWidthB);
2145 TexOutput(buf);
2146 } else
2147 TexOutput("\n<TD VALIGN=TOP>\n");
2148 OutputFont();
2149 } else
2150 TexOutput("\n</FONT></TD></TR>\n");
2151 }
2152 return TRUE;
2153 break;
2154 }
2155 case ltNUMBEREDBIBITEM:
2156 {
2157 if (arg_no == 1 && start)
2158 {
2159 TexOutput("\n<DT> ");
2160 }
2161 if (arg_no == 2 && !start)
2162 TexOutput("<P>\n");
2163 break;
2164 }
2165 case ltBIBITEM:
2166 {
2167 char buf[100];
2168 if (arg_no == 1 && start)
2169 {
2170 char *citeKey = GetArgData();
2171 TexRef *ref = (TexRef *)TexReferences.Get(citeKey);
2172 if (ref)
2173 {
2174 if (ref->sectionNumber) delete[] ref->sectionNumber;
2175 sprintf(buf, "[%d]", citeCount);
2176 ref->sectionNumber = copystring(buf);
2177 }
2178
2179 sprintf(buf, "\n<DT> [%d] ", citeCount);
2180 TexOutput(buf);
2181 citeCount ++;
2182 return FALSE;
2183 }
2184 if (arg_no == 2 && !start)
2185 TexOutput("<P>\n");
2186 return TRUE;
2187 break;
2188 }
2189 case ltMARGINPAR:
2190 case ltMARGINPARODD:
2191 case ltMARGINPAREVEN:
2192 case ltNORMALBOX:
2193 case ltNORMALBOXD:
2194 {
2195 if (start)
2196 {
2197 TexOutput("<HR>\n");
2198 return TRUE;
2199 }
2200 else
2201 TexOutput("<HR><P>\n");
2202 break;
2203 }
2204 // DHS
2205 case ltTWOCOLWIDTHA:
2206 {
2207 if (start)
2208 {
2209 char *val = GetArgData();
2210 float points = ParseUnitArgument(val);
2211 TwoColWidthA = (int)((points * 100.0) / 72.0);
2212 }
2213 return FALSE;
2214 break;
2215 }
2216 // DHS
2217 case ltTWOCOLWIDTHB:
2218 {
2219 if (start)
2220 {
2221 char *val = GetArgData();
2222 float points = ParseUnitArgument(val);
2223 TwoColWidthB = (int)((points * 100.0) / 72.0);
2224 }
2225 return FALSE;
2226 break;
2227 }
2228 /*
2229 * Accents
2230 *
2231 */
2232 case ltACCENT_GRAVE:
2233 {
2234 if (start)
2235 {
2236 char *val = GetArgData();
2237 if (val)
2238 {
2239 switch (val[0])
2240 {
2241 case 'a':
2242 TexOutput("&agrave;");
2243 break;
2244 case 'e':
2245 TexOutput("&egrave;");
2246 break;
2247 case 'i':
2248 TexOutput("&igrave;");
2249 break;
2250 case 'o':
2251 TexOutput("&ograve;");
2252 break;
2253 case 'u':
2254 TexOutput("&ugrave;");
2255 break;
2256 case 'A':
2257 TexOutput("&Agrave;");
2258 break;
2259 case 'E':
2260 TexOutput("&Egrave;");
2261 break;
2262 case 'I':
2263 TexOutput("&Igrave;");
2264 break;
2265 case 'O':
2266 TexOutput("&Ograve;");
2267 break;
2268 case 'U':
2269 TexOutput("&Igrave;");
2270 break;
2271 default:
2272 break;
2273 }
2274 }
2275 }
2276 return FALSE;
2277 break;
2278 }
2279 case ltACCENT_ACUTE:
2280 {
2281 if (start)
2282 {
2283 char *val = GetArgData();
2284 if (val)
2285 {
2286 switch (val[0])
2287 {
2288 case 'a':
2289 TexOutput("&aacute;");
2290 break;
2291 case 'e':
2292 TexOutput("&eacute;");
2293 break;
2294 case 'i':
2295 TexOutput("&iacute;");
2296 break;
2297 case 'o':
2298 TexOutput("&oacute;");
2299 break;
2300 case 'u':
2301 TexOutput("&uacute;");
2302 break;
2303 case 'y':
2304 TexOutput("&yacute;");
2305 break;
2306 case 'A':
2307 TexOutput("&Aacute;");
2308 break;
2309 case 'E':
2310 TexOutput("&Eacute;");
2311 break;
2312 case 'I':
2313 TexOutput("&Iacute;");
2314 break;
2315 case 'O':
2316 TexOutput("&Oacute;");
2317 break;
2318 case 'U':
2319 TexOutput("&Uacute;");
2320 break;
2321 case 'Y':
2322 TexOutput("&Yacute;");
2323 break;
2324 default:
2325 break;
2326 }
2327 }
2328 }
2329 return FALSE;
2330 break;
2331 }
2332 case ltACCENT_CARET:
2333 {
2334 if (start)
2335 {
2336 char *val = GetArgData();
2337 if (val)
2338 {
2339 switch (val[0])
2340 {
2341 case 'a':
2342 TexOutput("&acirc;");
2343 break;
2344 case 'e':
2345 TexOutput("&ecirc;");
2346 break;
2347 case 'i':
2348 TexOutput("&icirc;");
2349 break;
2350 case 'o':
2351 TexOutput("&ocirc;");
2352 break;
2353 case 'u':
2354 TexOutput("&ucirc;");
2355 break;
2356 case 'A':
2357 TexOutput("&Acirc;");
2358 break;
2359 case 'E':
2360 TexOutput("&Ecirc;");
2361 break;
2362 case 'I':
2363 TexOutput("&Icirc;");
2364 break;
2365 case 'O':
2366 TexOutput("&Ocirc;");
2367 break;
2368 case 'U':
2369 TexOutput("&Icirc;");
2370 break;
2371 default:
2372 break;
2373 }
2374 }
2375 }
2376 return FALSE;
2377 break;
2378 }
2379 case ltACCENT_TILDE:
2380 {
2381 if (start)
2382 {
2383 char *val = GetArgData();
2384 if (val)
2385 {
2386 switch (val[0])
2387 {
2388 case ' ':
2389 TexOutput("~");
2390 break;
2391 case 'a':
2392 TexOutput("&atilde;");
2393 break;
2394 case 'n':
2395 TexOutput("&ntilde;");
2396 break;
2397 case 'o':
2398 TexOutput("&otilde;");
2399 break;
2400 case 'A':
2401 TexOutput("&Atilde;");
2402 break;
2403 case 'N':
2404 TexOutput("&Ntilde;");
2405 break;
2406 case 'O':
2407 TexOutput("&Otilde;");
2408 break;
2409 default:
2410 break;
2411 }
2412 }
2413 }
2414 return FALSE;
2415 break;
2416 }
2417 case ltACCENT_UMLAUT:
2418 {
2419 if (start)
2420 {
2421 char *val = GetArgData();
2422 if (val)
2423 {
2424 switch (val[0])
2425 {
2426 case 'a':
2427 TexOutput("&auml;");
2428 break;
2429 case 'e':
2430 TexOutput("&euml;");
2431 break;
2432 case 'i':
2433 TexOutput("&iuml;");
2434 break;
2435 case 'o':
2436 TexOutput("&ouml;");
2437 break;
2438 case 'u':
2439 TexOutput("&uuml;");
2440 break;
2441 case 'y':
2442 TexOutput("&yuml;");
2443 break;
2444 case 'A':
2445 TexOutput("&Auml;");
2446 break;
2447 case 'E':
2448 TexOutput("&Euml;");
2449 break;
2450 case 'I':
2451 TexOutput("&Iuml;");
2452 break;
2453 case 'O':
2454 TexOutput("&Ouml;");
2455 break;
2456 case 'U':
2457 TexOutput("&Uuml;");
2458 break;
2459 case 'Y':
2460 TexOutput("&Yuml;");
2461 break;
2462 default:
2463 break;
2464 }
2465 }
2466 }
2467 return FALSE;
2468 break;
2469 }
2470 case ltACCENT_DOT:
2471 {
2472 if (start)
2473 {
2474 char *val = GetArgData();
2475 if (val)
2476 {
2477 switch (val[0])
2478 {
2479 case 'a':
2480 TexOutput("&aring;");
2481 break;
2482 case 'A':
2483 TexOutput("&Aring;");
2484 break;
2485 default:
2486 break;
2487 }
2488 }
2489 }
2490 return FALSE;
2491 break;
2492 }
2493 case ltBACKGROUND:
2494 {
2495 if (start)
2496 {
2497 char *val = GetArgData();
2498 if (val)
2499 {
2500 bool isPicture = FALSE;
2501 char *s = ParseColourString(val, &isPicture);
2502 if (isPicture)
2503 {
2504 if (backgroundImageString)
2505 delete[] backgroundImageString;
2506 backgroundImageString = copystring(val);
2507 }
2508 else
2509 {
2510 if (backgroundColourString)
2511 delete[] backgroundColourString;
2512 backgroundColourString = copystring(val);
2513 }
2514 }
2515 }
2516 return FALSE;
2517 break;
2518 }
2519 case ltBACKGROUNDIMAGE:
2520 {
2521 if (start)
2522 {
2523 char *val = GetArgData();
2524 if (val)
2525 {
2526 if (backgroundImageString)
2527 delete[] backgroundImageString;
2528 backgroundImageString = copystring(val);
2529 }
2530 }
2531 return FALSE;
2532 break;
2533 }
2534 case ltBACKGROUNDCOLOUR:
2535 {
2536 if (start)
2537 {
2538 char *val = GetArgData();
2539 if (val)
2540 {
2541 if (backgroundColourString)
2542 delete[] backgroundColourString;
2543 backgroundColourString = copystring(val);
2544 }
2545 }
2546 return FALSE;
2547 break;
2548 }
2549 case ltTEXTCOLOUR:
2550 {
2551 if (start)
2552 {
2553 char *val = GetArgData();
2554 if (val)
2555 {
2556 if (textColourString)
2557 delete[] textColourString;
2558 textColourString = copystring(val);
2559 }
2560 }
2561 return FALSE;
2562 break;
2563 }
2564 case ltLINKCOLOUR:
2565 {
2566 if (start)
2567 {
2568 char *val = GetArgData();
2569 if (val)
2570 {
2571 if (linkColourString)
2572 delete[] linkColourString;
2573 linkColourString = copystring(val);
2574 }
2575 }
2576 return FALSE;
2577 break;
2578 }
2579 case ltFOLLOWEDLINKCOLOUR:
2580 {
2581 if (start)
2582 {
2583 char *val = GetArgData();
2584 if (val)
2585 {
2586 if (followedLinkColourString)
2587 delete[] followedLinkColourString;
2588 followedLinkColourString = copystring(val);
2589 }
2590 }
2591 return FALSE;
2592 break;
2593 }
2594 case ltACCENT_CADILLA:
2595 {
2596 if (start)
2597 {
2598 char *val = GetArgData();
2599 if (val)
2600 {
2601 switch (val[0])
2602 {
2603 case 'c':
2604 TexOutput("&ccedil;");
2605 break;
2606 case 'C':
2607 TexOutput("&Ccedil;");
2608 break;
2609 default:
2610 break;
2611 }
2612 }
2613 }
2614 return FALSE;
2615 break;
2616 }
2617 /*
2618 case ltFOOTNOTE:
2619 case ltFOOTNOTEPOPUP:
2620 {
2621 if (arg_no == 1)
2622 return TRUE;
2623 else
2624 return FALSE;
2625 break;
2626 }
2627 */
2628 case ltTABULAR:
2629 case ltSUPERTABULAR:
2630 {
2631 if (arg_no == 1)
2632 {
2633 if (start)
2634 {
2635 currentRowNumber = 0;
2636 inTabular = TRUE;
2637 startRows = TRUE;
2638 tableVerticalLineLeft = FALSE;
2639 tableVerticalLineRight = FALSE;
2640 int currentWidth = 0;
2641
2642 char *alignString = copystring(GetArgData());
2643 ParseTableArgument(alignString);
2644
2645 TexOutput("<TABLE BORDER>\n");
2646
2647 // Write the first row formatting for compatibility
2648 // with standard Latex
2649 if (compatibilityMode)
2650 {
2651 TexOutput("<TR>\n<TD>");
2652 OutputFont();
2653 /*
2654 for (int i = 0; i < noColumns; i++)
2655 {
2656 currentWidth += TableData[i].width;
2657 sprintf(buf, "\\cellx%d", currentWidth);
2658 TexOutput(buf);
2659 }
2660 TexOutput("\\pard\\intbl\n");
2661 */
2662 }
2663 delete[] alignString;
2664
2665 return FALSE;
2666 }
2667 }
2668 else if (arg_no == 2 && !start)
2669 {
2670 TexOutput("</TABLE>\n");
2671 inTabular = FALSE;
2672 }
2673 break;
2674 }
2675 case ltTHEBIBLIOGRAPHY:
2676 {
2677 if (start && (arg_no == 1))
2678 {
2679 ReopenFile(&Chapters, &ChaptersName);
2680 AddTexRef("bibliography", ChaptersName, "bibliography");
2681 SetCurrentSubsectionName("bibliography", ChaptersName);
2682
2683 citeCount = 1;
2684
2685 SetCurrentOutput(Chapters);
2686
2687 char titleBuf[150];
2688 if (truncateFilenames)
2689 sprintf(titleBuf, "%s.htm", FileNameFromPath(FileRoot));
2690 else
2691 sprintf(titleBuf, "%s_contents.html", FileNameFromPath(FileRoot));
2692
2693 TexOutput("<head><title>");
2694 TexOutput(ReferencesNameString);
2695 TexOutput("</title></head>\n");
2696 OutputBodyStart();
2697
2698 fprintf(Chapters, "<A NAME=\"%s\">\n<H2>%s", "bibliography", ReferencesNameString);
2699 AddBrowseButtons("contents", titleBuf, // Up
2700 lastTopic, lastFileName, // Last topic
2701 "bibliography", ChaptersName); // This topic
2702
2703 SetCurrentOutputs(Contents, Chapters);
2704 fprintf(Contents, "\n<LI><A HREF=\"%s#%s\">", ConvertCase(ChaptersName), "bibliography");
2705
2706 fprintf(Contents, "%s</A>\n", ReferencesNameString);
2707 fprintf(Chapters, "</H2>\n</A>\n");
2708
2709 SetCurrentOutput(Chapters);
2710 return FALSE;
2711 }
2712 if (!start && (arg_no == 2))
2713 {
2714 }
2715 return TRUE;
2716 break;
2717 }
2718 case ltINDEX:
2719 {
2720 /* Build up list of keywords associated with topics */
2721 if (start)
2722 {
2723 // char *entry = GetArgData();
2724 char buf[300];
2725 OutputChunkToString(GetArgChunk(), buf);
2726 if (CurrentTopic)
2727 {
2728 AddKeyWordForTopic(CurrentTopic, buf, currentFileName);
2729 }
2730 }
2731 return FALSE;
2732 break;
2733 }
2734 case ltFCOL:
2735 // case ltBCOL:
2736 {
2737 if (start)
2738 {
2739 switch (arg_no)
2740 {
2741 case 1:
2742 {
2743 char *name = GetArgData();
2744 char buf2[10];
2745 if (!FindColourHTMLString(name, buf2))
2746 {
2747 strcpy(buf2, "#000000");
2748 char buf[100];
2749 sprintf(buf, "Could not find colour name %s", name);
2750 OnError(buf);
2751 }
2752 TexOutput("<FONT COLOR=\"");
2753 TexOutput(buf2);
2754 TexOutput("\">");
2755 break;
2756 }
2757 case 2:
2758 {
2759 return TRUE;
2760 break;
2761 }
2762 default:
2763 break;
2764 }
2765 }
2766 else
2767 {
2768 if (arg_no == 2) TexOutput("</FONT>");
2769 }
2770 return FALSE;
2771 break;
2772 }
2773 case ltINSERTATLEVEL:
2774 {
2775 // This macro allows you to insert text at a different level
2776 // from the current level, e.g. into the Sections from within a subsubsection.
2777 if (useWord)
2778 return FALSE;
2779 static int currentLevelNo = 1;
2780 static FILE* oldLevelFile = Chapters;
2781 if (start)
2782 {
2783 switch (arg_no)
2784 {
2785 case 1:
2786 {
2787 oldLevelFile = CurrentOutput1;
2788
2789 char *str = GetArgData();
2790 currentLevelNo = atoi(str);
2791 FILE* outputFile;
2792 // TODO: cope with article style (no chapters)
2793 switch (currentLevelNo)
2794 {
2795 case 1:
2796 {
2797 outputFile = Chapters;
2798 break;
2799 }
2800 case 2:
2801 {
2802 outputFile = Sections;
2803 break;
2804 }
2805 case 3:
2806 {
2807 outputFile = Subsections;
2808 break;
2809 }
2810 case 4:
2811 {
2812 outputFile = Subsubsections;
2813 break;
2814 }
2815 default:
2816 {
2817 outputFile = NULL;
2818 break;
2819 }
2820 }
2821 if (outputFile)
2822 CurrentOutput1 = outputFile;
2823 return FALSE;
2824 break;
2825 }
2826 case 2:
2827 {
2828 return TRUE;
2829 break;
2830 }
2831 default:
2832 break;
2833 }
2834 return TRUE;
2835 }
2836 else
2837 {
2838 if (arg_no == 2)
2839 {
2840 CurrentOutput1 = oldLevelFile;
2841 }
2842 return TRUE;
2843 }
2844 }
2845 default:
2846 return DefaultOnArgument(macroId, arg_no, start);
2847 break;
2848 }
2849 return TRUE;
2850 }
2851
2852 bool HTMLGo(void)
2853 {
2854 fileId = 0;
2855 inVerbatim = FALSE;
2856 indentLevel = 0;
2857 inTabular = FALSE;
2858 startRows = FALSE;
2859 tableVerticalLineLeft = FALSE;
2860 tableVerticalLineRight = FALSE;
2861 noColumns = 0;
2862
2863 if (InputFile && OutputFile)
2864 {
2865 // Do some HTML-specific transformations on all the strings,
2866 // recursively
2867 Text2HTML(GetTopLevelChunk());
2868
2869 char buf[300];
2870 if (truncateFilenames)
2871 sprintf(buf, "%s.htm", FileRoot);
2872 else
2873 sprintf(buf, "%s_contents.html", FileRoot);
2874 if (TitlepageName) delete[] TitlepageName;
2875 TitlepageName = copystring(buf);
2876 Titlepage = fopen(buf, "w");
2877
2878 if (truncateFilenames)
2879 sprintf(buf, "%s_fc.htm", FileRoot);
2880 else
2881 sprintf(buf, "%s_fcontents.html", FileRoot);
2882
2883 contentsFrameName = copystring(buf);
2884
2885 Contents = fopen(TmpContentsName, "w");
2886
2887 if (htmlFrameContents)
2888 {
2889 // FrameContents = fopen(TmpFrameContentsName, "w");
2890 FrameContents = fopen(contentsFrameName, "w");
2891 fprintf(FrameContents, "<HTML>\n<UL>\n");
2892 }
2893
2894 if (!Titlepage || !Contents)
2895 {
2896 OnError("Cannot open output file!");
2897 return FALSE;
2898 }
2899 AddTexRef("contents", FileNameFromPath(TitlepageName), ContentsNameString);
2900
2901 fprintf(Contents, "<P><P><H2>%s</H2><P><P>\n", ContentsNameString);
2902
2903 fprintf(Contents, "<UL>\n");
2904
2905 SetCurrentOutput(Titlepage);
2906 if (htmlWorkshopFiles) HTMLWorkshopStartContents();
2907 OnInform("Converting...");
2908
2909 TraverseDocument();
2910 fprintf(Contents, "</UL>\n\n");
2911
2912 // SetCurrentOutput(Titlepage);
2913 fclose(Titlepage);
2914
2915 if (Contents)
2916 {
2917 // fprintf(Titlepage, "\n</BODY></HTML>\n");
2918 fclose(Contents);
2919 Contents = NULL;
2920 }
2921
2922 if (FrameContents)
2923 {
2924 fprintf(FrameContents, "\n</UL>\n");
2925 fprintf(FrameContents, "</HTML>\n");
2926 fclose(FrameContents);
2927 FrameContents = NULL;
2928 }
2929
2930 if (Chapters)
2931 {
2932 fprintf(Chapters, "\n</FONT></BODY></HTML>\n");
2933 fclose(Chapters);
2934 Chapters = NULL;
2935 }
2936 if (Sections)
2937 {
2938 fprintf(Sections, "\n</FONT></BODY></HTML>\n");
2939 fclose(Sections);
2940 Sections = NULL;
2941 }
2942 if (Subsections && !combineSubSections)
2943 {
2944 fprintf(Subsections, "\n</FONT></BODY></HTML>\n");
2945 fclose(Subsections);
2946 Subsections = NULL;
2947 }
2948 if (Subsubsections && !combineSubSections)
2949 {
2950 fprintf(Subsubsections, "\n</FONT></BODY></HTML>\n");
2951 fclose(Subsubsections);
2952 Subsubsections = NULL;
2953 }
2954 if ( SectionContentsFD )
2955 {
2956 fclose(SectionContentsFD);
2957 SectionContentsFD = NULL;
2958 }
2959
2960 // Create a temporary file for the title page header, add some info,
2961 // and concat the titlepage just generated.
2962 // This is necessary in order to put the title of the document
2963 // at the TOP of the file within <HEAD>, even though we only find out
2964 // what it is later on.
2965 FILE *tmpTitle = fopen("title.tmp", "w");
2966 if (tmpTitle)
2967 {
2968 if (DocumentTitle)
2969 {
2970 SetCurrentOutput(tmpTitle);
2971 TexOutput("\n<HTML>\n<HEAD><TITLE>");
2972 TraverseChildrenFromChunk(DocumentTitle);
2973 TexOutput("</TITLE></HEAD>\n");
2974 }
2975 else
2976 {
2977 SetCurrentOutput(tmpTitle);
2978 if (contentsString)
2979 fprintf(tmpTitle, "<HEAD><TITLE>%s</TITLE></HEAD>\n\n", contentsString);
2980 else
2981 fprintf(tmpTitle, "<HEAD><TITLE>%s</TITLE></HEAD>\n\n", FileNameFromPath(FileRoot));
2982 }
2983
2984 // Output frame information
2985 if (htmlFrameContents)
2986 {
2987 char firstFileName[300];
2988 if (truncateFilenames)
2989 sprintf(firstFileName, "%s1.htm", FileRoot);
2990 else
2991 sprintf(firstFileName, "%s1.html", FileRoot);
2992
2993 fprintf(tmpTitle, "<FRAMESET COLS=\"30%%,70%%\">\n");
2994
2995 fprintf(tmpTitle, "<FRAME SRC=\"%s\">\n", ConvertCase(FileNameFromPath(contentsFrameName)));
2996 fprintf(tmpTitle, "<FRAME SRC=\"%s\" NAME=\"mainwindow\">\n", ConvertCase(FileNameFromPath(firstFileName)));
2997 fprintf(tmpTitle, "</FRAMESET>\n");
2998
2999 fprintf(tmpTitle, "<NOFRAMES>\n");
3000 }
3001
3002 // Output <BODY...> to temporary title page
3003 OutputBodyStart();
3004
3005 // Concat titlepage
3006 FILE *fd = fopen(TitlepageName, "r");
3007 if (fd)
3008 {
3009 int ch = getc(fd);
3010 while (ch != EOF)
3011 {
3012 putc(ch, tmpTitle);
3013 ch = getc(fd);
3014 }
3015 fclose(fd);
3016 }
3017
3018 fprintf(tmpTitle, "\n</FONT></BODY>\n");
3019
3020 if (htmlFrameContents)
3021 {
3022 fprintf(tmpTitle, "\n</NOFRAMES>\n");
3023 }
3024 fprintf(tmpTitle, "\n</HTML>\n");
3025
3026 fclose(tmpTitle);
3027 if (FileExists(TitlepageName)) wxRemoveFile(TitlepageName);
3028 if (!wxRenameFile("title.tmp", TitlepageName))
3029 {
3030 wxCopyFile("title.tmp", TitlepageName);
3031 wxRemoveFile("title.tmp");
3032 }
3033 }
3034
3035 if (lastFileName) delete[] lastFileName;
3036 lastFileName = NULL;
3037 if (lastTopic) delete[] lastTopic;
3038 lastTopic = NULL;
3039
3040 if (FileExists(ContentsName)) wxRemoveFile(ContentsName);
3041
3042 if (!wxRenameFile(TmpContentsName, ContentsName))
3043 {
3044 wxCopyFile(TmpContentsName, ContentsName);
3045 wxRemoveFile(TmpContentsName);
3046 }
3047
3048 // Generate .htx file if requested
3049 if (htmlIndex)
3050 {
3051 char htmlIndexName[300];
3052 sprintf(htmlIndexName, "%s.htx", FileRoot);
3053 GenerateHTMLIndexFile(htmlIndexName);
3054 }
3055
3056 // Generate HTML Help Workshop files if requested
3057 if (htmlWorkshopFiles)
3058 {
3059 HTMLWorkshopEndContents();
3060 GenerateHTMLWorkshopFiles(FileRoot);
3061 }
3062
3063
3064 return TRUE;
3065 }
3066
3067 return FALSE;
3068 }
3069
3070 // Output .htx index file
3071 void GenerateHTMLIndexFile(char *fname)
3072 {
3073 FILE *fd = fopen(fname, "w");
3074 if (!fd)
3075 return;
3076
3077 TopicTable.BeginFind();
3078 wxNode *node = NULL;
3079 while ((node = TopicTable.Next()))
3080 {
3081 TexTopic *texTopic = (TexTopic *)node->Data();
3082 const char *topicName = node->GetKeyString();
3083 if (texTopic->filename && texTopic->keywords)
3084 {
3085 wxNode *node1 = texTopic->keywords->First();
3086 while (node1)
3087 {
3088 char *s = (char *)node1->Data();
3089 fprintf(fd, "%s|%s|%s\n", topicName, texTopic->filename, s);
3090 node1 = node1->Next();
3091 }
3092 }
3093 }
3094 fclose(fd);
3095 }
3096
3097
3098
3099
3100
3101
3102
3103 // output .hpp, .hhc and .hhk files:
3104
3105
3106 void GenerateHTMLWorkshopFiles(char *fname)
3107 {
3108 FILE *f;
3109 char buf[300];
3110
3111 /* Generate project file : */
3112
3113 sprintf(buf, "%s.hhp", fname);
3114 f = fopen(buf, "wt");
3115 fprintf(f,
3116 "[OPTIONS]\n"
3117 "Compatibility=1.1\n"
3118 "Full-text search=Yes\n"
3119 "Contents file=%s.hhc\n"
3120 "Compiled file=%s.chm\n"
3121 "Default Window=%sHelp\n"
3122 "Default topic=%s\n"
3123 "Index file=%s.hhk\n"
3124 "Title=",
3125 FileNameFromPath(fname),
3126 FileNameFromPath(fname),
3127 FileNameFromPath(fname),
3128 FileNameFromPath(TitlepageName),
3129 FileNameFromPath(fname)
3130 );
3131
3132 if (DocumentTitle) {
3133 SetCurrentOutput(f);
3134 TraverseChildrenFromChunk(DocumentTitle);
3135 }
3136 else fprintf(f, "(unknown)");
3137
3138 fprintf(f, "\n\n[WINDOWS]\n"
3139 "%sHelp=,\"%s.hhc\",\"%s.hhk\",\"%s\",,,,,,0x2420,,0x380e,,,,,0,,,",
3140 FileNameFromPath(fname),
3141 FileNameFromPath(fname),
3142 FileNameFromPath(fname),
3143 FileNameFromPath(TitlepageName));
3144
3145
3146 fprintf(f, "\n\n[FILES]\n");
3147 fprintf(f, "%s\n", FileNameFromPath(TitlepageName));
3148 for (int i = 1; i <= fileId; i++) {
3149 if (truncateFilenames)
3150 sprintf(buf, "%s%d.htm", FileNameFromPath(FileRoot), i);
3151 else
3152 sprintf(buf, "%s%d.html", FileNameFromPath(FileRoot), i);
3153 fprintf(f, "%s\n", buf);
3154 }
3155 fclose(f);
3156
3157 /* Generate index file : */
3158
3159 sprintf(buf, "%s.hhk", fname);
3160 f = fopen(buf, "wt");
3161
3162 fprintf(f,
3163 "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML//EN\">\n"
3164 "<HTML>\n"
3165 "<HEAD>\n"
3166 "<meta name=\"GENERATOR\" content=\"tex2rtf\">\n"
3167 "<!-- Sitemap 1.0 -->\n"
3168 "</HEAD><BODY>\n"
3169 "<OBJECT type=\"text/site properties\">\n"
3170 " <param name=\"ImageType\" value=\"Folder\">\n"
3171 "</OBJECT>\n"
3172 "<UL>\n");
3173
3174 TopicTable.BeginFind();
3175 wxNode *node = NULL;
3176 while ((node = TopicTable.Next()))
3177 {
3178 TexTopic *texTopic = (TexTopic *)node->Data();
3179 const char *topicName = node->GetKeyString();
3180 if (texTopic->filename && texTopic->keywords)
3181 {
3182 wxNode *node1 = texTopic->keywords->First();
3183 while (node1)
3184 {
3185 char *s = (char *)node1->Data();
3186 fprintf(f,
3187 " <LI> <OBJECT type=\"text/sitemap\">\n"
3188 " <param name=\"Local\" value=\"%s#%s\">\n"
3189 " <param name=\"Name\" value=\"%s\">\n"
3190 " </OBJECT>\n",
3191 texTopic->filename, topicName, s);
3192 node1 = node1->Next();
3193 }
3194 }
3195 }
3196
3197 fprintf(f, "</UL>\n");
3198 fclose(f);
3199 }
3200
3201
3202
3203 static FILE *HTMLWorkshopContents = NULL;
3204 static int HTMLWorkshopLastLevel = 0;
3205
3206 void HTMLWorkshopAddToContents(int level, char *s, char *file)
3207 {
3208 int i;
3209
3210 if (level > HTMLWorkshopLastLevel)
3211 for (i = HTMLWorkshopLastLevel; i < level; i++)
3212 fprintf(HTMLWorkshopContents, "<UL>");
3213 if (level < HTMLWorkshopLastLevel)
3214 for (i = level; i < HTMLWorkshopLastLevel; i++)
3215 fprintf(HTMLWorkshopContents, "</UL>");
3216
3217 SetCurrentOutput(HTMLWorkshopContents);
3218 fprintf(HTMLWorkshopContents,
3219 " <LI> <OBJECT type=\"text/sitemap\">\n"
3220 " <param name=\"Local\" value=\"%s#%s\">\n"
3221 " <param name=\"Name\" value=\"",
3222 file, s);
3223 OutputCurrentSection();
3224 fprintf(HTMLWorkshopContents,
3225 "\">\n"
3226 " </OBJECT>\n");
3227 HTMLWorkshopLastLevel = level;
3228 }
3229
3230
3231 void HTMLWorkshopStartContents()
3232 {
3233 char buf[300];
3234 sprintf(buf, "%s.hhc", FileRoot);
3235 HTMLWorkshopContents = fopen(buf, "wt");
3236 HTMLWorkshopLastLevel = 0;
3237
3238 fprintf(HTMLWorkshopContents,
3239 "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML//EN\">\n"
3240 "<HTML>\n"
3241 "<HEAD>\n"
3242 "<meta name=\"GENERATOR\" content=\"tex2rtf\">\n"
3243 "<!-- Sitemap 1.0 -->\n"
3244 "</HEAD><BODY>\n"
3245 "<OBJECT type=\"text/site properties\">\n"
3246 " <param name=\"ImageType\" value=\"Folder\">\n"
3247 "</OBJECT>\n"
3248 "<UL>\n"
3249 "<LI> <OBJECT type=\"text/sitemap\">\n"
3250 "<param name=\"Local\" value=\"%s\">\n"
3251 "<param name=\"Name\" value=\"Contents\">\n</OBJECT>\n",
3252 FileNameFromPath(TitlepageName)
3253 );
3254
3255 }
3256
3257
3258 void HTMLWorkshopEndContents()
3259 {
3260 for (int i = HTMLWorkshopLastLevel; i >= 0; i--)
3261 fprintf(HTMLWorkshopContents, "</UL>\n");
3262 fclose(HTMLWorkshopContents);
3263 }