LeechCraft  0.6.70-18450-gabe19ee3b0
Modular cross-platform feature rich live environment.
xmlnode.cpp
Go to the documentation of this file.
1 /**********************************************************************
2  * LeechCraft - modular cross-platform feature rich internet client.
3  * Copyright (C) 2006-2014 Georg Rudoy
4  *
5  * Distributed under the Boost Software License, Version 1.0.
6  * (See accompanying file LICENSE or copy at https://www.boost.org/LICENSE_1_0.txt)
7  **********************************************************************/
8 
9 #include "xmlnode.h"
10 #include <QSize>
11 #include <QXmlStreamWriter>
12 #include <util/sll/visitor.h>
13 #include <util/sll/qtutil.h>
14 
15 namespace LC::Util
16 {
17  Nodes operator+ (Node&& node, Nodes&& nodes)
18  {
19  nodes.prepend (std::move (node));
20  return nodes;
21  }
22 
23  Nodes operator+ (Nodes&& nodes, Node&& node)
24  {
25  nodes.push_back (std::move (node));
26  return nodes;
27  }
28 
29  Nodes operator+ (Node&& n1, Node&& n2)
30  {
31  return { std::move (n1), std::move (n2) };
32  }
33 
34  Tag Tag::WithText (const QByteArray& name, const QString& contents)
35  {
36  return { .Name_ = name, .Children_ = { contents } };
37  }
38 
39  Node Tag::WithTextNonEmpty (const QByteArray& name, const QString& contents)
40  {
41  if (contents.isEmpty ())
42  return NoNode {};
43  return Tag { .Name_ = name, .Children_ = { contents } };
44  }
45 
46  namespace
47  {
48  void TagToHtml (const Tag& tag, QXmlStreamWriter& w)
49  {
50  w.writeStartElement (tag.Name_);
51 
52  for (const auto& [name, value] : tag.Attrs_)
53  w.writeAttribute (name, value);
54 
55  for (const auto& node : tag.Children_)
56  Visit (node,
57  [] (NoNode) {},
58  [&w] (const QString& str) { w.writeCharacters (str); },
59  [&w] (const Tag& childTag) { TagToHtml (childTag, w); });
60 
61  w.writeEndElement ();
62  }
63  }
64 
65  template<XmlRepr T>
66  T Tag::Serialize (const TagSerializeConfig& config) const
67  {
68  if (Name_.isEmpty ())
69  return {};
70 
71  T result;
72 
73  QXmlStreamWriter w { &result };
74  if (config.Indent_)
75  {
76  w.setAutoFormatting (true);
77  w.setAutoFormattingIndent (*config.Indent_);
78  }
79 
80  if (config.Prolog_)
81  w.writeStartDocument ();
82 
83  Visit (config.Dtd_,
84  [] (NoDtd) {},
85  [&w] (Html5Dtd) { w.writeDTD ("html"_qba); },
86  [&w] (const CustomDtd& dtd) { w.writeDTD (dtd.Dtd_); });
87 
88  TagToHtml (*this, w);
89 
90  if (config.Prolog_)
91  w.writeEndDocument ();
92 
93  return result;
94  }
95 
96  template QString Tag::Serialize (const TagSerializeConfig&) const;
97  template QByteArray Tag::Serialize (const TagSerializeConfig&) const;
98 
99  Tag& Tag::WithAttr (QByteArray key, QString value) &&
100  {
101  Attrs_.push_back ({ std::move (key), std::move (value) });
102  return *this;
103  }
104 
105  namespace Tags
106  {
107  UTIL_SLL_API const Tag Br { .Name_ = "br"_qba };
108 
109  Tag Html (Nodes&& children)
110  {
111  return
112  {
113  .Name_ = "html"_qba,
114  .Attrs_ = { { "xmlns"_qba, "http://www.w3.org/1999/xhtml"_qs } },
115  .Children_ = std::move (children),
116  };
117  }
118 
119  Tag Charset (const QString& charset)
120  {
121  return { .Name_ = "meta"_qba, .Attrs_ = { { "charset"_qba, charset } } };
122  }
123 
124  Tag Title (const QString& title)
125  {
126  return { .Name_ = "title"_qba, .Children_ = { title } };
127  }
128 
129  Tag Style (const QString& style)
130  {
131  return { .Name_ = "style"_qba, .Children_ = { style } };
132  }
133 
134  Tag Body (Nodes&& children)
135  {
136  return { .Name_ = "body"_qba, .Children_ = std::move (children) };
137  }
138 
139  Tag Image (const QString& url)
140  {
141  return { .Name_ = "img"_qba, .Attrs_ = { { "src"_qba, url } } };
142  }
143 
144  Tag Image (const QString& url, const QSize& size)
145  {
146  const auto& w = QString::number (size.width ());
147  const auto& h = QString::number (size.height ());
148  return
149  {
150  .Name_ = "img"_qba,
151  .Attrs_ = { { "src"_qba, url }, { "width"_qba, w }, { "height"_qba, h } },
152  };
153  }
154 
155  Tag Li (Nodes&& children)
156  {
157  return { .Name_ = "li"_qba, .Children_ = std::move (children) };
158  }
159 
160  Tag Ul (Nodes&& children)
161  {
162  return { .Name_ = "ul"_qba, .Children_ = std::move (children) };
163  }
164 
165  Tag P (Nodes&& children)
166  {
167  return { .Name_ = "p"_qba, .Children_ = std::move (children) };
168  }
169 
170  Nodes TableGrid (size_t rows, size_t cols, const std::function<Nodes (size_t, size_t)>& cell)
171  {
172  Nodes result;
173  result.reserve (rows);
174 
175  for (size_t r = 0; r < rows; ++r)
176  {
177  Nodes rowCells;
178  rowCells.reserve (cols);
179  for (size_t c = 0; c < cols; ++c)
180  rowCells.push_back (Tag { .Name_ = "td"_qba, .Children_ = cell (r, c) });
181 
182  result.push_back (Tag { .Name_ = "tr"_qba, .Children_ = std::move (rowCells) });
183  }
184 
185  return result;
186  }
187  }
188 }
Tag Image(const QString &url, const QSize &size)
Definition: xmlnode.cpp:144
Nodes TableGrid(size_t rows, size_t cols, const std::function< Nodes(size_t, size_t)> &cell)
Definition: xmlnode.cpp:170
static UTIL_SLL_API Node WithTextNonEmpty(const QByteArray &name, const QString &contents)
Definition: xmlnode.cpp:39
#define UTIL_SLL_API
Definition: sllconfig.h:16
std::optional< int > Indent_
Definition: xmlnode.h:46
std::variant< Tag, QString, NoNode > Node
Definition: xmlnode.h:27
Tag Body(Nodes &&children)
Definition: xmlnode.cpp:134
Tag Html(Nodes &&children)
Definition: xmlnode.cpp:109
UTIL_SLL_API const Tag Br
Definition: xmlnode.cpp:107
Tag Charset(const QString &charset)
Definition: xmlnode.cpp:119
UTIL_SLL_API T Serialize(const TagSerializeConfig &={}) const
auto Visit(const Either< Left, Right > &either, Args &&... args)
Definition: either.h:180
UTIL_SLL_API Tag & WithAttr(QByteArray, QString) &&
Definition: xmlnode.cpp:99
Tag Title(const QString &title)
Definition: xmlnode.cpp:124
Tag Style(const QString &style)
Definition: xmlnode.cpp:129
Tag P(Nodes &&children)
Definition: xmlnode.cpp:165
static UTIL_SLL_API Tag WithText(const QByteArray &name, const QString &contents)
Definition: xmlnode.cpp:34
QByteArray Name_
Definition: xmlnode.h:51
Tag Ul(Nodes &&children)
Definition: xmlnode.cpp:160
constexpr auto operator+(RawStr< N1, Char > s1, CtString< N2, Char > s2) noexcept
Definition: ctstring.h:167
TagAttrs Attrs_
Definition: xmlnode.h:52
Nodes Children_
Definition: xmlnode.h:54
Tag Li(Nodes &&children)
Definition: xmlnode.cpp:155
QVector< Node > Nodes
Definition: xmlnode.h:28