pldf-template
v1.0.1
Published
Template processing engine for PLDF (Processable Legal Document Format) - handles Mako templating and Markdown rendering
Maintainers
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/% endifstatements - Loops: Support for
% for/% endforstatements - 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-templateUsage
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 MarkdownUsing 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
% endifSupports comparison operators:
% if user.age > 18:
You are an adult
% endif
% if status == 'active':
Account is active
% endifLoops
% for item in items:
- ${ item }
% endforComments
## This is a comment and won't be renderedAPI Reference
TemplateProcessor
Constructor
new TemplateProcessor(options)options(Object): Marked options for Markdown renderingbreaks(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${ }syntaxdata(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 withmetadataandquestionsanswers(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 definitionanswers(Object): User answerstemplatePath(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 contentfilePath(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 contentfilePath(String): Output file path/nameoptions(Object, optional): HTML generation optionstitle(String): Document title (default: 'Generated Document')
- Returns:
Promise<void>
Template Data Structure
When using prepareTemplateData(), the following variables are automatically added:
metadata: Interview metadata objectcurrent_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_variableStatus: 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
BlobandURL.createObjectURL()for file downloads - No Node.js-specific dependencies in core functionality
- Falls back to Node.js
fsmodule 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
