KTextTemplate

node.h
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#ifndef KTEXTTEMPLATE_NODE_H
11#define KTEXTTEMPLATE_NODE_H
12
13// krazy:excludeall=dpointer
14
15#include "context.h"
16#include "filterexpression.h"
17#include "ktexttemplate_export.h"
18#include "outputstream.h"
19#include "safestring.h"
20
21#include <QStringList>
22
23// Need these for inheriting from QList<T> to work
24// http://lists.trolltech.com/qt-interest/2008-01/thread00578-0.html
25#include <QList>
26#include <QSet>
27
28namespace KTextTemplate
29{
30
31class Engine;
32class NodeList;
33class TemplateImpl;
34
35class NodePrivate;
36
37/// @headerfile node.h <KTextTemplate/Node>
38
39/**
40 @brief Base class for all nodes.
41
42 The **%Node** class can be implemented to make additional functionality
43 available to Templates.
44
45 A node is represented in template markup as content surrounded by percent
46 signed tokens.
47
48 @code
49 text content
50 {% some_tag arg1 arg2 %}
51 text content
52 {% some_other_tag arg1 arg2 %}
53 text content
54 {% end_some_other_tag %}
55 text content
56 @endcode
57
58 This is parsed into a tree of **%Node** objects by an implementation of
59 AbstractNodeFactory. The **%Node** objects can then later be rendered by their
60 @ref render method.
61
62 Rendering a **%Node** will usually mean writing some output to the stream. The
63 content written to the stream could be determined by the arguments to the tag,
64 or by the content of child nodes between a start and end tag, or both.
65
66 @see FilterExpression
67 @see @ref tags
68
69 @author Stephen Kelly <steveire@gmail.com>
70*/
71class KTEXTTEMPLATE_EXPORT Node : public QObject
72{
73 Q_OBJECT
74public:
75 /**
76 Constructor.
77
78 @param parent The parent QObject
79 */
80 explicit Node(QObject *parent = {});
81
82 /**
83 Destructor.
84 */
85 ~Node() override;
86
87 /**
88 Reimplement this to render the template in the Context @p c.
89
90 This will also involve calling render on and child nodes.
91 */
92 virtual void render(OutputStream *stream, Context *c) const = 0;
93
94#ifndef K_DOXYGEN
95 /**
96 @internal
97 */
98 virtual bool mustBeFirst()
99 { // krazy:exclude:inline
100 return false;
101 }
102#endif
103
104protected:
105 /**
106 Renders the value @p input in the Context @p c. This will involve escaping
107 @p input if necessary.
108
109 This is only relevant to developing template tags.
110 */
111 void streamValueInContext(OutputStream *stream, const QVariant &input, KTextTemplate::Context *c) const;
112
113 /**
114 Returns a raw pointer to the Template this **%Node** is in.
115 */
116 TemplateImpl *containerTemplate() const;
117
118private:
119 Q_DECLARE_PRIVATE(Node)
120 NodePrivate *const d_ptr;
121};
122
123/// @headerfile node.h KTextTemplate/node.h
124
125/**
126 @brief A list of Nodes with some convenience API for rendering them.
127
128 Typically, tags which have an end tag will create and later render a list of
129 child nodes.
130
131 This class contains API such as @ref append and @ref render to make creating
132 such list easily.
133
134 The @ref findChildren method behaves similarly to the QObject::findChildren
135 method, returning a list of nodes of a particular type from the Node objects
136 contained in the list (and their children).
137
138 @see @ref tags_with_end_tags
139*/
140class KTEXTTEMPLATE_EXPORT NodeList : public QList<KTextTemplate::Node *>
141{
142public:
143 /**
144 Creates an empty **%NodeList**.
145 */
146 NodeList();
147
148 /**
149 Copy constructor.
150 */
151 NodeList(const NodeList &list);
152
153 NodeList &operator=(const NodeList &list);
154
155 /**
156 Convenience constructor
157 */
158 /* implicit */ NodeList(const QList<KTextTemplate::Node *> &list);
159
160 /**
161 Destructor.
162 */
164
165 /**
166 Appends @p node to the end of this **%NodeList**.
167 */
168 void append(KTextTemplate::Node *node);
169
170 /**
171 Appends @p nodeList to the end of this **%NodeList**.
172 */
173 void append(const QList<KTextTemplate::Node *> &nodeList);
174
175 /**
176 Returns true if this **%NodeList** contains non-text nodes.
177 */
178 bool containsNonText() const;
179
180 /**
181 A recursive listing of nodes in this tree of type @p T.
182 */
183 template<typename T>
185 {
186 QList<T> children;
188 const QList<KTextTemplate::Node *>::const_iterator first = constBegin();
189 const QList<KTextTemplate::Node *>::const_iterator last = constEnd();
190 for (it = first; it != last; ++it) {
191 T object = qobject_cast<T>(*it);
192 if (object) {
193 children << object;
194 }
195 children << (*it)->findChildren<T>();
196 }
197 return children;
198 }
199
200 /**
201 Renders the list of Nodes in the Context @p c.
202 */
203 void render(OutputStream *stream, Context *c) const;
204
205private:
206 bool m_containsNonText;
207};
208
209class AbstractNodeFactoryPrivate;
210
211/// @headerfile node.h KTextTemplate/node.h
212
213/**
214 @brief Base class for all NodeFactories
215
216 This class can be used to make custom tags available to templates.
217 The getNode method should be implemented to return a Node to be rendered.
218
219 A node is represented in template markup as content surrounded by percent
220 signed tokens.
221
222 @code
223 text content
224 {% some_tag arg1 arg2 %}
225 text content
226 {% some_other_tag arg1 arg2 %}
227 text content
228 {% end_some_other_tag %}
229 text content
230 @endcode
231
232 It is the responsibility of an **%AbstractNodeFactory** implementation to
233 process the contents of a tag and return a Node implementation from its
234 getNode method.
235
236 The @ref getNode method would for example be called with the tagContent
237 \"<tt>some_tag arg1 arg2</tt>\". That content could then be split up, the
238 arguments processed and a Node created
239
240 @code
241 Node* SomeTagFactory::getNode(const QString &tagContent, Parser *p) {
242 QStringList parts = smartSplit( tagContent );
243
244 parts.removeFirst(); // Remove the "some_tag" part.
245
246 FilterExpression arg1( parts.first(), p );
247 FilterExpression arg2( parts.at( 1 ), p );
248
249 return new SomeTagNode( arg1, arg2, p );
250 }
251 @endcode
252
253 The @ref getNode implementation might also advance the parser. For example if
254 we had a @gr_tag{times} tag which rendered content the amount of times it was
255 given in its argument, it could be used like this:
256
257 @code
258 Some text content.
259 {% times 5 %}
260 the bit to be repeated
261 {% end_times %}
262 End text content
263 @endcode
264
265 The argument to @gr_tag{times} might not be a simple number, but could be a
266 FilterExpression such as \"<tt>someobject.some_property|getDigit:1</tt>\".
267
268 The implementation could look like
269
270 @code
271 Node* SomeOtherTagFactory::getNode(const QString &tagContent, Parser *p) {
272 QStringList parts = smartSplit( tagContent );
273
274 parts.removeFirst(); // Remove the "times" part.
275
276 FilterExpression arg( parts.first(), p );
277
278 auto node = new SomeTagNode( arg, p );
279 auto childNodes = p->parse( node, "end_times" );
280 node->setChildNodes( childNodes );
281 p->removeNextToken();
282
283 return node;
284 }
285 @endcode
286
287 Note that it is necessary to invoke the parser to create the child nodes only
288 after creating the Node to return. That node must be passed to the Parser to
289 perform as the parent QObject to the child nodes.
290
291 @see Parser::parse
292*/
293class KTEXTTEMPLATE_EXPORT AbstractNodeFactory : public QObject
294{
295 Q_OBJECT
296public:
297 /**
298 Constructor.
299
300 @param parent The parent QObject
301 */
302 explicit AbstractNodeFactory(QObject *parent = {});
303
304 /**
305 Destructor.
306 */
307 ~AbstractNodeFactory() override;
308
309 /**
310 This method should be reimplemented to return a Node which can be
311 rendered.
312
313 The @p tagContent is the content of the tag including the tag name and
314 arguments. For example, if the template content is @gr_tag{my_tag arg1
315 arg2}, the tagContent will be &quot;my_tag arg1 arg2&quot;.
316
317 The Parser @p p is available and can be advanced if appropriate. For
318 example, if the tag has an end tag, the parser can be advanced to the end
319 tag.
320
321 @see tags
322 */
323 virtual Node *getNode(const QString &tagContent, Parser *p) const = 0;
324
325#ifndef K_DOXYGEN
326 /**
327 @internal
328
329 Sets the Engine which created this NodeFactory. Used by the
330 ScriptableNodeFactory.
331 */
332 virtual void setEngine(Engine *)
333 {
334 }
335#endif
336
337protected:
338 /**
339 Splits @p str into a list, taking quote marks into account.
340
341 This is typically used in the implementation of getNode with the
342 tagContent.
343
344 If @p str is 'one &quot;two three&quot; four 'five &quot; six' seven', the
345 returned list will contain the following strings:
346
347 - one
348 - &quot;two three&quot;
349 - four
350 - five &quot; six
351 - seven
352 */
353 Q_INVOKABLE QStringList smartSplit(const QString &str) const;
354
355protected:
356 /**
357 Returns a list of FilterExpression objects created with Parser @p p as
358 described by the content of @p list.
359
360 This is used for convenience when handling the arguments to a tag.
361 */
362 QList<FilterExpression> getFilterExpressionList(const QStringList &list, Parser *p) const;
363
364private:
365 Q_DECLARE_PRIVATE(AbstractNodeFactory)
366 AbstractNodeFactoryPrivate *const d_ptr;
367};
368}
369
370#endif
Base class for all NodeFactories.
Definition node.h:294
virtual Node * getNode(const QString &tagContent, Parser *p) const =0
This method should be reimplemented to return a Node which can be rendered.
The Context class holds the context to render a Template with.
Definition context.h:107
KTextTemplate::Engine is the main entry point for creating KTextTemplate Templates.
Definition engine.h:110
A list of Nodes with some convenience API for rendering them.
Definition node.h:141
QList< T > findChildren()
A recursive listing of nodes in this tree of type T.
Definition node.h:184
NodeList(const NodeList &list)
Copy constructor.
Base class for all nodes.
Definition node.h:72
virtual void render(OutputStream *stream, Context *c) const =0
Reimplement this to render the template in the Context c.
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
The KTextTemplate namespace holds all public KTextTemplate API.
Definition Mainpage.dox:8
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.