#include "FloatList.h"
#include "support/lstrings.h"
+#include "support/lyxlib.h"
#include "support/filetools.h"
+#include "support/os.h"
-using lyx::support::LibFileSearch;
-using lyx::support::MakeDisplayPath;
+#include <boost/filesystem/operations.hpp>
+namespace fs = boost::filesystem;
+
+#include <sstream>
+
+using lyx::support::libFileSearch;
+using lyx::support::makeDisplayPath;
+using lyx::support::quoteName;
using lyx::support::rtrim;
using lyx::support::subst;
+using lyx::support::addName;
using std::endl;
using std::find_if;
string name_;
};
+
+int const FORMAT = 2;
+
+
+bool layout2layout(string const & filename, string const & tempfile)
+{
+ string const script = libFileSearch("scripts", "layout2layout.py");
+ if (script.empty()) {
+ lyxerr << "Could not find layout conversion "
+ "script layout2layout.py." << endl;
+ return false;
+ }
+
+ std::ostringstream command;
+ command << lyx::support::os::python() << ' ' << quoteName(script)
+ << ' ' << quoteName(filename)
+ << ' ' << quoteName(tempfile);
+ string const command_str = command.str();
+
+ lyxerr[Debug::TCLASS] << "Running `" << command_str << '\'' << endl;
+
+ lyx::support::cmd_ret const ret =
+ lyx::support::runCommand(command_str);
+ if (ret.first != 0) {
+ lyxerr << "Could not run layout conversion "
+ "script layout2layout.py." << endl;
+ return false;
+ }
+ return true;
+}
+
} // namespace anon
bool LyXTextClass::do_readStyle(LyXLex & lexrc, LyXLayout & lay)
{
lyxerr[Debug::TCLASS] << "Reading style " << lay.name() << endl;
- if (!lay.Read(lexrc, *this)) {
+ if (!lay.read(lexrc, *this)) {
// Resolve fonts
lay.resfont = lay.font;
lay.resfont.realize(defaultfont());
TC_COUNTER,
TC_NOFLOAT,
TC_TITLELATEXNAME,
- TC_TITLELATEXTYPE
+ TC_TITLELATEXTYPE,
+ TC_FORMAT
};
+
// Reads a textclass structure from file.
-bool LyXTextClass::Read(string const & filename, bool merge)
+bool LyXTextClass::read(string const & filename, bool merge)
{
+ if (!lyx::support::isFileReadable(filename)) {
+ lyxerr << "Cannot read layout file `" << filename << "'."
+ << endl;
+ return true;
+ }
+
keyword_item textClassTags[] = {
{ "charstyle", TC_CHARSTYLE },
{ "classoptions", TC_CLASSOPTIONS },
{ "defaultstyle", TC_DEFAULTSTYLE },
{ "environment", TC_ENVIRONMENT },
{ "float", TC_FLOAT },
+ { "format", TC_FORMAT },
{ "input", TC_INPUT },
{ "leftmargin", TC_LEFTMARGIN },
{ "nofloat", TC_NOFLOAT },
if (!merge)
lyxerr[Debug::TCLASS] << "Reading textclass "
- << MakeDisplayPath(filename)
+ << makeDisplayPath(filename)
<< endl;
else
lyxerr[Debug::TCLASS] << "Reading input file "
- << MakeDisplayPath(filename)
+ << makeDisplayPath(filename)
<< endl;
LyXLex lexrc(textClassTags,
sizeof(textClassTags) / sizeof(textClassTags[0]));
- bool error = false;
lexrc.setFile(filename);
- if (!lexrc.isOK()) error = true;
+ bool error = !lexrc.isOK();
+
+ // Format of files before the 'Format' tag was introduced
+ int format = 1;
// parsing
while (lexrc.isOK() && !error) {
switch (static_cast<TextClassTags>(le)) {
+ case TC_FORMAT:
+ if (lexrc.next())
+ format = lexrc.getInteger();
+ break;
+
case TC_OUTPUTTYPE: // output type definition
readOutputType(lexrc);
break;
case TC_INPUT: // Include file
if (lexrc.next()) {
- string tmp = LibFileSearch("layouts",
+ string tmp = libFileSearch("layouts",
lexrc.getString(),
"layout");
- if (Read(tmp, true)) {
+ if (read(tmp, true)) {
lexrc.printError("Error reading input"
"file: "+tmp);
error = true;
lay.setName(name);
if (le == TC_ENVIRONMENT)
lay.is_environment = true;
- if (!(error = do_readStyle(lexrc, lay)))
+ error = do_readStyle(lexrc, lay);
+ if (!error)
layoutlist_.push_back(
boost::shared_ptr<LyXLayout>(new LyXLayout(lay))
);
}
break;
}
+ if (format != FORMAT)
+ break;
+ }
+
+ if (format != FORMAT) {
+ lyxerr[Debug::TCLASS] << "Converting layout file from format "
+ << format << " to " << FORMAT << endl;
+ string const tempfile = lyx::support::tempName();
+ error = !layout2layout(filename, tempfile);
+ if (!error)
+ error = read(tempfile, merge);
+ lyx::support::unlink(tempfile);
+ return error;
}
if (!merge) { // we are at top level here.
lyxerr[Debug::TCLASS] << "Finished reading textclass "
- << MakeDisplayPath(filename)
+ << makeDisplayPath(filename)
<< endl;
if (defaultlayout_.empty()) {
lyxerr << "Error: Textclass '" << name_
<< "' is missing a defaultstyle." << endl;
error = true;
}
+
+ min_toclevel_ = LyXLayout::NOT_IN_TOC;
+ max_toclevel_ = LyXLayout::NOT_IN_TOC;
+ const_iterator cit = begin();
+ const_iterator the_end = end();
+ for ( ; cit != the_end ; ++cit) {
+ int const toclevel = (*cit)->toclevel;
+ if (toclevel != LyXLayout::NOT_IN_TOC) {
+ if (min_toclevel_ == LyXLayout::NOT_IN_TOC)
+ min_toclevel_ = toclevel;
+ else
+ min_toclevel_ = std::min(min_toclevel_,
+ toclevel);
+ max_toclevel_ = std::max(max_toclevel_,
+ toclevel);
+ }
+ }
+ lyxerr[Debug::TCLASS]
+ << "Minimum TocLevel is " << min_toclevel_
+ << ", maximum is " << max_toclevel_ <<endl;
+
} else
lyxerr[Debug::TCLASS] << "Finished reading input file "
- << MakeDisplayPath(filename)
+ << makeDisplayPath(filename)
<< endl;
return error;
keyword_item outputTypeTags[] = {
{ "docbook", DOCBOOK },
{ "latex", LATEX },
- { "linuxdoc", LINUXDOC },
{ "literate", LITERATE }
};
lexrc.printError("Unknown output type `$$Token'");
return;
case LATEX:
- case LINUXDOC:
case DOCBOOK:
case LITERATE:
outputType_ = static_cast<OutputType>(le);
}
-enum MaxCounterTags {
- MC_COUNTER_CHAPTER = 1,
- MC_COUNTER_SECTION,
- MC_COUNTER_SUBSECTION,
- MC_COUNTER_SUBSUBSECTION,
- MC_COUNTER_PARAGRAPH,
- MC_COUNTER_SUBPARAGRAPH,
- MC_COUNTER_ENUMI,
- MC_COUNTER_ENUMII,
- MC_COUNTER_ENUMIII,
- MC_COUNTER_ENUMIV
-};
-
-
enum ClassOptionsTags {
CO_FONTSIZE = 1,
CO_PAGESTYLE,
<< "' in the layout list. You MUST investigate!"
<< endl;
for (LayoutList::const_iterator it = layoutlist_.begin();
- it != layoutlist_.end(); ++it)
+ it != layoutlist_.end(); ++it)
lyxerr << " " << it->get()->name() << endl;
// we require the name to exist
// 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");
- loaded_ = const_cast<LyXTextClass*>(this)->Read(real_file) == 0;
+ // Read style-file, provided path is searched before the system ones
+ string layout_file;
+ if (!path.empty())
+ layout_file = addName(path, name_ + ".layout");
+ if (layout_file.empty() || !fs::exists(layout_file))
+ layout_file = libFileSearch("layouts", name_, "layout");
+ loaded_ = const_cast<LyXTextClass*>(this)->read(layout_file) == 0;
if (!loaded_) {
lyxerr << "Error reading `"
- << MakeDisplayPath(real_file)
+ << makeDisplayPath(layout_file)
<< "'\n(Check `" << name_
<< "')\nCheck your installation and "
"try Options/Reconfigure..." << endl;
}
+int LyXTextClass::min_toclevel() const
+{
+ return min_toclevel_;
+}
+
+
+int LyXTextClass::max_toclevel() const
+{
+ return max_toclevel_;
+}
+
+
+bool LyXTextClass::hasTocLevels() const
+{
+ return min_toclevel_ != LyXLayout::NOT_IN_TOC;
+}
+
+
ostream & operator<<(ostream & os, LyXTextClass::PageSides p)
{
switch (p) {