]> git.lyx.org Git - lyx.git/blobdiff - src/tex2lyx/tex2lyx.cpp
More requires --> required, for C++2a.
[lyx.git] / src / tex2lyx / tex2lyx.cpp
index 3f6fe73821431b688d6d9e82cb0ea9416dc03280..667fad76b6f88d08a1d7ea1a8ff3f99b32d97a1a 100644 (file)
@@ -172,30 +172,32 @@ void add_known_theorem(string const & theorem, string const & o1,
 }
 
 
-Layout const * findLayoutWithoutModule(TextClass const & textclass,
-                                       string const & name, bool command)
+Layout const * findLayoutWithoutModule(TextClass const & tc,
+                                       string const & name, bool command,
+                                       string const & latexparam)
 {
-       DocumentClass::const_iterator it = textclass.begin();
-       DocumentClass::const_iterator en = textclass.end();
-       for (; it != en; ++it) {
-               if (it->latexname() == name &&
-                   ((command && it->isCommand()) || (!command && it->isEnvironment())))
-                       return &*it;
+       for (auto const & lay : tc) {
+               if (lay.latexname() == name &&
+                   (latexparam.empty() ||
+                    (!lay.latexparam().empty() && suffixIs(latexparam, lay.latexparam()))) &&
+                   ((command && lay.isCommand()) || (!command && lay.isEnvironment())))
+                       return &lay;
        }
        return 0;
 }
 
 
-InsetLayout const * findInsetLayoutWithoutModule(TextClass const & textclass,
-                                                 string const & name, bool command)
+InsetLayout const * findInsetLayoutWithoutModule(TextClass const & tc,
+                                                 string const & name, bool command,
+                                                 string const & latexparam)
 {
-       DocumentClass::InsetLayouts::const_iterator it = textclass.insetLayouts().begin();
-       DocumentClass::InsetLayouts::const_iterator en = textclass.insetLayouts().end();
-       for (; it != en; ++it) {
-               if (it->second.latexname() == name &&
-                   ((command && it->second.latextype() == InsetLayout::COMMAND) ||
-                    (!command && it->second.latextype() == InsetLayout::ENVIRONMENT)))
-                       return &(it->second);
+       for (auto const & ilay : tc.insetLayouts()) {
+               if (ilay.second.latexname() == name &&
+                   (latexparam.empty() ||
+                    (!ilay.second.latexparam().empty() && suffixIs(latexparam, ilay.second.latexparam()))) &&
+                   ((command && ilay.second.latextype() == InsetLayout::COMMAND) ||
+                    (!command && ilay.second.latextype() == InsetLayout::ENVIRONMENT)))
+                       return &(ilay.second);
        }
        return 0;
 }
@@ -282,11 +284,10 @@ void initModules()
                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, c);
+                       modules[module] = getDocumentClass(baseClass, m);
                }
                init = false;
        }
@@ -312,7 +313,7 @@ bool addModule(string const & module)
        return false;
 }
 
-}
+} // namespace
 
 
 bool checkModule(string const & name, bool command)
@@ -320,17 +321,18 @@ bool checkModule(string const & name, bool command)
        // Cache to avoid slowdown by repated searches
        static set<string> failed[2];
 
-       // Only add the module if the command was actually defined in the LyX preamble
+       // Record whether the command was actually defined in the LyX preamble
        bool theorem = false;
+       bool preamble_def = true;
        if (command) {
                if (possible_textclass_commands.find('\\' + name) == possible_textclass_commands.end())
-                       return false;
+                       preamble_def = false;
        } else {
                if (possible_textclass_environments.find(name) == possible_textclass_environments.end()) {
                        if (possible_textclass_theorems.find(name) != possible_textclass_theorems.end())
                                theorem = true;
                        else
-                               return false;
+                               preamble_def = false;
                }
        }
        if (failed[command].find(name) != failed[command].end())
@@ -340,12 +342,16 @@ bool checkModule(string const & name, bool command)
        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
