[clang-tools-extra] [llvm] [llvm] add support for mustache templating language (PR #105893)
Nicolas van Kempen via llvm-commits
llvm-commits at lists.llvm.org
Thu Jan 9 15:13:55 PST 2025
================
@@ -0,0 +1,114 @@
+//===--- Mustache.h ---------------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// Implementation of the Mustache templating language supports version 1.4.2
+// currently relies on llvm::json::Value for data input
+// See the Mustache spec for more information
+// (https://mustache.github.io/mustache.5.html).
+//
+// Current Features Supported:
+// - Variables
+// - Sections
+// - Inverted Sections
+// - Partials
+// - Comments
+// - Lambdas
+// - Unescaped Variables
+//
+// Features Not Supported:
+// - Set Delimiter
+// - Blocks
+// - Parents
+// - Dynamic Names
+//
+// The Template class is container class outputs the Mustache template string
+// and is main class for users. It stores all the lambdas and the ASTNode Tree.
+// When the Template is instantiated it tokenize the Template String and
+// creates a vector of Tokens. Then it calls a basic recursive descent parser
+// to construct the ASTNode Tree. The ASTNodes are all stored in an arena
+// allocator which is freed once the template class goes out of scope
+//
+// Usage:
+// \code
+// // Creating a simple template and rendering it
+// auto Template = Template("Hello, {{name}}!");
+// Value Data = {{"name", "World"}};
+// StringRef Rendered = Template.render(Data);
+// // Rendered == "Hello, World!"
+//
+// // Creating a template with a partial and rendering it
+// auto Template = Template("{{>partial}}");
+// Template.registerPartial("partial", "Hello, {{name}}!");
+// Value Data = {{"name", "World"}};
+// StringRef Rendered = Template.render(Data);
+// // Rendered == "Hello, World!"
+//
+// // Creating a template with a lambda and rendering it
+// auto Template = Template("{{#lambda}}Hello, {{name}}!{{/lambda}}");
+// Template.registerLambda("lambda", []() { return true; });
+// Value Data = {{"name", "World"}};
+// StringRef Rendered = Template.render(Data);
+// // Rendered == "Hello, World!"
+// \endcode
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_MUSTACHE
+#define LLVM_SUPPORT_MUSTACHE
+
+#include "Error.h"
+#include "llvm/ADT/StringMap.h"
+#include "llvm/Support/Allocator.h"
+#include "llvm/Support/JSON.h"
+#include "llvm/Support/StringSaver.h"
+#include <vector>
+
+namespace llvm {
+namespace mustache {
+
+using Accessor = SmallVector<std::string>;
+using Lambda = std::function<llvm::json::Value()>;
+using SectionLambda = std::function<llvm::json::Value(std::string)>;
+
+class ASTNode;
+
+// A Template represents the container for the AST and the partials
+// and Lambdas that are registered with it.
+class Template {
+public:
+ Template(std::string TemplateStr);
----------------
nicovank wrote:
The benefit of passing by value and moving is allowing users to have **zero** copies by moving directly into the member. For large template text strings, copies are expensive. Passing by StringRef and copying **always** forces one copy. For example, the user may want:
```cpp
std::string readSomeFile();
// Passing by StringRef, this will generate an unnecessary copy.
std::string templateText = readSomeFile();
Template template(std::move(templateText));
// Even more sneaky, this will read the file into a string, and duplicate that string to create the template.
Template template(readSomeFile());
```
Maybe there is a way to restructure the API to use non-owning view members only? This is probably a non-trivial change to this work. I’ll try to have another look and post some review comments by end of week.
https://github.com/llvm/llvm-project/pull/105893
More information about the llvm-commits
mailing list