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;
class XMLStream {
public:
///
- explicit XMLStream(odocstream & os): os_(os), escape_(ESCAPE_ALL), is_last_tag_cr_(false) {}
+ explicit XMLStream(odocstream & os): os_(os), escape_(ESCAPE_ALL), is_last_tag_cr_(true) {}
///
odocstream & os() { return os_; }
///
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.
bool isTagOpen(xml::EndTag const &, int maxdepth = -1) const;
///
bool isTagPending(xml::StartTag const &, int maxdepth = -1) const;
+ /// 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_; };
-private:
+ void writeError(std::string const &);
///
- void clearTagDeque();
+ void writeError(docstring const &);
///
- void writeError(std::string const &) const;
+ typedef std::shared_ptr<xml::StartTag> 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_;
///
// own these pointers and how they will be deleted, so we use shared
// pointers.
///
- typedef std::shared_ptr<xml::StartTag> TagPtr;
typedef std::deque<TagPtr> TagDeque;
///
template <typename T>
TagDeque tag_stack_;
///
bool is_last_tag_cr_;
-public:
- bool pending_tags_empty() { return pending_tags_.empty();};
};
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
/// 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;
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;
/// <tag_ attr_>
virtual docstring writeTag() const;
/// </tag_>
/// whether to keep things like "<tag></tag>" 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_;
};
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;
/// </tag_>
virtual docstring writeEndTag() const;
///
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_;
};
{
///
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(docstring const & tag, std::string const & attr, std::string const & tagtype = "none")
+ : tag_(tag), attr_(from_utf8(attr)), tagtype_(tagtype) {}
///
- explicit CompTag(std::string const & tag, std::string const & attr)
- : tag_(tag), attr_(attr) {}
+ explicit CompTag(docstring const & tag, docstring const & attr, std::string const & tagtype = "none")
+ : tag_(tag), attr_(attr), tagtype_(tagtype) {}
/// <tag_ attr_ />
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;
};
/// 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
+// <blocktag>
+// Contents of the block.
+// </blocktag>
+// Content after
+// Paragraph style:
+// Content before
+// <paratag>Contents of the paragraph.</paratag>
+// Content after
+// Inline style:
+// Content before<inlinetag>Contents of the paragraph.</inlinetag>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