#include "TextClass.h"
#include "debug.h"
+#include "Layout.h"
#include "Lexer.h"
#include "Counters.h"
#include "gettext.h"
#include "support/filetools.h"
#include "support/os.h"
-#include <boost/filesystem/operations.hpp>
-namespace fs = boost::filesystem;
-
#include <sstream>
-
namespace lyx {
using support::FileName;
namespace {
-class LayoutNamesEqual : public std::unary_function<Layout_ptr, bool> {
+class LayoutNamesEqual : public std::unary_function<LayoutPtr, bool> {
public:
LayoutNamesEqual(docstring const & name)
: name_(name)
{}
- bool operator()(Layout_ptr const & c) const
+ bool operator()(LayoutPtr const & c) const
{
return c->name() == name_;
}
};
-int const FORMAT = 4;
+int const FORMAT = 5;
bool layout2layout(FileName const & filename, FileName const & tempfile)
floatlist_(new FloatList), counters_(new Counters),
texClassAvail_(texClassAvail)
{
+ modular_ = false;
outputType_ = LATEX;
columns_ = 1;
sides_ = OneSide;
TC_INPUT,
TC_STYLE,
TC_DEFAULTSTYLE,
- TC_CHARSTYLE,
TC_INSETLAYOUT,
TC_ENVIRONMENT,
TC_NOSTYLE,
// Reads a textclass structure from file.
-bool TextClass::read(FileName const & filename, bool merge)
+bool TextClass::read(FileName const & filename, ReadType rt)
{
- if (!support::isFileReadable(filename)) {
+ if (!filename.isFileReadable()) {
lyxerr << "Cannot read layout file `" << filename << "'."
<< endl;
return true;
}
keyword_item textClassTags[] = {
- { "charstyle", TC_CHARSTYLE },
{ "classoptions", TC_CLASSOPTIONS },
{ "columns", TC_COLUMNS },
{ "counter", TC_COUNTER },
{ "tocdepth", TC_TOCDEPTH }
};
- if (!merge)
- LYXERR(Debug::TCLASS) << "Reading textclass "
- << to_utf8(makeDisplayPath(filename.absFilename()))
- << endl;
- else
- LYXERR(Debug::TCLASS) << "Reading input file "
- << to_utf8(makeDisplayPath(filename.absFilename()))
- << endl;
+ switch (rt) {
+ case BASECLASS:
+ LYXERR(Debug::TCLASS) << "Reading textclass ";
+ break;
+ case MERGE:
+ LYXERR(Debug::TCLASS) << "Reading input file ";
+ break;
+ case MODULE:
+ LYXERR(Debug::TCLASS) << "Reading module file ";
+ break;
+ default:
+ BOOST_ASSERT(false);
+ }
+ LYXERR(Debug::TCLASS) << to_utf8(makeDisplayPath(filename.absFilename()))
+ << endl;
Lexer lexrc(textClassTags,
sizeof(textClassTags) / sizeof(textClassTags[0]));
lexrc.printError("Could not find input"
"file: " + inc);
error = true;
- } else if (read(tmp, true)) {
+ } else if (read(tmp, MERGE)) {
lexrc.printError("Error reading input"
"file: " + tmp.absFilename());
error = true;
case TC_LEFTMARGIN: // left margin type
if (lexrc.next())
- leftmargin_ = lexrc.getString();
+ leftmargin_ = lexrc.getDocString();
break;
case TC_RIGHTMARGIN: // right margin type
if (lexrc.next())
- rightmargin_ = lexrc.getString();
- break;
- case TC_CHARSTYLE:
- if (lexrc.next()) {
- string const name = subst(lexrc.getString(), '_', ' ');
- readCharStyle(lexrc, name);
- }
+ rightmargin_ = lexrc.getDocString();
break;
case TC_INSETLAYOUT:
if (lexrc.next()) {
FileName const tempfile(support::tempName());
error = !layout2layout(filename, tempfile);
if (!error)
- error = read(tempfile, merge);
+ error = read(tempfile, rt);
support::unlink(tempfile);
return error;
}
- if (!merge) { // we are at top level here.
+ if (rt == MODULE)
+ LYXERR(Debug::TCLASS) << "Finished reading module file "
+ << to_utf8(makeDisplayPath(filename.absFilename()))
+ << endl;
+ else if (rt == MERGE)
+ LYXERR(Debug::TCLASS) << "Finished reading input file "
+ << to_utf8(makeDisplayPath(filename.absFilename()))
+ << endl;
+ else { // we are at top level here.
LYXERR(Debug::TCLASS) << "Finished reading textclass "
<< to_utf8(makeDisplayPath(filename.absFilename()))
<< endl;
<< "Minimum TocLevel is " << min_toclevel_
<< ", maximum is " << max_toclevel_ <<endl;
- } else
- LYXERR(Debug::TCLASS) << "Finished reading input file "
- << to_utf8(makeDisplayPath(filename.absFilename()))
- << endl;
+ }
return error;
}
return;
case TITLE_COMMAND_AFTER:
case TITLE_ENVIRONMENT:
- titletype_ = static_cast<LYX_TITLE_LATEX_TYPES>(le);
+ titletype_ = static_cast<TitleLatexType>(le);
break;
default:
lyxerr << "Unhandled value " << le
lexrc.popTable();
}
-enum CharStyleTags {
- CS_FONT = 1,
- CS_LABELFONT,
- CS_LATEXTYPE,
- CS_LATEXNAME,
- CS_LATEXPARAM,
- CS_PREAMBLE,
- CS_END
-};
-
enum InsetLayoutTags {
IL_FONT = 1,
+ IL_BGCOLOR,
+ IL_DECORATION,
IL_LABELFONT,
IL_LABELSTRING,
- IL_LATEXTYPE,
IL_LATEXNAME,
IL_LATEXPARAM,
+ IL_LATEXTYPE,
+ IL_LYXTYPE,
+ IL_MULTIPAR,
IL_PREAMBLE,
+ IL_VERBATIM,
IL_END
};
-
-void TextClass::readCharStyle(Lexer & lexrc, string const & name)
-{
- keyword_item elementTags[] = {
- { "end", CS_END },
- { "font", CS_FONT },
- { "labelfont", CS_LABELFONT },
- { "latexname", CS_LATEXNAME },
- { "latexparam", CS_LATEXPARAM },
- { "latextype", CS_LATEXTYPE },
- { "preamble", CS_PREAMBLE}
- };
-
- lexrc.pushTable(elementTags, CS_END);
-
- string latextype;
- string latexname;
- string latexparam;
- Font font(Font::ALL_INHERIT);
- Font labelfont(Font::ALL_INHERIT);
- string preamble;
-
- bool getout = false;
- while (!getout && lexrc.isOK()) {
- int le = lexrc.lex();
- switch (le) {
- case Lexer::LEX_UNDEF:
- lexrc.printError("Unknown ClassOption tag `$$Token'");
- continue;
- default: break;
- }
- switch (static_cast<CharStyleTags>(le)) {
- case CS_LATEXTYPE:
- lexrc.next();
- latextype = lexrc.getString();
- break;
- case CS_LATEXNAME:
- lexrc.next();
- latexname = lexrc.getString();
- break;
- case CS_LATEXPARAM:
- lexrc.next();
- latexparam = subst(lexrc.getString(), """, "\"");
- break;
- case CS_LABELFONT:
- labelfont.lyxRead(lexrc);
- break;
- case CS_FONT:
- font.lyxRead(lexrc);
- labelfont = font;
- break;
- case CS_PREAMBLE:
- preamble = lexrc.getLongString("EndPreamble");
- break;
- case CS_END:
- getout = true;
- break;
- }
- }
-
- //
- // Here add element to list if getout == true
- if (getout) {
- CharStyle cs;
- cs.name = name;
- cs.latextype = latextype;
- cs.latexname = latexname;
- cs.latexparam = latexparam;
- cs.font = font;
- cs.labelfont = labelfont;
- cs.preamble = from_utf8(preamble);
- charstyles().push_back(cs);
- }
-
- lexrc.popTable();
-}
-
-
void TextClass::readInsetLayout(Lexer & lexrc, docstring const & name)
{
keyword_item elementTags[] = {
+ { "bgcolor", IL_BGCOLOR },
+ { "decoration", IL_DECORATION },
{ "end", IL_END },
{ "font", IL_FONT },
{ "labelfont", IL_LABELFONT },
{ "latexname", IL_LATEXNAME },
{ "latexparam", IL_LATEXPARAM },
{ "latextype", IL_LATEXTYPE },
- { "preamble", IL_PREAMBLE}
+ { "lyxtype", IL_LYXTYPE },
+ { "multipar", IL_MULTIPAR },
+ { "preamble", IL_PREAMBLE },
+ { "verbatim", IL_VERBATIM }
};
lexrc.pushTable(elementTags, IL_END);
+ string lyxtype;
docstring labelstring;
string latextype;
+ string decoration;
string latexname;
string latexparam;
- Font font(Font::ALL_INHERIT);
- Font labelfont(Font::ALL_INHERIT);
+ Font font(defaultfont());
+ Font labelfont(defaultfont());
+ Color::color bgcolor(Color::background);
string preamble;
+ bool multipar(false);
+ bool verbatim(false);
bool getout = false;
while (!getout && lexrc.isOK()) {
default: break;
}
switch (static_cast<InsetLayoutTags>(le)) {
+ case IL_LYXTYPE:
+ lexrc.next();
+ lyxtype = lexrc.getString();
+ break;
case IL_LATEXTYPE:
lexrc.next();
latextype = lexrc.getString();
lexrc.next();
labelstring = lexrc.getDocString();
break;
+ case IL_DECORATION:
+ lexrc.next();
+ decoration = lexrc.getString();
+ break;
case IL_LATEXNAME:
lexrc.next();
latexname = lexrc.getString();
labelfont.lyxRead(lexrc);
labelfont.realize(defaultfont());
break;
+ case IL_MULTIPAR:
+ lexrc.next();
+ multipar = lexrc.getBool();
+ break;
+ case IL_VERBATIM:
+ lexrc.next();
+ verbatim = lexrc.getBool();
+ break;
case IL_FONT:
font.lyxRead(lexrc);
font.realize(defaultfont());
+ // So: define font before labelfont
labelfont = font;
break;
+ case IL_BGCOLOR: {
+ lexrc.next();
+ string const token = lexrc.getString();
+ bgcolor = lcolor.getFromLyXName(token);
+ break;
+ }
case IL_PREAMBLE:
preamble = lexrc.getLongString("EndPreamble");
break;
// Here add element to list if getout == true
if (getout) {
InsetLayout il;
+ il.name = to_ascii(name);
+ il.lyxtype = lyxtype;
il.labelstring = labelstring;
+ il.decoration = decoration;
il.latextype = latextype;
il.latexname = latexname;
il.latexparam = latexparam;
+ il.multipar = multipar;
+ il.verbatim = verbatim;
il.font = font;
il.labelfont = labelfont;
- il.preamble = from_utf8(preamble);
+ il.bgcolor = bgcolor;
+ il.preamble = preamble;
insetlayoutlist_[name] = il;
}
}
-string const & TextClass::leftmargin() const
+docstring const & TextClass::leftmargin() const
{
return leftmargin_;
}
-string const & TextClass::rightmargin() const
+docstring const & TextClass::rightmargin() const
{
return rightmargin_;
}
-Layout_ptr const & TextClass::operator[](docstring const & name) const
+LayoutPtr const & TextClass::operator[](docstring const & name) const
{
BOOST_ASSERT(!name.empty());
FileName layout_file;
if (!path.empty())
layout_file = FileName(addName(path, name_ + ".layout"));
- if (layout_file.empty() || !fs::exists(layout_file.toFilesystemEncoding()))
+ if (layout_file.empty() || !layout_file.exists())
layout_file = libFileSearch("layouts", name_, "layout");
loaded_ = const_cast<TextClass*>(this)->read(layout_file) == 0;
return *counters_.get();
}
-InsetLayout const & TextClass::insetlayout(docstring const & name) const
-{
- return insetlayoutlist_[name];
-}
-
-CharStyles::iterator TextClass::charstyle(string const & s) const
+// Return the layout object of an inset given by name. If the name
+// is not found as such, the part after the ':' is stripped off, and
+// searched again. In this way, an error fallback can be provided:
+// An erroneous 'CharStyle:badname' (e.g., after a documentclass switch)
+// will invoke the layout object defined by name = 'CharStyle'.
+// If that doesn't work either, an empty object returns (shouldn't
+// happen). -- Idea JMarc, comment MV
+InsetLayout const & TextClass::insetlayout(docstring const & name) const
{
- CharStyles::iterator cs = charstyles().begin();
- CharStyles::iterator csend = charstyles().end();
- for (; cs != csend; ++cs) {
- if (cs->name == s)
- return cs;
+ docstring n = name;
+ while (!n.empty()) {
+ if (insetlayoutlist_.count(n) > 0)
+ return insetlayoutlist_[n];
+ docstring::size_type i = n.find(':');
+ if (i == string::npos)
+ break;
+ n = n.substr(0,i);
}
- return csend;
+ static InsetLayout empty;
+ empty.labelstring = from_utf8("UNDEFINED");
+ empty.bgcolor = Color::error;
+ return empty;
}
}
-Layout_ptr const & TextClass::defaultLayout() const
+LayoutPtr const & TextClass::defaultLayout() const
{
return operator[](defaultLayoutName());
}
}
-LYX_TITLE_LATEX_TYPES TextClass::titletype() const
+TitleLatexType TextClass::titletype() const
{
return titletype_;
}