LeechCraft 0.6.70-17609-g3dde4097dd
Modular cross-platform feature rich live environment.
Loading...
Searching...
No Matches
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
15namespace 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
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 Html(Nodes &&children)
Definition xmlnode.cpp:109
Tag Charset(const QString &charset)
Definition xmlnode.cpp:119
Tag Image(const QString &url)
Definition xmlnode.cpp:139
Tag Li(Nodes &&children)
Definition xmlnode.cpp:155
UTIL_SLL_API const Tag Br
Definition xmlnode.cpp:107
Tag Body(Nodes &&children)
Definition xmlnode.cpp:134
Tag Style(const QString &style)
Definition xmlnode.cpp:129
Tag P(Nodes &&children)
Definition xmlnode.cpp:165
Nodes TableGrid(size_t rows, size_t cols, const std::function< Nodes(size_t, size_t)> &cell)
Definition xmlnode.cpp:170
Tag Title(const QString &title)
Definition xmlnode.cpp:124
Tag Ul(Nodes &&children)
Definition xmlnode.cpp:160
QVector< Node > Nodes
Definition xmlnode.h:28
auto Visit(const Either< Left, Right > &either, Args &&... args)
Definition either.h:207
constexpr auto operator+(RawStr< N1, Char > s1, CtString< N2, Char > s2) noexcept
Definition ctstring.h:145
std::variant< Tag, QString, NoNode > Node
Definition xmlnode.h:27
#define UTIL_SLL_API
Definition sllconfig.h:16
UTIL_SLL_API Tag & WithAttr(QByteArray, QString) &&
Definition xmlnode.cpp:99
static UTIL_SLL_API Tag WithText(const QByteArray &name, const QString &contents)
Definition xmlnode.cpp:34
Nodes Children_
Definition xmlnode.h:54
TagAttrs Attrs_
Definition xmlnode.h:52
QByteArray Name_
Definition xmlnode.h:51
UTIL_SLL_API T Serialize(const TagSerializeConfig &={}) const
static UTIL_SLL_API Node WithTextNonEmpty(const QByteArray &name, const QString &contents)
Definition xmlnode.cpp:39
std::optional< int > Indent_
Definition xmlnode.h:46