X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Fxml.h;h=bf72fac9463d4a5d5d2dea055bfab9c5befe17e2;hb=a11780b59fcb6cdd16b15f9fa4de45d7ddfd1b2a;hp=5478a66361d8fe099d70a030967a556634c9a662;hpb=8ae0841826d90b8cdee1922f91fd6ccc5009f5ef;p=features.git diff --git a/src/xml.h b/src/xml.h index 5478a66361..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,8 @@ 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. /// Everything is reset for the next time. @@ -97,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_; /// @@ -116,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 @@ -125,6 +133,8 @@ private: TagDeque pending_tags_; /// TagDeque tag_stack_; + /// + bool is_last_tag_cr_; }; namespace xml { @@ -133,25 +143,26 @@ 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 docstring escapeString(docstring const & raw, XMLStream::EscapeSettings e=XMLStream::ESCAPE_ALL); -/// Converts a string to a form safe for links, etc. -docstring xmlize(docstring const &str, XMLStream::EscapeSettings e); - /// 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 const uniqueID(docstring const & label); +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; @@ -161,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; /// @@ -199,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_; }; @@ -206,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; /// @@ -220,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_; }; @@ -233,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; }; @@ -351,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