]> git.lyx.org Git - lyx.git/blobdiff - src/xml.h
Update fr.po
[lyx.git] / src / xml.h
index b4339ba7ffaa9782aec8ff7270f6029a8f995e91..346e42d78cd803d9cf99c7a06afd9db3058d9670 100644 (file)
--- 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;
@@ -38,93 +39,105 @@ struct CR;
 
 class XMLStream {
 public:
-    ///
-    explicit XMLStream(odocstream & os): os_(os), escape_(ESCAPE_ALL) {}
-    ///
-    odocstream & os() { return os_; }
-    ///
-    // int & tab() { return tab_; }
-    /// closes any font tags that are eligible to be closed,
-    /// i.e., last on the tag_stack_.
-    /// \return false if there are open font tags we could not close.
-    /// because they are "blocked" by open non-font tags on the stack.
-    bool closeFontTags();
-    /// sets a mark so we know what tags to close at the end.
-    /// normally called at the start of a paragraph.
-    void startDivision(bool keep_empty);
-    /// clears the mark set by previous method.
-    /// there should not be any other tags open before it on the stack,
-    /// but if there are, we will close them.
-    void endDivision();
-    ///
-    XMLStream & operator<<(docstring const &);
-    ///
-    XMLStream & operator<<(const char *);
-    ///
-    XMLStream & operator<<(char_type);
-    ///
-    XMLStream & operator<<(int);
-    ///
-    XMLStream & operator<<(char);
-    ///
-    XMLStream & operator<<(xml::StartTag const &);
-    ///
-    XMLStream & operator<<(xml::EndTag const &);
-    ///
-    XMLStream & operator<<(xml::CompTag const &);
-    ///
-    XMLStream & operator<<(xml::ParTag const &);
-    ///
-    XMLStream & operator<<(xml::FontTag const &);
-    ///
-    XMLStream & operator<<(xml::CR const &);
-    ///
-    enum EscapeSettings {
-        ESCAPE_NONE,
-        ESCAPE_AND, // meaning &
-        ESCAPE_ALL  // meaning <, >, &, at present
-    };
-    /// Sets what we are going to escape on the NEXT write.
-    /// Everything is reset for the next time.
-    XMLStream & operator<<(EscapeSettings);
-    /// This routine is for debugging the tag stack, etc. Code
-    /// for it is disabled by default, however, so you will need
-    /// to enable it if you want to use it.
-    void dumpTagStack(std::string const & msg);
+       ///
+       explicit XMLStream(odocstream & os): os_(os), escape_(ESCAPE_ALL), is_last_tag_cr_(true) {}
+       ///
+       odocstream & os() { return os_; }
+       ///
+       // int & tab() { return tab_; }
+       /// closes any font tags that are eligible to be closed,
+       /// i.e., last on the tag_stack_.
+       /// \return false if there are open font tags we could not close.
+       /// because they are "blocked" by open non-font tags on the stack.
+       bool closeFontTags();
+       /// sets a mark so we know what tags to close at the end.
+       /// normally called at the start of a paragraph.
+       void startDivision(bool keep_empty);
+       /// clears the mark set by previous method.
+       /// there should not be any other tags open before it on the stack,
+       /// but if there are, we will close them.
+       void endDivision();
+       ///
+       XMLStream & operator<<(docstring const &);
+       ///
+       XMLStream & operator<<(const char *);
+       ///
+       XMLStream & operator<<(char_type);
+       ///
+       XMLStream & operator<<(int);
+       ///
+       XMLStream & operator<<(char);
+       ///
+       XMLStream & operator<<(xml::NullTag const &);
+       ///
+       XMLStream & operator<<(xml::StartTag const &);
+       ///
+       XMLStream & operator<<(xml::EndTag const &);
+       ///
+       XMLStream & operator<<(xml::CompTag const &);
+       ///
+       XMLStream & operator<<(xml::ParTag const &);
+       ///
+       XMLStream & operator<<(xml::FontTag const &);
+       ///
+       XMLStream & operator<<(xml::CR const &);
+       ///
+       enum EscapeSettings {
+               ESCAPE_NONE,
+               ESCAPE_AND, // meaning &
+               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.
+       XMLStream & operator<<(EscapeSettings);
+       /// This routine is for debugging the tag stack, etc. Code
+       /// for it is disabled by default, however, so you will need
+       /// to enable it if you want to use it.
+       void dumpTagStack(std::string const & msg);
+       ///
+       bool isTagOpen(xml::StartTag const &, int maxdepth = -1) const;
+       ///
+       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_; }
+       ///
+       void writeError(std::string const &);
+       ///
+       void writeError(docstring 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 clearTagDeque();
-    ///
-    bool isTagOpen(xml::StartTag const &) const;
-    ///
-    bool isTagOpen(xml::EndTag const &) const;
-    ///
-    bool isTagPending(xml::StartTag const &) const;
-    ///
-    void writeError(std::string const &) const;
-    ///
-    void writeError(docstring const &) const;
-    ///
-    odocstream & os_;
-    ///
-    EscapeSettings escape_;
-    // What we would really like to do here is simply use a
-    // deque<StartTag>. But we want to store both StartTags and
-    // sub-classes thereof on this stack, which means we run into the
-    // so-called polymorphic class problem with the STL. We therefore have
-    // to use a deque<StartTag *>, which leads to the question who will
-    // 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>
-    TagPtr makeTagPtr(T const & tag) { return std::make_shared<T>(tag); }
-    ///
-    TagDeque pending_tags_;
-    ///
-    TagDeque tag_stack_;
+       ///
+       void clearTagDeque();
+       ///
+       odocstream & os_;
+       ///
+       EscapeSettings escape_;
+       // What we would really like to do here is simply use a
+       // deque<StartTag>. But we want to store both StartTags and
+       // sub-classes thereof on this stack, which means we run into the
+       // so-called polymorphic class problem with the STL. We therefore have
+       // to use a deque<StartTag *>, which leads to the question who will
+       // own these pointers and how they will be deleted, so we use shared
+       // pointers.
+       ///
+       typedef std::deque<TagPtr> TagDeque;
+       ///
+       template <typename T>
+       TagPtr makeTagPtr(T const & tag) { return std::make_shared<T>(tag); }
+       ///
+       TagDeque pending_tags_;
+       ///
+       TagDeque tag_stack_;
+       ///
+       bool is_last_tag_cr_;
 };
 
 namespace xml {
@@ -133,25 +146,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;
@@ -160,69 +174,62 @@ struct EndFontTag;
 /// be escaped before being passed to the constructor.
 struct StartTag
 {
-    ///
-    explicit StartTag(std::string const & tag) : tag_(from_ascii(tag)), keepempty_(false) {}
-    ///
-    explicit StartTag(docstring const & tag) : tag_(tag), keepempty_(false) {}
-    ///
-    explicit StartTag(docstring const & tag, docstring const & attr,
-                      bool keepempty = false)
-            : tag_(tag), attr_(attr), keepempty_(keepempty) {}
-    ///
-    explicit StartTag(std::string const & tag, std::string const & attr,
-                      bool keepempty = false)
-            : tag_(from_ascii(tag)), attr_(from_ascii(attr)), keepempty_(keepempty) {}
-    ///
-    explicit StartTag(std::string const & tag, docstring const & attr,
-                      bool keepempty = false)
-            : tag_(from_ascii(tag)), attr_(attr), keepempty_(keepempty) {}
-    ///
-    virtual ~StartTag() {}
-    /// <tag_ attr_>
-    virtual docstring writeTag() const;
-    /// </tag_>
-    virtual docstring writeEndTag() const;
-    ///
-    virtual FontTag const * asFontTag() const { return 0; }
-    ///
-    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 "<tag></tag>" or discard them
-    /// you would want this for td, e.g, but maybe not for a div
-    bool keepempty_;
+       ///
+       explicit StartTag(std::string const & tag) : tag_(from_ascii(tag)), keepempty_(false), tagtype_("none") {}
+       ///
+       explicit StartTag(docstring const & tag) : tag_(tag), keepempty_(false), tagtype_("none") {}
+       ///
+       explicit StartTag(docstring const & tag, docstring const & attr,
+                                         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, 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, std::string const & tagtype = "none")
+                       : tag_(from_ascii(tag)), attr_(attr), keepempty_(keepempty), tagtype_(tagtype) {}
+       ///
+       virtual ~StartTag() = default;
+       /// <tag_ attr_>
+       virtual docstring writeTag() const;
+       /// </tag_>
+       virtual docstring writeEndTag() const;
+       ///
+       virtual FontTag const * asFontTag() const { return nullptr; }
+       ///
+       docstring tag_;
+       ///
+       docstring attr_;
+       /// 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(docstring tag) : tag_(tag) {}
-    ///
-    virtual ~EndTag() {}
-    /// </tag_>
-    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; }
-    ///
-    docstring tag_;
+       ///
+       explicit EndTag(std::string const & tag, std::string const & tagtype = "none")
+               : tag_(from_ascii(tag)), tagtype_(tagtype) {}
+       ///
+       explicit EndTag(docstring const & tag, std::string const & tagtype = "none")
+               : tag_(tag), tagtype_(tagtype) {}
+       ///
+       virtual ~EndTag() = default;
+       /// </tag_>
+       virtual docstring writeEndTag() const;
+       ///
+       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,97 +238,124 @@ struct EndTag
 /// be escaped before being passed to the constructor.
 struct CompTag
 {
-    ///
-    explicit CompTag(std::string const & tag)
-            : tag_(tag) {}
-    ///
-    explicit CompTag(std::string const & tag, std::string const & attr)
-            : tag_(tag), attr_(attr) {}
-    /// <tag_ attr_ />
-    docstring writeTag() const;
-    ///
-    std::string tag_;
-    ///
-    std::string attr_;
+       ///
+       explicit CompTag(std::string const & 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(docstring const & tag, docstring const & attr, std::string const & tagtype = "none")
+                       : tag_(tag), attr_(attr), tagtype_(tagtype) {}
+       /// <tag_ attr_ />
+       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() {}
+       ///
+       explicit ParTag(std::string const & tag, const std::string & attr): StartTag(tag, from_utf8(attr)) {}
+       ///
+       ~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;
 };
 
 
 ///
 enum FontTypes {
-    // ranges
-    FT_EMPH,
-    FT_NOUN,
-    FT_UBAR,
-    FT_DBAR,
-    FT_WAVE,
-    FT_SOUT,
-    FT_XOUT,
-    // bold
-    FT_BOLD,
-    // shapes
-    FT_UPRIGHT,
-    FT_ITALIC,
-    FT_SLANTED,
-    FT_SMALLCAPS,
-    // families
-    FT_ROMAN,
-    FT_SANS,
-    FT_TYPE,
-    // sizes
-    FT_SIZE_TINY,
-    FT_SIZE_SCRIPT,
-    FT_SIZE_FOOTNOTE,
-    FT_SIZE_SMALL,
-    FT_SIZE_NORMAL,
-    FT_SIZE_LARGE,
-    FT_SIZE_LARGER,
-    FT_SIZE_LARGEST,
-    FT_SIZE_HUGE,
-    FT_SIZE_HUGER,
-    FT_SIZE_INCREASE,
-    FT_SIZE_DECREASE
-
-    // When updating this list, also update fontToTag in both output_docbook.cpp and output_xhtml.cpp,
-    // fontToRole in output_docbook.cpp, and fontToAttribute in output_xhtml.cpp.
+       // ranges
+       FT_EMPH,
+       FT_NOUN,
+       FT_UBAR,
+       FT_DBAR,
+       FT_WAVE,
+       FT_SOUT,
+       FT_XOUT,
+       // bold
+       FT_BOLD,
+       // shapes
+       FT_UPRIGHT,
+       FT_ITALIC,
+       FT_SLANTED,
+       FT_SMALLCAPS,
+       // families
+       FT_ROMAN,
+       FT_SANS,
+       FT_TYPE,
+       // sizes
+       FT_SIZE_TINY,
+       FT_SIZE_SCRIPT,
+       FT_SIZE_FOOTNOTE,
+       FT_SIZE_SMALL,
+       FT_SIZE_NORMAL,
+       FT_SIZE_LARGE,
+       FT_SIZE_LARGER,
+       FT_SIZE_LARGEST,
+       FT_SIZE_HUGE,
+       FT_SIZE_HUGER,
+       FT_SIZE_INCREASE,
+       FT_SIZE_DECREASE
+
+       // When updating this list, also update fontToTag in both output_docbook.cpp and output_xhtml.cpp,
+       // fontToRole in output_docbook.cpp, and fontToAttribute in output_xhtml.cpp.
 };
 
 
 ///
 struct FontTag : public StartTag
 {
-    ///
-    FontTag(docstring const & tag, FontTypes type): StartTag(tag), font_type_(type) {}
-    ///
-    FontTag(docstring const & tag, docstring const & attr, FontTypes type): StartTag(tag, attr), font_type_(type) {}
-    ///
-    FontTag const * asFontTag() const override { return this; }
-    ///
-    bool operator==(StartTag const &) const override;
-    ///
-    FontTypes font_type_;
+       ///
+       FontTag(docstring const & tag, FontTypes type): StartTag(tag), font_type_(type) {}
+       ///
+       FontTag(std::string const & tag, FontTypes type): StartTag(from_utf8(tag)), font_type_(type) {}
+       ///
+       FontTag(docstring const & tag, docstring const & attr, FontTypes type): StartTag(tag, attr), font_type_(type) {}
+       ///
+       FontTag(std::string const & tag, std::string const & attr, FontTypes type): StartTag(from_utf8(tag), from_utf8(attr)), font_type_(type) {}
+       ///
+       FontTag const * asFontTag() const override { return this; }
+       ///
+       FontTypes font_type_;
 };
 
 
 ///
 struct EndFontTag : public EndTag
 {
-    ///
-    EndFontTag(docstring const & tag, FontTypes type): EndTag(tag), font_type_(type) {}
-    ///
-    EndFontTag const * asFontTag() const override { return this; }
-    ///
-    FontTypes font_type_;
+       ///
+       EndFontTag(docstring const & tag, FontTypes type): EndTag(tag), font_type_(type) {}
+       ///
+       EndFontTag(std::string const & tag, FontTypes type): EndTag(from_utf8(tag)), font_type_(type) {}
+       ///
+       EndFontTag const * asFontTag() const override { return this; }
+       ///
+       FontTypes font_type_;
 };
 
 
@@ -345,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
+//       <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
 
+
+/// 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, <span>; in DocBook, <emphasis>.
+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