]> git.lyx.org Git - lyx.git/blobdiff - src/TextClass.cpp
Streamlining CollapseStatus stuff
[lyx.git] / src / TextClass.cpp
index 36aab53ac6de9bf44b396be699ee1b9131d5e7e7..77348f28195423cb21c8e52f181cc95f413939ae 100644 (file)
 #include "debug.h"
 #include "Lexer.h"
 #include "Counters.h"
+#include "gettext.h"
 #include "Floating.h"
 #include "FloatList.h"
 
+#include "frontends/alert.h"
+
 #include "support/lstrings.h"
 #include "support/lyxlib.h"
 #include "support/filetools.h"
@@ -53,7 +56,7 @@ namespace {
 
 class LayoutNamesEqual : public std::unary_function<Layout_ptr, bool> {
 public:
-       LayoutNamesEqual(string const & name)
+       LayoutNamesEqual(docstring const & name)
                : name_(name)
        {}
        bool operator()(Layout_ptr const & c) const
@@ -61,7 +64,7 @@ public:
                return c->name() == name_;
        }
 private:
-       string name_;
+       docstring name_;
 };
 
 
@@ -101,7 +104,7 @@ bool layout2layout(FileName const & filename, FileName const & tempfile)
 TextClass::TextClass(string const & fn, string const & cln,
                           string const & desc, bool texClassAvail )
        : name_(fn), latexname_(cln), description_(desc),
