﻿# 08. 入力解読仕様（Ohyna Markdown 1.0）

版: **1.0.0**  

**Ohyna Markdown 1.0** の入力契約です。関連: [03-文書設定リファレンス.md](./03-文書設定リファレンス.md)、[09-出力仕様.md](./09-出力仕様.md)、[10-準拠仕様マップ.md](./10-準拠仕様マップ.md)。

Ohyna Markdown は Markdown を基礎とした製品プロファイルです。受理する入力の契約をここに置きます。

---

## 1. 処理パイプライン（順序固定）

画面からのプレビュー／PDF 作成における本文解読順:

| 順 | 段階 | 内容 |
|----|------|------|
| 1 | BOM（U+FEFF）除去 | 先頭のバイト順マークを除く |
| 2 | front matter 分離・正規化 | ドキュメント設定ブロックの解釈（YAML 不正はエラー） |
| 3 | 本文整形 | 製品既定の整形 |
| 4 | エンジン用フェンス退避・正規化 | 図・数式フェンスの退避、`mermaid code` の扱い |
| 5 | Markdown → HTML | 製品の参照変換（拡張は §4） |
| 6 | HTML サニタイズ | 利用者由来の断片から危険なマークアップを除去 |
| 7 | `<details>` を展開表示 | 折りたたみは常に開いた状態で出力 |
| 8 | 数式・図の埋め込み | 製品レンダラの出力を差し込み（サニタイズ後） |
| 9 | 見出しの改ページ配慮 | 見出し直後の本文が孤立しにくいようグループ化（[09](./09-出力仕様.md)） |

静的解析は変換の前段ゲートです。error が 0 件のとき、画面のプレビュー更新と PDF 作成が進みます（[10](./10-準拠仕様マップ.md)）。

---

## 2. Front matter

### 2.1 文法

1. 任意個の先頭 HTML コメント（`<!-- ... -->`、前後空白可）を除去する。
2. 残り文字列が次の正規表現に一致したときだけ front matter とみなす:

```
\A---[ \t]*\r?\n(.*?)\r?\n---[ \t]*(?:\r?\n|$)
```

3. キャプチャした YAML を参照実装 `yaml.safe_load`（YAML 1.1 系）で読む。
4. 結果はオブジェクト（mapping）でなければならない。`null` のみのとき設定は空、本文は閉じ `---` 以降。
5. **区切りに一致したうえで YAML 構文エラー、または非オブジェクトのときは `FrontmatterError`。**
6. 区切りが無いときは front matter なし（本文＝全体）。静的解析では error（`SETTINGS_MISSING_FM`）。

型の暗黙変換（例: YAML 1.1 の `yes`/`on`）に注意し、真偽値は `true`/`false`、文字列は引用を推奨します。意味の検証は [03](./03-文書設定リファレンス.md) のスキーマに従います。

### 2.2 名前空間

- 有効な設定はトップレベルキー `ohyna:`（オブジェクト）のみ。
- その他のトップレベルキーは保持する。意味は本製品では解釈しない。

必須キー・列挙値・マージ規則は [03](./03-文書設定リファレンス.md) に従う。

---

## 3. コードフェンス（Ohyna Fence Grammar）

フェンスの判定は本節の規則が契約です。一般的な Markdown 処理系と差がある場合も、**本節を優先**します。

### 3.0 info 文字列

```text
info ::= language argument*
```

| 項目 | 規則 |
|------|------|
| 行頭インデント | スペース 0〜3 |
| 開き | `` ` `` または `~` が 3 つ以上 + info |
| `language` | info を空白分割した先頭。比較時は ASCII 小文字へ正規化 |
| `argument*` | 先頭以降のトークン（同様に小文字化）。Mermaid の `code` が正式 |
| 閉じ | 同じ文字種・長さ以上・info 空 |

### 3.1 Mermaid ダイアグラムフェンス

次をすべて満たすとき図ノードとする（`is_mermaid_diagram_fence`）:

1. マーカーが backtick（`` ` ``）
2. 言語トークンが正確に `mermaid`
3. 追加トークンが無い

正しい形:

````markdown
```mermaid
flowchart LR
  A --> B
```
````

出力上の形は [09](./09-出力仕様.md) §6。

### 3.2 Mermaid コードフェンス

次をすべて満たすとき、Mermaid 文法でハイライトした**通常のコードブロック**とする:

1. マーカーが backtick
2. 言語トークンが `mermaid`
3. 追加トークンが正確に `code` の 1 個だけ

正しい形:

````markdown
```mermaid code
flowchart LR
  A --> B
```
````

変換時は Language Registry 識別子 `mermaid-code` へ正規化してから本文パーサへ渡す。  
本文の Mermaid 構文は図と同様に検証する（不正なら `MERMAID_CODE_SYNTAX`）。構文例をプレーンテキストとして示すときは `text` フェンスを使います。

### 3.3 Mermaid の追加トークン

