Home
cd ../playbooks
Data & ReportingIntermediate

GEO Report PDF Renderer

Render a GEO audit markdown file into a styled client-ready PDF with a cover page, color-coded score tables, and severity callouts

10 minutes
By Zubair TrabzadaSource
#geo#pdf#reporting#client-deliverable

A markdown audit is a file. A PDF with a navy cover page and a color-coded score badge is a deliverable you can charge for. This playbook converts one into the other with pandoc and headless Chrome, no Python and no design work.

Who it's for: GEO and SEO agencies sending client deliverables, freelance consultants, marketing teams presenting to executives, anyone who needs an audit to look like a report

Example

"Turn GEO-AUDIT-REPORT.md into a PDF" → GEO-REPORT.pdf with a dark navy cover carrying the brand name, domain, and score badge, score cells shaded green through red by value, severity-tagged finding callouts, automatic section page breaks, and page-numbered footers

CLAUDE.md Template

New here? 3-minute setup guide → | Already set up? Copy the template below.

# GEO PDF Report Generator

Turn a finished GEO audit markdown file into a styled, client-ready PDF using pandoc plus headless Chrome. No Python, no ReportLab, no JSON wrangling.

## Prerequisites

- **pandoc** — `brew install pandoc` (macOS), `choco install pandoc` or `winget install JohnMacFarlane.Pandoc` (Windows), `apt install pandoc` (Debian/Ubuntu)
- **Google Chrome or Chromium** — used in headless mode to print HTML to PDF

Find the Chrome binary once and reuse the path:

| OS | Typical path |
|---|---|
| macOS | `/Applications/Google Chrome.app/Contents/MacOS/Google Chrome` |
| Windows | `C:\Program Files\Google\Chrome\Application\chrome.exe` |
| Linux | `google-chrome` or `chromium` on `PATH` |

## Input

A markdown audit report in the current folder, named `GEO-AUDIT-REPORT.md` by default. If no such file exists, stop and tell the user to produce the audit report first. Do not fabricate audit data to fill the PDF.

## Styling assets

The upstream geo-seo-claude suite ships a pandoc HTML template and stylesheet that produce the dark navy cover and score badge. Running as a standalone CLAUDE.md, you will not have those files. On the first run, generate them into a local `geo-pdf/` folder in the current directory:

- `geo-pdf/template.html` — a pandoc HTML5 template containing the cover section, the metadata variables listed below, and an inline `<script>` that post-processes the document before printing
- `geo-pdf/style.css` — typography, table styling, page footer, and `@page` rules

Reuse those files on later runs instead of regenerating them.

## Workflow

### Step 1: Check for the audit report

Look for `GEO-AUDIT-REPORT.md` in the current directory. If absent, stop.

### Step 2: Extract cover metadata

Read the top of the report and pull these fields:

| Field | Where to find it |
|---|---|
| `brand_name` | First H1 title, after "GEO Audit Report:" |
| `domain` | Second bold line, e.g. `**Domain:** example.com` |
| `geo_score` | Line matching `## Overall GEO Score: XX / 100` |
| `score_label` | The word after the score on that same line, e.g. "Poor", "Fair", "Good" |
| `date` | `**Audit Date:**` line |
| `business_type` | `**Business Type:**` line |
| `locations` | `**Locations:**` line |
| `platform` | `**CMS:**` line |

If a field is missing, omit its `--metadata` flag and let the template fall back to its default.

### Step 3: Run pandoc

```bash
pandoc GEO-AUDIT-REPORT.md \
  --to html5 \
  --standalone \
  --embed-resources \
  --template geo-pdf/template.html \
  --css geo-pdf/style.css \
  --metadata title="GEO Audit Report — <brand_name>" \
  --metadata brand_name="<brand_name>" \
  --metadata domain="<domain>" \
  --metadata geo_score="<geo_score>" \
  --metadata score_label="<score_label>" \
  --metadata date="<date>" \
  --metadata business_type="<business_type>" \
  --metadata locations="<locations>" \
  --metadata platform="<platform>" \
  -o GEO-REPORT.html
```

### Step 4: Print to PDF with headless Chrome

