]> git.lyx.org Git - lyx.git/blobdiff - src/output_xhtml.cpp
New \cite_engine_type default.
[lyx.git] / src / output_xhtml.cpp
index cbb2c5c3d40514b8293176804f621b8e66ff46fa..5130740fb743a250e556f69527e4e09c05d3586b 100644 (file)
@@ -148,15 +148,7 @@ docstring cleanAttr(docstring const & str)
 }
 
 
-bool isFontTag(string const & s)
-{
-       return s == "em" || s == "strong" || s == "i" || s == "b"
-           || s == "dfn" || s == "kbd" || s == "var" || s == "samp"
-           || s == "del" || s == "u";
-}
-
-
-docstring StartTag::asTag() const
+docstring StartTag::writeTag() const
 {
        string output = "<" + tag_;
        if (!attr_.empty())
@@ -166,34 +158,40 @@ docstring StartTag::asTag() const
 }
 
 
-docstring StartTag::asEndTag() const
+docstring StartTag::writeEndTag() const
 {
        string output = "</" + tag_ + ">";
        return from_utf8(output);
 }
 
 
-docstring EndTag::asEndTag() const
+bool StartTag::operator==(FontTag const & rhs) const
+{
+       return rhs == *this;
+}
+
+
+docstring EndTag::writeEndTag() const
 {
        string output = "</" + tag_ + ">";
        return from_utf8(output);
 }
 
 
-docstring ParTag::asTag() const
+docstring ParTag::writeTag() const
 {
-       docstring output = StartTag::asTag();
+       docstring output = StartTag::writeTag();
 
        if (parid_.empty())
                return output;
 
        string const pattr = "id='" + parid_ + "'";
-       output += html::CompTag("a", pattr).asTag();
+       output += html::CompTag("a", pattr).writeTag();
        return output;
 }
 
 
-docstring CompTag::asTag() const
+docstring CompTag::writeTag() const
 {
        string output = "<" + tag_;
        if (!attr_.empty())
@@ -202,6 +200,129 @@ docstring CompTag::asTag() const
        return from_utf8(output);
 }
 
