Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Converts long-form markdown (specs, RFCs, reports, plans, explainers) into a single-file, lightly-interactive HTML document with sticky TOC, scrollspy, search filter, code-copy buttons, and design-system-driven brand tokens. Triggers when the markdown-html-orchestrator classifies an input as DOCUMENT, or when invoked directly via /cs:md-document. Reads the design-system config via config_loader.py and inlines the user's 12 derived CSS custom properties; refuses to render if onboarding hasn't run
.claude/skills/itamarzand88-md-document/SKILL.md| Model | Eval pass | Runs |
|---|---|---|
| gemini-3.6-flash | 100% | 10 |
| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-03 | ✗→✓ | ▲ Improved | -54% | 0% |
| case-08 | ✗→✓ | ▲ Improved | -62% | 0% |
| case-02 | ✗→✓ | ▲ Improved | -50% | 0% |
| case-04 | ✗→✓ | ▲ Improved | -52% | 0% |
| case-05 | ✗→✓ | ▲ Improved | -26% | 0% |
<!-- source: md-document-html — https://raw.githubusercontent.com/alirezarezvani/claude-skills/main/markdown-html/skills/md-document/SKILL.md -->
The general-purpose converter — handles the 90% case Shihipar describes (specs, plans, RFCs, reports, explainers). Three stdlib tools pipeline together:
markdown_parser.py → html_renderer.py → interactivity_injector.py
(md → JSON AST) (AST + tokens → HTML) (HTML + JS behavior)Output is one .html file with sticky TOC, search filter, scrollspy, code-copy buttons, and the user's 12 derived brand tokens. Externals limited to Google Fonts CSS + Prism.js CDN.
| Symptom | Action | |---|---| | markdown-html-orchestrator routes input as DOCUMENT | Invoke this skill | | User runs /cs:md-document <path>.md directly | Invoke this skill | | User says "convert this spec/report/RFC/plan to HTML" | Invoke this skill | | Input is a code review (has diff blocks) | Route to md-review instead | | Input is a slide deck (clear --- boundaries) | Route to md-slides instead | | Input is < 100 lines | Refuse (Shihipar threshold — markdown still wins) | | Design-system not onboarded | Refuse, surface /cs:design-system |
bash# 1. Parse markdown → JSON AST python3 markdown-html/skills/md-document/scripts/markdown_parser.py \ --input <path>.md --output sections.json # 2. Render AST + design-system config → single-file HTML python3 markdown-html/skills/md-document/scripts/html_renderer.py \ --sections sections.json --output document.html # 3. Inject lightweight JS (search, copycode, smoothscroll, scrollspy) python3 markdown-html/skills/md-document/scripts/interactivity_injector.py \ --file document.html \ --features search,copycode,smoothscroll,scrollspy
Or all-in-one (sample render):
bashpython3 markdown-html/skills/md-document/scripts/html_renderer.py --sample \ | python3 markdown-html/skills/md-document/scripts/interactivity_injector.py \ --file /dev/stdin --output document.html
CommonMark subset sufficient for agent-generated artifacts:
code / links / !images python ) with Prism.js highlighting on demand> [!NOTE], > [!TIP], > [!IMPORTANT], > [!WARNING], > [!CAUTION])Out of scope: nested lists, HTML inlines, footnotes, definition lists, task list checkboxes (rendered as plain text), reference-style links.
config_loader.setup_completed() must return True. Otherwise surface /cs:design-system.fonts.googleapis.com and cdn.jsdelivr.net (Prism). Anything else is a regression.design_style=editorial produces 720px-wide layout with 1.75 line-height; playful rounds the callouts and adds shadow; technical is dense with 0.875rem code. Smoke-tested.prefers-color-scheme). Canon: WCAG 2.2 §1.4.3.<title> and is excluded from the TOC.md-review — that converter renders diff blocks + severity-tagged margin annotations. This one renders prose + tables + code + callouts.md-slides — that converter splits on --- boundaries into slides. This one renders one continuous document.marketing/landing/ — that generates landing pages from scratch (no markdown input). This converts existing markdown.{default_output_dir}/doc-{slug}.html (path resolved by orchestrator's output_path_resolver.py; collision suffix -2, -3, … by default).
references/ for full citations| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-03 | fail→pass | 27,762 | 6,919 | -75% | 1 | 1 | 0% | 6,194 | 2,862 | -54% | 0 | 0 | — |
case-08 | fail→pass | 23,555 | 4,246 | -82% | 1 | 1 | 0% | 6,171 | 2,369 | -62% | 0 | 0 | — |
case-01 | fail→fail | 26,815 | 8,265 | -69% | 1 | 1 | 0% | 6,136 | 2,638 | -57% | 0 | 0 | — |
case-02 | fail→pass | 27,333 | 7,999 | -71% | 1 | 1 | 0% | 6,176 | 3,068 | -50% | 0 | 0 | — |
case-04 | fail→pass | 23,011 | 4,604 | -80% | 1 | 1 | 0% | 4,886 | 2,345 | -52% | 0 | 0 | — |
case-05 | fail→pass | 13,765 | 3,704 | -73% | 1 | 1 | 0% | 3,033 | 2,254 | -26% | 0 | 0 | — |
case-06 | fail→pass | 15,824 | 4,762 | -70% | 1 | 1 | 0% | 3,298 | 2,491 | -24% | 0 | 0 | — |
case-07 | pass→pass | 24,053 | 4,344 | -82% | 1 | 1 | 0% | 6,148 | 2,315 | -62% | 0 | 0 | — |
case-09 | fail→pass | 7,932 | 3,589 | -55% | 1 | 1 | 0% | 1,648 | 2,312 | +40% | 0 | 0 | — |
case-10 | fail→pass | 10,573 | 2,888 | -73% | 1 | 1 | 0% | 2,174 | 2,175 | +0% | 0 | 0 | — |
case-11 | pass→pass | 9,361 | 3,875 | -59% | 1 | 1 | 0% | 1,729 | 2,415 | +40% | 0 | 0 | — |
case-12 | fail→pass | 10,598 | 3,938 | -63% | 1 | 1 | 0% | 2,072 | 2,417 | +17% | 0 | 0 | — |
case-13 | pass→pass | 6,858 | 2,073 | -70% | 1 | 1 | 0% | 1,460 | 1,995 | +37% | 0 | 0 | — |
case-14 | fail→pass | 10,271 | 4,608 | -55% | 1 | 1 | 0% | 2,023 | 2,437 | +20% | 0 | 0 | — |
case-15 | pass→pass | 7,165 | 1,875 | -74% | 1 | 1 | 0% | 1,593 | 1,887 | +18% | 0 | 0 | — |
case-16 | fail→pass | 18,420 | 2,010 | -89% | 1 | 1 | 0% | 1,236 | 1,998 | +62% | 0 | 0 | — |
case-17 | fail→pass | 6,736 | 1,584 | -76% | 1 | 1 | 0% | 1,223 | 1,828 | +49% | 0 | 0 | — |
case-18 | pass→pass | 7,366 | 1,811 | -75% | 1 | 1 | 0% | 1,609 | 1,834 | +14% | 0 | 0 | — |
case-19 | fail→pass | 3,465 | 2,169 | -37% | 1 | 1 | 0% | 706 | 2,003 | +184% | 0 | 0 | — |
case-20 | pass→pass | 9,775 | 6,244 | -36% | 1 | 1 | 0% | 2,038 | 2,817 | +38% | 0 | 0 | — |
case-21 | fail→pass | 8,814 | 4,990 | -43% | 1 | 1 | 0% | 1,811 | 2,635 | +45% | 0 | 0 | — |
case-22 | fail→pass | 9,219 | 3,537 | -62% | 1 | 1 | 0% | 1,823 | 2,379 | +30% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 22 cases were attempted, and 21 counted toward the lift figure. The other 1 produced results that are not comparable between the two arms, so they are excluded from the headline rather than averaged into it. The headline lift of +68 percentage points is the difference between those two pass rates over the 21 comparable cases.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
Other measured skills in the registry, with their headline benchmark lift.