21#include "filterexpression.h"
23#include <QtCore/QRegularExpression>
36class FilterExpressionPrivate
41 std::vector<ArgFilter> m_filters;
51static const char FILTER_SEPARATOR =
'|';
52static const char FILTER_ARGUMENT_SEPARATOR =
':';
62 "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_.");
66 "\"[^\"\\\\]*(?:\\\\.[^\"\\\\]*)*\"");
68 "\'[^\'\\\\]*(?:\\\\.[^\'\\\\]*)*\'");
72 const QString localizedExpression
73 = QStringLiteral(
"(?:") + i18nOpen + doubleQuoteStringLiteral + i18nClose
74 +
QLatin1Char(
'|') + i18nOpen + singleQuoteStringLiteral + i18nClose
76 + i18nOpen + variable + i18nClose +
QLatin1Char(
')');
78 const QString constantString = QStringLiteral(
"(?:")
86 + QStringLiteral(
"\\w+|") + argSep + QStringLiteral(
"(?:")
87 + constantString +
QLatin1Char(
'|') + localizedExpression
89 +
QLatin1Char(
'|') + filterSep + QStringLiteral(
"\\w+)");
106 static const auto sFilterRe = getFilterRegexp();
111 auto i = sFilterRe.globalMatch(vs);
112 while (i.hasNext()) {
113 auto match = i.next();
114 len = match.capturedLength();
115 pos = match.capturedStart();
116 subString = match.captured();
117 const auto ssSize = subString.
size();
119 if (pos != lastPos) {
122 QStringLiteral(
"Could not parse some characters: \"%1\"")
123 .arg(vs.mid(lastPos, pos)));
127 subString = subString.
right(ssSize - 1);
132 d->m_filterNames << subString;
136 if (d->m_filters.empty()
137 || d->m_filters.at(d->m_filters.size() - 1).second.isValid()) {
138 const auto remainder = vs.right(vs.size() - lastPos);
141 QStringLiteral(
"Could not parse the remainder, %1 from %2")
142 .arg(remainder, varString));
144 subString = subString.
right(ssSize - 1);
145 const auto lastFilter = d->m_filters.
size();
149 QStringLiteral(
"Missing argument to filter: %1")
150 .arg(d->m_filterNames[lastFilter - 1]));
152 d->m_filters[lastFilter - 1].second =
Variable(subString);
155 d->m_variable =
Variable(subString);
162 const auto remainder = vs.right(vs.size() - lastPos);
163 if (!remainder.isEmpty()) {
166 QStringLiteral(
"Could not parse the remainder, %1 from %2")
167 .arg(remainder, varString));
188 return d->m_variable.isValid();
196 return d->m_variable;
203 d_ptr->m_variable = other.d_ptr->m_variable;
204 d_ptr->m_filters = other.d_ptr->m_filters;
205 d_ptr->m_filterNames = other.d_ptr->m_filterNames;
212 auto var = d->m_variable.resolve(c);
214 for (
const auto &filterPair : d->m_filters) {
215 auto filter = filterPair.first;
216 filter->setStream(stream);
217 const auto argVar = filterPair.second;
218 auto arg = argVar.resolve(c);
222 if (arg.userType() == qMetaTypeId<Cutelee::SafeString>()) {
224 }
else if (arg.userType() == qMetaTypeId<QString>()) {
227 if (argVar.isConstant()) {
237 var = filter->doFilter(var, arg, c->autoEscape());
239 if (var.userType() == qMetaTypeId<Cutelee::SafeString>()
240 || var.userType() == qMetaTypeId<QString>()) {
241 if (filter->isSafe() && varString.isSafe()) {
243 }
else if (varString.needsEscape()) {
263 if (!var.canConvert<QVariantList>())
264 return QVariantList();
265 return var.value<QVariantList>();
276 return d->m_filterNames;
The Context class holds the context to render a Template with.
An exception for use when implementing template tags.
A FilterExpression object represents a filter expression in a template.
QVariantList toList(Context *c) const
bool isTrue(Context *c) const
QVariant resolve(OutputStream *stream, Context *c) const
Variable variable() const
FilterExpression & operator=(const FilterExpression &other)
The OutputStream class is used to render templates to a QTextStream.
The Parser class processes a string template into a tree of nodes.
std::shared_ptr< Filter > getFilter(const QString &name) const
A QString wrapper class for containing whether a string is safe or needs to be escaped.
const NestedString & get() const
A container for static variables defined in Templates.
The Cutelee namespace holds all public Cutelee API.
Cutelee::SafeString getSafeString(const QVariant &input)
Cutelee::SafeString markSafe(const Cutelee::SafeString &input)
Cutelee::SafeString markForEscaping(const Cutelee::SafeString &input)
bool variantIsTrue(const QVariant &variant)
QString escape(const QString &str)
bool isEmpty() const const
QString right(int n) const const
bool startsWith(const QString &s, Qt::CaseSensitivity cs) const const
Utility functions used throughout Cutelee.