From 93d47c825bfa1d3c5d9d4e6a25e73e2bcb6f537d Mon Sep 17 00:00:00 2001 From: Georg Baum Date: Fri, 23 Nov 2012 16:13:34 +0100 Subject: [PATCH] Implement tex2lyx -m switch (bug #8393) Backported from b8648dea168. With this new command line switch a list of modules can be loaded unconditionally. This seems to be needed for the literate programming formats, and it is useful to work around bug #5702 as well. --- src/tex2lyx/tex2lyx.1in | 12 +++++- src/tex2lyx/tex2lyx.cpp | 92 +++++++++++++++++++++++++++++++++-------- status.20x | 2 +- 3 files changed, 86 insertions(+), 20 deletions(-) diff --git a/src/tex2lyx/tex2lyx.1in b/src/tex2lyx/tex2lyx.1in index 1ac5161efb..c99de071eb 100644 --- a/src/tex2lyx/tex2lyx.1in +++ b/src/tex2lyx/tex2lyx.1in @@ -20,8 +20,9 @@ call it from the command line only if you need to use more complicated options. .PP \fBtex2lyx\fR [ \fB\-userdir\fR \fIuserdir\fR ] [ \fB\-systemdir\fR \fIsystemdir\fR ] -[ \fB\-n\fR ] [ \fB\-c\fR \fItextclass\fR ] [\ \fB\-s\fR\ \fIsfile1\fR[,\fIsfile2\fR...]] [ -\fB\-roundtrip\fR ] \fIinputfile\fR [ \fIoutputfile\fR ] +[ \fB\-f\fR ] [ \fB\-n\fR ] [ \fB\-c\fR \fItextclass\fR ] +[\ \fB\-m\fR \fImodule1\fR[,\fImodule2\fR...]] +[\ \fB\-s\fR\ \fIsfile1\fR[,\fIsfile2\fR...]] [\fB\-roundtrip\fR ] \fIinputfile\fR [ \fIoutputfile\fR ] .\" .PP .\" \fBtex2lyx\fR [ \fB\-userdir\fR \fIuserdir\fR ] [ \fB\-systemdir\fR \fIsystemdir\fR ] .\" [\ \fB\-r\fR\ \fIrenv1\fR[,\fIrenv2\fR...]] [\ \fB\-s\fR\ \fIsfile1\fR[,\fIsfile2\fR...]] @@ -40,6 +41,13 @@ matter or \f(CW\ebegin{document}\fR command. LyX files created by \fBtex2lyx\fR from partial files can be included in an existing LyX file using the \*[lq]Include LyX File\*[rq] command from LyX's Insert menu. .TP +.BI \-m +Module. Load the given modules. This is useful if \fBtex2lyx\fR does not +automatically detect a given module, but you know the modules that provide +some commands or environments that are used in the imported file. The modules +are loaded in the given order. If a module \fIfoo\fR depends on a module +\fIbar\fR, \fIbar\fR must be given before \fIfoo\fR. +.TP .BI \-f Force. \fBtex2lyx\fR will not run if the .lyx file it would generate already exists. Use the \fB\-f\fR option (carefully) to clobber any existing files. diff --git a/src/tex2lyx/tex2lyx.cpp b/src/tex2lyx/tex2lyx.cpp index 3acc0e7a22..3e9702d7d0 100644 --- a/src/tex2lyx/tex2lyx.cpp +++ b/src/tex2lyx/tex2lyx.cpp @@ -165,6 +165,7 @@ FullEnvironmentMap possible_textclass_environments; /// used modules LayoutModuleList used_modules; +vector preloaded_modules; void convertArgs(string const & o1, bool o2, vector & arguments) @@ -245,28 +246,16 @@ InsetLayout const * findInsetLayoutWithoutModule(TextClass const & textclass, } -bool checkModule(string const & name, bool command) -{ - // Cache to avoid slowdown by repated searches - static set failed[2]; - - // Only add the module if the command was actually defined in the LyX preamble - if (command) { - if (possible_textclass_commands.find('\\' + name) == possible_textclass_commands.end()) - return false; - } else { - if (possible_textclass_environments.find(name) == possible_textclass_environments.end()) - return false; - } - if (failed[command].find(name) != failed[command].end()) - return false; +namespace { +typedef map ModuleMap; +ModuleMap modules; +void initModules() +{ // Create list of dummy document classes if not already done. // This is needed since a module cannot be read on its own, only as // part of a document class. LayoutFile const & baseClass = LayoutFileList::get()[textclass.name()]; - typedef map ModuleMap; - static ModuleMap modules; static bool init = true; if (init) { baseClass.load(); @@ -284,6 +273,49 @@ bool checkModule(string const & name, bool command) } init = false; } +} + + +bool addModule(string const & module) +{ + initModules(); + LayoutFile const & baseClass = LayoutFileList::get()[textclass.name()]; + if (!used_modules.moduleCanBeAdded(module, &baseClass)) + return false; + FileName layout_file = libFileSearch("layouts", module, "module"); + if (textclass.read(layout_file, TextClass::MODULE)) { + used_modules.push_back(module); + // speed up further searches: + // the module does not need to be checked anymore. + ModuleMap::iterator const it = modules.find(module); + if (it != modules.end()) + modules.erase(it); + return true; + } + return false; +} + +} + + +bool checkModule(string const & name, bool command) +{ + // Cache to avoid slowdown by repated searches + static set failed[2]; + + // Only add the module if the command was actually defined in the LyX preamble + if (command) { + if (possible_textclass_commands.find('\\' + name) == possible_textclass_commands.end()) + return false; + } else { + if (possible_textclass_environments.find(name) == possible_textclass_environments.end()) + return false; + } + if (failed[command].find(name) != failed[command].end()) + return false; + + initModules(); + LayoutFile const & baseClass = LayoutFileList::get()[textclass.name()]; // Try to find a module that defines the command. // Only add it if the definition can be found in the preamble of the @@ -468,6 +500,7 @@ int parse_help(string const &, string const &) cerr << "Usage: tex2lyx [options] infile.tex [outfile.lyx]\n" "Options:\n" "\t-c textclass Declare the textclass.\n" + "\t-m mod1[,mod2...] Load the given modules.\n" "\t-e encoding Set the default encoding (latex name).\n" "\t-f Force overwrite of .lyx files.\n" "\t-help Print this message and quit.\n" @@ -518,6 +551,15 @@ int parse_class(string const & arg, string const &) } +int parse_module(string const & arg, string const &) +{ + if (arg.empty()) + error_message("Missing modules string after -m switch"); + split(arg, preloaded_modules, ','); + return 1; +} + + int parse_encoding(string const & arg, string const &) { if (arg.empty()) @@ -592,6 +634,7 @@ void easyParse(int & argc, char * argv[]) cmdmap["-version"] = parse_version; cmdmap["--version"] = parse_version; cmdmap["-c"] = parse_class; + cmdmap["-m"] = parse_module; cmdmap["-e"] = parse_encoding; cmdmap["-f"] = parse_force; cmdmap["-s"] = parse_syntaxfile; @@ -678,6 +721,21 @@ bool tex2lyx(idocstream & is, ostream & os, string encoding) preamble.parse(p, documentclass, textclass); + // Load preloaded modules. + // This needs to be done after the preamble is parsed, since the text + // class may not be known before. It neds to be done before parsing + // body, since otherwise the commands/environments provided by the + // modules would be parsed as ERT. + for (size_t i = 0; i < preloaded_modules.size(); ++i) { + if (!addModule(preloaded_modules[i])) { + cerr << "Error: Could not load module \"" + << preloaded_modules[i] << "\"." << endl; + return false; + } + } + // Ensure that the modules are not loaded again for included files + preloaded_modules.clear(); + active_environments.push_back("document"); Context context(true, textclass); stringstream ss; diff --git a/status.20x b/status.20x index f1bc55911c..8c0d0e981e 100644 --- a/status.20x +++ b/status.20x @@ -34,7 +34,7 @@ What's new * TEX2LYX IMPROVEMENTS - +- add new option -m to select needed modules (bug #8393). * USER INTERFACE -- 2.39.5