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