Awesome Search — Draft to HTML
Turns one hand-written draft in drafts/ into a single standalone HTML file
that can be pasted into an email, attached, or opened in a browser.
This is a published artifact, not a vault note — like kg-readme-writer's
README.md and kg-mail-list's digests. Vault conventions (approval, History
entries, kg-reviewer, wikilink resolution) do not apply, and the output is
written outside obsidian/vault/.
When to use
/kg-draft-to-html [<draft path or name>]
- "make an HTML version of this draft", "render the draft to HTML",
"turn drafts/foo.md into HTML"
- No draft given → list the
.md files in drafts/ and ask which one.
Never guess, and never render all of them unasked.
Output
drafts/html/<stem>.html, where <stem> is the draft's filename without
.md (drafts/llm-judge-agreement-plain-talk.md →
drafts/html/llm-judge-agreement-plain-talk.html). Create drafts/html/
if missing.
- One file per draft. Re-running overwrites it — the draft is the only truth,
and the HTML is a derived file that is never hand-edited. If someone has
hand-edited the HTML, those edits are lost; say so before overwriting when
you have reason to suspect it.
The hard rule: convert, never rewrite
This skill is a renderer, not an editor. Every word, sentence, heading,
table row, list item and link in the draft comes out in the same order with
the same wording. Specifically, do not:
- summarise, tighten, expand or re-voice any passage;
- strip statistics, counts or numbers — unlike
kg-mail-list, whose no-stats
rule exists because it derives an email from History entries, this skill
reproduces a document the author already wrote;
- rewrite
[[wikilinks]] into site links, or resolve them at all — they stay
verbatim as plain text (the script reports any it finds so the author can
decide);
- reorder sections, drop a trailing section, add a preamble, or invent a
subtitle, dateline or byline the draft does not have;
- fix the draft's typos, grammar or facts. If something looks wrong, mention
it in your summary and leave the file alone — the fix belongs in the
Markdown, not in the HTML.
The only additions to the author's text are the fixed <head> (title +
inline CSS) and the fixed footer sign-off, both described below.
Procedure
Resolve which draft to render (argument, or ask). Accept a bare name
(llm-judge-agreement-plain-talk) as well as a path.
Run the renderer from the repo root:
python3 claude-skills/kg-draft-to-html/scripts/draft_to_html.py drafts/<name>.md
It is stdlib-only Python 3, no dependencies. -o <path> overrides the
default output location. Use the script rather than hand-writing the
HTML — hand conversion of a 300-line essay is where paraphrase and
dropped paragraphs creep in.
Read the script's report: output path, the <title> it picked, and any
[[wikilinks]] left verbatim.
Spot-check the output — that the last section of the draft is present,
that tables and blockquotes rendered as such, and that no &amp; or
stray < escaping artefacts appear.
Stage the file with git add drafts/html/<stem>.html (add-only — never
commit or push; that stays the user's call).
Report: which draft was rendered, where the HTML went, the page title, and
any wikilinks or unsupported constructs worth the author's attention.
Page shape
Same house style as mails/<year>.<week>.html — self-contained, minimal,
valid HTML with no external stylesheets, scripts, fonts or images, so it
renders correctly with no network access.
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title><the draft's first H1, markup stripped></title>
<style> /* Georgia, max-width 640px, inline */ </style>
</head>
<body>
<h1>...</h1> <!-- the draft's own H1, in place -->
... <!-- the draft's body, converted -->
<hr>
<p>Best,<br>Andrew</p>
</body>
</html>
- The
<title> is the draft's first level-1 heading with */`/_
stripped; if the draft has no H1, it falls back to Draft and the script
says so — that is a cue to add an H1 to the Markdown, not to invent one in
the HTML.
- The H1 stays where the author put it; there is no separate dateline unless
the draft itself has one as body text.
- The footer is fixed and always present, exactly
<hr> followed by
<p>Best,<br>Andrew</p> — a sign-off, never a place for counts, credits or
boilerplate.
What the renderer supports
Headings (h1–h6), paragraphs, --- horizontal rules, fenced code blocks
(with a language-* class), blockquotes, bullet and ordered lists including
nesting, and pipe tables with the :---: alignment row. Inline: **strong**,
*em*/_em_, `code`, [text](url). YAML frontmatter is stripped.
Everything is HTML-escaped exactly once, so &, < and > in prose and in
URLs survive intact.
Known gaps: reference-style links, footnotes, inline HTML and images all
come through as literal text, and a setext heading's ===/--- underline
becomes a horizontal rule with the heading text left as a paragraph — so use
#-style headings in drafts. The drafts don't currently use them; if a
draft starts to, extend draft_to_html.py rather than hand-patching its
output.
1---2name: kg-draft-to-html3description: Render a long-form draft from drafts/*.md into a self-contained HTML page at drafts/html/<stem>.html, in the same house style as the mailing-list digests (Georgia, 640px, inline CSS, "Best, Andrew" sign-off). A faithful format conversion only — the draft's words, order and structure are never edited, summarised or rewritten. Triggers on `/kg-draft-to-html [<draft>]` or "make an HTML version of this draft" / "render the draft to HTML".4---56# Awesome Search — Draft to HTML78Turns one hand-written draft in `drafts/` into a single standalone HTML file9that can be pasted into an email, attached, or opened in a browser.1011This is a **published artifact, not a vault note** — like `kg-readme-writer`'s12README.md and `kg-mail-list`'s digests. Vault conventions (approval, History13entries, `kg-reviewer`, wikilink resolution) do not apply, and the output is14written outside `obsidian/vault/`.1516## When to use1718- `/kg-draft-to-html [<draft path or name>]`19- "make an HTML version of this draft", "render the draft to HTML",20 "turn drafts/foo.md into HTML"21- No draft given → list the `.md` files in `drafts/` and ask which one.22 Never guess, and never render all of them unasked.2324## Output2526- `drafts/html/<stem>.html`, where `<stem>` is the draft's filename without27 `.md` (`drafts/llm-judge-agreement-plain-talk.md` →28 `drafts/html/llm-judge-agreement-plain-talk.html`). Create `drafts/html/`29 if missing.30- One file per draft. Re-running overwrites it — the draft is the only truth,31 and the HTML is a derived file that is never hand-edited. If someone has32 hand-edited the HTML, those edits are lost; say so before overwriting when33 you have reason to suspect it.3435## The hard rule: convert, never rewrite3637This skill is a **renderer, not an editor**. Every word, sentence, heading,38table row, list item and link in the draft comes out in the same order with39the same wording. Specifically, do not:4041- summarise, tighten, expand or re-voice any passage;42- strip statistics, counts or numbers — unlike `kg-mail-list`, whose no-stats43 rule exists because it *derives* an email from History entries, this skill44 reproduces a document the author already wrote;45- rewrite `[[wikilinks]]` into site links, or resolve them at all — they stay46 verbatim as plain text (the script reports any it finds so the author can47 decide);48- reorder sections, drop a trailing section, add a preamble, or invent a49 subtitle, dateline or byline the draft does not have;50- fix the draft's typos, grammar or facts. If something looks wrong, mention51 it in your summary and leave the file alone — the fix belongs in the52 Markdown, not in the HTML.5354The only additions to the author's text are the fixed `<head>` (title +55inline CSS) and the fixed footer sign-off, both described below.5657## Procedure58591. Resolve which draft to render (argument, or ask). Accept a bare name60 (`llm-judge-agreement-plain-talk`) as well as a path.612. Run the renderer from the repo root:6263 ```sh64 python3 claude-skills/kg-draft-to-html/scripts/draft_to_html.py drafts/<name>.md65 ```6667 It is stdlib-only Python 3, no dependencies. `-o <path>` overrides the68 default output location. **Use the script rather than hand-writing the69 HTML** — hand conversion of a 300-line essay is where paraphrase and70 dropped paragraphs creep in.713. Read the script's report: output path, the `<title>` it picked, and any72 `[[wikilinks]]` left verbatim.734. Spot-check the output — that the last section of the draft is present,74 that tables and blockquotes rendered as such, and that no `&amp;` or75 stray `<` escaping artefacts appear.765. Stage the file with `git add drafts/html/<stem>.html` (add-only — never77 commit or push; that stays the user's call).786. Report: which draft was rendered, where the HTML went, the page title, and79 any wikilinks or unsupported constructs worth the author's attention.8081## Page shape8283Same house style as `mails/<year>.<week>.html` — self-contained, minimal,84valid HTML with no external stylesheets, scripts, fonts or images, so it85renders correctly with no network access.8687```html88<!doctype html>89<html lang="en">90<head>91<meta charset="utf-8">92<title><the draft's first H1, markup stripped></title>93<style> /* Georgia, max-width 640px, inline */ </style>94</head>95<body>96<h1>...</h1> <!-- the draft's own H1, in place -->97... <!-- the draft's body, converted -->9899<hr>100<p>Best,<br>Andrew</p>101</body>102</html>103```104105- The `<title>` is the draft's first level-1 heading with `*`/`` ` ``/`_`106 stripped; if the draft has no H1, it falls back to `Draft` and the script107 says so — that is a cue to add an H1 to the Markdown, not to invent one in108 the HTML.109- The H1 stays where the author put it; there is no separate dateline unless110 the draft itself has one as body text.111- The footer is fixed and always present, exactly `<hr>` followed by112 `<p>Best,<br>Andrew</p>` — a sign-off, never a place for counts, credits or113 boilerplate.114115## What the renderer supports116117Headings (h1–h6), paragraphs, `---` horizontal rules, fenced code blocks118(with a `language-*` class), blockquotes, bullet and ordered lists including119nesting, and pipe tables with the `:---:` alignment row. Inline: `**strong**`,120`*em*`/`_em_`, `` `code` ``, `[text](url)`. YAML frontmatter is stripped.121Everything is HTML-escaped exactly once, so `&`, `<` and `>` in prose and in122URLs survive intact.123124Known gaps: reference-style links, footnotes, inline HTML and images all125come through as literal text, and a setext heading's `===`/`---` underline126becomes a horizontal rule with the heading text left as a paragraph — so use127`#`-style headings in drafts. The drafts don't currently use them; if a128draft starts to, extend `draft_to_html.py` rather than hand-patching its129output.