4 * This file is part of LyX, the document processor.
5 * Licence details can be found in the file COPYING.
9 * Full author contact details are available in file CREDITS.
12 #ifndef OUTPUT_XHTML_H
13 #define OUTPUT_XHTML_H
15 #include "LayoutEnums.h"
17 #include "support/docstream.h"
18 #include "support/shared_ptr.h"
19 #include "support/strfwd.h"
29 // Inspiration for the *Tag structs and for XHTMLStream
30 // came from MathStream and its cousins.
34 /// Attributes will be escaped automatically and so should NOT
35 /// be escaped before being passed to the constructor.
39 explicit StartTag(std::string const & tag) : tag_(tag), keepempty_(false) {}
41 explicit StartTag(std::string const & tag, std::string const & attr,
42 bool keepempty = false)
43 : tag_(tag), attr_(attr), keepempty_(keepempty) {}
47 virtual docstring asTag() const;
49 virtual docstring asEndTag() const;
51 bool operator==(StartTag const & rhs) const
52 { return tag_ == rhs.tag_; }
54 bool operator!=(StartTag const & rhs) const
55 { return !(*this == rhs); }
60 /// whether to keep things like "<tag></tag>" or discard them
61 /// you would want this for td, e.g, but maybe not for a div
66 /// A special case of StartTag, used exclusively for tags that wrap paragraphs.
67 struct ParTag : public StartTag
70 explicit ParTag(std::string const & tag, std::string const & attr,
71 std::string const & parid)
72 : StartTag(tag, attr), parid_(parid)
77 docstring asTag() const;
78 /// the "magic par label" for this paragraph
103 struct FontTag : public StartTag
106 explicit FontTag(FontTypes type);
108 docstring asTag() const;
110 docstring asEndTag() const;
112 bool isFontTag() { return true; }
114 bool operator==(FontTag const & rhs)
115 { return font_type_ == rhs.font_type_; }
117 bool operator==(StartTag const &);
119 FontTypes font_type_;
127 explicit EndTag(std::string tag) : tag_(tag) {}
129 docstring asEndTag() const;
131 bool operator==(StartTag const & rhs) const
132 { return tag_ == rhs.tag_; }
134 bool operator!=(StartTag const & rhs) const
135 { return !(*this == rhs); }
141 /// Tags like <img />
142 /// Attributes will be escaped automatically and so should NOT
143 /// be escaped before being passed to the constructor.
147 explicit CompTag(std::string const & tag)
150 explicit CompTag(std::string const & tag, std::string const & attr)
151 : tag_(tag), attr_(attr) {}
153 docstring asTag() const;
161 // trivial struct for output of newlines
169 explicit XHTMLStream(odocstream & os);
171 odocstream & os() { return os_; }
173 // int & tab() { return tab_; }
174 /// closes any font tags that are eligible to be closed,
175 /// i.e., last on the tag_stack_.
176 /// \return false if there are open font tags we could not close.
177 /// because they are "blocked" by open non-font tags on the stack.
178 bool closeFontTags();
179 /// call at start of paragraph. sets a mark so we know what tags
180 /// to close at the end.
181 void startParagraph(bool keep_empty);
182 /// call at end of paragraph to clear that mark. note that this
183 /// will also close any tags still open.
186 XHTMLStream & operator<<(docstring const &);
188 XHTMLStream & operator<<(const char *);
190 XHTMLStream & operator<<(char_type);
192 XHTMLStream & operator<<(int);
194 XHTMLStream & operator<<(char);
196 XHTMLStream & operator<<(html::StartTag const &);
198 XHTMLStream & operator<<(html::EndTag const &);
200 XHTMLStream & operator<<(html::CompTag const &);
202 XHTMLStream & operator<<(html::ParTag const &);
204 XHTMLStream & operator<<(html::CR const &);
206 enum EscapeSettings {
208 ESCAPE_AND, // meaning &
209 ESCAPE_ALL // meaning <, >, &, at present
211 /// Sets what we are going to escape on the NEXT write.
212 /// Everything is reset for the next time.
213 XHTMLStream & operator<<(EscapeSettings);
215 /// This routine is for debugging the tag stack, etc. Code
216 /// for it is disabled by default, however, so you will need
217 /// to enable it if you want to use it.
218 void dumpTagStack(std::string const & msg) const;
222 void clearTagDeque();
224 bool isTagOpen(html::StartTag const &) const;
226 bool isTagOpen(html::EndTag const &) const;
228 bool isTagPending(html::StartTag const &) const;
230 void writeError(std::string const &) const;
234 EscapeSettings escape_;
235 // What we would really like to do here is simply use a
236 // deque<StartTag>. But we want to store both StartTags and
237 // sub-classes thereof on this stack, which means we run into the
238 // so-called polymorphic class problem with the STL. We therefore have
239 // to use a deque<StartTag *>, which leads to the question who will
240 // own these pointers and how they will be deleted, so we use shared
243 typedef shared_ptr<html::StartTag> TagPtr;
244 typedef std::deque<TagPtr> TagDeque;
246 template <typename T>
247 shared_ptr<T> makeTagPtr(T const & tag)
248 { return shared_ptr<T>(new T(tag)); }
250 TagDeque pending_tags_;
256 void xhtmlParagraphs(Text const & text,
259 OutputParams const & runparams);
261 /// \return a string appropriate for setting alignment in CSS
262 /// Does NOT return "justify" for "block"
263 std::string alignmentToCSS(LyXAlignment align);
267 docstring escapeChar(char_type c, XHTMLStream::EscapeSettings e);
268 /// converts a string to a form safe for links, etc
269 docstring htmlize(docstring const & str, XHTMLStream::EscapeSettings e);
270 /// cleans \param str for use as an atttribute by replacing
271 /// all non-alnum by "_"
272 docstring cleanAttr(docstring const & str);
274 std::string escapeChar(char c, XHTMLStream::EscapeSettings e);
276 std::string htmlize(std::string const & str, XHTMLStream::EscapeSettings e);
278 std::string cleanAttr(std::string const & str);