X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Fxml.h;h=346e42d78cd803d9cf99c7a06afd9db3058d9670;hb=26ba2a65838731ce639a09539f617cb0f0be3b22;hp=857867ba905a85c8d717d3ff2d4d0a0ce4a2cd2d;hpb=b5adcec28aac69e722e8b2bbf28ad2974010f853;p=lyx.git diff --git a/src/xml.h b/src/xml.h index 857867ba90..346e42d78c 100644 --- a/src/xml.h +++ b/src/xml.h @@ -25,12 +25,13 @@ class Paragraph; class OutputParams; // Inspiration for the *Tag structs and for XMLStream -// came from MathStream and its cousins. +// came from MathMLStream and its cousins. namespace xml { struct StartTag; struct EndTag; struct CompTag; +struct NullTag; struct ParTag; struct FontTag; struct CR; @@ -67,6 +68,8 @@ public: /// XMLStream & operator<<(char); /// + XMLStream & operator<<(xml::NullTag const &); + /// XMLStream & operator<<(xml::StartTag const &); /// XMLStream & operator<<(xml::EndTag const &); @@ -101,7 +104,7 @@ public: /// Is the last tag that was added to the stream a new line (CR)? This is mostly to known /// whether a new line must be added. Therefore, consider that an empty stream just had a CR, /// that simplifies the logic using this code. - bool isLastTagCR() const { return is_last_tag_cr_; }; + bool isLastTagCR() const { return is_last_tag_cr_; } /// void writeError(std::string const &); /// @@ -143,6 +146,7 @@ namespace xml { docstring escapeChar(char_type c, XMLStream::EscapeSettings e); /// Escape the given character, if necessary, to an entity. +/// \param c must be ASCII docstring escapeChar(char c, XMLStream::EscapeSettings e); /// Escape a word instead of a single character @@ -151,9 +155,6 @@ docstring escapeString(docstring const & raw, XMLStream::EscapeSettings e=XMLStr /// cleans \param str for use as an attribute by replacing all non-altnum by "_" docstring cleanAttr(docstring const & str); -/// \p c must be ASCII -docstring escapeChar(char c, XMLStream::EscapeSettings e); - /// replaces illegal characters from ID attributes docstring cleanID(docstring const &orig); @@ -174,23 +175,23 @@ struct EndFontTag; struct StartTag { /// - explicit StartTag(std::string const & tag) : tag_(from_ascii(tag)), keepempty_(false) {} + explicit StartTag(std::string const & tag) : tag_(from_ascii(tag)), keepempty_(false), tagtype_("none") {} /// - explicit StartTag(docstring const & tag) : tag_(tag), keepempty_(false) {} + explicit StartTag(docstring const & tag) : tag_(tag), keepempty_(false), tagtype_("none") {} /// explicit StartTag(docstring const & tag, docstring const & attr, - bool keepempty = false) - : tag_(tag), attr_(attr), keepempty_(keepempty) {} + bool keepempty = false, std::string const & tagtype = "none") + : tag_(tag), attr_(attr), keepempty_(keepempty), tagtype_(tagtype) {} /// explicit StartTag(std::string const & tag, std::string const & attr, - bool keepempty = false) - : tag_(from_ascii(tag)), attr_(from_utf8(attr)), keepempty_(keepempty) {} + bool keepempty = false, std::string const & tagtype = "none") + : tag_(from_ascii(tag)), attr_(from_utf8(attr)), keepempty_(keepempty), tagtype_(tagtype) {} /// explicit StartTag(std::string const & tag, docstring const & attr, - bool keepempty = false) - : tag_(from_ascii(tag)), attr_(attr), keepempty_(keepempty) {} + bool keepempty = false, std::string const & tagtype = "none") + : tag_(from_ascii(tag)), attr_(attr), keepempty_(keepempty), tagtype_(tagtype) {} /// - virtual ~StartTag() {} + virtual ~StartTag() = default; /// virtual docstring writeTag() const; /// @@ -198,20 +199,14 @@ struct StartTag /// virtual FontTag const * asFontTag() const { return nullptr; } /// - virtual bool operator==(StartTag const & rhs) const - { return tag_ == rhs.tag_; } - /// - virtual bool operator!=(StartTag const & rhs) const - { return !(*this == rhs); } - /// - virtual bool operator==(FontTag const & rhs) const; - /// docstring tag_; /// docstring attr_; /// whether to keep things like "" or discard them /// you would want this for td, e.g, but maybe not for a div bool keepempty_; + /// Type of tag for new-line behaviour. Either "paragraph", "inline", "block", or "none" (default). + std::string tagtype_; }; @@ -219,23 +214,22 @@ struct StartTag struct EndTag { /// - explicit EndTag(std::string tag) : tag_(from_ascii(tag)) {} + explicit EndTag(std::string const & tag, std::string const & tagtype = "none") + : tag_(from_ascii(tag)), tagtype_(tagtype) {} /// - explicit EndTag(docstring tag) : tag_(tag) {} + explicit EndTag(docstring const & tag, std::string const & tagtype = "none") + : tag_(tag), tagtype_(tagtype) {} /// - virtual ~EndTag() {} + virtual ~EndTag() = default; /// virtual docstring writeEndTag() const; /// - bool operator==(StartTag const & rhs) const - { return tag_ == rhs.tag_; } - /// - bool operator!=(StartTag const & rhs) const - { return !(*this == rhs); } - /// - virtual EndFontTag const * asFontTag() const { return 0; } + virtual EndFontTag const * asFontTag() const { return nullptr; } /// docstring tag_; + /// Type of tag for new-line behaviour. Either "paragraph", "inline", "block", or "none" (default). + /// The value should match that of the corresponding xml::StartTag. + std::string tagtype_; }; @@ -246,30 +240,50 @@ struct CompTag { /// explicit CompTag(std::string const & tag) - : tag_(from_utf8(tag)) {} + : tag_(from_utf8(tag)), tagtype_("none") {} /// - explicit CompTag(std::string const & tag, std::string const & attr) - : tag_(from_utf8(tag)), attr_(from_utf8(attr)) {} + explicit CompTag(docstring const & tag) + : tag_(tag), tagtype_("none") {} /// - explicit CompTag(std::string const & tag, docstring const & attr) - : tag_(from_utf8(tag)), attr_(attr) {} + explicit CompTag(std::string const & tag, std::string const & attr, std::string const & tagtype = "none") + : tag_(from_utf8(tag)), attr_(from_utf8(attr)), tagtype_(tagtype) {} + /// + explicit CompTag(std::string const & tag, docstring const & attr, std::string const & tagtype = "none") + : tag_(from_utf8(tag)), attr_(attr), tagtype_(tagtype) {} + /// + explicit CompTag(docstring const & tag, std::string const & attr, std::string const & tagtype = "none") + : tag_(tag), attr_(from_utf8(attr)), tagtype_(tagtype) {} + /// + explicit CompTag(docstring const & tag, docstring const & attr, std::string const & tagtype = "none") + : tag_(tag), attr_(attr), tagtype_(tagtype) {} /// docstring writeTag() const; /// docstring tag_; /// docstring attr_; + /// Type of tag for new-line behaviour. Either "paragraph", "inline", "block", or "none" (default). + std::string tagtype_; }; /// A special case of StartTag, used exclusively for tags that wrap paragraphs. -/// parid is only used for HTML output; XML is supposed to use attr for this. struct ParTag : public StartTag { /// explicit ParTag(std::string const & tag, const std::string & attr): StartTag(tag, from_utf8(attr)) {} /// - ~ParTag() {} + ~ParTag() override = default; +}; + + +/// A special tag that doesn't produce any XML output, but makes the XMLStream behave as it it output some text. +struct NullTag : public StartTag +{ + /// + NullTag(): StartTag("NULLTAG", from_utf8(""), true) {} + /// + ~NullTag() override = default; }; @@ -327,8 +341,6 @@ struct FontTag : public StartTag /// FontTag const * asFontTag() const override { return this; } /// - bool operator==(StartTag const &) const override; - /// FontTypes font_type_; }; @@ -367,8 +379,52 @@ void closeTag(odocstream & os, std::string const & name); /// Close tag void closeTag(odocstream & os, Paragraph const & par); +// Convenience functions to open and close tags. First, very low-level ones to ensure a consistent new-line behaviour. +// Block style: +// Content before +// +// Contents of the block. +// +// Content after +// Paragraph style: +// Content before +// Contents of the paragraph. +// Content after +// Inline style: +// Content beforeContents of the paragraph.Content after + +/// +void openTag(XMLStream & xs, const docstring & tag, const docstring & attr, const std::string & tagtype); +/// +void openTag(XMLStream & xs, const std::string & tag, const std::string & attr, const std::string & tagtype); +/// +void openTag(XMLStream & xs, const docstring & tag, const std::string & attr, const std::string & tagtype); +/// +void openTag(XMLStream & xs, const std::string & tag, const docstring & attr, const std::string & tagtype); +/// +void closeTag(XMLStream & xs, const docstring & tag, const std::string & tagtype); +/// +void closeTag(XMLStream & xs, const std::string & tag, const std::string & tagtype); +/// +void compTag(XMLStream & xs, const docstring & tag, const docstring & attr, const std::string & tagtype); +/// +void compTag(XMLStream & xs, const std::string & tag, const std::string & attr, const std::string & tagtype); +/// +void compTag(XMLStream & xs, const docstring & tag, const std::string & attr, const std::string & tagtype); +/// +void compTag(XMLStream & xs, const std::string & tag, const docstring & attr, const std::string & tagtype); + } // namespace xml + +/// Comparison operators for tags. They are defined as free functions, otherwise comparison of casts does not work. +/// For font tags, do not only compare the XML tag, but also the font type: several fonts can be using the same tag. +/// In XHTML, ; in DocBook, . +bool operator==(xml::StartTag const & lhs, xml::StartTag const & rhs); +bool operator==(xml::EndTag const & lhs, xml::StartTag const & rhs); +bool operator!=(xml::EndTag const & lhs, xml::StartTag const & rhs); +bool operator!=(xml::StartTag const & lhs, xml::StartTag const & rhs); + } // namespace lyx #endif // XML_H