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