summaryrefslogtreecommitdiff
path: root/includes/SimpleMustache.h
diff options
context:
space:
mode:
authorPixel <pixel@nobis-crew.org>2011-11-25 00:06:34 -0800
committerPixel <pixel@nobis-crew.org>2011-11-25 00:06:34 -0800
commitedae25d41d89564a21e0e0a11b4cde2287ba889e (patch)
tree31c07a4965a602e77c3f58b6762f7bb884a2024d /includes/SimpleMustache.h
parent5db0c9feb06217d2d343d75cdc6e2b3a5fec7343 (diff)
Adding a simple 'Mustache' template processor in C++.
Diffstat (limited to 'includes/SimpleMustache.h')
-rw-r--r--includes/SimpleMustache.h98
1 files changed, 98 insertions, 0 deletions
diff --git a/includes/SimpleMustache.h b/includes/SimpleMustache.h
new file mode 100644
index 0000000..d98b5eb
--- /dev/null
+++ b/includes/SimpleMustache.h
@@ -0,0 +1,98 @@
+#pragma once
+#include <map>
+#include <vector>
+#include <list>
+#include <Handle.h>
+#include <Buffer.h>
+
+namespace Balau {
+
+class SimpleMustache {
+ public:
+
+ class Context {
+ public:
+ class Proxy {
+ public:
+ Context & operator[](const char * str);
+ Context & operator=(const char * str);
+ Context & operator=(bool b);
+ private:
+ Proxy(Context * parent, ssize_t idx) : m_parent(parent), m_idx(idx) { }
+ Context * m_parent;
+ ssize_t m_idx;
+ friend class Context;
+ };
+
+ Context() : m_type(CONTEXTLIST), m_root(true) { }
+ ~Context() { empty(); }
+ Proxy operator[](ssize_t idx) { ensureList(); return Proxy(this, idx); }
+ Context & operator[](const char * str);
+ Context & operator=(const char * str) {
+ empty();
+ m_type = STRING;
+ m_str = str;
+ }
+ Context & operator=(bool b) {
+ empty();
+ m_type = BOOLSEC;
+ m_bool = b;
+ }
+ private:
+ enum ContextType {
+ UNKNOWN,
+ STRING,
+ BOOLSEC,
+ CONTEXTLIST,
+ LAMBDA,
+ } m_type;
+ Context(ContextType type) : m_type(type), m_root(false) { }
+ Context(Context & c) { Assert(false); }
+ Context & operator=(Context & c) { Assert(false); }
+ String m_str;
+ bool m_bool;
+ typedef std::map<String, Context *> SubContext;
+ typedef std::vector<SubContext> ContextList;
+ ContextList m_contextList;
+ bool m_root;
+
+ void empty(bool skipFirst = false);
+ void ensureList(bool single = false);
+
+ friend class Proxy;
+ friend class SimpleMustache;
+ };
+
+ void setTemplate(IO<Handle> h);
+ void setTemplate(const uint8_t * str, ssize_t s = -1) {
+ if (s < 0)
+ s = strlen((const char *) str);
+ IO<Buffer> b(new Buffer(str, s));
+ setTemplate(b);
+ }
+ void setTemplate(const char * str, ssize_t s = -1) { setTemplate((const uint8_t *) str, s); }
+ void setTemplate(const String & str) { setTemplate((const uint8_t *) str.to_charp(), str.strlen()); }
+ void render(IO<Handle> h, Context * ctx) { Assert(ctx); render_r(h, ctx, "", m_fragments.begin(), false, -1); }
+ void empty() { while (!m_fragments.empty()) { delete m_fragments.front(); m_fragments.pop_front(); } }
+ ~SimpleMustache() { empty(); }
+ private:
+ struct Fragment {
+ enum {
+ UNKNOWN,
+ STRING,
+ VARIABLE,
+ NOESCAPE,
+ SECTION,
+ INVERTED,
+ END_SECTION,
+ } type;
+ String str; // contains either the string, the variable name, or the sections names.
+ };
+ typedef std::list<Fragment *> Fragments;
+ Fragments m_fragments;
+
+ Fragments::iterator render_r(IO<Handle> h, Context * ctx, const String & endSection, Fragments::iterator begin, bool noWrite, int forceIdx);
+ String escape(const String & s) { return s; }
+};
+
+};