]> git.lyx.org Git - lyx.git/blob - src/xml.h
Support halfline and fullline also in vspace.
[lyx.git] / src / xml.h
1 // -*- C++ -*-
2 /**
3  * \file xml.h
4  * This file is part of LyX, the document processor.
5  * License details can be found in the file COPYING.
6  *
7  * \author José Matos
8  * \author John Levon
9  *
10  * Full author contact details are available in file CREDITS.
11  */
12
13 #ifndef XML_H
14 #define XML_H
15
16 #include "support/docstring.h"
17
18 #include <deque>
19 #include <memory>
20
21 namespace lyx {
22
23 class Buffer;
24 class Paragraph;
25 class OutputParams;
26
27 // Inspiration for the *Tag structs and for XMLStream
28 // came from MathStream and its cousins.
29
30 namespace xml {
31 struct StartTag;
32 struct EndTag;
33 struct CompTag;
34 struct ParTag;
35 struct FontTag;
36 struct CR;
37 }
38
39 class XMLStream {
40 public:
41     ///
42     explicit XMLStream(odocstream & os): os_(os), escape_(ESCAPE_ALL) {}
43     ///
44     odocstream & os() { return os_; }
45     ///
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.
51     bool closeFontTags();
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.
58     void endDivision();
59     ///
60     XMLStream & operator<<(docstring const &);
61     ///
62     XMLStream & operator<<(const char *);
63     ///
64     XMLStream & operator<<(char_type);
65     ///
66     XMLStream & operator<<(int);
67     ///
68     XMLStream & operator<<(char);
69     ///
70     XMLStream & operator<<(xml::StartTag const &);
71     ///
72     XMLStream & operator<<(xml::EndTag const &);
73     ///
74     XMLStream & operator<<(xml::CompTag const &);
75     ///
76     XMLStream & operator<<(xml::ParTag const &);
77     ///
78     XMLStream & operator<<(xml::FontTag const &);
79     ///
80     XMLStream & operator<<(xml::CR const &);
81     ///
82     enum EscapeSettings {
83         ESCAPE_NONE,
84         ESCAPE_AND, // meaning &
85         ESCAPE_ALL  // meaning <, >, &, at present
86     };
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);
94 private:
95     ///
96     void clearTagDeque();
97     ///
98     bool isTagOpen(xml::StartTag const &) const;
99     ///
100     bool isTagOpen(xml::EndTag const &) const;
101     ///
102     bool isTagPending(xml::StartTag const &) const;
103     ///
104     void writeError(std::string const &) const;
105     ///
106     void writeError(docstring const &) const;
107     ///
108     odocstream & os_;
109     ///
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
117     // pointers.
118     ///
119     typedef std::shared_ptr<xml::StartTag> TagPtr;
120     typedef std::deque<TagPtr> TagDeque;
121     ///
122     template <typename T>
123     TagPtr makeTagPtr(T const & tag) { return std::make_shared<T>(tag); }
124     ///
125     TagDeque pending_tags_;
126     ///
127     TagDeque tag_stack_;
128 };
129
130 namespace xml {
131
132 /// Escape the given character, if necessary, to an entity.
133 docstring escapeChar(char_type c, XMLStream::EscapeSettings e);
134
135 /// Escape the given character, if necessary, to an entity.
136 docstring escapeChar(char c, XMLStream::EscapeSettings e);
137
138 /// Escape a word instead of a single character
139 docstring escapeString(docstring const & raw, XMLStream::EscapeSettings e=XMLStream::ESCAPE_ALL);
140
141 /// Converts a string to a form safe for links, etc.
142 docstring xmlize(docstring const &str, XMLStream::EscapeSettings e);
143
144 /// cleans \param str for use as an attribute by replacing all non-altnum by "_"
145 docstring cleanAttr(docstring const & str);
146
147 /// \p c must be ASCII
148 docstring escapeChar(char c, XMLStream::EscapeSettings e);
149
150 /// replaces illegal characters from ID attributes
151 docstring cleanID(docstring const &orig);
152
153 /// returns a unique numeric ID
154 docstring const uniqueID(docstring const & label);
155
156 struct FontTag;
157 struct EndFontTag;
158
159 /// Attributes will be escaped automatically and so should NOT
160 /// be escaped before being passed to the constructor.
161 struct StartTag
162 {
163     ///
164     explicit StartTag(std::string const & tag) : tag_(from_ascii(tag)), keepempty_(false) {}
165     ///
166     explicit StartTag(docstring const & tag) : tag_(tag), keepempty_(false) {}
167     ///
168     explicit StartTag(docstring const & tag, docstring const & attr,
169                       bool keepempty = false)
170             : tag_(tag), attr_(attr), keepempty_(keepempty) {}
171     ///
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) {}
175     ///
176     explicit StartTag(std::string const & tag, docstring const & attr,
177                       bool keepempty = false)
178             : tag_(from_ascii(tag)), attr_(attr), keepempty_(keepempty) {}
179     ///
180     virtual ~StartTag() {}
181     /// <tag_ attr_>
182     virtual docstring writeTag() const;
183     /// </tag_>
184     virtual docstring writeEndTag() const;
185     ///
186     virtual FontTag const * asFontTag() const { return 0; }
187     ///
188     virtual bool operator==(StartTag const & rhs) const
189     { return tag_ == rhs.tag_; }
190     ///
191     virtual bool operator!=(StartTag const & rhs) const
192     { return !(*this == rhs); }
193     ///
194     virtual bool operator==(FontTag const & rhs) const;
195     ///
196     docstring tag_;
197     ///
198     docstring attr_;
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
201     bool keepempty_;
202 };
203
204
205 ///
206 struct EndTag
207 {
208     ///
209     explicit EndTag(std::string tag) : tag_(from_ascii(tag)) {}
210     ///
211     explicit EndTag(docstring tag) : tag_(tag) {}
212     ///
213     virtual ~EndTag() {}
214     /// </tag_>
215     virtual docstring writeEndTag() const;
216     ///
217     bool operator==(StartTag const & rhs) const
218     { return tag_ == rhs.tag_; }
219     ///
220     bool operator!=(StartTag const & rhs) const
221     { return !(*this == rhs); }
222     ///
223     virtual EndFontTag const * asFontTag() const { return 0; }
224     ///
225     docstring tag_;
226 };
227
228
229 /// Tags like <img />
230 /// Attributes will be escaped automatically and so should NOT
231 /// be escaped before being passed to the constructor.
232 struct CompTag
233 {
234     ///
235     explicit CompTag(std::string const & tag)
236             : tag_(tag) {}
237     ///
238     explicit CompTag(std::string const & tag, std::string const & attr)
239             : tag_(tag), attr_(attr) {}
240     /// <tag_ attr_ />
241     docstring writeTag() const;
242     ///
243     std::string tag_;
244     ///
245     std::string attr_;
246 };
247
248
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
252 {
253     ///
254     explicit ParTag(std::string const & tag, const std::string & attr): StartTag(tag, from_utf8(attr)) {}
255     ///
256     ~ParTag() {}
257 };
258
259
260 ///
261 enum FontTypes {
262     // ranges
263     FT_EMPH,
264     FT_NOUN,
265     FT_UBAR,
266     FT_DBAR,
267     FT_WAVE,
268     FT_SOUT,
269     FT_XOUT,
270     // bold
271     FT_BOLD,
272     // shapes
273     FT_UPRIGHT,
274     FT_ITALIC,
275     FT_SLANTED,
276     FT_SMALLCAPS,
277     // families
278     FT_ROMAN,
279     FT_SANS,
280     FT_TYPE,
281     // sizes
282     FT_SIZE_TINY,
283     FT_SIZE_SCRIPT,
284     FT_SIZE_FOOTNOTE,
285     FT_SIZE_SMALL,
286     FT_SIZE_NORMAL,
287     FT_SIZE_LARGE,
288     FT_SIZE_LARGER,
289     FT_SIZE_LARGEST,
290     FT_SIZE_HUGE,
291     FT_SIZE_HUGER,
292     FT_SIZE_INCREASE,
293     FT_SIZE_DECREASE
294
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.
297 };
298
299
300 ///
301 struct FontTag : public StartTag
302 {
303     ///
304     FontTag(docstring const & tag, FontTypes type): StartTag(tag), font_type_(type) {}
305     ///
306     FontTag(docstring const & tag, docstring const & attr, FontTypes type): StartTag(tag, attr), font_type_(type) {}
307     ///
308     FontTag const * asFontTag() const override { return this; }
309     ///
310     bool operator==(StartTag const &) const override;
311     ///
312     FontTypes font_type_;
313 };
314
315
316 ///
317 struct EndFontTag : public EndTag
318 {
319     ///
320     EndFontTag(docstring const & tag, FontTypes type): EndTag(tag), font_type_(type) {}
321     ///
322     EndFontTag const * asFontTag() const override { return this; }
323     ///
324     FontTypes font_type_;
325 };
326
327
328 // trivial struct for output of newlines
329 struct CR{};
330
331 // an illegal tag for internal use
332 xml::StartTag const parsep_tag("&LyX_parsep_tag&");
333
334 /// Open tag
335 void openTag(odocstream & os, std::string const & name,
336              std::string const & attribute = std::string());
337
338 /// Open tag
339 void openTag(Buffer const & buf, odocstream & os,
340              OutputParams const & runparams, Paragraph const & par);
341
342 /// Close tag
343 void closeTag(odocstream & os, std::string const & name);
344
345 /// Close tag
346 void closeTag(odocstream & os, Paragraph const & par);
347
348 } // namespace xml
349
350 } // namespace lyx
351
352 #endif // XML_H