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