Skip to content

wintercounter/pluvo

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

4 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

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 pluvo

Global CLI install (optional):

npm install -g pluvo

Quick 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.
  • each binds item and key into scope as $.item and $.key.
  • set writes 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.json

For globs, the CLI prints headers like:

--- path/to/file.js ---
<rendered output>

Additional Examples

Python

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
# @@@ endeach

Code:

const output = pluvo(template, { names: ["Ada", "Linus"] });

Output:

# generated

def greet(name):
    return f"Hello, {name}"

# name: Ada
# name: Linus
HTML

Template:

<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>
SQL

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;
YAML

Template:

service:
  name: api
# @@@ echo "  replicas: " + $.replicas + "\n"
# @@@ endecho

Code:

const output = pluvo(template, { replicas: 3 });

Output:

service:
  name: api
  replicas: 3

Security 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.

About

Code generator using real source code as your template and magic comments for logic.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors