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