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