]> git.lyx.org Git - features.git/blob - src/output_xhtml.h
0bcc9849c0e354c9781cfcccdbe4bc7e06000589
[features.git] / src / output_xhtml.h
1 // -*- C++ -*-
2 /**
3  * \file output_xhtml.h
4  * This file is part of LyX, the document processor.
5  * Licence details can be found in the file COPYING.
6  *
7  * \author Richard Heck
8  *
9  * Full author contact details are available in file CREDITS.
10  */
11
12 #ifndef OUTPUT_XHTML_H
13 #define OUTPUT_XHTML_H
14
15 #include "LayoutEnums.h"
16
17 #include "support/docstream.h"
18 #include "support/shared_ptr.h"
19 #include "support/strfwd.h"
20
21 #include <deque>
22
23 namespace lyx {
24
25 class Buffer;
26 class OutputParams;
27 class Text;
28
29 // Inspiration for the *Tag structs and for XHTMLStream
30 // came from MathStream and its cousins.
31
32 namespace html {
33
34 /// Attributes will be escaped automatically and so should NOT
35 /// be escaped before being passed to the constructor.
36 struct StartTag
37 {
38         ///
39         explicit StartTag(std::string const & tag) : tag_(tag), keepempty_(false) {}
40         ///
41         explicit StartTag(std::string const & tag, std::string const & attr, 
42                 bool keepempty = false) 
43                 : tag_(tag), attr_(attr), keepempty_(keepempty) {}
44         ///
45         ~StartTag() {}
46         /// <tag_ attr_>
47         virtual docstring asTag() const;
48         /// </tag_>
49         virtual docstring asEndTag() const;
50         ///
51         bool operator==(StartTag const & rhs) const
52                 { return tag_ == rhs.tag_; }
53         ///
54         bool operator!=(StartTag const & rhs) const
55                 { return !(*this == rhs); }
56         ///
57         std::string tag_;
58         ///
59         std::string attr_;
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
62         bool keepempty_;
63 };
64
65
66 /// A special case of StartTag, used exclusively for tags that wrap paragraphs.
67 struct ParTag : public StartTag
68 {
69         ///
70         explicit ParTag(std::string const & tag, std::string const & attr,
71                std::string const & parid)
72           : StartTag(tag, attr), parid_(parid)
73         {}
74         ///
75         ~ParTag() {}
76         ///
77         docstring asTag() const;
78         /// the "magic par label" for this paragraph
79         std::string parid_;
80 };
81
82
83 ///
84 enum FontTypes {
85         FT_EMPH,
86         FT_BOLD,
87         FT_NOUN,
88         FT_UBAR,
89         FT_DBAR,
90         FT_SOUT,
91         FT_WAVE,
92         FT_ITALIC,
93         FT_SLANTED,
94         FT_SMALLCAPS,
95         FT_ROMAN,
96         FT_SANS,
97         FT_TYPER
98         // SIZES?
99 };
100
101
102 ///
103 struct FontTag : public StartTag
104 {
105         ///
106         explicit FontTag(FontTypes type);
107         ///
108         docstring asTag() const;
109         ///
110         docstring asEndTag() const;
111         ///
112         bool isFontTag() { return true; }
113         ///
114         bool operator==(FontTag const & rhs)
115                 { return font_type_ == rhs.font_type_; }
116         /// Asserts.
117         bool operator==(StartTag const &);
118         ///
119         FontTypes font_type_;
120 };
121
122
123 ///
124 struct EndTag
125 {
126         ///
127         explicit EndTag(std::string tag) : tag_(tag) {}
128         /// </tag_>
129         docstring asEndTag() const;
130         ///
131         bool operator==(StartTag const & rhs) const
132                 { return tag_ == rhs.tag_; }
133         ///
134         bool operator!=(StartTag const & rhs) const
135                 { return !(*this == rhs); }
136         ///
137         std::string tag_;
138 };
139
140
141 /// Tags like <img />
142 /// Attributes will be escaped automatically and so should NOT
143 /// be escaped before being passed to the constructor.
144 struct CompTag
145 {
146         ///
147         explicit CompTag(std::string const & tag)
148                 : tag_(tag) {}
149         ///
150         explicit CompTag(std::string const & tag, std::string const & attr)
151                 : tag_(tag), attr_(attr) {}
152         /// <tag_ attr_ />
153         docstring asTag() const;
154         ///
155         std::string tag_;
156         ///
157         std::string attr_;
158 };
159
160
161 // trivial struct for output of newlines
162 struct CR{};
163
164 } // namespace html
165
166 class XHTMLStream {
167 public:
168         ///
169         explicit XHTMLStream(odocstream & os);
170         ///
171         odocstream & os() { return os_; }
172         ///
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. 
184         void endParagraph();
185         ///
186         XHTMLStream & operator<<(docstring const &);
187         ///
188         XHTMLStream & operator<<(const char *);
189         ///
190         XHTMLStream & operator<<(char_type);
191         ///
192         XHTMLStream & operator<<(int);
193         ///
194         XHTMLStream & operator<<(char);
195         ///
196         XHTMLStream & operator<<(html::StartTag const &);
197         ///
198         XHTMLStream & operator<<(html::EndTag const &);
199         ///
200         XHTMLStream & operator<<(html::CompTag const &);
201         ///
202         XHTMLStream & operator<<(html::ParTag const &);
203         ///
204         XHTMLStream & operator<<(html::CR const &);
205         ///
206         enum EscapeSettings {
207                 ESCAPE_NONE,
208                 ESCAPE_AND, // meaning &
209                 ESCAPE_ALL  // meaning <, >, &, at present
210         };
211         /// Sets what we are going to escape on the NEXT write.
212         /// Everything is reset for the next time.
213         XHTMLStream & operator<<(EscapeSettings);
214 #if 0
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;
219 #endif
220 private:
221         ///
222         void clearTagDeque();
223         ///
224         bool isTagOpen(html::StartTag const &) const;
225         ///
226         bool isTagOpen(html::EndTag const &) const;
227         ///
228         bool isTagPending(html::StartTag const &) const;
229         ///
230         void writeError(std::string const &) const;
231         ///
232         odocstream & os_;
233         /// 
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
241         // pointers.
242         ///
243         typedef shared_ptr<html::StartTag> TagPtr;
244         typedef std::deque<TagPtr> TagDeque;
245         ///
246         template <typename T> 
247         shared_ptr<T> makeTagPtr(T const & tag) 
248                 { return shared_ptr<T>(new T(tag)); }
249         ///
250         TagDeque pending_tags_;
251         ///
252         TagDeque tag_stack_;
253 };
254
255 ///
256 void xhtmlParagraphs(Text const & text,
257                        Buffer const & buf,
258                        XHTMLStream & xs,
259                        OutputParams const & runparams);
260
261 /// \return a string appropriate for setting alignment in CSS
262 /// Does NOT return "justify" for "block"
263 std::string alignmentToCSS(LyXAlignment align);
264
265 namespace html {
266 ///
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);
273 ///
274 std::string escapeChar(char c, XHTMLStream::EscapeSettings e);
275 /// 
276 std::string htmlize(std::string const & str, XHTMLStream::EscapeSettings e);
277 /// 
278 std::string cleanAttr(std::string const & str);
279
280 } // namespace html
281 } // namespace lyx
282
283 #endif