LLM に、このブログの Markdown で答えてもらう #

LLM に図を頼んで SVG が返ってきても、このブログではコードのまま見えることがある。中身が間違っているとは限らない。コードフェンスの言語が空だと、画像として描く経路に入らない。

このブログの tinymarkdown は小さな Markdown の処理系なので、「Markdown で答えて」だけでは、使える書き方が伝わらない。そこで、/preview にそのまま渡せる出力形式を伝えるプロンプトと、slops を書くエージェント向けの skill を用意した。

SVG は svg と書いたフェンスに入れる #

開始行は ```svg。両端の空白は入れず、バッククォートを三つ、その直後に小文字の svg を書く。次の行から <svg> の本体を置き、最後はバッククォート三つだけの行で閉じる。

図を埋め込みたいときは、この言語指定が必要になる。言語なしや xml、html、大文字の SVG では画像にならない。

次の図は、実際に svg フェンスで埋め込んでいる。

同じ SVG のソース svg フェンス 言語指定なし 図として表示 コードとして表示

一方、次は意図的に言語を指定していない。SVG ではあるが、ブログでは図にならず、ソースを表示するコードブロックになる。

<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 60">
  <circle cx="50" cy="30" r="20" fill="currentColor"/>
</svg>

この違いは、Go のビューとMoonBit のビューが、フェンスの言語名を svg と比較しているために生じる。SVG の内容を見て自動で画像だと判断しているわけではない。/preview でも同じ指定が要る。TypeScript 版のビューは現時点ではこの描画に追従していないので、全実装が同じだとは扱わない。

図の見栄えより、扱いやすさ #

今回は、四角、矢印、普通のテキストで図を作った。文字の大きさと配置は指定したが、フォントデータや外部フォントは使っていない。

PR #87の図には、生成された SVG に WOFF のデータと @font-face が入っている例がある。この書き方をブログの図の標準にする必要はない。図の意味が分かればよく、フォントまで持ち込んで揃えることは今回の目的に含めない。

SVG の直書きを使えるからといって、複雑な描画基盤を用意する必要もない。viewBox を付け、小さい画面でもラベルが読める程度に要素を減らす。インラインの線や文字は currentColor にすると、ページの明暗にも合わせやすい。

なお、SVG フェンスは中身をそのまま HTML に入れる。プレビューの記事にもあるように、サニタイズ済みの画像形式ではない。ここで使う図は、スクリプトやイベント属性、外部リソースを含まない単純なものにする。

preview 用の回答形式を、先に伝える #

01-preview-prompt.mdに、このブログで使える記法と出力形式を伝えるプロンプトを置いた。自分が使っている創作用プロンプトに、ファイルの原文を追加して併用する。創作の内容や方針は元のプロンプトで指定し、こちらは出力形式の指定として使う。回答された Markdown を /preview に貼るか、ファイルとして読み込ませる。

伝えるのは、単に「SVG を使って」だけではない。

  • 回答全体は一つの Markdown 文書にする。前置きの挨拶や、文書全体を包むコードフェンスは付けない。
  • 図を入れるときは、必ず小文字の svg を言語として指定する。図が要らない場合まで、無理に追加しない。
  • 見出し、箇条書き、表、コード、リンクといった、このブログで扱える記法を使う。
  • 画像記法、強調、番号付きリスト、Mermaid などを、普段の Markdown のつもりで使わない。
  • 図は読み取れる簡単なものにし、フォント埋め込みで飾らない。

プレビューで見て、使えない書き方があれば、出力を簡単にするか、処理系に機能を足したいかを考えればよい。この記事では、処理系の対応範囲を広げる変更はしていない。

複数ファイルでも、一つの記事になる #

もう一つ伝えておきたいのは、一つの記事を一枚のファイルにまとめなくてもよいことだ。この記事自身が、次の四ファイルからなるバンドルになっている。

slops/2026-10-27-writing-slops.md/
  README.md
  01-preview-prompt.md
  02-bundle-prompt.md
  03-svg-pitfalls.md

README.md を記事の顔として、その後に残りのファイルが名前順のセクションとして並ぶ。ここでは本文と、コピーして使う二つのプロンプト、あとから足した落とし穴のメモを分けた。ファイルを物理的に連結して保存するのではなく、ブログがページを組み立てるときに合わせて表示する。

README.md の front matter が記事全体のタイトルや説明を決める。ほかの Markdown は本文の補足、.svg ファイルなら画像、それ以外のテキストならコードとして表示され、各ファイルは個別にも取得できる。下位ディレクトリや PNG/JPEG のようなバイナリーファイルは、このバンドルでは扱えない。

02-bundle-prompt.mdは、その形でファイルを作れるエージェントに渡すための依頼文。本文とは別に補足や異なる説明を残したいときに使う。

preview で見た目を確認する #

/preview に Markdown を貼るか、ファイルを読み込んで、文章や図の見た目を確認できる。バンドル全体の並びは、ローカルのブログで確認する。

エージェント向けの詳しい手順は、write-slops の skillにまとめた。

その skill に沿って既存の記事の図を描き直したときに出てきた落とし穴は、03-svg-pitfalls.mdに残した。

01-preview-prompt.md #

preview 用の Markdown 出力形式 #

創作用プロンプトと併用する出力形式の指定です。創作の内容や方針は、そのプロンプトに従ってください。回答を html-sandbox の /preview に貼って表示するため、次の出力形式に従ってください。

  • 回答は記事の Markdown 本文だけにしてください。挨拶、形式の解説、回答全体を囲むコードブロックは不要です。
  • 最初に # の見出しでタイトルを書いてください。front matter は不要です。
  • 見出しは # から #####、箇条書きは - または * を使ってください。段落、引用、区切り行のある表、インラインコード、通常のリンク、バッククォート三つのコードブロックを使えます。
  • 強調、番号付きリスト、Markdown の画像記法、HTML の直書き、Mermaid には頼らないでください。このサイトは Markdown の小さなサブセットを扱います。
  • 図が説明に役立つ場合は、短い SVG を本文中に埋め込んでください。必ず開始行を ```svg とし、両端の空白を除いて、小文字の言語名 svg を付けてください。言語なし、xml、html、SVG のコードブロックでは画像になりません。
  • SVG は <svg xmlns="http://www.w3.org/2000/svg" viewBox="…"> から始まる完全な要素にし、終了タグの次の行をバッククォート三つだけにして閉じてください。SVG 自体を画像記法や別のコードブロックで包まないでください。
  • 図は矩形、線、短いテキストなどで簡潔に表現してください。通常のフォントに任せ、フォントデータの埋め込み、外部フォント、文字のパス化で見栄えを揃える処理はしないでください。文字サイズや配置の指定は必要な範囲で構いません。
  • インラインの図の線と文字には currentColor を使えます。スクリプト、イベント属性、foreignObject、外部リソースを含めないでください。
  • 外部の資料にリンクするなら https:// の URL を使ってください。

