| .. | ||
| templates | ||
| convert | ||
| convert-diff | ||
| index.sh | ||
| README.md | ||
| zddc.conf | ||
ZDDC Pandoc Tools
A collection of tools for converting Markdown documents to HTML with a professional viewer interface, optimized for technical documentation and engineering documents.
Server-side conversion (zddc-server)
The shell scripts in this folder are standalone CLI/batch tools.
zddc-serverimplements its own on-demand conversion (Go packagezddc/internal/convert) and does not call these scripts. It does, however, reuse the sametemplates/(embedded at build time). See AGENTS.md → "Server-side document conversion" for the authoritative reference.
zddc-server can render any served .md on demand: requesting the sibling URL
<path>/foo.docx (or .html / .pdf) returns the converted bytes — no query
string. A real on-disk file of that name always wins; the virtual conversion
only fires when the requested file doesn't exist but foo.md does. The browse
app's markdown editor surfaces these as DOCX/HTML/PDF download links (auto-saving
a dirty buffer first so the output matches what's on screen).
Architecture. The Go code does the minimum — it execs pandoc and
chromium-browser directly. The sandbox and resource caps live in the runtime
image, where /usr/local/bin/{pandoc,chromium-browser} are wrapper scripts
that run the real binary inside a per-conversion bubblewrap sandbox
(--unshare-all, read-only binds, --tmpfs /tmp, --clearenv) under cgroup v2
memory/PID caps. I/O is via stdin/stdout plus a per-call scratch dir. There is no
container runtime and no image pulling at request time.
The PDF flow is two-stage: pandoc renders the markdown through the selected
templates/<doctype>.html to standalone HTML, then headless Chromium prints that
HTML to PDF — preserving the template's print-media CSS rather than going through
pandoc's LaTeX template.
Converted bytes are cached at <dir>/.zddc.d/converted/<base>.<ext> with mtime
synced to the source, so a fresh cache hit is a stat-and-serve with no exec.
A PUT/DELETE/MOVE on the source .md purges the sidecars. Per-project header
metadata (client/project/contractor/project_number) comes from the .zddc
convert: cascade; title/tracking_number/revision/status are derived from the
filename via zddc.ParseFilename.
Relevant flags (defaults in parens):
--convert-pandoc-binary(pandoc) /--convert-chromium-binary(chromium-browser;chromiumon Debian) — PATH-resolved name or absolute path--convert-scratch-dir($TMPDIR) — host scratch root for template + intermediates--convert-mem-mib(1024) — per-conversion memory cap (cgroupmemory.max)--convert-pids(256) — per-conversion PID cap (cgrouppids.max)--convert-timeout(60s) — per-conversion wall clock (Gocontext.WithTimeout)
If pandoc/chromium aren't on PATH (e.g. running zddc-server outside the runtime
image) the endpoint serves 503 with a Retry-After; the rest of the server keeps
working. Running against raw pandoc/chromium with no wrapper gives a working but
unsandboxed endpoint — fine for dev iteration.
Features
Document Conversion (convert)
- Batch processing: Convert multiple Markdown files at once
- Force overwrite:
-fflag to overwrite existing output files - Custom output directory:
-oflag to specify output location - Configuration-driven: Uses
zddc.conffor project-specific settings - Template integration: Automatically applies the viewer template
- Progress tracking: Real-time conversion status and summary
Professional templates (templates/)
Named doctype templates — report.html, letter.html, specification.html —
share _head.html / _doc.html / _scripts.html partials. A document selects one
with a template: field in its YAML front matter (default report), and turns on
legal-style heading numbering with numbering: true (default off). Both fields are
read by pandoc straight from the front matter. Server deployments additionally
resolve per-project/per-party overrides from .zddc.d/templates/<name>.html.
- Modern responsive design: Works on desktop, tablet, and mobile
- Table of Contents (TOC): Auto-generated sidebar navigation with smooth scrolling
- Print optimization: Professional formatting for PDF generation
- Page break controls for tables
- Repeating table headers
- Proper page numbering
- Clean print layout
- URL hash navigation: Shareable links to specific document sections
- Mobile-friendly: Collapsible sidebar and touch-optimized interface
- Professional styling: Clean typography optimized for technical documents
Usage
Basic Conversion
# Convert all Markdown files in current directory
./convert *.md
# Convert with force overwrite
./convert -f *.md
# Convert to specific output directory
./convert -o rendered/ *.md
# Combine flags
./convert -f -o rendered/ *.md
Configuration (zddc.conf)
Create a zddc.conf file in your project directory. It is sourced as shell,
so use var="value" syntax (no spaces around =). Only these four variables are
read; all are optional and feed the document header via pandoc --variable:
contractor="Contractor Name" # contracting organization (header)
client="Client Name" # client org (header, paired with project)
project="Project Name" # full project name
project_number="AR 28088" # shown in parentheses after the project name
The template path is discovered automatically (input dir → script dir →
symlink target) or set per-run with -T; the output directory is set with -o.
They are not zddc.conf keys.
Directory Structure
your-project/
├── zddc.conf # Configuration file
├── document1.md # Source Markdown files
├── document2.md
└── rendered/ # Generated HTML files
├── document1.html
└── document2.html
Template Features
Navigation
- TOC Generation: Automatically creates navigation from document headings
- Smooth Scrolling: Click TOC items for smooth navigation to sections
- Hash URLs: Address bar updates with section anchors for sharing
- Mobile Menu: Collapsible sidebar for mobile devices
Print Styling
- Page Breaks: Tables won't split across pages
- Header Repetition: Table headers repeat on each page
- Professional Layout: Optimized margins and typography
- Page Numbers: Sequential page numbering in footer
Responsive Design
- Desktop: Full sidebar with TOC always visible
- Tablet: Collapsible sidebar with overlay
- Mobile: Hamburger menu with full-screen TOC overlay
File Types Supported
- Input: Markdown (
.md), DOCX (.docx), and HTML (.html/.htm) files (auto-detected: DOCX→MD, MD→HTML, HTML→MD; override with-t md|html|docx). Direct DOCX→HTML is not supported — convert to MD first. - Output: HTML files with embedded CSS and JavaScript (plus MD and DOCX targets)
- Images: Supports embedded images and diagrams
- Tables: Full table support with print optimization
- Code: Syntax highlighting for code blocks
Dependencies
- pandoc: Document conversion engine
- Modern browser: For viewing generated HTML files
- Optional: Web server for serving files (prevents CORS issues)
Troubleshooting
Common Issues
- Template not found: Keep the
templates/directory beside the script (or input), or pass-T /path/to/template.html - Permission errors: Make sure
convertscript is executable (chmod +x convert) - Missing output: Check that output directory exists or use
-oto create it - Print issues: Use "Print to PDF" in browser for best results