Export a markdown file to a self-contained HTML folder using Jinja templates. Creates an output folder with HTML, CSS, and image assets from the template. Supports metadata like title, author, client, date via YAML frontmatter or arguments. Triggers: "export to html", "render markdown", "convert to html", "make html", "export document", "render document", "html export".
Export markdown files to self-contained HTML folders with all assets included.
/export-to-html <markdown-file> [template] [options]
| Argument | Required | Default | Description |
|---|---|---|---|
markdown-file | Yes | - | Path to the source markdown file |
template | No | 2lines-external | Template directory name |
| Option | Description |
|---|---|
--title | Document title (overrides frontmatter) |
--subtitle| Document subtitle or one-line description |
--author | Author name (default: "John Carpenter, 2Lines Software") |
--client | Client name (for external docs) |
--date | Document date (default: today, e.g., "February 2026") |
--version | Document version (default: "1.0") |
--classification | Classification level (default: "Confidential") |
--output | Output folder path (default: same location as source, named after file) |
/export-to-html clients/Circuit/proposal.md
/export-to-html research/technical-spike.md --title "Technical Analysis" --client "Acme Corp"
/export-to-html pipeline/rfp-response.md 2lines-external --output exports/rfp
The skill creates a self-contained folder with all necessary assets:
<document-name>/
├── index.html # Rendered HTML document
├── style.css # Stylesheet from template
└── logo.svg # Logo and other images from template
Example: For clients/Circuit/proposal.md, output is:
clients/Circuit/proposal/
├── index.html
├── style.css
└── logo.svg
| Template | Directory | Purpose |
|---|---|---|
| 2lines-external | _templates/2lines-external/ | External documents (proposals, reports, deliverables) |
Each template directory contains:
_templates/<template-name>/
├── base.html # Main template with cover page, TOC, and body structure
├── style.css # Stylesheet (copied to output folder)
└── logo.svg # 2Lines logo (copied to output folder)
The 2lines-external template includes:
Extract the markdown file path, template name, and any metadata options from the user's request.
# Example parsing
markdown_file = "clients/Circuit/proposal.md"
template_name = "2lines-external" # default
options = {
"title": "Project Proposal",
"client": "Circuit",
"classification": "Confidential"
}
from pathlib import Path
# Read the source markdown
md_path = Path(markdown_file)
if not md_path.is_absolute():
md_path = Path("/Users/john/Documents/Workspace/2Lines/knowledge-base") / md_path
md_content = md_path.read_text()
If the markdown file has YAML frontmatter, extract metadata:
import re
frontmatter = {}
content = md_content
# Check for YAML frontmatter
if md_content.startswith('---'):
match = re.match(r'^---\n(.*?)\n---\n', md_content, re.DOTALL)
if match:
import yaml
frontmatter = yaml.safe_load(match.group(1)) or {}
content = md_content[match.end():]
import markdown
md = markdown.Markdown(extensions=[
'tables',
'fenced_code',
'codehilite',
'toc', # Generates md.toc with table of contents HTML
'meta',
])
html_content = md.convert(content)
# Extract table of contents (generated by toc extension)
toc_html = md.toc # Contains <div class="toc">...</div>
Merge frontmatter with command-line options (options take precedence):
from datetime import date
context = {
**frontmatter, # From YAML frontmatter
**options, # From command arguments
'content': html_content,
'toc': toc_html, # Table of contents
}
# Set defaults
if 'title' not in context:
context['title'] = md_path.stem.replace('-', ' ').title()
if 'date' not in context:
context['date'] = date.today().isoformat()
import shutil
# Determine output folder path
if 'output' in options:
output_dir = Path(options['output'])