# 機能設計書 8-LiterateCoffeeScript対応

## 概要

本ドキュメントは、Markdownスタイルのリテラルドキュメント内のコードブロックを抽出してコンパイルする機能について、その処理内容、入出力仕様、およびコードリーディングガイドを記載したものである。

### 本機能の処理概要

Literate CoffeeScript対応機能は、Markdown形式で記述されたドキュメント（.litcoffee, .coffee.md）から、インデントされたコードブロックを抽出し、通常のCoffeeScriptとしてコンパイルする機能である。

**業務上の目的・背景**：Literate Programming（文芸的プログラミング）のスタイルでは、コードとドキュメントを一体化して記述する。Markdownドキュメントの中に説明文とコードを混在させることで、可読性の高いコード・ドキュメントを作成できる。この機能により、Markdownファイルを直接コンパイル可能になる。

**機能の利用シーン**：技術ドキュメントとコードを一体化したい場合、教育用教材の作成時、ライブラリのドキュメント付きソースコード作成時、ブログ記事内のコード例を実行可能にしたい場合に利用される。

**主要な処理内容**：
1. ファイル拡張子による自動検出（.litcoffee, .coffee.md）
2. Markdownテキストの解析
3. インデントされたコードブロックの抽出
4. 非コード部分のコメント化
5. 通常のCoffeeScriptとしてコンパイル

**関連システム・外部連携**：Markdownパーサー（軽量実装）、Lexer

**権限による制御**：特になし（すべてのユーザーが利用可能）

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 3 | テストスイート | 補助機能 | text/x-literate-coffeescriptタイプのテストコードに対応 |
| 17 | Annotated Source - Helpers | 補助機能 | invertLiterate関数の解説を含む |
| 32 | Annotated Source - Helpers | 補助機能 | invertLiterate関数の解説を含む（v2） |

## 機能種別

計算処理 / テキスト変換

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| code | string | Yes | Literate CoffeeScriptソース | 文字列であること |
| options.literate | boolean | No | 強制的にLiterate処理（自動検出時は不要） | - |
| filename | string | No | ファイル名（拡張子で自動検出） | - |

### 入力データソース

- .litcoffeeファイル
- .coffee.mdファイル
- options.literate=true指定の文字列

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| code | string | 変換後のCoffeeScriptコード（非コード部分はコメント化） |

### 出力先

- Lexerの入力として渡される

## 処理フロー

### 処理シーケンス

```
1. Literate判定
   └─ 拡張子またはオプションで判定

2. invertLiterate呼び出し
   └─ Markdown→CoffeeScript変換

3. 行ごとの解析
   ├─ 空行: そのまま保持
   ├─ リスト項目開始: コメント化開始
   ├─ インデント行: コードとして保持
   └─ その他: コメント化

4. 結合
   └─ 変換後の行を結合

5. 通常コンパイル
   └─ Lexerに渡す
```

### フローチャート

