]> git.lyx.org Git - lyx.git/blobdiff - src/TextClass.cpp
HTML for stackrel.
[lyx.git] / src / TextClass.cpp
index 0a349e85720d3935faa1593a9d928c9a589bb722..6bc0bc0c8e65aded738618c509014955e8c4588b 100644 (file)
 #include <fstream>
 #include <sstream>
 
+#ifdef ERROR
+#undef ERROR
+#endif
+
 using namespace std;
 using namespace lyx::support;
 
@@ -62,7 +66,7 @@ private:
 };
 
 // Keep the changes documented in the Customization manual. 
-int const FORMAT = 16;
+int const FORMAT = 26;
 
 
 bool layout2layout(FileName const & filename, FileName const & tempfile)
@@ -91,7 +95,7 @@ bool layout2layout(FileName const & filename, FileName const & tempfile)
 }
 
 
-std::string translateRT(TextClass::ReadType rt) 
+string translateRT(TextClass::ReadType rt) 
 {
        switch (rt) {
        case TextClass::BASECLASS:
@@ -164,6 +168,7 @@ enum TextClassTags {
        TC_OUTPUTFORMAT,
        TC_INPUT,
        TC_STYLE,
+       TC_IFSTYLE,
        TC_DEFAULTSTYLE,
        TC_INSETLAYOUT,
        TC_NOSTYLE,
@@ -182,6 +187,7 @@ enum TextClassTags {
        TC_RIGHTMARGIN,
        TC_FLOAT,
        TC_COUNTER,
+       TC_IFCOUNTER,
        TC_NOFLOAT,
        TC_TITLELATEXNAME,
        TC_TITLELATEXTYPE,
@@ -190,7 +196,9 @@ enum TextClassTags {
        TC_ADDTOHTMLPREAMBLE,
        TC_DEFAULTMODULE,
        TC_PROVIDESMODULE,
-       TC_EXCLUDESMODULE
+       TC_EXCLUDESMODULE,
+       TC_HTMLTOCSECTION,
+       TC_CITEFORMAT
 };
 
 
@@ -199,6 +207,7 @@ namespace {
        LexerKeyword textClassTags[] = {
                { "addtohtmlpreamble", TC_ADDTOHTMLPREAMBLE },
                { "addtopreamble",     TC_ADDTOPREAMBLE },
+               { "citeformat",        TC_CITEFORMAT },
                { "classoptions",      TC_CLASSOPTIONS },
                { "columns",           TC_COLUMNS },
                { "counter",           TC_COUNTER },
@@ -209,6 +218,9 @@ namespace {
                { "float",             TC_FLOAT },
                { "format",            TC_FORMAT },
                { "htmlpreamble",      TC_HTMLPREAMBLE },
+               { "htmltocsection",    TC_HTMLTOCSECTION },
+               { "ifcounter",         TC_IFCOUNTER },
+               { "ifstyle",           TC_IFSTYLE },
                { "input",             TC_INPUT },
                { "insetlayout",       TC_INSETLAYOUT },
                { "leftmargin",        TC_LEFTMARGIN },
@@ -352,6 +364,10 @@ TextClass::ReturnValues TextClass::read(Lexer & lexrc, ReadType rt)
                        break;
                }
 
+               // used below to track whether we are in an IfStyle or IfCounter tag.
+               bool ifstyle    = false;
+               bool ifcounter  = false;
+
                switch (static_cast<TextClassTags>(le)) {
 
                case TC_FORMAT:
@@ -404,6 +420,9 @@ TextClass::ReturnValues TextClass::read(Lexer & lexrc, ReadType rt)
                        }
                        break;
 
+               case TC_IFSTYLE:
+                       ifstyle = true;
+                       // fall through
                case TC_STYLE: {
                        if (!lexrc.next()) {
                                lexrc.printError("No name given for style: `$$Token'.");
@@ -423,7 +442,7 @@ TextClass::ReturnValues TextClass::read(Lexer & lexrc, ReadType rt)
                        } else if (hasLayout(name)) {
                                Layout & lay = operator[](name);
                                error = !readStyle(lexrc, lay);
-                       } else {
+                       } else if (!ifstyle) {
                                Layout layout;
                                layout.setName(name);
                                error = !readStyle(lexrc, layout);
@@ -436,6 +455,15 @@ TextClass::ReturnValues TextClass::read(Lexer & lexrc, ReadType rt)
                                        defaultlayout_ = name;
                                }
                        }
+                       else {
+                               // scan the rest and discard it
+                               Layout lay;
+                               readStyle(lexrc, lay);
+                               error = false;
+                       }
+
+                       // reset flag
+                       ifstyle = false;
                        break;
                }
 
@@ -505,6 +533,10 @@ TextClass::ReturnValues TextClass::read(Lexer & lexrc, ReadType rt)
                case TC_HTMLPREAMBLE:
                        htmlpreamble_ = from_utf8(lexrc.getLongString("EndPreamble"));
                        break;
+               
+               case TC_HTMLTOCSECTION:
+                       html_toc_section_ = from_utf8(trim(lexrc.getString()));
+                       break;
 
                case TC_ADDTOPREAMBLE:
                        preamble_ += from_utf8(lexrc.getLongString("EndPreamble"));
@@ -604,7 +636,13 @@ TextClass::ReturnValues TextClass::read(Lexer & lexrc, ReadType rt)
                case TC_FLOAT:
                        readFloat(lexrc);
                        break;
+               
+               case TC_CITEFORMAT:
+                       readCiteFormat(lexrc);
+                       break;
 
+               case TC_IFCOUNTER:
+                       ifcounter = true;
                case TC_COUNTER:
                        if (lexrc.next()) {
                                docstring const name = lexrc.getDocString();
@@ -617,12 +655,14 @@ TextClass::ReturnValues TextClass::read(Lexer & lexrc, ReadType rt)
                                        // and discard it.
                                        c.read(lexrc);
                                } else
-                                       error = !counters_.read(lexrc, name);
+                                       error = !counters_.read(lexrc, name, !ifcounter);
                        }
                        else {
                                lexrc.printError("No name given for style: `$$Token'.");
                                error = true;
                        }
+                       // reset flag
+                       ifcounter = false;
                        break;
 
                case TC_TITLELATEXTYPE:
@@ -812,6 +852,28 @@ void TextClass::readClassOptions(Lexer & lexrc)
 }
 
 
+void TextClass::readCiteFormat(Lexer & lexrc)
+{
+       string etype;
+       string definition;
+       while (lexrc.isOK()) {
+               lexrc.next();
+               etype = lexrc.getString();
+               if (!lexrc.isOK() || compare_ascii_no_case(etype, "end") == 0)
+                       break;
+               lexrc.eatLine();
+               definition = lexrc.getString();
+               char initchar = etype[0];
+               if (initchar == '#')
+                       continue;
+               if (initchar == '!' || initchar == '_')
+                       cite_macros_[etype] = definition;
+               else
+                       cite_formats_[etype] = definition;
+       }
+}
+
+
 void TextClass::readFloat(Lexer & lexrc)
 {
        enum {
@@ -822,10 +884,12 @@ void TextClass::readFloat(Lexer & lexrc)
                FT_WITHIN,
                FT_STYLE,
                FT_LISTNAME,
-               FT_BUILTIN,
+               FT_NEEDSFLOAT,
                FT_HTMLSTYLE,
-               FT_HTMLCLASS,
-               FT_HTMLTYPE,
+               FT_HTMLATTR,
+               FT_HTMLTAG,
+               FT_LISTCOMMAND,
+               FT_REFPREFIX,
                FT_END
        };
 
@@ -833,13 +897,15 @@ void TextClass::readFloat(Lexer & lexrc)
                { "end", FT_END },
                { "extension", FT_EXT },
                { "guiname", FT_NAME },
-               { "htmlclass", FT_HTMLCLASS },
+               { "htmlattr", FT_HTMLATTR },
                { "htmlstyle", FT_HTMLSTYLE },
-               { "htmltype", FT_HTMLTYPE },
-               { "latexbuiltin", FT_BUILTIN },
+               { "htmltag", FT_HTMLTAG },
+               { "listcommand", FT_LISTCOMMAND },
                { "listname", FT_LISTNAME },
+               { "needsfloatpkg", FT_NEEDSFLOAT },
                { "numberwithin", FT_WITHIN },
                { "placement", FT_PLACEMENT },
+               { "refprefix", FT_REFPREFIX },
                { "style", FT_STYLE },
                { "type", FT_TYPE }
        };
@@ -847,16 +913,18 @@ void TextClass::readFloat(Lexer & lexrc)
        lexrc.pushTable(floatTags);
 
        string ext;
-       string htmlclass;
+       string htmlattr;
        string htmlstyle;
-       string htmltype;
-       string listName;
+       string htmltag;
+       string listname;
+       string listcommand;
        string name;
        string placement;
+       string refprefix;
        string style;
        string type;
        string within;
-       bool builtin = false;
+       bool needsfloat = true;
 
        bool getout = false;
        while (!getout && lexrc.isOK()) {
@@ -878,8 +946,10 @@ void TextClass::readFloat(Lexer & lexrc)
                                within = fl.within();
                                style = fl.style();
                                name = fl.name();
-                               listName = fl.listName();
-                               builtin = fl.builtin();
+                               listname = fl.listName();
+                               needsfloat = fl.needsFloatPkg();
+                               listcommand = fl.listCommand();
+                               refprefix = fl.refPrefix();
                        } 
                        break;
                case FT_NAME:
@@ -904,25 +974,33 @@ void TextClass::readFloat(Lexer & lexrc)
                        lexrc.next();
                        style = lexrc.getString();
                        break;
+               case FT_LISTCOMMAND:
+                       lexrc.next();
+                       listcommand = lexrc.getString();
+                       break;
+               case FT_REFPREFIX:
+                       lexrc.next();
+                       refprefix = lexrc.getString();
+                       break;
                case FT_LISTNAME:
                        lexrc.next();
-                       listName = lexrc.getString();
+                       listname = lexrc.getString();
                        break;
-               case FT_BUILTIN:
+               case FT_NEEDSFLOAT:
                        lexrc.next();
-                       builtin = lexrc.getBool();
+                       needsfloat = lexrc.getBool();
                        break;
-               case FT_HTMLCLASS:
+               case FT_HTMLATTR:
                        lexrc.next();
-                       htmlclass = lexrc.getString();
+                       htmlattr = lexrc.getString();
                        break;
                case FT_HTMLSTYLE:
                        lexrc.next();
                        htmlstyle = lexrc.getLongString("EndHTMLStyle");
                        break;
-               case FT_HTMLTYPE:
+               case FT_HTMLTAG:
                        lexrc.next();
-                       htmltype = lexrc.getString();
+                       htmltag = lexrc.getString();
                        break;
                case FT_END:
                        getout = true;
@@ -930,10 +1008,15 @@ void TextClass::readFloat(Lexer & lexrc)
                }
        }
 
-       // Here if have a full float if getout == true
+       // Here we have a full float if getout == true
        if (getout) {
+               if (!needsfloat && listcommand.empty())
+                       LYXERR0("The layout does not provide a list command " <<
+                               "for the builtin float `" << type << "'. LyX will " <<
+                               "not be able to produce a float list.");
                Floating fl(type, placement, ext, within, style, name, 
-                               listName, htmltype, htmlclass, htmlstyle, builtin);
+                               listname, listcommand, refprefix, 
+                               htmltag, htmlattr, htmlstyle, needsfloat);
                floatlist_.newFloat(fl);
                // each float has its own counter
                counters_.newCounter(from_ascii(type), from_ascii(within),
@@ -948,6 +1031,15 @@ void TextClass::readFloat(Lexer & lexrc)
 }
 
 
+string const & TextClass::prerequisites() const
+{ 
+       if (contains(prerequisites_, ',')) {
+               vector<string> const pres = getVectorFromString(prerequisites_);
+               prerequisites_ = getStringFromVector(pres, "\n\t");
+       }
+       return prerequisites_; 
+}
+
 bool TextClass::hasLayout(docstring const & n) const
 {
        docstring const name = n.empty() ? defaultLayoutName() : n;
@@ -1138,6 +1230,7 @@ Layout TextClass::createBasicLayout(docstring const & name, bool unknown) const
        return *defaultLayout;
 }
 
+
 /////////////////////////////////////////////////////////////////////////
 //
 // DocumentClassBundle
@@ -1174,7 +1267,7 @@ DocumentClass & DocumentClassBundle::makeDocumentClass(
        LayoutModuleList::const_iterator en = modlist.end();
        for (; it != en; it++) {
                string const modName = *it;
-               LyXModule * lm = moduleList[modName];
+               LyXModule * lm = theModuleList[modName];
                if (!lm) {
                        docstring const msg =
                                                bformat(_("The module %1$s has been requested by\n"
@@ -1237,6 +1330,53 @@ bool DocumentClass::hasTocLevels() const
 }
 
 
+Layout const & DocumentClass::htmlTOCLayout() const
+{
+       if (html_toc_section_.empty()) {
+               // we're going to look for the layout with the minimum toclevel
+               TextClass::LayoutList::const_iterator lit = begin();
+               TextClass::LayoutList::const_iterator const len = end();
+               int minlevel = 1000;
+               Layout const * lay = NULL;
+               for (; lit != len; ++lit) {
+                       int const level = lit->toclevel;
+                       // we don't want Part
+                       if (level == Layout::NOT_IN_TOC || level < 0 || level >= minlevel)
+                               continue;
+                       lay = &*lit;
+                       minlevel = level;
+               }
+               if (lay)
+                       html_toc_section_ = lay->name();
+               else
+                       // hmm. that is very odd, so we'll do our best
+                       html_toc_section_ = defaultLayoutName();
+       }
+       return operator[](html_toc_section_);
+}
+
+
+string const & DocumentClass::getCiteFormat(string const & entry_type) const
+{
+       static string default_format = N_("{%author%[[%author%, ]][[{%editor%[[%editor%, ed., ]]}]]}\"%title%\"{%journal%[[, {!<i>!}%journal%{!</i>!}]][[{%publisher%[[, %publisher%]][[{%institution%[[, %institution%]]}]]}]]}{%year%[[ (%year%)]]}{%pages%[[, %pages%]]}.");
+       
+       map<string, string>::const_iterator it = cite_formats_.find(entry_type);
+       if (it != cite_formats_.end())
+               return it->second;
+       return default_format;
+}
+
+
+string const & DocumentClass::getCiteMacro(string const & macro) const
+{
+       static string empty;
+       map<string, string>::const_iterator it = cite_macros_.find(macro);
+       if (it != cite_macros_.end())
+               return it->second;
+       return empty;
+}
+
+
 /////////////////////////////////////////////////////////////////////////
 //
 // PageSides