# ai-pdf-builder

**🤖 AI-Powered Professional PDF Generation** — Create beautiful business documents with AI or from Markdown. Generate whitepapers, memos, agreements, and term sheets instantly. Perfect for AI agents, chatbots, and automation workflows.

> **New in v0.4:** AI document generation! Just describe what you need and let Claude create professional PDFs automatically.

---

## Works With

<p align="center">
  <img src="https://img.shields.io/badge/Claude-AI-orange?style=for-the-badge&logo=anthropic" alt="Claude AI" />
  <img src="https://img.shields.io/badge/GPT-OpenAI-412991?style=for-the-badge&logo=openai" alt="GPT" />
  <img src="https://img.shields.io/badge/Telegram-Bot-26A5E4?style=for-the-badge&logo=telegram" alt="Telegram" />
  <img src="https://img.shields.io/badge/WhatsApp-Bot-25D366?style=for-the-badge&logo=whatsapp" alt="WhatsApp" />
  <img src="https://img.shields.io/badge/Discord-Bot-5865F2?style=for-the-badge&logo=discord" alt="Discord" />
  <img src="https://img.shields.io/badge/Slack-Bot-4A154B?style=for-the-badge&logo=slack" alt="Slack" />
  <img src="https://img.shields.io/badge/Signal-Bot-3A76F0?style=for-the-badge&logo=signal" alt="Signal" />
  <img src="https://img.shields.io/badge/iMessage-Compatible-000000?style=for-the-badge&logo=apple" alt="iMessage" />
</p>

<p align="center">
  <strong>Built for:</strong> Clawdbot • Moltbot • LangChain • AutoGPT • Custom AI Agents
</p>

---

## Perfect For

- **🤖 AI Agents & Chatbots** — Generate documents on-the-fly from conversational AI
- **⚖️ Legal Tech** — Automate NDA, contract, and agreement generation
- **💰 Fintech** — Create term sheets, SAFEs, and investment documents programmatically
- **🔄 Automation Workflows** — Integrate with n8n, Zapier, Make, or custom pipelines
- **📱 Messaging Bots** — Let users request documents via Telegram, WhatsApp, Discord, Slack, or Signal
- **🏢 Enterprise** — Bulk document generation with consistent branding

---

## Table of Contents

