xref: /aosp_15_r20/external/tinyxml2/contrib/html5-printer.cpp (revision 7485b22521f577cf944e5687361548d8993d8d2c)
1*7485b225SElliott Hughes //  g++ -Wall -O2 contrib/html5-printer.cpp -o html5-printer -ltinyxml2
2*7485b225SElliott Hughes 
3*7485b225SElliott Hughes //  This program demonstrates how to use "tinyxml2" to generate conformant HTML5
4*7485b225SElliott Hughes //  by deriving from the "tinyxml2::XMLPrinter" class.
5*7485b225SElliott Hughes 
6*7485b225SElliott Hughes //  http://dev.w3.org/html5/markup/syntax.html
7*7485b225SElliott Hughes 
8*7485b225SElliott Hughes //  In HTML5, there are 16 so-called "void" elements.  "void elements" NEVER have
9*7485b225SElliott Hughes //  inner content (but they MAY have attributes), and are assumed to be self-closing.
10*7485b225SElliott Hughes //  An example of a self-closig HTML5 element is "<br/>" (line break)
11*7485b225SElliott Hughes //  All other elements are called "non-void" and MUST never self-close.
12*7485b225SElliott Hughes //  Examples: "<div class='lolcats'></div>".
13*7485b225SElliott Hughes 
14*7485b225SElliott Hughes //  tinyxml2::XMLPrinter will emit _ALL_ XML elements with no inner content as
15*7485b225SElliott Hughes //  self-closing.  This behavior produces space-effeceint XML, but incorrect HTML5.
16*7485b225SElliott Hughes 
17*7485b225SElliott Hughes //  Author: Dennis Jenkins,  dennis (dot) jenkins (dot) 75 (at) gmail (dot) com.
18*7485b225SElliott Hughes //  License: Same as tinyxml2 (zlib, see below)
19*7485b225SElliott Hughes //  This example is a small contribution to the world!  Enjoy it!
20*7485b225SElliott Hughes 
21*7485b225SElliott Hughes /*
22*7485b225SElliott Hughes This software is provided 'as-is', without any express or implied
23*7485b225SElliott Hughes warranty. In no event will the authors be held liable for any
24*7485b225SElliott Hughes damages arising from the use of this software.
25*7485b225SElliott Hughes 
26*7485b225SElliott Hughes Permission is granted to anyone to use this software for any
27*7485b225SElliott Hughes purpose, including commercial applications, and to alter it and
28*7485b225SElliott Hughes redistribute it freely, subject to the following restrictions:
29*7485b225SElliott Hughes 
30*7485b225SElliott Hughes 1. The origin of this software must not be misrepresented; you must
31*7485b225SElliott Hughes not claim that you wrote the original software. If you use this
32*7485b225SElliott Hughes software in a product, an acknowledgment in the product documentation
33*7485b225SElliott Hughes would be appreciated but is not required.
34*7485b225SElliott Hughes 
35*7485b225SElliott Hughes 2. Altered source versions must be plainly marked as such, and
36*7485b225SElliott Hughes must not be misrepresented as being the original software.
37*7485b225SElliott Hughes 
38*7485b225SElliott Hughes 3. This notice may not be removed or altered from any source
39*7485b225SElliott Hughes distribution.
40*7485b225SElliott Hughes */
41*7485b225SElliott Hughes 
42*7485b225SElliott Hughes 
43*7485b225SElliott Hughes #include "../tinyxml2.h"
44*7485b225SElliott Hughes #include <iostream>
45*7485b225SElliott Hughes 
46*7485b225SElliott Hughes #if defined (_MSC_VER)
47*7485b225SElliott Hughes #define strcasecmp stricmp
48*7485b225SElliott Hughes #endif
49*7485b225SElliott Hughes 
50*7485b225SElliott Hughes using namespace tinyxml2;
51*7485b225SElliott Hughes 
52*7485b225SElliott Hughes // Contrived input containing a mix of void and non-void HTML5 elements.
53*7485b225SElliott Hughes // When printed via XMLPrinter, some non-void elements will self-close (not valid HTML5).
54*7485b225SElliott Hughes static const char input[] =
55*7485b225SElliott Hughes "<html><body><p style='a'></p><br/>&copy;<col a='1' b='2'/><div a='1'></div></body></html>";
56*7485b225SElliott Hughes 
57*7485b225SElliott Hughes // XMLPrinterHTML5 is small enough, just put the entire implementation inline.
58*7485b225SElliott Hughes class	XMLPrinterHTML5 : public XMLPrinter
59*7485b225SElliott Hughes {
60*7485b225SElliott Hughes public:
XMLPrinterHTML5(FILE * file=0,bool compact=false,int depth=0)61*7485b225SElliott Hughes     XMLPrinterHTML5 (FILE* file=0, bool compact = false, int depth = 0) :
62*7485b225SElliott Hughes         XMLPrinter (file, compact, depth)
63*7485b225SElliott Hughes     {}
64*7485b225SElliott Hughes 
65*7485b225SElliott Hughes protected:
CloseElement()66*7485b225SElliott Hughes     virtual void CloseElement () {
67*7485b225SElliott Hughes         if (_elementJustOpened && !isVoidElement (_stack.PeekTop())) {
68*7485b225SElliott Hughes             SealElementIfJustOpened();
69*7485b225SElliott Hughes             }
70*7485b225SElliott Hughes         XMLPrinter::CloseElement();
71*7485b225SElliott Hughes     }
72*7485b225SElliott Hughes 
isVoidElement(const char * name)73*7485b225SElliott Hughes     virtual bool isVoidElement (const char *name) {
74*7485b225SElliott Hughes // Complete list of all HTML5 "void elements",
75*7485b225SElliott Hughes // http://dev.w3.org/html5/markup/syntax.html
76*7485b225SElliott Hughes         static const char *list[] = {
77*7485b225SElliott Hughes             "area", "base", "br", "col", "command", "embed", "hr", "img",
78*7485b225SElliott Hughes             "input", "keygen", "link", "meta", "param", "source", "track", "wbr",
79*7485b225SElliott Hughes             NULL
80*7485b225SElliott Hughes         };
81*7485b225SElliott Hughes 
82*7485b225SElliott Hughes // I could use 'bsearch', but I don't have MSVC to test on (it would work with gcc/libc).
83*7485b225SElliott Hughes         for (const char **p = list; *p; ++p) {
84*7485b225SElliott Hughes             if (!strcasecmp (name, *p)) {
85*7485b225SElliott Hughes                 return true;
86*7485b225SElliott Hughes             }
87*7485b225SElliott Hughes         }
88*7485b225SElliott Hughes 
89*7485b225SElliott Hughes         return false;
90*7485b225SElliott Hughes     }
91*7485b225SElliott Hughes };
92*7485b225SElliott Hughes 
main(void)93*7485b225SElliott Hughes int	main (void) {
94*7485b225SElliott Hughes     XMLDocument doc (false);
95*7485b225SElliott Hughes     doc.Parse (input);
96*7485b225SElliott Hughes 
97*7485b225SElliott Hughes     std::cout << "INPUT:\n" << input << "\n\n";
98*7485b225SElliott Hughes 
99*7485b225SElliott Hughes     XMLPrinter prn (NULL, true);
100*7485b225SElliott Hughes     doc.Print (&prn);
101*7485b225SElliott Hughes     std::cout << "XMLPrinter (not valid HTML5):\n" << prn.CStr() << "\n\n";
102*7485b225SElliott Hughes 
103*7485b225SElliott Hughes     XMLPrinterHTML5 html5 (NULL, true);
104*7485b225SElliott Hughes     doc.Print (&html5);
105*7485b225SElliott Hughes     std::cout << "XMLPrinterHTML5:\n" << html5.CStr() << "\n";
106*7485b225SElliott Hughes 
107*7485b225SElliott Hughes     return 0;
108*7485b225SElliott Hughes }
109