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