]> git.lyx.org Git - lyx.git/blobdiff - src/LayoutFile.cpp
use lfun
[lyx.git] / src / LayoutFile.cpp
index 42b74fc62bb145727baf93760bbb5e00b7abed4f..88a4cf63f57a26e56807702fced1997823b38fb4 100644 (file)
@@ -3,7 +3,7 @@
  * This file is part of LyX, the document processor.
  * Licence details can be found in the file COPYING.
  *
- * \author Lars Gullik Bjønnes
+ * \author Lars Gullik Bjønnes
  * \author John Levon
  *
  * Full author contact details are available in file CREDITS.
 #include "Lexer.h"
 #include "TextClass.h"
 
+#include "frontends/alert.h"
+
 #include "support/debug.h"
 #include "support/FileName.h"
 #include "support/filetools.h"
 #include "support/gettext.h"
+#include "support/lassert.h"
+#include "support/lstrings.h"
 
 #include <boost/bind.hpp>
 #include <boost/regex.hpp>
@@ -46,6 +50,14 @@ LayoutFile::LayoutFile(string const & fn, string const & cln,
        texClassAvail_ = texClassAvail;
 }
 
+LayoutFileList::~LayoutFileList()
+{
+       ClassMap::const_iterator it = classmap_.begin();
+       ClassMap::const_iterator en = classmap_.end();
+       for (; it != en; ++it) {
+               delete it->second;
+       }
+}
 
 LayoutFileList & LayoutFileList::get() 
 {
@@ -68,15 +80,14 @@ bool LayoutFileList::haveClass(string const & classname) const
 
 LayoutFile const & LayoutFileList::operator[](string const & classname) const
 {
-       BOOST_ASSERT(haveClass(classname));
+       LASSERT(haveClass(classname), /**/);
        return *classmap_[classname];
 }
 
 
-LayoutFile & 
-       LayoutFileList::operator[](string const & classname)
+LayoutFile & LayoutFileList::operator[](string const & classname)
 {
-       BOOST_ASSERT(haveClass(classname));
+       LASSERT(haveClass(classname), /**/);
        return *classmap_[classname];
 }
 
@@ -128,27 +139,27 @@ bool LayoutFileList::read()
                default:
                        string const fname = lex.getString();
                        LYXERR(Debug::TCLASS, "Fname: " << fname);
-                       if (lex.next()) {
-                               string const clname = lex.getString();
-                               LYXERR(Debug::TCLASS, "Clname: " << clname);
-                               if (lex.next()) {
-                                       string const desc = lex.getString();
-                                       LYXERR(Debug::TCLASS, "Desc: " << desc);
-                                       if (lex.next()) {
-                                               bool avail = lex.getBool();
-                                               LYXERR(Debug::TCLASS, "Avail: " << avail);
-                                               // This code is run when we have
-                                               // fname, clname, desc, and avail
-                                               LayoutFile * tmpl = new LayoutFile(fname, clname, desc, avail);
-                                               if (lyxerr.debugging(Debug::TCLASS)) {
-                                                       // only system layout files are loaded here so no
-                                                       // buffer path is needed.
-                                                       tmpl->load();
-                                               }
-                                               classmap_[fname] = tmpl;
-                                       }
-                               }
+                       if (!lex.next()) 
+                               break;
+                       string const clname = lex.getString();
+                       LYXERR(Debug::TCLASS, "Clname: " << clname);
+                       if (!lex.next()) 
+                               break;
+                       string const desc = lex.getString();
+                       LYXERR(Debug::TCLASS, "Desc: " << desc);
+                       if (!lex.next()) 
+                               break;
+                       bool avail = lex.getBool();
+                       LYXERR(Debug::TCLASS, "Avail: " << avail);
+                       // This code is run when we have
+                       // fname, clname, desc, and avail
+                       LayoutFile * tmpl = new LayoutFile(fname, clname, desc, avail);
+                       if (lyxerr.debugging(Debug::TCLASS)) {
+                               // only system layout files are loaded here so no
+                               // buffer path is needed.
+                               tmpl->load();
                        }
+                       classmap_[fname] = tmpl;
                }
        }
        LYXERR(Debug::TCLASS, "End of parsing of textclass.lst");
