]> git.lyx.org Git - lyx.git/blobdiff - src/Layout.cpp
Update my email and status.
[lyx.git] / src / Layout.cpp
index f1d76c6228298a936bc4cc026096680206433465..1eaa38aa5fa3b495a590ba70f858bfa736a6eb47 100644 (file)
 #include <config.h>
 
 #include "Layout.h"
+#include "Encoding.h"
+#include "FontInfo.h"
 #include "Language.h"
-#include "TextClass.h"
 #include "Lexer.h"
-#include "FontInfo.h"
+#include "output_xhtml.h"
+#include "TextClass.h"
 
-#include "support/Messages.h"
 #include "support/debug.h"
 #include "support/lassert.h"
 #include "support/lstrings.h"
+#include "support/Messages.h"
+#include "support/textutils.h"
 
-#include <boost/regex.hpp>
 
 using namespace std;
 using namespace lyx::support;
@@ -38,6 +40,7 @@ const int Layout::NOT_IN_TOC = -1000;
 enum LayoutTags {
        LT_ALIGN = 1,
        LT_ALIGNPOSSIBLE,
+       LT_ARGUMENT,
        LT_MARGIN,
        LT_BOTTOMSEP,
        LT_CATEGORY,
@@ -45,17 +48,12 @@ enum LayoutTags {
        LT_COPYSTYLE,
        LT_DEPENDSON,
        LT_OBSOLETEDBY,
-       //LT_EMPTY,
        LT_END,
-       //LT_ENVIRONMENT_DEFAULT,
-       //LT_FANCYHDR,
-       LT_FILL_BOTTOM,
-       LT_FILL_TOP,
-       //LT_FIRST_COUNTER,
        LT_FONT,
        LT_FREE_SPACING,
        LT_PASS_THRU,
-       //LT_HEADINGS,
+       LT_PARBREAK_IS_NEWLINE,
+       LT_ITEMCOMMAND,
        LT_ITEMSEP,
        LT_KEEPEMPTY,
        LT_LABEL_BOTTOMSEP,
@@ -71,8 +69,8 @@ enum LayoutTags {
        LT_ENDLABELTYPE,
        LT_LATEXNAME,
        LT_LATEXPARAM,
-       LT_OPTARGS,
        LT_LATEXTYPE,
+       LT_LEFTDELIM,
        LT_LEFTMARGIN,
        LT_NEED_PROTECT,
        LT_NEWLINE,
@@ -80,7 +78,6 @@ enum LayoutTags {
        LT_PARINDENT,
        LT_PARSEP,
        LT_PARSKIP,
-       //LT_PLAIN,
        LT_PREAMBLE,
        LT_LANGPREAMBLE,
        LT_BABELPREAMBLE,
@@ -103,6 +100,11 @@ enum LayoutTags {
        LT_HTMLSTYLE,
        LT_HTMLFORCECSS,
        LT_INPREAMBLE,
+       LT_HTMLTITLE,
+       LT_SPELLCHECK,
+       LT_REFPREFIX,
+       LT_RESETARGS,
+       LT_RIGHTDELIM,
        LT_INTITLE // keep this last!
 };
 
@@ -115,7 +117,6 @@ Layout::Layout()
        latextype = LATEX_PARAGRAPH;
        intitle = false;
        inpreamble = false;
-       optionalargs = 0;
        needprotect = false;
        keepempty = false;
        font = inherit_font;
@@ -135,15 +136,17 @@ Layout::Layout()
        endlabeltype = END_LABEL_NO_LABEL;
        // Should or should not. That is the question.
        // spacing.set(Spacing::OneHalf);
-       fill_top = false;
-       fill_bottom = false;
        newline_allowed = true;
        free_spacing = false;
        pass_thru = false;
+       parbreak_is_newline = false;
        toclevel = NOT_IN_TOC;
        commanddepth = 0;
        htmllabelfirst_ = false;
        htmlforcecss_ = false;
+       htmltitle_ = false;
+       spellcheck = true;
+       itemcommand_ = "item";
 }
 
 
@@ -153,6 +156,7 @@ bool Layout::read(Lexer & lex, TextClass const & tclass)
        LexerKeyword layoutTags[] = {
                { "align",          LT_ALIGN },
                { "alignpossible",  LT_ALIGNPOSSIBLE },
+               { "argument",       LT_ARGUMENT },
                { "babelpreamble",  LT_BABELPREAMBLE },
                { "bottomsep",      LT_BOTTOMSEP },
                { "category",       LT_CATEGORY },
@@ -162,8 +166,6 @@ bool Layout::read(Lexer & lex, TextClass const & tclass)
                { "end",            LT_END },
                { "endlabelstring", LT_ENDLABELSTRING },
                { "endlabeltype",   LT_ENDLABELTYPE },
-               { "fill_bottom",    LT_FILL_BOTTOM },
-               { "fill_top",       LT_FILL_TOP },
                { "font",           LT_FONT },
                { "freespacing",    LT_FREE_SPACING },
                { "htmlattr",       LT_HTMLATTR },
@@ -173,12 +175,14 @@ bool Layout::read(Lexer & lex, TextClass const & tclass)
                { "htmllabel",      LT_HTMLLABEL },
                { "htmllabelattr",  LT_HTMLLABELATTR },
                { "htmllabelfirst", LT_HTMLLABELFIRST },
-               { "htmlpremable",   LT_HTMLPREAMBLE },
+               { "htmlpreamble",   LT_HTMLPREAMBLE },
                { "htmlstyle",      LT_HTMLSTYLE },
                { "htmltag",        LT_HTMLTAG },
+               { "htmltitle",      LT_HTMLTITLE },
                { "innertag",       LT_INNERTAG },
-               { "intitle",        LT_INTITLE },
                { "inpreamble",     LT_INPREAMBLE },
+               { "intitle",        LT_INTITLE },
+               { "itemcommand",    LT_ITEMCOMMAND },
                { "itemsep",        LT_ITEMSEP },
                { "itemtag",        LT_ITEMTAG },
                { "keepempty",      LT_KEEPEMPTY },
@@ -195,21 +199,26 @@ bool Layout::read(Lexer & lex, TextClass const & tclass)
                { "latexname",      LT_LATEXNAME },
                { "latexparam",     LT_LATEXPARAM },
                { "latextype",      LT_LATEXTYPE },
+               { "leftdelim",      LT_LEFTDELIM },
                { "leftmargin",     LT_LEFTMARGIN },
                { "margin",         LT_MARGIN },
                { "needprotect",    LT_NEED_PROTECT },
                { "newline",        LT_NEWLINE },
                { "nextnoindent",   LT_NEXTNOINDENT },
                { "obsoletedby",    LT_OBSOLETEDBY },
-               { "optionalargs",   LT_OPTARGS },
+               { "parbreakisnewline", LT_PARBREAK_IS_NEWLINE },
                { "parindent",      LT_PARINDENT },
                { "parsep",         LT_PARSEP },
                { "parskip",        LT_PARSKIP },
                { "passthru",       LT_PASS_THRU },
                { "preamble",       LT_PREAMBLE },
+               { "refprefix",      LT_REFPREFIX },
                { "requires",       LT_REQUIRES },
+               { "resetargs",      LT_RESETARGS },
+               { "rightdelim",     LT_RIGHTDELIM },
                { "rightmargin",    LT_RIGHTMARGIN },
                { "spacing",        LT_SPACING },
+               { "spellcheck",     LT_SPELLCHECK },
                { "textfont",       LT_TEXTFONT },
                { "toclevel",       LT_TOCLEVEL },
                { "topsep",         LT_TOPSEP }
@@ -218,6 +227,7 @@ bool Layout::read(Lexer & lex, TextClass const & tclass)
        bool error = false;
        bool finished = false;
        lex.pushTable(layoutTags);
+
        // parse style section
        while (!finished && lex.isOK() && !error) {
                int le = lex.lex();
@@ -226,7 +236,8 @@ bool Layout::read(Lexer & lex, TextClass const & tclass)
                case Lexer::LEX_FEOF:
                        continue;
 
-               case Lexer::LEX_UNDEF:          // parse error
+               case Lexer::LEX_UNDEF:
+                       // parse error
                        lex.printError("Unknown layout tag `$$Token'");
                        error = true;
                        continue;
@@ -235,7 +246,7 @@ bool Layout::read(Lexer & lex, TextClass const & tclass)
                        break;
                }
                switch (static_cast<LayoutTags>(le)) {
-               case LT_END:            // end of structure
+               case LT_END:
                        finished = true;
                        break;
 
@@ -243,7 +254,7 @@ bool Layout::read(Lexer & lex, TextClass const & tclass)
                        lex >> category_;
                        break;
 
-               case LT_COPYSTYLE: {     // initialize with a known style
+               case LT_COPYSTYLE: {
                        docstring style;
                        lex >> style;
                        style = subst(style, '_', ' ');
@@ -264,7 +275,7 @@ bool Layout::read(Lexer & lex, TextClass const & tclass)
                        break;
                        }
 
-               case LT_OBSOLETEDBY: {   // replace with a known style
+               case LT_OBSOLETEDBY: {
                        docstring style;
                        lex >> style;
                        style = subst(style, '_', ' ');
@@ -291,11 +302,11 @@ bool Layout::read(Lexer & lex, TextClass const & tclass)
                        depends_on_ = subst(depends_on_, '_', ' ');
                        break;
 
-               case LT_MARGIN:         // margin style definition.
+               case LT_MARGIN:
                        readMargin(lex);
                        break;
 
-               case LT_LATEXTYPE:      // LaTeX style definition.
+               case LT_LATEXTYPE:
                        readLatexType(lex);
                        break;
 
@@ -311,8 +322,17 @@ bool Layout::read(Lexer & lex, TextClass const & tclass)
                        lex >> toclevel;
                        break;
 
-               case LT_OPTARGS:
-                       lex >> optionalargs ;
+               case LT_RESETARGS:
+                       bool reset;
+                       lex >> reset;
+                       if (reset) {
+                               latexargs_.clear();
+                               itemargs_.clear();
+                       }
+                       break;
+
+               case LT_ARGUMENT:
+                       readArgument(lex);
                        break;
 
                case LT_NEED_PROTECT:
@@ -336,7 +356,7 @@ bool Layout::read(Lexer & lex, TextClass const & tclass)
                        labelfont = lyxRead(lex, labelfont);
                        break;
 
-               case LT_NEXTNOINDENT:   // Indent next paragraph?
+               case LT_NEXTNOINDENT:
                        lex >> nextnoindent;
                        break;
 
@@ -353,6 +373,18 @@ bool Layout::read(Lexer & lex, TextClass const & tclass)
                        latexparam_ = subst(latexparam_, "&quot;", "\"");
                        break;
 
+               case LT_LEFTDELIM:
+                       lex >> leftdelim_;
+                       leftdelim_ = support::subst(leftdelim_, from_ascii("<br/>"),
+                                                   from_ascii("\n"));
+                       break;
+
+               case LT_RIGHTDELIM:
+                       lex >> rightdelim_;
+                       rightdelim_ = support::subst(rightdelim_, from_ascii("<br/>"),
+                                                    from_ascii("\n"));
+                       break;
+
                case LT_INNERTAG:
                        lex >> innertag_;
                        break;
@@ -365,6 +397,10 @@ bool Layout::read(Lexer & lex, TextClass const & tclass)
                        lex >> itemtag_;
                        break;
 
+               case LT_ITEMCOMMAND:
+                       lex >> itemcommand_;
+                       break;
+
                case LT_PREAMBLE:
                        preamble_ = from_utf8(lex.getLongString("EndPreamble"));
                        break;
@@ -385,71 +421,64 @@ bool Layout::read(Lexer & lex, TextClass const & tclass)
                        readEndLabelType(lex);
                        break;
 
-               case LT_LEFTMARGIN:     // left margin type
+               case LT_LEFTMARGIN:
                        lex >> leftmargin;
                        break;
 
-               case LT_RIGHTMARGIN:    // right margin type
+               case LT_RIGHTMARGIN:
                        lex >> rightmargin;
                        break;
 
-               case LT_LABELINDENT:    // label indenting flag
+               case LT_LABELINDENT:
                        lex >> labelindent;
                        break;
 
-               case LT_PARINDENT:      // paragraph indent. flag
+               case LT_PARINDENT:
                        lex >> parindent;
                        break;
 
-               case LT_PARSKIP:        // paragraph skip size
+               case LT_PARSKIP:
                        lex >> parskip;
                        break;
 
-               case LT_ITEMSEP:        // item separation size
+               case LT_ITEMSEP:
                        lex >> itemsep;
                        break;
 
-               case LT_TOPSEP:         // top separation size
+               case LT_TOPSEP:
                        lex >> topsep;
                        break;
 
-               case LT_BOTTOMSEP:      // bottom separation size
+               case LT_BOTTOMSEP:
                        lex >> bottomsep;
                        break;
 
-               case LT_LABEL_BOTTOMSEP: // label bottom separation size
+               case LT_LABEL_BOTTOMSEP:
                        lex >> labelbottomsep;
                        break;
 
-               case LT_LABELSEP:       // label separator
+               case LT_LABELSEP:
                        lex >> labelsep;
                        labelsep = subst(labelsep, 'x', ' ');
                        break;
 
-               case LT_PARSEP:         // par. separation size
+               case LT_PARSEP:
                        lex >> parsep;
                        break;
 
-               case LT_FILL_TOP:       // fill top flag
-                       lex >> fill_top;
-                       break;
-
-               case LT_FILL_BOTTOM:    // fill bottom flag
-                       lex >> fill_bottom;
-                       break;
-
-               case LT_NEWLINE:        // newlines allowed?
+               case LT_NEWLINE:
                        lex >> newline_allowed;
                        break;
 
-               case LT_ALIGN:          // paragraph align
+               case LT_ALIGN:
                        readAlign(lex);
                        break;
-               case LT_ALIGNPOSSIBLE:  // paragraph allowed align
+       
+               case LT_ALIGNPOSSIBLE:
                        readAlignPossible(lex);
                        break;
 
-               case LT_LABELSTRING:    // label string definition
+               case LT_LABELSTRING:
                        // FIXME: this means LT_ENDLABELSTRING may only
                        // occur after LT_LABELSTRING
                        lex >> labelstring_;
@@ -457,30 +486,34 @@ bool Layout::read(Lexer & lex, TextClass const & tclass)
                        labelstring_appendix_ = labelstring_;
                        break;
 
-               case LT_ENDLABELSTRING: // endlabel string definition
+               case LT_ENDLABELSTRING:
                        lex >> endlabelstring_; 
                        endlabelstring_ = trim(endlabelstring_);
                        break;
 
-               case LT_LABELSTRING_APPENDIX: // label string appendix definition
+               case LT_LABELSTRING_APPENDIX:
                        lex >> labelstring_appendix_;   
                        labelstring_appendix_ = trim(labelstring_appendix_);
                        break;
 
-               case LT_LABELCOUNTER: // name of counter to use
+               case LT_LABELCOUNTER:
                        lex >> counter; 
                        counter = trim(counter);
                        break;
 
-               case LT_FREE_SPACING:   // Allow for free spacing.
+               case LT_FREE_SPACING:
                        lex >> free_spacing;
                        break;
 
-               case LT_PASS_THRU:      // Allow for pass thru.
+               case LT_PASS_THRU:
                        lex >> pass_thru;
                        break;
 
-               case LT_SPACING: // setspace.sty
+               case LT_PARBREAK_IS_NEWLINE:
+                       lex >> parbreak_is_newline;
+                       break;
+
+               case LT_SPACING:
                        readSpacing(lex);
                        break;
 
@@ -491,6 +524,16 @@ bool Layout::read(Lexer & lex, TextClass const & tclass)
                        requires_.insert(req.begin(), req.end());
                        break;
                }
+                       
+               case LT_REFPREFIX: {
+                       docstring arg;
+                       lex >> arg;
+                       if (arg == "OFF")
+                               refprefix.clear();
+                       else
+                               refprefix = arg;
+                       break;
+               }
 
                case LT_HTMLTAG:
                        lex >> htmltag_;
@@ -526,16 +569,30 @@ bool Layout::read(Lexer & lex, TextClass const & tclass)
 
                case LT_HTMLFORCECSS:
                        lex >> htmlforcecss_;
+                       break;
 
                case LT_HTMLPREAMBLE:
                        htmlpreamble_ = from_utf8(lex.getLongString("EndPreamble"));
                        break;
+               
+               case LT_HTMLTITLE:
+                       lex >> htmltitle_;
+                       break;
 
+               case LT_SPELLCHECK:
+                       lex >> spellcheck;
+                       break;
                }
        }
        lex.popTable();
+       // make sure we only have inpreamble = true for commands
+       if (inpreamble && latextype != LATEX_COMMAND && latextype != LATEX_PARAGRAPH) {
+               LYXERR0("InPreamble not permitted except with command and paragraph layouts.");
+               LYXERR0("Layout name: " << name());
+               inpreamble = false;
+       }
 
-       return !error;
+       return finished && !error;
 }
 
 
@@ -827,52 +884,124 @@ void Layout::readSpacing(Lexer & lex)
 }
 
 
-namespace {
-
-docstring const i18npreamble(Language const * lang, docstring const & templ)
+void Layout::readArgument(Lexer & lex)
 {
-       if (templ.empty())
-               return templ;
-
-       string preamble = subst(to_utf8(templ), "$$lang", lang->babel());
-
-#ifdef TEX2LYX
-       // tex2lyx does not have getMessages()
-       LASSERT(false, /**/);
-#else
-       // FIXME UNICODE
-       // boost::regex is not unicode-safe.
-       // Should use QRegExp or (boost::u32regex, but that requires ICU)
-       static boost::regex const reg("_\\(([^\\)]+)\\)");
-       boost::smatch sub;
-       while (boost::regex_search(preamble, sub, reg)) {
-               string const key = sub.str(1);
-               string translated;
-               if (isAscii(key))
-                       translated = to_utf8(getMessages(lang->code()).get(key));
-               else {
-                       lyxerr << "Warning: not translating `" << key
-                              << "' because it is not pure ASCII." << endl;
-                       translated = key;
+       latexarg arg;
+       arg.mandatory = false;
+       arg.autoinsert = false;
+       bool error = false;
+       bool finished = false;
+       arg.font = inherit_font;
+       arg.labelfont = inherit_font;
+       string id;
+       lex >> id;
+       bool const itemarg = prefixIs(id, "item:");
+       bool const postcmd = prefixIs(id, "post:");
+
+       while (!finished && lex.isOK() && !error) {
+               lex.next();
+               string const tok = ascii_lowercase(lex.getString());
+
+               if (tok.empty()) {
+                       continue;
+               } else if (tok == "endargument") {
+                       finished = true;
+               } else if (tok == "labelstring") {
+                       lex.next();
+                       arg.labelstring = lex.getDocString();
+               } else if (tok == "menustring") {
+                       lex.next();
+                       arg.menustring = lex.getDocString();
+               } else if (tok == "mandatory") {
+                       lex.next();
+                       arg.mandatory = lex.getBool();
+               } else if (tok == "autoinsert") {
+                       lex.next();
+                       arg.autoinsert = lex.getBool();
+               } else if (tok == "leftdelim") {
+                       lex.next();
+                       arg.ldelim = lex.getDocString();
+                       arg.ldelim = support::subst(arg.ldelim, from_ascii("<br/>"),
+                                                   from_ascii("\n"));
+               } else if (tok == "rightdelim") {
+                       lex.next();
+                       arg.rdelim = lex.getDocString();
+                       arg.rdelim = support::subst(arg.rdelim, from_ascii("<br/>"),
+                                                   from_ascii("\n"));
+               } else if (tok == "presetarg") {
+                       lex.next();
+                       arg.presetarg = lex.getDocString();
+               } else if (tok == "tooltip") {
+                       lex.next();
+                       arg.tooltip = lex.getDocString();
+               } else if (tok == "requires") {
+                       lex.next();
+                       arg.requires = lex.getString();
+               } else if (tok == "decoration") {
+                       lex.next();
+                       arg.decoration = lex.getString();
+               } else if (tok == "font") {
+                       arg.font = lyxRead(lex, arg.font);
+               } else if (tok == "labelfont") {
+                       arg.labelfont = lyxRead(lex, arg.labelfont);
+               } else {
+                       lex.printError("Unknown tag");
+                       error = true;
                }
-               preamble = subst(preamble, sub.str(), translated);
        }
-#endif
-       return from_utf8(preamble);
+       if (arg.labelstring.empty())
+               LYXERR0("Incomplete Argument definition!");
+       else if (itemarg)
+               itemargs_[id] = arg;
+       else if (postcmd)
+               postcommandargs_[id] = arg;
+       else
+               latexargs_[id] = arg;
 }
 
+
+Layout::LaTeXArgMap Layout::args() const
+{
+       LaTeXArgMap args = latexargs_;
+       if (!postcommandargs_.empty())
+               args.insert(postcommandargs_.begin(), postcommandargs_.end());
+       if (!itemargs_.empty())
+               args.insert(itemargs_.begin(), itemargs_.end());
+       return args;
 }
 
 
-docstring const Layout::langpreamble(Language const * lang) const
+int Layout::optArgs() const
 {
-       return i18npreamble(lang, langpreamble_);
+       int nr = 0;
+       LaTeXArgMap::const_iterator it = latexargs_.begin();
+       for (; it != latexargs_.end(); ++it) {
+               if (!(*it).second.mandatory)
+                       ++nr;
+       }
+       LaTeXArgMap::const_iterator iit = postcommandargs_.begin();
+       for (; iit != postcommandargs_.end(); ++iit) {
+               if (!(*iit).second.mandatory)
+                       ++nr;
+       }
+       return nr;
 }
 
 
-docstring const Layout::babelpreamble(Language const * lang) const
+int Layout::requiredArgs() const
 {
-       return i18npreamble(lang, babelpreamble_);
+       int nr = 0;
+       LaTeXArgMap::const_iterator it = latexargs_.begin();
+       for (; it != latexargs_.end(); ++it) {
+               if ((*it).second.mandatory)
+                       ++nr;
+       }
+       LaTeXArgMap::const_iterator iit = postcommandargs_.begin();
+       for (; iit != postcommandargs_.end(); ++iit) {
+               if (!(*iit).second.mandatory)
+                       ++nr;
+       }
+       return nr;
 }
 
 
@@ -910,8 +1039,13 @@ string const & Layout::htmlitemattr() const
 
 string const & Layout::htmllabeltag() const 
 { 
-       if (htmllabeltag_.empty())
-               htmllabeltag_ = "span";
+       if (htmllabeltag_.empty()) {
+               if (labeltype != LABEL_TOP_ENVIRONMENT &&
+                   labeltype != LABEL_CENTERED_TOP_ENVIRONMENT)
+                       htmllabeltag_ = "span";
+               else
+                       htmllabeltag_ = "div";
+       }
        return htmllabeltag_; 
 }
 
@@ -924,7 +1058,8 @@ string const & Layout::htmllabelattr() const
 }
 
 
-docstring Layout::htmlstyle() const {
+docstring Layout::htmlstyle() const
+{
        if (!htmlstyle_.empty() && !htmlforcecss_)
                return htmlstyle_;
        if (htmldefaultstyle_.empty()) 
@@ -944,40 +1079,100 @@ string Layout::defaultCSSClass() const
        docstring::const_iterator it = name().begin();
        docstring::const_iterator en = name().end();
        for (; it != en; ++it) {
-               if (!isalpha(*it))
-                       continue;
-               if (islower(*it))
-                       d += *it;
-               else 
-                       d += lowercase(*it);
+               char_type const c = *it;
+               if (!isAlphaASCII(c)) {
+                       if (d.empty())
+                               // make sure we don't start with an underscore,
+                               // as that sometimes causes problems.
+                               d = from_ascii("lyx_");
+                       else
+                               d += '_';
+               } else if (isLower(c))
+                       d += c;
+               else
+                       // this is slow, so do it only if necessary
+                       d += lowercase(c);
        }
-       // are there other characters we need to remove?
        defaultcssclass_ = to_utf8(d);
        return defaultcssclass_;
 }
 
 
-// NOTE There is a whole ton of stuff that could go into this.
-// Things like bottomsep, topsep, and parsep could become various
-// sorts of margins or padding, for example. But for now we are
-// going to keep it simple.
-void Layout::makeDefaultCSS() const {
+namespace {
+
+string makeMarginValue(char const * side, double d)
+{
+       ostringstream os;
+       os << "margin-" << side << ": " << d << "ex;\n";
+       return os.str();
+}
+
+}
+
+
+void Layout::makeDefaultCSS() const
+{
        // this never needs to be redone, since reloading layouts will
        // wipe out what we did before.
        if (!htmldefaultstyle_.empty()) 
                return;
-       docstring const mainfontCSS = font.asCSS();
-       if (!mainfontCSS.empty())
+       
+       // main font
+       htmldefaultstyle_ = font.asCSS();
+       
+       // bottom margins
+       string tmp;
+       if (topsep > 0)
+               tmp += makeMarginValue("top", topsep);
+       if (bottomsep > 0)
+               tmp += makeMarginValue("bottom", bottomsep);
+       if (!leftmargin.empty()) {
+               // we can't really do what LyX does with the margin, so 
+               // we'll just figure out how many characters it is
+               int const len = leftmargin.length();
+               tmp += makeMarginValue("left", len);
+       }
+       if (!rightmargin.empty()) {
+               int const len = rightmargin.length();
+               tmp += makeMarginValue("right", len);
+       }
+               
+       if (!tmp.empty()) {
+               if (!htmldefaultstyle_.empty())
+                       htmldefaultstyle_ += from_ascii("\n");
+               htmldefaultstyle_ += from_ascii(tmp);
+       }
+
+// tex2lyx does not see output_xhtml.cpp
+#ifndef TEX2LYX
+       // alignment
+       string where = alignmentToCSS(align);
+       if (!where.empty()) {
+               htmldefaultstyle_ += from_ascii("text-align: " + where + ";\n");
+       }
+#endif
+       
+       // wrap up what we have, if anything
+       if (!htmldefaultstyle_.empty())
                htmldefaultstyle_ = 
                        from_ascii(htmltag() + "." + defaultCSSClass() + " {\n") +
-                       mainfontCSS + from_ascii("\n}\n");
-       if (labelfont == font || htmllabeltag() == "NONE")
+                       htmldefaultstyle_ + from_ascii("\n}\n");
+       
+       if (labeltype == LABEL_NO_LABEL || htmllabeltag() == "NONE")
                return;
-       docstring const labelfontCSS = labelfont.asCSS();
-       if (!labelfontCSS.empty())
+       
+       docstring labelCSS;
+       
+       // label font
+       if (labelfont != font)
+               labelCSS = labelfont.asCSS() + from_ascii("\n");
+       if (labeltype == LABEL_CENTERED_TOP_ENVIRONMENT)
+               labelCSS += from_ascii("text-align: center;\n");
+       
+       if (!labelCSS.empty())
                htmldefaultstyle_ +=
                        from_ascii(htmllabeltag() + "." + defaultCSSLabelClass() + " {\n") +
-                       labelfontCSS + from_ascii("\n}\n");
+                       labelCSS + from_ascii("\n}\n");
 }