Skip to content

step21/pldf-template

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

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

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published