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