KTextTemplate

node.cpp
1/*
2 This file is part of the KTextTemplate library
3
4 SPDX-FileCopyrightText: 2009, 2010 Stephen Kelly <steveire@gmail.com>
5
6 SPDX-License-Identifier: LGPL-2.1-or-later
7
8*/
9
10#include "node.h"
11
12#include "metaenumvariable_p.h"
13#include "nodebuiltins_p.h"
14#include "template.h"
15#include "util.h"
16
17#include <QRegularExpressionMatchIterator>
18
19using namespace KTextTemplate;
20
21namespace KTextTemplate
22{
23
24class NodePrivate
25{
26 NodePrivate(Node *node)
27 : q_ptr(node)
28 {
29 }
30 Q_DECLARE_PUBLIC(Node)
31 Node *const q_ptr;
32};
33
34class AbstractNodeFactoryPrivate
35{
36 AbstractNodeFactoryPrivate(AbstractNodeFactory *factory)
37 : q_ptr(factory)
38 {
39#if defined(Q_CC_MSVC)
40// MSVC doesn't like static string concatenations like L"foo" "bar", as
41// results from QStringLiteral, so use QLatin1String here instead.
42#define STRING_LITERAL QLatin1String
43#else
44#define STRING_LITERAL QStringLiteral
45#endif
46 smartSplitRe =
47 QRegularExpression(STRING_LITERAL("(" // match
48 "(?:[^\\s\\\'\\\"]*" // things that are not whitespace or
49 // escaped quote chars
50 "(?:" // followed by
51 "(?:\"" // Either a quote starting with "
52 "(?:[^\"\\\\]|\\\\.)*\"" // followed by anything that is
53 // not the end of the quote
54 "|\'" // Or a quote starting with '
55 "(?:[^\'\\\\]|\\\\.)*\'" // followed by anything that is
56 // not the end of the quote
57 ")" // (End either)
58 "[^\\s\'\"]*" // To the start of the next such fragment
59 ")+" // Perform multiple matches of the above.
60 ")" // End of quoted string handling.
61 "|\\S+" // Apart from quoted strings, match
62 // non-whitespace fragments also
63 ")" // End match
64 ));
65
66#undef STRING_LITERAL
67 }
68
69 Q_DECLARE_PUBLIC(AbstractNodeFactory)
70 AbstractNodeFactory *const q_ptr;
71
72public:
73 QRegularExpression smartSplitRe;
74};
75}
76
77Node::Node(QObject *parent)
78 : QObject(parent)
79 , d_ptr(new NodePrivate(this))
80{
81}
82
84{
85 delete d_ptr;
86}
87
88void Node::streamValueInContext(OutputStream *stream, const QVariant &input, Context *c) const
89{
90 KTextTemplate::SafeString inputString;
91 if (input.userType() == qMetaTypeId<QVariantList>()) {
92 inputString = toString(input.value<QVariantList>());
93 } else if (input.userType() == qMetaTypeId<MetaEnumVariable>()) {
94 const auto mev = input.value<MetaEnumVariable>();
95 if (mev.value >= 0)
96 (*stream) << QString::number(mev.value);
97 } else {
98 inputString = getSafeString(input);
99 }
100 if (c->autoEscape() && !inputString.isSafe())
101 inputString.setNeedsEscape(true);
102
103 (*stream) << inputString;
104}
105
106TemplateImpl *Node::containerTemplate() const
107{
108 auto _parent = parent();
109 auto ti = qobject_cast<TemplateImpl *>(_parent);
110 while (_parent && !ti) {
111 _parent = _parent->parent();
112 ti = qobject_cast<TemplateImpl *>(_parent);
113 }
114 Q_ASSERT(ti);
115 return ti;
116}
117
119 : m_containsNonText(false)
120{
121}
122
123NodeList::NodeList(const NodeList &list) = default;
124
125NodeList &NodeList::operator=(const NodeList &list)
126{
127 if (&list == this) {
128 return *this;
129 }
130 static_cast<QList<KTextTemplate::Node *> &>(*this) = static_cast<QList<KTextTemplate::Node *>>(list);
131 m_containsNonText = list.m_containsNonText;
132 return *this;
133}
134
136 : QList<KTextTemplate::Node *>(list)
137 , m_containsNonText(false)
138{
139 for (KTextTemplate::Node *node : list) {
140 auto textNode = qobject_cast<TextNode *>(node);
141 if (!textNode) {
142 m_containsNonText = true;
143 return;
144 }
145 }
146}
147
148NodeList::~NodeList() = default;
149
151{
152 if (!m_containsNonText) {
153 auto textNode = qobject_cast<TextNode *>(node);
154 if (!textNode)
155 m_containsNonText = true;
156 }
157
159}
160
162{
163 if (!m_containsNonText) {
164 for (KTextTemplate::Node *node : nodeList) {
165 auto textNode = qobject_cast<TextNode *>(node);
166 if (!textNode) {
167 m_containsNonText = true;
168 break;
169 }
170 }
171 }
172
174}
175
177{
178 return m_containsNonText;
179}
180
181void NodeList::render(OutputStream *stream, Context *c) const
182{
183 for (auto i = 0; i < this->size(); ++i) {
184 this->at(i)->render(stream, c);
185 }
186}
187
189 : QObject(parent)
190 , d_ptr(new AbstractNodeFactoryPrivate(this))
191{
192}
193
195{
196 delete d_ptr;
197}
198
200{
202 for (auto &varString : list) {
203 fes << FilterExpression(varString, p);
204 }
205 return fes;
206}
207
209{
211 QStringList l;
212
213 auto i = d->smartSplitRe.globalMatch(str);
214 while (i.hasNext()) {
215 auto match = i.next();
216 l.append(match.captured());
217 }
218
219 return l;
220}
221
222#include "moc_node.cpp"
Base class for all NodeFactories.
Definition node.h:294
~AbstractNodeFactory() override
Destructor.
Definition node.cpp:194
AbstractNodeFactory(QObject *parent={})
Constructor.
Definition node.cpp:188
QList< FilterExpression > getFilterExpressionList(const QStringList &list, Parser *p) const
Returns a list of FilterExpression objects created with Parser p as described by the content of list.
Definition node.cpp:199
Q_INVOKABLE QStringList smartSplit(const QString &str) const
Splits str into a list, taking quote marks into account.
Definition node.cpp:208
The Context class holds the context to render a Template with.
Definition context.h:107
A FilterExpression object represents a filter expression in a template.
A list of Nodes with some convenience API for rendering them.
Definition node.h:141
NodeList()
Creates an empty NodeList.
Definition node.cpp:118
bool containsNonText() const
Returns true if this NodeList contains non-text nodes.
Definition node.cpp:176
void append(KTextTemplate::Node *node)
Appends node to the end of this NodeList.
Definition node.cpp:150
void render(OutputStream *stream, Context *c) const
Renders the list of Nodes in the Context c.
Definition node.cpp:181
Base class for all nodes.
Definition node.h:72
TemplateImpl * containerTemplate() const
Returns a raw pointer to the Template this Node is in.
Definition node.cpp:106
~Node() override
Destructor.
Definition node.cpp:83
void streamValueInContext(OutputStream *stream, const QVariant &input, KTextTemplate::Context *c) const
Renders the value input in the Context c.
Definition node.cpp:88
The OutputStream class is used to render templates to a QTextStream.
The Parser class processes a string template into a tree of nodes.
Definition parser.h:38
A QString wrapper class for containing whether a string is safe or needs to be escaped.
Definition safestring.h:81
bool isSafe() const
Whether the string is safe.
The KTextTemplate namespace holds all public KTextTemplate API.
Definition Mainpage.dox:8
KTextTemplate::SafeString getSafeString(const QVariant &input)
Retrieves and returns a SafeString from the input.
Definition util.cpp:91
void append(QList< T > &&value)
const_reference at(qsizetype i) const const
qsizetype size() const const
QObject * parent() const const
QString number(double n, char format, int precision)
int userType() const const
T value() const const
Q_D(Todo)
Utility functions used throughout KTextTemplate.
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Tue Mar 26 2024 11:19:42 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.