- [Works With](#works-with)
- [Perfect For](#perfect-for)
- [Features](#features)
- [🤖 AI Generation (NEW!)](#-ai-generation-new)
- [Prerequisites](#prerequisites)
- [Installation](#installation)
- [Quick Start](#quick-start)
- [Usage Examples](#usage-examples)
  - [Basic PDF Generation](#basic-pdf-generation)
  - [Generate a Business Memo](#generate-a-business-memo)
  - [Generate a Legal Agreement](#generate-a-legal-agreement)
  - [Generate a Term Sheet](#generate-a-term-sheet)
  - [Generate a Whitepaper](#generate-a-whitepaper)
  - [Custom Colors](#custom-colors)
  - [Save to File](#save-to-file)
  - [Custom Templates](#custom-templates)
  - [List Available Templates](#list-available-templates)
  - [Check System Requirements](#check-system-requirements)
- [Integration with Next.js](#integration-with-nextjs)
- [API Reference](#api-reference)
- [Built-in Templates](#built-in-templates)
- [Troubleshooting](#troubleshooting)
- [Error Handling](#error-handling)
- [TypeScript Best Practices](#typescript-best-practices)
- [Advanced Topics](#advanced-topics)
- [Production Deployment](#production-deployment)
- [FAQ](#faq)
- [Integrations](#integrations)
- [License](#license)
- [Contributing](#contributing)

## Features

- **🤖 AI Document Generation**: Describe what you need → get a professional PDF (powered by Claude)
- **Company-Aware AI**: Use `--company` to auto-include your company details in generated docs
- **Multiple Document Types**: Built-in templates for memos, agreements, term sheets, and whitepapers
- **Custom Styling**: Apply custom colors and branding to any template
- **TypeScript Support**: Full type definitions included
- **Flexible Output**: Get PDF as Buffer or save directly to file
- **Template System**: Use built-in templates or register your own
- **Security**: Built-in content sanitization for LaTeX safety

## 🤖 AI Generation (NEW!)

Generate professional documents by describing what you need. No Markdown required!

### Quick AI Examples

```bash
# Generate a business memo
npx ai-pdf-builder ai "Write a memo about Q1 2026 hiring plans" -o hiring-memo.pdf

# Generate with your company branding (reads from company.json)
npx ai-pdf-builder ai "Create an NDA for a potential partner" --company -o nda.pdf

# Generate a whitepaper
npx ai-pdf-builder ai "Write a technical whitepaper about AI in fintech" --template whitepaper -o whitepaper.pdf

# Generate a term sheet
npx ai-pdf-builder ai "Create a Series A term sheet for a $5M raise at $20M pre-money" --template termsheet -o termsheet.pdf
```

### The `--company` Flag

Create a `company.json` file in your project root with your company details:

```json
{
  "name": "Acme Corp",
  "legalName": "Acme Corporation Inc.",
  "address": "123 Main St, San Francisco, CA 94102",
  "website": "https://acme.com",
  "industry": "Enterprise Software",
  "description": "We build productivity tools for modern teams."
}
```

Then use `--company` to automatically inject these details:

```bash
# AI knows your company context
npx ai-pdf-builder ai "Write an investor update for Q4" --company -o q4-update.pdf
npx ai-pdf-builder ai "Create a partnership proposal" --company -o proposal.pdf
```

### AI CLI Options

| Flag | Description |
|------|-------------|
| `--company`, `-c` | Load company context from `company.json` |
| `--template`, `-t` | Use specific template (memo, agreement, termsheet, whitepaper) |
| `--output`, `-o` | Output file path |
| `--model` | Claude model to use (default: claude-sonnet-4-20250514) |
| `--verbose`, `-v` | Show AI generation progress |

### Programmatic AI Generation

```typescript
import { generateWithAI } from 'ai-pdf-builder';

// Simple AI generation
const result = await generateWithAI({
  prompt: "Write a professional memo about remote work policy changes",
  template: "memo",
  metadata: {
    title: "Remote Work Policy Update",
    author: "HR Department"
  }
});

// With company context
const result = await generateWithAI({
  prompt: "Create an advisor agreement",
  template: "agreement",
  companyContext: {
    name: "Acme Corp",
    legalName: "Acme Corporation Inc."
  }
});

if (result.success) {
  fs.writeFileSync('output.pdf', result.buffer);
}
```

### Requirements for AI Generation

- **Anthropic API Key**: Set `ANTHROPIC_API_KEY` environment variable
- Pandoc and LaTeX (same as regular PDF generation)

## Prerequisites

This package requires **Pandoc** and **LaTeX** to be installed on your system:

### macOS

```bash
# Install Pandoc
brew install pandoc

# Install BasicTeX (minimal LaTeX)
brew install --cask basictex

# After installing BasicTeX, install required packages
sudo tlmgr update --self
sudo tlmgr install collection-fontsrecommended fancyhdr titlesec enumitem xcolor booktabs longtable geometry hyperref setspace array multirow listings
```

### Ubuntu/Debian

```bash
# Install Pandoc and TeX Live
sudo apt-get update
sudo apt-get install -y pandoc texlive-latex-base texlive-latex-extra texlive-fonts-recommended
```

### Windows

1. Download and install [Pandoc](https://pandoc.org/installing.html)
2. Download and install [MiKTeX](https://miktex.org/download)

### Docker

For containerized environments, use a Pandoc/LaTeX image:

```dockerfile
FROM pandoc/latex:latest
```

## Installation

```bash
npm install ai-pdf-builder
```

Or with yarn:

```bash
yarn add ai-pdf-builder
```

### For AI Generation

Set your Anthropic API key:

```bash
export ANTHROPIC_API_KEY="your-api-key"
```

Or add to `.env`:

```
ANTHROPIC_API_KEY=your-api-key
```

## Quick Start

### AI Generation (Easiest!)

```bash
# One command to generate a professional PDF
npx ai-pdf-builder ai "Write a business proposal for a SaaS product" -o proposal.pdf
```

### From Markdown

```typescript
import { generatePDF } from 'ai-pdf-builder';
import * as fs from 'fs';

const result = await generatePDF({
  content: '# My Document\n\nThis is the content of my PDF.',
  metadata: {
    title: 'My First PDF',
    author: 'John Doe',
    date: 'January 2026'
  }
});

if (result.success && result.buffer) {
  fs.writeFileSync('output.pdf', result.buffer);
  console.log(`PDF generated! Size: ${result.fileSize} bytes`);
}
```

## Usage Examples

### AI-Generated Business Memo

```bash
# CLI - Instant memo generation
npx ai-pdf-builder ai "Write an executive memo about launching our new mobile app in Q2. Include timeline, resource needs, and risk factors." --template memo -o app-launch-memo.pdf

# With company context for branded output
npx ai-pdf-builder ai "Create a board update covering our Series A progress, key metrics, and next quarter goals" --company --template memo -o board-update.pdf
```

### AI-Generated Legal Documents

```bash
# NDA with your company details
npx ai-pdf-builder ai "Generate an NDA for sharing proprietary technology with a potential partner" --company -o tech-nda.pdf

# Advisor agreement
npx ai-pdf-builder ai "Create an advisor agreement offering 0.5% equity over 2 years with monthly vesting" --company --template agreement -o advisor-agreement.pdf
```

### Basic PDF Generation

```typescript
import { generatePDF } from 'ai-pdf-builder';

const result = await generatePDF({
  content: `
# Executive Summary

This document outlines our strategic initiatives for Q1 2026.

## Key Objectives

- Increase market share by 15%
- Launch new product line
- Expand to 3 new markets

## Timeline

Implementation begins February 1st, 2026.
  `,
  metadata: {
    title: 'Q1 Strategic Plan',
    subtitle: 'Confidential',
    author: 'Strategy Team',
    date: 'January 2026',
    version: 'v1.0'
  },
  toc: true,
  numberSections: true
});
```

### Generate a Business Memo

```typescript
import { generateMemo } from 'ai-pdf-builder';

const memo = await generateMemo(
  `
# Executive Summary

Key findings from our market analysis indicate strong growth potential.

## Recommendations

1. Accelerate product development
2. Increase marketing budget by 20%
3. Hire 5 additional engineers
  `,
  {
    title: 'Product Whitepaper',
    subtitle: 'Intelligence Infrastructure for Financial Markets',
    author: 'John Smith',
    date: 'January 2026'
  }
);
```

### Generate a Legal Agreement

```typescript
import { generateAgreement } from 'ai-pdf-builder';

const agreement = await generateAgreement(
  `
# Advisor Agreement

This Advisor Agreement is entered into as of the Effective Date.

## 1. Services

The Advisor agrees to provide strategic guidance and introductions to potential investors.

## 2. Compensation

In consideration of the Services, the Company shall pay the Advisor:

- 8% of cash raised through Advisor's introductions
- 0.25% equity per $250,000 raised, up to 1% maximum

## 3. Term

This Agreement shall remain in effect for 12 months from the Effective Date.
  `,
  {
    title: 'Capital Introduction Agreement',
    subtitle: 'Acme Corp',
    date: 'January 15, 2026'
  }
);
```

### Generate a Term Sheet

```typescript
import { generateTermsheet } from 'ai-pdf-builder';

const termsheet = await generateTermsheet(
  `
# Series Seed Term Sheet

## Investment Amount

$2,000,000 (Two Million Dollars)

## Pre-Money Valuation

$8,000,000

## Security Type

Series Seed Preferred Stock

## Investors

Lead Investor: TBD
  `,
  {
    title: 'Series Seed',
    company: 'Acme Corp',
    doctype: 'Term Sheet',
    date: 'January 2026'
  }
);
```

### Generate a Whitepaper

```typescript
import { generateWhitepaper } from 'ai-pdf-builder';

const whitepaper = await generateWhitepaper(
  `
# Abstract

This paper presents a novel approach to financial market intelligence.

# Introduction

Financial markets generate vast amounts of data...

# Technical Architecture

Our system consists of three main components...

# Conclusion

We have demonstrated a scalable solution for...
  `,
  {
    title: 'Product Whitepaper',
    subtitle: 'A Canonical Asset Resolution System',
    author: 'Research Team',
    version: 'v1.0',
    date: 'January 2026'
  }
);
```

### Custom Colors

```typescript
import { generatePDF } from 'ai-pdf-builder';

const result = await generatePDF({
  content: '# Branded Document\n\nWith custom colors!',
  metadata: { title: 'Custom Branded PDF' },
  customColors: {
    primary: '#3B82F6',    // Blue
    secondary: '#6B7280',  // Gray
    accent: '#111827'      // Dark
  }
});
```

### Save to File

```typescript
import { generatePDF } from 'ai-pdf-builder';

const result = await generatePDF({
  content: '# My Document',
  metadata: { title: 'Saved PDF' },
  outputPath: './output/my-document.pdf'
});

if (result.success) {
  console.log(`PDF saved to: ${result.path}`);
}
```

### Custom Templates

```typescript
import { generatePDF, registerTemplate } from 'ai-pdf-builder';

// Register a custom template
registerTemplate({
  name: 'company-branded',
  path: './templates/company.latex',
  description: 'Company branded template with logo',
  supportedDocTypes: ['memo', 'whitepaper', 'report']
});

// Use the custom template
const result = await generatePDF({
  content: '# Company Report',
  metadata: { title: 'Annual Report' },
  template: 'company-branded'
});
```

### List Available Templates

```typescript
import { listTemplates } from 'ai-pdf-builder';

const templates = listTemplates();
templates.forEach(t => {
  console.log(`${t.name}: ${t.description}`);
  console.log(`  Supports: ${t.supportedDocTypes.join(', ')}`);
});
```

### Check System Requirements

```typescript
import { checkSystem } from 'ai-pdf-builder';

const status = checkSystem();
if (status.ready) {
  console.log('System ready:', status.message);
} else {
  console.error('Missing dependencies:', status.message);
  if (!status.pandoc.available) {
    console.error('Pandoc:', status.pandoc.error);
  }
  if (!status.latex.available) {
    console.error('LaTeX:', status.latex.error);
  }
}
```

## Integration with Next.js

### API Route Example

```typescript
// app/api/generate-pdf/route.ts
import { generatePDF } from 'ai-pdf-builder';
import { NextResponse } from 'next/server';

export async function POST(request: Request) {
  const { content, title, type } = await request.json();
  
  const result = await generatePDF({
    content,
    metadata: { title },
    template: type === 'memo' ? 'memo' : 'default'
  });

  if (!result.success) {
    return NextResponse.json({ error: result.error }, { status: 500 });
  }

  return new NextResponse(result.buffer, {
    headers: {
      'Content-Type': 'application/pdf',
      'Content-Disposition': `attachment; filename="${title}.pdf"`
    }
  });
}
```

### Server Action Example

```typescript
// app/actions/pdf.ts
'use server';

import { generateMemo } from 'ai-pdf-builder';

export async function createMemo(content: string, title: string) {
  const result = await generateMemo(content, { title });
  
  if (!result.success) {
    throw new Error(result.error);
  }
  
  return result.buffer?.toString('base64');
}
```

## API Reference

### CLI Commands

#### `ai` - AI Document Generation

```bash
npx ai-pdf-builder ai <prompt> [options]
```

| Option | Alias | Description | Default |
|--------|-------|-------------|---------|
| `--output` | `-o` | Output file path | `output.pdf` |
| `--template` | `-t` | Template: memo, agreement, termsheet, whitepaper | Auto-detected |
| `--company` | `-c` | Load company context from `company.json` | `false` |
| `--model` | | Claude model | `claude-sonnet-4-20250514` |
| `--verbose` | `-v` | Show progress | `false` |

#### `generate` - Markdown to PDF

```bash
npx ai-pdf-builder generate <input.md> [options]
```

| Option | Alias | Description | Default |
|--------|-------|-------------|---------|
| `--output` | `-o` | Output file path | `<input>.pdf` |
| `--template` | `-t` | Template name | `default` |
| `--title` | | Document title | Filename |
| `--author` | | Document author | |
| `--toc` | | Include table of contents | `true` |

#### `check` - System Check

```bash
npx ai-pdf-builder check
```

Verifies Pandoc and LaTeX are properly installed.

### generatePDF(options: PDFOptions): Promise<PDFResult>

Main function to generate a PDF from Markdown content.

#### PDFOptions

| Property | Type | Required | Description |
|----------|------|----------|-------------|
| `content` | `string` | Yes | Markdown content to convert |
| `metadata` | `DocumentMetadata` | No | Document metadata (title, author, etc.) |
| `template` | `string` | No | Template name or path (default: 'default') |
| `customColors` | `ColorConfig` | No | Custom color configuration |
| `outputPath` | `string` | No | Save PDF to this path instead of returning buffer |
| `toc` | `boolean` | No | Include table of contents (default: true) |
| `tocDepth` | `number` | No | Depth of TOC (1-3, default: 2) |
| `numberSections` | `boolean` | No | Number sections (default: true) |
| `fontSize` | `number` | No | Font size in points (default: 11) |
| `margin` | `string` | No | Page margins (default: '1in') |
| `paperSize` | `'letter' \| 'a4'` | No | Paper size (default: 'letter') |
| `timeout` | `number` | No | Timeout in ms (default: 60000) |

#### PDFResult

| Property | Type | Description |
|----------|------|-------------|
| `success` | `boolean` | Whether generation succeeded |
| `buffer` | `Buffer` | Generated PDF (if outputPath not specified) |
| `path` | `string` | Path to saved PDF (if outputPath specified) |
| `error` | `string` | Error message if failed |
| `pageCount` | `number` | Estimated page count |
| `fileSize` | `number` | File size in bytes |
| `generationTime` | `number` | Generation time in ms |

### generateWithAI(options: AIGenerationOptions): Promise<PDFResult>

Generate a PDF using AI to create the content.

#### AIGenerationOptions

| Property | Type | Required | Description |
|----------|------|----------|-------------|
| `prompt` | `string` | Yes | Description of what document to generate |
| `template` | `string` | No | Template to use (auto-detected if not specified) |
| `metadata` | `DocumentMetadata` | No | Override document metadata |
| `companyContext` | `CompanyContext` | No | Company details for context |
| `model` | `string` | No | Claude model (default: claude-sonnet-4-20250514) |

#### Example

```typescript
import { generateWithAI } from 'ai-pdf-builder';

const result = await generateWithAI({
  prompt: "Write an executive summary about our AI product launch",
  template: "memo",
  companyContext: {
    name: "TechCorp",
    industry: "AI/ML Software"
  }
});
```

### Preset Functions

All preset functions have the signature:

```typescript
function preset(
  content: string,
  metadata: DocumentMetadata,
  options?: Partial<PDFOptions>
): Promise<PDFResult>
```

Available presets:
- `generateMemo` - Business memos
- `generateAgreement` - Legal agreements
- `generateTermsheet` - Investment term sheets
- `generateWhitepaper` - Technical whitepapers
- `generateReport` - Business reports
- `generateProposal` - Proposals
- `generateCapitalIntroAgreement` - Fundraising agreements
- `generateSAFE` - SAFE documents
- `generateNDA` - Non-disclosure agreements

### Template Functions

- `getTemplate(name: string): string | null` - Get template content
- `listTemplates(): TemplateConfig[]` - List all templates
- `registerTemplate(config: TemplateConfig): void` - Register custom template
- `hasTemplate(name: string): boolean` - Check if template exists

### Utility Functions

- `checkSystem(): SystemCheck` - Check Pandoc/LaTeX availability
- `checkPandoc(): PandocCheck` - Check Pandoc installation
- `checkLaTeX(): LaTeXCheck` - Check LaTeX installation
- `sanitizeContent(content: string): string` - Sanitize for LaTeX safety

## Built-in Templates

| Template | Description | Best For |
|----------|-------------|----------|
| `default` | Clean, professional styling | Whitepapers, reports |
| `memo` | Compact business memo | Executive summaries |
| `agreement` | Formal legal document | Contracts, agreements |
| `termsheet` | Premium dark + gold finance | Term sheets, investment docs |

## Troubleshooting

### "Pandoc not found"

Install Pandoc:
- macOS: `brew install pandoc`
- Ubuntu: `sudo apt-get install pandoc`
- Windows: Download from [pandoc.org](https://pandoc.org)

### "pdflatex not found"

Install LaTeX:
- macOS: `brew install --cask basictex`
- Ubuntu: `sudo apt-get install texlive-latex-base texlive-latex-extra`
- Windows: Install [MiKTeX](https://miktex.org)

### Missing LaTeX packages

```bash
sudo tlmgr install <package-name>
```

Common packages needed:
```bash
sudo tlmgr install fancyhdr titlesec enumitem xcolor booktabs longtable geometry hyperref
```

### Timeout errors

Increase the timeout for large documents:

```typescript
const result = await generatePDF({
  content: longContent,
  timeout: 120000 // 2 minutes
});
```

## Error Handling

Proper error handling is crucial for production applications.

### Basic Error Handling

```typescript
import { generatePDF } from 'ai-pdf-builder';

try {
  const result = await generatePDF({
    content: markdownContent,
    metadata: { title: 'My Document' }
  });
  
  if (!result.success) {
    console.error('PDF generation failed:', result.error);
    
    // Handle specific errors
    if (result.error?.includes('Pandoc')) {
      console.error('Pandoc is not installed. Please install it first.');
      // Guide user to installation instructions
    } else if (result.error?.includes('pdflatex')) {
      console.error('LaTeX is not installed. Please install TeX Live or MiKTeX.');
    } else if (result.error?.includes('timeout')) {
      console.error('Generation timed out. Try increasing the timeout option.');
    }
    
    return;
  }
  
  // Success - use result.buffer or result.path
  console.log(`PDF generated successfully: ${result.fileSize} bytes`);
  
} catch (error) {
  console.error('Unexpected error:', error);
  // Handle system-level errors
}
```

### Retry Logic

```typescript
async function generateWithRetry(
  options: PDFOptions, 
  maxRetries: number = 3
): Promise<PDFResult> {
  for (let attempt = 1; attempt <= maxRetries; attempt++) {
    const result = await generatePDF(options);
    
    if (result.success) {
      return result;
    }
    
    console.warn(`Attempt ${attempt}/${maxRetries} failed:`, result.error);
    
    // Wait before retry (exponential backoff)
    if (attempt < maxRetries) {
      await new Promise(resolve => setTimeout(resolve, 1000 * attempt));
    }
  }
  
  throw new Error(`PDF generation failed after ${maxRetries} attempts`);
}
```

### Error Handling in Express

```typescript
app.post('/api/pdf', async (req, res) => {
  try {
    const { content, title } = req.body;
    
    const result = await generatePDF({
      content,
      metadata: { title },
      timeout: 30000
    });
    
    if (!result.success) {
      return res.status(500).json({ 
        error: 'PDF generation failed',
        details: result.error 
      });
    }
    
    res.setHeader('Content-Type', 'application/pdf');
    res.setHeader('Content-Disposition', `attachment; filename="${title}.pdf"`);
    res.send(result.buffer);
    
  } catch (error) {
    console.error('PDF generation error:', error);
    res.status(500).json({ error: 'Internal server error' });
  }
});
```

## TypeScript Best Practices

Get the most out of TypeScript's type system for safer code.

### Fully Typed Configuration

```typescript
import { 
  generatePDF, 
  PDFOptions, 
  PDFResult, 
  DocumentMetadata,
  ColorConfig,
  TemplateConfig 
} from 'ai-pdf-builder';

// Type-safe metadata
const metadata: DocumentMetadata = {
  title: 'Annual Report',
  author: 'Jane Doe',
  date: new Date().toLocaleDateString('en-US'),
  version: 'v2.0',
  subtitle: 'Financial Year 2025'
};

// Type-safe color configuration
const colors: ColorConfig = {
  primary: '59,130,246',    // RGB format
  secondary: '107,114,128',
  accent: '17,24,39'
};

// Complete options with type checking
const options: PDFOptions = {
  content: markdownContent,
  metadata,
  customColors: colors,
  template: 'default',
  toc: true,
  tocDepth: 2,
  numberSections: true,
  fontSize: 11,
  margin: '1in',
  paperSize: 'letter',
  timeout: 60000
};

const result: PDFResult = await generatePDF(options);

// Type-safe result handling
if (result.success && result.buffer) {
  const size: number = result.fileSize || 0;
  const pages: number = result.pageCount || 0;
  console.log(`Generated ${pages} pages (${size} bytes)`);
}
```

### Custom Type Guards

```typescript
import { PDFResult } from 'ai-pdf-builder';

function isSuccessfulResult(result: PDFResult): result is PDFResult & { 
  success: true; 
  buffer: Buffer 
} {
  return result.success && !!result.buffer;
}

// Use the type guard
const result = await generatePDF(options);
if (isSuccessfulResult(result)) {
  // TypeScript knows result.buffer is defined here
  saveToFile(result.buffer);
}
```

### Extending Types

```typescript
import { DocumentMetadata } from 'ai-pdf-builder';

// Extend with custom metadata
interface CustomMetadata extends DocumentMetadata {
  department?: string;
  classification?: 'public' | 'internal' | 'confidential';
  reviewers?: string[];
}

const metadata: CustomMetadata = {
  title: 'Security Report',
  author: 'Security Team',
  date: '2026-01-22',
  department: 'IT Security',
  classification: 'confidential',
  reviewers: ['Alice', 'Bob']
};
```

## Advanced Topics

### Batch Processing

Generate multiple PDFs concurrently:

```typescript
import { generatePDF } from 'ai-pdf-builder';
import pLimit from 'p-limit';

async function generateBatch(documents: Array<{ content: string; title: string }>) {
  // Limit concurrent operations to avoid overwhelming the system
  const limit = pLimit(3);
  
  const tasks = documents.map(doc => 
    limit(() => generatePDF({
      content: doc.content,
      metadata: { title: doc.title }
    }))
  );
  
  const results = await Promise.all(tasks);
  
  // Process results
  const successful = results.filter(r => r.success);
  const failed = results.filter(r => !r.success);
  
  console.log(`Generated ${successful.length}/${results.length} PDFs`);
  return { successful, failed };
}
```

### Performance Optimization

Tips for large documents:

```typescript
// 1. Increase timeout for large documents
const result = await generatePDF({
  content: largeMarkdownContent,
  timeout: 180000 // 3 minutes
});

// 2. Disable TOC for faster generation
const result = await generatePDF({
  content,
  toc: false,  // Skip table of contents
  numberSections: false
});

// 3. Use simpler templates
const result = await generatePDF({
  content,
  template: 'default'  // Simpler than termsheet template
});

// 4. Process in chunks for very large documents
async function generateLargeDocument(sections: string[]) {
  const pdfs = await Promise.all(
    sections.map(section => generatePDF({
      content: section,
      toc: false
    }))
  );
  // Merge PDFs using a library like pdf-lib
}
```

### Memory Management

For high-volume operations:

```typescript
import { generatePDF } from 'ai-pdf-builder';

// Monitor memory usage
function logMemoryUsage() {
  const used = process.memoryUsage();
  console.log({
    rss: `${Math.round(used.rss / 1024 / 1024)}MB`,
    heapUsed: `${Math.round(used.heapUsed / 1024 / 1024)}MB`
  });
}

// Process in batches to avoid memory issues
async function processLargeQueue(queue: any[], batchSize = 10) {
  for (let i = 0; i < queue.length; i += batchSize) {
    const batch = queue.slice(i, i + batchSize);
    await Promise.all(batch.map(item => generatePDF(item)));
    
    // Allow garbage collection between batches
    await new Promise(resolve => setImmediate(resolve));
    logMemoryUsage();
  }
}
```

### Custom Template Creation

Create your own LaTeX templates:

```typescript
import { registerTemplate, generatePDF } from 'ai-pdf-builder';
import * as path from 'path';

// Register a custom template
registerTemplate({
  name: 'company-branded',
  path: path.join(__dirname, 'templates', 'company.latex'),
  description: 'Company branded template with logo',
  supportedDocTypes: ['memo', 'whitepaper', 'report']
});

// Use the custom template
const result = await generatePDF({
  content: markdownContent,
  template: 'company-branded',
  customColors: {
    primary: '0,102,204',  // Company blue
    secondary: '128,128,128'
  }
});
```

See [TEMPLATE_GUIDE.md](./TEMPLATE_GUIDE.md) for a complete guide to creating custom LaTeX templates.

## Production Deployment

### Docker Deployment

**Dockerfile:**

```dockerfile
FROM pandoc/latex:latest

# Install Node.js
RUN apk add --no-cache nodejs npm

# Set working directory
WORKDIR /app

# Copy package files
COPY package*.json ./
RUN npm ci --only=production

# Copy application
COPY . .

# Install required LaTeX packages
RUN tlmgr update --self && \
    tlmgr install \
    collection-fontsrecommended \
    fancyhdr \
    titlesec \
    enumitem \
    xcolor \
    booktabs \
    longtable \
    geometry \
    hyperref \
    setspace \
    array \
    multirow \
    listings

EXPOSE 3000

CMD ["node", "server.js"]
```

**docker-compose.yml:**

```yaml
version: '3.8'
services:
  pdf-generator:
    build: .
    ports:
      - "3000:3000"
    environment:
      - NODE_ENV=production
      - MAX_CONCURRENT_PDFS=3
    volumes:
      - pdf-cache:/app/cache
    mem_limit: 2g
    mem_reservation: 1g

volumes:
  pdf-cache:
```

### Next.js Production Configuration

```typescript
// next.config.js
module.exports = {
  experimental: {
    serverComponentsExternalPackages: ['ai-pdf-builder']
  },
  // Increase API route timeout for PDF generation
  api: {
    responseLimit: '8mb'
  }
};

// app/api/pdf/route.ts
import { generatePDF } from 'ai-pdf-builder';
import { NextResponse } from 'next/server';

export const maxDuration = 60; // 60 seconds timeout

export async function POST(request: Request) {
  const { content, title } = await request.json();
  
  const result = await generatePDF({
    content,
    metadata: { title },
    timeout: 50000 // Leave buffer before Next.js timeout
  });
  
  if (!result.success) {
    return NextResponse.json({ error: result.error }, { status: 500 });
  }
  
  return new NextResponse(result.buffer, {
    headers: {
      'Content-Type': 'application/pdf',
      'Content-Disposition': `attachment; filename="${title}.pdf"`,
      'Cache-Control': 'no-store'
    }
  });
}
```

### Serverless Considerations

**AWS Lambda:**

```typescript
// Lambda function with custom runtime
// NOTE: Lambda has a 512MB /tmp limit and 15min timeout
import { generatePDF } from 'ai-pdf-builder';

export const handler = async (event) => {
  // Use /tmp for working directory
  const result = await generatePDF({
    content: event.content,
    metadata: event.metadata,
    workDir: '/tmp/pdf-work',
    timeout: 840000 // 14 minutes (leave buffer)
  });
  
  if (result.success) {
    // Upload to S3 instead of returning (size limits)
    await uploadToS3(result.buffer, event.key);
    return { statusCode: 200, body: JSON.stringify({ url: s3Url }) };
  }
  
  return { statusCode: 500, body: JSON.stringify({ error: result.error }) };
};
```

**Note:** For serverless, consider using the container approach or a dedicated PDF generation service due to Pandoc/LaTeX size requirements.

### Error Monitoring

**Sentry Integration:**

```typescript
import * as Sentry from '@sentry/node';
import { generatePDF } from 'ai-pdf-builder';

Sentry.init({ dsn: process.env.SENTRY_DSN });

async function generateWithMonitoring(options) {
  const transaction = Sentry.startTransaction({
    op: 'pdf.generate',
    name: 'Generate PDF'
  });
  
  try {
    const result = await generatePDF(options);
    
    if (!result.success) {
      Sentry.captureMessage('PDF generation failed', {
        level: 'error',
        extra: { error: result.error, options }
      });
    }
    
    transaction.setStatus('ok');
    return result;
    
  } catch (error) {
    Sentry.captureException(error);
    transaction.setStatus('internal_error');
    throw error;
  } finally {
    transaction.finish();
  }
}
```

## FAQ

### How does AI generation work?

The `ai` command sends your prompt to Claude (Anthropic's AI), which generates professional Markdown content based on your description. This content is then converted to PDF using Pandoc and LaTeX.

**What makes it smart:**
- Automatically detects document type from your prompt
- Structures content appropriately (headers, sections, formatting)
- Uses professional language and business conventions
- With `--company`, includes your company details naturally

### What's the difference between AI and manual generation?

| Aspect | AI Generation | Manual (Markdown) |
|--------|--------------|-------------------|
| Input | Natural language prompt | Structured Markdown |
| Control | AI decides structure | You control everything |
| Speed | Fastest for drafts | Better for precise docs |
| Best for | First drafts, ideas, quick docs | Final versions, exact specs |

**Pro tip:** Use AI to generate a first draft, then export the Markdown for manual refinement.

### Why is my PDF generation slow?

PDF generation involves multiple steps (Markdown parsing, LaTeX compilation, font rendering). Typical generation times:
- Simple document (1-5 pages): 1-3 seconds
- Medium document (10-20 pages): 3-8 seconds  
- Large document (50+ pages): 10-30 seconds

**To improve performance:**
- Disable TOC if not needed (`toc: false`)
- Use simpler templates (`template: 'default'`)
- Process documents concurrently for batch operations
- Cache generated PDFs when possible

### Can I use this in a serverless environment?

Yes, but with caveats:
- **Docker-based serverless** (AWS Fargate, Cloud Run): ✅ Recommended
- **Traditional Lambda/Functions**: ⚠️ Challenging due to Pandoc/LaTeX dependencies (~300MB)

For traditional serverless, consider:
1. Using a custom Lambda layer with Pandoc/LaTeX
2. Calling a dedicated PDF generation service
3. Using AWS Lambda Container Images

### How do I debug LaTeX errors?

```typescript
// Enable detailed error logging
const result = await generatePDF({
  content: markdownContent,
  metadata: { title: 'Debug Test' }
});

if (!result.success) {
  console.error('Full error:', result.error);
  // LaTeX errors typically mention line numbers and commands
  // Example: "LaTeX Error: Environment Shaded undefined"
}
```

Common LaTeX errors:
- **"pdflatex not found"**: Install LaTeX (see Prerequisites)
- **"Unicode character not set up"**: Use ASCII alternatives or configure unicode support
- **"Environment undefined"**: Missing LaTeX package

### What Markdown features are supported?

Supported (via Pandoc):
- ✅ Headers (H1-H6)
- ✅ Lists (ordered, unordered, nested)
- ✅ Bold, italic, code
- ✅ Links and URLs
- ✅ Tables (simple and grid)
- ✅ Code blocks with syntax highlighting
- ✅ Blockquotes
- ✅ Horizontal rules
- ✅ Images (if file paths are accessible)

Limited support:
- ⚠️ HTML (basic tags only)
- ⚠️ Complex tables (may need LaTeX syntax)
- ⚠️ Emojis (depends on LaTeX font support)

Not supported:
- ❌ GitHub-flavored Markdown task lists
- ❌ Mermaid diagrams (consider rendering to image first)

### How do I add images to my PDFs?

```typescript
const content = `
# Document with Images

![Company Logo](./assets/logo.png)

Regular text here.

![Chart](./charts/quarterly-results.png){ width=80% }
`;

const result = await generatePDF({
  content,
  metadata: { title: 'Document with Images' }
});
```

**Requirements:**
- Image paths must be accessible from where the code runs
- Supported formats: PNG, JPG, PDF
- Use relative or absolute paths
- Control size with Pandoc syntax: `{ width=50% }` or `{ height=3in }`

### Can I generate PDFs from HTML?

Yes, convert HTML to Markdown first or use Pandoc's HTML input:

```typescript
import { generatePDF } from 'ai-pdf-builder';
import TurndownService from 'turndown';

// Convert HTML to Markdown
const turndown = new TurndownService();
const markdown = turndown.turndown(htmlContent);

const result = await generatePDF({
  content: markdown,
  metadata: { title: 'From HTML' }
});
```

### How do I handle concurrent requests?

Use a queue system to limit concurrent PDF generations:

```typescript
import Queue from 'bull';
import { generatePDF } from 'ai-pdf-builder';

const pdfQueue = new Queue('pdf-generation', process.env.REDIS_URL);

// Limit to 3 concurrent jobs
pdfQueue.process(3, async (job) => {
  return await generatePDF(job.data.options);
});

// Add jobs
app.post('/api/pdf', async (req, res) => {
  const job = await pdfQueue.add({ options: req.body });
  res.json({ jobId: job.id });
});
```

## Integrations

ai-pdf-builder is designed to work seamlessly with AI agents and automation platforms:

### AI Agent Frameworks

| Framework | Integration |
|-----------|-------------|
| **Clawdbot / Moltbot** | Native support — generate PDFs from chat commands |
| **LangChain** | Use as a tool in your agent chains |
| **AutoGPT** | Add as a plugin for document generation |
| **CrewAI** | Integrate as an agent capability |
| **Semantic Kernel** | Use via function calling |

### Messaging Platforms

Works with any bot framework that can execute Node.js:
- **Telegram** — `node-telegram-bot-api`, `telegraf`
- **WhatsApp** — `whatsapp-web.js`, `@whiskeysockets/baileys`
- **Discord** — `discord.js`
- **Slack** — `@slack/bolt`
- **Signal** — `signal-cli`

### Automation Tools

- **n8n** — Use the Execute Command or Code node
- **Zapier** — Via Code by Zapier or webhooks
- **Make (Integromat)** — HTTP module + hosted endpoint
- **Pipedream** — Native Node.js support

### Example: LangChain Tool

```typescript
import { Tool } from "langchain/tools";
import { generateWithAI } from "ai-pdf-builder";

const pdfTool = new Tool({
  name: "generate_pdf",
  description: "Generate a professional PDF document from a description",
  func: async (prompt: string) => {
    const result = await generateWithAI({ prompt });
    if (result.success) {
      // Save or return the PDF
      return `PDF generated: ${result.fileSize} bytes`;
    }
    return `Error: ${result.error}`;
  }
});
```

### Example: Telegram Bot

```typescript
import TelegramBot from 'node-telegram-bot-api';
import { generateWithAI } from 'ai-pdf-builder';

const bot = new TelegramBot(process.env.BOT_TOKEN, { polling: true });

bot.onText(/\/pdf (.+)/, async (msg, match) => {
  const chatId = msg.chat.id;
  const prompt = match[1];
  
  await bot.sendMessage(chatId, '📄 Generating your PDF...');
  
  const result = await generateWithAI({ prompt });
  
  if (result.success) {
    await bot.sendDocument(chatId, result.buffer, {
      filename: 'document.pdf'
    });
  }
});
```

## Author

Built by [@NextXFrontier](https://x.com/NextXFrontier) — Follow for AI tools, automation, and building in public.

## License

MIT

## Contributing

Contributions welcome! Please read our [CONTRIBUTING.md](./CONTRIBUTING.md) guidelines before submitting PRs.
