Skip to content

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

License

Notifications You must be signed in to change notification settings

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

No packages published