2 // Generated by gtkmmproc -- DO NOT MODIFY!
3 #ifndef _GLIBMM_MARKUP_H
4 #define _GLIBMM_MARKUP_H
7 /* $Id: markup.hg,v 1.5 2005/01/21 12:48:05 murrayc Exp $ */
9 /* Copyright (C) 2002 The gtkmm Development Team
11 * This library is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU Library General Public
13 * License as published by the Free Software Foundation; either
14 * version 2 of the License, or (at your option) any later version.
16 * This library is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * Library General Public License for more details.
21 * You should have received a copy of the GNU Library General Public
22 * License along with this library; if not, write to the Free
23 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27 #include <glibmm/error.h>
28 #include <sigc++/sigc++.h>
31 #include <glibmmconfig.h>
35 #ifndef DOXYGEN_SHOULD_SKIP_THIS
36 extern "C" { typedef struct _GMarkupParseContext GMarkupParseContext; }
43 /** @defgroup Markup Simple XML Subset Parser
45 * The Glib::Markup parser is intended to parse a simple markup format that's a
46 * subset of XML. This is a small, efficient, easy-to-use parser. It should not
47 * be used if you expect to interoperate with other applications generating
48 * full-scale XML. However, it's very useful for application data files, config
49 * files, etc. where you know your application will be the only one writing the
50 * file. Full-scale XML parsers should be able to parse the subset used by
51 * Glib::Markup parser, so you can easily migrate to full-scale XML at a later
52 * time if the need arises.
54 * Glib::Markup is not guaranteed to signal an error on all invalid XML;
55 * the parser may accept documents that an XML parser would not. However,
56 * invalid XML documents are not considered valid Glib::Markup documents.
58 * @par Simplifications to XML include:
60 * - Only UTF-8 encoding is allowed.
61 * - No user-defined entities.
62 * - Processing instructions, comments and the doctype declaration are "passed
63 * through" but are not interpreted in any way.
64 * - No DTD or validation.
66 * @par The markup format does support:
70 * - 5 standard entities: <tt>\& \< \> \" \'</tt>
71 * - Character references
72 * - Sections marked as <tt>CDATA</tt>
77 /** %Exception class for markup parsing errors.
79 class MarkupError : public Glib::Error
92 MarkupError(Code error_code, const Glib::ustring& error_message);
93 explicit MarkupError(GError* gobject);
96 #ifndef DOXYGEN_SHOULD_SKIP_THIS
99 #ifdef GLIBMM_EXCEPTIONS_ENABLED
100 static void throw_func(GError* gobject);
102 //When not using exceptions, we just pass the Exception object around without throwing it:
103 static std::auto_ptr<Glib::Error> throw_func(GError* gobject);
104 #endif //GLIBMM_EXCEPTIONS_ENABLED
106 friend void wrap_init(); // uses throw_func()
111 /*! @var MarkupError::Code MarkupError::BAD_UTF8
112 * Text being parsed was not valid UTF-8.
114 /*! @var MarkupError::Code MarkupError::EMPTY
115 * Document contained nothing, or only whitespace.
117 /*! @var MarkupError::Code MarkupError::PARSE
118 * Document was ill-formed.
120 /*! @var MarkupError::Code MarkupError::UNKNOWN_ELEMENT
121 * This error should be set by Glib::Markup::Parser virtual methods;
122 * element wasn't known.
124 /*! @var MarkupError::Code MarkupError::UNKNOWN_ATTRIBUTE
125 * This error should be set by Glib::Markup::Parser virtual methods;
126 * attribute wasn't known.
128 /*! @var MarkupError::Code MarkupError::INVALID_CONTENT
129 * This error should be set by Glib::Markup::Parser virtual methods;
130 * something was wrong with contents of the document, e.g. invalid attribute value.
133 /** @} group Markup */
141 /** @ingroup Markup */
142 typedef Glib::MarkupError Error;
145 /** Escapes text so that the markup parser will parse it verbatim.
146 * Less than, greater than, ampersand, etc. are replaced with the corresponding
147 * entities. This function would typically be used when writing out a file to
148 * be parsed with the markup parser.
150 * @param text Some valid UTF-8 text.
151 * @return Escaped text.
153 Glib::ustring escape_text(const Glib::ustring& text);
156 /** There are no flags right now. Pass <tt>Glib::Markup::ParseFlags(0)</tt> for
157 * the flags argument to all functions (this should be the default argument
160 /** @addtogroup glibmmEnums Enums and Flags */
163 * @ingroup glibmmEnums
164 * @par Bitwise operators:
165 * <tt>%ParseFlags operator|(ParseFlags, ParseFlags)</tt><br>
166 * <tt>%ParseFlags operator&(ParseFlags, ParseFlags)</tt><br>
167 * <tt>%ParseFlags operator^(ParseFlags, ParseFlags)</tt><br>
168 * <tt>%ParseFlags operator~(ParseFlags)</tt><br>
169 * <tt>%ParseFlags& operator|=(ParseFlags&, ParseFlags)</tt><br>
170 * <tt>%ParseFlags& operator&=(ParseFlags&, ParseFlags)</tt><br>
171 * <tt>%ParseFlags& operator^=(ParseFlags&, ParseFlags)</tt><br>
175 DO_NOT_USE_THIS_UNSUPPORTED_FLAG = 1 << 0,
176 TREAT_CDATA_AS_TEXT = 1 << 1
179 /** @ingroup glibmmEnums */
180 inline ParseFlags operator|(ParseFlags lhs, ParseFlags rhs)
181 { return static_cast<ParseFlags>(static_cast<unsigned>(lhs) | static_cast<unsigned>(rhs)); }
183 /** @ingroup glibmmEnums */
184 inline ParseFlags operator&(ParseFlags lhs, ParseFlags rhs)
185 { return static_cast<ParseFlags>(static_cast<unsigned>(lhs) & static_cast<unsigned>(rhs)); }
187 /** @ingroup glibmmEnums */
188 inline ParseFlags operator^(ParseFlags lhs, ParseFlags rhs)
189 { return static_cast<ParseFlags>(static_cast<unsigned>(lhs) ^ static_cast<unsigned>(rhs)); }
191 /** @ingroup glibmmEnums */
192 inline ParseFlags operator~(ParseFlags flags)
193 { return static_cast<ParseFlags>(~static_cast<unsigned>(flags)); }
195 /** @ingroup glibmmEnums */
196 inline ParseFlags& operator|=(ParseFlags& lhs, ParseFlags rhs)
197 { return (lhs = static_cast<ParseFlags>(static_cast<unsigned>(lhs) | static_cast<unsigned>(rhs))); }
199 /** @ingroup glibmmEnums */
200 inline ParseFlags& operator&=(ParseFlags& lhs, ParseFlags rhs)
201 { return (lhs = static_cast<ParseFlags>(static_cast<unsigned>(lhs) & static_cast<unsigned>(rhs))); }
203 /** @ingroup glibmmEnums */
204 inline ParseFlags& operator^=(ParseFlags& lhs, ParseFlags rhs)
205 { return (lhs = static_cast<ParseFlags>(static_cast<unsigned>(lhs) ^ static_cast<unsigned>(rhs))); }
208 /*! @var Markup::ParseFlags DO_NOT_USE_THIS_UNSUPPORTED_FLAG
209 * Flag you should not use.
213 /** Binary predicate used by Markup::Parser::AttributeMap.
215 * Unlike <tt>operator<(const ustring& lhs, const ustring& rhs)</tt>
216 * which would be used by the default <tt>std::less<></tt> predicate,
217 * the AttributeKeyLess predicate is locale-independent. This is both
218 * more correct and much more efficient.
220 class AttributeKeyLess
223 typedef Glib::ustring first_argument_type;
224 typedef Glib::ustring second_argument_type;
225 typedef bool result_type;
227 bool operator()(const Glib::ustring& lhs, const Glib::ustring& rhs) const;
231 #ifndef DOXYGEN_SHOULD_SKIP_THIS
232 class ParserCallbacks;
235 /** The abstract markup parser base class.
237 * To implement a parser for your markup format, derive from
238 * Glib::Markup::Parser and implement the virtual methods.
240 * You don't have to override all of the virtual methods. If a particular
241 * method is not implement the data passed to it will be ignored. Except for
242 * the error method, any of these callbacks can throw an error exception; in
243 * particular the MarkupError::UNKNOWN_ELEMENT,
244 * MarkupError::UNKNOWN_ATTRIBUTE, and MarkupError::INVALID_CONTENT errors
245 * are intended to be thrown from these overridden methods. If you throw an
246 * error from a method, Glib::Markup::ParseContext::parse() will report that
247 * error back to its caller.
249 class Parser : public sigc::trackable
252 typedef std::map<Glib::ustring, Glib::ustring, Glib::Markup::AttributeKeyLess> AttributeMap;
254 virtual ~Parser() = 0;
257 /** Constructs a Parser object.
258 * Note that Markup::Parser is an abstract class which can't be instantiated
259 * directly. To implement the parser for your markup format, derive from
260 * Markup::Parser and implement the virtual methods.
264 /** Called for open tags <tt>\<foo bar="baz"\></tt>.
265 * This virtual method is invoked when the opening tag of an element is seen.
266 * @param context The Markup::ParseContext object the parsed data belongs to.
267 * @param element_name The name of the element.
268 * @param attributes A map of attribute name/value pairs.
269 * @throw Glib::MarkupError An exception <em>you</em> should throw if
270 * something went wrong, for instance if an unknown attribute name was
271 * encountered. In particular the MarkupError::UNKNOWN_ELEMENT,
272 * MarkupError::UNKNOWN_ATTRIBUTE, and MarkupError::INVALID_CONTENT
273 * errors are intended to be thrown from user-implemented methods.
275 virtual void on_start_element(ParseContext& context,
276 const Glib::ustring& element_name,
277 const AttributeMap& attributes);
279 /** Called for close tags <tt>\</foo\></tt>.
280 * This virtual method is invoked when the closing tag of an element is seen.
281 * @param context The Markup::ParseContext object the parsed data belongs to.
282 * @param element_name The name of the element.
283 * @throw Glib::MarkupError An exception <em>you</em> should throw if
284 * something went wrong, for instance if an unknown attribute name was
285 * encountered. In particular the MarkupError::UNKNOWN_ELEMENT,
286 * MarkupError::UNKNOWN_ATTRIBUTE, and MarkupError::INVALID_CONTENT
287 * errors are intended to be thrown from user-implemented methods.
289 virtual void on_end_element(ParseContext& context, const Glib::ustring& element_name);
291 /** Called for character data.
292 * This virtual method is invoked when some text is seen (text is always
293 * inside an element).
294 * @param context The Markup::ParseContext object the parsed data belongs to.
295 * @param text The parsed text in UTF-8 encoding.
296 * @throw Glib::MarkupError An exception <em>you</em> should throw if
297 * something went wrong, for instance if an unknown attribute name was
298 * encountered. In particular the MarkupError::UNKNOWN_ELEMENT,
299 * MarkupError::UNKNOWN_ATTRIBUTE, and MarkupError::INVALID_CONTENT
300 * errors are intended to be thrown from user-implemented methods.
302 virtual void on_text(ParseContext& context, const Glib::ustring& text);
304 /** Called for strings that should be re-saved verbatim in this same
305 * position, but are not otherwise interpretable.
306 * This virtual method is invoked for comments, processing instructions and
307 * doctype declarations; if you're re-writing the parsed document, write the
308 * passthrough text back out in the same position.
309 * @param context The Markup::ParseContext object the parsed data belongs to.
310 * @param passthrough_text The text that should be passed through.
311 * @throw Glib::MarkupError An exception <em>you</em> should throw if
312 * something went wrong, for instance if an unknown attribute name was
313 * encountered. In particular the MarkupError::UNKNOWN_ELEMENT,
314 * MarkupError::UNKNOWN_ATTRIBUTE, and MarkupError::INVALID_CONTENT
315 * errors are intended to be thrown from user-implemented methods.
317 virtual void on_passthrough(ParseContext& context, const Glib::ustring& passthrough_text);
319 /** Called on error, including one thrown by an overridden virtual method.
320 * @param context The Markup::ParseContext object the parsed data belongs to.
321 * @param error A MarkupError object with detailed information about the error.
323 virtual void on_error(ParseContext& context, const MarkupError& error);
327 Parser(const Parser&);
328 Parser& operator=(const Parser&);
330 #ifndef DOXYGEN_SHOULD_SKIP_THIS
331 friend class Glib::Markup::ParserCallbacks;
336 /** A parse context is used to parse marked-up documents.
338 * You can feed any number of documents into a context, as long as no errors
339 * occur; once an error occurs, the parse context can't continue to parse text
340 * (you have to destroy it and create a new parse context).
342 class ParseContext : public sigc::trackable
345 /** Creates a new parse context.
346 * @param parser A Markup::Parser instance.
347 * @param flags Bitwise combination of Markup::ParseFlags.
349 explicit ParseContext(Parser& parser, ParseFlags flags = ParseFlags(0));
350 virtual ~ParseContext();
352 /** Feed some data to the ParseContext.
353 * The data need not be valid UTF-8; an error will be signalled if it's
354 * invalid. The data need not be an entire document; you can feed a document
355 * into the parser incrementally, via multiple calls to this function.
356 * Typically, as you receive data from a network connection or file, you feed
357 * each received chunk of data into this function, aborting the process if an
358 * error occurs. Once an error is reported, no further data may be fed to the
359 * ParseContext; all errors are fatal.
360 * @param text Chunk of text to parse.
361 * @throw Glib::MarkupError
363 void parse(const Glib::ustring& text);
365 /** Feed some data to the ParseContext.
366 * The data need not be valid UTF-8; an error will be signalled if it's
367 * invalid. The data need not be an entire document; you can feed a document
368 * into the parser incrementally, via multiple calls to this function.
369 * Typically, as you receive data from a network connection or file, you feed
370 * each received chunk of data into this function, aborting the process if an
371 * error occurs. Once an error is reported, no further data may be fed to the
372 * ParseContext; all errors are fatal.
373 * @param text_begin Begin of chunk of text to parse.
374 * @param text_end End of chunk of text to parse.
375 * @throw Glib::MarkupError
377 void parse(const char* text_begin, const char* text_end);
379 /** Signals to the ParseContext that all data has been fed into the parse
380 * context with parse(). This method reports an error if the document isn't
381 * complete, for example if elements are still open.
382 * @throw Glib::MarkupError
386 /** Retrieves the name of the currently open element.
387 * @return The name of the currently open element, or <tt>""</tt>.
389 Glib::ustring get_element() const;
391 /** Retrieves the current line number.
392 * Intended for use in error messages; there are no strict semantics for what
393 * constitutes the "current" line number other than "the best number we could
394 * come up with for error messages."
396 int get_line_number() const;
398 /** Retrieves the number of the current character on the current line.
399 * Intended for use in error messages; there are no strict semantics for what
400 * constitutes the "current" character number other than "the best number we
401 * could come up with for error messages."
403 int get_char_number() const;
405 Parser* get_parser() { return parser_; }
406 const Parser* get_parser() const { return parser_; }
408 #ifndef DOXYGEN_SHOULD_SKIP_THIS
409 GMarkupParseContext* gobj() { return gobject_; }
410 const GMarkupParseContext* gobj() const { return gobject_; }
414 Markup::Parser* parser_;
415 GMarkupParseContext* gobject_;
418 ParseContext(const ParseContext&);
419 ParseContext& operator=(const ParseContext&);
421 static void destroy_notify_callback(void* data);
424 } // namespace Markup
429 #endif /* _GLIBMM_MARKUP_H */