`` ```mermaid `` に `code` 以外の追加トークンがあるとき、静的解析 error（`MERMAID_FENCE_MODE`）。

図と `mermaid code` は backtick マーカーで開きます。

### 3.4 数式フェンス

次をすべて満たすときディスプレイ数式ノードとする（`is_math_fence`）:

1. マーカーが backtick
2. 言語トークンが `math` / `latex` / `katex` / `tex` / `stex` のいずれか
3. 追加トークンが無い

正しい形:

````markdown
```math
E = mc^2
```
````

出力上の形は [09](./09-出力仕様.md) §7。

### 3.5 その他のフェンス（Language Registry）

言語識別子は **Ohyna Language Registry** に登録された値です。  
参照実装では Pygments lexer（および製品エイリアス・`mermaid-code` Lexer）で解決する。未解決は静的解析 error（`LANG_UNKNOWN`）。

編集画面は同じ Registry のうちよく使う言語を色分けします。成果物側で解釈できる識別子は PDF／プレビューで色分けされます。

空の JSON / YAML フェンス、未閉じフェンスは静的解析 error。

---

## 4. Markdown 拡張（参照実装）

受理構文の参照実装における拡張セット:

| 拡張 | 設定 |
|------|------|
| tables, sane_lists, footnotes, attr_list, def_list, abbr, admonition, smarty | 既定 |
| toc | `permalink: false` |
| pymdownx.betterem, tilde, mark, caret | 既定 |
| pymdownx.magiclink | `hide_protocol: false`, `repo_url_shortener: false` |
| pymdownx.tasklist | `custom_checkbox: true` |
| pymdownx.details | 既定（出力時は常に `open`。プレビューでも開閉固定） |
| pymdownx.highlight | `pygments_lang_class: true`, `css_class: highlight` |
| pymdownx.superfences | 既定 |
| pymdownx.arithmatex | `generic: true`、インライン `\(`/`\)`、ブロック `\[`/`\]` |

HTML ブロックはそのまま HTML として扱います。

キーボードキーは HTML `<kbd>`（許可タグ）です。

例:

```markdown
保存は <kbd>Ctrl</kbd>+<kbd>S</kbd> です。
```

---

## 5. インライン数式（KaTeX）

フェンス外で次を数式とする（auto-render と解析の双方）:

| 区切り | モード |
|--------|--------|
| `$...$` | インライン |
| `$$...$$` | ディスプレイ |
| `\(...\)` | インライン |
| `\[...\]` | ディスプレイ |

| フェーズ | 設定 | 目的 |
|----------|------|------|
| レンダリング | `throwOnError: false`, `strict: "ignore"`, `trust: false` | 診断位置とエラー内容の回収（recovery） |
| 製品検証 | 出力に `katex-error` があれば error（`KATEX_RENDER`） | `validationPolicy = reject` |

---

## 6. 画像パス（本画面）

本画面から参照する画像:

| 項目 | 扱い |
|------|------|
| `http` / `https` / `data:` | 受理（PDF 化時は製品が許す通信先） |

組織が別経路（バッチ等）を用意している場合の画像解決は、その提供者の案内に従ってください。

---

## 7. 静的解析診断

各診断は次のフィールドを持つ:

| フィールド | 内容 |
|------------|------|
| `severity` | `error` / `warning` / `info` |
| `message` | 人間向け文言 |
| `line` | 1-based（分かるとき） |
| `category` | `settings` / `yaml` / `markdown` / `syntax` / `mermaid` / `katex` / `engine` |
| `code` | 安定 ID（機械可読） |

ゲート: `severity === "error"` が 0 件のとき、画面のプレビュー更新と PDF 作成が進みます。

編集中の即時チェックは近似です。列挙値の誤りなどは **error** として扱い、最終判定はサーバ側の静的解析です。

### 7.1 診断コード一覧（主要）

| code | category | 概要 |
|------|----------|------|
| `DOC_EMPTY` | markdown | 文書が空 |
| `FENCE_UNCLOSED` | markdown | フェンス未閉じ |
| `SETTINGS_MISSING_FM` | settings | front matter なし |
| `SETTINGS_*` | settings | 必須欠落・未知列挙など（[03](./03-文書設定リファレンス.md)） |
| `LANG_UNKNOWN` | syntax | Language Registry 未登録 |
| `JSON_EMPTY` / `JSON_SYNTAX` | syntax | JSON フェンス |
| `YAML_FENCE_EMPTY` / `YAML_FENCE_SYNTAX` | syntax | YAML フェンス |
| `MERMAID_FENCE_FORM` | mermaid | 図フェンスの形式（backtick・言語トークン） |
| `MERMAID_FENCE_MODE` | mermaid | `mermaid` の未知追加トークン |
| `MERMAID_EMPTY` | mermaid | 図フェンスが空 |
| `MERMAID_CODE_EMPTY` | mermaid | `mermaid code` が空 |
| `MERMAID_RENDER` | mermaid | 図の描画／構文失敗 |
| `MERMAID_CODE_SYNTAX` | mermaid | コード表示用ソースの構文失敗 |
| `MATH_FENCE_FORM` / `MATH_EMPTY` | katex | 数式フェンス形式 |
| `KATEX_RENDER` / `KATEX_BOOT` | katex | 数式検証失敗 |