図を入れる場合の囲み方は次の通りです。これは記法の例です。

入力 結果

02-bundle-prompt.md #

slops の記事バンドルの作成依頼 #

html-sandbox の slops に、次のテーマで日本語の記事を作ってください。

  • テーマ: (ここに書く)
  • 日付: (記事の日付。指定しない場合は Asia/Tokyo の今日)
  • スラッグ: (小文字の英字・数字・ハイフンで書く)
  • 参照する材料と、本文の外に分けて残したい補足: (ここに書く)

まずリポジトリの AGENTS.md と .claude/skills/write-slops/SKILL.md を読んでください。

slops/YYYY-MM-DD-slug.md/ というディレクトリを一つの記事にしてください。README.md を記事の顔とし、補足や別の説明を必要に応じて 01-notes.md などに分けてください。複数のファイルを一つの Markdown ファイルに連結して保存しないでください。役割のないファイルは作らなくて構いません。

顔となる README.md にはタイトルを付けてください。front matter を使うなら title、description、prev、next 以外のキーは追加しないでください。残りのファイルは名前順で並ぶので、表示順が必要なら数字の接頭辞を付けてください。サブディレクトリやバイナリー画像は置かないでください。

SVG の図を本文へ入れる場合は、開始フェンスをバッククォート三つと小文字の svg にしてください。言語指定のないフェンスでは図がコードとして表示されます。SVG は簡単な図形とテキストで作り、フォントデータや外部フォントは持ち込まないでください。必要なら .svg を独立したメンバーとして置くこともできます。Markdown の画像記法は使わないでください。

相対リンクは、そのリンクを書くファイルの場所を基準にしてください。同じページ内の補足セクションへ飛ばしたいリンクと、メンバーの原文ファイルへのリンクを区別してください。

本文や図の見た目は /preview で確認できます。バンドル全体の並び、メンバーの取得、ファイル間のリンクは、ローカルのブログで確認してください。確認した範囲を報告してください。

03-svg-pitfalls.md #

skill に沿って図を作り直したときの落とし穴 #

posts の AI 小説の記事にある9枚の SVG を、write-slops の skill の「位置・大きさ・重なりに意味を持たせる」という方針で描き直した。そのときにつまずいたところを残す。

元の9枚は、どれも本文の要点を箱に入れて矢印でつないだ図だった。たとえば文字列の類似度の図は「類似度:極めて低い」「読者の認知:同じ場面」という2行を箱に入れただけで、本文を読めば済む。作り直しでは、各図の主張をひとつの視覚的な性質に結びつけた(作中の時間を縦の位置に、分量を帯の長さに、段落同士の似かたを行列の塗りに)。落とし穴はその先で出てきた。

位置の意味が軸と逆になる #

「再描写を削ると、直後の台詞が軽くなる」を、横軸を本文の位置、縦軸を読者に溜まる重みにした曲線で描いた。最初の版では、削った場合の台詞を元の台詞より右に置いていた。

