| 
 | 1 | +//===--- Mustache.h ---------------------------------------------*- C++ -*-===//  | 
 | 2 | +//  | 
 | 3 | +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.  | 
 | 4 | +// See https://llvm.org/LICENSE.txt for license information.  | 
 | 5 | +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception  | 
 | 6 | +//  | 
 | 7 | +//===----------------------------------------------------------------------===//  | 
 | 8 | +//  | 
 | 9 | +// Implementation of the Mustache templating language supports version 1.4.2  | 
 | 10 | +// currently relies on llvm::json::Value for data input.  | 
 | 11 | +// See the Mustache spec for more information  | 
 | 12 | +// (https://mustache.github.io/mustache.5.html).  | 
 | 13 | +//  | 
 | 14 | +// Current Features Supported:  | 
 | 15 | +// - Variables  | 
 | 16 | +// - Sections  | 
 | 17 | +// - Inverted Sections  | 
 | 18 | +// - Partials  | 
 | 19 | +// - Comments  | 
 | 20 | +// - Lambdas  | 
 | 21 | +// - Unescaped Variables  | 
 | 22 | +//  | 
 | 23 | +// Features Not Supported:  | 
 | 24 | +// - Set Delimiter  | 
 | 25 | +// - Blocks  | 
 | 26 | +// - Parents  | 
 | 27 | +// - Dynamic Names  | 
 | 28 | +//  | 
 | 29 | +// The Template class is a container class that outputs the Mustache template  | 
 | 30 | +// string and is the main class for users. It stores all the lambdas and the  | 
 | 31 | +// ASTNode Tree. When the Template is instantiated it tokenizes the Template  | 
 | 32 | +// String and creates a vector of Tokens. Then it calls a basic recursive  | 
 | 33 | +// descent parser to construct the ASTNode Tree. The ASTNodes are all stored  | 
 | 34 | +// in an arena allocator which is freed once the template class goes out of  | 
 | 35 | +// scope.  | 
 | 36 | +//  | 
 | 37 | +// Usage:  | 
 | 38 | +// \code  | 
 | 39 | +//   // Creating a simple template and rendering it  | 
 | 40 | +//   auto Template = Template("Hello, {{name}}!");  | 
 | 41 | +//   Value Data = {{"name", "World"}};  | 
 | 42 | +//   std::string Out;  | 
 | 43 | +//   raw_string_ostream OS(Out);  | 
 | 44 | +//   T.render(Data, OS);  | 
 | 45 | +//   // Out == "Hello, World!"  | 
 | 46 | +//  | 
 | 47 | +//   // Creating a template with a partial and rendering it  | 
 | 48 | +//   auto Template = Template("{{>partial}}");  | 
 | 49 | +//   Template.registerPartial("partial", "Hello, {{name}}!");  | 
 | 50 | +//   Value Data = {{"name", "World"}};  | 
 | 51 | +//   std::string Out;  | 
 | 52 | +//   raw_string_ostream OS(Out);  | 
 | 53 | +//   T.render(Data, OS);  | 
 | 54 | +//   // Out == "Hello, World!"  | 
 | 55 | +//  | 
 | 56 | +//   // Creating a template with a lambda and rendering it  | 
 | 57 | +//   Value D = Object{};  | 
 | 58 | +//   auto T = Template("Hello, {{lambda}}!");  | 
 | 59 | +//   Lambda L = []() -> llvm::json::Value { return "World"; };  | 
 | 60 | +//   T.registerLambda("lambda", L);  | 
 | 61 | +//   std::string Out;  | 
 | 62 | +//   raw_string_ostream OS(Out);  | 
 | 63 | +//   T.render(D, OS);  | 
 | 64 | +//   // Out == "Hello, World!"  | 
 | 65 | +// \endcode  | 
 | 66 | +//  | 
 | 67 | +//===----------------------------------------------------------------------===//  | 
 | 68 | + | 
 | 69 | +#ifndef LLVM_SUPPORT_MUSTACHE  | 
 | 70 | +#define LLVM_SUPPORT_MUSTACHE  | 
 | 71 | + | 
 | 72 | +#include "Error.h"  | 
 | 73 | +#include "llvm/ADT/StringMap.h"  | 
 | 74 | +#include "llvm/Support/Allocator.h"  | 
 | 75 | +#include "llvm/Support/JSON.h"  | 
 | 76 | +#include "llvm/Support/StringSaver.h"  | 
 | 77 | +#include <functional>  | 
 | 78 | +#include <vector>  | 
 | 79 | + | 
 | 80 | +namespace llvm::mustache {  | 
 | 81 | + | 
 | 82 | +using Lambda = std::function<llvm::json::Value()>;  | 
 | 83 | +using SectionLambda = std::function<llvm::json::Value(std::string)>;  | 
 | 84 | + | 
 | 85 | +class ASTNode;  | 
 | 86 | + | 
 | 87 | +// A Template represents the container for the AST and the partials  | 
 | 88 | +// and Lambdas that are registered with it.  | 
 | 89 | +class Template {  | 
 | 90 | +public:  | 
 | 91 | +  Template(StringRef TemplateStr);  | 
 | 92 | + | 
 | 93 | +  Template(const Template &) = delete;  | 
 | 94 | + | 
 | 95 | +  Template &operator=(const Template &) = delete;  | 
 | 96 | + | 
 | 97 | +  Template(Template &&Other) noexcept;  | 
 | 98 | + | 
 | 99 | +  Template &operator=(Template &&Other) noexcept;  | 
 | 100 | + | 
 | 101 | +  void render(const llvm::json::Value &Data, llvm::raw_ostream &OS);  | 
 | 102 | + | 
 | 103 | +  void registerPartial(std::string Name, std::string Partial);  | 
 | 104 | + | 
 | 105 | +  void registerLambda(std::string Name, Lambda Lambda);  | 
 | 106 | + | 
 | 107 | +  void registerLambda(std::string Name, SectionLambda Lambda);  | 
 | 108 | + | 
 | 109 | +  // By default the Mustache Spec Specifies that HTML special characters  | 
 | 110 | +  // should be escaped. This function allows the user to specify which  | 
 | 111 | +  // characters should be escaped.  | 
 | 112 | +  void overrideEscapeCharacters(DenseMap<char, std::string> Escapes);  | 
 | 113 | + | 
 | 114 | +private:  | 
 | 115 | +  StringMap<ASTNode *> Partials;  | 
 | 116 | +  StringMap<Lambda> Lambdas;  | 
 | 117 | +  StringMap<SectionLambda> SectionLambdas;  | 
 | 118 | +  DenseMap<char, std::string> Escapes;  | 
 | 119 | +  // The allocator for the ASTNode Tree  | 
 | 120 | +  llvm::BumpPtrAllocator AstAllocator;  | 
 | 121 | +  // Allocator for each render call resets after each render  | 
 | 122 | +  llvm::BumpPtrAllocator RenderAllocator;  | 
 | 123 | +  ASTNode *Tree;  | 
 | 124 | +};  | 
 | 125 | +} // namespace llvm::mustache  | 
 | 126 | + | 
 | 127 | +#endif // LLVM_SUPPORT_MUSTACHE  | 
0 commit comments