File indexing completed on 2025-02-09 04:28:37
0001 /* 0002 This file is part of the KTextTemplate library 0003 0004 SPDX-FileCopyrightText: 2009, 2010 Stephen Kelly <steveire@gmail.com> 0005 0006 SPDX-License-Identifier: LGPL-2.1-or-later 0007 0008 */ 0009 0010 #ifndef KTEXTTEMPLATE_FILTEREXPRESSION_H 0011 #define KTEXTTEMPLATE_FILTEREXPRESSION_H 0012 0013 #include "variable.h" 0014 0015 #include "ktexttemplate_export.h" 0016 0017 namespace KTextTemplate 0018 { 0019 class Filter; 0020 class OutputStream; 0021 class Parser; 0022 struct Token; 0023 0024 class FilterExpressionPrivate; 0025 0026 /// @headerfile filterexpression.h <KTextTemplate/FilterExpression> 0027 0028 /** 0029 @brief A **%FilterExpression** object represents a filter expression in a 0030 template. 0031 0032 This class is only relevant if implementing custom tags or filters. Most of 0033 the API here is internal. 0034 Usually when implementing tags or filters, filter expressions will just be 0035 created and resolved. 0036 0037 In template markup, a filter expression is a variable followed by one or more 0038 filters separated by pipes: 0039 0040 %Filter expressions may appear in variable nodes: 0041 @code 0042 {{ some_var|upper_filter|lower_filter }} 0043 @endcode 0044 0045 Or as arguments to tags 0046 @code 0047 {% some_tag some_arg1|filter1|filter2 some_arg2|filter3 %} 0048 @endcode 0049 0050 The **%FilterExpression** class would be used in the getNode implementation of 0051 the AbstractNodeFactory implementation for the <tt>some_tag</tt> tag. 0052 0053 @code 0054 Node* SomeTagFactory::getNode(const QString &tagContent, Parser *p) const { 0055 auto parts = smartSplit( tagContent ); 0056 0057 parts.removeFirst(); // Remove the "some_tag" part. 0058 0059 FilterExpression arg1( parts.first(), p ); 0060 FilterExpression arg2( parts.at( 1 ), p ); 0061 0062 return new SomeTagNode( arg1, arg2, p ); 0063 } 0064 @endcode 0065 0066 @see AbstractNodeFactory::getFilterExpressionList 0067 0068 When implementing the Node::render method, the @ref resolve method may be used 0069 to process the filter expression. 0070 0071 For example, if our <tt>SomeTagNode</tt> was to concatenate the resolved 0072 values given as arguments: 0073 0074 @code 0075 void SomeTagNode::render( QTextStream *stream, Context *c ) { 0076 m_arg1.resolve( stream, c ); 0077 m_arg2.resolve( stream, c ); 0078 } 0079 @endcode 0080 0081 Because Filters are highly generic, they do not all write data to the stream. 0082 For example, a Filter might take as input a string, and return a list by 0083 splitting the string on commas, or a Filter might compare an input to its 0084 argument and return whether they are the same, but not write anything to the 0085 stream. For that reason, the @ref resolve method writes data to the given 0086 stream, and returns the same data in its returned QVariant. 0087 0088 The suitability of either of the @ref resolve methods will depend on the 0089 implementation and requirements of your custom tag. For example if the 0090 <tt>SomeTagNode</tt> ran a comparison of the arguments: 0091 0092 @code 0093 void SomeTagNode::render( QTextStream *stream, Context *c ) { 0094 QString first = m_arg1.resolve( c ).toString(); 0095 QString second = m_arg2.resolve( c ).toString(); 0096 0097 if ( first == second ) 0098 m_trueList.render( stream, c ); 0099 else 0100 m_falseList.render( stream, c ); 0101 } 0102 @endcode 0103 0104 @see @ref tags_with_end_tags 0105 0106 @author Stephen Kelly <steveire@gmail.com> 0107 */ 0108 class KTEXTTEMPLATE_EXPORT FilterExpression 0109 { 0110 public: 0111 /** 0112 Constructs an invalid **%FilterExpression**. 0113 */ 0114 FilterExpression(); 0115 0116 /** 0117 Constructs a filter expression from the string @p varString. The Parser @p 0118 parser is used to retrieve filters. 0119 */ 0120 FilterExpression(const QString &varString, KTextTemplate::Parser *parser); 0121 0122 /** 0123 Copy constructor. 0124 */ 0125 FilterExpression(const FilterExpression &other); 0126 0127 /** 0128 Destructor. 0129 */ 0130 ~FilterExpression(); 0131 0132 /** 0133 Assignment operator. 0134 */ 0135 FilterExpression &operator=(const FilterExpression &other); 0136 0137 /** 0138 Returns the initial variable in the **%FilterExpression**. 0139 */ 0140 Variable variable() const; 0141 0142 /** 0143 Resolves the **%FilterExpression** in the Context @p c and writes it to the 0144 stream @p stream. 0145 */ 0146 QVariant resolve(OutputStream *stream, Context *c) const; 0147 0148 /** 0149 Resolves the **%FilterExpression** in the Context @p c. 0150 */ 0151 QVariant resolve(Context *c) const; 0152 0153 /** 0154 Returns whether the Filter resolves to true in the Context @p c. 0155 @see @ref truthiness 0156 */ 0157 bool isTrue(Context *c) const; 0158 0159 /** 0160 Returns a list for the **%FilterExpression**. 0161 0162 If the **%FilterExpression** can not be resolved to a list, an empty list 0163 will be returned. 0164 */ 0165 QVariantList toList(Context *c) const; 0166 0167 /** 0168 Returns whether a filter expression is valid. 0169 0170 A **%FilterExpression** is valid if all filters in the expression exist and 0171 the initial variable being filtered is valid. 0172 */ 0173 bool isValid() const; 0174 0175 #ifndef K_DOXYGEN 0176 /** 0177 @internal 0178 Returns the list of filters in the **%FilterExpression**. 0179 */ 0180 QStringList filters() const; 0181 #endif 0182 0183 private: 0184 Q_DECLARE_PRIVATE(FilterExpression) 0185 FilterExpressionPrivate *const d_ptr; 0186 }; 0187 } 0188 0189 #endif