```bash
"<chrome-binary-path>" \
  --headless=new \
  --disable-gpu \
  --no-sandbox \
  --print-to-pdf="$(pwd)/GEO-REPORT.pdf" \
  --print-to-pdf-no-header \
  --no-pdf-header-footer \
  --virtual-time-budget=5000 \
  "file://$(pwd)/GEO-REPORT.html"
```

### Step 5: Report completion

Tell the user the PDF path, the file size, and how to open it.

## What the PDF Contains

- **Cover page** — dark navy gradient, brand name, domain, GEO score badge colored by score, audit date, business type, locations, CMS platform
- **Score tables** — cells containing `XX/100` are color-coded: 80 and up green, 65 and up blue, 50 and up amber, 35 and up orange, below 35 red
- **Finding sections** — H3 headings containing "Critical", "High", "Medium", or "Low" get severity-colored left-border callout blocks in red, orange, yellow, or green
- **Section page breaks** — major sections (High Priority, 90-Day Roadmap, Component Score Summary, Generated Schema) start on a new page
- **Code blocks** — JSON schema templates render with dark-theme monospace styling
- **Page footer** — brand name, "GEO Audit", date, and page numbers via CSS `@page`

## Customizing

- **Colors and typography** — edit `geo-pdf/style.css`
- **Cover layout** — edit `geo-pdf/template.html`
- **Score color thresholds** — edit the `scoreColor()` function in the template's `<script>` block
- **Which sections break to a new page** — edit the `breakBefore` array in the template's `<script>` block

## Troubleshooting

| Problem | Fix |
|---|---|
| `pandoc: command not found` | Install pandoc for your OS, then reopen the terminal |
| Chrome not found | Verify the binary path for your OS from the table above |
| PDF is blank or empty | Raise `--virtual-time-budget` to 8000 so the inline script finishes |
| Cover metadata missing | Check that the audit markdown uses the standard header format in Step 2 |
| Fonts not loading | The PDF renders offline and falls back to system fonts. Expected. |
| Score cells not colored | The color-coding runs in the template's inline script. Confirm the cell text matches the `XX/100` pattern. |
README.md

What This Does

Takes a finished GEO audit written in markdown and prints it to a styled PDF. Claude reads the cover metadata out of the report header, runs pandoc to build a self-contained HTML file, then drives headless Chrome to print that HTML to PDF.

Pairs with the GEO Client Report Generator, which produces the markdown this consumes.


Quick Start

Step 1: Create a Project Folder

mkdir -p ~/Documents/GEOReports

Step 2: Download the Template

Click Download above, then:

mv ~/Downloads/CLAUDE.md ~/Documents/GEOReports/

Step 3: Start Working

cd ~/Documents/GEOReports
claude

With your audit markdown in the folder, say "turn the audit report into a PDF."


Dependencies

Two external tools, both must be installed before the first run:

  • pandocbrew install pandoc, winget install JohnMacFarlane.Pandoc, or apt install pandoc
  • Google Chrome or Chromium — used headless to print the HTML to PDF

The playbook also needs an input file. It looks for GEO-AUDIT-REPORT.md in the current directory and stops if that file is absent rather than inventing audit data.

The upstream geo-seo-claude suite installs a pandoc HTML template and stylesheet under ~/.claude/skills/geo/templates/. Running this as a standalone CLAUDE.md, you will not have them, so the template instructs Claude to generate a local geo-pdf/template.html and geo-pdf/style.css on the first run and reuse them afterward.


What the PDF Contains

  • Cover page with a dark navy gradient, brand name, domain, GEO score badge colored by value, audit date, business type, locations, and CMS
  • Score cells shaded by threshold: 80 and up green, 65 and up blue, 50 and up amber, 35 and up orange, below 35 red
  • Severity callouts on findings, with left borders in red, orange, yellow, or green
  • Automatic page breaks before major sections
  • Dark-theme monospace styling for JSON schema blocks
  • Footer with brand name, date, and page numbers

Troubleshooting

Problem Fix
pandoc: command not found Install pandoc, then reopen the terminal
Chrome not found Check the binary path for your OS
PDF is blank Raise --virtual-time-budget to 8000 so the inline script finishes
Cover metadata missing The audit markdown needs the standard header format Claude parses
Fonts look wrong The PDF renders offline and falls back to system fonts. Expected.

$Related Playbooks