npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

pldf-template

v1.0.1

Published

Template processing engine for PLDF (Processable Legal Document Format) - handles Mako templating and Markdown rendering

Readme

pldf-template

Template processing engine for PLDF (Processable Legal Document Format). This package processes Docassemble-compatible Mako templates and renders Markdown to HTML for generating legal documents from structured data.

Browser-compatible - Works in both Node.js and browser environments.

Features

  • Mako Template Processing: Use Docassemble-compatible ${ } syntax for variable interpolation
  • Conditionals: Support for % if / % endif statements
  • Loops: Support for % for / % endfor statements
  • Markdown Rendering: Convert Markdown to HTML with GitHub Flavored Markdown support
  • Flexible Template Loading: Load templates from files, URLs, or inline strings
  • Document Generation: Generate documents from interview definitions and answers
  • Multiple Output Formats: Export as Markdown or HTML files
  • Browser & Node.js: Fully compatible with both environments

Installation

npm install pldf-template

Usage

Basic Template Processing

import { TemplateProcessor } from 'pldf-template';

const processor = new TemplateProcessor();

const template = `# Hello ${ name }

Welcome to **${ company }**!`;

const data = {
    name: 'John Doe',
    company: 'Acme Corp'
};

const result = processor.processTemplate(template, data);
console.log(result.markdown); // Rendered Mako template
console.log(result.html);     // HTML from Markdown

Using Conditionals

const template = `Hello, ${ user }.  This text is in **bold face**.

% if user.age_in_years() > 30:
You cannot be trusted!
% endif`;

const data = {
    user: 'Jane',
    user: {
        age_in_years: () => 35
    }
};

const result = processor.processTemplate(template, data);

Using Loops

const template = `# Team Members

% for member in team:
- **${ member.name }**: ${ member.role }
% endfor`;

const data = {
    team: [
        { name: 'Alice', role: 'Developer' },
        { name: 'Bob', role: 'Designer' }
    ]
};

const result = processor.processTemplate(template, data);

Working with PLDF Interview Definitions

import { TemplateProcessor } from 'pldf-template';

const processor = new TemplateProcessor();

const definition = {
    metadata: {
        title: 'Employment Contract'
    },
    questions: [
        { question: 'What is your name?', variable: 'employee_name' },
        { question: 'What is your position?', variable: 'position' }
    ]
};

const answers = {
    employee_name: 'Jane Smith',
    position: 'Senior Developer'
};

const template = `# ${ metadata.title }

**Employee:** ${ employee_name }
**Position:** ${ position }

Generated on ${ current_date }`;

const result = await processor.generateDocument(definition, answers, template);

Loading Templates from Files

const processor = new TemplateProcessor();

// In Node.js: Load from file path
const templateContent = await processor.loadTemplate('./templates/contract.md');

// In browser or Node.js: Load from URL
const templateFromUrl = await processor.loadTemplate('https://example.com/template.md');

const result = await processor.generateDocument(definition, answers, './templates/contract.md');

Saving Documents

const processor = new TemplateProcessor();
const result = processor.processTemplate(template, data);

// In browser: triggers download
// In Node.js: saves to file system
await processor.saveAsMarkdown(result.markdown, 'output.md');

await processor.saveAsHTML(result.html, 'output.html', {
    title: 'My Document'
});

Template Syntax

Variable Interpolation

Use Mako/Docassemble syntax with ${ }:

Hello, ${ user_name }!
Your email is ${ user.email }.

Conditionals

% if condition:
This will be shown if condition is true
% endif

Supports comparison operators:

% if user.age > 18:
You are an adult
% endif

% if status == 'active':
Account is active
% endif

Loops

% for item in items:
- ${ item }
% endfor

Comments

## This is a comment and won't be rendered

API Reference

TemplateProcessor

Constructor

new TemplateProcessor(options)
  • options (Object): Marked options for Markdown rendering
    • breaks (Boolean): Enable line breaks (default: true)
    • gfm (Boolean): Enable GitHub Flavored Markdown (default: true)

Methods

processTemplate(template, data)

Process a Mako template with data and convert to HTML.

  • template (String): Mako template string with ${ } syntax
  • data (Object): Data to render in template
  • Returns: { markdown: String, html: String }
async loadTemplate(templateSource)

Load template from file, URL, or use inline string.

  • templateSource (String): File path (Node.js), URL, or template string
  • Returns: Promise<String> - Template content
getDefaultTemplate()

