VERSION 2.0

The AI-Native PDF Language.

DARE is a high-fidelity, token-efficient markup language designed specifically for AI Agents to generate perfect PDF documents. It replaces the verbosity and unpredictability of HTML/CSS with a strict, minimalist, and deterministic system.

V2 ships with 16 built-in components, professional chart rendering, and a live web compiler.

Quick Start

The entire DARE Engine is a self-contained Node.js project. Get it running in under a minute.

1. Setup

# Clone the project repository
git clone https://github.com/local-over/dare-engine.git dare-engine
cd dare-engine

# Install dependencies (will download a headless Chrome instance)
npm install

2. Run Your First Compilation

Use the command-line tool to compile the example file.

node cli.js examples/ultimate.dare report.pdf

File Structure

A DARE file has two main blocks: @setup and @doc.

@setup {
  // Global settings like paper size & variables
  format: A4;
  $brand: color=#0ea5e9;
}

@doc {
  // Visual content, structured into pages
  page {
    txt($brand) { Hello World }
  }
}

Variables ($)

Variables are the key to DARE's efficiency. Define complex styles once in @setup and reuse them with a single token.

@setup {
  $card: bg=#1e293b border=1 rounded=5mm p=10mm;
}

@doc {
  page {
    box($card) { ... }
  }
}

Layout System

DARE's layout is powered by a simplified Flexbox and a physical unit system. This combination ensures layouts are both powerful and predictable.

Flexbox

Use display=flex on a box to arrange its children. Combine with justify and align for precise control.

box(display=flex, justify=space-between) {
  txt{Left}
  txt{Right}
}

The Fill Command

For perfect header/footer layouts, set one box to h=fill. The engine will automatically calculate and stretch this box to fill all remaining vertical space on the page.

page {
  box(h=25mm) { /* Header */ }
  box(h=fill) { /* Body */ }
  box(h=20mm) { /* Footer */ }
}

Primitives

The basic building blocks of any DARE document.

Primitive Description
page The root container for each page. Creates a hard boundary for content.
box The fundamental container for layout and styling (like a `div`).
txt The container for all text content.

Components

DARE provides built-in "smart" components for common document needs.

Component Description Example
img Embeds an image. Supports local and remote URLs. img(src="logo.png") {}
qr Generates a vector QR code from a data string. qr(data="url") {}
bar Renders a high-fidelity SVG bar chart. bar(data="A:10;B:20") {}
tbl Creates a grid-based table from CSV-like data. tbl{H1,H2; R1,R2}

✨ V2 Components

New in DARE v2 — professional components for complete document control.

