template.h
Go to the documentation of this file.
1 /******************************************************************************
2  *
3  * Copyright (C) 1997-2015 by Dimitri van Heesch.
4  *
5  * Permission to use, copy, modify, and distribute this software and its
6  * documentation under the terms of the GNU General Public License is hereby
7  * granted. No representations are made about the suitability of this software
8  * for any purpose. It is provided "as is" without express or implied warranty.
9  * See the GNU General Public License for more details.
10  *
11  * Documents produced by Doxygen are derivative works derived from the
12  * input used in their production; they are not affected by this license.
13  *
14  */
15 
16 #ifndef TEMPLATE_H
17 #define TEMPLATE_H
18 
19 #include <qcstring.h>
20 #include <qvaluelist.h>
21 
22 class FTextStream;
23 
24 class TemplateListIntf;
25 class TemplateStructIntf;
26 class TemplateEngine;
27 
28 /** @defgroup template_api Template API
29  *
30  * This is the API for a
31  * <a href="https://docs.djangoproject.com/en/1.6/topics/templates/">Django</a>
32  * compatible template system written in C++.
33  * It is somewhat inspired by Stephen Kelly's
34  * <a href="http://www.gitorious.org/grantlee/pages/Home">Grantlee</a>.
35  *
36  * A template is simply a text file.
37  * A template contains \b variables, which get replaced with values when the
38  * template is evaluated, and \b tags, which control the logic of the template.
39  *
40  * Variables look like this: `{{ variable }}`
41  * When the template engine encounters a variable, it evaluates that variable and
42  * replaces it with the result. Variable names consist of any combination of
43  * alphanumeric characters and the underscore ("_").
44  * Use a dot (.) to access attributes of a structured variable.
45  *
46  * One can modify variables for display by using \b filters, for example:
47  * `{{ value|default:"nothing" }}`
48  *
49  * Tags look like this: `{% tag %}`. Tags are more complex than variables:
50  * Some create text in the output, some control flow by performing loops or logic,
51  * and some load external information into the template to be used by later variables.
52  *
53  * To comment-out part of a line in a template, use the comment syntax:
54  * `{# comment text #}`.
55  *
56  * Supported Django tags:
57  * - `for ... empty ... endfor`
58  * - `if ... else ... endif`
59  * - `block ... endblock`
60  * - `extend`
61  * - `include`
62  * - `with ... endwith`
63  * - `spaceless ... endspaceless`
64  * - `cycle`
65  *
66  * Extension tags:
67  * - `create` which instantiates a template and writes the result to a file.
68  * The syntax is `{% create 'filename' from 'template' %}`.
69  * - `recursetree`
70  * - `markers`
71  * - `msg` ... `endmsg`
72  * - `set`
73  *
74  * Supported Django filters:
75  * - `default`
76  * - `length`
77  * - `add`
78  * - `divisibleby`
79  *
80  * Extension filters:
81  * - `stripPath`
82  * - `nowrap`
83  * - `prepend`
84  * - `append`
85  *
86  * @{
87  */
88 
89 /** @brief Variant type which can hold one value of a fixed set of types. */
91 {
92  public:
93  /** @brief Helper class to create a delegate that can store a function/method call. */
94  class Delegate
95  {
96  public:
97  /** Callback type to use when creating a delegate from a function. */
98  typedef TemplateVariant (*StubType)(const void *obj, const QValueList<TemplateVariant> &args);
99 
101 
102  /** Creates a delegate given an object. The method to call is passed as a template parameter */
103  template <class T, TemplateVariant (T::*TMethod)(const QValueList<TemplateVariant> &) const>
104  static Delegate fromMethod(const T* objectPtr)
105  {
106  Delegate d;
107  d.m_objectPtr = objectPtr;
108  d.m_stubPtr = &methodStub<T, TMethod>;
109  return d;
110  }
111  /** Creates a delegate given an object, and a plain function. */
112  static Delegate fromFunction(const void *obj,StubType func)
113  {
114  Delegate d;
115  d.m_objectPtr = obj;
116  d.m_stubPtr = func;
117  return d;
118  }
119 
120  /** Invokes the function/method stored in the delegate */
122  {
123  return (*m_stubPtr)(m_objectPtr, args);
124  }
125 
126  private:
127  const void* m_objectPtr;
129 
130  template <class T, TemplateVariant (T::*TMethod)(const QValueList<TemplateVariant> &) const>
131  static TemplateVariant methodStub(const void* objectPtr, const QValueList<TemplateVariant> &args)
132  {
133  T* p = (T*)(objectPtr);
134  return (p->*TMethod)(args);
135  }
136  };
137 
138  /** Types of data that can be stored in a TemplateVariant */
140 
141  /** Returns the type of the value stored in the variant */
142  Type type() const { return m_type; }
143 
144  /** Return a string representation of the type of the value stored in the variant */
146  {
147  switch (m_type)
148  {
149  case None: return "none";
150  case Bool: return "bool";
151  case Integer: return "integer";
152  case String: return "string";
153  case Struct: return "struct";
154  case List: return "list";
155  case Function: return "function";
156  }
157  return "invalid";
158  }
159 
160  /** Returns TRUE if the variant holds a valid value, or FALSE otherwise */
161  bool isValid() const { return m_type!=None; }
162 
163  /** Constructs an invalid variant. */
165 
166  /** Constructs a new variant with a boolean value \a b. */
167  explicit TemplateVariant(bool b) : m_type(Bool), m_boolVal(b), m_raw(FALSE) {}
168 
169  /** Constructs a new variant with a integer value \a v. */
171 
172  /** Constructs a new variant with a string value \a s. */
173  TemplateVariant(const char *s,bool raw=FALSE) : m_type(String), m_strVal(s), m_strukt(0), m_raw(raw) {}
174 
175  /** Constructs a new variant with a string value \a s. */
177 
178  /** Constructs a new variant with a struct value \a s.
179  * @note. The variant will hold a reference to the object.
180  */
182 
183  /** Constructs a new variant with a list value \a l.
184  * @note. The variant will hold a reference to the object.
185  */
187 
188  /** Constructs a new variant which represents a method call
189  * @param[in] delegate Delegate object to invoke when
190  * calling call() on this variant.
191  * @note Use TemplateVariant::Delegate::fromMethod() and
192  * TemplateVariant::Delegate::fromFunction() to create
193  * Delegate objects.
194  */
195  TemplateVariant(const Delegate &delegate) : m_type(Function), m_strukt(0), m_delegate(delegate), m_raw(FALSE) {}
196 
197  /** Destroys the Variant object */
199 
200  /** Constructs a copy of the variant, \a v,
201  * passed as the argument to this constructor.
202  */
204 
205  /** Assigns the value of the variant \a v to this variant. */
207 
208  /** Compares this QVariant with v and returns true if they are equal;
209  * otherwise returns false.
210  */
212  {
213  if (m_type==None)
214  {
215  return FALSE;
216  }
218  {
219  return m_list==other.m_list; // TODO: improve me
220  }
222  {
223  return m_strukt==other.m_strukt; // TODO: improve me
224  }
225  else
226  {
227  return toString()==other.toString();
228  }
229  }
230 
231  /** Returns the variant as a string. */
233  {
234  switch (m_type)
235  {
236  case None: return QCString();
237  case Bool: return m_boolVal ? "true" : "false";
238  case Integer: return QCString().setNum(m_intVal);
239  case String: return m_strVal;
240  case Struct: return "[struct]";
241  case List: return "[list]";
242  case Function: return "[function]";
243  }
244  return QCString();
245  }
246 
247  /** Returns the variant as a boolean. */
248  bool toBool() const;
249 
250  /** Returns the variant as an integer. */
251  int toInt() const;
252 
253  /** Returns the pointer to list referenced by this variant
254  * or 0 if this variant does not have list type.
255  */
257  {
258  return m_type==List ? m_list : 0;
259  }
260 
261  /** Returns the pointer to struct referenced by this variant
262  * or 0 if this variant does not have struct type.
263  */
265  {
266  return m_type==Struct ? m_strukt : 0;
267  }
268 
269  /** Return the result of apply this function with \a args.
270  * Returns an empty string if the variant type is not a function.
271  */
273  {
274  if (m_type==Function) return m_delegate(args);
275  return TemplateVariant();
276  }
277 
278  /** Sets whether or not the value of the Variant should be
279  * escaped or written as-is (raw).
280  * @param[in] b TRUE means write as-is, FALSE means apply escaping.
281  */
282  void setRaw(bool b) { m_raw = b; }
283 
284  /** Returns whether or not the value of the Value is raw.
285  * @see setRaw()
286  */
287  bool raw() const { return m_raw; }
288 
289  private:
292  union
293  {
294  int m_intVal;
295  bool m_boolVal;
298  };
300  bool m_raw;
301 };
302 
303 //------------------------------------------------------------------------
304 
305 template<class T> class TemplateAutoRef
306 {
307  public:
308  TemplateAutoRef(T *obj) : m_obj(obj)
309  {
310  m_obj->addRef();
311  }
313  {
314  m_obj->release();
315  }
316  T &operator*() const { return *m_obj; }
317  T *operator->() const { return m_obj; }
318  T *get() const { return m_obj; }
319 
320  private:
322 };
323 
324 //------------------------------------------------------------------------
325 
326 /** @brief Abstract read-only interface for a context value of type list.
327  * @note The values of the list are TemplateVariants.
328  */
330 {
331  public:
332  /** @brief Abstract interface for a iterator of a list. */
334  {
335  public:
336  /** Destructor for the iterator */
337  virtual ~ConstIterator() {}
338  /** Moves iterator to the first element in the list */
339  virtual void toFirst() = 0;
340  /** Moves iterator to the last element in the list */
341  virtual void toLast() = 0;
342  /** Moves iterator to the next element in the list */
343  virtual void toNext() = 0;
344  /** Moves iterator to the previous element in the list */
345  virtual void toPrev() = 0;
346  /* Returns TRUE if the iterator points to a valid element
347  * in the list, or FALSE otherwise.
348  * If TRUE is returned, the value pointed to be the
349  * iterator is assigned to \a v.
350  */
351  virtual bool current(TemplateVariant &v) const = 0;
352  };
353 
354  /** Destroys the list */
355  virtual ~TemplateListIntf() {}
356 
357  /** Returns the number of elements in the list */
358  virtual int count() const = 0;
359 
360  /** Returns the element at index position \a index. */
361  virtual TemplateVariant at(int index) const = 0;
362 
363  /** Creates a new iterator for this list.
364  * @note the user should call delete on the returned pointer.
365  */
366  virtual TemplateListIntf::ConstIterator *createIterator() const = 0;
367 
368  /** Increase object's reference count */
369  virtual int addRef() = 0;
370 
371  /** Decreases object's referenc count, destroy object if 0 */
372  virtual int release() = 0;
373 };
374 
375 /** @brief Default implementation of a context value of type list. */
377 {
378  public:
379  // TemplateListIntf methods
380  virtual int count() const;
381  virtual TemplateVariant at(int index) const;
382  virtual TemplateListIntf::ConstIterator *createIterator() const;
383  virtual int addRef();
384  virtual int release();
385 
386  /** Creates an instance with ref count set to 0 */
387  static TemplateList *alloc();
388 
389  /** Appends element \a v to the end of the list */
390  virtual void append(const TemplateVariant &v);
391 
392  private:
393  /** Creates a list */
394  TemplateList();
395  /** Destroys the list */
396  ~TemplateList();
397 
399  class Private;
400  Private *p;
401 };
402 
403 //------------------------------------------------------------------------
404 
405 /** @brief Abstract interface for a context value of type struct. */
407 {
408  public:
409  /** Destroys the struct */
410  virtual ~TemplateStructIntf() {}
411 
412  /** Gets the value for a field name.
413  * @param[in] name The name of the field.
414  */
415  virtual TemplateVariant get(const char *name) const = 0;
416 
417  /** Increase object's reference count */
418  virtual int addRef() = 0;
419 
420  /** Decreases object's referenc count, destroy object if 0 */
421  virtual int release() = 0;
422 };
423 
424 
425 /** @brief Default implementation of a context value of type struct. */
427 {
428  public:
429  // TemplateStructIntf methods
430  virtual TemplateVariant get(const char *name) const;
431  virtual int addRef();
432  virtual int release();
433 
434  /** Creates an instance with ref count set to 0. */
435  static TemplateStruct *alloc();
436 
437  /** Sets the value the field of a struct
438  * @param[in] name The name of the field.
439  * @param[in] v The value to set.
440  */
441  virtual void set(const char *name,const TemplateVariant &v);
442 
443 
444  private:
445  /** Creates a struct */
446  TemplateStruct();
447  /** Destroys the struct */
448  virtual ~TemplateStruct();
449 
450  class Private;
451  Private *p;
452 };
453 
454 //------------------------------------------------------------------------
455 
456 /** @brief Interface used to escape characters in a string */
458 {
459  public:
460  /** Returns the \a input after escaping certain characters */
461  virtual QCString escape(const QCString &input) = 0;
462  /** Setting tabbing mode on or off (for LaTeX) */
463  virtual void enableTabbing(bool b) = 0;
464 };
465 
466 //------------------------------------------------------------------------
467 
468 /** @brief Interface used to remove redundant spaces inside a spaceless block */
470 {
471  public:
472  /** Returns the \a input after removing redundant whitespace */
473  virtual QCString remove(const QCString &input) = 0;
474  /** Reset filter state */
475  virtual void reset() = 0;
476 };
477 
478 //------------------------------------------------------------------------
479 
480 /** @brief Abstract interface for a template context.
481  *
482  * A Context consists of a stack of dictionaries.
483  * A dictionary consists of a mapping of string keys onto TemplateVariant values.
484  * A key is searched starting with the dictionary at the top of the stack
485  * and searching downwards until it is found. The stack is used to create
486  * local scopes.
487  * @note This object must be created by TemplateEngine::createContext()
488  */
490 {
491  public:
492  virtual ~TemplateContext() {}
493 
494  /** Push a new scope on the stack. */
495  virtual void push() = 0;
496 
497  /** Pop the current scope from the stack. */
498  virtual void pop() = 0;
499 
500  /** Sets a value in the current scope.
501  * @param[in] name The name of the value; the key in the dictionary.
502  * @param[in] v The value associated with the key.
503  * @note When a given key is already present,
504  * its value will be replaced by \a v
505  */
506  virtual void set(const char *name,const TemplateVariant &v) = 0;
507 
508  /** Gets the value for a given key
509  * @param[in] name The name of key.
510  * @returns The value, which can be an invalid variant in case the
511  * key was not found.
512  */
513  virtual TemplateVariant get(const QCString &name) const = 0;
514 
515  /** Returns a pointer to the value corresponding to a given key.
516  * @param[in] name The name of key.
517  * @returns A pointer to the value, or 0 in case the key was not found.
518  */
519  virtual const TemplateVariant *getRef(const QCString &name) const = 0;
520 
521  /** When files are created (i.e. by {% create ... %}) they written
522  * to the directory \a dir.
523  */
524  virtual void setOutputDirectory(const QCString &dir) = 0;
525 
526  /** Sets the interface that will be used for escaping the result
527  * of variable expansion before writing it to the output.
528  */
529  virtual void setEscapeIntf(const QCString &extension, TemplateEscapeIntf *intf) = 0;
530 
531  /** Sets the interface that will be used inside a spaceless block
532  * to remove any redundant whitespace.
533  */
534  virtual void setSpacelessIntf(TemplateSpacelessIntf *intf) = 0;
535 };
536 
537 //------------------------------------------------------------------------
538 
539 /** @brief Abstract interface for a template.
540  * @note Must be created and is deleted by the TemplateEngine
541  */
542 class Template
543 {
544  public:
545  /** Destructor */
546  virtual ~Template() {}
547 
548  /** Renders a template instance to a stream.
549  * @param[in] ts The text stream to write the results to.
550  * @param[in] c The context containing data that can be used
551  * when instantiating the template.
552  */
553  virtual void render(FTextStream &ts,TemplateContext *c) = 0;
554 };
555 
556 //------------------------------------------------------------------------
557 
558 /** @brief Engine to create templates and template contexts. */
560 {
561  public:
562  /** Create a template engine. */
563  TemplateEngine();
564 
565  /** Destroys the template engine. */
566  ~TemplateEngine();
567 
568  /** Creates a new context that can be using to render a template.
569  * @see Template::render()
570  */
571  TemplateContext *createContext() const;
572 
573  /** Destroys a context created via createContext().
574  * @param[in] ctx The context.
575  */
576  void destroyContext(TemplateContext *ctx);
577 
578  /** Creates a new template whose contents are in a file.
579  * @param[in] fileName The name of the file containing the template data
580  * @param[in] fromLine The line number of the statement that triggered the load
581  * @return the new template, the engine will keep ownership of the object.
582  */
583  Template *loadByName(const QCString &fileName,int fromLine);
584 
585  /** Indicates that template \a t is no longer needed. The engine
586  * may decide to delete it.
587  */
588  void unload(Template *t);
589 
590  /** Prints the current template file include stack */
591  void printIncludeContext(const char *fileName,int line) const;
592 
593  private:
594  friend class TemplateNodeBlock;
595  friend class TemplateNodeCreate;
596 
597  void enterBlock(const QCString &fileName,const QCString &blockName,int line);
598  void leaveBlock();
599 
600  /** Sets the extension of the output file. This is used to control the
601  * format of 'special' tags in the template
602  */
603  void setOutputExtension(const char *extension);
604 
605  /** Returns the output extension, set via setOutputExtension() */
606  QCString outputExtension() const;
607 
608  class Private;
609  Private *p;
610 };
611 
612 /** @} */
613 
614 #endif
static QCString name
Definition: declinfo.cpp:673
Abstract interface for a template context.
Definition: template.h:489
Class representing an &#39;create&#39; tag in a template.
Definition: template.cpp:3478
Private * p
Definition: template.h:450
Abstract interface for a template.
Definition: template.h:542
Private * p
Definition: template.h:399
TemplateVariant(* StubType)(const void *obj, const QValueList< TemplateVariant > &args)
Definition: template.h:98
TemplateVariant(int v)
Definition: template.h:170
static QCString blockName
TemplateListIntf * toList() const
Definition: template.h:256
static Delegate fromMethod(const T *objectPtr)
Definition: template.h:104
TemplateListIntf * m_list
Definition: template.h:297
const bool FALSE
Definition: qglobal.h:370
Default implementation of a context value of type list.
Definition: template.h:376
QCString typeAsString() const
Definition: template.h:145
TemplateVariant call(const QValueList< TemplateVariant > &args)
Definition: template.h:272
bool toBool() const
Definition: template.cpp:207
Raw data description.
Simplified and optimized version of QTextStream.
Definition: ftextstream.h:11
Abstract interface for a context value of type struct.
Definition: template.h:406
string dir
static Delegate fromFunction(const void *obj, StubType func)
Definition: template.h:112
Private data of the template engine.
Definition: template.cpp:4837
Class representing a &#39;block&#39; tag in a template.
Definition: template.cpp:3241
TemplateVariant & operator=(const TemplateVariant &v)
Definition: template.cpp:180
Delegate m_delegate
Definition: template.h:299
bool operator==(TemplateVariant &other)
Definition: template.h:211
TemplateVariant operator()(const QValueList< TemplateVariant > &args) const
Definition: template.h:121
static QCString args
Definition: declinfo.cpp:674
static QStrList * l
Definition: config.cpp:1044
T & operator*() const
Definition: template.h:316
int toInt() const
Definition: template.cpp:222
Helper class to create a delegate that can store a function/method call.
Definition: template.h:94
QCString m_strVal
Definition: template.h:291
Private data of a template list object.
Definition: template.cpp:303
QTextStream & reset(QTextStream &s)
QCString toString() const
Definition: template.h:232
TemplateStructIntf * m_strukt
Definition: template.h:296
virtual ~TemplateListIntf()
Definition: template.h:355
static int input(void)
Definition: code.cpp:15695
fileName
Definition: dumpTree.py:9
virtual ~TemplateStructIntf()
Definition: template.h:410
const void * m_objectPtr
Definition: template.h:127
TemplateVariant(const Delegate &delegate)
Definition: template.h:195
Abstract interface for a iterator of a list.
Definition: template.h:333
p
Definition: test.py:223
static Entry * current
Interface used to escape characters in a string.
Definition: template.h:457
Private * p
Definition: template.h:608
bool isValid() const
Definition: template.h:161
static TemplateVariant methodStub(const void *objectPtr, const QValueList< TemplateVariant > &args)
Definition: template.h:131
TemplateAutoRef(T *obj)
Definition: template.h:308
bool raw() const
Definition: template.h:287
Variant type which can hold one value of a fixed set of types.
Definition: template.h:90
Private data of a template struct object.
Definition: template.cpp:241
Engine to create templates and template contexts.
Definition: template.h:559
QCString & setNum(short n)
Definition: qcstring.cpp:469
string release
Definition: conf.py:24
void setRaw(bool b)
Definition: template.h:282
T * operator->() const
Definition: template.h:317
virtual ~TemplateContext()
Definition: template.h:492
TemplateVariant(bool b)
Definition: template.h:167
void line(double t, double *p, double &x, double &y, double &z)
def func()
Definition: docstring.py:7
virtual ~Template()
Definition: template.h:546
static bool * b
Definition: config.cpp:1043
TemplateVariant(const char *s, bool raw=FALSE)
Definition: template.h:173
TemplateStructIntf * toStruct() const
Definition: template.h:264
Type type() const
Definition: template.h:142
std::string escape(std::string const &str)
Abstract read-only interface for a context value of type list.
Definition: template.h:329
Default implementation of a context value of type struct.
Definition: template.h:426
static QCString * s
Definition: config.cpp:1042
TemplateVariant(const QCString &s, bool raw=FALSE)
Definition: template.h:176
Interface used to remove redundant spaces inside a spaceless block.
Definition: template.h:469