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