From 64f0cffbba33c9a02e8f1f5d3b825d8e79257012 Mon Sep 17 00:00:00 2001 From: Richard Heck Date: Tue, 7 May 2013 02:30:26 -0400 Subject: [PATCH] Rework the way the parsep tag is handled, and introduce comparison operators for these tags. --- src/output_xhtml.cpp | 64 +++++++++++++++++++++++++------------------- src/output_xhtml.h | 62 +++++++++++++++++++++++++++++++++++++++--- 2 files changed, 96 insertions(+), 30 deletions(-) diff --git a/src/output_xhtml.cpp b/src/output_xhtml.cpp index b06f8bd5d1..cbb2c5c3d4 100644 --- a/src/output_xhtml.cpp +++ b/src/output_xhtml.cpp @@ -173,6 +173,13 @@ docstring StartTag::asEndTag() const } +docstring EndTag::asEndTag() const +{ + string output = ""; + return from_utf8(output); +} + + docstring ParTag::asTag() const { docstring output = StartTag::asTag(); @@ -186,13 +193,6 @@ docstring ParTag::asTag() const } -docstring EndTag::asEndTag() const -{ - string output = ""; - return from_utf8(output); -} - - docstring CompTag::asTag() const { string output = "<" + tag_; @@ -246,7 +246,7 @@ void XHTMLStream::writeError(std::string const & s) const namespace { // an illegal tag for internal use - static string const parsep_tag = "&LyX_parsep_tag&"; + static html::StartTag const parsep_tag("&LyX_parsep_tag&"); } @@ -272,7 +272,7 @@ bool XHTMLStream::closeFontTags() curtag = tag_stack_.back(); } - if (curtag->tag_ == parsep_tag) + if (*curtag == parsep_tag) return true; // so we've hit a non-font tag. @@ -281,8 +281,7 @@ bool XHTMLStream::closeFontTags() TagDeque::const_reverse_iterator it = tag_stack_.rbegin(); TagDeque::const_reverse_iterator const en = tag_stack_.rend(); for (; it != en; ++it) { - string const tagname = (*it)->tag_; - if (tagname == parsep_tag) + if (**it == parsep_tag) break; writeError((*it)->tag_); } @@ -309,7 +308,7 @@ void XHTMLStream::endParagraph() // of everything that hasn't been used. TagPtr const cur_tag = pending_tags_.back(); pending_tags_.pop_back(); - if (cur_tag->tag_ == parsep_tag) + if (*cur_tag == parsep_tag) break; } return; @@ -325,7 +324,7 @@ void XHTMLStream::endParagraph() while (!tag_stack_.empty()) { TagPtr const cur_tag = tag_stack_.back(); tag_stack_.pop_back(); - if (cur_tag->tag_ == parsep_tag) + if (*cur_tag == parsep_tag) break; writeError("Tag `" + cur_tag->tag_ + "' still open at end of paragraph. Closing."); os_ << cur_tag->asEndTag(); @@ -337,7 +336,7 @@ void XHTMLStream::clearTagDeque() { while (!pending_tags_.empty()) { TagPtr const tag = pending_tags_.front(); - if (tag->tag_ != parsep_tag) + if (*tag != parsep_tag) // tabs? os_ << tag->asTag(); tag_stack_.push_back(tag); @@ -438,23 +437,34 @@ XHTMLStream & XHTMLStream::operator<<(html::CR const &) } -bool XHTMLStream::isTagOpen(string const & stag) const +bool XHTMLStream::isTagOpen(html::StartTag const & stag) const { TagDeque::const_iterator sit = tag_stack_.begin(); TagDeque::const_iterator const sen = tag_stack_.end(); for (; sit != sen; ++sit) - if ((*sit)->tag_ == stag) + if (**sit == stag) return true; return false; } -bool XHTMLStream::isTagPending(string const & stag) const +bool XHTMLStream::isTagOpen(html::EndTag const & etag) const +{ + TagDeque::const_iterator sit = tag_stack_.begin(); + TagDeque::const_iterator const sen = tag_stack_.end(); + for (; sit != sen; ++sit) + if (etag == **sit) + return true; + return false; +} + + +bool XHTMLStream::isTagPending(html::StartTag const & stag) const { TagDeque::const_iterator sit = pending_tags_.begin(); TagDeque::const_iterator const sen = pending_tags_.end(); for (; sit != sen; ++sit) - if ((*sit)->tag_ == stag) + if (**sit == stag) return true; return false; } @@ -473,7 +483,7 @@ XHTMLStream & XHTMLStream::operator<<(html::EndTag const & etag) // if this tag is pending, we can simply discard it. if (!pending_tags_.empty()) { - if (etag.tag_ == pending_tags_.back()->tag_) { + if (etag == *pending_tags_.back()) { // we have , so we discard it and remove it // from the pending_tags_. pending_tags_.pop_back(); @@ -488,7 +498,7 @@ XHTMLStream & XHTMLStream::operator<<(html::EndTag const & etag) TagDeque::iterator dit = pending_tags_.begin(); TagDeque::iterator const den = pending_tags_.end(); for (; dit != den; ++dit) { - if ((*dit)->tag_ == etag.tag_) { + if (etag == **dit) { // 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 `" @@ -498,7 +508,7 @@ XHTMLStream & XHTMLStream::operator<<(html::EndTag const & etag) } } // so etag isn't itself pending. is it even open? - if (!isTagOpen(etag.tag_)) { + if (!isTagOpen(etag)) { writeError("Tried to close `" + etag.tag_ + "' when tag was not open. Tag discarded."); return *this; @@ -524,7 +534,7 @@ XHTMLStream & XHTMLStream::operator<<(html::EndTag const & etag) } // is the tag we are closing the last one we opened? - if (etag.tag_ == tag_stack_.back()->tag_) { + if (etag == *tag_stack_.back()) { // output it... os_ << etag.asEndTag(); // ...and forget about it @@ -534,7 +544,7 @@ XHTMLStream & XHTMLStream::operator<<(html::EndTag const & etag) // we are trying to close a tag other than the one last opened. // let's first see if this particular tag is still open somehow. - if (!isTagOpen(etag.tag_)) { + if (!isTagOpen(etag)) { writeError("Tried to close `" + etag.tag_ + "' when tag was not open. Tag discarded."); return *this; @@ -549,7 +559,7 @@ XHTMLStream & XHTMLStream::operator<<(html::EndTag const & etag) TagDeque::const_reverse_iterator rit = tag_stack_.rbegin(); TagDeque::const_reverse_iterator ren = tag_stack_.rend(); for (; rit != ren; ++rit) { - if ((*rit)->tag_ == etag.tag_) + if (etag == **rit) break; if (!html::isFontTag((*rit)->tag_)) { // we'll just leave it and, presumably, have to close it later. @@ -567,7 +577,7 @@ XHTMLStream & XHTMLStream::operator<<(html::EndTag const & etag) TagPtr curtag = tag_stack_.back(); // ...remembering them in a stack. TagDeque fontstack; - while (etag.tag_ != curtag->tag_) { + while (etag != *curtag) { os_ << curtag->asEndTag(); fontstack.push_back(curtag); tag_stack_.pop_back(); @@ -592,9 +602,9 @@ XHTMLStream & XHTMLStream::operator<<(html::EndTag const & etag) writeError("Closing tag `" + etag.tag_ + "' when other tags are open, namely:"); TagPtr curtag = tag_stack_.back(); - while (etag.tag_ != curtag->tag_) { + while (etag != *curtag) { writeError(curtag->tag_); - if (curtag->tag_ != parsep_tag) + if (*curtag != parsep_tag) os_ << curtag->asEndTag(); tag_stack_.pop_back(); curtag = tag_stack_.back(); diff --git a/src/output_xhtml.h b/src/output_xhtml.h index ceabc42dcf..0bcc9849c0 100644 --- a/src/output_xhtml.h +++ b/src/output_xhtml.h @@ -30,6 +30,7 @@ class Text; // came from MathStream and its cousins. namespace html { + /// Attributes will be escaped automatically and so should NOT /// be escaped before being passed to the constructor. struct StartTag @@ -47,6 +48,12 @@ struct StartTag /// virtual docstring asEndTag() const; /// + bool operator==(StartTag const & rhs) const + { return tag_ == rhs.tag_; } + /// + bool operator!=(StartTag const & rhs) const + { return !(*this == rhs); } + /// std::string tag_; /// std::string attr_; @@ -60,7 +67,7 @@ struct StartTag struct ParTag : public StartTag { /// - ParTag(std::string const & tag, std::string const & attr, + explicit ParTag(std::string const & tag, std::string const & attr, std::string const & parid) : StartTag(tag, attr), parid_(parid) {} @@ -73,6 +80,47 @@ struct ParTag : public StartTag }; +/// +enum FontTypes { + FT_EMPH, + FT_BOLD, + FT_NOUN, + FT_UBAR, + FT_DBAR, + FT_SOUT, + FT_WAVE, + FT_ITALIC, + FT_SLANTED, + FT_SMALLCAPS, + FT_ROMAN, + FT_SANS, + FT_TYPER + // SIZES? +}; + + +/// +struct FontTag : public StartTag +{ + /// + explicit FontTag(FontTypes type); + /// + docstring asTag() const; + /// + docstring asEndTag() const; + /// + bool isFontTag() { return true; } + /// + bool operator==(FontTag const & rhs) + { return font_type_ == rhs.font_type_; } + /// Asserts. + bool operator==(StartTag const &); + /// + FontTypes font_type_; +}; + + +/// struct EndTag { /// @@ -80,6 +128,12 @@ struct EndTag /// docstring asEndTag() const; /// + bool operator==(StartTag const & rhs) const + { return tag_ == rhs.tag_; } + /// + bool operator!=(StartTag const & rhs) const + { return !(*this == rhs); } + /// std::string tag_; }; @@ -167,9 +221,11 @@ private: /// void clearTagDeque(); /// - bool isTagOpen(std::string const &) const; + bool isTagOpen(html::StartTag const &) const; /// - bool isTagPending(std::string const &) const; + bool isTagOpen(html::EndTag const &) const; + /// + bool isTagPending(html::StartTag const &) const; /// void writeError(std::string const &) const; ///