The branch, master, has been updated.

- Log -----------------------------------------------------------------

commit 78a7743166f539861cdd0465d98a4c5d3f40ac5c
Author: Georg Baum <[email protected]>
Date:   Fri Oct 26 22:23:16 2012 +0200

    Import theorems correctly (bugs #5702, #5776)
    
    Actually tex2lyx can handle modules since some time (#5702), but not
    theorems (#5776). Now the following issues are fixed:
    - Modules that depend on other modules can be loaded, since the dependencies
      are loaded first
    - Default moduls of the text class are loaded correctly
    - \newtheorem is recognized as a command that defines new environments and
      treated similar to \newenvironment

diff --git a/src/LayoutModuleList.cpp b/src/LayoutModuleList.cpp
index a650721..d532b2d 100644
--- a/src/LayoutModuleList.cpp
+++ b/src/LayoutModuleList.cpp
@@ -67,10 +67,8 @@ bool LayoutModuleList::moduleCanBeAdded(string const & 
modName,
        if (!lm)
                return true;
 
-       // Is this module explicitly excluded by the document class?
-       const_iterator const exclmodstart = lay->excludedModules().begin();
-       const_iterator const exclmodend = lay->excludedModules().end();
-       if (find(exclmodstart, exclmodend, modName) != exclmodend)
+       // Does this module conflict with the document class or any loaded 
modules?
+       if (moduleConflicts(modName, lay))
                return false;
 
        // Is this module already provided by the document class?
@@ -79,26 +77,13 @@ bool LayoutModuleList::moduleCanBeAdded(string const & 
modName,
        if (find(provmodstart, provmodend, modName) != provmodend)
                return false;
 
-       // Check for conflicts with used modules
-       // first the provided modules...
-       const_iterator provmodit = provmodstart;
-       for (; provmodit != provmodend; ++provmodit) {
-               if (!LyXModule::areCompatible(modName, *provmodit))
-                       return false;
-       }
-       // and then the selected modules
-       const_iterator mit = begin();
-       const_iterator const men = end();
-       for (; mit != men; ++mit)
-               if (!LyXModule::areCompatible(modName, *mit))
-                       return false;
-
        // Check whether some required module is available
        vector<string> const reqs = lm->getRequiredModules();
        if (reqs.empty())
                return true;
 
-       mit = begin(); // reset
+       const_iterator mit = begin();
+       const_iterator const men = end();
        vector<string>::const_iterator rit = reqs.begin();
        vector<string>::const_iterator ren = reqs.end();
        bool foundone = false;
@@ -114,6 +99,32 @@ bool LayoutModuleList::moduleCanBeAdded(string const & 
modName,
 }
 
 
+bool LayoutModuleList::moduleConflicts(string const & modName,
+                                       LayoutFile const * const lay) const
+{
+       // Is this module explicitly excluded by the document class?
+       const_iterator const exclmodstart = lay->excludedModules().begin();
+       const_iterator const exclmodend = lay->excludedModules().end();
+       if (find(exclmodstart, exclmodend, modName) != exclmodend)
+               return true;
+       // Check for conflicts with used modules
+       // first the provided modules...
+       const_iterator provmodit = lay->providedModules().begin();
+       const_iterator const provmodend = lay->providedModules().end();
+       for (; provmodit != provmodend; ++provmodit) {
+               if (!LyXModule::areCompatible(modName, *provmodit))
+                       return true;
+       }
+       // and then the selected modules
+       const_iterator mit = begin();
+       const_iterator const men = end();
+       for (; mit != men; ++mit)
+               if (!LyXModule::areCompatible(modName, *mit))
+                       return true;
+       return false;
+}
+
+
 void LayoutModuleList::addDefaultModules(LayoutFile const * const lay,
                std::list<string> removedModules)
 {
diff --git a/src/LayoutModuleList.h b/src/LayoutModuleList.h
index 245b6a7..f5741de 100644
--- a/src/LayoutModuleList.h
+++ b/src/LayoutModuleList.h
@@ -57,7 +57,10 @@ public:
        std::list<std::string> const & list() const { return lml_; }
        /// Checks to make sure module's requriements are satisfied, that it 
does
        /// not conflict with already-present modules, isn't already loaded, 
etc.
-       bool moduleCanBeAdded(std::string const & modName, 
+       bool moduleCanBeAdded(std::string const & modName,
+                       LayoutFile const * const lay) const;
+       /// Like !moduleCanBeAdded(), but does not check requirements
+       bool moduleConflicts(std::string const & modName,
                        LayoutFile const * const lay) const;
        /// If the user changes the base class for a given document, then the
        /// associated module list has to be updated. This just calls
diff --git a/src/tex2lyx/Makefile.am b/src/tex2lyx/Makefile.am
index b0be0af..1c296a7 100644
--- a/src/tex2lyx/Makefile.am
+++ b/src/tex2lyx/Makefile.am
@@ -28,6 +28,7 @@ TEST_FILES = \
        test/foo.png \
        test/test-insets.tex \
        test/test.ltx \
+       test/test-modules.tex \
        test/test-structure.tex \
        test/XeTeX-polyglossia.tex \
        test/xfigtest.fig \
diff --git a/src/tex2lyx/Preamble.cpp b/src/tex2lyx/Preamble.cpp
index 430708c..a567426 100644
--- a/src/tex2lyx/Preamble.cpp
+++ b/src/tex2lyx/Preamble.cpp
@@ -1428,6 +1428,22 @@ void Preamble::parse(Parser & p, string const & 
forceclass,
 
                }
 
+               else if (t.cs() == "newtheorem") {
+                       string const name = p.getArg('{', '}');
+                       string const opt1 = p.getFullOpt();
+                       string const opt2 = p.getFullOpt();
+                       string const body = p.verbatim_item();
+                       string const opt3 = p.getFullOpt();
+
+                       add_known_theorem(name, opt1, !opt2.empty(),
+                               from_utf8("\\newtheorem{" + name + '}' +
+                                         opt1 + opt2 + '{' + body + '}' + 
opt3));
+
+                       if (!in_lyx_preamble)
+                               h_preamble << "\\newtheorem{" << name << '}'
+                                          << opt1 << opt2 << '{' << '}' << 
opt3;
+               }
+
                else if (t.cs() == "def") {
                        string name = p.get_token().cs();
                        // In fact, name may be more than the name:
diff --git a/src/tex2lyx/test/CMakeLists.txt b/src/tex2lyx/test/CMakeLists.txt
index 365d953..5e1cd31 100644
--- a/src/tex2lyx/test/CMakeLists.txt
+++ b/src/tex2lyx/test/CMakeLists.txt
@@ -9,7 +9,7 @@ project(test)
 set(_test_depend "test.ltx")
 set(_test_output)
 
-foreach(_arg test-structure test-insets box-color-size-space-align CJK 
XeTeX-polyglossia)
+foreach(_arg test-structure test-insets test-modules 
box-color-size-space-align CJK XeTeX-polyglossia)
   list(APPEND _test_depend "${TOP_SRC_DIR}/src/tex2lyx/test/${_arg}.tex")
   list(APPEND _test_output "${CMAKE_CURRENT_BINARY_DIR}/${_arg}.lyx.tex")
   list(APPEND _test_output "${CMAKE_CURRENT_BINARY_DIR}/${_arg}.lyx.lyx")
diff --git a/src/tex2lyx/test/runtests.py b/src/tex2lyx/test/runtests.py
index 094f5d6..13d62f6 100755
--- a/src/tex2lyx/test/runtests.py
+++ b/src/tex2lyx/test/runtests.py
@@ -46,8 +46,8 @@ def main(argv):
         outputdir = os.path.join(os.path.dirname(tex2lyx), "test")
 
     files = ['test.ltx', 'test-structure.tex', 'test-insets.tex', \
-             'box-color-size-space-align.tex', 'CJK.tex', \
-             'XeTeX-polyglossia.tex']
+             'test-modules.tex', 'box-color-size-space-align.tex', \
+             'CJK.tex', 'XeTeX-polyglossia.tex']
 
     errors = []
     overwrite = (outputdir == inputdir)
diff --git a/src/tex2lyx/test/test-modules.lyx.lyx 
b/src/tex2lyx/test/test-modules.lyx.lyx
new file mode 100644
index 0000000..89297fd
--- /dev/null
+++ b/src/tex2lyx/test/test-modules.lyx.lyx
@@ -0,0 +1,156 @@
+#LyX file created by tex2lyx 2.1.0dev
+\lyxformat 445
+\begin_document
+\begin_header
+\textclass amsart
+\begin_preamble
+\usepackage{babel}
+
+\end_preamble
+\use_default_options false
+\begin_modules
+theorems-ams
+\end_modules
+\maintain_unincluded_children false
+\language english
+\language_package default
+\inputencoding latin9
+\fontencoding T1
+\font_roman default
+\font_sans default
+\font_typewriter default
+\font_math auto
+\font_default_family default
+\use_non_tex_fonts false
+\font_sc false
+\font_osf false
+\font_sf_scale 100
+\font_tt_scale 100
+\graphics default
+\default_output_format default
+\output_sync 0
+\bibtex_command default
+\index_command default
+\paperfontsize default
+\spacing single
+\use_hyperref false
+\papersize default
+\use_geometry false
+\use_package amsmath 1
+\use_package amssymb 0
+\use_package esint 1
+\use_package mathdots 0
+\use_package mathtools 0
+\use_package mhchem 0
+\use_package undertilde 0
+\cite_engine basic
+\cite_engine_type numerical
+\biblio_style plain
+\use_bibtopic false
+\use_indices false
+\paperorientation portrait
+\suppress_date false
+\justification true
+\use_refstyle 0
+\index Index
+\shortcut idx
+\color #008000
+\end_index
+\secnumdepth 3
+\tocdepth 3
+\paragraph_separation indent
+\paragraph_indentation default
+\quotes_language english
+\papercolumns 1
+\papersides 1
+\paperpagestyle default
+\tracking_changes false
+\output_changes false
+\html_math_output 0
+\html_css_as_file 0
+\html_be_strict false
+\end_header
+
+\begin_body
+
+\begin_layout Standard
+
+This is a dummy file
+\end_layout
+
+\begin_layout Standard
+
+It has a theorem, a lemma and a proof.
+\end_layout
+
+\begin_layout Standard
+
+The theorem is recognized is a style provided by the module theorems-ams, 
since the preamble code matches.
+\end_layout
+
+\begin_layout Standard
+
+The lemma is not recognized as a command provided by a module, since the 
preamble code is from an older version of 
+\begin_inset ERT
+status collapsed
+
+\begin_layout Standard
+
+LyX
+\end_layout
+
+\end_inset
+
+, and modules are only loaded if the preamble code matches (otherwise you 
could easily get completely different output for some often used names like 
+\backslash
+theorem.
+\end_layout
+
+\begin_layout Standard
+
+The proof is recognized as a builtin style provided by the text class.
+\end_layout
+
+\begin_layout Standard
+
+
+\begin_inset ERT
+status collapsed
+
+\begin_layout Standard
+
+
+\backslash
+begin{lem}
+\end_layout
+
+\end_inset
+
+ this is a lemma
+\begin_inset ERT
+status collapsed
+
+\begin_layout Standard
+
+
+\backslash
+end{lem}
+\end_layout
+
+\end_inset
+
+ 
+\end_layout
+
+\begin_layout Theorem
+
+this is the theorem
+\end_layout
+
+\begin_layout Proof
+
+this is the proof 
+\end_layout
+
+\end_body
+\end_document
diff --git a/src/tex2lyx/test/test-modules.tex 
b/src/tex2lyx/test/test-modules.tex
new file mode 100644
index 0000000..b27ada9
--- /dev/null
+++ b/src/tex2lyx/test/test-modules.tex
@@ -0,0 +1,43 @@
+%% LyX 1.6.1 created this file.  For more info, see http://www.lyx.org/.
+%% Do not edit unless you really know what you are doing.
+\documentclass[oneside,english]{amsart}
+\usepackage[T1]{fontenc}
+\usepackage[latin9]{inputenc}
+\usepackage{amsthm}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Textclass specific LaTeX commands.
+\numberwithin{equation}{section} %% Comment out for sequentially-numbered
+\numberwithin{figure}{section} %% Comment out for sequentially-numbered
+\providecommand{\theoremname}{Theorem}
+\theoremstyle{plain}
+\theoremstyle{plain}
+\newtheorem{thm}{\protect\theoremname}
+  \theoremstyle{plain}
+  \newtheorem{lem}[thm]{Lemma}
+
+\usepackage{babel}
+
+\begin{document}
+This is a dummy file
+
+It has a theorem, a lemma and a proof.
+
+The theorem is recognized is a style provided by the module theorems-ams,
+since the preamble code matches.
+
+The lemma is not recognized as a command provided by a module, since the
+preamble code is from an older version of LyX, and modules are only loaded
+if the preamble code matches (otherwise you could easily get completely
+different output for some often used names like \textbackslash theorem.
+
+The proof is recognized as a builtin style provided by the text class.
+
+\begin{lem}
+this is a lemma\end{lem}
+\begin{thm}
+this is the theorem\end{thm}
+\begin{proof}
+this is the proof
+\end{proof}
+
+\end{document}
diff --git a/src/tex2lyx/tex2lyx.cpp b/src/tex2lyx/tex2lyx.cpp
index 7561774..0e6afd9 100644
--- a/src/tex2lyx/tex2lyx.cpp
+++ b/src/tex2lyx/tex2lyx.cpp
@@ -36,6 +36,7 @@
 #include "support/Systemcall.h"
 
 #include <cstdlib>
+#include <algorithm>
 #include <iostream>
 #include <string>
 #include <sstream>
@@ -150,6 +151,7 @@ CommandMap known_environments;
 CommandMap known_math_environments;
 FullCommandMap possible_textclass_commands;
 FullEnvironmentMap possible_textclass_environments;
+FullCommandMap possible_textclass_theorems;
 int const LYX_FORMAT = LYX_FORMAT_TEX2LYX;
 
 /// used modules
@@ -206,6 +208,17 @@ void add_known_environment(string const & environment, 
string const & o1,
 }
 
 
+void add_known_theorem(string const & theorem, string const & o1,
+                       bool o2, docstring const & definition)
+{
+       vector<ArgumentType> arguments;
+       convertArgs(o1, o2, arguments);
+       if (!definition.empty())
+               possible_textclass_theorems[theorem] =
+                       FullCommand(arguments, definition);
+}
+
+
 Layout const * findLayoutWithoutModule(TextClass const & textclass,
                                        string const & name, bool command)
 {
@@ -239,6 +252,69 @@ namespace {
 
 typedef map<string, DocumentClassPtr> ModuleMap;
 ModuleMap modules;
+
+
+bool addModule(string const module, LayoutFile const & baseClass, 
LayoutModuleList & m, vector<string> & visited)
+{
+       // avoid endless loop for circular dependency
+       vector<string>::const_iterator const vb = visited.begin();
+       vector<string>::const_iterator const ve = visited.end();
+       if (find(vb, ve, module) != ve) {
+               cerr << "Circular dependency detected for module " << module << 
'\n';
+               return false;
+       }
+       LyXModule const * const lm = theModuleList[module];
+       if (!lm) {
+               cerr << "Could not find module " << module << " in module 
list.\n";
+               return false;
+       }
+       bool foundone = false;
+       LayoutModuleList::const_iterator const exclmodstart = 
baseClass.excludedModules().begin();
+       LayoutModuleList::const_iterator const exclmodend = 
baseClass.excludedModules().end();
+       LayoutModuleList::const_iterator const provmodstart = 
baseClass.providedModules().begin();
+       LayoutModuleList::const_iterator const provmodend = 
baseClass.providedModules().end();
+       vector<string> const reqs = lm->getRequiredModules();
+       if (reqs.empty())
+               foundone = true;
+       else {
+               LayoutModuleList::const_iterator mit = m.begin();
+               LayoutModuleList::const_iterator men = m.end();
+               vector<string>::const_iterator rit = reqs.begin();
+               vector<string>::const_iterator ren = reqs.end();
+               for (; rit != ren; ++rit) {
+                       if (find(mit, men, *rit) != men) {
+                               foundone = true;
+                               break;
+                       }
+                       if (find(provmodstart, provmodend, *rit) != provmodend) 
{
+                               foundone = true;
+                               break;
+                       }
+               }
+               if (!foundone) {
+                       visited.push_back(module);
+                       for (rit = reqs.begin(); rit != ren; ++rit) {
+                               if (find(exclmodstart, exclmodend, *rit) == 
exclmodend) {
+                                       if (addModule(*rit, baseClass, m, 
visited)) {
+                                               foundone = true;
+                                               break;
+                                       }
+                               }
+                       }
+                       visited.pop_back();
+               }
+       }
+       if (!foundone) {
+               cerr << "Could not add required modules for " << module << 
".\n";
+               return false;
+       }
+       if (!m.moduleCanBeAdded(module, &baseClass))
+               return false;
+       m.push_back(module);
+       return true;
+}
+
+
 void initModules()
 {
        // Create list of dummy document classes if not already done.
@@ -253,10 +329,9 @@ void initModules()
                for (; it != end; ++it) {
                        string const module = it->getID();
                        LayoutModuleList m;
-                       // FIXME this excludes all modules that depend on 
another one
-                       if (!m.moduleCanBeAdded(module, &baseClass))
+                       vector<string> v;
+                       if (!addModule(module, baseClass, m, v))
                                continue;
-                       m.push_back(module);
                        modules[module] = getDocumentClass(baseClass, m);
                }
                init = false;
@@ -292,12 +367,17 @@ bool checkModule(string const & name, bool command)
        static set<string> failed[2];
 
        // Only add the module if the command was actually defined in the LyX 
preamble
+       bool theorem = false;
        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 (possible_textclass_environments.find(name) == 
possible_textclass_environments.end()) {
+                       if (possible_textclass_theorems.find(name) != 
possible_textclass_theorems.end())
+                               theorem = true;
+                       else
+                               return false;
+               }
        }
        if (failed[command].find(name) != failed[command].end())
                return false;
@@ -315,7 +395,7 @@ bool checkModule(string const & name, bool command)
        ModuleMap::iterator const end = modules.end();
        for (ModuleMap::iterator it = modules.begin(); it != end; ++it) {
                string const module = it->first;
-               if (!used_modules.moduleCanBeAdded(module, &baseClass))
+               if (used_modules.moduleConflicts(module, &baseClass))
                        continue;
                if (findLayoutWithoutModule(textclass, name, command))
                        continue;
@@ -338,6 +418,11 @@ bool checkModule(string const & name, bool command)
                                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];
@@ -756,6 +841,12 @@ bool tex2lyx(idocstream & is, ostream & os, string 
encoding)
        //p.dump();
 
        preamble.parse(p, documentclass, textclass);
+       list<string> removed_modules;
+       LayoutFile const & baseClass = LayoutFileList::get()[textclass.name()];
+       if (!used_modules.adaptToBaseClass(&baseClass, removed_modules)) {
+               cerr << "Could not load default modules for text class." << 
endl;
+               return false;
+       }
 
        // Load preloaded modules.
        // This needs to be done after the preamble is parsed, since the text
@@ -795,7 +886,7 @@ bool tex2lyx(idocstream & is, ostream & os, string encoding)
                        preamble.addModule(*it);
        }
        if (!preamble.writeLyXHeader(os, !active_environments.empty())) {
-               cerr << "Could write LyX file header." << endl;
+               cerr << "Could not write LyX file header." << endl;
                return false;
        }
 
diff --git a/src/tex2lyx/tex2lyx.h b/src/tex2lyx/tex2lyx.h
index 37585fd..e3da48b 100644
--- a/src/tex2lyx/tex2lyx.h
+++ b/src/tex2lyx/tex2lyx.h
@@ -106,6 +106,8 @@ void add_known_command(std::string const & command, 
std::string const & o1,
 extern void add_known_environment(std::string const & environment,
        std::string const & o1, bool o2, docstring const & beg,
        docstring const & end);
+extern void add_known_theorem(std::string const & theorem,
+       std::string const & o1, bool o2, docstring const & definition);
 extern Layout const * findLayoutWithoutModule(TextClass const & textclass,
        std::string const & name, bool command);
 extern InsetLayout const * findInsetLayoutWithoutModule(
@@ -164,6 +166,8 @@ extern CommandMap known_math_environments;
 extern FullCommandMap possible_textclass_commands;
 /// Environments that might be defined by the document class or modules
 extern FullEnvironmentMap possible_textclass_environments;
+/// Theorems that might be defined by the document class or modules
+extern FullCommandMap possible_textclass_theorems;
 ///
 extern bool noweb_mode;
 /// Did we recognize any pdflatex-only construct?

-----------------------------------------------------------------------

Summary of changes:
 src/LayoutModuleList.cpp                           |   49 +++++---
 src/LayoutModuleList.h                             |    5 +-
 src/tex2lyx/Makefile.am                            |    1 +
 src/tex2lyx/Preamble.cpp                           |   16 +++
 src/tex2lyx/test/CMakeLists.txt                    |    2 +-
 src/tex2lyx/test/runtests.py                       |    4 +-
 ...eX-polyglossia.lyx.lyx => test-modules.lyx.lyx} |  127 +++++++-------------
 src/tex2lyx/test/test-modules.tex                  |   43 +++++++
 src/tex2lyx/tex2lyx.cpp                            |  105 +++++++++++++++-
 src/tex2lyx/tex2lyx.h                              |    4 +
 10 files changed, 242 insertions(+), 114 deletions(-)
 copy src/tex2lyx/test/{XeTeX-polyglossia.lyx.lyx => test-modules.lyx.lyx} (64%)
 create mode 100644 src/tex2lyx/test/test-modules.tex


hooks/post-receive
-- 
The LyX Source Repository

Reply via email to