削れば本文は短くなるので、台詞は手前に来るはずだ。縦の高さ(重みが低い)だけを見て置き場所を決め、横軸が何を表すかを忘れていた。描画した画像を見ても形としては自然なので気づきにくい。点を置くたびに、両方の軸についてその位置が正しいかを確かめる。

ひとつの塗りに二つの意味を持たせてしまう #

段落を並べた帯で「削る前」と「削ったあと」を比べる図では、上の段の濃い塗りが「再描写の段落」、下の段の濃い塗りが「直しが要る段落」になっていた。同じ見た目が別のことを指している。削る段落を点線の枠に変え、塗りは「直しが要る」だけに使った。

同じことは図をまたいでも起きる。作中の時間の線グラフに「期待される動き」として灰色の太い帯を入れたところ、前からあった「再描写の区間」の網掛けが帯と同じ灰色で、区別がつかなくなった。網掛けは消した。線が帯から落ちるだけで、再描写の区間は読み取れた。

逆に、記号をそろえると得をする。記事1の線グラフと記事4のジャンル比較の図で「太線=本文が描いている時点」「灰色の帯=読者が期待する動き」を共通にしたので、記事4の図は記事1の読み方のまま読める。束の記事では、記号の意味を記事をまたいで固定しておくとよい。

currentColor の図で色の名前を書く #

currentColor で描いた図は、ダークテーマでは線と文字が白になる。凡例に「黒線:本文が描いている場面」「濃いほど大きく」と書いていたので、ダークテーマでは説明が見た目と食い違った。

黒線:本文の位置 黒線:本文の位置 ライトテーマ ダークテーマ:線は白い

色の名前ではなく、テーマに左右されない性質で呼ぶ。「太線」「塗りの強さ」「点線の枠」なら、どちらのテーマでも同じものを指す。

図の id はページ全体で一つ #

斜線の <pattern> やグラデーションの <linearGradient> には id が要る。svg フェンスは中身がそのまま HTML に入り、束はすべてのメンバーが一つのページに並ぶ。そのため、別々の図に書いた id も同じ文書の中でぶつかる。同じ id で中身の違う定義があると、後の図が先の図の定義で塗られることがある。

今回は実際に崩れる前に気づき、novel-hatch、novel-hatch-split のように図ごとに別の名前にした。単体の SVG ファイルとして確認していると、この衝突は見えない。

右寄せのラベルが viewBox の外へはみ出す #

行の見出しを text-anchor="end" で左端の帯の手前に置いたところ、「削ったあと」だけが長くて viewBox の左端で切れた。文字幅はフォントで変わるので、座標から確実には読めない。描画して見て見つけ、viewBox を左に広げた。

模式図が測ったデータに見える #

線グラフや行列、分量の帯は、数値のグラフのように見える。今回の図はどれも説明のための模式図で、実際の小説を測ったものではない。特に分量の帯は、比率に根拠があるように読めてしまう。本文で模式図だと断る必要がある。差し替えた直後は断りがなかったので、あとから各記事の最初の図の近くに一文ずつ足した。表の数字も同じで、架空の例だと書いておく。

図を差し替えると、本文の言い回しが古い図に残る #

記事1の図の直後には「描写のかたまりが、あちこちにいくつもぶら下がっている」という一文があった。これは、出来事の箱から描写の箱が枝分かれしていた古い図に合わせた言い方だ。新しい線グラフには「ぶら下がる」形がない。図だけを差し替えると、本文の「この図では」「こうやって図にしてみると」が古い図を指したまま残る。この一文は、あとから新しい図の見え方(線が何度も「裏切り」の高さへ落ちて戻る)に合わせて書き直した。

SVG でなくてよい箇所もある #

図のない節に何かを足そうとしたとき、記事3の「プロファイラにならざるを得ない」という節は、本文そのものが「出来事ごと・話ごとの分量の分布を見せる」と書いていた。プロファイラの出力はもともと集計表なので、ここは SVG ではなく markdown の表にした。セルに■を並べれば分量の大小も見える。表にしておくと、「第3話と第5話の欄が同じ■■で見分けがつかない」ことが、そのまま「合否を判定できない」理由として読める。

形や位置の関係を見せたいときは SVG、行と列で比べたいときは表、というように、先に何を見せたいかを決めてから形式を選ぶ。

確認の経路 #

  • rsvg-convert で PNG にすると、形や文字のはみ出しは確認できる。ただし背景は白で、ブログの CSS もダークテーマも効かない。上の「黒線」の食い違いは、これでは見つからなかった。
  • /preview はブラウザの中で wasm を動かすページなので、コマンドラインからは結果を取り出しにくい。
  • 今回は、make -C go watch で動いているブログから記事ページの HTML を取得し、本文の部分だけ図に差し替えたファイルを作った。それを headless Chrome で、ダークテーマとライトテーマの両方で撮影した。ブログの CSS が当たった状態で、テーマごとの見え方を比べられる。
  • watch のサーバーは、ファイルを保存した直後だとまだ古い内容を返すことがあった。少し待ってから取得し直すと反映されていた。