Get the default PLDF template.

  • Returns: String - Default template with Mako syntax
prepareTemplateData(definition, answers)

Prepare data for template rendering from interview definition and answers.

  • definition (Object): Interview definition with metadata and questions
  • answers (Object): User answers keyed by variable names
  • Returns: Object - Prepared template data
async generateDocument(definition, answers, templatePath)

Generate complete document from definition and answers.

  • definition (Object): Interview definition
  • answers (Object): User answers
  • templatePath (String, optional): Path to template file or inline template
  • Returns: Promise<{ markdown: String, html: String }>
async saveAsMarkdown(content, filePath)

Save content as Markdown file (or download in browser).

  • content (String): Markdown content
  • filePath (String): Output file path/name
  • Returns: Promise<void>
async saveAsHTML(content, filePath, options)

Save content as HTML file with styling (or download in browser).

  • content (String): HTML content
  • filePath (String): Output file path/name
  • options (Object, optional): HTML generation options
    • title (String): Document title (default: 'Generated Document')
  • Returns: Promise<void>

Template Data Structure

When using prepareTemplateData(), the following variables are automatically added:

  • metadata: Interview metadata object
  • current_date: Current date (localized)
  • current_time: Current time (localized)
  • questions: Array of { question, answer } objects
  • All answer variables are included at the top level

Integration with Other PLDF Packages

This package is designed to work with:

  • pldf-parser (pldf-cli): Parse interview YAML files
  • pldf-interview-engine: Run interactive interviews (to be created)

Example workflow:

import { PLDFParser } from 'pldf-parser';
import { TemplateProcessor } from 'pldf-template';

const parser = new PLDFParser();
const definition = parser.parse(yamlContent);

const processor = new TemplateProcessor();
const result = await processor.generateDocument(
    definition,
    answers,
    './templates/contract.md'
);

await processor.saveAsHTML(result.html, 'contract.html');

Current Limitations & Future TODOs

Current Implementation

✅ Variable interpolation: ${ variable } ✅ Property access: ${ user.name } ✅ Simple method calls: ${ user.age_in_years() } ✅ Conditionals: % if / % endif with comparison operators ✅ Loops: % for / % endfor ✅ Comments: ## ✅ Browser and Node.js compatibility

TODO: Advanced Features

The following Docassemble features are not yet implemented but planned for future releases:

Custom Markup Tags (TODO)

Docassemble supports extensive custom markup tags for document formatting:

  • [PAGEBREAK], [PAGENUM], [SECTIONNUM]
  • [START_INDENTATION], [STOP_INDENTATION]
  • [BEGIN_TWOCOL]...[BREAK]...[END_TWOCOL]
  • [FLUSHLEFT], [FLUSHRIGHT], [CENTER], [BOLDCENTER]
  • [NOINDENT], [INDENTBY 1in]
  • [BORDER]
  • [SINGLESPACING], [DOUBLESPACING], [TRIPLESPACING]
  • [NBSP], [ENDASH], [EMDASH], [HYPHEN]
  • [BLANK], [BLANKFILL]
  • [NEWPAR], [SKIPLINE], [BR], [TAB]
  • [FILE filename.ext] for image embedding

Status: Not implemented. Will require custom markdown extensions or post-processing.

Pandoc Integration (TODO)

Docassemble uses Pandoc for converting Markdown to PDF/DOCX/RTF with metadata support:

metadata:
  SingleSpacing: True
  fontsize: 10pt
  HeaderLeft: Page [PAGENUM]

Status: Not implemented. Would require calling Pandoc as external process (Node.js) or using pandoc.js (browser).

Complex Python Expressions (TODO)

Full Python code evaluation in templates requires a Python interpreter.

Status: Basic JavaScript expression evaluation only. For complex Python code, would need Pyodide integration.

Template File References (TODO)

Docassemble supports:

content file: hello.md
content file:
  code: template_variable

Status: Partially supported. Can load template from path/URL, but not from YAML content file directive.

Browser Compatibility

The package is fully browser-compatible:

  • Uses native fetch() API for loading remote templates
  • Uses Blob and URL.createObjectURL() for file downloads
  • No Node.js-specific dependencies in core functionality
  • Falls back to Node.js fs module when in Node environment

License

MIT

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

Priority areas for contribution:

  • Custom markup tag support
  • Pandoc integration
  • Enhanced Python expression evaluation
  • Additional test coverage

Repository

https://github.com/step21/pldf-template