pluvo
v0.1.1
Published
A code generation tool that treats real source files as templates. Directives live in comments and are stripped after rendering, so your templates stay valid for any language.
Downloads
188
Readme
pluvo
A code generation tool that treats real source files as templates. Directives live in comments and are stripped after rendering, so your templates stay valid for any language.
- No handlebars/ejs syntax. Templates are the original language.
- A single token (
@@@) for all directives. - Works with strings, files, and globs.
- Supports includes with path interpolation.
- Comment-only directives keep syntax highlighting, formatters, linters, and IDE tooling intact.
Requirements
- Runtime: Node.js or Bun.
- Module: native ESM (
.mjs). No bundling or transpilation.
Installation
# npm
npm install pluvo
# pnpm
pnpm add pluvo
# yarn
yarn add pluvo
# bun
bun add pluvoGlobal CLI install (optional):
npm install -g pluvoQuick Start (JavaScript)
Template:
const template = `// @@@ if $.enabled
export const name = /* @@@ echo $.name */"default"/* @@@ endecho */;
// @@@ else
export const name = "fallback";
// @@@ endif
`;Code:
import { pluvo } from "pluvo";
const output = pluvo(template, { enabled: true, name: "variableName" });
console.log(output);Output:
export const name = "variableName";How It Works
- Templates are valid code. Directives appear in comments and are removed during render.
- The directive token is
@@@. - Expressions use JavaScript syntax and evaluate against a
$scope (e.g.$.foo).
Supported Directives
@@@ if <expr>
@@@ elseif <expr>
@@@ else
@@@ endif
@@@ each <item>[, <key>] of <expr>
@@@ endeach
@@@ echo <expr>
@@@ endecho
@@@ set <name> = <expr>
@@@ include <path>Expressions and Scope
- Expressions are JavaScript.
- Context is accessed via
$, e.g.$.user.name. eachbindsitemandkeyinto scope as$.itemand$.key.setwrites to the current scope.
Comment Handling
The engine searches for @@@ inside known comment styles and strips the wrapper.
If a directive is the only content on a line, the whole line is removed.
Default line markers:
//,#,--,;,%,!,REM,::,'
Default block markers:
/* ... */,<!-- ... -->,{- ... -},(* ... *)
You can extend these via commentStyles (see API.md).
Includes and Path Interpolation
include accepts a path, file, or glob. Use {...} to interpolate expressions:
// @@@ include "../path/{$.lang}/index.js"Paths are resolved relative to baseDir or the current file.
API Usage
See API.md for a full reference. Quick overview:
import pluvo, { renderTemplate, DEFAULT_COMMENT_STYLES } from "pluvo";
const output = pluvo("./templates/*.js", { foo: "bar" });Return value:
- String for a template string or a single file.
- Object map (
{ [filepath]: output }) for globs.
CLI Usage
See CLI.md for details. Quick overview:
pluvo ./templates/*.js --context '{"foo":"bar"}'
pluvo ./templates/*.js --context @context.jsonFor globs, the CLI prints headers like:
--- path/to/file.js ---
<rendered output>Additional Examples
Template:
# @@@ set banner = "# generated\n"
# @@@ echo $.banner
# @@@ endecho
def greet(name):
return f"Hello, {name}"
# @@@ each item, key of $.names
# @@@ echo "# name: " + $.item + "\n"
# @@@ endecho
# @@@ endeachCode:
const output = pluvo(template, { names: ["Ada", "Linus"] });Output:
# generated
def greet(name):
return f"Hello, {name}"
# name: Ada
# name: LinusTemplate:
<div class="app"></div>
<!-- @@@ if $.ready === true -->
<!-- @@@ echo '<span>ready</span>\n' -->
<!-- @@@ endecho -->
<!-- @@@ else -->
<!-- @@@ echo '<span>pending</span>\n' -->
<!-- @@@ endecho -->
<!-- @@@ endif -->Code:
const output = pluvo(template, { ready: true });Output:
<div class="app"></div>
<span>ready</span>Template:
SELECT id, email FROM users;
-- @@@ if $.includeWhere
-- @@@ echo "WHERE active = 1\n"
-- @@@ endecho
-- @@@ endif
ORDER BY id;Code:
const output = pluvo(template, { includeWhere: true });Output:
SELECT id, email FROM users;
WHERE active = 1
ORDER BY id;Template:
service:
name: api
# @@@ echo " replicas: " + $.replicas + "\n"
# @@@ endechoCode:
const output = pluvo(template, { replicas: 3 });Output:
service:
name: api
replicas: 3Security Notes
Expressions are evaluated with new Function. Only process templates and context data
from trusted sources.
Reference
- Full directive and parsing spec:
SPEC.md - API details:
API.md - CLI details:
CLI.md
License
See LICENSE.
