aboutsummaryrefslogtreecommitdiff
path: root/examples/xhtml/driver.cxx
blob: c2989834e24901d7ccd1a32a9a0fa0674807c65d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
// file      : examples/xhtml/driver.cxx
// copyright : not copyrighted - public domain

#include <iostream>

#include <xml/serializer>

using namespace std;
using namespace xml;

namespace xhtml
{
  // "Canonical" XHTML5 vocabulary.
  //
  const char* xmlns = "http://www.w3.org/1999/xhtml";

  inline void _html (serializer& s)
  {
    s.doctype_decl ("html");
    s.start_element (xmlns, "html");
    s.namespace_decl (xmlns, "");
  }
  inline void html_ (serializer& s) {s.end_element ();}

  inline void _head (serializer& s)
  {
    s.start_element (xmlns, "head");
    s.start_element (xmlns, "meta");
    s.attribute ("charset", "UTF-8");
    s.end_element ();
  }
  inline void head_ (serializer& s) {s.end_element ();}

  inline void _title (serializer& s) {s.start_element (xmlns, "title");}
  inline void title_ (serializer& s) {s.end_element ();}

  inline void _body (serializer& s) {s.start_element (xmlns, "body");}
  inline void body_ (serializer& s) {s.end_element ();}

  inline void _p (serializer& s) {s.start_element (xmlns, "p");}
  inline void p_ (serializer& s) {s.end_element ();}

  // "Inline" elements, i.e., those that are written without
  // indentation.
  //
  inline void _em (serializer& s)
  {
    s.suspend_indentation ();
    s.start_element (xmlns, "em");
  }
  inline void em_ (serializer& s)
  {
    s.end_element ();
    s.resume_indentation ();
  }

  inline void _br_ (serializer& s)
  {
    s.suspend_indentation ();
    s.start_element (xmlns, "br");
    s.end_element ();
    s.resume_indentation ();
  }

  // Attributes.
  //
  template <typename T>
  struct attr_value
  {
    attr_value (const char* n, const T& v): name (n), value (v) {}

    void operator() (serializer& s) const {s.attribute (name, value);}
    const char* name;
    const T& value;
  };

  struct attr
  {
    const char* name;

    explicit
    attr (const char* n): name (n) {}

    // s << (attr = 123);
    //
    template <typename T>
    attr_value<T> operator= (const T& v) {return attr_value<T> (name, v);}

    // s << attr (123);
    //
    template <typename T>
    attr_value<T> operator() (const T& v) {return attr_value<T> (name, v);}

    // s << attr << 123 << ~attr;
    //
    void operator() (serializer& s) const {s.start_attribute (name);}
    void (*operator~ ())(serializer& s) const {return &end;}

    static void end (serializer& s) {s.end_attribute ();}
  };

  static attr id ("id");
}

int
main ()
{
  try
  {
    using namespace xhtml;

    serializer s (cout, "output");

    s << _html
      <<   _head
      <<     _title << "Example XHTML5 document" << title_
      <<   head_
      <<   _body << (id = 123)
      <<     _p << "Here be " << _em << "Dragons!" << em_ << _br_
      <<        "And " << 123 << p_
      <<   body_
      << html_;
  }
  catch (const xml::serialization& e)
  {
    cerr << e.what () << endl;
    return 1;
  }
}