4 * This file is part of LyX, the document processor.
5 * License details can be found in the file COPYING.
10 * Full author contact details are available in file CREDITS.
16 #include "support/docstring.h"
27 // Inspiration for the *Tag structs and for XMLStream
28 // came from MathStream and its cousins.
42 explicit XMLStream(odocstream & os): os_(os), escape_(ESCAPE_ALL) {}
44 odocstream & os() { return os_; }
46 // int & tab() { return tab_; }
47 /// closes any font tags that are eligible to be closed,
48 /// i.e., last on the tag_stack_.
49 /// \return false if there are open font tags we could not close.
50 /// because they are "blocked" by open non-font tags on the stack.
52 /// sets a mark so we know what tags to close at the end.
53 /// normally called at the start of a paragraph.
54 void startDivision(bool keep_empty);
55 /// clears the mark set by previous method.
56 /// there should not be any other tags open before it on the stack,
57 /// but if there are, we will close them.
60 XMLStream & operator<<(docstring const &);
62 XMLStream & operator<<(const char *);
64 XMLStream & operator<<(char_type);
66 XMLStream & operator<<(int);
68 XMLStream & operator<<(char);
70 XMLStream & operator<<(xml::StartTag const &);
72 XMLStream & operator<<(xml::EndTag const &);
74 XMLStream & operator<<(xml::CompTag const &);
76 XMLStream & operator<<(xml::ParTag const &);
78 XMLStream & operator<<(xml::FontTag const &);
80 XMLStream & operator<<(xml::CR const &);
84 ESCAPE_AND, // meaning &
85 ESCAPE_ALL // meaning <, >, &, at present
87 /// Sets what we are going to escape on the NEXT write.
88 /// Everything is reset for the next time.
89 XMLStream & operator<<(EscapeSettings);
90 /// This routine is for debugging the tag stack, etc. Code
91 /// for it is disabled by default, however, so you will need
92 /// to enable it if you want to use it.
93 void dumpTagStack(std::string const & msg);
98 bool isTagOpen(xml::StartTag const &) const;
100 bool isTagOpen(xml::EndTag const &) const;
102 bool isTagPending(xml::StartTag const &) const;
104 void writeError(std::string const &) const;
106 void writeError(docstring const &) const;
110 EscapeSettings escape_;
111 // What we would really like to do here is simply use a
112 // deque<StartTag>. But we want to store both StartTags and
113 // sub-classes thereof on this stack, which means we run into the
114 // so-called polymorphic class problem with the STL. We therefore have
115 // to use a deque<StartTag *>, which leads to the question who will
116 // own these pointers and how they will be deleted, so we use shared
119 typedef std::shared_ptr<xml::StartTag> TagPtr;
120 typedef std::deque<TagPtr> TagDeque;
122 template <typename T>
123 TagPtr makeTagPtr(T const & tag) { return std::make_shared<T>(tag); }
125 TagDeque pending_tags_;
132 /// Escape the given character, if necessary, to an entity.
133 docstring escapeChar(char_type c, XMLStream::EscapeSettings e);
135 /// Escape the given character, if necessary, to an entity.
136 docstring escapeChar(char c, XMLStream::EscapeSettings e);
138 /// Escape a word instead of a single character
139 docstring escapeString(docstring const & raw, XMLStream::EscapeSettings e=XMLStream::ESCAPE_ALL);
141 /// Converts a string to a form safe for links, etc.
142 docstring xmlize(docstring const &str, XMLStream::EscapeSettings e);
144 /// cleans \param str for use as an attribute by replacing all non-altnum by "_"
145 docstring cleanAttr(docstring const & str);
147 /// \p c must be ASCII
148 docstring escapeChar(char c, XMLStream::EscapeSettings e);
150 /// replaces illegal characters from ID attributes
151 docstring cleanID(docstring const &orig);
153 /// returns a unique numeric ID
154 docstring const uniqueID(docstring const & label);
159 /// Attributes will be escaped automatically and so should NOT
160 /// be escaped before being passed to the constructor.
164 explicit StartTag(std::string const & tag) : tag_(from_ascii(tag)), keepempty_(false) {}
166 explicit StartTag(docstring const & tag) : tag_(tag), keepempty_(false) {}
168 explicit StartTag(docstring const & tag, docstring const & attr,
169 bool keepempty = false)
170 : tag_(tag), attr_(attr), keepempty_(keepempty) {}
172 explicit StartTag(std::string const & tag, std::string const & attr,
173 bool keepempty = false)
174 : tag_(from_ascii(tag)), attr_(from_ascii(attr)), keepempty_(keepempty) {}
176 explicit StartTag(std::string const & tag, docstring const & attr,
177 bool keepempty = false)
178 : tag_(from_ascii(tag)), attr_(attr), keepempty_(keepempty) {}
180 virtual ~StartTag() {}
182 virtual docstring writeTag() const;
184 virtual docstring writeEndTag() const;
186 virtual FontTag const * asFontTag() const { return 0; }
188 virtual bool operator==(StartTag const & rhs) const
189 { return tag_ == rhs.tag_; }
191 virtual bool operator!=(StartTag const & rhs) const
192 { return !(*this == rhs); }
194 virtual bool operator==(FontTag const & rhs) const;
199 /// whether to keep things like "<tag></tag>" or discard them
200 /// you would want this for td, e.g, but maybe not for a div
209 explicit EndTag(std::string tag) : tag_(from_ascii(tag)) {}
211 explicit EndTag(docstring tag) : tag_(tag) {}
215 virtual docstring writeEndTag() const;
217 bool operator==(StartTag const & rhs) const
218 { return tag_ == rhs.tag_; }
220 bool operator!=(StartTag const & rhs) const
221 { return !(*this == rhs); }
223 virtual EndFontTag const * asFontTag() const { return 0; }
229 /// Tags like <img />
230 /// Attributes will be escaped automatically and so should NOT
231 /// be escaped before being passed to the constructor.
235 explicit CompTag(std::string const & tag)
238 explicit CompTag(std::string const & tag, std::string const & attr)
239 : tag_(tag), attr_(attr) {}
241 docstring writeTag() const;
249 /// A special case of StartTag, used exclusively for tags that wrap paragraphs.
250 /// parid is only used for HTML output; XML is supposed to use attr for this.
251 struct ParTag : public StartTag
254 explicit ParTag(std::string const & tag, const std::string & attr): StartTag(tag, from_utf8(attr)) {}
295 // When updating this list, also update fontToTag in both output_docbook.cpp and output_xhtml.cpp,
296 // fontToRole in output_docbook.cpp, and fontToAttribute in output_xhtml.cpp.
301 struct FontTag : public StartTag
304 FontTag(docstring const & tag, FontTypes type): StartTag(tag), font_type_(type) {}
306 FontTag(docstring const & tag, docstring const & attr, FontTypes type): StartTag(tag, attr), font_type_(type) {}
308 FontTag const * asFontTag() const override { return this; }
310 bool operator==(StartTag const &) const override;
312 FontTypes font_type_;
317 struct EndFontTag : public EndTag
320 EndFontTag(docstring const & tag, FontTypes type): EndTag(tag), font_type_(type) {}
322 EndFontTag const * asFontTag() const override { return this; }
324 FontTypes font_type_;
328 // trivial struct for output of newlines
331 // an illegal tag for internal use
332 xml::StartTag const parsep_tag("&LyX_parsep_tag&");
335 void openTag(odocstream & os, std::string const & name,
336 std::string const & attribute = std::string());
339 void openTag(Buffer const & buf, odocstream & os,
340 OutputParams const & runparams, Paragraph const & par);
343 void closeTag(odocstream & os, std::string const & name);
346 void closeTag(odocstream & os, Paragraph const & par);