Component Type Description Example
pie Void SVG pie/donut chart with legend. pie(data="A:40;B:60") {}
badge Leaf Pill-shaped status label. badge(bg=#22c55e) { LIVE }
list Leaf Auto-formatted bullet or numbered list. list { Item 1; Item 2 }
link Leaf Styled hyperlink with underline. link(href="url") { Click }
line Void Horizontal rule / divider. line(color=#e2e8f0) {}
sp Void Vertical spacer. sp(h=10) {}
cols Container Multi-column grid layout. cols(n=3, gap=5mm) { ... }
hdr Container Page header with flex layout. hdr(bg=#1e293b) { ... }
ftr Container Page footer, auto-sticks to bottom. ftr(bg=#f8fafc) { ... }

Component Types

Container — Children are recursively parsed (page, box, cols, hdr, ftr).
Leaf — Inner content is raw text (txt, tbl, badge, list, link).
Void — No meaningful children (img, qr, bar, pie, line, sp).

Tooling: CLI

Use the command line for local development and automated scripting. The tool is globally available in the project via `node cli.js`.

# Usage
node cli.js  

# Example
node cli.js examples/ultimate.dare report.pdf

Tooling: REST API

Start a production-ready API server for on-demand PDF generation from any application.

1. Start the Server

node server.js

2. Send a POST Request

Send your raw DARE code in the body of a POST request to /api/render.

curl -X POST http://localhost:3000/api/render \
     -H "Content-Type: text/plain" \
     --data-binary "@examples/ultimate.dare" \
     --output api_result.pdf

Tooling: Node.js Library

Integrate the DARE engine directly into your Node.js backend for maximum control.

const dare = require('./index.js');
const fs = require('fs');

async function generate() {
  const dareCode = '@doc{ page{ txt{Hello} } }';

  // convertString returns a PDF buffer
  const pdfBuffer = await dare.convertString(dareCode);
  fs.writeFileSync('from_lib.pdf', pdfBuffer);
}

🤖 For AI Agents: System Prompt

This is the master prompt to teach any LLM how to write perfect DARE code. Use it as the system prompt or at the beginning of your conversation.

TOOL: DARE v2 PDF Engine
PURPOSE: Token-efficient markup language for AI-generated PDF documents.

STRUCTURE:
@setup { format: A4; $var: props; }
@doc { page { ... } }

UNITS: mm for layout, pt for text size. Bare numbers auto-add mm.

VARIABLES: Define in @setup with $name, reuse anywhere. Composable.
  @setup { $blue: color=#0ea5e9; $title: size=24 bold $blue; }

PRIMITIVES:
  page { }           — Fixed page (A4/A5/Letter/Legal/A3)
  box(props) { }     — Container. h=fill stretches to fill remaining space
  txt(props) { text } — Text content

COMPONENTS:
  img(src="path") {}           — Image (local file or URL)
  tbl(cols="2fr 1fr") { H1,H2; R1,R2 }  — Grid table. ; = row, , = cell
  bar(data="A:10;B:20") {}     — Bar chart (SVG)
  pie(data="A:30;B:70") {}     — Pie chart. type=donut for donut
  qr(data="url") {}            — QR code
  list { Item 1; Item 2 }      — Bullet list. type=num for numbered
  hr {}                        — Horizontal divider
  line(color=#ccc, thick=2) {} — Custom divider
  sp(h=10) {}                  — Vertical spacer (10mm)
  badge(bg=#e0f2fe) { TEXT }   — Inline badge/pill
  link(href="url") { label }   — Clickable link
  cols(n=3, gap=5) { }         — Quick N-column grid
  hdr { }                      — Page header (flex, spaced)
  ftr { }                      — Page footer (flex, spaced)

CSS SHORTHANDS (saves 60%+ tokens vs HTML):
  w h bg p m mt mb ml mr mx my px py pt pb pl pr
  rounded/r border gap z opacity pos top bottom left right
  lh(line-height) ta(text-align) td(text-decoration) tt(text-transform)
  ls(letter-spacing) fw(font-weight) fs/size(font-size:pt) font/ff(font-family)
  minw minh maxw maxh shadow ow ox oy

FLAGS (boolean, no value needed):
  bold italic underline strikethrough uppercase lowercase capitalize
  center row col wrap nowrap hidden grid inline block
  between around evenly start end stretch relative absolute fixed nobreak

PATTERNS:
  Header+Body+Footer:
    page {
      box(h=25mm, bg=#111, row, center, px=10) { txt(bold, color=white){Title} }
      box(h=fill, p=15) { txt(size=12){Content} }
      box(h=10mm, row, between, px=10) { txt(size=8){Left} txt(size=8){Right} }
    }

  Two Columns:
    cols(n=2, gap=10) { box{...} box{...} }

  Card:
    box(bg=white, border=1, rounded=3, p=8, shadow="0 2px 8px rgba(0,0,0,0.1)") { }

RULES:
1. Always wrap content in @doc { page { } }
2. Use variables ($) for repeated styles — saves massive tokens
3. Use h=fill on the main content box
4. Use flags (bold, center, row) instead of verbose CSS
5. tbl uses ; for rows and , for columns — no nested tags
6. bar/pie data format: "Label:Value; Label:Value"

Author

DARE was designed and architected by Hassan Elkady as a robust, efficient solution for AI-driven document generation.