```mermaid
flowchart TD
    A[開始: Literate判定] --> B{literate?}
    B -->|No| C[通常処理続行]
    B -->|Yes| D[invertLiterate呼び出し]
    D --> E[行分割]
    E --> F{次の行あり?}
    F -->|No| K[行結合]
    F -->|Yes| G{行タイプ判定}
    G -->|空行| H[そのまま保持]
    G -->|リスト項目| I[コメント化 + insideComment=true]
    G -->|インデント & !insideComment| J[コードとして保持]
    G -->|その他| I
    H --> F
    I --> F
    J --> F
    K --> L[CoffeeScript処理続行]
    L --> M[終了]
    C --> M
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | インデント=コード | 4スペースまたは1タブでインデントされた行はコード | 常時 |
| BR-02 | リスト項目検出 | `*`, `-`, `+` または数字+ピリオドで始まる行はリスト | 常時 |
| BR-03 | リスト内はコメント | リスト項目開始後はインデントでもコメント扱い | リスト内 |
| BR-04 | 空行でリスト終了 | 空行でリストコンテキストをリセット | 空行検出時 |
| BR-05 | 自動拡張子検出 | .litcoffee, .coffee.md は自動でLiterate処理 | ファイル指定時 |

### 計算ロジック

**インデント検出正規表現**:
```coffeescript
indented = /^[\t ]/
```

**リスト項目検出正規表現**:
```coffeescript
listItemStart = /^(?:\t?|\ {0,3})(?:[\*\-\+]|[0-9]{1,9}\.)[\ \t]/
```

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

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

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| SyntaxError | 構文エラー | 抽出後のコードが不正 | コードブロックを修正 |

### リトライ仕様

リトライは行わない

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

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

## パフォーマンス要件

- O(n)の時間計算量（ファイルサイズに比例）
- 追加のオーバーヘッドは軽微

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

- 入力ファイルの内容チェックなし

## 備考

- Literate CoffeeScriptはCoffeeScript本体のソースでも使用されている
- sourcemap.litcoffee, scope.litcoffee等

---

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

本機能を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

まず、Literate CoffeeScriptの入出力形式を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | sourcemap.litcoffee | `src/sourcemap.litcoffee` | 実際のLiterate CoffeeScriptファイルの例として確認 |

**読解のコツ**: Markdownの通常テキストと、インデントされたコードブロックの区別を理解する。

#### Step 2: エントリーポイントを理解する

Literate判定と変換呼び出しを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | helpers.coffee | `src/helpers.coffee` | `isLiterate`関数（207行目）で拡張子判定 |
| 2-2 | lexer.coffee | `src/lexer.coffee` | `clean`メソッド（113行目）でinvertLiterate呼び出し |

**主要処理フロー**:
1. **207行目（helpers）**: `.litcoffee`または`.coffee.md`で判定
2. **113行目（lexer）**: `@literate`フラグがtrueならinvertLiterate実行

#### Step 3: 変換処理を理解する

invertLiterate関数の詳細を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | helpers.coffee | `src/helpers.coffee` | `invertLiterate`関数（67-92行目） |

**主要処理フロー**:
- **68行目**: 出力配列初期化
- **69行目**: 空行判定用正規表現
- **70行目**: インデント判定用正規表現
- **71-78行目**: リスト項目開始判定用正規表現
- **79行目**: insideCommentフラグ初期化
- **80-91行目**: 各行の処理ループ
- **92行目**: 結果結合

#### Step 4: 行タイプ別処理を理解する

各行タイプの処理を詳細に理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | helpers.coffee | `src/helpers.coffee` | 80-91行目の条件分岐 |

**主要処理フロー**:
- **81-83行目**: 空行 → そのまま保持、insideComment=false
- **84-86行目**: insideCommentまたはリスト項目 → コメント化
- **87-88行目**: インデント行 → コードとして保持
- **89-91行目**: その他 → コメント化

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

```
CoffeeScript.compile (coffeescript.coffee:62)
    │
    └─ lexer.tokenize (lexer.coffee:37)
           │
           └─ clean (lexer.coffee:97)
                  │
                  └─ [literate=true時]
                         │
                         └─ invertLiterate (helpers.coffee:67)
                                │
                                ├─ blankLine.test (空行判定)
                                │
                                ├─ listItemStart.test (リスト判定)
                                │
                                ├─ indented.test (インデント判定)
                                │
                                └─ "# #{line}" (コメント化)
```

### データフロー図

```
[入力]                    [処理]                           [出力]

Literate CoffeeScript
```markdown
# Example

This is a description.

    x = 1
    y = 2

More text.
```
       │
       ▼
  invertLiterate
       │
       ▼
[出力]
```coffeescript
# # Example
#
# This is a description.
#
    x = 1
    y = 2
#
# More text.
```
       │
       ▼
  通常のLexer処理
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| helpers.coffee | `src/helpers.coffee` | ソース | invertLiterate, isLiterate関数 |
| lexer.coffee | `src/lexer.coffee` | ソース | Literate判定とinvertLiterate呼び出し |
| sourcemap.litcoffee | `src/sourcemap.litcoffee` | サンプル | Literate CoffeeScriptの実例 |
| scope.litcoffee | `src/scope.litcoffee` | サンプル | Literate CoffeeScriptの実例 |
