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