# 漫画

> PostextでMarkdownから漫画とコミックを組む方法。割り方の木で割る漫画のページ、セーフエリアを守ってトリミングするコマの絵、台本から作る写植（セリフ、思考、ささやき、叫び、無線、ナレーション、描き文字）、吹き出しのスタイル、絵に置く話者のアンカー、本文中の帯漫画、見開き、右から左に読むページと縦書きの写植、翻訳、そしてCanvas、PDF、HTML、EPUBの出力

- HTML版: https://postext.dev/ja/docs/comics
- 最終更新: 2026-10-07
- 読了時間: 25分
- 他の言語: [en](https://postext.dev/en/docs/comics.md), [es](https://postext.dev/es/docs/comics.md), [ca](https://postext.dev/ca/docs/comics.md), [pt](https://postext.dev/pt/docs/comics.md), [zh](https://postext.dev/zh/docs/comics.md), [ar](https://postext.dev/ar/docs/comics.md)

## かんたんな説明

このページでは、Postextで漫画を作る方法を説明します。絵がそのままコマになり、登場人物が話すこと、考えること、耳にする音は、すべてMarkdownファイルに文字で書きます。Postextはコマをページに並べ、その言葉の周りに吹き出し、ナレーション、描き文字を自動で描きます。翻訳するときは言葉だけを書き直せば、Postextが新しい言語で写植し直し、日本語なら縦書き、アラビア語なら右から左に組みます。ほかに、本の中に入れる短い漫画、向かい合う2ページにまたがるページ、各出力、まだ残っている制限も取り上げます。

**絵がコマになり、セリフも心の声もナレーションも音も、すべてMarkdownのテキストです。**

Postextの漫画は、絵の一式と台本でできています。絵は、文字を入れずに描いたふつうのビットマップかSVGのリソースです。台本は章のMarkdownに書きます。`:::page`ブロックがページをコマに割り、各コマに絵を与え、そのコマの吹き出し、ナレーション、描き文字を1行ずつ並べます。Postextはコマを割り付け、大事な部分を切らないように絵を各コマに合わせてトリミングし、文字を本の写植書体で一つのサイズに組み、その周りに吹き出しを描き、しっぽを話者に向け、顔を隠さない位置に読む順に吹き出しを置きます。翻訳は、同じコマに別の言葉を入れたもう一つのMarkdownファイルです。Postextはそれを一から写植し直し、日本語なら縦書きに、アラビア語なら右から左に組みます。

漫画の機能は、使うときだけ働きます。`:::page`も`:::strip`もない文書は、これまでとまったく同じに組まれます。設定は[設定の`comics`の節](https://postext.dev/ja/docs/configuration.md#漫画)に、記法の要約は[文書形式 › 漫画](https://postext.dev/ja/docs/document-format.md#漫画)にあります。

## 漫画のページ

`:::page`ブロックが漫画の1ページです。`:::page{…}`の行で始め、コマごとに`::panel`の行とそのコマの台本を続け、何も付けない`:::`で閉じます。

```md
:::page{split="30 [30 | 20 | *] / *" gutter=4mm}
::panel{art=lh-arrive}
caption: 毎年夏になると、マヤは灯台で一週間を過ごした。
maya: おじいちゃん！来たよ！
::panel{art=lh-radio}
tomas: ちょうどよかった。無線が聞こえなくなってな、
tomas: 嵐が近づいとる。
::panel{art=lh-maya}
maya{thought}: あの真空管、ゆるんでるみたい…
::panel{art=lh-beam bleed}
sfx{rotate=-8}: バキッ
tomas{shout}: 手すりにつかまれ！
:::
```

ブロックは必ず新しいページから始まり、そのページ全体を使います。閉じのフェンスの後の文章は次のページから始まるので、`:::page`ブロックを2つ続ければ漫画のページが2ページになり、間に`:::pagebreak`を入れてもページは増えません。エンジンはブロックの中身を、`:::verse`と同じように自分で1行ずつ読みます。中ではMarkdownのブロック、コンテナー、ほかのディレクティブは認識されず、`<!-- comments -->`は複数行にわたるものも含めて無視されます。

ページの役割は`'comic'`（`VDTPage.role`）です。漫画のページはコマだけでできているので柱もノンブルも入りませんが、ページ番号には数えられます。`comics.runningHeads: true`にすると柱とノンブルが入ります。コマは**枠**から割り付けます。枠はふつうページの余白の内側の版面ですが、`comics.frame.margins`で漫画のページに独自の余白を与えることもできます。

開始行の属性は次のとおりです。

| 属性 | 効果 |
| --- | --- |
| `split="…"` | 枠を区画にどう割るか（[ページの分割](https://postext.dev/ja/docs/comics.md#ページの分割)を参照）。未指定のときは、同じ高さの段にコマを上から積みます。 |
| `gutter=4mm`、`gutter="4mm 2mm"` | 段と段の間隔。2つ目の値を書くと、段の中で横に並ぶコマの間隔も指定します。単位のない数はミリメートルです。未指定のときは`comics.gutter`（4mmと2mm）。 |
| `style=…` | ページのすべてのコマに使う名前付きのコマのスタイル（`comics.panelStyles`）。 |
| `bleed` | 枠に接するコマをすべて仕上がり線まで、さらに塗り足しまで伸ばします。 |
| `direction=rtl`、`dir=ltr` | 設定にかかわらず、このページを読む方向を決めます（[読む方向](https://postext.dev/ja/docs/comics.md#読む方向)を参照）。 |
| `spread` | ページを向かい合う2ページにまたがって組みます（[見開き](https://postext.dev/ja/docs/comics.md#見開き)を参照）。 |

## ページの分割

`split`属性は、ページを割り方の木として書きます。`/`で区切ったサイズの並びは区画を上から下へ積み（段）、`|`で区切った並びは区画を読み始める側から横に並べます。サイズの後に角かっこで並びを書くと、その区画をもう一方の向きでさらに割ります。上の例のページ`30 [30 | 20 | *] / *`は、枠の高さの30%の段を、幅の30%のコマ、20%のコマ、残りを取る3つ目のコマに割り、その下にページの残りを取る2段目を置いたものです。Sandboxの画面では、この区画を「割り」と呼んでいます。

> **図: コマ割り 30 [30 | 20 | *] / ***
> コマ割り 30 [30 | 20 | *] / * で割ったページの枠。1段目は高さの30%を取り、幅の30%、20%、残りの3つのコマに割られています。その下の2段目は、ページの残りを1つのコマとして取ります。間白は割り線をまたいでいます。ページの横には、このコマ割りを木として描いています。2つの項目を持つ段の並びのうち、1つ目が3つのコマを横に並べた角かっこの並びを持ちます。木の葉は、読む順に1から4の番号を付けたコマです。
>
> *サイズは親の区画に対する割合で、* は残りを取ります。コマの番号は読む順、つまり木の順です。*

文法の全体は次のとおりです。

```
split := list
list  := item ( "/" item )*  |  item ( "|" item )*
item  := size [ "[" list "]" ]
size  := number ["%"] [ "~" number ["%"] ]  |  "*"  |  (nothing)
```

- **サイズ**は、並びの向きに沿った親の区画に対する割合です。`30`と`30%`は同じ意味です。`*`か空のサイズは、書いたサイズの残りを等分して取ります。並びの最後の項目は、サイズに何と書いてあっても常に端まで伸びます。
- **1つの並びに区切りは1種類**。同じ並びに`/`と`|`を混ぜること、`[`を閉じないこと、親と同じ向きの角かっこの並びを書くことは、いずれも構文エラー（`comicSplitSyntax`）で、読める部分だけが使われます。
- **合計が多すぎるとき**。サイズの合計が100%を超えると、各`*`に5%が残るように縮められ、ページは`comicSplitOverflow`を報告します。
- **読む順**は木の順です。段は上から下へ、段の中のコマは始まり側から読みます。`::panel`の行はこの順に区画を埋めます。区画より多くのコマがあるページでは余ったコマは組まれず、少ないページでは最後の区画が空のまま残ります（`comicPanelCount`。`split`を書いたときだけ報告します）。

割り方の例をいくつか挙げます。

| 割り方 | ページ |
| --- | --- |
| `*` | 1ページ1コマの大ゴマ。 |
| `33 / 33 / *` | 3段。 |
| `* / * / * / *` | 同じ高さの4段。4コマ漫画の形です。 |
| `50 [* \| *] / 50 [* \| * \| *]` | 2コマの段の下に3コマの段。 |
| `30 / 35 [* \| * \| *] / *` | 横長のコマ、3コマの段、横長のコマ。 |
| `60 \| * [50 / *]` | 始まり側に縦長のコマ、その横に縦に積んだ2コマ。 |
| `* [40~55 \| *] / 35` | 斜めの線で割ったアクションの段と、その下の高さ35%の段。 |

### 斜めの割り線

サイズを`a~b`と書くと、割り線が斜めになります。区画の奥側の辺が、交差する軸の始まりでは`a`%、もう一方の端では`b`%の位置を通ります。横に並ぶコマでは始まりは上なので、`40~55 | *`は上端で幅の40%、下端で55%の位置を結ぶ線を引きます。段では、始まりは読み始める側です。サイズは両端でそれぞれ別に足し合わされ、区画は凸多角形のまま保たれます。角の丸みは長方形のコマにだけ付き、斜めのコマの角は尖ったままです。

### 間白

間白は各割り線をまたいで両側に半分ずつ取るので、30%の位置に書いた線は区画のちょうど30%の位置に来ます。斜めの線もその向きの間白を保ち、幅は線に垂直に測ります。既定値は一般的なページに合わせてあり、段の間が4mm、段の中のコマの間が2mmです（`comics.gutter.horizontal`と`vertical`、またはページの`gutter`属性）。

### 裁ち落とし

裁ち落としのコマは枠の外へ出ます。枠に接する各辺を仕上がり線まで、ページに塗り足しがあれば（`page.cutLines.bleed`）さらにその外まで伸ばします。ページの`bleed`属性はすべてのコマを、コマ自身の`bleed`はそのコマだけを裁ち落としにします。`bleed="top start"`は指定した辺（`top`、`bottom`、`start`、`end`、`left`、`right`）だけを伸ばし、`bleed=false`は裁ち落としにしません。`bleed: true`を持つコマのスタイルは、そのスタイルのコマを裁ち落としにします。

### コマの余白と乗せゴマ

`pad`はコマを区画より小さくします。値は1〜4個で、CSSのマージンと同じ順に論理的な辺（上、終わり、下、始まり）に対応し、それぞれ長さか区画に対する割合です。`::panel{art=x pad="0 15%"}`は、段より幅の狭いコマを段の中央に置きます。

`inset="x y w h"`を持つコマは区画を取らず、直前のコマの上に、そのコマの箱に対する割合で指定した位置と大きさで乗ります。隅に入れる小さな顔のアップや、引きの絵に重ねる寄りの絵がこれにあたります。台本はその乗せゴマの中に写植されます。

```md
:::page{split="*"}
::panel{art=storm-wide}
caption{at=bottom-start}: 真夜中、嵐が来た。
::panel{art=maya-window inset="62% 6% 32% 30%"}
maya{whisper}: おじいちゃん？
:::
```

## コマと絵

`::panel{…}`の行がコマを始め、その台本は次の`::panel`の行か閉じのフェンスまで続きます。`art`のないコマは背景色だけの空のコマとして描かれ、文字だけのコマはこうして作ります。最初の`::panel`より前にある文字は最初のコマのナレーションとして写植され、`comicStrayText`として報告されます。

| 属性 | 効果 |
| --- | --- |
| `art=<id>` | コマの絵。ビットマップかSVGのリソースのIDです。不明なIDのときはコマが空になり、`comicUnknownArt`を報告します。 |
| `fit=cover`、`fit=contain` | `cover`は区画を埋めるように絵をトリミングしますが、セーフエリアには食い込みません。`contain`は絵全体を表示し、余りはコマの背景色の帯になります。未指定のときはコマのスタイルの値（`cover`）。 |
| `focus="70% 40%"` | セーフエリアが位置を選ぶ余地を残すときに、中央に保つ絵の点。 |
| `style=…` | このコマに使う名前付きのコマのスタイル。 |
| `border=none`、`border=0.5mm` | 枠線なし、またはその太さの枠線。 |
| `bg=#1b1b2f` | コマの背景。色、パレットのID、または`none`。 |
| `bleed`、`bleed="top start"`、`bleed=false` | [裁ち落とし](https://postext.dev/ja/docs/comics.md#裁ち落とし)を参照。 |
| `pad="…"` | [コマの余白と乗せゴマ](https://postext.dev/ja/docs/comics.md#コマの余白と乗せゴマ)を参照。 |
| `inset="x y w h"` | 区画を取らずに、このコマを直前のコマの上に乗せます。 |
| `pop=<id>` | 枠線の上に描く切り抜き（[枠からはみ出す絵](https://postext.dev/ja/docs/comics.md#枠からはみ出す絵)を参照）。 |
| `mirror`、`mirror=false` | このコマの絵を左右反転するか、ページが絵を反転するときにこのコマだけ描いたままにします（[読む方向](https://postext.dev/ja/docs/comics.md#読む方向)を参照）。 |
| `alt="…"` | タグ付きPDF、HTML、EPUBのためのコマの代替テキスト。未指定のときはリソースの`altText`。 |
| `id=…` | コマのID。HTMLとEPUBの出力がアンカーとして使います。 |

### コマに合わせた絵のトリミング

コマの絵は、最終的に入る区画の形を考えずに描かれます。ページの割り方を変えることも、割り線をドラッグすることもあり、翻訳で段を高くする必要が出ることもあるからです。見えていなければならない部分は、絵の**セーフエリア**（`Resource.safeArea`。[文書形式 › セーフエリア](https://postext.dev/ja/docs/document-format.md#セーフエリア)を参照）が示し、トリミングは区画ごとに計算されます。

1. `fit=cover`では、表示する窓は区画と同じ縦横比で、絵が許すかぎり大きく取ります。
2. 窓は、セーフエリアがその中に入るように置きます。それでも位置を選ぶ余地があるときは、コマが`focus`を指定していればその点を窓の中央にし、指定がなければセーフエリアの外の余白をその大きさに比例して切ります。そのため、中央より左にいる被写体は中央より左に残ります。
3. 区画の縦横比の窓にセーフエリアが収まらないとき（縦長の被写体に対して極端に横長の区画など）は、セーフエリア全体が見えるように絵を表示し、区画の残りをコマの背景色で埋めます。ページは`comicPanelLetterbox`を報告します。W × Hの絵のセーフエリアが区画に全部収まるのは、区画の幅と高さの比が`sw·W/H`から`W/(sh·H)`の間にあるときです。`sw`と`sh`は、セーフエリアの幅と高さを割合で表したものです。

セーフエリアのない絵は、中央か`focus`を中心にトリミングされます。固有のサイズのないSVGは、そのまま区画を埋めます。レンダラーは区画の多角形でクリップし、絵全体をトリミング前の大きさで描くので、トリミングで画像が再サンプリングされることはありません。

### コマのスタイル

コマの見た目は、`comics.panel`（黒の1ptの枠線、白の地、`cover`）、ページやコマが`style=`で選ぶ`comics.panelStyles`の名前付きスタイル、そしてコマ自身の`border`と`bg`で決まります。枠線は`solid`、`none`、`rough`から選べます。`rough`は少し揺れる手描き風の線で、揺れはコマから決まるシードで作るので、何度組んでも同じ形になります。すべての項目は[設定 › 漫画](https://postext.dev/ja/docs/configuration.md#漫画)にあります。

### 枠からはみ出す絵

人物や物がコマから飛び出して枠線を破る表現には、絵が2枚要ります。ふつうどおり区画でクリップされるコマの絵と、はみ出す部分を透明な地に切り抜いた絵で、後者は`pop`で指定します。切り抜きはコマの絵とまったく同じようにトリミングして置き（絵と同じ大きさの画像にしてください）、枠線の後にクリップせずに描くので、枠線と間白の上に重なります。

```md
::panel{art=gull-sky pop=gull-cutout bleed="top"}
sfx{at="70% 20%"}: ギャアッ
```

## 写植

各`::panel`の行の下には、そのコマの台本を1行に吹き出し1つずつ書きます。

```md
key{attributes}: text
```

**キー**（`key`）は話者のID（英字、数字、`_`、`.`、`-`）で、どの言語の版でも同じです。絵のアンカーや[登場人物](https://postext.dev/ja/docs/comics.md#登場人物)と対応します。予約されたキーが3つあります。`caption`（ナレーションの箱）、`sfx`（描き文字。吹き出しはありません）、`note`（編集部の注）です。コロンは、中国語や日本語の入力方式で入力される全角の`：`でもかまいません。テキストはインラインのMarkdownです。`*強調*`と`**強い強調**`は写植の慣習どおりボールドイタリックで印字され（イタリックのない文字体系ではボールドだけ）、`:tcy[12]`は縦の行の中で数字を縦中横にし、`:ruby`は読みを親文字の上（縦書きでは横）に半分の大きさで組み、`:ltr`と`:rtl`は逆向きの吹き出しの中で一部の文字列を本来の向きのまま保ちます。スペース2つかタブで字下げした行は、上の吹き出しの続きです。前の行とはスペースでつなぎますが、中国語や日本語の2文字の間には何も入れません。行末のバックスラッシュは、そこで吹き出しの文字を改行します。空行は無視され、台本の形になっていない行はナレーションとして写植されて`comicStrayText`として報告されます。

```md
::panel{art=lh-radio}
tomas: ちょうどよかった。
  無線が聞こえなくなってな、\
  嵐が近づいとる。
biscuit{to="40% 70%"}: ニャ？
note: 真空管ラジオは、声が出るまで1分ほど温めなければならない。
```

台本の行の属性は次のとおりです。

| 属性 | 効果 |
| --- | --- |
| `{whisper}`、`style=whisper` | 吹き出しのスタイル。波かっこの中に語を1つだけ書くと、スタイルの名前になります。`thought`、`whisper`、`shout`、`radio`、`inner`、または本で定義したスタイルです。不明な名前は`comicUnknownBalloonStyle`を報告し、その行はキーのスタイルを使います。 |
| `at="62% 40%"` | 吹き出しの中心を、コマの絵（絵のないコマでは区画）のその点に固定します。点は絵に対する割合なので、トリミングや割り線のドラッグを経ても、絵の同じ場所にとどまります。 |
| `at=top-start` | 吹き出しをコマの角か辺に置きます。`top-start`、`top-end`、`bottom-start`、`bottom-end`、`top`、`bottom`。ナレーションと注は枠線にぴったり付けて置きます。 |
| `to="40% 70%"` | しっぽを話者のアンカーではなく、絵のその点に向けます。しっぽはその点のほうへ向き、口の手前で止まるときと同じように、点に届く手前で止まります。 |
| `tail=none`、`tail=start` | しっぽを付けないか、指定した側（`top`、`bottom`、`start`、`end`）のコマの外にいる話者へしっぽを向けます。既定は`tail=auto`です。 |
| `join`、`join=false` | `comics.lettering.joinSameSpeaker`の設定にかかわらず、同じ話者の直前の吹き出しにつなげるか、離します。 |
| `break` | 吹き出しが枠線を越えて間白や隣のコマに出ることを許します。求めた越境なので、はみ出しとしては報告されません。ただし向こう側で覆うもの（顔、ほかのコマの吹き出し）は報告され、吹き出しの中心は自分のコマの中にとどまります。 |
| `rotate=-8` | 吹き出しか描き文字を、時計回りに度単位で回転します。 |
| `skew=-8` | 文字をその角度だけ傾けます（正の値で斜体のように前へ、負の値で後ろへ）。回転の前に適用されます。遠近法で見た物の上の文字（本の表紙の題名、看板など）に使います。`rotate`と組み合わせると、文字が物の上辺と左右の辺の両方に沿います。吹き出しスタイルでは`skew`で全行に設定できます。 |
| `size=1.5` | 描き文字の大きさを倍率で変えます。 |
| `color=#c0392b` | 文字の色。16進数の色かパレットのID。 |
| `font="…"` | この行の書体。 |
| `vertical`、`horizontal`、`mode=vertical` | 本全体より優先される、この行の組み方向です。`vertical`は横組みの版でその行を縦に組み（翻訳しない`ドン`など）、`horizontal`は縦組みの版で横に組みます（横書きの看板など）。ほかの言語の本で縦に組んだ行は、その行自身の文字の規則に従い（かながあれば日本語の規則）、縦書きの写植の行送りを使います。縦組みの本では、中国語や日本語の文字を含まない行は、`vertical`と書かない限り、もともと横に組まれます。 |

### 吹き出しのでき方

写植は、テキストフレームの流儀ではなく、漫画の写植の習慣に従います。

- **本全体で1つのサイズ**。どの吹き出しも`comics.lettering.fontFamily`で、`comics.lettering.fontSize`（既定は7.5pt）の大きさに組みます。変わるのはスタイルの`fontScale`による倍率だけです（ささやきは0.9、叫びは1.15）。収めるために文字を縮めることはありません。収まらない吹き出しは形を変えるか、移動するか、枠線を越えるか、報告されます。
- **先に文字、後に吹き出し**。まず語を行に分けます。目指す形は菱形で、上と下の行を短く、中ほどの行をいちばん長くし、最後の行がほかの行より極端に短くならないようにし、同じくらいよい改行位置がほかにあれば冠詞や前置詞で行を終えません。その後、行の周りに、どの側にも同じだけの余白を取って輪郭を描きます。
- **表記の決まり**。ピリオド3つは三点リーダーになります。`textTransform: 'uppercase'`は文字をすべて大文字にします（大文字のない文字体系はそのままで、ドイツ語のßはSSになります）。日本語と中国語では吹き出しの最後の句点を省き（`dropFinalStop`）、縦書きではASCIIの`!`と`?`を全角の形にし、2つ続くときは1マスに収めます（`!?`は⁉）。`doubleDash`は、アメリカのコミックのように全角ダッシュを`--`で写植します。
- **配置**。コマの吹き出しは読む順にコマの中へ置き、枠線から`comics.lettering.inset`（1.5mm）離します。最初の吹き出しは上寄りの始まり側に置き、次の吹き出しは、読む方向にさらに先へ進んでいる場合を除いて、前の吹き出しより高い位置には置きません。吹き出しは絵が示す顔と回避エリア、話者の口、ほかの吹き出しを避け、話者の下ではなく上か横に置かれ、しっぽどうしはなるべく交差させません。角を指定したナレーションと注を最初に、次に固定した吹き出し、最後に残りを置きます。配置は決定的で、同じページからは常に同じ吹き出しが得られます。
- **紙面の内側**。写植が仕上がり線の外に出ることはありません。裁ち落としのコマでは、吹き出しはコマのうち枠の内側にある部分にとどまり、断裁で切られることはありません。コマの横の塗り足しに入れるのは、`at=`で固定したか`break`を付けた描き文字だけです。
- **収まらないとき**。きれいに置けない吹き出しは、まず枠線を越え（`break`があるときだけ）、次に回避エリアにかかり（顔には決してかかりません）、さらに幅の広い形や狭い形を試します。狭い区画の長いセリフは区画とほぼ同じ幅に組まれて間白にはみ出し、話者の顔の上に細い柱のように立つことはありません。それでも何かに重なるときは最も害の少ない位置に置かれ、ページは`comicBalloonOverflow`を報告して、そのコマと覆っているものを示します。`break`や`at=`の固定で求めた越境はこの問題に数えず、そのときの警告は吹き出しが覆っているものだけを示します。行を短くするか、コマを大きくするか、`at=`で固定すれば解決します。

### しっぽ

セリフの吹き出しのしっぽは話者の口を、思考の吹き出しの泡は頭を指します（[話者とアンカー](https://postext.dev/ja/docs/comics.md#話者とアンカー)を参照）。しっぽは輪郭の話者に面した側から出て、少し曲がり、口の手前で止まります。話者のアンカーがトリミングでコマの外に出たとき、または絵にその話者のアンカーがないときは、しっぽはコマの外、アンカーの方向か最も近い枠線の方向を指し、枠線のところで終わります。このような吹き出しは声の聞こえてくる側の枠線の近くに置かれ、しっぽは短くなります。コマを横切る長いしっぽは矢印のように見えるので、しっぽを伸ばす代わりに吹き出しを動かします。`to="x% y%"`はしっぽを絵の別の点に向け、`tail=start`（または`top`、`bottom`、`end`）はその側のコマの外にいる話者に向けます。ナレーション、注、描き文字にはしっぽがありません。

### 吹き出しの連結

同じ話者の行が2つ続くと、話の途中の間を写植で表すときのように、吹き出しがつながります。`joinSameSpeaker: 'butt'`（既定）では2つの本体が重なって1つの輪郭を共有し、`'connector'`では細い首でつながり、`'none'`ではしっぽを1つずつ持つ2つの吹き出しのままです。しっぽを持つのはグループの最初の吹き出しだけです。行ごとに`join`か`join=false`で指定することもできます。

### 描き文字

`sfx`の行には吹き出しがありません。文字は大きく（写植のサイズの2.4倍）、太字で、文書の言語に合った描き文字用の書体で組まれ、絵の上でも読めるように文字の周りに白い縁が付きます。絵に`sfx`のアンカー（IDが`sfx`のアンカー）があればその近くに、なければ顔を覆わない場所に置きます。`rotate`、`size`、`color`、`font`で変更でき、`at`で固定できます。縦書きの写植では1行に縦に組み、長さは5字までです。描き文字は、ページのすべての吹き出しの後に描かれます。

行ごとに組み方向を指定することもできます。漫画の横組みの版で日本語の描き文字を残すときは、その行を縦に組みます。

```md
sfx{vertical size=2.6 font="Dela Gothic One"}: ドン
```

### 写植の設定

`comics.lettering`は、本全体の書体、サイズ、行送り、色、表記の決まりを持ちます。既定の書体は文書の言語に従い、描き文字の書体も同じです。

| 言語 | 写植 | 描き文字 |
| --- | --- | --- |
| ラテン文字、ギリシャ文字、キリル文字、その他 | Comic Neue | Bangers |
| 日本語 | Zen Antique | Dela Gothic One |
| 簡体字中国語 | Noto Sans SC | ZCOOL KuaiLe |
| 繁体字中国語 | LXGW WenKai TC | LXGW WenKai TC |
| アラビア語、ペルシア語、ウルドゥー語 | Playpen Sans Arabic | Lalezar |

どれもGoogle Fontsにあり、ほかの書体と同じように名前で読み込まれます。行の高さが既定のままなら、縦書きの吹き出しと中国語・日本語の吹き出しは行送り1.5で、アラビア語の吹き出しは1.45で組まれます。日本語、中国語、アラビア語の写植はスタイルの指定にかかわらず斜体にならず、アラビア語には字間を付けません。

### 登場人物

`comics.cast`は登場人物の一覧です。各人物は、ID（話者のキー）と`name`を持ち、任意で、その人物が話す吹き出しのスタイル（`balloonStyle`。いつも`radio`で話すロボットなど）、ほかの人物と区別するための文字の`color`と吹き出しの`fill`、`fontFamily`を持ちます。名前は出力が読み手に伝えるものです。HTMLビューアーとリフロー型のEPUBは、各行を「名前：セリフ」の形で印字します。登場人物に載っている話者が、不明な話者として報告されることはありません。

```ts
comics: {
  cast: [
    { id: 'maya', name: 'マヤ' },
    { id: 'tomas', name: 'トマスじいさん' },
    { id: 'beacon', name: '灯台のビーコン', balloonStyle: 'radio', fill: { hex: '#e8f4ff', model: 'hex' } },
  ],
}
```

## 吹き出しのスタイル

吹き出しのスタイルは吹き出しの種類で、輪郭、しっぽ、文字を決めます（Sandboxの画面では「フキダシ」と表記しています）。組み込みのスタイルが9つあり、台本の行は波かっこの中に語を1つ書いてスタイルを指定します（`ben{whisper}: …`）。予約されたキーは名前と同じスタイルを使い（`caption:`、`sfx:`、`note:`）、それ以外の行は`speech`か、登場人物に設定した`balloonStyle`を使います。

| スタイル | 輪郭 | しっぽ | その他 |
| --- | --- | --- | --- |
| `speech` | 楕円 | 曲線 | すべてのスタイルの土台です。白の塗り、黒の0.6ptの輪郭、0.55emの余白。 |
| `thought` | 雲形 | 泡 | 泡は口ではなく頭を指します。 |
| `whisper` | 楕円、破線 | 曲線 | 文字は0.9倍。 |
| `shout` | ギザギザ | くさび形 | 文字は1.15倍で太字。輪郭は0.8pt。 |
| `radio` | 電気（ジグザグ） | 稲妻 | 無線、電話、機械から聞こえる声。 |
| `caption` | 四角 | なし | 淡い黄色で、上・始まり側の角に付けて置き、文字は始まり側にそろえます。 |
| `inner` | 角丸の四角 | なし | 灰色の塗りに斜体。人物の心の声（モノローグ）です。 |
| `note` | 四角 | なし | 下・終わり側の角に付けて置き、文字は0.8倍。 |
| `sfx` | なし | なし | 文字は2.4倍、太字、描き文字の書体で、1.5ptの白い縁が付きます。 |

`comics.balloonStyles`で組み込みのスタイルを変更したり、新しいスタイルを加えたりします。組み込みのIDを持つ項目はそのスタイルに重ねて適用され、新しいIDの項目は`speech`から始まります。

```ts
comics: {
  balloonStyles: [
    { id: 'caption', fill: { hex: '#ffffff', model: 'hex' }, textTransform: 'uppercase' },
    { id: 'shout', burstPoints: 18, burstDepth: 0.3 },
    { id: 'eerie', shape: 'wavy', stroke: { hex: '#5b4a8a', model: 'hex' }, italic: true },
    { id: 'writing', shape: 'none', tail: 'none', fontFamily: 'Caveat', color: { hex: '#3b2a1a', model: 'hex' } },
  ],
}
```

```md
ghost{eerie}: この家から出ていけ…
caption{at=bottom-end}: 三つ先の通りで。
```

輪郭は`oval`（行に合わせた超楕円。`roundness`は2.2）、`rounded`、`rectangle`、`cloud`（ふくらみの数は周の長さから決まります）、`burst`（とげが`burstPoints`本、深さ`burstDepth`）、`wavy`、`electric`、`none`です。`dash`は破線の輪郭を、`double`は二重の輪郭を描き、`wobble`（0〜1）は輪郭を手描きのように揺らします。同じ吹き出しの揺れはいつも同じです。しっぽは`curved`、`wedge`、`bubbles`、`zigzag`、`none`です。すべての項目と既定値は[設定 › 漫画](https://postext.dev/ja/docs/configuration.md#漫画)にあります。

レンダラーは、欧米のレタラーが吹き出しにペンを入れるのと同じ手順で吹き出しを描きます。グループのすべての輪郭をまず2倍の太さで引き、次に塗り、最後に文字を組みます。そのため、連結した2つの本体としっぽは、間に線のない1つの形になります。

## 話者とアンカー

しっぽが人物を指し、吹き出しが顔を避けられるのは、絵が人物の位置を教えるからです。ビットマップやSVGのリソースは**アンカー**を持てます。話者ごとに1つの点を一度だけ書き、セーフエリアと同じく、絵の左上の角からの割合（0〜1）で表します。

```ts
const arrive: Resource = {
  id: 'lh-arrive', typeId: 'figure', kind: 'bitmap', createdAt: 0, updatedAt: 0,
  bitmap: { fileId: 'lh-arrive.jpg', format: 'jpeg', width: 1100, height: 733 },
  altText: '黄色いレインコートの少女が、海沿いの小道を灯台へ向かって歩いている。',
  safeArea: { x: 0.2, y: 0.08, width: 0.42, height: 0.82 },
  anchors: [
    { id: 'maya', x: 0.29, y: 0.52, head: { x: 0.27, y: 0.47 }, face: { x: 0.22, y: 0.42, width: 0.12, height: 0.16 } },
    { id: 'biscuit', x: 0.4, y: 0.68 },
  ],
  avoid: [{ x: 0.51, y: 0.09, width: 0.1, height: 0.43 }], // 灯台
};
```

- `id`は、台本が使う話者のキー（`maya: …`）です。IDが`sfx`のアンカーは、そのコマの描き文字の位置を決めます。
- `x`、`y`は口の位置で、セリフの吹き出しのしっぽはここを指します。
- `head`は、思考の吹き出しの泡が指す点です。未指定なら口と同じです。
- `face`は、どの吹き出しにも覆わせない長方形です。これを持たないアンカーには口の上と周りに数em分の保護枠が付くので、輪郭を指定していない顔も吹き出しに覆われません。
- `avoid`（リソースに書きます）は、吹き出しで覆わないほかの長方形の一覧です。手、話の鍵になる物、看板などに使います。余地がなければ吹き出しが回避エリアにかかることはありますが、顔にはかかりません。

アンカーは絵に対する割合なので、トリミングに合わせて動きます。エンジンは各アンカーをコマのトリミングと反転を通してページ上に写すので、割り線をドラッグしても、割り方を変えても、翻訳しても、しっぽが話者から外れることはありません。トリミングでコマの外に出たアンカーには、しっぽがコマの外のその方向を指します。そうならないように守るのがセーフエリアです。セーフエリアの外にあるアンカーはトリミングで切られるおそれがあるので、作者向けのヒントとして`comicAnchorOutsideSafeArea`で報告されます。ページのどの絵にも指定がなく、登場人物にもいない話者のキーは`comicUnknownSpeaker`として報告され、たいていはIDの綴り間違いがこれで見つかります。絵にアンカーがまったくないページは何も報告しないので、アンカーなしでも漫画を写植できます。

アンカーと回避エリアは絵に属し、どの言語でも同じです。Sandboxでは、[**リソース**パネル](https://postext.dev/ja/docs/sandbox.md#リソースパネル)の画像のエディターで指定します。**セーフエリアと写植**の項目からダイアログを開くと、**セーフエリア**、**話者**、**回避エリア**の3つのモードがあります。絵をクリックするとそこに話者が加わり、口、頭、顔をドラッグで位置に合わせ、横の欄にIDを入力します。絵の何もない部分をドラッグすると回避エリアを描きます。どの印も矢印キーで移動でき（Shiftを押すと大きく動きます）、Deleteで削除でき、ダイアログは独自の取り消しの履歴を持ちます。

## 帯漫画

`:::strip`ブロックの中身は漫画のページと同じですが、文章の中に、段幅かページ幅の箱としてコマに割って置かれます。新聞の連載漫画、雑誌の4コマ漫画、散文の本に挟む短い漫画などに使います。

```md
:::strip{split="* | * | * | *" aspect=4 span=page placement=top}
::panel{art=pip-1}
pip: オットー、氷がとけてるよ。
::panel{art=pip-2}
otto{thought}: パン屋だけはやめてくれ…
::panel{art=pip-3}
::panel{art=pip-4}
sfx: ザブーン
:::
```

| 属性 | 効果 |
| --- | --- |
| `span=column`、`span=page` | 置かれた段（既定）か、版面にまたがります。 |
| `placement=here` | 既定です。書いた位置で本文の中に組みます。帯漫画は分割されず、収まらないときは直前の見出しも連れて、まるごと次の段かページへ移ります。複数段のページで`here`と書いたページ幅の帯漫画は、ページ幅の囲みと同じく、置いた位置で段を区切ります。上の本文はすべての段で高さをそろえて終わり、帯漫画がページの幅に組まれ、本文はその下の段で続きます。ページの残りに収まらないときは、次のページから始まります。 |
| `placement=top`、`bottom`、`auto` | 図と同じようにフロートとして、この位置以降で余地のある最初のページの上端か下端に置きます。 |
| `width=60%`、`width=12cm` | 帯漫画の幅。またがる行長（段、`span=page`なら版面）に対する割合か、長さです（単位のない数はミリメートル）。その行長より広くはなりません。未指定のときは行長いっぱいに組みます。 |
| `align=start`、`center`、`end` | 行長より狭い帯漫画を、行長のどこに置くか。既定は`center`です。`start`と`end`は文字の方向に従い、右から左のページでは右端、縦組みのページでは段の上端が始まりの側になります。 |
| `height=4cm` | 帯漫画の高さ（単位のない数はミリメートル）。 |
| `aspect=4`、`aspect=4/1` | 幅と高さの比で、幅は帯漫画自身の幅です。未指定のときは、コマが正方形になる比率を取ります（4コマを横に並べれば4）。 |
| `caption="…"` | 帯漫画の下（`captionStyle.position: 'above'`なら上）に置くキャプション。帯漫画の幅で、図のキャプションスタイルで組みます。テキストはインラインのMarkdownで、版ごとにその言語で書きます。 |
| `type=figure` | キャプションのある帯漫画を、その種類のリソースとして番号付けします。キャプションはその種類のラベルと番号（「図3」）で始まり、帯漫画はその種類の番号の並びに、その種類のリソースと読む順に数えられます。`type`がないとき、またはどのリソースの種類にもない種類のときは、キャプションは番号なしで、帯漫画は数えられません。 |
| `id=…` | 番号付きの帯漫画に名前を付けます。`:ref{id="…"}`は、図のときと同じくそのラベルと番号を印字し、帯漫画へリンクします。 |

`split`のない帯漫画は、コマを横に並べます。帯漫画の箱がそのまま枠になり、間白、コマのスタイル、写植は設定のものを使い、裁ち落としはありません。段より高い帯漫画は、キャプションも含めて段の高さに縮められます。帯漫画の後の本文は、インラインの図の後と同じく、`layout.inlineResourceGap`が求める間隔を空けて、ベースライングリッドの次の行から続きます。縦組みのページでは帯漫画は回転した箱の中に組まれるので、`* / * / * / *`で`aspect=0.25`の4コマ漫画は縦の段を上から下へ進み、キャプションは縦組みの行としてその後に続きます。

```md
:::strip{split="* | * | *" width=70% caption="氷の上のピップとオットー。" type=figure id=pip-ice}
::panel{art=pip-1}
::panel{art=pip-2}
::panel{art=pip-3}
:::

:ref{id="pip-ice"}のとおり、氷は薄かった。
```

キャプションには、キャプションスタイルが設定するものがすべて効きます。書体とサイズ、ラベルと本文の色、ラベルの太さと傾き、帯漫画とキャプションの間のアキ、そろえ、背後の帯です。種類に固有の`captionStyle`は、その種類で番号付けした帯漫画に効きます。

VDTでは、帯漫画は`type: 'resource'`のブロックで、`comic`フィールドを持ち、`resourceBlock`は持ちません。座標はシート上のブロックの箱に対する相対値で、行長より狭い帯漫画や、キャプションの下にある帯漫画は、その箱の内側に置かれます（そのとき`comic.frame`は箱の角から始まりません）。キャプションはブロック自身の`lines`で、キャプションの書体と色で組まれます。`stripCaption`は、どの行がキャプションか、その位置、種類と番号、帯を示します。`pageComics(page)`は、ページの漫画と、その段とフロートにある帯漫画を、すべてシート上の座標に移して返します。

## 見開き

`:::page{spread}`は、1つの割り方の木を向かい合う2ページに広げます。パノラマや、開いた本の全面を使う戦いの場面のためのものです。枠は2つの版面をノドでつないだもので、ノド側の余白は含みません。割り方、間白、トリミングは1ページのときと同じように働き、コマや絵がノドをまたいでもかまいません。

```md
:::page{spread split="25 [* | * | *] / *" bleed}
::panel{art=market-1}
::panel{art=market-2}
::panel{art=market-3}
::panel{art=market-panorama}
caption: 時計塔から見た土曜の市。
:::
```

見開きは、両半分が向かい合うように偶数ページから始まります。漫画が奇数ページから始まることになる場合は、その前に白ページを1ページ加えます。1ページ目が単独で置かれる本の冒頭でも同じです。左綴じの本では偶数ページは左ページ、右綴じの本（アラビア語、縦組みの日本語と中国語、右から左に読むコミック）では右ページです。各ページには自分の側の半分が載ります。その側に届くコマがノドで切られて入り、ノドをまたぐコマの絵は両方のページに描かれます。裁ち落としのコマは天、地、小口では塗り足しまで伸びますが、ノドでは伸びません。製本で隠れてしまうノドの周りの8mmの帯には何も写植しません。そこに固定した吹き出しは近いほうの側へずれます。吹き出しはそれぞれ中心のあるページに置かれます。

## 読む方向

欧米のコミックは左から右に読み、段の最初のコマは左にあります。マンガとアラビア語のコミックは右から左に読みます。Postextは`comics.readingDirection`から方向を決めます。

- `'auto'`（既定）：版の言語の向きに従います。右から左に書く文書では右から左になるので、アラビア語版ではページの配置が左右反転します。縦組みの文書と、日本語および繁体字中国語（`ja`、`zh-Hant`、`zh-TW`、`zh-HK`、`zh-MO`）の文書でも右から左になるので、欧米のコミックの日本語版はマンガと同じく右から左に読みます。そのほかの言語では、簡体字中国語と韓国語を含め（現在の中国と韓国のコミックは左から右に読みます）、絵が描かれた向きである`comics.artDirection`（既定は`'ltr'`）に従います。`artDirection: 'rtl'`のマンガはどの言語でも右から左です。
- `'ltr'`か`'rtl'`は本全体の方向を固定し、ページの`direction`属性はそのページの方向を固定します。

綴じはコミックの向きに従います。`page.binding: 'auto'`のとき、`comics`セクションが右から左に読む本は右綴じになります。1ページ目は背の左側に単独で置かれ、見開きは`[3 | 2]`の順に並び、ビューアーは左方向にページをめくり、PDFは右から左のページ順を指定し、EPUBは右から左のページ送りを宣言します。決めるのは本全体の`comics`セクションなので、コミックのページがない章もほかの章と同じ綴じになります。ページ自身の`direction`で背の位置は変わりません。`comics`セクションがなく、コミックのページが既定値を使う文書は、本文の綴じのままです（`comics: {}`と書けば、コミックの読む向きに合わせて綴じます）。`page.binding: 'left'`または`'right'`を明示した場合はそれが優先されます。[綴じ](https://postext.dev/ja/docs/configuration.md#綴じ)を参照してください。

同じソースから両方のページ配置が得られます。右から左のページでは各段のコマを右から並べるので、コマ1は右上に来ます。斜めの線もそれに合わせて反転し、`bleed`、`pad`、角を表すキーワードの論理的な辺も同様です（`top-start`のナレーションは右上に来ます）。段の順は上から下のままで、台本の読む順も変わりません。写植の規則も反転します。コマの最初の吹き出しは右に寄り、次の吹き出しが前より高い位置に来られるのは、さらに左にある場合だけです。

絵は、指定しないかぎり反転しません。`comics.mirrorArt: true`は、`artDirection`と逆の方向に読むページの絵をすべて左右反転します。かつて欧米で出版されたマンガが長く行っていたやり方です。`::panel{mirror=false}`は絵を描いたままにします（絵の中に描かれた文字、右利きの剣士など）。アンカーとセーフエリアも反転に従います。反転はふつう使わないほうがよいでしょう。コマの順序はすでに読者に合わせてあり、反転した絵は作者が描いたものを変えてしまいます。

吹き出しの組み方向は、コマの順序ではなく言語に従います。`comics.lettering.writingMode: 'auto'`では、日本語と繁体字中国語は右から左へ行を進める縦書きで写植されます。1行は最大`maxColumnChars`字（8字）で、日本語の禁則処理に従い、数字は`:tcy`で縦中横にし、約物は縦書き用の形になります。縦組みで組む文書は、どの言語でも縦書きで写植されます。簡体字中国語、韓国語、その他の言語は横書きで写植され、`'horizontal'`か`'vertical'`でどちらかに固定できます。アラビア語は右から左に写植し、ラテン文字の語と数字はそれぞれ本来の方向で組み、斜体にも字間にもしません。

## 漫画の翻訳

翻訳は、同じ`:::page`と`::panel`の行、同じ話者のキーを持ち、言葉だけが違うMarkdownファイルです。絵とそのセーフエリア、アンカー、回避エリア、割り方、固定位置（`at=`の点は絵に対する割合です）は、すべての版で共有します。写植は版ごとに行われます。文字はその版の言語と書体で測られ、その言語の行に分けられ、吹き出しはすべてその周りに形を作り直して置き直されます。たとえば、上の最初のページの英語版は次のようになります。

```md
:::page{split="30 [30 | 20 | *] / *"}
::panel{art=lh-arrive}
caption: Every summer, Maya spent a week at the lighthouse.
maya: Grandpa! I'm here!
::panel{art=lh-radio}
tomas: Just in time. The radio's gone deaf,
tomas: and there's a storm on the way.
:::
```

版ごとに変わるものは、文書の`locale`から決まります。既定の写植と描き文字の書体、日本語と繁体字中国語の縦書き、中国語と日本語の句点の省略、行送り、アラビア語版のページの方向です。文章はスペイン語やフランス語では英語よりおよそ5分の1長くなり、中国語や日本語ではずっと短くなります。吹き出しはそれに合わせて大きくも小さくもなり、`comicBalloonOverflow`が、翻訳で行を短くするか固定が必要なコマを示します。描き文字もほかの言葉と同じです。翻訳するか、元の描き文字を残してその下に小さく訳を添えます。

## 漫画の出力

どの出力も同じ漫画を描きます。コマの背景、コマでクリップした絵、枠線、枠からはみ出す絵、次に連結グループごとの吹き出し（輪郭の線、塗り、文字の順）、最後に描き文字です。

- **Canvas**。SandboxのCanvas、Folioの3Dのページ、サムネイルは、すべて`renderPageToCanvas`で描きます。
- **PDF**。`postext-pdf`は漫画のページの輪郭をベクターで描き、写植の書体を埋め込みます。PDFの印刷用マスター（`svg.pdfFileId`）を持つSVGの絵は、そのマスターとして埋め込みます。タグ付きPDFでは、漫画の各ページが`Div`、各コマが代替テキスト（コマの`alt`、なければリソースの`altText`）付きの`Figure`になり、各吹き出しはそのコマの`Figure`の後に読む順に並ぶ`P`になります。描き文字は、その語を`/ActualText`に持つ`Span`です。背景、枠線、輪郭はアーティファクトです。出力はveraPDFのPDF/UA-1の検査に通ります。
- **HTML**。各コマは、インラインのSVG（クリップ、絵、枠線、切り抜き）とコマの代替テキストを持つ`<figure>`で、その後に吹き出しが読む順に`<p>`要素として続きます。セリフの吹き出しは視覚的に隠したspanの話者名で始まるので、スクリーンリーダーは「マヤ：おじいちゃん！来たよ！」と読み上げます。描き文字は、その語をラベルにした画像として読み上げられます。SandboxのHTMLビューアーのページは画面の幅とスクロールする高さを持つので、漫画のページは印刷のページをビューポートに合わせて縮小した形で組み（`comics.viewerLeaf`）、リフローはしません。
- **固定レイアウトのEPUB**。ページは印刷版と同じです。本には**領域ベースのナビゲーション**（`regions.xhtml`、EPUB Region-Based Navigation 1.0）も入ります。読む順にコマごとに1つの`panel`領域があり、その中に吹き出し、ナレーション、描き文字が入るので、リーディングシステムはコマ単位で本を読み進められます。ページ送りの方向は漫画の読む方向に従います。`renderToEpub`のオプション`kindlePanelView: true`はKindleのパネルビューを加えます。コマごとのタップ領域と、画面いっぱいに拡大した複製を、Kindleが求めるメタデータとともに入れます。
- **リフロー型のEPUB**。ここには保つべきページがないので、各コマはページと同じようにトリミングした絵になり、その後にセリフがテキストとして続きます。「**マヤ**：おじいちゃん！来たよ！」の形で、ナレーションは段落として、描き文字は斜体で入ります。

帯漫画のキャプションは、図のキャプションと同じく本文とともに描かれます。タグ付きPDFでは帯漫画の`Div`の`Caption`になり、コマの後に読まれます（帯漫画の上に置いたときはコマの前）。HTML、固定レイアウトのEPUB、リフロー型のEPUBでは、帯漫画とそのキャプションが1つの`<figure>`になり、キャプションはその`<figcaption>`です。縦組みや右から左のページでは帯漫画の絵がシートの上に重ねて置かれるので、HTMLではキャプションを本文の中に単独で残します。

## Sandboxでの漫画の編集

Canvas、HTMLのページ、Folioの**テキストを選択**モードでは、漫画のページをポインターで編集でき、どの編集も章のMarkdownに書き戻されます（詳しくは[Sandboxのガイド](https://postext.dev/ja/docs/sandbox.md#漫画の編集)を参照）。

- **割り線**。間白の上ではポインターがサイズ変更のカーソルになります。ドラッグすると割り線が動き、離すと新しい割合がページの`split`の値に書き込まれ（ページにこの属性がなければ加えます）、ページが組み直されます。Shiftを押すと5%刻みになり、Altを押すと近い側の端だけが動いて線が斜めになります。5%より狭くなる区画はありません。ドラッグ中は、絵が全体表示になってしまうコマに印が付きます。各割り線はフォーカスできる区切りでもあり、矢印キーで1%（Shiftで5%）動かし、Enterで位置を書き込み、Escapeで元に戻します。
- **コマ**。コマの上の小さなツールバーで、コマを横線か縦線で分割すると、新しい区画のための空の`::panel`がそのコマの後に加わります。次のコマと結合すると割り線がなくなり、結合したコマは最初のコマの絵と、両方の台本を持ちます。
- **吹き出し**。吹き出しをドラッグすると固定されます。台本の行に、コマの絵に対する割合で`at="x% y%"`が付きます。連結したグループは一体で動きます。動かしている間、顔か回避エリアを覆う位置やコマからはみ出す位置では吹き出しがオレンジ色になり、ツールチップがどれに当たるかを示します。フォーカスのある吹き出しは矢印キーで1%ずつ動き、固定した吹き出しをダブルクリックすると固定が外れます。
- **しっぽ**。しっぽの先をドラッグすると、しっぽが指す点が`to="x% y%"`として行に書き込まれます。先をダブルクリックすると`to`が消え、しっぽは話者に向き直ります。フォーカスのある吹き出しからTでしっぽに移り、矢印キーで指す点を動かします。
- **キーボード**。フォーカスのあるコマは、Hで横線、Vで縦線で分割し、Mで次のコマと結合します。
- **帯漫画**。どのツールも`:::strip`のブロックで使えます。段の中、フロート、ページ幅のどれでも、行長より狭くてもキャプションの下にあっても同じで、書き込み先は帯漫画自身のフェンスです。
- **絵**。絵のセーフエリア、話者、回避エリアは**リソース**パネルで指定します（[話者とアンカー](https://postext.dev/ja/docs/comics.md#話者とアンカー)を参照）。
- **設定**。**デザイン**パネルの**マンガ**グループに、読む方向、枠と間白、既定のコマとコマのスタイル、写植、吹き出しのスタイルがあり、それぞれにプレビューが付きます。
- **エディター**。テキストエディターは`:::page`、`::panel`、台本の行に色を付け、**検査**パネルは漫画の警告をその行の位置に一覧表示します。

## 漫画の警告

どの警告も対象の行か属性を示し、Sandboxの**検査**パネルは、1列目の題で警告をその位置に一覧表示します。

| 警告 | 原因 | 対処 |
| --- | --- | --- |
| コマ割りを読めない `comicSplitSyntax` | `split`の値の全体を読めません。余計な文字、閉じていない`[`、1つの並びでの`/`と`\|`の混在、親と同じ向きの角かっこの並びなどです。読める部分が使われ、まったく読めない値ではコマが1つになります。 | [文法](https://postext.dev/ja/docs/comics.md#ページの分割)に照らして値を直します。1つの並びに区切りは1種類だけで、向きを変えるには角かっこを使います。 |
| コマのサイズが100%を超えている `comicSplitOverflow` | 1つの並びのサイズの合計が100%を超えています。各`*`に5%を残して縮められます。 | サイズを小さくするか、1つを`*`に置き換えます。 |
| コマの数と割りの数が合わない `comicPanelCount` | ページの`::panel`の行が割り方の区画より多い（余ったコマは組まれません）か、少ない（最後の区画が空のまま残ります）。 | 割り方の区画か、台本のコマを増やすか減らします。空の`::panel`の行を置けば、意図して空の区画を作れます。 |
| 台本の行になっていない文字 `comicStrayText` | 最初の`::panel`の行より前にある文字か、`key:`がなく上の行の続きでもない行です。ナレーションとして写植されます。 | 行をキー（`caption:`、`maya:`）で始めるか、スペース2つで字下げして上の吹き出しの続きにします。 |
| 不明なフキダシのスタイル `comicUnknownBalloonStyle` | 行が波かっこの中で指定したスタイルが、組み込みのスタイルにも`comics.balloonStyles`にもありません。多くは綴りの間違いです（`{wisper}`）。その行はキーのスタイルを使います。 | 名前を直すか、スタイルを`comics.balloonStyles`に加えます。 |
| コマの絵が見つからない `comicUnknownArt` | コマの`art`か`pop`が指すリソースがないか、ビットマップでもSVGでもないリソースを指しています。コマは空のまま描かれます。 | IDを直すか、絵を本のリソースに加えます。 |
| 絵がコマに全体表示されている `comicPanelLetterbox` | 区画の比率が絵の比率から離れすぎていて、その形のどのトリミングにもセーフエリア全体が収まりません。そのため絵はセーフエリア全体が見えるように、コマの背景色の帯に挟まれて表示されます。 | 割り線を動かして区画の比率を変える（Sandboxはドラッグ中にそうなる位置に印を付けます）、セーフエリアを小さく描き直す、または別の絵を使います。 |
| 話し手の位置がセーフエリアの外 `comicAnchorOutsideSafeArea` | 絵のアンカーがセーフエリアの外にあります。トリミングで話者が切られることがあり、そのときしっぽはコマの外を指します。 | セーフエリアを広げて口を含めるか、アンカーを動かします。話者がときどきコマの外に出るのが意図どおりなら、直す必要はありません。 |
| フキダシが収まらない `comicBalloonOverflow` | どの代わりの手段を試しても、吹き出しが顔、ほかの吹き出し、回避エリア、口のどれかを覆うか、コマからはみ出します（`break`や`at=`の固定で求めた越境は数えません）。警告はそのコマと、覆っているものを示します。Sandboxで吹き出しをドラッグしている間は、覆うことになる顔や回避エリア、越えることになる枠線が、離す前に表示されます。 | 行を短くするか2つに分ける、コマを広げる、`at=`で吹き出しを固定する、または`break`で枠線を越えさせます。文字が小さくされることはありません。 |
| 位置のない話し手 `comicUnknownSpeaker` | ページのどの絵もアンカーで指定しておらず、登場人物にもいない話者のキーで、多くはキーの綴り間違いです。しっぽはコマの外を指します。アンカーを持つ絵のあるページでだけ出る、情報としての警告です。 | キーを直すか、絵に話者を指定するか、一度も描かれない話者なら`comics.cast`に加えます。 |

警告は、対象の行か属性のソース範囲とともに、文書の`contentWarnings`に返ります（[設定 › 文書の中の警告](https://postext.dev/ja/docs/configuration.md#文書の中の警告)を参照）。

吹き出しのスタイルの`shape: 'ovl'`や`readingDirection: 'rlt'`のように、いくつかの語のうち1つを取る漫画の設定に別の値が入っていると、その設定は既定値として読まれ、**検査**パネルに**不明な設定値**（`unknownConfigValue`）として、エンジンが使った値と最も近い語とともに表示されます。検査する設定は、`readingDirection`、`artDirection`、コマのスタイルの`borderStyle`と`fit`、写植の`writingMode`、`textTransform`、`dropFinalStop`、`joinSameSpeaker`、吹き出しのスタイルの`shape`、`tail`、`target`、`position`、`align`、`textTransform`です。

## プログラムからの利用

漫画に必要なのは`buildDocument`だけです。リソースが絵とそのセーフエリア、アンカー、回避エリアを持ち、設定が必要に応じて`comics`を持ちます。写植は読み込んだフォントで文字を測るので、ほかの書体と同じく、写植の書体はレイアウトの前に読み込んでおく必要があります。`comicFontFamilies(config, markdown)`は文書の漫画に必要な書体（写植の書体と、すべての吹き出しのスタイルと登場人物の書体）を一覧にし、`markdownHasComics(markdown)`はテキストに漫画のページか帯漫画があるかどうかを返します。PDFでは、フォントプロバイダーがほかの書体と同じようにそれらの書体を求められます。

組まれた漫画はVDTにあります。`page.comic`（`VDTComicPage`）は、枠、読む方向、読む順に並んだコマ（多角形、枠線、背景、`art.source`と`art.box`としての絵のトリミング）、割り線（書き込み先の`split`の値のソース範囲付き）、吹き出し（輪郭のパス、テキストのブロック、しっぽの先、種類、話者）を持ちます。割り方の文法はエディターのためにエクスポートされています。`parseComicSplit`、`serializeComicSplit`、`moveComicSplitLine`、`splitComicCell`、`mergeComicCells`は`split`の値を読み、書き換え、できるかぎりその中の`*`を保ちます。`comicArtCrop`と`comicCropFeasibleRange`はトリミングを計算し、`comicArtPointToPage`は絵の上の点をページ上に写します。

## 既知の制限

- **割り方は木だけ**。割り方は各区画を、区画を横切る線で2つに分けるので、ページ全体を横切る線のないレイアウトは書けません。たとえば、5つ目のコマの周りを4つのコマが風車のように囲む形です。そうしたレイアウトでやりたいことの多くは、乗せゴマと枠からはみ出す絵で表せます。
- **コマの形**。コマは凸多角形です。円形やぎざぎざのコマ、枠線のないぼかしのコマ、回転や拡大をした絵、スピード線は、Postextではなく絵の中に描きます。
- **写植**。右から左に読む親文字にはルビを付けず、そのほかの注記は吹き出しの中ではプレーンテキストとして印字されます。配置はコマごとに行います。しっぽの交差はコストで避けるだけで、互いを迂回する経路は引かず、コマからコマへの流れの釣り合いも取りません。ごく小さな区画の長いセリフは報告するだけで、解決はしません。指定のない顔の保護枠は口と頭の点から大きさを決める（アンカーに頭がなければ数em）ので、顔のアップでは顔全体より口を守ることがあります。顔を指定してください。
- **帯漫画**は、ページ全体に満たない数の段にまたがることはできず（3段のページで`columns=2`）、章の最上位でだけ読まれます（囲み、表、脚注の中では読まれません）。帯漫画のキャプションの中の文献の引用は、書いたとおりに印字されます。
- **見開き**。ノドで切られた角丸のコマは、丸い角をすべて失います。左綴じの本に入れた右から左に読む漫画も左ページから始まるので、最初のコマが見開きの2ページ目に来ます。
- **枠からはみ出す絵**はコマの絵のトリミングを使うので、切り抜きは絵と同じ大きさでなければなりません。
- **出力**。`alt`も`altText`もないコマの代替テキストは、英語の「Panel N」です。領域ベースのナビゲーションは、斜めのコマをその外接矩形で表します。Kindleのパネルビューはページの漫画をコマの数だけ複製するのでファイルが大きくなり、Kindle Previewerでの確認はまだです。

## 出典

- Nate Piekos、[*Comic Book Grammar & Tradition*](https://blambot.com/pages/comic-book-grammar-tradition)（Blambot）：吹き出しの種類、ナレーション、強調、ダブルダッシュ。
- John RoshellとComicraft、[*Balloon Tales*](https://balloontales.com/creating-tails-and-joins/)：しっぽと連結、および輪郭を引いてから塗る[レイヤー法](https://balloontales.com/the-layer-method/)。
- Todd Klein、[*Digital lettering for comics*](https://kleinletters.com/Blog/digital-lettering-for-comics/)。
- David Kurlander、Tim Skelly、David Salesin、[*Comic Chat*](https://kurlander.net/DJ/Pubs/SIGGRAPH96.pdf)、SIGGRAPH 96：読む順に沿った吹き出しの配置。
- IDPF、[*EPUB Region-Based Navigation 1.0*](https://idpf.org/epub/renditions/region-nav/epub-region-nav.html)、Amazon KDP、[Kindle Panel View](https://kdp.amazon.com/en_US/help/topic/G9GSTY4LTRT39D4Z)。