-       // style that corresponds to the command. This is a heuristic and
-       // different from the way how we parse the builtin commands of the
-       // text class (in that case we only compare the name), but it is
-       // needed since it is not unlikely that two different modules define a
+       // For commands with preamble definitions we prefer modules where the definition
+       // can be found in the preamble of the style that corresponds to the command. 
+       // For others we check whether the command or module requires a package that is loaded
+       // in the tex file and use a style with the respective command.
+       // This is a heuristic and different from the way how we parse the builtin
+       // commands of the text class (in that case we only compare the name), 
+       // but it is needed since it is not unlikely that two different modules define a
        // command with the same name.
+       string found_module;
+       vector<string> potential_modules;
        ModuleMap::iterator const end = modules.end();
        for (ModuleMap::iterator it = modules.begin(); it != end; ++it) {
                string const module = it->first;
@@ -357,40 +363,101 @@ bool checkModule(string const & name, bool command)
                        continue;
                DocumentClassConstPtr c = it->second;
                Layout const * layout = findLayoutWithoutModule(*c, name, command);
-               InsetLayout const * insetlayout = layout ? 0 :
+               InsetLayout const * insetlayout = layout ? nullptr :
                        findInsetLayoutWithoutModule(*c, name, command);
-               docstring preamble;
-               if (layout)
-                       preamble = layout->preamble();
-               else if (insetlayout)
-                       preamble = insetlayout->preamble();
-               if (preamble.empty())
+               docstring dpre;
+               std::set<std::string> cmd_reqs;
+               bool found_style = false;
+               if (layout) {
+                       found_style = true;
+                       dpre = layout->preamble();
+                       std::set<std::string> lreqs = layout->required();
+                       if (!lreqs.empty())
+                               cmd_reqs.insert(lreqs.begin(), lreqs.end());
+               } else if (insetlayout) {
+                       found_style = true;
+                       dpre = insetlayout->preamble();
+                       std::set<std::string> lreqs = insetlayout->required();
+                       if (!lreqs.empty())
+                               cmd_reqs.insert(lreqs.begin(), lreqs.end());
+               }
+               if (dpre.empty() && preamble_def)
                        continue;
-               bool add = false;
-               if (command) {
-                       FullCommand const & cmd =
-                               possible_textclass_commands['\\' + name];
-                       if (preamble.find(cmd.def) != docstring::npos)
-                               add = true;
-               } else if (theorem) {
-                       FullCommand const & thm =
-                               possible_textclass_theorems[name];
-                       if (preamble.find(thm.def) != docstring::npos)
-                               add = true;
-               } else {
-                       FullEnvironment const & env =
-                               possible_textclass_environments[name];
-                       if (preamble.find(env.beg) != docstring::npos &&
-                           preamble.find(env.end) != docstring::npos)
-                               add = true;
+               bool const package_cmd = dpre.empty();
+               bool match_req = false;
+               if (package_cmd) {
+                       std::set<std::string> mreqs = it->second->required();
+                       if (!mreqs.empty())
+                               cmd_reqs.insert(mreqs.begin(), mreqs.end());
+                       for (auto const & pack : cmd_reqs) {
+                               // If a requirement of the module matches a used package
+                               // we load the module except if we have an auto-loaded package
+                               // which is only required generally by the module, and the module
+                               // does not provide the [inset]layout we are looking for.
+                               // This heuristics should
+                               // * load modules if the provide a style we don't have in the class
+                               // * load modules that provide a package support generally (such as fixltx2e)
+                               // * not unnecessarily load modules just because they require a package which we
+                               //   load anyway.
+                               if (preamble.isPackageUsed(pack)
+                                   && (found_style || !preamble.isPackageAutoLoaded(pack))) {
+                                   if (found_style)
+                                           match_req = true;
+                                   else                
+                                           potential_modules.push_back(module);
+                                   break;
+                               }
+                       }
+               }
+               bool add = match_req;
+               if (preamble_def) {
+                       if (command) {
+                               FullCommand const & cmd =
+                                       possible_textclass_commands['\\' + name];
+                               if (dpre.find(cmd.def) != docstring::npos)
+                                       add = true;
+                       } else if (theorem) {
+                               FullCommand const & thm =
+                                       possible_textclass_theorems[name];
+                               if (dpre.find(thm.def) != docstring::npos)
+                                       add = true;
+                       } else {
+                               FullEnvironment const & env =
+                                       possible_textclass_environments[name];
+                               if (dpre.find(env.beg) != docstring::npos &&
+                                   dpre.find(env.end) != docstring::npos)
+                                       add = true;
+                       }
                }
                if (add) {
-                       FileName layout_file = libFileSearch("layouts", module, "module");
+                       found_module = module;
+                       break;
+               }
+       }
+       if (found_module.empty()) {
+               // take one of the second row
+               if (!potential_modules.empty())
+                       found_module = potential_modules.front();  
+       }
+               
+       if (!found_module.empty()) {
+               vector<string> v;
+               LayoutModuleList mods;
+               // addModule is necessary in order to catch required modules
+               // as well (see #11156)
+               if (!addModule(found_module, baseClass, mods, v))
+                       return false;
+               for (auto const & mod : mods) {
+                       if (!used_modules.moduleCanBeAdded(mod, &baseClass))
+                               return false;
+                       FileName layout_file = libFileSearch("layouts", mod, "module");
                        if (textclass.read(layout_file, TextClass::MODULE)) {
-                               used_modules.push_back(module);
+                               used_modules.push_back(mod);
                                // speed up further searches:
                                // the module does not need to be checked anymore.
-                               modules.erase(it);
+                               ModuleMap::iterator const it = modules.find(mod);
+                               if (it != modules.end())
+                                       modules.erase(it);
                                return true;
                        }
                }
@@ -878,6 +945,8 @@ bool tex2lyx(idocstream & is, ostream & os, string const & encoding,
        context.font.language = preamble.defaultLanguage();
        // parse the main text
        parse_text(p, ss, FLAG_END, true, context);
+       // check if we need a commented bibtex inset (biblatex)
+       check_comment_bib(ss, context);
        if (Context::empty)
                // Empty document body. LyX needs at least one paragraph.
                context.check_layout(ss);
@@ -924,7 +993,7 @@ bool tex2lyx(FileName const & infilename, ostream & os, string encoding,
        // actual encoding is different (bug 7509).
        if (encoding.empty()) {
                Encoding const * enc = 0;
-               if (preamble.inputencoding() == "auto") {
+               if (preamble.inputencoding() == "auto-legacy") {
                        ifdocstream is(setEncoding("ISO-8859-1"));
                        // forbid buffering on this stream
                        is.rdbuf()->pubsetbuf(0, 0);
@@ -945,6 +1014,8 @@ bool tex2lyx(FileName const & infilename, ostream & os, string encoding,
                        encoding = enc->iconvName();
                else
                        encoding = "ISO-8859-1";
+               // store
+               preamble.docencoding = encoding;
        }
 
        ifdocstream is(setEncoding(encoding));
@@ -1060,7 +1131,9 @@ int TeX2LyXApp::run()
                if (configFileNeedsUpdate("lyxrc.defaults") ||
                    configFileNeedsUpdate("lyxmodules.lst") ||
                    configFileNeedsUpdate("textclass.lst") ||
-                   configFileNeedsUpdate("packages.lst"))
+                   configFileNeedsUpdate("packages.lst") ||
+                   configFileNeedsUpdate("lyxciteengines.lst") ||
+                   configFileNeedsUpdate("xtemplates.lst"))
                        package().reconfigureUserLyXDir("");
                fileUnlock(fd, lock_file.c_str());
        } else
@@ -1179,7 +1252,7 @@ int main(int argc, char * argv[])
 
        lyx::lyxerr.setStream(cerr);
 
-       os::init(argc, argv);
+       os::init(argc, &argv);
 
        lyx::TeX2LyXApp app(argc, argv);
        return app.exec();