141 lines
7.5 KiB
Markdown
141 lines
7.5 KiB
Markdown
---
|
||
name: clouddrift-docx
|
||
description: Convert any Markdown file into a Cloud Drift branded .docx or .pdf using pandoc and a custom reference template (fonts, colors, logo, footer pagination pulled from Cloud Drift's brand guide and case-study docx). Use when the user asks to "export as a Cloud Drift branded doc/pdf", "convert this markdown to a Cloud Drift docx", "make this look like our case study", or wants a client-ready styled document from a markdown file.
|
||
---
|
||
|
||
# Cloud Drift branded docx/pdf export
|
||
|
||
## Purpose
|
||
|
||
Turn any Markdown file into a document that looks like it came from Cloud
|
||
Drift's own brand: Open Sans / Open Sans Light typography, the Fire
|
||
Opal / White Coffee / Raisin Black color system, the "Cloud Drift." logo in
|
||
a running header, and page-numbered footers. Output can be `.docx`,
|
||
`.pdf`, or both.
|
||
|
||
The brand spec was extracted directly from `tmp/Cloud_Drift_CI_v1b 2.pdf`
|
||
(the CI/brand guide) and cross-checked against the real embedded fonts/
|
||
colors/logo inside `tmp/Branded [case study] ... .docx` — this isn't a
|
||
guess at "corporate-looking" styling, it replicates the actual brand:
|
||
|
||
- **Font:** Open Sans Light (body, title, H1), Open Sans regular/bold (H2/H3, table headers)
|
||
- **Colors:** Fire Opal `#E45249` (primary/accent — title, H2, hyperlinks, blockquote bar), White Coffee `#E8DCD0` (table shading/borders), Raisin Black `#252525` (body text, H1)
|
||
- **Logo:** "Cloud Drift." wordmark, placed in the page header on every page
|
||
- **Layout:** A4, 1" margins, footer with "Page X of Y"
|
||
|
||
## How this fits together
|
||
|
||
1. `assets/clouddrift-reference.docx` — the pandoc reference-doc. Pandoc
|
||
clones this file's styles (Normal, Title, Heading 1-6, Block Text,
|
||
Hyperlink, Table), page setup, and header/footer (including the logo)
|
||
into whatever it generates. The Open Sans / Open Sans Light fonts are
|
||
embedded inside it (unobfuscated TTF parts, same scheme the original
|
||
Cloud Drift case-study docx uses), so Word will render it correctly even
|
||
on a machine that doesn't have the fonts installed.
|
||
2. `assets/fonts/*.ttf` — the same 8 font files, for reinstalling the fonts
|
||
locally if needed (see below).
|
||
3. `assets/clouddrift-logo.png` — the extracted logo, already baked into
|
||
the reference doc's header; kept here for reuse elsewhere if needed.
|
||
4. `scripts/convert.py` — the conversion driver (see usage below).
|
||
5. `scripts/build_reference.py` + `scripts/embed_fonts.py` — the one-time
|
||
scripts that built `clouddrift-reference.docx` from pandoc's own default
|
||
reference doc. Only needed again if the brand changes (new colors, new
|
||
logo, different heading scheme) — see "Regenerating the template" below.
|
||
|
||
## Usage
|
||
|
||
```bash
|
||
python3 .claude/skills/clouddrift-docx/scripts/convert.py INPUT.md --format docx
|
||
python3 .claude/skills/clouddrift-docx/scripts/convert.py INPUT.md --format pdf
|
||
python3 .claude/skills/clouddrift-docx/scripts/convert.py INPUT.md --format both --output outputs/documents/my-doc
|
||
```
|
||
|
||
- `--format` — `docx` (default), `pdf`, or `both`.
|
||
- `--output` — path without extension; defaults to the input's own path/name.
|
||
- `--reference-doc` — override the template (rarely needed).
|
||
|
||
The `.docx` step is pure pandoc (`pandoc INPUT.md -o OUTPUT.docx --reference-doc=...`).
|
||
PDF export works by asking macOS **Pages** to open that generated `.docx`
|
||
and export it to PDF — this guarantees the PDF is pixel-identical to the
|
||
branded docx rather than a second, independently-maintained template. This
|
||
means:
|
||
- **macOS only.** There's no PDF engine pandoc can drive directly in this
|
||
environment, so this is the practical path rather than building a
|
||
parallel LaTeX/CSS template.
|
||
- **First run may need a permission grant.** macOS will prompt to let the
|
||
automating process control Pages (System Settings → Privacy & Security →
|
||
Automation). Approve it once.
|
||
- **If invoked through Claude Code's Bash tool**, the PDF step needs
|
||
`dangerouslyDisableSandbox: true` — sandboxed Bash can't send Apple
|
||
Events to GUI apps like Pages. The docx-only step does not need this.
|
||
- If Pages returns "Connection is invalid" on the very first call, it
|
||
usually means Pages hadn't finished launching yet — retry once.
|
||
|
||
**Why not `pandoc --pdf-engine=...` directly?** Tried this on 2026-07-14 —
|
||
installed `tectonic` (a self-contained LaTeX engine) specifically so pandoc
|
||
could produce PDF natively. It failed: tectonic fetches its TeX resource
|
||
bundle from `relay.fullyjustified.net` on first use, and that domain
|
||
resolves to `0.0.0.0` on this network (a DNS-level filter, not something to
|
||
route around). General internet access otherwise works fine — it's specific
|
||
to that host. Asked the user how to proceed; they chose to keep the
|
||
Pages-based PDF path rather than switch to a bigger `BasicTeX` install or
|
||
allowlist the domain. `tectonic` was uninstalled again. If this is
|
||
revisited later, either option is viable — see git/workload history for
|
||
2026-07-14 for the tradeoffs discussed.
|
||
|
||
## Font install (one-time, already done as of 2026-07-14)
|
||
|
||
Open Sans / Open Sans Light aren't system fonts on macOS by default. They've
|
||
already been installed to `~/Library/Fonts/` from `assets/fonts/` so Pages/
|
||
Word render them correctly instead of falling back to a serif substitute.
|
||
If this is ever run on a different machine, install them first:
|
||
|
||
```bash
|
||
cp .claude/skills/clouddrift-docx/assets/fonts/*.ttf ~/Library/Fonts/
|
||
```
|
||
|
||
(Open Sans is SIL Open Font License — freely redistributable. These exact
|
||
files came from the Cloud Drift case-study docx in `tmp/`.)
|
||
|
||
## Regenerating the template
|
||
|
||
Only needed if the brand changes. From a scratch directory:
|
||
|
||
```bash
|
||
pandoc -o pandoc-default-reference.docx --print-default-data-file reference.docx
|
||
cp <skill>/assets/fonts/*.ttf ./fonts/
|
||
cp <skill>/assets/clouddrift-logo.png ./clouddrift-logo.png
|
||
python3 <skill>/scripts/build_reference.py # edit colors/fonts/sizes at the top first if rebranding
|
||
python3 <skill>/scripts/embed_fonts.py clouddrift-reference.docx
|
||
cp clouddrift-reference.docx <skill>/assets/clouddrift-reference.docx
|
||
```
|
||
|
||
Then sanity-check visually: convert a test markdown file and render page 1
|
||
with `qlmanage -t -s 1600 -o <dir> file.pdf` (no poppler/pdftoppm needed) —
|
||
or install `poppler` (`brew install poppler`) for `pdftoppm` to check
|
||
arbitrary pages of a multi-page doc, which is what caught the page-break
|
||
issue below.
|
||
|
||
## Known fixes
|
||
|
||
- **2026-07-14 — empty page before large tables.** Pandoc's default
|
||
reference doc sets `keepNext`/`keepLines` on every Heading style
|
||
(standard Word behavior: never strand a heading alone at the bottom of a
|
||
page). Under Pages specifically, this backfired when a heading was
|
||
immediately followed by a large table: the heading got stranded alone on
|
||
a page and the *entire* table got pushed to the next page, leaving a
|
||
near-empty page in between. `build_reference.py` now explicitly strips
|
||
`keepNext`/`keepLines` from Heading 1–9 (see `disable_keep_with_next`) so
|
||
pagination flows naturally — worst case a heading ends up as the last
|
||
line on a page, which is a far smaller cosmetic cost than a blank page.
|
||
If a similar gap ever reappears with some other block type, check the
|
||
relevant style's `pPr` for `keepNext`/`keepLines`/`pageBreakBefore` first.
|
||
|
||
## Known limitations
|
||
|
||
- Bullet markers use the default (black) bullet glyph, not the Fire-Opal-red
|
||
bullet dot seen in the case study — pandoc generates its own numbering
|
||
definitions per document rather than inheriting the reference doc's, so
|
||
this isn't controllable through the reference-doc mechanism alone.
|
||
- PDF export is macOS/Pages-only; there is no cross-platform fallback in
|
||
this environment.
|