# 機能設計書：99-htmlgen（HTML生成マクロ）

## 1. 概要

### 本機能の処理概要
htmlgenモジュールは、HTMLおよびXMLコードを生成するためのマクロコレクションを提供する。各HTML/MathMLタグに対応するマクロが定義されており、Nimコード内でタグ名をそのまま関数として呼び出すことでHTML文字列を生成できる。属性の検証はコンパイル時に行われ、不正な属性名はエラーとなる。

### 関連画面
本機能は標準ライブラリのHTML生成ユーティリティであり、特定の画面には関連しない。Webアプリケーション開発でHTMLテンプレートの生成に使用される。

### 機能種別
ライブラリ機能（マクロ・コード生成・DSL）

## 2. 入力仕様

### 属性定数
```nim
const
  coreAttr*: string    # DOM Core属性（accesskey, class, id等）
  eventAttr*: string   # DOMイベント属性（onclick, onload等）
  ariaAttr*: string    # ARIA属性（role）
  commonAttr*: string  # 共通属性（coreAttr + eventAttr + ariaAttr）
```

### マクロシグネチャ（共通パターン）
```nim
macro tagName*(e: varargs[untyped]): untyped
```

### xmlCheckedTagプロシージャ
```nim
proc xmlCheckedTag*(argsList: NimNode, tag: string, optAttr = "",
                    reqAttr = "", isLeaf = false): NimNode
```

| パラメータ | 型 | 説明 |
|----------|-----|------|
| argsList | NimNode | 属性と子要素のリスト |
| tag | string | HTMLタグ名 |
| optAttr | string | オプション属性（スペース区切り） |
| reqAttr | string | 必須属性（スペース区切り） |
| isLeaf | bool | リーフ要素（自己終了タグ）かどうか |

## 3. 出力仕様

### 生成されるHTML形式

```html
<!-- 通常要素 -->
<tag attr="value">content</tag>

<!-- リーフ要素（isLeaf=true） -->
<tag attr="value" />
```

### サポートされるタグカテゴリ

| カテゴリ | タグ例 | 数 |
|---------|--------|---|
| 構造要素 | html, head, body, div, span | 多数 |
| テキスト要素 | h1-h6, p, a, em, strong | 多数 |
| フォーム要素 | form, input, button, select | 多数 |
| テーブル要素 | table, tr, td, th | 多数 |
| メディア要素 | img, video, audio | 多数 |
| MathML要素 | math, mrow, msup, mfrac | 多数 |

## 4. 処理フロー

### 4.1 xmlCheckedTag処理フロー

```
[xmlCheckedTag(argsList, tag, optAttr, reqAttr, isLeaf)]
    |
    v
[属性リスト準備]
    +-- req = splitWhitespace(reqAttr)
    +-- opt = splitWhitespace(optAttr)
    |
    v
[結果nnkBracket作成]
    +-- add "<"
    +-- add tag
    |
    v
[第1パス：属性処理]
    |
    +-- [nnkExprEqExpr検出]
    |       |
    |       v
    |   [属性名取得（getIdent）]
    |       |
    |       +-- [data-*] --> 許可
    |       +-- [req/optに存在] --> 許可・リストから削除
    |       +-- [存在しない] --> エラー
    |       |
    |       v
    |   [属性追加: " name=\"value\""]
    |
    v
[必須属性チェック]
    +-- [req.len > 0] --> エラー
    |
    v
[isLeaf判定]
    |
    +-- [true] --> [子要素禁止チェック] --> " />"追加
    |
    +-- [false]
            |
            v
        [第2パス：子要素処理]
            +-- ">"追加
            +-- 非属性ノードを追加
            +-- "</tag>"追加
    |
    v
[nestList(ident"&", result)]
    |
    v
[文字列結合式を返却]
```

### 4.2 getIdent処理

```
[getIdent(e)]
    |
    v
[e.kind判定]
    |
    +-- [nnkIdent] --> e.strVal.normalize
    |
    +-- [nnkAccQuoted] --> 各要素を結合
    |
    +-- [その他] --> エラー
```

## 5. ビジネスルール

### BR-01: 属性検証
タグに指定された属性はoptAttrまたはreqAttrに含まれている必要がある。ただし`data-*`属性は常に許可される。

### BR-02: 必須属性
reqAttrに指定された属性は必ず指定する必要がある。未指定の場合はコンパイルエラー。

### BR-03: リーフ要素
`isLeaf=true`のタグは子要素を持てない。子要素が指定された場合はコンパイルエラー。

### BR-04: 文字列結合最適化
生成されたHTML部品は`&`演算子で結合されるリストとして返され、コンパイル時に定数畳み込みが行われる。

### BR-05: バッククォート記法
Nimの予約語と衝突するタグ（div, var, template, object）はバッククォートで囲む。

### BR-06: MathMLサポート
HTML5準拠のMathMLタグがサポートされており、数式の視覚化が可能。

## 6. データベース操作仕様

本機能はデータベース操作を行わない。

## 7. エラー処理

### コンパイル時エラー

| 条件 | エラーメッセージ |
|-----|----------------|
| 無効な属性 | "invalid attribute for 'tag' element: name" |
| 必須属性未指定 | "attr attribute for 'tag' element expected" |
| リーフ要素に子要素 | "element tag cannot be nested" |
| 無効な識別子 | "cannot extract identifier from node: ..." |

## 8. トランザクション仕様

