]> git.lyx.org Git - features.git/blob - src/output_xhtml.h
Rework that way that font tags are handled in XHTML output. We need
[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 class FontTag;
35 class EndFontTag;
36
37 /// Attributes will be escaped automatically and so should NOT
38 /// be escaped before being passed to the constructor.
39 struct StartTag
40 {
41         ///
42         explicit StartTag(std::string const & tag) : tag_(tag), keepempty_(false) {}
43         ///
44         explicit StartTag(std::string const & tag, std::string const & attr, 
45                 bool keepempty = false) 
46                 : tag_(tag), attr_(attr), keepempty_(keepempty) {}
47         ///
48         ~StartTag() {}
49         /// <tag_ attr_>
50         virtual docstring writeTag() const;
51         /// </tag_>
52         virtual docstring writeEndTag() const;
53         ///
54         virtual FontTag const * asFontTag() const { return 0; }
55         ///
56         virtual bool operator==(StartTag const & rhs) const
57                 { return tag_ == rhs.tag_; }
58         ///
59         virtual bool operator!=(StartTag const & rhs) const
60                 { return !(*this == rhs); }
61         ///
62         virtual bool operator==(FontTag const & rhs) const;
63         ///
64         std::string tag_;
65         ///
66         std::string attr_;
67         /// whether to keep things like "<tag></tag>" or discard them
68         /// you would want this for td, e.g, but maybe not for a div
69         bool keepempty_;
70 };
71
72
73 ///
74 struct EndTag
75 {
76         ///
77         explicit EndTag(std::string tag) : tag_(tag) {}
78         /// </tag_>
79         virtual docstring writeEndTag() const;
80         ///
81         bool operator==(StartTag const & rhs) const
82                 { return tag_ == rhs.tag_; }
83         ///
84         bool operator!=(StartTag const & rhs) const
85                 { return !(*this == rhs); }
86         ///
87         virtual EndFontTag const * asFontTag() const { return 0; }
88         ///
89         std::string tag_;
90 };
91
92
93 /// Tags like <img />
94 /// Attributes will be escaped automatically and so should NOT
95 /// be escaped before being passed to the constructor.
96 struct CompTag
97 {
98         ///
99         explicit CompTag(std::string const & tag)
100                 : tag_(tag) {}
101         ///
102         explicit CompTag(std::string const & tag, std::string const & attr)
103                 : tag_(tag), attr_(attr) {}
104         /// <tag_ attr_ />
105         docstring writeTag() const;
106         ///
107         std::string tag_;
108         ///
109         std::string attr_;
110 };
111
112
113 /// A special case of StartTag, used exclusively for tags that wrap paragraphs.
114 struct ParTag : public StartTag
115 {
116         ///
117         explicit ParTag(std::string const & tag, std::string const & attr,
118                std::string const & parid)
119           : StartTag(tag, attr), parid_(parid)
120         {}
121         ///
122         ~ParTag() {}
123         ///
124         docstring writeTag() const;
125         /// the "magic par label" for this paragraph
126         std::string parid_;
127 };
128
129
130 ///
131 enum FontTypes {
132         FT_EMPH,
133         FT_BOLD,
134         FT_NOUN,
135         FT_UBAR,
136         FT_DBAR,
137         FT_SOUT,
138         FT_WAVE,
139         FT_ITALIC,
140         FT_SLANTED,
141         FT_SMALLCAPS,
142         FT_ROMAN,
143         FT_SANS,
144         FT_TYPER
145         // SIZES?
146 };
147
148
149 ///
150 struct FontTag : public StartTag
151 {
152         ///
153         explicit FontTag(FontTypes type);
154         ///
155         FontTag const * asFontTag() const { return this; }
156         ///
157         bool operator==(StartTag const &) const;
158         ///
159         FontTypes font_type_;
160 };
161
162
163 ///
164 struct EndFontTag : public EndTag
165 {
166         ///
167         explicit EndFontTag(FontTypes type);
168         ///
169         EndFontTag const * asFontTag() const { return this; }
170         ///
171         FontTypes font_type_;
172 };
173
174
175 // trivial struct for output of newlines
176 struct CR{};
177
178 } // namespace html
179
180 class XHTMLStream {
181 public:
182         ///
183         explicit XHTMLStream(odocstream & os);
184         ///
185         odocstream & os() { return os_; }
186         ///
187         // int & tab() { return tab_; }
188         /// closes any font tags that are eligible to be closed,
189         /// i.e., last on the tag_stack_.
190         /// \return false if there are open font tags we could not close.
191         /// because they are "blocked" by open non-font tags on the stack.
192         bool closeFontTags();
193         /// call at start of paragraph. sets a mark so we know what tags
194         /// to close at the end. 
195         void startParagraph(bool keep_empty);
196         /// call at end of paragraph to clear that mark. note that this
197         /// will also close any tags still open. 
198         void endParagraph();
199         ///
200         XHTMLStream & operator<<(docstring const &);
201         ///
202         XHTMLStream & operator<<(const char *);
203         ///
204         XHTMLStream & operator<<(char_type);
205         ///
206         XHTMLStream & operator<<(int);
207         ///
208         XHTMLStream & operator<<(char);
209         ///
210         XHTMLStream & operator<<(html::StartTag const &);
211         ///
212         XHTMLStream & operator<<(html::EndTag const &);
213         ///
214         XHTMLStream & operator<<(html::CompTag const &);
215         ///
216         XHTMLStream & operator<<(html::ParTag const &);
217         ///
218         XHTMLStream & operator<<(html::FontTag const &);
219         ///
220         XHTMLStream & operator<<(html::CR const &);
221         ///
222         enum EscapeSettings {
223                 ESCAPE_NONE,
224                 ESCAPE_AND, // meaning &
225                 ESCAPE_ALL  // meaning <, >, &, at present
226         };
227         /// Sets what we are going to escape on the NEXT write.
228         /// Everything is reset for the next time.
229         XHTMLStream & operator<<(EscapeSettings);
230 #if 0
231         /// This routine is for debugging the tag stack, etc. Code
232         /// for it is disabled by default, however, so you will need
233         /// to enable it if you want to use it.
234         void dumpTagStack(std::string const & msg) const;
235 #endif
236 private:
237         ///
238         void clearTagDeque();
239         ///
240         bool isTagOpen(html::StartTag const &) const;
241         ///
242         bool isTagOpen(html::EndTag const &) const;
243         ///
244         bool isTagPending(html::StartTag const &) const;
245         ///
246         void writeError(std::string const &) const;
247         ///
248         odocstream & os_;
249         /// 
250         EscapeSettings escape_;
251         // What we would really like to do here is simply use a
252         // deque<StartTag>. But we want to store both StartTags and
253         // sub-classes thereof on this stack, which means we run into the 
254         // so-called polymorphic class problem with the STL. We therefore have
255         // to use a deque<StartTag *>, which leads to the question who will
256         // own these pointers and how they will be deleted, so we use shared
257         // pointers.
258         ///
259         typedef shared_ptr<html::StartTag> TagPtr;
260         typedef std::deque<TagPtr> TagDeque;
261         ///
262         template <typename T> 
263         shared_ptr<T> makeTagPtr(T const & tag) 
264                 { return shared_ptr<T>(new T(tag)); }
265         ///
266         TagDeque pending_tags_;
267         ///
268         TagDeque tag_stack_;
269 };
270
271 ///
272 void xhtmlParagraphs(Text const & text,
273                        Buffer const & buf,
274                        XHTMLStream & xs,
275                        OutputParams const & runparams);
276
277 /// \return a string appropriate for setting alignment in CSS
278 /// Does NOT return "justify" for "block"
279 std::string alignmentToCSS(LyXAlignment align);
280
281 namespace html {
282 ///
283 docstring escapeChar(char_type c, XHTMLStream::EscapeSettings e);
284 /// converts a string to a form safe for links, etc
285 docstring htmlize(docstring const & str, XHTMLStream::EscapeSettings e);
286 /// cleans \param str for use as an atttribute by replacing
287 /// all non-alnum by "_"
288 docstring cleanAttr(docstring const & str);
289 ///
290 std::string escapeChar(char c, XHTMLStream::EscapeSettings e);
291 /// 
292 std::string htmlize(std::string const & str, XHTMLStream::EscapeSettings e);
293 /// 
294 std::string cleanAttr(std::string const & str);
295
296 } // namespace html
297 } // namespace lyx
298
299 #endif