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