diff options
Diffstat (limited to 'src/template.h')
-rw-r--r-- | src/template.h | 557 |
1 files changed, 0 insertions, 557 deletions
diff --git a/src/template.h b/src/template.h deleted file mode 100644 index 4b0cfe5..0000000 --- a/src/template.h +++ /dev/null @@ -1,557 +0,0 @@ -/****************************************************************************** - * - * Copyright (C) 1997-2015 by Dimitri van Heesch. - * - * Permission to use, copy, modify, and distribute this software and its - * documentation under the terms of the GNU General Public License is hereby - * granted. No representations are made about the suitability of this software - * for any purpose. It is provided "as is" without express or implied warranty. - * See the GNU General Public License for more details. - * - * Documents produced by Doxygen are derivative works derived from the - * input used in their production; they are not affected by this license. - * - */ - -#ifndef TEMPLATE_H -#define TEMPLATE_H - -#include <vector> -#include <memory> -#include <functional> -#include <variant> - -#include "qcstring.h" -#include "containers.h" - -class TemplateListIntf; -class TemplateStructIntf; -class TemplateEngine; -class TextStream; - -using TemplateListIntfPtr = std::shared_ptr<TemplateListIntf>; -using TemplateStructIntfPtr = std::shared_ptr<TemplateStructIntf>; -using TemplateStructIntfWeakPtr = std::weak_ptr<TemplateStructIntf>; - -/** @defgroup template_api Template API - * - * This is the API for a - * <a href="https://www.djangoproject.com/">Django</a> - * compatible template system written in C++. - * It is somewhat inspired by Stephen Kelly's - * <a href="http://www.gitorious.org/grantlee/pages/Home">Grantlee</a>. - * - * A template is simply a text file. - * A template contains \b variables, which get replaced with values when the - * template is evaluated, and \b tags, which control the logic of the template. - * - * Variables look like this: `{{ variable }}` - * When the template engine encounters a variable, it evaluates that variable and - * replaces it with the result. Variable names consist of any combination of - * alphanumeric characters and the underscore ("_"). - * Use a dot (.) to access attributes of a structured variable. - * - * One can modify variables for display by using \b filters, for example: - * `{{ value|default:"nothing" }}` - * - * Tags look like this: `{% tag %}`. Tags are more complex than variables: - * Some create text in the output, some control flow by performing loops or logic, - * and some load external information into the template to be used by later variables. - * - * To comment-out part of a line in a template, use the comment syntax: - * `{# comment text #}`. - * - * Supported Django tags: - * - `for ... empty ... endfor` - * - `if ... else ... endif` - * - `block ... endblock` - * - `extend` - * - `include` - * - `with ... endwith` - * - `spaceless ... endspaceless` - * - `cycle` - * - * Extension tags: - * - `create` which instantiates a template and writes the result to a file. - * The syntax is `{% create 'filename' from 'template' %}`. - * - `recursetree` - * - `markers` - * - `msg` ... `endmsg` - * - `set` - * - * Supported Django filters: - * - `default` - * - `length` - * - `add` - * - `divisibleby` - * - * Extension filters: - * - `stripPath` - * - `nowrap` - * - `prepend` - * - `append` - * - * @{ - */ - -/** @brief Variant type which can hold one value of a fixed set of types. */ -class TemplateVariant -{ - public: - /** Type representing a function call in a template */ - using FunctionDelegate = std::function<TemplateVariant(const std::vector<TemplateVariant>&)>; - - /** Symbolic names for the possible types that this variant can hold. */ - using VariantT = std::variant<std::monostate, // index==0, Invalid/default type - bool, // index==1: Type::Bool - int, // index==2: Type::Int - QCString, // index==3: Type::String - TemplateStructIntfPtr, // index==4: Type::Struct - TemplateListIntfPtr, // index==5: Type::List - FunctionDelegate, // index==6: Type::Function - TemplateStructIntfWeakPtr // index==7: Type::WeakStruct - >; - - enum class Type : uint8_t - { - None = 0, - Bool = 1, - Int = 2, - String = 3, - Struct = 4, - List = 5, - Function = 6, - WeakStruct = 7 - }; - - /** Constructs an invalid variant. */ - TemplateVariant() {} - - /** Constructs a new variant with a boolean value \a b. */ - explicit TemplateVariant(bool b) { m_variant = b; } - - /** Constructs a new variant with a integer value \a v. */ - TemplateVariant(int v) { m_variant = v; } - - /** Constructs a new variant with a integer value \a v. */ - TemplateVariant(unsigned int v) { m_variant = static_cast<int>(v); } - - /** Constructs a new variant with a integer value \a v. - * We use SFINAE to avoid a compiler error in case size_t already matches the 'unsigned int' overload. - */ - template<typename T, - typename std::enable_if<std::is_same<T,size_t>::value,T>::type* = nullptr - > - TemplateVariant(T v) { m_variant = static_cast<int>(v); } - - /** Constructs a new variant with a string value \a s. */ - TemplateVariant(const char *s,bool raw=FALSE) : m_raw(raw) { m_variant = QCString(s); } - - /** Constructs a new variant with a string value \a s. */ - TemplateVariant(const QCString &s,bool raw=FALSE) : m_raw(raw) { m_variant = s; } - - /** Constructs a new variant with a string value \a s. */ - TemplateVariant(const std::string &s,bool raw=FALSE) : m_raw(raw) { m_variant = QCString(s); } - - /** Constructs a new variant with a struct value \a s. - * @note. The variant will hold a counting reference to the object. - */ - TemplateVariant(TemplateStructIntfPtr s) { m_variant = s; } - - /** Constructs a new variant with a list value \a l. - * @note. The variant will hold a counting reference to the object. - */ - TemplateVariant(TemplateListIntfPtr l) { m_variant = l; } - - /** Constructs a new variant with a struct value \a s. - * @note. The variant will hold a non-counting reference to the object. - */ - TemplateVariant(TemplateStructIntfWeakPtr s) { m_variant = s; } - - /** Constructs a new variant which represents a method call - * @param[in] delegate FunctionDelegate object to invoke when - * calling call() on this variant. - * @note Use TemplateVariant::FunctionDelegate::fromMethod() and - * TemplateVariant::FunctionDelegate::fromFunction() to create - * FunctionDelegate objects. - */ - TemplateVariant(FunctionDelegate delegate) { m_variant = delegate; } - - /** Destroys the Variant object */ - ~TemplateVariant() = default; - - /** Constructs a copy of the variant, \a v, - * passed as the argument to this constructor. - */ - TemplateVariant(const TemplateVariant &v) = default; - - /** Moves the contents of variant \a v into this variant. - * variant \a v will become invalid - */ - TemplateVariant(TemplateVariant &&v); - - /** Assigns the value of the variant \a v to this variant. */ - TemplateVariant &operator=(const TemplateVariant &v) = default; - - /** Move the value of the variant \a v into this variant. - * Variant \a v will become invalid */ - TemplateVariant &operator=(TemplateVariant &&v); - - /** Compares this QVariant with v and returns true if they are equal; - * otherwise returns false. - */ - bool operator==(TemplateVariant &other) const; - - /** Returns the variant as a string. */ - QCString toString() const; - - /** Returns the variant as a boolean. */ - bool toBool() const; - - /** Returns the variant as an integer. */ - int toInt() const; - - /** Returns TRUE if the variant holds a valid value, or FALSE otherwise */ - constexpr bool isValid() const { return std::holds_alternative<std::monostate>(m_variant); } - /** Returns TRUE if the variant holds a boolean value */ - constexpr bool isBool() const { return std::holds_alternative<bool>(m_variant); } - /** Returns TRUE if the variant holds an integer value */ - constexpr bool isInt() const { return std::holds_alternative<int>(m_variant); } - /** Returns TRUE if the variant holds a string value */ - constexpr bool isString() const { return std::holds_alternative<QCString>(m_variant); } - /** Returns TRUE if the variant holds a struct value */ - constexpr bool isStruct() const { return std::holds_alternative<TemplateStructIntfPtr>(m_variant); } - /** Returns TRUE if the variant holds a list value */ - constexpr bool isList() const { return std::holds_alternative<TemplateListIntfPtr>(m_variant); } - /** Returns TRUE if the variant holds a function value */ - constexpr bool isFunction() const { return std::holds_alternative<FunctionDelegate>(m_variant); } - /** Returns TRUE if the variant holds a struct value */ - constexpr bool isWeakStruct() const { return std::holds_alternative<TemplateStructIntfWeakPtr>(m_variant); } - - /** Returns the pointer to list referenced by this variant - * or 0 if this variant does not have list type. - */ - TemplateListIntfPtr toList(); - const TemplateListIntfPtr toList() const; - - /** Returns the pointer to struct referenced by this variant - * or 0 if this variant does not have struct type. - */ - TemplateStructIntfPtr toStruct(); - const TemplateStructIntfPtr toStruct() const; - - /** Return the result of apply this function with \a args. - * Returns an empty string if the variant type is not a function. - */ - TemplateVariant call(const std::vector<TemplateVariant> &args = std::vector<TemplateVariant>()); - - /** Sets whether or not the value of the Variant should be - * escaped or written as-is (raw). - * @param[in] b TRUE means write as-is, FALSE means apply escaping. - */ - void setRaw(bool b) { m_raw = b; } - - /** Returns whether or not the value of the Value is raw. - * @see setRaw() - */ - constexpr bool raw() const { return m_raw; } - - /** Returns the type held by this variant */ - constexpr Type type() const { return static_cast<Type>(m_variant.index()); } - - /** Returns a string representation of this variant's type */ - const char *typeAsString() const; - - private: - QCString listToString() const; - QCString structToString() const; - - VariantT m_variant; - bool m_raw = false; -}; - -using TemplateVariantList = std::vector<TemplateVariant>; - -//------------------------------------------------------------------------ - -/** @brief Abstract read-only interface for a context value of type list. - * @note The values of the list are TemplateVariants. - */ -class TemplateListIntf -{ - public: - /** @brief Abstract interface for a iterator of a list. */ - class ConstIterator - { - public: - /** Destructor for the iterator */ - virtual ~ConstIterator() = default; - /** Moves iterator to the first element in the list */ - virtual void toFirst() = 0; - /** Moves iterator to the last element in the list */ - virtual void toLast() = 0; - /** Moves iterator to the next element in the list */ - virtual void toNext() = 0; - /** Moves iterator to the previous element in the list */ - virtual void toPrev() = 0; - /* Returns TRUE if the iterator points to a valid element - * in the list, or FALSE otherwise. - * If TRUE is returned, the value pointed to be the - * iterator is assigned to \a v. - */ - virtual bool current(TemplateVariant &v) const = 0; - }; - using ConstIteratorPtr = std::unique_ptr<ConstIterator>; - - /** Destroys the list */ - virtual ~TemplateListIntf() = default; - - /** Returns the number of elements in the list */ - virtual size_t count() const = 0; - - /** Returns the element at index position \a index. */ - virtual TemplateVariant at(size_t index) const = 0; - - /** Creates a new iterator for this list. - * @note the user should call delete on the returned pointer. - */ - virtual TemplateListIntf::ConstIteratorPtr createIterator() const = 0; - -}; - -/** @brief Default implementation of a immutable context value of type list. */ -class TemplateImmutableList : public TemplateListIntf -{ - public: - // TemplateListIntf methods - virtual size_t count() const; - virtual TemplateVariant at(size_t index) const; - virtual TemplateListIntf::ConstIteratorPtr createIterator() const; - - /** Creates an instance and returns a shared pointer to it */ - static TemplateListIntfPtr alloc(std::initializer_list<TemplateVariant> elements); - static TemplateListIntfPtr alloc(const std::vector<TemplateVariant> &elements); - - /** Creates a list */ - TemplateImmutableList(std::initializer_list<TemplateVariant> elements); - TemplateImmutableList(const std::vector<TemplateVariant> &elements); - /** Destroys the list */ - virtual ~TemplateImmutableList(); - - private: - class Private; - std::unique_ptr<Private> p; -}; - -//------------------------------------------------------------------------ - -/** @brief Abstract interface for a context value of type struct. */ -class TemplateStructIntf -{ - public: - /** Destroys the struct */ - virtual ~TemplateStructIntf() = default; - - /** Gets the value for a field name. - * @param[in] name The name of the field. - */ - virtual TemplateVariant get(const QCString &name) const = 0; - - /** Return the list of fields. */ - virtual StringVector fields() const = 0; -}; - -//------------------------------------------------------------------------ - -/** @brief Default implementation of an immutable context value of type struct. */ -class TemplateImmutableStruct : public TemplateStructIntf -{ - public: - // TemplateStructIntf methods - virtual TemplateVariant get(const QCString &name) const; - virtual StringVector fields() const; - - using StructField = std::pair<const std::string,TemplateVariant>; - - /** Creates an instance and returns a shared pointer to it - * @param fields the fields of the struct as key/value pairs. - */ - static TemplateStructIntfPtr alloc(std::initializer_list<StructField> fields); - - /** Creates a struct */ - TemplateImmutableStruct(std::initializer_list<StructField> fields); - /** Destroys the struct */ - virtual ~TemplateImmutableStruct(); - - private: - - class Private; - std::unique_ptr<Private> p; -}; - - -//------------------------------------------------------------------------ - -/** @brief Interface used to escape characters in a string */ -class TemplateEscapeIntf -{ - public: - virtual ~TemplateEscapeIntf() = default; - /** Create a copy of the escape filter */ - virtual std::unique_ptr<TemplateEscapeIntf> clone() = 0; - /** Returns the \a input after escaping certain characters */ - virtual QCString escape(const QCString &input) = 0; - /** Setting tabbing mode on or off (for LaTeX) */ - virtual void enableTabbing(bool b) = 0; -}; - -//------------------------------------------------------------------------ - -/** @brief Interface used to remove redundant spaces inside a spaceless block */ -class TemplateSpacelessIntf -{ - public: - virtual ~TemplateSpacelessIntf() = default; - /** Create a copy of the spaceless filter */ - virtual std::unique_ptr<TemplateSpacelessIntf> clone() = 0; - /** Returns the \a input after removing redundant whitespace */ - virtual QCString remove(const QCString &input) = 0; - /** Reset filter state */ - virtual void reset() = 0; -}; - -//------------------------------------------------------------------------ - -/** @brief Abstract interface for a template context. - * - * A Context consists of a stack of dictionaries. - * A dictionary consists of a mapping of string keys onto TemplateVariant values. - * A key is searched starting with the dictionary at the top of the stack - * and searching downwards until it is found. The stack is used to create - * local scopes. - * @note This object must be created by TemplateEngine::createContext() - */ -class TemplateContext -{ - public: - virtual ~TemplateContext() = default; - - /** Push a new scope on the stack. */ - virtual void push() = 0; - - /** Pop the current scope from the stack. */ - virtual void pop() = 0; - - /** Sets a value in the current scope. - * @param[in] name The name of the value; the key in the dictionary. - * @param[in] v The value associated with the key. - * @note When a given key is already present, - * its value will be replaced by \a v - */ - virtual void set(const QCString &name,const TemplateVariant &v) = 0; - - /** Gets the value for a given key - * @param[in] name The name of key. - * @returns The value, which can be an invalid variant in case the - * key was not found. - */ - virtual TemplateVariant get(const QCString &name) const = 0; - - /** Returns a pointer to the value corresponding to a given key. - * @param[in] name The name of key. - * @returns A pointer to the value, or 0 in case the key was not found. - */ - virtual const TemplateVariant *getRef(const QCString &name) const = 0; - - /** When files are created (i.e. by {% create ... %}) they written - * to the directory \a dir. - */ - virtual void setOutputDirectory(const QCString &dir) = 0; - - /** Sets the interface that will be used for escaping the result - * of variable expansion before writing it to the output. - */ - virtual void setEscapeIntf(const QCString &extension, std::unique_ptr<TemplateEscapeIntf> intf) = 0; - - /** Sets the interface that will be used inside a spaceless block - * to remove any redundant whitespace. - */ - virtual void setSpacelessIntf(std::unique_ptr<TemplateSpacelessIntf> intf) = 0; -}; - -//------------------------------------------------------------------------ - -/** @brief Abstract interface for a template. - * @note Must be created and is deleted by the TemplateEngine - */ -class Template -{ - public: - /** Destructor */ - virtual ~Template() = default; - - /** Renders a template instance to a stream. - * @param[in] ts The text stream to write the results to. - * @param[in] c The context containing data that can be used - * when instantiating the template. - */ - virtual void render(TextStream &ts,TemplateContext *c) = 0; -}; - -//------------------------------------------------------------------------ - -/** @brief Engine to create templates and template contexts. */ -class TemplateEngine -{ - public: - /** Create a template engine. */ - TemplateEngine(); - - /** Destroys the template engine. */ - ~TemplateEngine(); - - /** Creates a new context that can be using to render a template. - * @see Template::render() - */ - std::unique_ptr<TemplateContext> createContext() const; - - /** Creates a new template whose contents are in a file. - * @param[in] fileName The name of the file containing the template data - * @param[in] fromLine The line number of the statement that triggered the load - * @return the new template, the engine will keep ownership of the object. - */ - Template *loadByName(const QCString &fileName,int fromLine); - - /** Indicates that template \a t is no longer needed. The engine - * may decide to delete it. - */ - void unload(Template *t); - - /** Prints the current template file include stack */ - void printIncludeContext(const QCString &fileName,int line) const; - - /** Sets the search directory where to look for template files */ - void setTemplateDir(const QCString &dirName); - - private: - friend class TemplateNodeBlock; - friend class TemplateNodeCreate; - - void enterBlock(const QCString &fileName,const QCString &blockName,int line); - void leaveBlock(); - - /** Sets the extension of the output file. This is used to control the - * format of 'special' tags in the template - */ - void setOutputExtension(const QCString &extension); - - /** Returns the output extension, set via setOutputExtension() */ - QCString outputExtension() const; - - class Private; - std::unique_ptr<Private> p; -}; - -/** @} */ - -#endif |