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