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

[posts の AI 小説の記事](../../posts/2026-10-27-why-ai-novel-is-bored.md)にある9枚の SVG を、write-slops の skill の「位置・大きさ・重なりに意味を持たせる」という方針で描き直した。そのときにつまずいたところを残す。

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

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

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

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

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

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

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

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

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

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

```svg
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 420 150" width="420" height="150" role="img" aria-label="同じ図でも、ダークテーマでは線が白くなり、黒線と書いた凡例が合わなくなる">
  <rect x="10" y="10" width="190" height="100" rx="6" fill="#ffffff" stroke="#888888"/>
  <rect x="220" y="10" width="190" height="100" rx="6" fill="#13171f" stroke="#888888"/>
  <path d="M25 80H75V50H125V30H185" fill="none" stroke="#000000" stroke-width="2.5"/>
  <path d="M235 80H285V50H335V30H395" fill="none" stroke="#ffffff" stroke-width="2.5"/>
  <text x="105" y="100" font-size="11" text-anchor="middle" fill="#000000">黒線：本文の位置</text>
  <text x="315" y="100" font-size="11" text-anchor="middle" fill="#ffffff">黒線：本文の位置</text>
  <g fill="currentColor" font-size="11" text-anchor="middle">
    <text x="105" y="132">ライトテーマ</text>
    <text x="315" y="132">ダークテーマ：線は白い</text>
  </g>
</svg>
```

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

## 図の 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 のサーバーは、ファイルを保存した直後だとまだ古い内容を返すことがあった。少し待ってから取得し直すと反映されていた。
