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