]> git.saurik.com Git - wxWidgets.git/blob - utils/tex2rtf/src/tex2rtf.cpp
b7a9d9912727de8a697cf225c11d2e4c10c5e67f
[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(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 *RefName = 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 RefName = 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 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 (RefName)
534 {
535 delete RefName;
536 RefName = 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 OnInform(" -interactive");
595 OnInform(" -bufsize <size in K>");
596 OnInform(" -charset <pc | pca | ansi | mac> (default ansi)");
597 OnInform(" -twice");
598 OnInform(" -sync");
599 OnInform(" -macros <filename>");
600 OnInform(" -winhelp");
601 OnInform(" -rtf");
602 OnInform(" -html");
603 OnInform(" -xlp\n");
604 }
605
606 #ifndef NO_GUI
607
608 BEGIN_EVENT_TABLE(MyFrame, wxFrame)
609 EVT_CLOSE(MyFrame::OnCloseWindow)
610 EVT_MENU(TEX_QUIT, MyFrame::OnExit)
611 EVT_MENU(TEX_GO, MyFrame::OnGo)
612 EVT_MENU(TEX_SET_INPUT, MyFrame::OnSetInput)
613 EVT_MENU(TEX_SET_OUTPUT, MyFrame::OnSetOutput)
614 EVT_MENU(TEX_SAVE_FILE, MyFrame::OnSaveFile)
615 EVT_MENU(TEX_VIEW_LATEX, MyFrame::OnViewLatex)
616 EVT_MENU(TEX_VIEW_OUTPUT, MyFrame::OnViewOutput)
617 EVT_MENU(TEX_VIEW_CUSTOM_MACROS, MyFrame::OnShowMacros)
618 EVT_MENU(TEX_LOAD_CUSTOM_MACROS, MyFrame::OnLoadMacros)
619 EVT_MENU(TEX_MODE_RTF, MyFrame::OnModeRTF)
620 EVT_MENU(TEX_MODE_WINHELP, MyFrame::OnModeWinHelp)
621 EVT_MENU(TEX_MODE_HTML, MyFrame::OnModeHTML)
622 EVT_MENU(TEX_MODE_XLP, MyFrame::OnModeXLP)
623 EVT_MENU(TEX_OPTIONS_CURELY_BRACE, MyFrame::OnOptionsCurleyBrace)
624 EVT_MENU(TEX_OPTIONS_SYNTAX_CHECKING, MyFrame::OnOptionsSyntaxChecking)
625 EVT_MENU(TEX_HELP, MyFrame::OnHelp)
626 EVT_MENU(TEX_ABOUT, MyFrame::OnAbout)
627 END_EVENT_TABLE()
628
629 // My frame constructor
630 MyFrame::MyFrame(wxFrame *frame, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size):
631 wxFrame(frame, id, title, pos, size)
632 {}
633
634 void MyFrame::OnCloseWindow(wxCloseEvent& event)
635 {
636 if (!stopRunning && !OkToClose)
637 {
638 stopRunning = TRUE;
639 runTwice = FALSE;
640 return;
641 }
642 else if (OkToClose)
643 {
644 this->Destroy();
645 }
646 }
647
648 void MyFrame::OnExit(wxCommandEvent& event)
649 {
650 Close();
651 // this->Destroy();
652 }
653
654 void MyFrame::OnGo(wxCommandEvent& event)
655 {
656 passNumber = 1;
657 errorCount = 0;
658 menuBar->EnableTop(0, FALSE);
659 menuBar->EnableTop(1, FALSE);
660 menuBar->EnableTop(2, FALSE);
661 menuBar->EnableTop(3, FALSE);
662 textWindow->Clear();
663 Tex2RTFYield(TRUE);
664 Go();
665
666 if (runTwice)
667 {
668 Tex2RTFYield(TRUE);
669 Go();
670 }
671 menuBar->EnableTop(0, TRUE);
672 menuBar->EnableTop(1, TRUE);
673 menuBar->EnableTop(2, TRUE);
674 menuBar->EnableTop(3, TRUE);
675 }
676
677 void MyFrame::OnSetInput(wxCommandEvent& event)
678 {
679 ChooseInputFile(TRUE);
680 }
681
682 void MyFrame::OnSetOutput(wxCommandEvent& event)
683 {
684 ChooseOutputFile(TRUE);
685 }
686
687 void MyFrame::OnSaveFile(wxCommandEvent& event)
688 {
689 wxString s = wxFileSelector("Save text to file", "", "", "txt", "*.txt");
690 if (s != "")
691 {
692 textWindow->SaveFile(s);
693 char buf[350];
694 sprintf(buf, "Saved text to %s", (const char*) s);
695 frame->SetStatusText(buf, 0);
696 }
697 }
698
699 void MyFrame::OnViewOutput(wxCommandEvent& event)
700 {
701 ChooseOutputFile();
702 if (OutputFile && wxFileExists(OutputFile))
703 {
704 textWindow->LoadFile(OutputFile);
705 char buf[300];
706 wxString str(wxFileNameFromPath(OutputFile));
707 sprintf(buf, "Tex2RTF [%s]", (const char*) str);
708 frame->SetTitle(buf);
709 }
710 }
711
712 void MyFrame::OnViewLatex(wxCommandEvent& event)
713 {
714 ChooseInputFile();
715 if (InputFile && wxFileExists(InputFile))
716 {
717 textWindow->LoadFile(InputFile);
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::OnLoadMacros(wxCommandEvent& event)
726 {
727 textWindow->Clear();
728 wxString s = wxFileSelector("Choose custom macro file", wxPathOnly(MacroFile), wxFileNameFromPath(MacroFile), "ini", "*.ini");
729 if (s != "" && wxFileExists(s))
730 {
731 MacroFile = copystring(s);
732 ReadCustomMacros((char*) (const char*) s);
733 ShowCustomMacros();
734 }
735 }
736
737 void MyFrame::OnShowMacros(wxCommandEvent& event)
738 {
739 textWindow->Clear();
740 Tex2RTFYield(TRUE);
741 ShowCustomMacros();
742 }
743
744 void MyFrame::OnModeRTF(wxCommandEvent& event)
745 {
746 convertMode = TEX_RTF;
747 winHelp = FALSE;
748 InputFile = NULL;
749 OutputFile = NULL;
750 SetStatusText("In linear RTF mode.", 1);
751 }
752
753 void MyFrame::OnModeWinHelp(wxCommandEvent& event)
754 {
755 convertMode = TEX_RTF;
756 winHelp = TRUE;
757 InputFile = NULL;
758 OutputFile = NULL;
759 SetStatusText("In WinHelp RTF mode.", 1);
760 }
761
762 void MyFrame::OnModeHTML(wxCommandEvent& event)
763 {
764 convertMode = TEX_HTML;
765 winHelp = FALSE;
766 InputFile = NULL;
767 OutputFile = NULL;
768 SetStatusText("In HTML mode.", 1);
769 }
770
771 void MyFrame::OnModeXLP(wxCommandEvent& event)
772 {
773 convertMode = TEX_XLP;
774 InputFile = NULL;
775 OutputFile = NULL;
776 SetStatusText("In XLP mode.", 1);
777 }
778
779 void MyFrame::OnOptionsCurleyBrace(wxCommandEvent& event)
780 {
781 checkCurleyBraces = !checkCurleyBraces;
782 if (checkCurleyBraces)
783 {
784 SetStatusText("Checking curley braces: YES", 1);
785 }
786 else
787 {
788 SetStatusText("Checking curley braces: NO", 1);
789 }
790 }
791
792
793 void MyFrame::OnOptionsSyntaxChecking(wxCommandEvent& event)
794 {
795 checkSyntax = !checkSyntax;
796 if (checkSyntax)
797 {
798 SetStatusText("Checking syntax: YES", 1);
799 }
800 else
801 {
802 SetStatusText("Checking syntax: NO", 1);
803 }
804 }
805
806
807 void MyFrame::OnHelp(wxCommandEvent& event)
808 {
809 #if wxUSE_HELP
810 HelpInstance->LoadFile();
811 HelpInstance->DisplayContents();
812 #endif // wxUSE_HELP
813 }
814
815 void MyFrame::OnAbout(wxCommandEvent& event)
816 {
817 char buf[300];
818 #ifdef __WIN32__
819 char *platform = " (32-bit)";
820 #else
821 #ifdef __WXMSW__
822 char *platform = " (16-bit)";
823 #else
824 char *platform = "";
825 #endif
826 #endif
827 sprintf(buf, "Tex2RTF Version %.2f%s\nLaTeX to RTF, WinHelp, HTML and wxHelp Conversion\n\n(c) Julian Smart 1999", versionNo, platform);
828 wxMessageBox(buf, "About Tex2RTF");
829 }
830
831 void ChooseInputFile(bool force)
832 {
833 if (force || !InputFile)
834 {
835 wxString s = wxFileSelector("Choose LaTeX input file", wxPathOnly(InputFile), wxFileNameFromPath(InputFile), "tex", "*.tex");
836 if (s != "")
837 {
838 // Different file, so clear index entries.
839 ClearKeyWordTable();
840 ResetContentsLevels(0);
841 passNumber = 1;
842 errorCount = 0;
843
844 InputFile = copystring(s);
845 wxString str = wxFileNameFromPath(InputFile);
846 wxString buf;
847 buf.Printf("Tex2RTF [%s]", str.c_str());
848 frame->SetTitle((char *)buf.c_str());
849 OutputFile = NULL;
850 }
851 }
852 }
853
854 void ChooseOutputFile(bool force)
855 {
856 char extensionBuf[10];
857 char wildBuf[10];
858 strcpy(wildBuf, "*.");
859 wxString path;
860 if (OutputFile)
861 path = wxPathOnly(OutputFile);
862 else if (InputFile)
863 path = wxPathOnly(InputFile);
864
865 switch (convertMode)
866 {
867 case TEX_RTF:
868 {
869 strcpy(extensionBuf, "rtf");
870 strcat(wildBuf, "rtf");
871 break;
872 }
873 case TEX_XLP:
874 {
875 strcpy(extensionBuf, "xlp");
876 strcat(wildBuf, "xlp");
877 break;
878 }
879 case TEX_HTML:
880 {
881 #if defined(__WXMSW__) && defined(__WIN16__)
882 strcpy(extensionBuf, "htm");
883 strcat(wildBuf, "htm");
884 #else
885 strcpy(extensionBuf, "html");
886 strcat(wildBuf, "html");
887 #endif
888 break;
889 }
890 }
891 if (force || !OutputFile)
892 {
893 wxString s = wxFileSelector("Choose output file", path, wxFileNameFromPath(OutputFile),
894 extensionBuf, wildBuf);
895 if (s != "")
896 OutputFile = copystring(s);
897 }
898 }
899 #endif
900
901 bool Go(void)
902 {
903 #ifndef NO_GUI
904 ChooseInputFile();
905 ChooseOutputFile();
906 #endif
907
908 if (!InputFile || !OutputFile)
909 return FALSE;
910
911 #ifndef NO_GUI
912 if (isInteractive)
913 {
914 char buf[300];
915 wxString str = wxFileNameFromPath(InputFile);
916
917 sprintf(buf, "Tex2RTF [%s]", (const char*) str);
918 frame->SetTitle(buf);
919 }
920
921 wxStartTimer();
922 #endif
923
924 // Find extension-less filename
925 strcpy(FileRoot, OutputFile);
926 StripExtension(FileRoot);
927
928 if (truncateFilenames && convertMode == TEX_HTML)
929 {
930 // Truncate to five characters. This ensures that
931 // we can generate DOS filenames such as thing999. But 1000 files
932 // may not be enough, of course...
933 char* sName = wxFileNameFromPath( FileRoot); // this Julian's method is non-destructive reference
934
935 if(sName)
936 if(strlen( sName) > 5)
937 sName[5] = '\0'; // that should do!
938 }
939
940 sprintf(ContentsName, "%s.con", FileRoot);
941 sprintf(TmpContentsName, "%s.cn1", FileRoot);
942 sprintf(TmpFrameContentsName, "%s.frc", FileRoot);
943 sprintf(WinHelpContentsFileName, "%s.cnt", FileRoot);
944 sprintf(RefName, "%s.ref", FileRoot);
945
946 TexPathList.EnsureFileAccessible(InputFile);
947 if (!bulletFile)
948 {
949 wxString s = TexPathList.FindValidPath("bullet.bmp");
950 if (s != "")
951 {
952 wxString str = wxFileNameFromPath(s);
953 bulletFile = copystring(str);
954 }
955 }
956
957 if (wxFileExists(RefName))
958 ReadTexReferences(RefName);
959
960 bool success = FALSE;
961
962 if (InputFile && OutputFile)
963 {
964 if (!FileExists(InputFile))
965 {
966 OnError("Cannot open input file!");
967 TexCleanUp();
968 return FALSE;
969 }
970 #ifndef NO_GUI
971 if (isInteractive)
972 {
973 wxString buf;
974 buf.Printf("Working, pass %d...Click CLOSE to abort", passNumber);
975 frame->SetStatusText((char *)buf.c_str());
976 }
977 #endif
978 OkToClose = FALSE;
979 OnInform("Reading LaTeX file...");
980 TexLoadFile(InputFile);
981
982 switch (convertMode)
983 {
984 case TEX_RTF:
985 {
986 success = RTFGo();
987 break;
988 }
989 case TEX_XLP:
990 {
991 success = XLPGo();
992 break;
993 }
994 case TEX_HTML:
995 {
996 success = HTMLGo();
997 break;
998 }
999 }
1000 }
1001 if (stopRunning)
1002 {
1003 OnInform("*** Aborted by user.");
1004 success = FALSE;
1005 stopRunning = FALSE;
1006 }
1007
1008 if (success)
1009 {
1010 WriteTexReferences(RefName);
1011 TexCleanUp();
1012 startedSections = FALSE;
1013
1014 wxString buf;
1015 #ifndef NO_GUI
1016 long tim = wxGetElapsedTime();
1017 buf.Printf("Finished PASS #%d in %ld seconds.\n", passNumber, (long)(tim/1000.0));
1018 OnInform((char *)buf.c_str());
1019
1020 if (errorCount)
1021 {
1022 buf.Printf("Errors encountered during this pass: %lu\n", errorCount);
1023 OnInform((char *)buf.c_str());
1024 }
1025
1026 if (isInteractive)
1027 {
1028 buf.Printf("Done, %d %s.", passNumber, (passNumber > 1) ? "passes" : "pass");
1029 frame->SetStatusText((char *)buf.c_str());
1030 }
1031 #else
1032 buf.Printf("Done, %d %s.", passNumber, (passNumber > 1) ? "passes" : "pass");
1033 OnInform((char *)buf.c_str());
1034 if (errorCount)
1035 {
1036 buf.Printf("Errors encountered during this pass: %lu\n", errorCount);
1037 OnInform((char *)buf.c_str());
1038 }
1039 #endif
1040 passNumber ++;
1041 errorCount = 0;
1042 OkToClose = TRUE;
1043 return TRUE;
1044 }
1045
1046 TexCleanUp();
1047 startedSections = FALSE;
1048
1049 frame->SetStatusText("Aborted by user.");
1050
1051 OnInform("Sorry, unsuccessful.");
1052 OkToClose = TRUE;
1053 return FALSE;
1054 }
1055
1056 void OnError(char *msg)
1057 {
1058 errorCount++;
1059
1060 #ifdef NO_GUI
1061 cerr << "Error: " << msg << "\n";
1062 cerr.flush();
1063 #else
1064 if (isInteractive && frame)
1065 (*frame->textWindow) << "Error: " << msg << "\n";
1066 else
1067 #ifdef __UNIX__
1068 {
1069 cerr << "Error: " << msg << "\n";
1070 cerr.flush();
1071 }
1072 #endif
1073
1074 #ifdef __WXMSW__
1075 wxError(msg);
1076 #endif
1077 Tex2RTFYield(TRUE);
1078 #endif // NO_GUI
1079 }
1080
1081 void OnInform(char *msg)
1082 {
1083 #ifdef NO_GUI
1084 cout << msg << "\n";
1085 cout.flush();
1086 #else
1087 if (isInteractive && frame)
1088 (*frame->textWindow) << msg << "\n";
1089 /* This whole block of code is just wrong I think. It would behave
1090 completely wrong under anything other than MSW due to the ELSE
1091 with no statement, and the cout calls would fail under MSW, as
1092 the code in this block is compiled if !NO_GUI This code has been
1093 here since v1.1 of this file too. - gt
1094 else
1095 #ifdef __WXMSW__
1096 {
1097 cout << msg << "\n";
1098 cout.flush();
1099 }
1100 #endif
1101 #ifdef __WXMSW__
1102 {}
1103 #endif
1104 */
1105 if (isInteractive)
1106 {
1107 Tex2RTFYield(TRUE);
1108 }
1109 #endif // NO_GUI
1110 }
1111
1112 void OnMacro(int macroId, int no_args, bool start)
1113 {
1114 switch (convertMode)
1115 {
1116 case TEX_RTF:
1117 {
1118 RTFOnMacro(macroId, no_args, start);
1119 break;
1120 }
1121 case TEX_XLP:
1122 {
1123 XLPOnMacro(macroId, no_args, start);
1124 break;
1125 }
1126 case TEX_HTML:
1127 {
1128 HTMLOnMacro(macroId, no_args, start);
1129 break;
1130 }
1131 }
1132 }
1133
1134 bool OnArgument(int macroId, int arg_no, bool start)
1135 {
1136 switch (convertMode)
1137 {
1138 case TEX_RTF:
1139 {
1140 return RTFOnArgument(macroId, arg_no, start);
1141 break;
1142 }
1143 case TEX_XLP:
1144 {
1145 return XLPOnArgument(macroId, arg_no, start);
1146 break;
1147 }
1148 case TEX_HTML:
1149 {
1150 return HTMLOnArgument(macroId, arg_no, start);
1151 break;
1152 }
1153 }
1154 return TRUE;
1155 }
1156
1157 /*
1158 * DDE Stuff
1159 */
1160 #if defined(__WXMSW__) && !defined(NO_GUI)
1161
1162 /*
1163 * Server
1164 */
1165
1166 wxConnectionBase *Tex2RTFServer::OnAcceptConnection(const wxString& topic)
1167 {
1168 if (topic == "TEX2RTF")
1169 {
1170 if (!ipc_buffer)
1171 ipc_buffer = new char[1000];
1172
1173 return new Tex2RTFConnection(ipc_buffer, 4000);
1174 }
1175 else
1176 return NULL;
1177 }
1178
1179 /*
1180 * Connection
1181 */
1182
1183 Tex2RTFConnection::Tex2RTFConnection(char *buf, int size):wxDDEConnection(buf, size)
1184 {
1185 }
1186
1187 Tex2RTFConnection::~Tex2RTFConnection(void)
1188 {
1189 }
1190
1191 bool SplitCommand(char *data, char *firstArg, char *secondArg)
1192 {
1193 firstArg[0] = 0;
1194 secondArg[0] = 0;
1195 int i = 0;
1196 int len = strlen(data);
1197 bool stop = FALSE;
1198 // Find first argument (command name)
1199 while (!stop)
1200 {
1201 if (data[i] == ' ' || data[i] == 0)
1202 stop = TRUE;
1203 else
1204 {
1205 firstArg[i] = data[i];
1206 i ++;
1207 }
1208 }
1209 firstArg[i] = 0;
1210 if (data[i] == ' ')
1211 {
1212 // Find second argument
1213 i ++;
1214 int j = 0;
1215 while (data[i] != 0)
1216 {
1217 secondArg[j] = data[i];
1218 i ++;
1219 j ++;
1220 }
1221 secondArg[j] = 0;
1222 }
1223 return TRUE;
1224 }
1225
1226 bool Tex2RTFConnection::OnExecute(const wxString& topic, char *data, int size, int format)
1227 {
1228 strcpy(Tex2RTFLastStatus, "OK");
1229
1230 char firstArg[50];
1231 char secondArg[300];
1232 if (SplitCommand(data, firstArg, secondArg))
1233 {
1234 bool hasArg = (strlen(secondArg) > 0);
1235 if (strcmp(firstArg, "INPUT") == 0 && hasArg)
1236 {
1237 if (InputFile) delete[] InputFile;
1238 InputFile = copystring(secondArg);
1239 if (frame)
1240 {
1241 char buf[100];
1242 wxString str = wxFileNameFromPath(InputFile);
1243 sprintf(buf, "Tex2RTF [%s]", (const char*) str);
1244 frame->SetTitle(buf);
1245 }
1246 }
1247 else if (strcmp(firstArg, "OUTPUT") == 0 && hasArg)
1248 {
1249 if (OutputFile) delete[] OutputFile;
1250 OutputFile = copystring(secondArg);
1251 }
1252 else if (strcmp(firstArg, "GO") == 0)
1253 {
1254 strcpy(Tex2RTFLastStatus, "WORKING");
1255 if (!Go())
1256 strcpy(Tex2RTFLastStatus, "CONVERSION ERROR");
1257 else
1258 strcpy(Tex2RTFLastStatus, "OK");
1259 }
1260 else if (strcmp(firstArg, "EXIT") == 0)
1261 {
1262 if (frame) frame->Close();
1263 }
1264 else if (strcmp(firstArg, "MINIMIZE") == 0 || strcmp(firstArg, "ICONIZE") == 0)
1265 {
1266 if (frame)
1267 frame->Iconize(TRUE);
1268 }
1269 else if (strcmp(firstArg, "SHOW") == 0 || strcmp(firstArg, "RESTORE") == 0)
1270 {
1271 if (frame)
1272 {
1273 frame->Iconize(FALSE);
1274 frame->Show(TRUE);
1275 }
1276 }
1277 else
1278 {
1279 // Try for a setting
1280 strcpy(Tex2RTFLastStatus, RegisterSetting(firstArg, secondArg, FALSE));
1281 #ifndef NO_GUI
1282 if (frame && strcmp(firstArg, "conversionMode") == 0)
1283 {
1284 char buf[100];
1285 strcpy(buf, "In ");
1286
1287 if (winHelp && (convertMode == TEX_RTF))
1288 strcat(buf, "WinHelp RTF");
1289 else if (!winHelp && (convertMode == TEX_RTF))
1290 strcat(buf, "linear RTF");
1291 else if (convertMode == TEX_HTML) strcat(buf, "HTML");
1292 else if (convertMode == TEX_XLP) strcat(buf, "XLP");
1293 strcat(buf, " mode.");
1294 frame->SetStatusText(buf, 1);
1295 }
1296 #endif
1297 }
1298 }
1299 return TRUE;
1300 }
1301
1302 char *Tex2RTFConnection::OnRequest(const wxString& topic, const wxString& item, int *size, int format)
1303 {
1304 return Tex2RTFLastStatus;
1305 }
1306
1307 #endif
1308
1309 #ifndef NO_GUI
1310 #ifndef __WXGTK__
1311 //void wxObject::Dump(ostream& str)
1312 //{
1313 // if (GetClassInfo() && GetClassInfo()->GetClassName())
1314 // str << GetClassInfo()->GetClassName();
1315 // else
1316 // str << "unknown object class";
1317 //}
1318 #endif
1319 #endif