#include "Preamble.h"
#include "TextClass.h"
+#include "support/ConsoleApplication.h"
#include "support/convert.h"
#include "support/ExceptionMessage.h"
#include "support/filetools.h"
#include <cstdlib>
#include <algorithm>
+#include <exception>
#include <iostream>
#include <string>
#include <sstream>
for (; it != end; ++it) {
string const module = it->getID();
LayoutModuleList m;
+ LayoutModuleList c;
vector<string> v;
if (!addModule(module, baseClass, m, v))
continue;
- modules[module] = getDocumentClass(baseClass, m);
+ modules[module] = getDocumentClass(baseClass, m, c);
}
init = false;
}
typedef int (*cmd_helper)(string const &, string const &);
+class StopException : public exception
+{
+ public:
+ StopException(int status) : status_(status) {}
+ int status() const { return status_; }
+ private:
+ int status_;
+};
+
+
+/// The main application class
+class TeX2LyXApp : public ConsoleApplication
+{
+public:
+ TeX2LyXApp(int & argc, char * argv[])
+ : ConsoleApplication("tex2lyx" PROGRAM_SUFFIX, argc, argv),
+ argc_(argc), argv_(argv)
+ {
+ }
+ void doExec()
+ {
+ try {
+ int const exit_status = run();
+ exit(exit_status);
+ }
+ catch (StopException & e) {
+ exit(e.status());
+ }
+ }
+private:
+ void easyParse();
+ /// Do the real work
+ int run();
+ int & argc_;
+ char ** argv_;
+};
+
+
int parse_help(string const &, string const &)
{
cout << "Usage: tex2lyx [options] infile.tex [outfile.lyx]\n"
"\tand \"SYSDIR/layouts\" are searched for layout and module files.\n"
"Check the tex2lyx man page for more details."
<< endl;
- exit(error_code);
+ throw StopException(error_code);
}
{
cout << "tex2lyx " << lyx_version
<< " (" << lyx_release_date << ")" << endl;
- cout << "Built on " << lyx_build_date << ", " << lyx_build_time
- << endl;
cout << lyx_version_info << endl;
- exit(error_code);
+ throw StopException(error_code);
}
void error_message(string const & message)
{
cerr << "tex2lyx: " << message << "\n\n";
- error_code = 1;
+ error_code = EXIT_FAILURE;
parse_help(string(), string());
}
}
-void easyParse(int & argc, char * argv[])
+void TeX2LyXApp::easyParse()
{
map<string, cmd_helper> cmdmap;
cmdmap["-roundtrip"] = parse_roundtrip;
cmdmap["-copyfiles"] = parse_copyfiles;
- for (int i = 1; i < argc; ++i) {
+ for (int i = 1; i < argc_; ++i) {
map<string, cmd_helper>::const_iterator it
- = cmdmap.find(argv[i]);
+ = cmdmap.find(argv_[i]);
// don't complain if not found - may be parsed later
if (it == cmdmap.end()) {
- if (argv[i][0] == '-')
- error_message(string("Unknown option `") + argv[i] + "'.");
+ if (argv_[i][0] == '-')
+ error_message(string("Unknown option `") + argv_[i] + "'.");
else
continue;
}
- string arg = (i + 1 < argc) ? os::utf8_argv(i + 1) : string();
- string arg2 = (i + 2 < argc) ? os::utf8_argv(i + 2) : string();
+ string arg = (i + 1 < argc_) ? os::utf8_argv(i + 1) : string();
+ string arg2 = (i + 2 < argc_) ? os::utf8_argv(i + 2) : string();
int const remove = 1 + it->second(arg, arg2);
// Now, remove used arguments by shifting
// the following ones remove places down.
os::remove_internal_args(i, remove);
- argc -= remove;
- for (int j = i; j < argc; ++j)
- argv[j] = argv[j + remove];
+ argc_ -= remove;
+ for (int j = i; j < argc_; ++j)
+ argv_[j] = argv_[j + remove];
--i;
}
}
* You must ensure that \p parentFilePathTeX is properly set before calling
* this function!
*/
-bool tex2lyx(idocstream & is, ostream & os, string encoding)
+bool tex2lyx(idocstream & is, ostream & os, string const & encoding,
+ string const & outfiledir)
{
- // Set a sensible default encoding.
- // This is used until an encoding command is found.
- // For child documents use the encoding of the master, else ISO8859-1,
- // (formerly known by its latex name latin1), since ISO8859-1 does not
- // cause an iconv error if the actual encoding is different (bug 7509).
- if (encoding.empty()) {
- if (preamble.inputencoding() == "auto")
- encoding = "ISO8859-1";
- else {
- Encoding const * const enc = encodings.fromLyXName(
- preamble.inputencoding(), true);
- encoding = enc->iconvName();
- }
- }
-
Parser p(is, fixed_encoding ? default_encoding : string());
p.setEncoding(encoding);
//p.dump();
for (; it != end; ++it)
preamble.addModule(*it);
}
- if (!preamble.writeLyXHeader(os, !active_environments.empty())) {
+ if (!preamble.writeLyXHeader(os, !active_environments.empty(), outfiledir)) {
cerr << "Could not write LyX file header." << endl;
return false;
}
/// convert TeX from \p infilename to LyX and write it to \p os
-bool tex2lyx(FileName const & infilename, ostream & os, string const & encoding)
+bool tex2lyx(FileName const & infilename, ostream & os, string encoding,
+ string const & outfiledir)
{
- ifdocstream is;
+ // Set a sensible default encoding.
+ // This is used until an encoding command is found.
+ // For child documents use the encoding of the master, else try to
+ // detect it from the preamble, since setting an encoding of an open
+ // fstream does currently not work on OS X.
+ // Always start with ISO-8859-1, (formerly known by its latex name
+ // latin1), since ISO-8859-1 does not cause an iconv error if the
+ // actual encoding is different (bug 7509).
+ if (encoding.empty()) {
+ Encoding const * enc = 0;
+ if (preamble.inputencoding() == "auto") {
+ ifdocstream is(setEncoding("ISO-8859-1"));
+ // forbid buffering on this stream
+ is.rdbuf()->pubsetbuf(0, 0);
+ is.open(infilename.toFilesystemEncoding().c_str());
+ if (is.good()) {
+ Parser ep(is, string());
+ ep.setEncoding("ISO-8859-1");
+ Preamble encodingpreamble;
+ string const e = encodingpreamble
+ .parseEncoding(ep, documentclass);
+ if (!e.empty())
+ enc = encodings.fromLyXName(e, true);
+ }
+ } else
+ enc = encodings.fromLyXName(
+ preamble.inputencoding(), true);
+ if (enc)
+ encoding = enc->iconvName();
+ else
+ encoding = "ISO-8859-1";
+ }
+
+ ifdocstream is(setEncoding(encoding));
// forbid buffering on this stream
- is.rdbuf()->pubsetbuf(0,0);
+ is.rdbuf()->pubsetbuf(0, 0);
is.open(infilename.toFilesystemEncoding().c_str());
if (!is.good()) {
cerr << "Could not open input file \"" << infilename
}
string const oldParentFilePath = parentFilePathTeX;
parentFilePathTeX = onlyPath(infilename.absFileName());
- bool retval = tex2lyx(is, os, encoding);
+ bool retval = tex2lyx(is, os, encoding, outfiledir);
parentFilePathTeX = oldParentFilePath;
return retval;
}
cerr << "Input file: " << infilename << "\n";
cerr << "Output file: " << outfilename << "\n";
#endif
- return tex2lyx(FileName(infilename), os, encoding);
+ return tex2lyx(FileName(infilename), os, encoding,
+ outfilename.onlyPath().absFileName() + '/');
}
return false;
}
-} // namespace lyx
+namespace {
-int main(int argc, char * argv[])
+int TeX2LyXApp::run()
{
- using namespace lyx;
-
- //setlocale(LC_CTYPE, "");
-
- lyxerr.setStream(cerr);
-
- os::init(argc, argv);
+ // qt changes this, and our numeric conversions require the C locale
+ setlocale(LC_NUMERIC, "C");
try {
init_package(internal_path(os::utf8_argv(0)), string(), string());
return EXIT_FAILURE;
}
- easyParse(argc, argv);
+ easyParse();
- if (argc <= 1)
+ if (argc_ <= 1)
error_message("Not enough arguments.");
try {
infilename = makeAbsPath(infilename).absFileName();
string outfilename;
- if (argc > 2) {
+ if (argc_ > 2) {
outfilename = internal_path(os::utf8_argv(2));
if (outfilename != "-")
outfilename = makeAbsPath(outfilename).absFileName();
if (outfilename == "-") {
// assume same directory as input file
masterFilePathLyX = masterFilePathTeX;
- if (tex2lyx(FileName(infilename), cout, default_encoding))
+ if (tex2lyx(FileName(infilename), cout, default_encoding, masterFilePathLyX))
return EXIT_SUCCESS;
} else {
masterFilePathLyX = onlyPath(outfilename);
if (tex2tex(infilename, FileName(outfilename), default_encoding))
return EXIT_SUCCESS;
} else {
- if (tex2lyx(infilename, FileName(outfilename), default_encoding))
+ if (lyx::tex2lyx(infilename, FileName(outfilename), default_encoding))
return EXIT_SUCCESS;
}
}
return EXIT_FAILURE;
}
+} // anonymous namespace
+} // namespace lyx
+
+
+int main(int argc, char * argv[])
+{
+ //setlocale(LC_CTYPE, "");
+
+ lyx::lyxerr.setStream(cerr);
+
+ os::init(argc, argv);
+
+ lyx::TeX2LyXApp app(argc, argv);
+ return app.exec();
+}
+
// }])