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