From: Bo Peng Date: Sun, 9 Apr 2006 04:35:24 +0000 (+0000) Subject: First patch for auto-cls-layout feature, from Bo Peng (ben.bob@gmail.com) X-Git-Tag: 1.6.10~13372 X-Git-Url: https://git.lyx.org/gitweb/?a=commitdiff_plain;h=2b82051a8191e7095631801dd18cc0178bfad756;p=features.git First patch for auto-cls-layout feature, from Bo Peng (ben.bob@gmail.com) layout file in the same directory as .lyx file will be used. .cls can also be in this directory. * src/buffer.C, bufferparams.C: move filepath to bufferparams so this info will be available in getToken() * src/lyxtextclasslist.h, .C: add addTextClass() that read a .layout file from filepath. * src/lyxtextclass.h, .C: pass filepath to LyXTextClass::load(). .layout file in filepath will be loaded before system ones. git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@13611 a592a061-630c-0410-9148-cb99ea01b6c8 --- diff --git a/src/buffer.C b/src/buffer.C index a4d257ee9f..2375a9b11d 100644 --- a/src/buffer.C +++ b/src/buffer.C @@ -182,9 +182,6 @@ public: /// name of the file the buffer is associated with. string filename; - /// The path to the document file. - string filepath; - boost::scoped_ptr messages; /** Set to true only when the file is fully loaded. @@ -203,12 +200,13 @@ public: Buffer::Impl::Impl(Buffer & parent, string const & file, bool readonly_) : lyx_clean(true), bak_clean(true), unnamed(false), read_only(readonly_), - filename(file), filepath(onlyPath(file)), file_fully_loaded(false), + filename(file), file_fully_loaded(false), inset(params) { inset.setAutoBreakRows(true); lyxvc.buffer(&parent); temppath = createBufferTmpDir(); + params.filepath = onlyPath(file); // FIXME: And now do something if temppath == string(), because we // assume from now on that temppath points to a valid temp dir. // See http://www.mail-archive.com/lyx-devel@lists.lyx.org/msg67406.html @@ -378,7 +376,7 @@ void Buffer::setReadonly(bool const flag) void Buffer::setFileName(string const & newfile) { pimpl_->filename = makeAbsPath(newfile); - pimpl_->filepath = onlyPath(pimpl_->filename); + params().filepath = onlyPath(pimpl_->filename); setReadonly(fs::is_readonly(pimpl_->filename)); updateTitles(); } @@ -476,7 +474,7 @@ bool Buffer::readDocument(LyXLex & lex) BOOST_ASSERT(paragraphs().empty()); readHeader(lex); - if (!params().getLyXTextClass().load()) { + if (!params().getLyXTextClass().load(filePath())) { string theclass = params().getLyXTextClass().name(); Alert::error(_("Can't load document class"), bformat( "Using the default document class, because the " @@ -1468,7 +1466,7 @@ string const & Buffer::fileName() const string const & Buffer::filePath() const { - return pimpl_->filepath; + return params().filepath; } diff --git a/src/bufferparams.C b/src/bufferparams.C index 8c48aaf9f8..924b7e2698 100644 --- a/src/bufferparams.C +++ b/src/bufferparams.C @@ -406,9 +406,18 @@ string const BufferParams::readToken(LyXLex & lex, string const & token) if (pp.first) { textclass = pp.second; } else { - textclass = 0; - return classname; + // if text class does not exist, try to load it from filepath + pp = textclasslist.addTextClass(classname, filepath); + if (pp.first) { + textclass = pp.second; + } else { + textclass = 0; + return classname; + } } + // FIXME: isTeXClassAvailable will try to load the layout file, but will + // fail because of the lack of path info. Warnings will be given although + // the layout file will be correctly loaded later. if (!getLyXTextClass().isTeXClassAvailable()) { string const msg = bformat(_("The document uses a missing " diff --git a/src/bufferparams.h b/src/bufferparams.h index 5951f83011..bfbaf7c936 100644 --- a/src/bufferparams.h +++ b/src/bufferparams.h @@ -230,6 +230,8 @@ public: std::string const paperSizeName() const; /// std::string const babelCall(std::string const & lang_opts) const; + /// path of the current buffer + std::string filepath; private: /** Use the Pimpl idiom to hide those member variables that would otherwise diff --git a/src/lyxtextclass.C b/src/lyxtextclass.C index 0e2e964501..1790d979b6 100644 --- a/src/lyxtextclass.C +++ b/src/lyxtextclass.C @@ -24,6 +24,8 @@ #include "support/lstrings.h" #include "support/lyxlib.h" #include "support/filetools.h" +#include +namespace fs = boost::filesystem; #include @@ -910,13 +912,15 @@ bool LyXTextClass::delete_layout(string const & name) // Load textclass info if not loaded yet -bool LyXTextClass::load() const +bool LyXTextClass::load(string const & path) const { if (loaded_) return true; - // Read style-file - string const real_file = libFileSearch("layouts", name_, "layout"); + // Read style-file, current directory is searched before system ones + string real_file = path + "/" + name_ + ".layout"; + if (!fs::exists(real_file)) + real_file = libFileSearch("layouts", name_, "layout"); loaded_ = const_cast(this)->read(real_file) == 0; if (!loaded_) { diff --git a/src/lyxtextclass.h b/src/lyxtextclass.h index a878b25eff..7d34e5032c 100644 --- a/src/lyxtextclass.h +++ b/src/lyxtextclass.h @@ -84,7 +84,7 @@ public: LyXLayout_ptr const & operator[](std::string const & vname) const; /// Sees to that the textclass structure has been loaded - bool load() const; + bool load(std::string const & path=".") const; /// Has this layout file been loaded yet? bool loaded() const { return loaded_; } diff --git a/src/lyxtextclasslist.C b/src/lyxtextclasslist.C index 5887c72aee..d0be70ff77 100644 --- a/src/lyxtextclasslist.C +++ b/src/lyxtextclasslist.C @@ -19,6 +19,10 @@ #include "support/filetools.h" #include +#include +#include +#include +namespace fs = boost::filesystem; using lyx::textclass_type; @@ -26,6 +30,8 @@ using lyx::support::libFileSearch; using lyx::support::makeDisplayPath; using boost::bind; +using boost::regex; +using boost::smatch; #ifndef CXX_GLOBAL_CSTD using std::exit; @@ -38,6 +44,7 @@ using std::make_pair; using std::sort; using std::string; using std::pair; +using std::ifstream; // Gets textclass number from name @@ -167,6 +174,44 @@ bool LyXTextClassList::read() } +std::pair const +LyXTextClassList::addTextClass(std::string const & textclass, std::string const & path) +{ + // 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 + string layout_file = path + "/" + textclass + ".layout"; + if (fs::exists(layout_file)) { + lyxerr[Debug::TCLASS] << "Adding class " << textclass << " from directory " << path << endl; + // Read .layout file and get description, real latex classname etc + // + // This is a C++ version of function processLayoutFile in configure.py, + // which uses the following regex + // \Declare(LaTeX|DocBook|LinuxDoc)Class\s*(\[([^,]*)(,.*)*\])*\s*{(.*)} + ifstream ifs(layout_file.c_str()); + static regex const reg("^#\\s*\\\\Declare(LaTeX|DocBook|LinuxDoc)Class\\s*" + "(?:\\[([^,]*)(?:,.*)*\\])*\\s*\\{(.*)\\}\\s*"); + string line; + while (getline(ifs, line)) { + // look for the \DeclareXXXClass line + smatch sub; + if (regex_match(line, sub, reg)) { + // returns: whole string, classtype (not used here), first option, description + BOOST_ASSERT(sub.size()==4); + // now, add the layout to textclass. + LyXTextClass tmpl(textclass, sub.str(2)==""?textclass:sub.str(2), + sub.str(3) + " <" + path + ">", true); + if (lyxerr.debugging(Debug::TCLASS)) + tmpl.load(path); + classlist_.push_back(tmpl); + return make_pair(true, classlist_.size() - 1); + } + } + } + // If .layout is not in local directory, or an invalid layout is found, return false + return make_pair(false, textclass_type(0)); +} + + // Global variable: textclass table. LyXTextClassList textclasslist; diff --git a/src/lyxtextclasslist.h b/src/lyxtextclasslist.h index 80ac1de17b..9bea70bde5 100644 --- a/src/lyxtextclasslist.h +++ b/src/lyxtextclasslist.h @@ -47,6 +47,12 @@ public: /// Read textclass list. Returns false if this fails. bool read(); + + /// add a textclass from user local directory. + /// Return ture/false, and textclass number + std::pair const + addTextClass(std::string const & textclass, std::string const & path); + private: /// mutable ClassList classlist_;