X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2FLayoutFile.cpp;h=5f2f0d3db8d4819ee106e29bae6316f1ef30e364;hb=0b791d49f52d0e0271b9f189e0561cbb314f81e1;hp=a915f7129b8236d91328676ac963bdc454841172;hpb=f9fa189e02ef0271b042cabc32f8cf90e0b54cb3;p=lyx.git diff --git a/src/LayoutFile.cpp b/src/LayoutFile.cpp index a915f7129b..5f2f0d3db8 100644 --- a/src/LayoutFile.cpp +++ b/src/LayoutFile.cpp @@ -27,8 +27,8 @@ #include "support/lassert.h" #include "support/lstrings.h" -#include -#include +#include "support/bind.h" +#include "support/regex.h" #include @@ -37,18 +37,17 @@ using namespace lyx::support; namespace lyx { -using boost::bind; -using boost::regex; -using boost::smatch; + LayoutFile::LayoutFile(string const & fn, string const & cln, - string const & desc, string const & prereq, - bool texclassavail) + string const & desc, string const & prereq, + string const & category, bool texclassavail) { name_ = fn; latexname_ = cln; description_ = desc; prerequisites_ = prereq; + category_ = category; tex_class_avail_ = texclassavail; } @@ -105,16 +104,14 @@ bool LayoutFileList::read() LYXERR(Debug::TCLASS, "Reading textclasses from `" << real_file << "'."); if (real_file.empty()) { - LYXERR0("LayoutFileList::Read: unable to find textclass file `" - << makeDisplayPath(real_file.absFilename(), 1000) - << "'."); - success = false; + LYXERR0("LayoutFileList::Read: unable to find textclass file " + << "`textclass.lst'."); } else if (!lex.setFile(real_file)) { LYXERR0("LayoutFileList::Read: lyxlex was not able to set file: " << real_file << '.'); } else if (!lex.isOK()) { LYXERR0("LayoutFileList::Read: unable to open textclass file `" - << makeDisplayPath(real_file.absFilename(), 1000) + << makeDisplayPath(real_file.absFileName(), 1000) << "'\nCheck your installation."); } else { // we have a file we can read. @@ -145,9 +142,13 @@ bool LayoutFileList::read() break; string const prereq = lex.getString(); LYXERR(Debug::TCLASS, "Prereq: " << prereq); + if (!lex.next()) + break; + string const category = lex.getString(); + LYXERR(Debug::TCLASS, "Category: " << category); // This code is run when we have // fname, clname, desc, prereq, and avail - LayoutFile * tmpl = new LayoutFile(fname, clname, desc, prereq, avail); + LayoutFile * tmpl = new LayoutFile(fname, clname, desc, prereq, category, avail); if (lyxerr.debugging(Debug::TCLASS)) { // only system layout files are loaded here so no // buffer path is needed. @@ -181,12 +182,14 @@ std::vector LayoutFileList::classList() const } -void LayoutFileList::reset(LayoutFileIndex const & classname) { +void LayoutFileList::reset(LayoutFileIndex const & classname) +{ LASSERT(haveClass(classname), /**/); LayoutFile * tc = classmap_[classname]; LayoutFile * tmpl = new LayoutFile(tc->name(), tc->latexname(), tc->description(), - tc->prerequisites(), tc->isTeXClassAvailable()); + tc->prerequisites(), tc->category(), + tc->isTeXClassAvailable()); classmap_[classname] = tmpl; delete tc; } @@ -214,15 +217,16 @@ string layoutpost = } + LayoutFileIndex LayoutFileList::addEmptyClass(string const & textclass) { - FileName const tempLayout = FileName::tempName(); + FileName const tempLayout = FileName::tempName("basic_layout"); ofstream ofs(tempLayout.toFilesystemEncoding().c_str()); // This writes a very basic class, but it also attempts to include // stdclass.inc. That would give us something moderately usable. ofs << "# This layout is automatically generated\n" "# \\DeclareLaTeXClass{" << textclass << "}\n\n" - "Format 26\n" + "Format " << LAYOUT_FORMAT << "\n" "Input stdclass.inc\n\n" << layoutpost; ofs.close(); @@ -231,20 +235,20 @@ LayoutFileIndex LayoutFileList::addEmptyClass(string const & textclass) // the last parameter to true will suppress a warning message about missing // tex class. LayoutFile * tc = new LayoutFile(textclass, textclass, - "Unknown text class " + textclass, textclass + ".cls", true); + "Unknown text class " + textclass, textclass + ".cls", "", true); - if (!tc->load(tempLayout.absFilename())) { + if (!tc->load(tempLayout.absFileName())) { // The only way this happens is because the hardcoded layout file - // aboveis wrong or stdclass.inc cannot be found. So try again - // without stdclass.inc. + // above is wrong or stdclass.inc cannot be found. So try again + // without stdclass.inc and without stdinsets.inc. ofstream ofs2(tempLayout.toFilesystemEncoding().c_str()); ofs2 << "# This layout is automatically generated\n" "# \\DeclareLaTeXClass{" << textclass << "}\n\n" - "Format 26\n" - "Input stdclass.inc\n\n" + "Format " << LAYOUT_FORMAT << "\n" + "Provides stdinsets 1\n" << layoutpost; ofs2.close(); - if (!tc->load(tempLayout.absFilename())) { + if (!tc->load(tempLayout.absFileName())) { // This can only happen if the hardcoded file above is wrong. LASSERT(false, /* */); } @@ -255,8 +259,8 @@ LayoutFileIndex LayoutFileList::addEmptyClass(string const & textclass) } -LayoutFileIndex - LayoutFileList::addLocalLayout(string const & textclass, string const & path) +LayoutFileIndex LayoutFileList::addLocalLayout( + string const & textclass, string const & path) { // FIXME There is a bug here: 4593 // @@ -276,7 +280,12 @@ LayoutFileIndex ifstream ifs(layout_file.toFilesystemEncoding().c_str()); static regex const reg("^#\\s*\\\\Declare(LaTeX|DocBook)Class\\s*" "(?:\\[([^,]*)(?:,.*)*\\])*\\s*\\{(.*)\\}\\s*"); + static regex const catreg("^#\\s*\\\\DeclareCategory\\{(.*)\\}"); string line; + string class_name; + string class_prereq; + string category; + bool have_declaration = false; while (getline(ifs, line)) { // look for the \DeclareXXXClass line smatch sub; @@ -284,29 +293,38 @@ LayoutFileIndex // returns: whole string, classtype (not used here), class name, description LASSERT(sub.size() == 4, /**/); // now, create a TextClass with description containing path information - string class_name(sub.str(2) == "" ? textclass : sub.str(2)); - string class_prereq(class_name + ".cls"); - LayoutFile * tmpl = - new LayoutFile(textclass, class_name, textclass, class_prereq, true); - //FIXME: The prerequisites are available from the layout file and - // can be extracted from the above regex, but for now this - // field is simply set to class_name + ".cls" - // 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); - // 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; + class_name = (sub.str(2) == "" ? textclass : sub.str(2)); + class_prereq = class_name + ".cls"; + have_declaration = true; } + else if (regex_match(line, sub, catreg)) { + category = sub.str(1); + } + if (have_declaration && !category.empty()) + break; + } + if (have_declaration) { + LayoutFile * tmpl = + new LayoutFile(textclass, class_name, textclass, class_prereq, category, true); + //FIXME: The prerequisites are available from the layout file and + // can be extracted from the above regex, but for now this + // field is simply set to class_name + ".cls" + // 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); + // 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; } } - // If .layout is not in local directory, or an invalid layout is found, return null + // If .layout is not in local directory, or an invalid layout + // is found, return null return string(); } @@ -319,13 +337,7 @@ bool LayoutFileList::load(string const & name, string const & buf_path) } 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; + return tc->load(buf_path); }