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