@@ -175,7 +186,7 @@ std::vector<LayoutFileIndex> LayoutFileList::classList() const
 
 
 void LayoutFileList::reset(LayoutFileIndex const & classname) {
-       BOOST_ASSERT(haveClass(classname));
+       LASSERT(haveClass(classname), /**/);
        LayoutFile * tc = classmap_[classname];
        LayoutFile * tmpl = 
                new LayoutFile(tc->name(), tc->latexname(), tc->description(),
@@ -185,13 +196,51 @@ void LayoutFileList::reset(LayoutFileIndex const & classname) {
 }
 
 
-string const LayoutFileList::localPrefix = "LOCAL:";
-string const LayoutFileList::embeddedPrefix = "EMBED:";
+LayoutFileIndex LayoutFileList::addEmptyClass(string const & textclass)
+{
+       if (haveClass(textclass))
+               return textclass;
+
+       FileName const tempLayout = FileName::tempName();
+       ofstream ofs(tempLayout.toFilesystemEncoding().c_str());
+       ofs << "# This layout is automatically generated\n"
+               "# \\DeclareLaTeXClass{" << textclass << "}\n\n"
+               "Format         7\n"
+               "Input stdclass.inc\n\n"
+               "Columns                1\n"
+               "Sides                  1\n"
+               "SecNumDepth    2\n"
+               "TocDepth               2\n"
+               "DefaultStyle   Standard\n\n"
+               "Style Standard\n"
+               "       Category              MainText\n"
+               "       Margin                Static\n"
+               "       LatexType             Paragraph\n"
+               "       LatexName             dummy\n"
+               "       ParIndent             MM\n"
+               "       ParSkip               0.4\n"
+               "       Align                 Block\n"
+               "       AlignPossible         Block, Left, Right, Center\n"
+               "       LabelType             No_Label\n"
+               "End\n";
+       ofs.close();
+
+       // We do not know if a LaTeX class is available for this document, but setting
+       // the last parameter to true will suppress a warning message about missing
+       // tex class.
+       LayoutFile * tc = new LayoutFile(textclass, textclass, "Unknown text class " + textclass, true);
+       if (!tc->load(tempLayout.absFilename())) {
+               // The only way this happens is because the hardcoded layout file above
+               // is wrong.
+               LASSERT(false, /**/);
+       }
+       classmap_[textclass] = tc;
+       return textclass;
+}
 
 
 LayoutFileIndex 
-       LayoutFileList::addLayoutFile(string const & textclass, string const & path,
-               Layout_Type type)
+       LayoutFileList::addLocalLayout(string const & textclass, string const & path)
 {
        // FIXME  There is a bug here: 4593
        //
@@ -199,17 +248,7 @@ LayoutFileIndex
        // NOTE: latex class name is defined in textclass.layout, which can be 
        // different from textclass
        string fullName = addName(path, textclass + ".layout");
-       string localIndex;
-       
-       if (type == Local)
-               localIndex = localPrefix + fullName;
-       else if (type == Embedded)
-               localIndex = embeddedPrefix + textclass;
        
-       // if the local file has already been loaded, return it
-       if (haveClass(localIndex))
-               return localIndex;
-
        FileName const layout_file(fullName);
        if (layout_file.exists()) {
                LYXERR(Debug::TCLASS, "Adding class " << textclass << " from directory " << path);
@@ -227,17 +266,23 @@ LayoutFileIndex
                        smatch sub;
                        if (regex_match(line, sub, reg)) {
                                // returns: whole string, classtype (not used here), class name, description
-                               BOOST_ASSERT(sub.size() == 4);
+                               LASSERT(sub.size() == 4, /**/);
                                // now, create a TextClass with description containing path information
                                string className(sub.str(2) == "" ? textclass : sub.str(2));
                                LayoutFile * tmpl = 
-                                       new LayoutFile(textclass, className, localIndex, true);
+                                       new LayoutFile(textclass, className, textclass, true);
                                // This textclass is added on request so it will definitely be
                                // used. Load it now because other load() calls may fail if they
                                // are called in a context without buffer path information.
                                tmpl->load(path);
-                               classmap_[localIndex] = tmpl;
-                               return localIndex;
+                               // There will be only one textclass with this name, even if different
+                               // layout files are loaded from different directories.
+                               if (haveClass(textclass)) {
+                                       LYXERR0("Existing textclass " << textclass << " is redefined by " << fullName);
+                                       delete classmap_[textclass];
+                               }
+                               classmap_[textclass] = tmpl;
+                               return textclass;
                        }
                }
        }
@@ -246,6 +291,24 @@ LayoutFileIndex
 }
 
 
+bool LayoutFileList::load(string const & name, string const & buf_path)
+{
+       if (!haveClass(name)) {
+               LYXERR0("Document class \"" << name << "\" does not exist.");
+               return false;
+       }
+
+       LayoutFile * tc = classmap_[name];
+       if (!tc->load(buf_path)) {
+               docstring s = bformat(_("The document class %1$s "
+                                  "could not be loaded."), from_utf8(name));
+               frontend::Alert::error(_("Could not load class"), s);
+               return false;
+       }
+       return true;
+}
+
+
 LayoutFileIndex defaultBaseclass()
 {
        if (LayoutFileList::get().haveClass("article"))