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