-         floatlist_(new FloatList), ctrs_(new Counters),
+         floatlist_(new FloatList), counters_(new Counters),
          texClassAvail_(texClassAvail)
 {
        outputType_ = LATEX;
@@ -127,7 +130,7 @@ bool TextClass::isTeXClassAvailable() const
 
 bool TextClass::do_readStyle(Lexer & lexrc, Layout & lay)
 {
-       LYXERR(Debug::TCLASS) << "Reading style " << lay.name() << endl;
+       LYXERR(Debug::TCLASS) << "Reading style " << to_utf8(lay.name()) << endl;
        if (!lay.read(lexrc, *this)) {
                // Resolve fonts
                lay.resfont = lay.font;
@@ -136,7 +139,7 @@ bool TextClass::do_readStyle(Lexer & lexrc, Layout & lay)
                lay.reslabelfont.realize(defaultfont());
                return false; // no errors
        }
-       lyxerr << "Error parsing style `" << lay.name() << '\'' << endl;
+       lyxerr << "Error parsing style `" << to_utf8(lay.name()) << '\'' << endl;
        return true;
 }
 
@@ -147,6 +150,7 @@ enum TextClassTags {
        TC_STYLE,
        TC_DEFAULTSTYLE,
        TC_CHARSTYLE,
+       TC_INSETLAYOUT,
        TC_ENVIRONMENT,
        TC_NOSTYLE,
        TC_COLUMNS,
@@ -189,6 +193,7 @@ bool TextClass::read(FileName const & filename, bool merge)
                { "float",           TC_FLOAT },
                { "format",          TC_FORMAT },
                { "input",           TC_INPUT },
+               { "insetlayout",     TC_INSETLAYOUT },
                { "leftmargin",      TC_LEFTMARGIN },
                { "nofloat",         TC_NOFLOAT },
                { "nostyle",         TC_NOSTYLE },
@@ -207,12 +212,12 @@ bool TextClass::read(FileName const & filename, bool merge)
 
        if (!merge)
                LYXERR(Debug::TCLASS) << "Reading textclass "
-                                       << to_utf8(makeDisplayPath(filename.absFilename()))
-                                       << endl;
+                                     << to_utf8(makeDisplayPath(filename.absFilename()))
+                                     << endl;
        else
                LYXERR(Debug::TCLASS) << "Reading input file "
-                                    << to_utf8(makeDisplayPath(filename.absFilename()))
-                                    << endl;
+                                     << to_utf8(makeDisplayPath(filename.absFilename()))
+                                     << endl;
 
        Lexer lexrc(textClassTags,
                sizeof(textClassTags) / sizeof(textClassTags[0]));
@@ -259,7 +264,7 @@ bool TextClass::read(FileName const & filename, bool merge)
 
                                if (tmp.empty()) {
                                        lexrc.printError("Could not find input"
-                                                        "file: " + inc);
+                                                        "file: " + inc);
                                        error = true;
                                } else if (read(tmp, true)) {
                                        lexrc.printError("Error reading input"
@@ -271,8 +276,8 @@ bool TextClass::read(FileName const & filename, bool merge)
 
                case TC_DEFAULTSTYLE:
                        if (lexrc.next()) {
-                               string const name = subst(lexrc.getString(),
-                                                         '_', ' ');
+                               docstring const name = from_utf8(subst(lexrc.getString(),
+                                                         '_', ' '));
                                defaultlayout_ = name;
                        }
                        break;
@@ -280,9 +285,15 @@ bool TextClass::read(FileName const & filename, bool merge)
                case TC_ENVIRONMENT:
                case TC_STYLE:
                        if (lexrc.next()) {
-                               string const name = subst(lexrc.getString(),
-                                                   '_', ' ');
-                               if (hasLayout(name)) {
+                               docstring const name = from_utf8(subst(lexrc.getString(),
+                                                   '_', ' '));
+                               if (name.empty()) {
+                                       string s = "Could not read name for style: `$$Token' "
+                                               + lexrc.getString() + " is probably not valid UTF-8!";
+                                       lexrc.printError(s.c_str());
+                                       Layout lay;
+                                       error = do_readStyle(lexrc, lay);
+                               } else if (hasLayout(name)) {
                                        Layout * lay = operator[](name).get();
                                        error = do_readStyle(lexrc, *lay);
                                } else {
@@ -313,11 +324,11 @@ bool TextClass::read(FileName const & filename, bool merge)
 
                case TC_NOSTYLE:
                        if (lexrc.next()) {
-                               string const style = subst(lexrc.getString(),
-                                                    '_', ' ');
+                               docstring const style = from_utf8(subst(lexrc.getString(),
+                                                    '_', ' '));
                                if (!delete_layout(style))
                                        lyxerr << "Cannot delete style `"
-                                              << style << '\'' << endl;
+                                              << to_utf8(style) << '\'' << endl;
 //                                     lexrc.printError("Cannot delete style"
 //                                                      " `$$Token'");
                        }
@@ -402,6 +413,12 @@ bool TextClass::read(FileName const & filename, bool merge)
                                readCharStyle(lexrc, name);
                        }
                        break;
+               case TC_INSETLAYOUT:
+                       if (lexrc.next()) {
+                               docstring const name = subst(lexrc.getDocString(), '_', ' ');
+                               readInsetLayout(lexrc, name);
+                       }
+                       break;
                case TC_FLOAT:
                        readFloat(lexrc);
                        break;
@@ -597,6 +614,19 @@ enum CharStyleTags {
 };
 
 
+enum InsetLayoutTags {
+       IL_FONT = 1,
+       IL_LABELFONT,
+       IL_LABELSTRING,
+       IL_LATEXTYPE,
+       IL_LATEXNAME,
+       IL_LATEXPARAM,
+       IL_PREAMBLE,
+       IL_END
+};
+
+
+
 void TextClass::readCharStyle(Lexer & lexrc, string const & name)
 {
        keyword_item elementTags[] = {
@@ -674,6 +704,92 @@ void TextClass::readCharStyle(Lexer & lexrc, string const & name)
 }
 
 
+void TextClass::readInsetLayout(Lexer & lexrc, docstring const & name)
+{
+       keyword_item elementTags[] = {
+               { "end", IL_END },
+               { "font", IL_FONT },
+               { "labelfont", IL_LABELFONT },
+               { "labelstring", IL_LABELSTRING },
+               { "latexname", IL_LATEXNAME },
+               { "latexparam", IL_LATEXPARAM },
+               { "latextype", IL_LATEXTYPE },
+               { "preamble", IL_PREAMBLE}
+       };
+
+       lexrc.pushTable(elementTags, IL_END);
+
+       docstring labelstring;
+       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<InsetLayoutTags>(le)) {
+               case IL_LATEXTYPE:
+                       lexrc.next();
+                       latextype = lexrc.getString();
+                       break;
+               case IL_LABELSTRING:
+                       lexrc.next();
+                       labelstring = lexrc.getDocString();
+                       break;
+               case IL_LATEXNAME:
+                       lexrc.next();
+                       latexname = lexrc.getString();
+                       break;
+               case IL_LATEXPARAM:
+                       lexrc.next();
+                       latexparam = subst(lexrc.getString(), "&quot;", "\"");
+                       break;
+               case IL_LABELFONT:
+                       labelfont.lyxRead(lexrc);
+                       labelfont.realize(defaultfont());
+                       break;
+               case IL_FONT:
+                       font.lyxRead(lexrc);
+                       font.realize(defaultfont());
+                       labelfont = font;
+                       break;
+               case IL_PREAMBLE:
+                       preamble = lexrc.getLongString("EndPreamble");
+                       break;
+               case IL_END:
+                       getout = true;
+                       break;
+               }
+       }
+
+       //
+       // Here add element to list if getout == true
+       if (getout) {
+               InsetLayout il;
+               il.labelstring = labelstring;
+               il.latextype = latextype;
+               il.latexname = latexname;
+               il.latexparam = latexparam;
+               il.font = font;
+               il.labelfont = labelfont;
+               il.preamble = from_utf8(preamble);
+               insetlayoutlist_[name] = il;
+       }
+
+       lexrc.popTable();
+}
+
+
+
 enum FloatTags {
        FT_TYPE = 1,
        FT_NAME,
@@ -709,7 +825,7 @@ void TextClass::readFloat(Lexer & lexrc)
        string within;
        string style;
        string name;
-       string listname;
+       string listName;
        bool builtin = false;
 
        bool getout = false;
@@ -725,8 +841,16 @@ void TextClass::readFloat(Lexer & lexrc)
                case FT_TYPE:
                        lexrc.next();
                        type = lexrc.getString();
-                       // Here we could check if this type is already defined
-                       // and modify it with the rest of the vars instead.
+                       if (floatlist_->typeExist(type)) {
+                               Floating const & fl = floatlist_->getType(type);
+                               placement = fl.placement();
+                               ext = fl.ext();
+                               within = fl.within();
+                               style = fl.style();
+                               name = fl.name();
+                               listName = fl.listName();
+                               builtin = fl.builtin();
+                       } 
                        break;
                case FT_NAME:
                        lexrc.next();
@@ -752,7 +876,7 @@ void TextClass::readFloat(Lexer & lexrc)
                        break;
                case FT_LISTNAME:
                        lexrc.next();
-                       listname = lexrc.getString();
+                       listName = lexrc.getString();
                        break;
                case FT_BUILTIN:
                        lexrc.next();
@@ -766,9 +890,12 @@ void TextClass::readFloat(Lexer & lexrc)
 
        // Here if have a full float if getout == true
        if (getout) {
-               Floating newfloat(type, placement, ext, within,
-                                 style, name, listname, builtin);
-               floatlist_->newFloat(newfloat);
+               Floating fl(type, placement, ext, within,
+                           style, name, listName, builtin);
+               floatlist_->newFloat(fl);
+               // each float has its own counter
+               counters_->newCounter(from_ascii(type), from_ascii(within), 
+                                     docstring(), docstring());
        }
 
        lexrc.popTable();
@@ -778,6 +905,8 @@ void TextClass::readFloat(Lexer & lexrc)
 enum CounterTags {
        CT_NAME = 1,
        CT_WITHIN,
+       CT_LABELSTRING,
+       CT_LABELSTRING_APPENDIX,
        CT_END
 };
 
@@ -785,6 +914,8 @@ void TextClass::readCounter(Lexer & lexrc)
 {
        keyword_item counterTags[] = {
                { "end", CT_END },
+               { "labelstring", CT_LABELSTRING },
+               { "labelstringappendix", CT_LABELSTRING_APPENDIX },
                { "name", CT_NAME },
                { "within", CT_WITHIN }
        };
@@ -793,6 +924,8 @@ void TextClass::readCounter(Lexer & lexrc)
 
        docstring name;
        docstring within;
+       docstring labelstring;
+       docstring labelstring_appendix;
 
        bool getout = false;
        while (!getout && lexrc.isOK()) {
@@ -806,14 +939,31 @@ void TextClass::readCounter(Lexer & lexrc)
                switch (static_cast<CounterTags>(le)) {
                case CT_NAME:
                        lexrc.next();
-                       name = from_ascii(lexrc.getString());
+                       name = lexrc.getDocString();
+                       if (counters_->hasCounter(name))
+                               LYXERR(Debug::TCLASS) 
+                                       << "Reading existing counter " 
+                                       << to_utf8(name) << endl;
+                       else
+                               LYXERR(Debug::TCLASS) 
+                                       << "Reading new counter " 
+                                       << to_utf8(name) << endl;
                        break;
                case CT_WITHIN:
                        lexrc.next();
-                       within = from_ascii(lexrc.getString());
+                       within = lexrc.getDocString();
                        if (within == "none")
                                within.erase();
                        break;
+               case CT_LABELSTRING:
+                       lexrc.next();
+                       labelstring = lexrc.getDocString();
+                       labelstring_appendix = labelstring;
+                       break;
+               case CT_LABELSTRING_APPENDIX:
+                       lexrc.next();
+                       labelstring_appendix = lexrc.getDocString();
+                       break;
                case CT_END:
                        getout = true;
                        break;
@@ -821,12 +971,9 @@ void TextClass::readCounter(Lexer & lexrc)
        }
 
        // Here if have a full counter if getout == true
-       if (getout) {
-               if (within.empty())
-                       ctrs_->newCounter(name);
-               else
-                       ctrs_->newCounter(name, within);
-       }
+       if (getout)
+               counters_->newCounter(name, within, 
+                                     labelstring, labelstring_appendix);
 
        lexrc.popTable();
 }
@@ -850,9 +997,9 @@ string const & TextClass::rightmargin() const
 }
 
 
-bool TextClass::hasLayout(string const & n) const
+bool TextClass::hasLayout(docstring const & n) const
 {
-       string const name = (n.empty() ? defaultLayoutName() : n);
+       docstring const name = n.empty() ? defaultLayoutName() : n;
 
        return find_if(layoutlist_.begin(), layoutlist_.end(),
                       LayoutNamesEqual(name))
@@ -861,7 +1008,7 @@ bool TextClass::hasLayout(string const & n) const
 
 
 
-Layout_ptr const & TextClass::operator[](string const & name) const
+Layout_ptr const & TextClass::operator[](docstring const & name) const
 {
        BOOST_ASSERT(!name.empty());
 
@@ -871,12 +1018,12 @@ Layout_ptr const & TextClass::operator[](string const & name) const
                        LayoutNamesEqual(name));
 
        if (cit == layoutlist_.end()) {
-               lyxerr << "We failed to find the layout '" << name
+               lyxerr << "We failed to find the layout '" << to_utf8(name)
                       << "' in the layout list. You MUST investigate!"
                       << endl;
                for (LayoutList::const_iterator it = layoutlist_.begin();
                         it != layoutlist_.end(); ++it)
-                       lyxerr  << " " << it->get()->name() << endl;
+                       lyxerr  << " " << to_utf8(it->get()->name()) << endl;
 
                // we require the name to exist
                BOOST_ASSERT(false);
@@ -887,7 +1034,7 @@ Layout_ptr const & TextClass::operator[](string const & name) const
 
 
 
-bool TextClass::delete_layout(string const & name)
+bool TextClass::delete_layout(docstring const & name)
 {
        if (name == defaultLayoutName())
                return false;
@@ -943,7 +1090,12 @@ FloatList const & TextClass::floats() const
 
 Counters & TextClass::counters() const
 {
-       return *ctrs_.get();
+       return *counters_.get();
+}
+
+InsetLayout const & TextClass::insetlayout(docstring const & name) const 
+{
+       return insetlayoutlist_[name]; 
 }
 
 
@@ -959,7 +1111,7 @@ CharStyles::iterator TextClass::charstyle(string const & s) const
 }
 
 
-string const & TextClass::defaultLayoutName() const
+docstring const & TextClass::defaultLayoutName() const
 {
        // This really should come from the actual layout... (Lgb)
        return defaultlayout_;