markdown-to-html · git:20260811.72b7e8c · 2026-08-11 · sha256 45c4d0626ee7845a

markdown-to-html git:20260811.72b7e8cB

Immutable. This exact content is served forever at /api/v1/blob/45c4d0626ee7845a.

---
name: markdown-to-html
description: Convert a Markdown file to a self-contained, styled HTML page (sticky header, sidebar nav, syntax-highlighted code, callout boxes, Mermaid diagrams, print-ready). Use when the user asks to render, convert, or export a `.md` file as a shareable HTML document -- not for slides, presentations, or pitch decks. Rendering is deterministic via `marked` + `highlight.js`; the agent only invokes the script.
metadata:
  boundaries: [filesystem_write]
---

# Markdown to HTML

A thin wrapper around `<skill-dir>/scripts/render.js`. The renderer parses Markdown
deterministically with `marked` + `highlight.js`, post-processes for
callouts and table wraps, builds a sidebar nav and print TOC from
heading IDs, and stamps everything into `scripts/template.html`.

## Output rendering

Key–value / one record — For a single record's fields, use an aligned key: value list, not a two-row table.

## Installed entry-point contract

Treat `<skill-dir>` as the installer-supplied directory containing this active
`SKILL.md`; never infer it from the current working directory, user input, an
environment variable, or a profile path. Replace `<skill-dir>` with that actual
validated directory before executing or relaying any command; never send the
placeholder to a runtime or user. Before every invocation of `render.js`:

1. Canonicalize `<skill-dir>`, its `scripts/` child, and the expected entry
   point, resolving symlinks. Require the entry point to be a regular file and
   its resolved path to remain beneath the canonical `scripts/` directory.
2. If the entry is missing, is not a regular file, encounters a symlink loop or
   resolution error, or escapes that directory, stop before launching Node.
   Report only `error: installed skill entry point is unavailable: <entry>`,
   substituting the basename. Do not expose an absolute, home, profile,
   environment, or protected path; do not relay raw runtime stderr; and do not
   offer credential, SSO-capture, token, scope, or dependency remediation.
3. Invoke with a discrete argument vector, for example
   `["node", "<skill-dir>/scripts/render.js", "..."]`, so spaces, both quote characters, `$()`, backticks, and
   variable-shaped text cannot be expanded by a shell. Keep the project root as
   the working directory so user content paths retain their documented meaning.
4. If only a shell string is available, use a single-quoted literal path on
   POSIX or PowerShell and refuse paths containing a single quote. On cmd.exe,
   use a double-quoted path and refuse paths containing `"`, `%`, or `!`.
   If the adapter cannot represent the path safely, refuse instead of invoking.

Interpret exit codes only after this preflight succeeds and the entry point
actually runs.

## Instructions

You are not the renderer. The script is. Invoke it and report the path.

### Step 1 — Verify dependencies

The renderer needs Node.js and the `marked` + `highlight.js` packages
(pinned in `package.json`). Use the actual `<skill-dir>` resolved during
preflight as npm's explicit prefix; do not substitute the current working
directory. Render that prefix with the same safe literal/refusal rules as the
entry point. The examples below show the POSIX/PowerShell single-quoted form;
refuse a path containing a single quote instead of relaying either command.
Check whether the packages are already installed:

```bash
npm --prefix '<skill-dir>' ls --depth=0 --silent marked highlight.js
```

- Exit 0 → dependencies present; go to Step 2.
- Non-zero → not installed yet. Confirm `npm` is available
  (`npm --version`); if it isn't, tell the user to install Node.js and
  stop. If it is, **ask the user before installing**, then run the
  one-time install and re-verify — don't assume it succeeded:

  ```bash
  npm --prefix '<skill-dir>' install
  npm --prefix '<skill-dir>' ls --depth=0 --silent marked highlight.js
  ```

(The install is one-time; subsequent runs are cached in `node_modules/`.)

> Note: if your installer drops this skill into a tracked directory, add the skill's `node_modules/` to your project's `.gitignore` to avoid committing installed dependency artifacts.

### Step 2 — Render

```bash
node '<skill-dir>/scripts/render.js' <input.md> [--output OUT.html] [--title T] [--subtitle S] [--theme NAME] [--no-mermaid]
```

| Flag | Meaning |
|---|---|
| `--output FILE` | Output path. Default: input with `.html` extension. |
| `--title TEXT` | Page title. Default: first H1, then filename. |
| `--subtitle TEXT` | Header subtitle (small grey text next to the title). |
| `--theme NAME` | `navy` (default), `green`, `teal`, `amber`, `rose`. |
| `--no-mermaid` | Skip the Mermaid CDN script (for sources with no diagrams). |

The script writes the HTML and prints three lines to stdout:

```
OUTPUT: /path/to/file.html
SECTIONS: <number of h2/h3 anchors built>
MERMAID: yes|no
```

Surface the output path to the user and the section/mermaid summary if
relevant.

### Step 3 — What the renderer handles automatically

- **Headings** get stable `id` attributes used by sidebar links and the
  print TOC. Don't rewrite the markdown's headings.
- **Code blocks** are syntax-highlighted via `highlight.js`. Fenced
  blocks tagged ` ```mermaid ` pass through as `<div class="mermaid">`
  for the runtime CDN renderer.
- **Tables** are wrapped in `<div class="table-wrap">` for horizontal
  scrolling on narrow viewports.
- **Callouts**: paragraphs that begin with `**Note:**`, `**Tip:**`,
  `**Warning:**`, `**Important:**`, or `**Stop:**` are wrapped in a
  styled callout box. Don't try to add HTML manually — the script
  detects the bold lead-in.
- **Print**: every output includes an `@media print` block that hides
  the sidebar, builds a single-page TOC, and preserves background
  colors. `Ctrl+P → Save as PDF` works out of the box.

### Don't

- Don't write your own HTML. The script is the renderer; if the output
  is wrong, fix the script (or the template).
- Don't pre-process the markdown by hand. The renderer expects raw
  Markdown including any `**Note:**` lead-ins.
- Don't pass `--theme` unless the user asked for a specific accent
  color. `navy` is the default for a reason.
- Don't suggest pasting the rendered HTML into chat. Open the output
  file in a browser.

### Edge cases

- **Missing dependencies**: `node '<skill-dir>/scripts/render.js'` exits 1 with an
  install hint. Follow Step 1 — install on consent, then re-verify;
  don't install bare.
- **No headings**: sidebar shows `(no sections)`. Output still works,
  the sidebar just stays empty.
- **Custom theme requested by name not in the list**: the script exits
  with the list of valid choices. Ask the user which to use; don't
  invent a sixth.
- **Source contains a Mermaid block but you want fully offline output**:
  pass `--no-mermaid` and the diagram will fall back to a plain `<pre>`.
- **Trust model**: the renderer assumes the input markdown is the user's
  own document. Marked's default behavior is to pass through raw HTML
  embedded in markdown (e.g., a `<script>` tag in a `.md` file lands in
  the output as-is). This is fine for documents you authored; do not
  use this skill to render markdown from untrusted sources without a
  separate sanitization step.