]>
git.saurik.com Git - wxWidgets.git/blob - utils/tex2rtf/src/tex2rtf.cpp
1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: Converts Latex to linear/WinHelp RTF, HTML, wxHelp.
4 // Author: Julian Smart
8 // Copyright: (c) Julian Smart
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
13 #pragma implementation
16 // For compilers that support precompilation, includes "wx.h".
17 #include "wx/wxprec.h"
48 #if (defined(__WXGTK__) || defined(__WXMOTIF__)) && !defined(NO_GUI)
49 #include "tex2rtf.xpm"
52 const float versionNo
= 2.0;
54 TexChunk
*currentMember
= NULL
;
55 bool startedSections
= FALSE
;
56 char *contentsString
= NULL
;
57 bool suppressNameDecoration
= FALSE
;
58 bool OkToClose
= TRUE
;
62 wxHelpController
*HelpInstance
= NULL
;
65 static char *ipc_buffer
= NULL
;
66 static char Tex2RTFLastStatus
[100];
67 Tex2RTFServer
*TheTex2RTFServer
= NULL
;
71 char *bulletFile
= NULL
;
73 FILE *Contents
= NULL
; // Contents page
74 FILE *Chapters
= NULL
; // Chapters (WinHelp RTF) or rest of file (linear RTF)
75 FILE *Sections
= NULL
;
76 FILE *Subsections
= NULL
;
77 FILE *Subsubsections
= NULL
;
79 FILE *WinHelpContentsFile
= NULL
;
81 char *InputFile
= NULL
;
82 char *OutputFile
= NULL
;
83 char *MacroFile
= copystring("tex2rtf.ini");
85 char *FileRoot
= NULL
;
86 char *ContentsName
= NULL
; // Contents page from last time around
87 char *TmpContentsName
= NULL
; // Current contents page
88 char *TmpFrameContentsName
= NULL
; // Current frame contents page
89 char *WinHelpContentsFileName
= NULL
; // WinHelp .cnt file
90 char *RefName
= NULL
; // Reference file name
92 char *RTFCharset
= copystring("ansi");
95 int BufSize
= 100; // Size of buffer in K
101 void ShowOptions(void);
105 extern char *wxBuffer
; // we must init it, otherwise tex2rtf will crash
107 int main(int argc
, char **argv
)
109 wxMenuBar
*menuBar
= NULL
;
110 MyFrame
*frame
= NULL
;
112 // DECLARE_APP(MyApp)
115 // `Main program' equivalent, creating windows and returning main app frame
119 // Use default list of macros defined in tex2any.cc
120 DefineDefaultMacros();
121 AddMacroDef(ltHARDY
, "hardy", 0);
123 FileRoot
= new char[300];
124 ContentsName
= new char[300];
125 TmpContentsName
= new char[300];
126 TmpFrameContentsName
= new char[300];
127 WinHelpContentsFileName
= new char[300];
128 RefName
= new char[300];
132 // Read input/output files
135 if (argv
[1][0] != '-')
142 if (argv
[2][0] != '-')
144 OutputFile
= argv
[2];
152 wxBuffer
= new char[1500];
153 // this is done in wxApp, but NO_GUI version doesn't call it :-(
155 if (!InputFile
|| !OutputFile
)
157 cout
<< "Tex2RTF: input or output file is missing.\n";
165 TexPathList
.EnsureFileAccessible(InputFile
);
167 if (!InputFile
|| !OutputFile
)
168 isInteractive
= TRUE
;
170 for (int i
= n
; i
< argc
;)
172 if (strcmp(argv
[i
], "-winhelp") == 0)
175 convertMode
= TEX_RTF
;
179 else if (strcmp(argv
[i
], "-interactive") == 0)
182 isInteractive
= TRUE
;
185 else if (strcmp(argv
[i
], "-sync") == 0) // Don't yield
190 else if (strcmp(argv
[i
], "-rtf") == 0)
193 convertMode
= TEX_RTF
;
195 else if (strcmp(argv
[i
], "-html") == 0)
198 convertMode
= TEX_HTML
;
200 else if (strcmp(argv
[i
], "-xlp") == 0)
203 convertMode
= TEX_XLP
;
205 else if (strcmp(argv
[i
], "-twice") == 0)
210 else if (strcmp(argv
[i
], "-macros") == 0)
215 MacroFile
= copystring(argv
[i
]);
219 else if (strcmp(argv
[i
], "-bufsize") == 0)
224 BufSize
= atoi(argv
[i
]);
228 else if (strcmp(argv
[i
], "-charset") == 0)
235 if (strcmp(s
, "ansi") == 0 || strcmp(s
, "pc") == 0 || strcmp(s
, "mac") == 0 ||
236 strcmp(s
, "pca") == 0)
237 RTFCharset
= copystring(s
);
240 OnError("Incorrect argument for -charset");
247 sprintf(buf
, "Invalid switch %s.\n", argv
[i
]);
257 #if defined(__WXMSW__) && !defined(NO_GUI)
259 Tex2RTFLastStatus
[0] = 0; // DDE connection return value
260 TheTex2RTFServer
= new Tex2RTFServer
;
261 TheTex2RTFServer
->Create("TEX2RTF");
264 #if defined(__WXMSW__) && defined(__WIN16__)
265 // Limit to max Windows array size
266 if (BufSize
> 64) BufSize
= 64;
269 TexInitialize(BufSize
);
270 ResetContentsLevels(0);
278 // Create the main frame window
279 frame
= new MyFrame(NULL
, -1, "Tex2RTF", wxPoint(-1, -1), wxSize(400, 300));
280 frame
->CreateStatusBar(2);
283 // TODO: uncomment this when we have tex2rtf.xpm
284 frame
->SetIcon(wxICON(tex2rtf
));
288 sprintf(buf
, "Tex2RTF [%s]", FileNameFromPath(InputFile
));
289 frame
->SetTitle(buf
);
293 wxMenu
*file_menu
= new wxMenu
;
294 file_menu
->Append(TEX_GO
, "&Go", "Run converter");
295 file_menu
->Append(TEX_SET_INPUT
, "Set &Input File", "Set the LaTeX input file");
296 file_menu
->Append(TEX_SET_OUTPUT
, "Set &Output File", "Set the output file");
297 file_menu
->AppendSeparator();
298 file_menu
->Append(TEX_VIEW_LATEX
, "View &LaTeX File", "View the LaTeX input file");
299 file_menu
->Append(TEX_VIEW_OUTPUT
, "View Output &File", "View output file");
300 file_menu
->Append(TEX_SAVE_FILE
, "&Save log file", "Save displayed text into file");
301 file_menu
->AppendSeparator();
302 file_menu
->Append(TEX_QUIT
, "E&xit", "Exit Tex2RTF");
304 wxMenu
*macro_menu
= new wxMenu
;
306 macro_menu
->Append(TEX_LOAD_CUSTOM_MACROS
, "&Load Custom Macros", "Load custom LaTeX macro file");
307 macro_menu
->Append(TEX_VIEW_CUSTOM_MACROS
, "View &Custom Macros", "View custom LaTeX macros");
309 wxMenu
*mode_menu
= new wxMenu
;
311 mode_menu
->Append(TEX_MODE_RTF
, "Output linear &RTF", "Wordprocessor-compatible RTF");
312 mode_menu
->Append(TEX_MODE_WINHELP
, "Output &WinHelp RTF", "WinHelp-compatible RTF");
313 mode_menu
->Append(TEX_MODE_HTML
, "Output &HTML", "HTML World Wide Web hypertext file");
314 mode_menu
->Append(TEX_MODE_XLP
, "Output &XLP", "wxHelp hypertext help file");
316 wxMenu
*help_menu
= new wxMenu
;
318 help_menu
->Append(TEX_HELP
, "&Help", "Tex2RTF Contents Page");
319 help_menu
->Append(TEX_ABOUT
, "&About Tex2RTF", "About Tex2RTF");
321 menuBar
= new wxMenuBar
;
322 menuBar
->Append(file_menu
, "&File");
323 menuBar
->Append(macro_menu
, "&Macros");
324 menuBar
->Append(mode_menu
, "&Conversion Mode");
325 menuBar
->Append(help_menu
, "&Help");
327 frame
->SetMenuBar(menuBar
);
328 frame
->textWindow
= new wxTextCtrl(frame
, -1, "", wxPoint(-1, -1), wxSize(-1, -1), wxTE_READONLY
|wxTE_MULTILINE
);
330 (*frame
->textWindow
) << "Welcome to Julian Smart's LaTeX to RTF converter.\n";
333 HelpInstance
= new wxHelpController();
334 HelpInstance
->Initialize("tex2rtf");
337 * Read macro/initialisation file
342 if ((path
= TexPathList
.FindValidPath(MacroFile
)) != "")
343 ReadCustomMacros((char*) (const char*) path
);
347 if (winHelp
&& (convertMode
== TEX_RTF
))
348 strcat(buf
, "WinHelp RTF");
349 else if (!winHelp
&& (convertMode
== TEX_RTF
))
350 strcat(buf
, "linear RTF");
351 else if (convertMode
== TEX_HTML
) strcat(buf
, "HTML");
352 else if (convertMode
== TEX_XLP
) strcat(buf
, "XLP");
353 strcat(buf
, " mode.");
354 frame
->SetStatusText(buf
, 1);
363 * Read macro/initialisation file
368 if ((path
= TexPathList
.FindValidPath(MacroFile
)) != "")
369 ReadCustomMacros((char*) (const char*) path
);
381 // Return the main frame window
392 wxNode
*node
= CustomMacroList
.First();
395 CustomMacro
*macro
= (CustomMacro
*)node
->Data();
398 node
= CustomMacroList
.First();
400 MacroDefs
.BeginFind();
401 node
= MacroDefs
.Next();
404 TexMacroDef
* def
= (TexMacroDef
*) node
->Data();
406 node
= MacroDefs
.Next();
410 delete TheTex2RTFServer
;
415 // TODO: this simulates zero-memory leaks!
416 // Otherwise there are just too many...
418 wxDebugContext::SetCheckpoint();
424 void ShowOptions(void)
427 sprintf(buf
, "Tex2RTF version %.2f", versionNo
);
429 OnInform("Usage: tex2rtf [input] [output] [switches]\n");
430 OnInform("where valid switches are");
431 OnInform(" -interactive");
432 OnInform(" -bufsize <size in K>");
433 OnInform(" -charset <pc | pca | ansi | mac> (default ansi)");
436 OnInform(" -macros <filename>");
437 OnInform(" -winhelp");
445 BEGIN_EVENT_TABLE(MyFrame
, wxFrame
)
446 EVT_CLOSE(MyFrame::OnCloseWindow
)
447 EVT_MENU(TEX_QUIT
, MyFrame::OnExit
)
448 EVT_MENU(TEX_GO
, MyFrame::OnGo
)
449 EVT_MENU(TEX_SET_INPUT
, MyFrame::OnSetInput
)
450 EVT_MENU(TEX_SET_OUTPUT
, MyFrame::OnSetOutput
)
451 EVT_MENU(TEX_SAVE_FILE
, MyFrame::OnSaveFile
)
452 EVT_MENU(TEX_VIEW_LATEX
, MyFrame::OnViewLatex
)
453 EVT_MENU(TEX_VIEW_OUTPUT
, MyFrame::OnViewOutput
)
454 EVT_MENU(TEX_VIEW_CUSTOM_MACROS
, MyFrame::OnShowMacros
)
455 EVT_MENU(TEX_LOAD_CUSTOM_MACROS
, MyFrame::OnLoadMacros
)
456 EVT_MENU(TEX_MODE_RTF
, MyFrame::OnModeRTF
)
457 EVT_MENU(TEX_MODE_WINHELP
, MyFrame::OnModeWinHelp
)
458 EVT_MENU(TEX_MODE_HTML
, MyFrame::OnModeHTML
)
459 EVT_MENU(TEX_MODE_XLP
, MyFrame::OnModeXLP
)
460 EVT_MENU(TEX_HELP
, MyFrame::OnHelp
)
461 EVT_MENU(TEX_ABOUT
, MyFrame::OnAbout
)
464 // My frame constructor
465 MyFrame::MyFrame(wxFrame
*frame
, wxWindowID id
, const wxString
& title
, const wxPoint
& pos
, const wxSize
& size
):
466 wxFrame(frame
, id
, title
, pos
, size
)
469 void MyFrame::OnCloseWindow(wxCloseEvent
& event
)
471 if (!stopRunning
&& !OkToClose
)
483 void MyFrame::OnExit(wxCommandEvent
& event
)
488 void MyFrame::OnGo(wxCommandEvent
& event
)
490 menuBar
->EnableTop(0, FALSE
);
491 menuBar
->EnableTop(1, FALSE
);
492 menuBar
->EnableTop(2, FALSE
);
493 menuBar
->EnableTop(3, FALSE
);
503 menuBar
->EnableTop(0, TRUE
);
504 menuBar
->EnableTop(1, TRUE
);
505 menuBar
->EnableTop(2, TRUE
);
506 menuBar
->EnableTop(3, TRUE
);
509 void MyFrame::OnSetInput(wxCommandEvent
& event
)
511 ChooseInputFile(TRUE
);
514 void MyFrame::OnSetOutput(wxCommandEvent
& event
)
516 ChooseOutputFile(TRUE
);
519 void MyFrame::OnSaveFile(wxCommandEvent
& event
)
521 wxString s
= wxFileSelector("Save text to file", "", "", "txt", "*.txt");
524 textWindow
->SaveFile(s
);
526 sprintf(buf
, "Saved text to %s", (const char*) s
);
527 frame
->SetStatusText(buf
, 0);
531 void MyFrame::OnViewOutput(wxCommandEvent
& event
)
534 if (OutputFile
&& wxFileExists(OutputFile
))
536 textWindow
->LoadFile(OutputFile
);
538 wxString
str(wxFileNameFromPath(OutputFile
));
539 sprintf(buf
, "Tex2RTF [%s]", (const char*) str
);
540 frame
->SetTitle(buf
);
544 void MyFrame::OnViewLatex(wxCommandEvent
& event
)
547 if (InputFile
&& wxFileExists(InputFile
))
549 textWindow
->LoadFile(InputFile
);
551 wxString
str(wxFileNameFromPath(OutputFile
));
552 sprintf(buf
, "Tex2RTF [%s]", (const char*) str
);
553 frame
->SetTitle(buf
);
557 void MyFrame::OnLoadMacros(wxCommandEvent
& event
)
560 wxString s
= wxFileSelector("Choose custom macro file", wxPathOnly(MacroFile
), wxFileNameFromPath(MacroFile
), "ini", "*.ini");
561 if (s
!= "" && wxFileExists(s
))
563 MacroFile
= copystring(s
);
564 ReadCustomMacros((char*) (const char*) s
);
569 void MyFrame::OnShowMacros(wxCommandEvent
& event
)
576 void MyFrame::OnModeRTF(wxCommandEvent
& event
)
578 convertMode
= TEX_RTF
;
582 SetStatusText("In linear RTF mode.", 1);
585 void MyFrame::OnModeWinHelp(wxCommandEvent
& event
)
587 convertMode
= TEX_RTF
;
591 SetStatusText("In WinHelp RTF mode.", 1);
594 void MyFrame::OnModeHTML(wxCommandEvent
& event
)
596 convertMode
= TEX_HTML
;
600 SetStatusText("In HTML mode.", 1);
603 void MyFrame::OnModeXLP(wxCommandEvent
& event
)
605 convertMode
= TEX_XLP
;
608 SetStatusText("In XLP mode.", 1);
611 void MyFrame::OnHelp(wxCommandEvent
& event
)
613 HelpInstance
->LoadFile();
614 HelpInstance
->DisplayContents();
617 void MyFrame::OnAbout(wxCommandEvent
& event
)
621 char *platform
= " (32-bit)";
624 char *platform
= " (16-bit)";
629 sprintf(buf
, "Tex2RTF Version %.2f%s\nLaTeX to RTF, WinHelp, HTML and wxHelp Conversion\n\n(c) Julian Smart 1999", versionNo
, platform
);
630 wxMessageBox(buf
, "About Tex2RTF");
633 void ChooseInputFile(bool force
)
635 if (force
|| !InputFile
)
637 wxString s
= wxFileSelector("Choose LaTeX input file", wxPathOnly(InputFile
), wxFileNameFromPath(InputFile
), "tex", "*.tex");
640 // Different file, so clear index entries.
642 ResetContentsLevels(0);
645 InputFile
= copystring(s
);
646 wxString str
= wxFileNameFromPath(InputFile
);
647 sprintf(buf
, "Tex2RTF [%s]", (const char*) str
);
648 frame
->SetTitle(buf
);
654 void ChooseOutputFile(bool force
)
656 char extensionBuf
[10];
658 strcpy(wildBuf
, "*.");
661 path
= wxPathOnly(OutputFile
);
663 path
= wxPathOnly(InputFile
);
669 strcpy(extensionBuf
, "rtf");
670 strcat(wildBuf
, "rtf");
675 strcpy(extensionBuf
, "xlp");
676 strcat(wildBuf
, "xlp");
681 #if defined(__WXMSW__) && defined(__WIN16__)
682 strcpy(extensionBuf
, "htm");
683 strcat(wildBuf
, "htm");
685 strcpy(extensionBuf
, "html");
686 strcat(wildBuf
, "html");
691 if (force
|| !OutputFile
)
693 wxString s
= wxFileSelector("Choose output file", path
, wxFileNameFromPath(OutputFile
),
694 extensionBuf
, wildBuf
);
696 OutputFile
= copystring(s
);
708 if (!InputFile
|| !OutputFile
)
715 wxString str
= wxFileNameFromPath(InputFile
);
717 sprintf(buf
, "Tex2RTF [%s]", (const char*) str
);
718 frame
->SetTitle(buf
);
724 // Find extension-less filename
725 strcpy(FileRoot
, OutputFile
);
726 StripExtension(FileRoot
);
728 if (truncateFilenames
&& convertMode
== TEX_HTML
)
730 // Truncate to five characters. This ensures that
731 // we can generate DOS filenames such as thing999. But 1000 files
732 // may not be enough, of course...
733 char* sName
= wxFileNameFromPath( FileRoot
); // this Julian's method is non-destructive reference
736 if(strlen( sName
) > 5)
737 sName
[5] = '\0'; // that should do!
740 sprintf(ContentsName
, "%s.con", FileRoot
);
741 sprintf(TmpContentsName
, "%s.cn1", FileRoot
);
742 sprintf(TmpFrameContentsName
, "%s.frc", FileRoot
);
743 sprintf(WinHelpContentsFileName
, "%s.cnt", FileRoot
);
744 sprintf(RefName
, "%s.ref", FileRoot
);
746 TexPathList
.EnsureFileAccessible(InputFile
);
749 wxString s
= TexPathList
.FindValidPath("bullet.bmp");
752 wxString str
= wxFileNameFromPath(s
);
753 bulletFile
= copystring(str
);
757 if (wxFileExists(RefName
))
758 ReadTexReferences(RefName
);
760 bool success
= FALSE
;
762 if (InputFile
&& OutputFile
)
764 if (!FileExists(InputFile
))
766 OnError("Cannot open input file!");
774 sprintf(buf
, "Working, pass %d...", passNumber
);
775 frame
->SetStatusText(buf
);
779 OnInform("Reading LaTeX file...");
780 TexLoadFile(InputFile
);
803 OnInform("*** Aborted by user.");
810 WriteTexReferences(RefName
);
812 startedSections
= FALSE
;
816 long tim
= wxGetElapsedTime();
817 sprintf(buf
, "Finished in %ld seconds.", (long)(tim
/1000.0));
821 sprintf(buf
, "Done, %d %s.", passNumber
, (passNumber
> 1) ? "passes" : "pass");
822 frame
->SetStatusText(buf
);
825 sprintf(buf
, "Done, %d %s.", passNumber
, (passNumber
> 1) ? "passes" : "pass");
834 startedSections
= FALSE
;
836 OnInform("Sorry, unsuccessful.");
841 void OnError(char *msg
)
844 cerr
<< "Error: " << msg
<< "\n";
848 (*frame
->textWindow
) << "Error: " << msg
<< "\n";
852 cerr
<< "Error: " << msg
<< "\n";
863 void OnInform(char *msg
)
870 (*frame
->textWindow
) << msg
<< "\n";
888 void OnMacro(int macroId
, int no_args
, bool start
)
894 RTFOnMacro(macroId
, no_args
, start
);
899 XLPOnMacro(macroId
, no_args
, start
);
904 HTMLOnMacro(macroId
, no_args
, start
);
910 bool OnArgument(int macroId
, int arg_no
, bool start
)
916 return RTFOnArgument(macroId
, arg_no
, start
);
921 return XLPOnArgument(macroId
, arg_no
, start
);
926 return HTMLOnArgument(macroId
, arg_no
, start
);
936 #if defined(__WXMSW__) && !defined(NO_GUI)
942 wxConnectionBase
*Tex2RTFServer::OnAcceptConnection(const wxString
& topic
)
944 if (topic
== "TEX2RTF")
947 ipc_buffer
= new char[1000];
949 return new Tex2RTFConnection(ipc_buffer
, 4000);
959 Tex2RTFConnection::Tex2RTFConnection(char *buf
, int size
):wxDDEConnection(buf
, size
)
963 Tex2RTFConnection::~Tex2RTFConnection(void)
967 bool SplitCommand(char *data
, char *firstArg
, char *secondArg
)
972 int len
= strlen(data
);
974 // Find first argument (command name)
977 if (data
[i
] == ' ' || data
[i
] == 0)
981 firstArg
[i
] = data
[i
];
988 // Find second argument
993 secondArg
[j
] = data
[i
];
1002 bool Tex2RTFConnection::OnExecute(const wxString
& topic
, char *data
, int size
, int format
)
1004 strcpy(Tex2RTFLastStatus
, "OK");
1007 char secondArg
[300];
1008 if (SplitCommand(data
, firstArg
, secondArg
))
1010 bool hasArg
= (strlen(secondArg
) > 0);
1011 if (strcmp(firstArg
, "INPUT") == 0 && hasArg
)
1013 if (InputFile
) delete[] InputFile
;
1014 InputFile
= copystring(secondArg
);
1018 wxString str
= wxFileNameFromPath(InputFile
);
1019 sprintf(buf
, "Tex2RTF [%s]", (const char*) str
);
1020 frame
->SetTitle(buf
);
1023 else if (strcmp(firstArg
, "OUTPUT") == 0 && hasArg
)
1025 if (OutputFile
) delete[] OutputFile
;
1026 OutputFile
= copystring(secondArg
);
1028 else if (strcmp(firstArg
, "GO") == 0)
1030 strcpy(Tex2RTFLastStatus
, "WORKING");
1032 strcpy(Tex2RTFLastStatus
, "CONVERSION ERROR");
1034 strcpy(Tex2RTFLastStatus
, "OK");
1036 else if (strcmp(firstArg
, "EXIT") == 0)
1038 if (frame
) frame
->Close();
1040 else if (strcmp(firstArg
, "MINIMIZE") == 0 || strcmp(firstArg
, "ICONIZE") == 0)
1043 frame
->Iconize(TRUE
);
1045 else if (strcmp(firstArg
, "SHOW") == 0 || strcmp(firstArg
, "RESTORE") == 0)
1049 frame
->Iconize(FALSE
);
1055 // Try for a setting
1056 strcpy(Tex2RTFLastStatus
, RegisterSetting(firstArg
, secondArg
, FALSE
));
1058 if (frame
&& strcmp(firstArg
, "conversionMode") == 0)
1063 if (winHelp
&& (convertMode
== TEX_RTF
))
1064 strcat(buf
, "WinHelp RTF");
1065 else if (!winHelp
&& (convertMode
== TEX_RTF
))
1066 strcat(buf
, "linear RTF");
1067 else if (convertMode
== TEX_HTML
) strcat(buf
, "HTML");
1068 else if (convertMode
== TEX_XLP
) strcat(buf
, "XLP");
1069 strcat(buf
, " mode.");
1070 frame
->SetStatusText(buf
, 1);
1078 char *Tex2RTFConnection::OnRequest(const wxString
& topic
, const wxString
& item
, int *size
, int format
)
1080 return Tex2RTFLastStatus
;
1087 //void wxObject::Dump(ostream& str)
1089 // if (GetClassInfo() && GetClassInfo()->GetClassName())
1090 // str << GetClassInfo()->GetClassName();
1092 // str << "unknown object class";