本機能はトランザクション処理を行わない。

## 9. パフォーマンス要件

### コンパイル時
- 属性検証はコンパイル時に完了
- 定数文字列は畳み込み最適化対象

### 実行時
- 動的な値のみ実行時に結合
- 静的なHTML部分は単一文字列リテラル化

## 10. セキュリティ考慮事項

### XSS対策
- 本モジュールは自動エスケープを行わない
- ユーザー入力を含む場合は手動でエスケープが必要

### 推奨事項
- ドキュメントに記載の通り、`from std/htmlgen import nil`でインポートし完全修飾で使用
- 本番環境ではKaraxなどの専用フレームワークの使用を検討

## 11. コードリーディングガイド

### 11.1 推奨される読み解き順序

1. **モジュールドキュメント**（10-41行目）
   - 使用方法と推奨事項
   - MathMLサポートの説明

2. **属性定数**（46-58行目）
   - coreAttr: DOM Core属性
   - eventAttr: イベントハンドラ属性
   - ariaAttr: ARIA属性
   - commonAttr: 上記の結合

3. **ヘルパー関数**（60-78行目）
   - getIdent: 識別子抽出
   - delete: リスト要素削除

4. **xmlCheckedTag**（80-119行目）
   - 属性検証ロジック
   - HTML文字列生成
   - リーフ要素処理

5. **HTMLタグマクロ**（121-617行目）
   - 各HTML5タグ対応マクロ
   - タグ固有属性の定義

6. **MathMLタグマクロ**（624-788行目）
   - 数学表記用タグ
   - mathbackground, mathcolor等の共通属性

### 11.2 プログラム呼び出し階層図

```
HTMLタグマクロ（a, div, h1等）
└── xmlCheckedTag(e, "tagname", optAttr, reqAttr, isLeaf)
    ├── getIdent(node)
    │   └── [nnkIdent] strVal.normalize
    │   └── [nnkAccQuoted] 再帰的結合
    ├── delete(seq, item)
    │   └── find → 削除 → true/false
    ├── [属性検証]
    │   ├── data-* → 常に許可
    │   ├── req/opt → 削除して許可
    │   └── その他 → error
    ├── [必須属性チェック]
    │   └── req.len > 0 → error
    └── nestList(ident"&", result)
        └── 文字列結合式生成
```

### 11.3 データフロー図

```
入力:
  a(href = "url", "Link Text")

解析:
  argsList = [
    nnkExprEqExpr(href, "url"),  # 属性
    "Link Text"                   # 子要素
  ]

処理:
  ┌─────────────────────────────────────┐
  │ xmlCheckedTag                        │
  │                                     │
  │ [第1パス] 属性処理                    │
  │   href → optAttrに存在 → 追加        │
  │   → " href=\"" & "url" & "\""      │
  │                                     │
  │ [第2パス] 子要素処理                  │
  │   "Link Text" → 追加                │
  │                                     │
  │ 結果組み立て:                        │
  │   "<" & "a" & " href=\"" & "url"    │
  │   & "\"" & ">" & "Link Text"        │
  │   & "</" & "a" & ">"                │
  └─────────────────────────────────────┘

出力:
  <a href="url">Link Text</a>
```

### 11.4 関連ファイル一覧

| ファイル | 役割 | 行数 |
|---------|------|------|
| lib/pure/htmlgen.nim | HTMLタグマクロの実装 | 815 |
| lib/core/macros.nim | NimNode操作（nestList等） | - |
| lib/pure/strutils.nim | splitWhitespace | - |

### 11.5 重要な実装詳細

#### 属性検証ロジック（92-102行目）
```nim
for i in 0 ..< argsList.len:
  if argsList[i].kind == nnkExprEqExpr:
    var name = getIdent(argsList[i][0])
    if name.startsWith("data-") or delete(req, name) or delete(opt, name):
      # 属性を追加
    else:
      error("invalid attribute for '" & tag & "' element: " & name, argsList[i])
```

`data-*`属性は常に許可。その他は必須/オプション属性リストから削除（存在確認）。

#### リーフ要素処理（106-110行目）
```nim
if isLeaf:
  for i in 0 ..< argsList.len:
    if argsList[i].kind != nnkExprEqExpr:
      error("element " & tag & " cannot be nested", argsList[i])
  result.add(newStrLitNode(" />"))
```

リーフ要素は子要素禁止で自己終了タグを生成。

#### nestListによる結合（119行目）
```nim
result = nestList(ident"&", result)
```

`[a, b, c]`を`a & b & c`形式の結合式に変換。コンパイル時定数畳み込みの恩恵を受ける。

### 11.6 サポートされる主要タグ

#### HTML5標準タグ
- 構造: html, head, body, div, span, section, article, aside, header, footer, nav, main
- テキスト: h1-h6, p, a, em, strong, code, pre, blockquote
- リスト: ul, ol, li, dl, dt, dd
- テーブル: table, thead, tbody, tfoot, tr, th, td
- フォーム: form, input, button, select, option, textarea, label
- メディア: img, video, audio, source, picture, canvas
- インライン: span, br, hr, wbr

#### MathML（624-788行目）
- コンテナ: math, mrow, semantics
- 数式要素: mi, mn, mo, ms, mtext
- レイアウト: mfrac, msqrt, mroot, msup, msub, msubsup, mover, munder, munderover
- テーブル: mtable, mtr, mtd
- その他: mspace, mpadded, mphantom, menclose, merror
