#include <config.h>
#include "BaseClassList.h"
-#include "TextClass.h"
+#include "Counters.h"
+#include "Floating.h"
+#include "FloatList.h"
#include "Lexer.h"
+#include "TextClass.h"
#include "support/debug.h"
#include "support/FileName.h"
#include "support/filetools.h"
+#include "support/gettext.h"
#include <boost/bind.hpp>
#include <boost/regex.hpp>
using boost::regex;
using boost::smatch;
+LayoutFile::LayoutFile(string const & fn, string const & cln,
+ string const & desc, bool texClassAvail )
+{
+ name_ = fn;
+ latexname_ = cln;
+ description_ = desc;
+ texClassAvail_ = texClassAvail;
+}
+
+
BaseClassList & BaseClassList::get()
{
static BaseClassList baseclasslist;
}
-// Gets textclass number from name
-pair<bool, BaseClassIndex> const
-BaseClassList::numberOfClass(string const & textclass) const
+bool BaseClassList::haveClass(string const & classname) const
{
- ClassList::const_iterator cit =
- find_if(classlist_.begin(), classlist_.end(),
- bind(equal_to<string>(),
- bind(&TextClass::name, _1),
- textclass));
-
- return cit != classlist_.end() ?
- make_pair(true, BaseClassIndex(cit - classlist_.begin())) :
- make_pair(false, BaseClassIndex(0));
+ ClassMap::const_iterator it = classmap_.begin();
+ ClassMap::const_iterator en = classmap_.end();
+ for (; it != en; ++it) {
+ if (it->first == classname)
+ return true;
+ }
+ return false;
}
-// Gets a textclass structure from number
-TextClass const &
-BaseClassList::operator[](BaseClassIndex textclass) const
+LayoutFile const & BaseClassList::operator[](string const & classname) const
{
- if (textclass >= classlist_.size())
- return classlist_[0];
-
- //FIXME I don't believe the following line is actually necessary (rgh)
- classlist_[textclass].load();
- return classlist_[textclass];
+ BOOST_ASSERT(haveClass(classname));
+ return classmap_[classname];
}
-// used when sorting the textclass list.
-class less_textclass_avail_desc
- : public binary_function<TextClass, TextClass, int>
+LayoutFile &
+ BaseClassList::operator[](string const & classname)
{
-public:
- int operator()(TextClass const & tc1,
- TextClass const & tc2) const
- {
- // Ordering criteria:
- // 1. Availability of text class
- // 2. Description (lexicographic)
-
- return (tc1.isTeXClassAvailable() && !tc2.isTeXClassAvailable()) ||
- (tc1.isTeXClassAvailable() == tc2.isTeXClassAvailable() &&
- tc1.description() < tc2.description());
- }
-};
+ BOOST_ASSERT(haveClass(classname));
+ return classmap_[classname];
+}
// Reads LyX textclass definitions according to textclass config file
LYXERR(Debug::TCLASS, "Avail: " << avail);
// This code is run when we have
// fname, clname, desc, and avail
- TextClass tmpl(fname, clname, desc, avail);
+ LayoutFile tmpl(fname, clname, desc, avail);
if (lyxerr.debugging(Debug::TCLASS)) {
// only system layout files are loaded here so no
// buffer path is needed.
tmpl.load();
}
- classlist_.push_back(tmpl);
+ classmap_[fname] = tmpl;
}
}
}
}
LYXERR(Debug::TCLASS, "End of parsing of textclass.lst");
- // lyx will start with an empty classlist_, but only reconfigure is allowed
+ // lyx will start with an empty classmap_, but only reconfigure is allowed
// in this case. This gives users a second chance to configure lyx if
// initial configuration fails. (c.f. bug 2829)
- if (classlist_.empty())
+ if (classmap_.empty())
lyxerr << "BaseClassList::Read: no textclasses found!"
<< endl;
- else
- // Ok everything loaded ok, now sort the list.
- sort(classlist_.begin(), classlist_.end(), less_textclass_avail_desc());
return true;
}
-void BaseClassList::reset(BaseClassIndex const textclass) {
- if (textclass >= classlist_.size())
- return;
- TextClass const & tc = classlist_[textclass];
- TextClass tmpl(tc.name(), tc.latexname(), tc.description(),
+std::vector<LayoutFileIndex> BaseClassList::classList() const
+{
+ std::vector<LayoutFileIndex> cl;
+ ClassMap::const_iterator it = classmap_.begin();
+ ClassMap::const_iterator en = classmap_.end();
+ for (; it != en; ++it)
+ cl.push_back(it->first);
+ return cl;
+}
+
+
+void BaseClassList::reset(LayoutFileIndex const & classname) {
+ BOOST_ASSERT(haveClass(classname));
+ LayoutFile const & tc = classmap_[classname];
+ LayoutFile tmpl(tc.name(), tc.latexname(), tc.description(),
tc.isTeXClassAvailable());
- classlist_[textclass] = tmpl;
+ classmap_[classname] = tmpl;
}
-pair<bool, BaseClassIndex> const
-BaseClassList::addTextClass(string const & textclass, string const & path)
+string const BaseClassList::localPrefix = "LOCAL:";
+
+
+LayoutFileIndex
+ BaseClassList::addLayoutFile(string const & textclass, string const & path)
{
+ // FIXME There is a bug here: 4593
+ //
// only check for textclass.layout file, .cls can be anywhere in $TEXINPUTS
- // NOTE: latex class name is defined in textclass.layout, which can be different from textclass
- FileName const layout_file(addName(path, textclass + ".layout"));
+ // NOTE: latex class name is defined in textclass.layout, which can be
+ // different from textclass
+ string fullName = addName(path, textclass + ".layout");
+ string localIndex = localPrefix + fullName;
+
+ // 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);
// Read .layout file and get description, real latex classname etc
// returns: whole string, classtype (not used here), class name, description
BOOST_ASSERT(sub.size() == 4);
// now, create a TextClass with description containing path information
- TextClass tmpl(textclass, sub.str(2) == "" ? textclass : sub.str(2),
+ LayoutFile tmpl(textclass, sub.str(2) == "" ? textclass : sub.str(2),
sub.str(3) + " <" + path + ">", true);
- if (lyxerr.debugging(Debug::TCLASS))
- tmpl.load(path);
- // Do not add this local TextClass to classlist_ if it has
- // already been loaded by, for example, a master buffer.
- pair<bool, lyx::BaseClassIndex> pp = numberOfClass(textclass);
- // only layouts from the same directory are considered to be identical.
- if (pp.first && classlist_[pp.second].description() == tmpl.description())
- return pp;
- classlist_.push_back(tmpl);
+ classmap_[localIndex] = tmpl;
// 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.
- classlist_.back().load(path);
- return make_pair(true, classlist_.size() - 1);
+ classmap_[localIndex].load(path);
+ return localIndex;
}
}
}
- // If .layout is not in local directory, or an invalid layout is found, return false
- return make_pair(false, BaseClassIndex(0));
+ // If .layout is not in local directory, or an invalid layout is found, return null
+ return string();
}
-
-BaseClassIndex defaultBaseclass()
+LayoutFileIndex defaultBaseclass()
{
- // We want to return the article class. if `first' is
- // true in the returned pair, then `second' is the textclass
- // number; if it is false, second is 0. In both cases, second
- // is what we want.
- return BaseClassList::get().numberOfClass("article").second;
+ if (BaseClassList::get().haveClass("article"))
+ return string("article");
+ if (BaseClassList::get().empty())
+ return string();
+ return BaseClassList::get().classList().front();
}