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