+
+
+namespace {
+
+string fontToTag(html::FontTypes type)
+ {
+       switch(type) {
+       case FT_EMPH:
+               return "em";
+       case FT_BOLD:
+               return "b";
+       case FT_NOUN:
+               return "dfn";
+       case FT_UBAR:
+       case FT_WAVE:
+       case FT_DBAR:
+               return "u";
+       case FT_SOUT:
+               return "del";
+       case FT_ITALIC:
+               return "i";
+       case FT_UPRIGHT:
+       case FT_SLANTED:
+       case FT_SMALLCAPS:
+       case FT_ROMAN:
+       case FT_SANS:
+       case FT_TYPE:
+       case FT_SIZE_TINY:
+       case FT_SIZE_SCRIPT:
+       case FT_SIZE_FOOTNOTE:
+       case FT_SIZE_SMALL:
+       case FT_SIZE_NORMAL:
+       case FT_SIZE_LARGE:
+       case FT_SIZE_LARGER:
+       case FT_SIZE_LARGEST:
+       case FT_SIZE_HUGE:
+       case FT_SIZE_HUGER:
+       case FT_SIZE_INCREASE:
+       case FT_SIZE_DECREASE:
+               return "span";
+       }
+       // kill warning
+       return "";
+}
+
+StartTag fontToStartTag(html::FontTypes type)
+ {
+       string tag = fontToTag(type);
+       switch(type) {
+       case FT_EMPH:
+               return html::StartTag(tag);
+       case FT_BOLD:
+               return html::StartTag(tag);
+       case FT_NOUN:
+               return html::StartTag(tag, "class='lyxnoun'");
+       case FT_UBAR:
+               return html::StartTag(tag);
+       case FT_DBAR:
+               return html::StartTag(tag, "class='dline'");
+       case FT_SOUT:
+               return html::StartTag(tag, "class='strikeout'");
+       case FT_WAVE:
+               return html::StartTag(tag, "class='wline'");
+       case FT_ITALIC:
+               return html::StartTag(tag);
+       case FT_UPRIGHT:
+               return html::StartTag(tag, "style='font-style:normal;'");
+       case FT_SLANTED:
+               return html::StartTag(tag, "style='font-style:oblique;'");
+       case FT_SMALLCAPS:
+               return html::StartTag(tag, "style='font-variant:small-caps;'");
+       case FT_ROMAN:
+               return html::StartTag(tag, "style='font-family:serif;'");
+       case FT_SANS:
+               return html::StartTag(tag, "style='font-family:sans-serif;'");
+       case FT_TYPE:
+               return html::StartTag(tag, "style='font-family:monospace;'");
+       case FT_SIZE_TINY:
+       case FT_SIZE_SCRIPT:
+       case FT_SIZE_FOOTNOTE:
+               return html::StartTag(tag, "style='font-size:x-small;'");
+       case FT_SIZE_SMALL:
+               return html::StartTag(tag, "style='font-size:small;'");
+       case FT_SIZE_NORMAL:
+               return html::StartTag(tag, "style='font-size:normal;'");
+       case FT_SIZE_LARGE:
+               return html::StartTag(tag, "style='font-size:large;'");
+       case FT_SIZE_LARGER:
+       case FT_SIZE_LARGEST:
+               return html::StartTag(tag, "style='font-size:x-large;'");
+       case FT_SIZE_HUGE:
+       case FT_SIZE_HUGER:
+               return html::StartTag(tag, "style='font-size:xx-large;'");
+       case FT_SIZE_INCREASE:
+               return html::StartTag(tag, "style='font-size:larger;'");
+       case FT_SIZE_DECREASE:
+               return html::StartTag(tag, "style='font-size:smaller;'");
+       }
+       // kill warning
+       return StartTag("");
+}
+
+} // end anonymous namespace
+
+
+FontTag::FontTag(FontTypes type)
+  : StartTag(fontToStartTag(type)), font_type_(type)
+{}
+
+
+bool FontTag::operator==(StartTag const & tag) const
+{
+       FontTag const * const ftag = tag.asFontTag();
+       if (!ftag)
+               return false;
+       return (font_type_ == ftag->font_type_);
+}
+
+
+EndFontTag::EndFontTag(FontTypes type)
+         : EndTag(fontToTag(type)), font_type_(type)
+{}
+
 } // namespace html
 
 
@@ -263,8 +384,8 @@ bool XHTMLStream::closeFontTags()
 
        // first, we close any open font tags we can close
        TagPtr curtag = tag_stack_.back();
-       while (html::isFontTag(curtag->tag_)) {
-               os_ << curtag->asEndTag();
+       while (curtag->asFontTag()) {
+               os_ << curtag->writeEndTag();
                tag_stack_.pop_back();
                // this shouldn't happen, since then the font tags
                // weren't in any other tag.
@@ -327,7 +448,7 @@ void XHTMLStream::endParagraph()
                if (*cur_tag == parsep_tag)
                        break;
                writeError("Tag `" + cur_tag->tag_ + "' still open at end of paragraph. Closing.");
-               os_ << cur_tag->asEndTag();
+               os_ << cur_tag->writeEndTag();
        }
 }
 
@@ -338,7 +459,7 @@ void XHTMLStream::clearTagDeque()
                TagPtr const tag = pending_tags_.front();
                if (*tag != parsep_tag)
                        // tabs?
-                       os_ << tag->asTag();
+                       os_ << tag->writeTag();
                tag_stack_.push_back(tag);
                pending_tags_.pop_front();
        }
@@ -423,12 +544,21 @@ XHTMLStream & XHTMLStream::operator<<(html::CompTag const & tag)
        if (tag.tag_.empty())
                return *this;
        clearTagDeque();
-       os_ << tag.asTag();
+       os_ << tag.writeTag();
        *this << html::CR();
        return *this;
 }
 
 
