X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Fxml.h;h=bf72fac9463d4a5d5d2dea055bfab9c5befe17e2;hb=0515bfa989474c6dc46256b1bea52cff7f330336;hp=12e7f25fa52b593245cb1be6b595f9954dc55c30;hpb=f025538c955b40861ec61c7ba08022bd4ed64e66;p=features.git diff --git a/src/xml.h b/src/xml.h index 12e7f25fa5..bf72fac946 100644 --- a/src/xml.h +++ b/src/xml.h @@ -25,7 +25,7 @@ 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; @@ -39,7 +39,7 @@ struct CR; class XMLStream { public: /// - explicit XMLStream(odocstream & os): os_(os), escape_(ESCAPE_ALL) {} + explicit XMLStream(odocstream & os): os_(os), escape_(ESCAPE_ALL), is_last_tag_cr_(true) {} /// odocstream & os() { return os_; } /// @@ -82,7 +82,7 @@ public: enum EscapeSettings { ESCAPE_NONE, ESCAPE_AND, // meaning & - ESCAPE_ALL, // meaning <, >, &, at present + ESCAPE_ALL, // meaning <, >, &, at present, except things that are forbidden in comments ESCAPE_COMMENTS // Anything that is forbidden within comments }; /// Sets what we are going to escape on the NEXT write. @@ -98,13 +98,21 @@ public: bool isTagOpen(xml::EndTag const &, int maxdepth = -1) const; /// bool isTagPending(xml::StartTag const &, int maxdepth = -1) const; -private: + /// 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_; } /// - void clearTagDeque(); + void writeError(std::string const &); /// - void writeError(std::string const &) const; + void writeError(docstring const &); + /// + typedef std::shared_ptr TagPtr; + /// Returns the last element on the tag stack. XMLStream keeps ownership of the item. + TagPtr getLastStackTag(); +private: /// - void writeError(docstring const &) const; + void clearTagDeque(); /// odocstream & os_; /// @@ -117,7 +125,6 @@ private: // own these pointers and how they will be deleted, so we use shared // pointers. /// - typedef std::shared_ptr TagPtr; typedef std::deque TagDeque; /// template @@ -126,6 +133,8 @@ private: TagDeque pending_tags_; /// TagDeque tag_stack_; + /// + bool is_last_tag_cr_; }; namespace xml { @@ -134,6 +143,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 @@ -142,15 +152,18 @@ 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); /// returns a unique numeric ID docstring uniqueID(docstring const & label); +/// determines whether a string only contains space characters +bool isNotOnlySpace(docstring const & str); + +/// trims the string to the left, i.e. remove any space-like character at the beginning of the string +docstring trimLeft(docstring const & str); + struct FontTag; struct EndFontTag; @@ -159,23 +172,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_ascii(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; /// @@ -197,6 +210,8 @@ struct StartTag /// 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_; }; @@ -204,11 +219,13 @@ 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; /// @@ -218,9 +235,12 @@ struct EndTag 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_; }; @@ -231,27 +251,40 @@ struct CompTag { /// explicit CompTag(std::string const & tag) - : tag_(tag) {} + : tag_(from_utf8(tag)), tagtype_("none") {} + /// + explicit CompTag(docstring const & tag) + : tag_(tag), tagtype_("none") {} + /// + 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(std::string const & tag, std::string const & attr) - : tag_(tag), attr_(attr) {} + 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; /// - std::string tag_; + docstring tag_; /// - std::string attr_; + 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; }; @@ -349,6 +382,41 @@ 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 } // namespace lyx