]> git.saurik.com Git - wxWidgets.git/blob - utils/tex2rtf/src/tex2rtf.cpp
case insensitive <font face>
[wxWidgets.git] / utils / tex2rtf / src / tex2rtf.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: tex2rtf.cpp
3 // Purpose: Converts Latex to linear/WinHelp RTF, HTML, wxHelp.
4 // Author: Julian Smart
5 // Modified by:
6 // Created: 7.9.93
7 // RCS-ID: $Id$
8 // Copyright: (c) Julian Smart
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 #ifdef __GNUG__
13 #pragma implementation
14 #endif
15
16 // For compilers that support precompilation, includes "wx.h".
17 #include "wx/wxprec.h"
18
19 #ifdef __BORLANDC__
20 #pragma hdrstop
21 #endif
22
23 #ifndef WX_PRECOMP
24 #include "wx/wx.h"
25 #endif
26
27 #ifndef NO_GUI
28 #include "wx/help.h"
29 #include "wx/timer.h"
30 #endif
31
32 #if defined(NO_GUI) || defined(__UNIX__)
33 #if wxUSE_IOSTREAMH
34 #include <iostream.h>
35 #include <fstream.h>
36 #else
37 #include <iostream>
38 #include <fstream>
39 #endif
40 #endif
41
42 #include <ctype.h>
43 #include <stdlib.h>
44 #include "tex2any.h"
45 #include "tex2rtf.h"
46 #include "rtfutils.h"
47
48 #if (defined(__WXGTK__) || defined(__WXMOTIF__) || defined(__WXMAC__)) && !defined(NO_GUI)
49 #include "tex2rtf.xpm"
50 #endif
51
52 const float versionNo = 2.0;
53
54 TexChunk *currentMember = NULL;
55 bool startedSections = FALSE;
56 char *contentsString = NULL;
57 bool suppressNameDecoration = FALSE;
58 bool OkToClose = TRUE;
59 int passNumber = 1;
60 int errorCount = 0;
61
62 #ifndef NO_GUI
63
64 extern char *BigBuffer;
65 extern char *TexFileRoot;
66 extern char *TexBibName; // Bibliography output file name
67 extern char *TexTmpBibName; // Temporary bibliography output file name
68 extern wxList ColourTable;
69 extern TexChunk *TopLevel;
70 extern char *PageStyle;
71 extern char *BibliographyStyleString;
72 extern char *DocumentStyleString;
73 extern char *bitmapMethod;
74 extern char *backgroundColourString;
75 extern char *ContentsNameString;
76 extern char *AbstractNameString;
77 extern char *GlossaryNameString;
78 extern char *ReferencesNameString;
79 extern char *FiguresNameString;
80 extern char *TablesNameString;
81 extern char *FigureNameString;
82 extern char *TableNameString;
83 extern char *IndexNameString;
84 extern char *ChapterNameString;
85 extern char *SectionNameString;
86 extern char *SubsectionNameString;
87 extern char *SubsubsectionNameString;
88 extern char *UpNameString;
89
90
91
92 #if wxUSE_HELP
93 wxHelpController *HelpInstance = NULL;
94 #endif // wxUSE_HELP
95
96 #ifdef __WXMSW__
97 static char *ipc_buffer = NULL;
98 static char Tex2RTFLastStatus[100];
99 Tex2RTFServer *TheTex2RTFServer = NULL;
100 #endif
101 #endif
102
103 char *bulletFile = NULL;
104
105 FILE *Contents = NULL; // Contents page
106 FILE *Chapters = NULL; // Chapters (WinHelp RTF) or rest of file (linear RTF)
107 FILE *Sections = NULL;
108 FILE *Subsections = NULL;
109 FILE *Subsubsections = NULL;
110 FILE *Popups = NULL;
111 FILE *WinHelpContentsFile = NULL;
112
113 char *InputFile = NULL;
114 char *OutputFile = NULL;
115 char *MacroFile = copystring("tex2rtf.ini");
116
117 char *FileRoot = NULL;
118 char *ContentsName = NULL; // Contents page from last time around
119 char *TmpContentsName = NULL; // Current contents page
120 char *TmpFrameContentsName = NULL; // Current frame contents page
121 char *WinHelpContentsFileName = NULL; // WinHelp .cnt file
122 char *RefFileName = NULL; // Reference file name
123
124 char *RTFCharset = copystring("ansi");
125
126 #ifdef __WXMSW__
127 int BufSize = 100; // Size of buffer in K
128 #else
129 int BufSize = 500;
130 #endif
131
132 bool Go(void);
133 void ShowOptions(void);
134
135 #ifdef NO_GUI
136
137 #if wxUSE_GUI || !defined(__UNIX__)
138 // wxBase for Unix does not have wxBuffer
139 extern
140 #endif
141 char *wxBuffer; // we must init it, otherwise tex2rtf will crash
142
143 int main(int argc, char **argv)
144 #else
145 wxMenuBar *menuBar = NULL;
146 MyFrame *frame = NULL;
147
148 // DECLARE_APP(MyApp)
149 IMPLEMENT_APP(MyApp)
150
151 // `Main program' equivalent, creating windows and returning main app frame
152 bool MyApp::OnInit()
153 #endif
154 {
155 // Use default list of macros defined in tex2any.cc
156 DefineDefaultMacros();
157 AddMacroDef(ltHARDY, "hardy", 0);
158
159 FileRoot = new char[300];
160 ContentsName = new char[300];
161 TmpContentsName = new char[300];
162 TmpFrameContentsName = new char[300];
163 WinHelpContentsFileName = new char[300];
164 RefFileName = new char[300];
165
166 ColourTable.DeleteContents(TRUE);
167
168 int n = 1;
169
170 // Read input/output files
171 if (argc > 1)
172 {
173 if (argv[1][0] != '-')
174 {
175 InputFile = argv[1];
176 n ++;
177
178 if (argc > 2)
179 {
180 if (argv[2][0] != '-')
181 {
182 OutputFile = argv[2];
183 n ++;
184 }
185 }
186 }
187 }
188
189 #ifdef NO_GUI
190 wxBuffer = new char[1500];
191 // this is done in wxApp, but NO_GUI version doesn't call it :-(
192
193 if (!InputFile || !OutputFile)
194 {
195 wxSTD cout << "Tex2RTF: input or output file is missing.\n";
196 ShowOptions();
197 exit(1);
198 }
199
200 #endif
201 if (InputFile)
202 {
203 TexPathList.EnsureFileAccessible(InputFile);
204 }
205 if (!InputFile || !OutputFile)
206 isInteractive = TRUE;
207
208 int i;
209 for (i = n; i < argc;)
210 {
211 if (strcmp(argv[i], "-winhelp") == 0)
212 {
213 i ++;
214 convertMode = TEX_RTF;
215 winHelp = TRUE;
216 }
217 #ifndef NO_GUI
218 else if (strcmp(argv[i], "-interactive") == 0)
219 {
220 i ++;
221 isInteractive = TRUE;
222 }
223 #endif
224 else if (strcmp(argv[i], "-sync") == 0) // Don't yield
225 {
226 i ++;
227 isSync = TRUE;
228 }
229 else if (strcmp(argv[i], "-rtf") == 0)
230 {
231 i ++;
232 convertMode = TEX_RTF;
233 }
234 else if (strcmp(argv[i], "-html") == 0)
235 {
236 i ++;
237 convertMode = TEX_HTML;
238 }
239 else if (strcmp(argv[i], "-xlp") == 0)
240 {
241 i ++;
242 convertMode = TEX_XLP;
243 }
244 else if (strcmp(argv[i], "-twice") == 0)
245 {
246 i ++;
247 runTwice = TRUE;
248 }
249 else if (strcmp(argv[i], "-macros") == 0)
250 {
251 i ++;
252 if (i < argc)
253 {
254 MacroFile = copystring(argv[i]);
255 i ++;
256 }
257 }
258 else if (strcmp(argv[i], "-bufsize") == 0)
259 {
260 i ++;
261 if (i < argc)
262 {
263 BufSize = atoi(argv[i]);
264 i ++;
265 }
266 }
267 else if (strcmp(argv[i], "-charset") == 0)
268 {
269 i ++;
270 if (i < argc)
271 {
272 char *s = argv[i];
273 i ++;
274 if (strcmp(s, "ansi") == 0 || strcmp(s, "pc") == 0 || strcmp(s, "mac") == 0 ||
275 strcmp(s, "pca") == 0)
276 RTFCharset = copystring(s);
277 else
278 {
279 OnError("Incorrect argument for -charset");
280 return FALSE;
281 }
282 }
283 }
284 else if (strcmp(argv[i], "-checkcurleybraces") == 0)
285 {
286 i ++;
287 checkCurleyBraces = TRUE;
288 }
289 else if (strcmp(argv[i], "-checksyntax") == 0)
290 {
291 i ++;
292 checkSyntax = TRUE;
293 }
294 else
295 {
296 wxString buf;
297 buf.Printf("Invalid switch %s.\n", argv[i]);
298 OnError((char *)buf.c_str());
299 i++;
300 #ifdef NO_GUI
301 ShowOptions();
302 exit(1);
303 #endif
304 return FALSE;
305 }
306 }
307
308 #if defined(__WXMSW__) && !defined(NO_GUI)
309 wxDDEInitialize();
310 Tex2RTFLastStatus[0] = 0; // DDE connection return value
311 TheTex2RTFServer = new Tex2RTFServer;
312 TheTex2RTFServer->Create("TEX2RTF");
313 #endif
314
315 #if defined(__WXMSW__) && defined(__WIN16__)
316 // Limit to max Windows array size
317 if (BufSize > 64) BufSize = 64;
318 #endif
319
320 TexInitialize(BufSize);
321 ResetContentsLevels(0);
322
323 #ifndef NO_GUI
324
325 if (isInteractive)
326 {
327 char buf[100];
328
329 // Create the main frame window
330 frame = new MyFrame(NULL, -1, "Tex2RTF", wxPoint(-1, -1), wxSize(400, 300));
331 frame->CreateStatusBar(2);
332
333 // Give it an icon
334 // TODO: uncomment this when we have tex2rtf.xpm
335 frame->SetIcon(wxICON(tex2rtf));
336
337 if (InputFile)
338 {
339 sprintf(buf, "Tex2RTF [%s]", FileNameFromPath(InputFile));
340 frame->SetTitle(buf);
341 }
342
343 // Make a menubar
344 wxMenu *file_menu = new wxMenu;
345 file_menu->Append(TEX_GO, "&Go", "Run converter");
346 file_menu->Append(TEX_SET_INPUT, "Set &Input File", "Set the LaTeX input file");
347 file_menu->Append(TEX_SET_OUTPUT, "Set &Output File", "Set the output file");
348 file_menu->AppendSeparator();
349 file_menu->Append(TEX_VIEW_LATEX, "View &LaTeX File", "View the LaTeX input file");
350 file_menu->Append(TEX_VIEW_OUTPUT, "View Output &File", "View output file");
351 file_menu->Append(TEX_SAVE_FILE, "&Save log file", "Save displayed text into file");
352 file_menu->AppendSeparator();
353 file_menu->Append(TEX_QUIT, "E&xit", "Exit Tex2RTF");
354
355 wxMenu *macro_menu = new wxMenu;
356
357 macro_menu->Append(TEX_LOAD_CUSTOM_MACROS, "&Load Custom Macros", "Load custom LaTeX macro file");
358 macro_menu->Append(TEX_VIEW_CUSTOM_MACROS, "View &Custom Macros", "View custom LaTeX macros");
359
360 wxMenu *mode_menu = new wxMenu;
361
362 mode_menu->Append(TEX_MODE_RTF, "Output linear &RTF", "Wordprocessor-compatible RTF");
363 mode_menu->Append(TEX_MODE_WINHELP, "Output &WinHelp RTF", "WinHelp-compatible RTF");
364 mode_menu->Append(TEX_MODE_HTML, "Output &HTML", "HTML World Wide Web hypertext file");
365 mode_menu->Append(TEX_MODE_XLP, "Output &XLP", "wxHelp hypertext help file");
366
367 wxMenu *options_menu = new wxMenu;
368
369 options_menu->Append(TEX_OPTIONS_CURELY_BRACE, "Curley brace matching", "Checks for mismatched curley braces",TRUE);
370 options_menu->Append(TEX_OPTIONS_SYNTAX_CHECKING, "Syntax checking", "Syntax checking for common errors",TRUE);
371
372 options_menu->Check(TEX_OPTIONS_CURELY_BRACE, checkCurleyBraces);
373 options_menu->Check(TEX_OPTIONS_SYNTAX_CHECKING, checkSyntax);
374
375 wxMenu *help_menu = new wxMenu;
376
377 help_menu->Append(TEX_HELP, "&Help", "Tex2RTF Contents Page");
378 help_menu->Append(TEX_ABOUT, "&About Tex2RTF", "About Tex2RTF");
379
380 menuBar = new wxMenuBar;
381 menuBar->Append(file_menu, "&File");
382 menuBar->Append(macro_menu, "&Macros");
383 menuBar->Append(mode_menu, "&Conversion Mode");
384 menuBar->Append(options_menu, "&Options");
385 menuBar->Append(help_menu, "&Help");
386
387 frame->SetMenuBar(menuBar);
388 frame->textWindow = new wxTextCtrl(frame, -1, "", wxPoint(-1, -1), wxSize(-1, -1), wxTE_READONLY|wxTE_MULTILINE);
389
390 (*frame->textWindow) << "Welcome to Julian Smart's LaTeX to RTF converter.\n";
391 // ShowOptions();
392
393 #if wxUSE_HELP
394 HelpInstance = new wxHelpController();
395 HelpInstance->Initialize("tex2rtf");
396 #endif // wxUSE_HELP
397
398 /*
399 * Read macro/initialisation file
400 *
401 */
402
403 wxString path;
404 if ((path = TexPathList.FindValidPath(MacroFile)) != "")
405 ReadCustomMacros((char*) (const char*) path);
406
407 strcpy(buf, "In ");
408
409 if (winHelp && (convertMode == TEX_RTF))
410 strcat(buf, "WinHelp RTF");
411 else if (!winHelp && (convertMode == TEX_RTF))
412 strcat(buf, "linear RTF");
413 else if (convertMode == TEX_HTML) strcat(buf, "HTML");
414 else if (convertMode == TEX_XLP) strcat(buf, "XLP");
415 strcat(buf, " mode.");
416 frame->SetStatusText(buf, 1);
417
418 frame->Show(TRUE);
419 return TRUE;
420 }
421 else
422 #endif // NO_GUI
423 {
424 /*
425 * Read macro/initialisation file
426 *
427 */
428
429 wxString path;
430 if ((path = TexPathList.FindValidPath(MacroFile)) != "")
431 ReadCustomMacros((char*) (const char*) path);
432
433 Go();
434 if (runTwice)
435 {
436 Go();
437 }
438 #ifdef NO_GUI
439 return 0;
440 #else
441 return NULL;
442 #endif
443 }
444
445 #ifndef NO_GUI
446 // Return the main frame window
447 return TRUE;
448 #else
449 delete[] wxBuffer;
450 return FALSE;
451 #endif
452 }
453
454 #ifndef NO_GUI
455 int MyApp::OnExit()
456 {
457 wxNode *node = CustomMacroList.First();
458 while (node)
459 {
460 CustomMacro *macro = (CustomMacro *)node->Data();
461 delete macro;
462 delete node;
463 node = CustomMacroList.First();
464 }
465 MacroDefs.BeginFind();
466 node = MacroDefs.Next();
467 while (node)
468 {
469 TexMacroDef* def = (TexMacroDef*) node->Data();
470 delete def;
471 node = MacroDefs.Next();
472 }
473 MacroDefs.Clear();
474 #ifdef __WXMSW__
475 delete TheTex2RTFServer;
476 wxDDECleanUp();
477 #endif
478
479 #if wxUSE_HELP
480 delete HelpInstance;
481 #endif // wxUSE_HELP
482
483 if (BigBuffer)
484 {
485 delete BigBuffer;
486 BigBuffer = NULL;
487 }
488 if (currentArgData)
489 {
490 delete currentArgData;
491 currentArgData = NULL;
492 }
493 if (TexFileRoot)
494 {
495 delete TexFileRoot;
496 TexFileRoot = NULL;
497 }
498 if (TexBibName)
499 {
500 delete TexBibName;
501 TexBibName = NULL;
502 }
503 if (TexTmpBibName)
504 {
505 delete TexTmpBibName;
506 TexTmpBibName = NULL;
507 }
508 if (FileRoot)
509 {
510 delete FileRoot;
511 FileRoot = NULL;
512 }
513 if (ContentsName)
514 {
515 delete ContentsName;
516 ContentsName = NULL;
517 }
518 if (TmpContentsName)
519 {
520 delete TmpContentsName;
521 TmpContentsName = NULL;
522 }
523 if (TmpFrameContentsName)
524 {
525 delete TmpFrameContentsName;
526 TmpFrameContentsName = NULL;
527 }
528 if (WinHelpContentsFileName)
529 {
530 delete WinHelpContentsFileName;
531 WinHelpContentsFileName = NULL;
532 }
533 if (RefFileName)
534 {
535 delete RefFileName;
536 RefFileName = NULL;
537 }
538 if (TopLevel)
539 {
540 delete TopLevel;
541 TopLevel = NULL;
542 }
543 if (MacroFile)
544 {
545 delete MacroFile;
546 MacroFile = NULL;
547 }
548 if (RTFCharset)
549 {
550 delete RTFCharset;
551 RTFCharset = NULL;
552 }
553
554 delete [] PageStyle;
555 delete [] BibliographyStyleString;
556 delete [] DocumentStyleString;
557 delete [] bitmapMethod;
558 delete [] backgroundColourString;
559 delete [] ContentsNameString;
560 delete [] AbstractNameString;
561 delete [] GlossaryNameString;
562 delete [] ReferencesNameString;
563 delete [] FiguresNameString;
564 delete [] TablesNameString;
565 delete [] FigureNameString;
566 delete [] TableNameString;
567 delete [] IndexNameString;
568 delete [] ChapterNameString;
569 delete [] SectionNameString;
570 delete [] SubsectionNameString;
571 delete [] SubsubsectionNameString;
572 delete [] UpNameString;
573 if (winHelpTitle)
574 delete[] winHelpTitle;
575
576 // TODO: this simulates zero-memory leaks!
577 // Otherwise there are just too many...
578 #ifndef __WXGTK__
579 #if (defined(__WXDEBUG__) && wxUSE_MEMORY_TRACING) || wxUSE_DEBUG_CONTEXT
580 wxDebugContext::SetCheckpoint();
581 #endif
582 #endif
583
584 return 0;
585 }
586 #endif
587 void ShowOptions(void)
588 {
589 char buf[100];
590 sprintf(buf, "Tex2RTF version %.2f", versionNo);
591 OnInform(buf);
592 OnInform("Usage: tex2rtf [input] [output] [switches]\n");
593 OnInform("where valid switches are");
594 #ifndef NO_GUI
595 OnInform(" -interactive");
596 #endif
597 OnInform(" -bufsize <size in K>");
598 OnInform(" -charset <pc | pca | ansi | mac> (default ansi)");
599 OnInform(" -twice");
600 OnInform(" -sync");
601 OnInform(" -checkcurleybraces");
602 OnInform(" -checksyntax");
603 OnInform(" -macros <filename>");
604 OnInform(" -winhelp");
605 OnInform(" -rtf");
606 OnInform(" -html");
607 OnInform(" -xlp\n");
608 }
609
610 #ifndef NO_GUI
611
612 BEGIN_EVENT_TABLE(MyFrame, wxFrame)
613 EVT_CLOSE(MyFrame::OnCloseWindow)
614 EVT_MENU(TEX_QUIT, MyFrame::OnExit)
615 EVT_MENU(TEX_GO, MyFrame::OnGo)
616 EVT_MENU(TEX_SET_INPUT, MyFrame::OnSetInput)
617 EVT_MENU(TEX_SET_OUTPUT, MyFrame::OnSetOutput)
618 EVT_MENU(TEX_SAVE_FILE, MyFrame::OnSaveFile)
619 EVT_MENU(TEX_VIEW_LATEX, MyFrame::OnViewLatex)
620 EVT_MENU(TEX_VIEW_OUTPUT, MyFrame::OnViewOutput)
621 EVT_MENU(TEX_VIEW_CUSTOM_MACROS, MyFrame::OnShowMacros)
622 EVT_MENU(TEX_LOAD_CUSTOM_MACROS, MyFrame::OnLoadMacros)
623 EVT_MENU(TEX_MODE_RTF, MyFrame::OnModeRTF)
624 EVT_MENU(TEX_MODE_WINHELP, MyFrame::OnModeWinHelp)
625 EVT_MENU(TEX_MODE_HTML, MyFrame::OnModeHTML)
626 EVT_MENU(TEX_MODE_XLP, MyFrame::OnModeXLP)
627 EVT_MENU(TEX_OPTIONS_CURELY_BRACE, MyFrame::OnOptionsCurleyBrace)
628 EVT_MENU(TEX_OPTIONS_SYNTAX_CHECKING, MyFrame::OnOptionsSyntaxChecking)
629 EVT_MENU(TEX_HELP, MyFrame::OnHelp)
630 EVT_MENU(TEX_ABOUT, MyFrame::OnAbout)
631 END_EVENT_TABLE()
632
633 // My frame constructor
634 MyFrame::MyFrame(wxFrame *frame, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size):
635 wxFrame(frame, id, title, pos, size)
636 {}
637
638 void MyFrame::OnCloseWindow(wxCloseEvent& event)
639 {
640 if (!stopRunning && !OkToClose)
641 {
642 stopRunning = TRUE;
643 runTwice = FALSE;
644 return;
645 }
646 else if (OkToClose)
647 {
648 this->Destroy();
649 }
650 }
651
652 void MyFrame::OnExit(wxCommandEvent& event)
653 {
654 Close();
655 // this->Destroy();
656 }
657
658 void MyFrame::OnGo(wxCommandEvent& event)
659 {
660 passNumber = 1;
661 errorCount = 0;
662 menuBar->EnableTop(0, FALSE);
663 menuBar->EnableTop(1, FALSE);
664 menuBar->EnableTop(2, FALSE);
665 menuBar->EnableTop(3, FALSE);
666 textWindow->Clear();
667 Tex2RTFYield(TRUE);
668 Go();
669
670 if (stopRunning)
671 {
672 SetStatusText("Build aborted!");
673 wxString errBuf;
674 errBuf.Printf("\nErrors encountered during this pass: %lu\n", errorCount);
675 OnInform((char *)errBuf.c_str());
676 }
677
678
679 if (runTwice && !stopRunning)
680 {
681 Tex2RTFYield(TRUE);
682 Go();
683 }
684 menuBar->EnableTop(0, TRUE);
685 menuBar->EnableTop(1, TRUE);
686 menuBar->EnableTop(2, TRUE);
687 menuBar->EnableTop(3, TRUE);
688 }
689
690 void MyFrame::OnSetInput(wxCommandEvent& event)
691 {
692 ChooseInputFile(TRUE);
693 }
694
695 void MyFrame::OnSetOutput(wxCommandEvent& event)
696 {
697 ChooseOutputFile(TRUE);
698 }
699
700 void MyFrame::OnSaveFile(wxCommandEvent& event)
701 {
702 wxString s = wxFileSelector("Save text to file", "", "", "txt", "*.txt");
703 if (s != "")
704 {
705 textWindow->SaveFile(s);
706 char buf[350];
707 sprintf(buf, "Saved text to %s", (const char*) s);
708 frame->SetStatusText(buf, 0);
709 }
710 }
711
712 void MyFrame::OnViewOutput(wxCommandEvent& event)
713 {
714 ChooseOutputFile();
715 if (OutputFile && wxFileExists(OutputFile))
716 {
717 textWindow->LoadFile(OutputFile);
718 char buf[300];
719 wxString str(wxFileNameFromPath(OutputFile));
720 sprintf(buf, "Tex2RTF [%s]", (const char*) str);
721 frame->SetTitle(buf);
722 }
723 }
724
725 void MyFrame::OnViewLatex(wxCommandEvent& event)
726 {
727 ChooseInputFile();
728 if (InputFile && wxFileExists(InputFile))
729 {
730 textWindow->LoadFile(InputFile);
731 char buf[300];
732 wxString str(wxFileNameFromPath(OutputFile));
733 sprintf(buf, "Tex2RTF [%s]", (const char*) str);
734 frame->SetTitle(buf);
735 }
736 }
737
738 void MyFrame::OnLoadMacros(wxCommandEvent& event)
739 {
740 textWindow->Clear();
741 wxString s = wxFileSelector("Choose custom macro file", wxPathOnly(MacroFile), wxFileNameFromPath(MacroFile), "ini", "*.ini");
742 if (s != "" && wxFileExists(s))
743 {
744 MacroFile = copystring(s);
745 ReadCustomMacros((char*) (const char*) s);
746 ShowCustomMacros();
747 }
748 }
749
750 void MyFrame::OnShowMacros(wxCommandEvent& event)
751 {
752 textWindow->Clear();
753 Tex2RTFYield(TRUE);
754 ShowCustomMacros();
755 }
756
757 void MyFrame::OnModeRTF(wxCommandEvent& event)
758 {
759 convertMode = TEX_RTF;
760 winHelp = FALSE;
761 InputFile = NULL;
762 OutputFile = NULL;
763 SetStatusText("In linear RTF mode.", 1);
764 }
765
766 void MyFrame::OnModeWinHelp(wxCommandEvent& event)
767 {
768 convertMode = TEX_RTF;
769 winHelp = TRUE;
770 InputFile = NULL;
771 OutputFile = NULL;
772 SetStatusText("In WinHelp RTF mode.", 1);
773 }
774
775 void MyFrame::OnModeHTML(wxCommandEvent& event)
776 {
777 convertMode = TEX_HTML;
778 winHelp = FALSE;
779 InputFile = NULL;
780 OutputFile = NULL;
781 SetStatusText("In HTML mode.", 1);
782 }
783
784 void MyFrame::OnModeXLP(wxCommandEvent& event)
785 {
786 convertMode = TEX_XLP;
787 InputFile = NULL;
788 OutputFile = NULL;
789 SetStatusText("In XLP mode.", 1);
790 }
791
792 void MyFrame::OnOptionsCurleyBrace(wxCommandEvent& event)
793 {
794 checkCurleyBraces = !checkCurleyBraces;
795 if (checkCurleyBraces)
796 {
797 SetStatusText("Checking curley braces: YES", 1);
798 }
799 else
800 {
801 SetStatusText("Checking curley braces: NO", 1);
802 }
803 }
804
805
806 void MyFrame::OnOptionsSyntaxChecking(wxCommandEvent& event)
807 {
808 checkSyntax = !checkSyntax;
809 if (checkSyntax)
810 {
811 SetStatusText("Checking syntax: YES", 1);
812 }
813 else
814 {
815 SetStatusText("Checking syntax: NO", 1);
816 }
817 }
818
819
820 void MyFrame::OnHelp(wxCommandEvent& event)
821 {
822 #if wxUSE_HELP
823 HelpInstance->LoadFile();
824 HelpInstance->DisplayContents();
825 #endif // wxUSE_HELP
826 }
827
828 void MyFrame::OnAbout(wxCommandEvent& event)
829 {
830 char buf[300];
831 #ifdef __WIN32__
832 char *platform = " (32-bit)";
833 #else
834 #ifdef __WXMSW__
835 char *platform = " (16-bit)";
836 #else
837 char *platform = "";
838 #endif
839 #endif
840 sprintf(buf, "Tex2RTF Version %.2f%s\nLaTeX to RTF, WinHelp, HTML and wxHelp Conversion\n\n(c) Julian Smart 1999", versionNo, platform);
841 wxMessageBox(buf, "About Tex2RTF");
842 }
843
844 void ChooseInputFile(bool force)
845 {
846 if (force || !InputFile)
847 {
848 wxString s = wxFileSelector("Choose LaTeX input file", wxPathOnly(InputFile), wxFileNameFromPath(InputFile), "tex", "*.tex");
849 if (s != "")
850 {
851 // Different file, so clear index entries.
852 ClearKeyWordTable();
853 ResetContentsLevels(0);
854 passNumber = 1;
855 errorCount = 0;
856
857 InputFile = copystring(s);
858 wxString str = wxFileNameFromPath(InputFile);
859 wxString buf;
860 buf.Printf("Tex2RTF [%s]", str.c_str());
861 frame->SetTitle((char *)buf.c_str());
862 OutputFile = NULL;
863 }
864 }
865 }
866
867 void ChooseOutputFile(bool force)
868 {
869 char extensionBuf[10];
870 char wildBuf[10];
871 strcpy(wildBuf, "*.");
872 wxString path;
873 if (OutputFile)
874 path = wxPathOnly(OutputFile);
875 else if (InputFile)
876 path = wxPathOnly(InputFile);
877
878 switch (convertMode)
879 {
880 case TEX_RTF:
881 {
882 strcpy(extensionBuf, "rtf");
883 strcat(wildBuf, "rtf");
884 break;
885 }
886 case TEX_XLP:
887 {
888 strcpy(extensionBuf, "xlp");
889 strcat(wildBuf, "xlp");
890 break;
891 }
892 case TEX_HTML:
893 {
894 #if defined(__WXMSW__) && defined(__WIN16__)
895 strcpy(extensionBuf, "htm");
896 strcat(wildBuf, "htm");
897 #else
898 strcpy(extensionBuf, "html");
899 strcat(wildBuf, "html");
900 #endif
901 break;
902 }
903 }
904 if (force || !OutputFile)
905 {
906 wxString s = wxFileSelector("Choose output file", path, wxFileNameFromPath(OutputFile),
907 extensionBuf, wildBuf);
908 if (s != "")
909 OutputFile = copystring(s);
910 }
911 }
912 #endif
913
914 bool Go(void)
915 {
916 #ifndef NO_GUI
917 ChooseInputFile();
918 ChooseOutputFile();
919 #endif
920
921 if (!InputFile || !OutputFile || stopRunning)
922 return FALSE;
923
924 #ifndef NO_GUI
925 if (isInteractive)
926 {
927 char buf[300];
928 wxString str = wxFileNameFromPath(InputFile);
929
930 sprintf(buf, "Tex2RTF [%s]", (const char*) str);
931 frame->SetTitle(buf);
932 }
933
934 wxStartTimer();
935 #endif
936
937 // Find extension-less filename
938 strcpy(FileRoot, OutputFile);
939 StripExtension(FileRoot);
940
941 if (truncateFilenames && convertMode == TEX_HTML)
942 {
943 // Truncate to five characters. This ensures that
944 // we can generate DOS filenames such as thing999. But 1000 files
945 // may not be enough, of course...
946 char* sName = wxFileNameFromPath( FileRoot); // this Julian's method is non-destructive reference
947
948 if(sName)
949 if(strlen( sName) > 5)
950 sName[5] = '\0'; // that should do!
951 }
952
953 sprintf(ContentsName, "%s.con", FileRoot);
954 sprintf(TmpContentsName, "%s.cn1", FileRoot);
955 sprintf(TmpFrameContentsName, "%s.frc", FileRoot);
956 sprintf(WinHelpContentsFileName, "%s.cnt", FileRoot);
957 sprintf(RefFileName, "%s.ref", FileRoot);
958
959 TexPathList.EnsureFileAccessible(InputFile);
960 if (!bulletFile)
961 {
962 wxString s = TexPathList.FindValidPath("bullet.bmp");
963 if (s != "")
964 {
965 wxString str = wxFileNameFromPath(s);
966 bulletFile = copystring(str);
967 }
968 }
969
970 if (wxFileExists(RefFileName))
971 ReadTexReferences(RefFileName);
972
973 bool success = FALSE;
974
975 if (InputFile && OutputFile)
976 {
977 if (!FileExists(InputFile))
978 {
979 OnError("Cannot open input file!");
980 TexCleanUp();
981 return FALSE;
982 }
983 #ifndef NO_GUI
984 if (isInteractive)
985 {
986 wxString buf;
987 buf.Printf("Working, pass %d...Click CLOSE to abort", passNumber);
988 frame->SetStatusText((char *)buf.c_str());
989 }
990 #endif
991 OkToClose = FALSE;
992 OnInform("Reading LaTeX file...");
993 TexLoadFile(InputFile);
994
995 if (stopRunning)
996 {
997 OkToClose = TRUE;
998 return FALSE;
999 }
1000
1001 switch (convertMode)
1002 {
1003 case TEX_RTF:
1004 {
1005 success = RTFGo();
1006 break;
1007 }
1008 case TEX_XLP:
1009 {
1010 success = XLPGo();
1011 break;
1012 }
1013 case TEX_HTML:
1014 {
1015 success = HTMLGo();
1016 break;
1017 }
1018 }
1019 }
1020 if (stopRunning)
1021 {
1022 OnInform("*** Aborted by user.");
1023 success = FALSE;
1024 stopRunning = FALSE;
1025 OkToClose = TRUE;
1026 }
1027
1028 if (success)
1029 {
1030 WriteTexReferences(RefFileName);
1031 TexCleanUp();
1032 startedSections = FALSE;
1033
1034 wxString buf;
1035 #ifndef NO_GUI
1036 long tim = wxGetElapsedTime();
1037 buf.Printf("Finished PASS #%d in %ld seconds.\n", passNumber, (long)(tim/1000.0));
1038 OnInform((char *)buf.c_str());
1039
1040 if (errorCount)
1041 {
1042 buf.Printf("Errors encountered during this pass: %lu\n", errorCount);
1043 OnInform((char *)buf.c_str());
1044 }
1045
1046 if (isInteractive)
1047 {
1048 buf.Printf("Done, %d %s.", passNumber, (passNumber > 1) ? "passes" : "pass");
1049 frame->SetStatusText((char *)buf.c_str());
1050 }
1051 #else
1052 buf.Printf("Done, %d %s.", passNumber, (passNumber > 1) ? "passes" : "pass");
1053 OnInform((char *)buf.c_str());
1054 if (errorCount)
1055 {
1056 buf.Printf("Errors encountered during this pass: %lu\n", errorCount);
1057 OnInform((char *)buf.c_str());
1058 }
1059 #endif
1060 passNumber ++;
1061 errorCount = 0;
1062 OkToClose = TRUE;
1063 return TRUE;
1064 }
1065
1066 TexCleanUp();
1067 startedSections = FALSE;
1068
1069 #ifndef NO_GUI
1070 frame->SetStatusText("Aborted by user.");
1071 #endif // GUI
1072
1073 OnInform("Sorry, unsuccessful.");
1074 OkToClose = TRUE;
1075 return FALSE;
1076 }
1077
1078 void OnError(const char *msg)
1079 {
1080 errorCount++;
1081
1082 #ifdef NO_GUI
1083 wxSTD cerr << "Error: " << msg << "\n";
1084 wxSTD cerr.flush();
1085 #else
1086 if (isInteractive && frame)
1087 (*frame->textWindow) << "Error: " << msg << "\n";
1088 else
1089 #ifdef __UNIX__
1090 {
1091 wxSTD cerr << "Error: " << msg << "\n";
1092 wxSTD cerr.flush();
1093 }
1094 #endif
1095
1096 #ifdef __WXMSW__
1097 wxError(msg);
1098 #endif
1099 Tex2RTFYield(TRUE);
1100 #endif // NO_GUI
1101 }
1102
1103 void OnInform(const char *msg)
1104 {
1105 #ifdef NO_GUI
1106 wxSTD cout << msg << "\n";
1107 wxSTD cout.flush();
1108 #else
1109 if (isInteractive && frame)
1110 (*frame->textWindow) << msg << "\n";
1111 /* This whole block of code is just wrong I think. It would behave
1112 completely wrong under anything other than MSW due to the ELSE
1113 with no statement, and the cout calls would fail under MSW, as
1114 the code in this block is compiled if !NO_GUI This code has been
1115 here since v1.1 of this file too. - gt
1116 else
1117 #ifdef __WXMSW__
1118 {
1119 wxSTD cout << msg << "\n";
1120 wxSTD cout.flush();
1121 }
1122 #endif
1123 #ifdef __WXMSW__
1124 {}
1125 #endif
1126 */
1127 if (isInteractive)
1128 {
1129 Tex2RTFYield(TRUE);
1130 }
1131 #endif // NO_GUI
1132 }
1133
1134 void OnMacro(int macroId, int no_args, bool start)
1135 {
1136 switch (convertMode)
1137 {
1138 case TEX_RTF:
1139 {
1140 RTFOnMacro(macroId, no_args, start);
1141 break;
1142 }
1143 case TEX_XLP:
1144 {
1145 XLPOnMacro(macroId, no_args, start);
1146 break;
1147 }
1148 case TEX_HTML:
1149 {
1150 HTMLOnMacro(macroId, no_args, start);
1151 break;
1152 }
1153 }
1154 }
1155
1156 bool OnArgument(int macroId, int arg_no, bool start)
1157 {
1158 switch (convertMode)
1159 {
1160 case TEX_RTF:
1161 {
1162 return RTFOnArgument(macroId, arg_no, start);
1163 break;
1164 }
1165 case TEX_XLP:
1166 {
1167 return XLPOnArgument(macroId, arg_no, start);
1168 break;
1169 }
1170 case TEX_HTML:
1171 {
1172 return HTMLOnArgument(macroId, arg_no, start);
1173 break;
1174 }
1175 }
1176 return TRUE;
1177 }
1178
1179 /*
1180 * DDE Stuff
1181 */
1182 #if defined(__WXMSW__) && !defined(NO_GUI)
1183
1184 /*
1185 * Server
1186 */
1187
1188 wxConnectionBase *Tex2RTFServer::OnAcceptConnection(const wxString& topic)
1189 {
1190 if (topic == "TEX2RTF")
1191 {
1192 if (!ipc_buffer)
1193 ipc_buffer = new char[1000];
1194
1195 return new Tex2RTFConnection(ipc_buffer, 4000);
1196 }
1197 else
1198 return NULL;
1199 }
1200
1201 /*
1202 * Connection
1203 */
1204
1205 Tex2RTFConnection::Tex2RTFConnection(char *buf, int size):wxDDEConnection(buf, size)
1206 {
1207 }
1208
1209 Tex2RTFConnection::~Tex2RTFConnection(void)
1210 {
1211 }
1212
1213 bool SplitCommand(char *data, char *firstArg, char *secondArg)
1214 {
1215 firstArg[0] = 0;
1216 secondArg[0] = 0;
1217 int i = 0;
1218 int len = strlen(data);
1219 bool stop = FALSE;
1220 // Find first argument (command name)
1221 while (!stop)
1222 {
1223 if (data[i] == ' ' || data[i] == 0)
1224 stop = TRUE;
1225 else
1226 {
1227 firstArg[i] = data[i];
1228 i ++;
1229 }
1230 }
1231 firstArg[i] = 0;
1232 if (data[i] == ' ')
1233 {
1234 // Find second argument
1235 i ++;
1236 int j = 0;
1237 while (data[i] != 0)
1238 {
1239 secondArg[j] = data[i];
1240 i ++;
1241 j ++;
1242 }
1243 secondArg[j] = 0;
1244 }
1245 return TRUE;
1246 }
1247
1248 bool Tex2RTFConnection::OnExecute(const wxString& topic, char *data, int size, int format)
1249 {
1250 strcpy(Tex2RTFLastStatus, "OK");
1251
1252 char firstArg[50];
1253 char secondArg[300];
1254 if (SplitCommand(data, firstArg, secondArg))
1255 {
1256 bool hasArg = (strlen(secondArg) > 0);
1257 if (strcmp(firstArg, "INPUT") == 0 && hasArg)
1258 {
1259 if (InputFile) delete[] InputFile;
1260 InputFile = copystring(secondArg);
1261 if (frame)
1262 {
1263 char buf[100];
1264 wxString str = wxFileNameFromPath(InputFile);
1265 sprintf(buf, "Tex2RTF [%s]", (const char*) str);
1266 frame->SetTitle(buf);
1267 }
1268 }
1269 else if (strcmp(firstArg, "OUTPUT") == 0 && hasArg)
1270 {
1271 if (OutputFile) delete[] OutputFile;
1272 OutputFile = copystring(secondArg);
1273 }
1274 else if (strcmp(firstArg, "GO") == 0)
1275 {
1276 strcpy(Tex2RTFLastStatus, "WORKING");
1277 if (!Go())
1278 strcpy(Tex2RTFLastStatus, "CONVERSION ERROR");
1279 else
1280 strcpy(Tex2RTFLastStatus, "OK");
1281 }
1282 else if (strcmp(firstArg, "EXIT") == 0)
1283 {
1284 if (frame) frame->Close();
1285 }
1286 else if (strcmp(firstArg, "MINIMIZE") == 0 || strcmp(firstArg, "ICONIZE") == 0)
1287 {
1288 if (frame)
1289 frame->Iconize(TRUE);
1290 }
1291 else if (strcmp(firstArg, "SHOW") == 0 || strcmp(firstArg, "RESTORE") == 0)
1292 {
1293 if (frame)
1294 {
1295 frame->Iconize(FALSE);
1296 frame->Show(TRUE);
1297 }
1298 }
1299 else
1300 {
1301 // Try for a setting
1302 strcpy(Tex2RTFLastStatus, RegisterSetting(firstArg, secondArg, FALSE));
1303 #ifndef NO_GUI
1304 if (frame && strcmp(firstArg, "conversionMode") == 0)
1305 {
1306 char buf[100];
1307 strcpy(buf, "In ");
1308
1309 if (winHelp && (convertMode == TEX_RTF))
1310 strcat(buf, "WinHelp RTF");
1311 else if (!winHelp && (convertMode == TEX_RTF))
1312 strcat(buf, "linear RTF");
1313 else if (convertMode == TEX_HTML) strcat(buf, "HTML");
1314 else if (convertMode == TEX_XLP) strcat(buf, "XLP");
1315 strcat(buf, " mode.");
1316 frame->SetStatusText(buf, 1);
1317 }
1318 #endif
1319 }
1320 }
1321 return TRUE;
1322 }
1323
1324 char *Tex2RTFConnection::OnRequest(const wxString& topic, const wxString& item, int *size, int format)
1325 {
1326 return Tex2RTFLastStatus;
1327 }
1328
1329 #endif
1330
1331 #ifndef NO_GUI
1332 #ifndef __WXGTK__
1333 //void wxObject::Dump(wxSTD ostream& str)
1334 //{
1335 // if (GetClassInfo() && GetClassInfo()->GetClassName())
1336 // str << GetClassInfo()->GetClassName();
1337 // else
1338 // str << "unknown object class";
1339 //}
1340 #endif
1341 #endif