Files
claude-md-to-pdf/docs/superpowers/specs/2026-05-04-md-to-pdf-skill-design.md
2026-05-04 19:58:43 +02:00

5.2 KiB

md-to-pdf Skill — Design Spec

Date: 2026-05-04 Author: Jean-Luc Makiola Status: Approved (pending implementation)

Goal

Provide a globally available Claude Code skill that converts the user's working Markdown file to a PDF on demand, triggered by natural language ("exportier mal", "mach das als PDF", "regenerate the PDF") rather than a slash command. The skill is distributed as a Claude Code plugin via a self-hosted Gitea marketplace, so installing it once on each device makes it permanently available with auto-updates.

Non-Goals

  • Other output formats (DOCX, HTML, EPUB) — out of scope, kept open for later.
  • Watch mode or batch (--all) conversions — not part of the current workflow.
  • Multiple named style presets — a single sensible default plus per-project override is enough.
  • Slash command UX — explicitly excluded; the trigger is the skill description.

Distribution

The repository is published to Gitea (gitea.<user-domain>/jlmak/claude-md-to-pdf) using Claude Code's plugin marketplace format. On each device, the user runs once:

/plugin marketplace add https://gitea.<user-domain>/jlmak/claude-md-to-pdf
/plugin install md-to-pdf@claude-md-to-pdf

After that, Claude Code's plugin update mechanism handles new versions.

Repository Layout

claude-md-to-pdf/
├── .claude-plugin/
│   └── marketplace.json            # marketplace manifest, lists the md-to-pdf plugin
├── plugins/
│   └── md-to-pdf/
│       ├── .claude-plugin/
│       │   └── plugin.json         # plugin manifest (name, version, description)
│       └── skills/
│           └── md-to-pdf/
│               ├── SKILL.md        # trigger description + instructions
│               └── default.config.js  # bundled md-to-pdf style config
├── docs/
│   └── superpowers/specs/
│       └── 2026-05-04-md-to-pdf-skill-design.md   (this file)
├── README.md
└── LICENSE

The default.config.js is a verbatim copy of the user's proven A4 / small-table CSS currently used in the Databases project.

Skill Trigger

The SKILL.md description is written so Claude's skill-matcher activates on natural-language requests in either German or English. Examples that must trigger:

  • "exportier mal das PDF"
  • "mach mir daraus ein PDF"
  • "regenerate the PDF"
  • "PDF neu generieren"
  • "convert this markdown to pdf"

The description is explicit enough to not trigger on unrelated PDF requests (e.g. "open this PDF", "show me the lecture PDF").

Skill Behavior

When invoked, the skill follows this flow:

1. Identify the source .md

Order of resolution:

  1. A .md path explicitly mentioned in the user's most recent message.
  2. The .md file most recently read or written in the current session, if unambiguous.
  3. The single most-recently-modified .md file in the current working directory.
  4. If none of the above resolves to a single file, the skill asks the user which file to convert.

2. Resolve the config

  1. Walk upward from the source .md looking for .md-to-pdf.config.js. Use the first one found.
  2. Otherwise, fall back to the bundled default.config.js shipped with the skill (${CLAUDE_PLUGIN_ROOT}/skills/md-to-pdf/default.config.js).

3. Run the converter

npx --yes md-to-pdf <source.md> --config-file <resolved-config>

The output PDF is written next to the source (Loesung.mdLoesung.pdf), overwriting an existing file.

4. Confirm

Report back: PDF path, byte size, and which config was used (project vs. bundled default), so the user can tell at a glance which style applied.

Default Config

The bundled default.config.js mirrors the user's current setup — A4, 15mm/12mm margins, 5pt fixed-layout tables with no wrap, system sans-serif at 11pt. Optimized for German university homework with wide tables.

Project-local .md-to-pdf.config.js files always win, so the default is just a sensible fallback.

Error Handling

Boundaries where validation is needed:

  • npx / Node not available → surface a clear error pointing the user to install Node.
  • md-to-pdf package fetch fails → relay the npx error directly; don't retry silently.
  • Source .md ambiguous → ask the user to disambiguate (do not guess).
  • Config file syntactically broken → relay the error from md-to-pdf; don't try to "fix" the user's config.

Internal calls between skill steps trust each other; no defensive validation between them.

Testing Strategy

Manual smoke tests on first commit:

  1. Run skill in the existing Databases project — must regenerate Uebungen/03/Loesung.pdf and visually match the current output (same layout, fonts, table rendering).
  2. Run skill in a fresh directory with no .md-to-pdf.config.js — must produce a PDF using the bundled default.
  3. Run skill where the source .md is ambiguous — must ask, not guess.

No automated test suite for v1; the toolchain is a thin wrapper over npx md-to-pdf.

Open Questions

None blocking. Future considerations (not part of v1):

  • Should the bundled default eventually grow into multiple presets (homework / article / slides)?
  • Should the skill help bootstrap a project-local .md-to-pdf.config.js on request?