FactDev  0.1
mustache.h
1 /*
2  Copyright 2012, Robert Knight
3 
4  Redistribution and use in source and binary forms, with or without modification,
5  are permitted provided that the following conditions are met:
6 
7  Redistributions of source code must retain the above copyright notice,
8  this list of conditions and the following disclaimer.
9 
10  Redistributions in binary form must reproduce the above copyright notice,
11  this list of conditions and the following disclaimer in the documentation
12  and/or other materials provided with the distribution.
13 */
14 
15 #pragma once
16 
17 #include <QtCore/QStack>
18 #include <QtCore/QString>
19 #include <QtCore/QVariant>
20 
21 #if __cplusplus >= 201103L
22 #include <functional> /* for std::function */
23 #endif
24 
25 namespace Mustache
26 {
27 
28 class PartialResolver;
29 class Renderer;
30 
34 class Context
35 {
36 public:
40  explicit Context(PartialResolver* resolver = 0);
41  virtual ~Context() {}
42 
46  virtual QString stringValue(const QString& key) const = 0;
47 
55  virtual bool isFalse(const QString& key) const = 0;
56 
60  virtual int listCount(const QString& key) const = 0;
61 
66  virtual void push(const QString& key, int index = -1) = 0;
67 
69  virtual void pop() = 0;
70 
72  QString partialValue(const QString& key) const;
73 
76 
86  virtual bool canEval(const QString& key) const;
87 
93  virtual QString eval(const QString& key, const QString& _template, Renderer* renderer);
94 
95 private:
96  PartialResolver* m_partialResolver;
97 };
98 
100 class QtVariantContext : public Context
101 {
102 public:
106 #if __cplusplus >= 201103L
107  typedef std::function<QString(const QString&, Mustache::Renderer*, Mustache::Context*)> fn_t;
108 #else
109  typedef QString (*fn_t)(const QString&, Mustache::Renderer*, Mustache::Context*);
110 #endif
111  explicit QtVariantContext(const QVariant& root, PartialResolver* resolver = 0);
112 
113  virtual QString stringValue(const QString& key) const;
114  virtual bool isFalse(const QString& key) const;
115  virtual int listCount(const QString& key) const;
116  virtual void push(const QString& key, int index = -1);
117  virtual void pop();
118  virtual bool canEval(const QString& key) const;
119  virtual QString eval(const QString& key, const QString& _template, Mustache::Renderer* renderer);
120 
121 private:
122  QVariant value(const QString& key) const;
123 
124  QStack<QVariant> m_contextStack;
125 };
126 
129 {
130 public:
131  virtual ~PartialResolver() {}
132 
134  virtual QString getPartial(const QString& name) = 0;
135 };
136 
140 {
141 public:
142  explicit PartialMap(const QHash<QString,QString>& partials);
143 
144  virtual QString getPartial(const QString& name);
145 
146 private:
147  QHash<QString, QString> m_partials;
148 };
149 
156 {
157 public:
158  explicit PartialFileLoader(const QString& basePath);
159 
160  virtual QString getPartial(const QString& name);
161 
162 private:
163  QString m_basePath;
164  QHash<QString, QString> m_cache;
165 };
166 
168 struct Tag
169 {
170  enum Type
171  {
172  Null,
173  Value,
180  };
181 
182  enum EscapeMode
183  {
184  Escape,
185  Unescape,
186  Raw
187  };
188 
189  Tag()
190  : type(Null)
191  , start(0)
192  , end(0)
193  , escapeMode(Escape)
194  {}
195 
196  Type type;
197  QString key;
198  int start;
199  int end;
200  EscapeMode escapeMode;
201 };
202 
206 class Renderer
207 {
208 public:
209  Renderer();
210 
214  QString render(const QString& _template, Context* context);
215 
219  QString error() const;
220 
227  int errorPos() const;
228 
232  QString errorPartial() const;
233 
237  void setTagMarkers(const QString& startMarker, const QString& endMarker);
238 
239 private:
240  QString render(const QString& _template, int startPos, int endPos, Context* context);
241 
242  Tag findTag(const QString& content, int pos, int endPos);
243  Tag findEndTag(const QString& content, const Tag& startTag, int endPos);
244  void setError(const QString& error, int pos);
245 
246  void readSetDelimiter(const QString& content, int pos, int endPos);
247  static QString readTagName(const QString& content, int pos, int endPos);
248 
257  static void expandTag(Tag& tag, const QString& content);
258 
259  QStack<QString> m_partialStack;
260  QString m_error;
261  int m_errorPos;
262  QString m_errorPartial;
263 
264  QString m_tagStartMarker;
265  QString m_tagEndMarker;
266 
267  QString m_defaultTagStartMarker;
268  QString m_defaultTagEndMarker;
269 };
270 
272 QString renderTemplate(const QString& templateString, const QVariantHash& args);
273 
274 };
275 
276 Q_DECLARE_METATYPE(Mustache::QtVariantContext::fn_t)
Definition: mustache.h:100
virtual QString getPartial(const QString &name)
Definition: mustache.cpp:214
virtual QString getPartial(const QString &name)
Definition: mustache.cpp:205
Context(PartialResolver *resolver=0)
Definition: mustache.cpp:66
QString(* fn_t)(const QString &, Mustache::Renderer *, Mustache::Context *)
Definition: mustache.h:109
QString errorPartial() const
Definition: mustache.cpp:244
virtual QString eval(const QString &key, const QString &_template, Renderer *renderer)
Definition: mustache.cpp:88
void setTagMarkers(const QString &startMarker, const QString &endMarker)
Definition: mustache.cpp:520
virtual bool isFalse(const QString &key) const =0
virtual int listCount(const QString &key) const
Definition: mustache.cpp:179
virtual bool isFalse(const QString &key) const
Definition: mustache.cpp:138
virtual void pop()=0
Definition: mustache.h:139
virtual QString eval(const QString &key, const QString &_template, Mustache::Renderer *renderer)
Definition: mustache.cpp:192
Definition: mustache.h:155
virtual bool canEval(const QString &key) const
Definition: mustache.cpp:187
Definition: mustache.h:34
A {{/section}} tag.
Definition: mustache.h:177
QString partialValue(const QString &key) const
Definition: mustache.cpp:75
virtual void push(const QString &key, int index=-1)=0
QString render(const QString &_template, Context *context)
Definition: mustache.cpp:249
virtual QString stringValue(const QString &key) const
Definition: mustache.cpp:155
virtual void pop()
Definition: mustache.cpp:174
Definition: mustache.h:206
virtual int listCount(const QString &key) const =0
QString error() const
Definition: mustache.cpp:234
An {{^inverted-section}} tag.
Definition: mustache.h:176
Definition: mustache.h:128
Definition: mustache.h:168
A {{#section}} tag.
Definition: mustache.h:175
A {{^partial}} tag.
Definition: mustache.h:178
virtual void push(const QString &key, int index=-1)
Definition: mustache.cpp:163
A {{key}} or {{{key}}} tag.
Definition: mustache.h:174
A {{! comment }} tag.
Definition: mustache.h:179
int errorPos() const
Definition: mustache.cpp:239
virtual QString getPartial(const QString &name)=0
virtual QString stringValue(const QString &key) const =0
virtual bool canEval(const QString &key) const
Definition: mustache.cpp:83
Type
Definition: mustache.h:170
PartialResolver * partialResolver() const
Definition: mustache.cpp:70