+XHTMLStream & XHTMLStream::operator<<(html::FontTag const & tag)
+{
+       if (tag.tag_.empty())
+               return *this;
+       pending_tags_.push_back(makeTagPtr(tag));
+       return *this;
+}
+
+
 XHTMLStream & XHTMLStream::operator<<(html::CR const &)
 {
        // tabs?
@@ -502,7 +632,8 @@ XHTMLStream & XHTMLStream::operator<<(html::EndTag const & etag)
                                // it was pending, so we just erase it
                                writeError("Tried to close pending tag `" + etag.tag_ 
                                        + "' when other tags were pending. Last pending tag is `"
-                                       + pending_tags_.back()->tag_ + "'. Tag discarded.");
+                                       + to_utf8(pending_tags_.back()->writeTag()) 
+                                       + "'. Tag discarded.");
                                pending_tags_.erase(dit);
                                return *this;
                        }
@@ -519,7 +650,7 @@ XHTMLStream & XHTMLStream::operator<<(html::EndTag const & etag)
                string estr = "Closing tag `" + etag.tag_ 
                        + "' when other tags are pending. Discarded pending tags:\n";
                for (dit = pending_tags_.begin(); dit != den; ++dit)
-                       estr += (*dit)->tag_ + "\n";
+                       estr += to_utf8(html::htmlize((*dit)->writeTag(), XHTMLStream::ESCAPE_ALL)) + "\n";
                writeError(estr);
                // clear the pending tags...
                pending_tags_.clear();
@@ -536,7 +667,7 @@ XHTMLStream & XHTMLStream::operator<<(html::EndTag const & etag)
        // is the tag we are closing the last one we opened?
        if (etag == *tag_stack_.back()) {
                // output it...
-               os_ << etag.asEndTag();
+               os_ << etag.writeEndTag();
                // ...and forget about it
                tag_stack_.pop_back();
                return *this;
@@ -553,7 +684,7 @@ XHTMLStream & XHTMLStream::operator<<(html::EndTag const & etag)
        // so the tag was opened, but other tags have been opened since
        // and not yet closed.
        // if it's a font tag, though...
-       if (html::isFontTag(etag.tag_)) {
+       if (etag.asFontTag()) {
                // it won't be a problem if the other tags open since this one
                // are also font tags.
                TagDeque::const_reverse_iterator rit = tag_stack_.rbegin();
@@ -561,7 +692,7 @@ XHTMLStream & XHTMLStream::operator<<(html::EndTag const & etag)
                for (; rit != ren; ++rit) {
                        if (etag == **rit)
                                break;
-                       if (!html::isFontTag((*rit)->tag_)) {
+                       if (!(*rit)->asFontTag()) {
                                // we'll just leave it and, presumably, have to close it later.
                                writeError("Unable to close font tag `" + etag.tag_ 
                                        + "' due to open non-font tag `" + (*rit)->tag_ + "'.");
@@ -578,13 +709,12 @@ XHTMLStream & XHTMLStream::operator<<(html::EndTag const & etag)
                // ...remembering them in a stack.
                TagDeque fontstack;
                while (etag != *curtag) {
-                       os_ << curtag->asEndTag();
+                       os_ << curtag->writeEndTag();
                        fontstack.push_back(curtag);
                        tag_stack_.pop_back();
                        curtag = tag_stack_.back();
                }
-               // now close our tag...
-               os_ << etag.asEndTag();
+    os_ << etag.writeEndTag();
                tag_stack_.pop_back();
 
                // ...and restore the other tags.
@@ -605,12 +735,12 @@ XHTMLStream & XHTMLStream::operator<<(html::EndTag const & etag)
        while (etag != *curtag) {
                writeError(curtag->tag_);
                if (*curtag != parsep_tag)
-                       os_ << curtag->asEndTag();
+                       os_ << curtag->writeEndTag();
                tag_stack_.pop_back();
                curtag = tag_stack_.back();
        }
        // curtag is now the one we actually want.
-       os_ << curtag->asEndTag();
+       os_ << curtag->writeEndTag();
        tag_stack_.pop_back();
        
        return *this;