# 帳票設計書 8-Notebook Cell Output Copy

## 概要

本ドキュメントは、VS CodeのNotebook機能におけるセル出力のコピー・保存機能の帳票出力仕様を定義するものである。

### 本帳票の処理概要

Notebook Cell Output Copyは、JupyterノートブックやInteractive Window等のセル出力（テキスト、画像等）をクリップボードにコピーまたはファイルに保存する機能である。

**業務上の目的・背景**：データサイエンティストや開発者がノートブックのセル実行結果を他のドキュメントやツールで再利用するために使用される。出力結果の共有、レポート作成、デバッグ情報の保存等に活用される。

**帳票の利用シーン**：
- セル出力ツールバーの「Copy Cell Output」ボタンをクリック
- セル出力ツールバーの「Save Image」ボタンをクリック（画像出力の場合）
- コンテキストメニューからのコピー/保存操作

**主要な出力内容**：
1. テキスト出力（プレーンテキスト、JSON、HTML等）
2. 画像出力（PNG、JPEG、SVG等）

**帳票の出力タイミング**：ユーザーがコピー/保存アクションを実行した際。

**帳票の利用者**：VS Codeユーザー、データサイエンティスト、開発者

## 帳票種別

セル出力コピー / 画像保存

## 利用画面

| 画面No | 画面名 | URL/ルーティング | 出力操作 |
|--------|--------|-----------------|---------|
| - | Notebook Editor | - | Copy Cell Output ボタン |
| - | Notebook Editor | - | Save Image ボタン |

## 出力形式

### 基本仕様（コピー）

| 項目 | 内容 |
|-----|------|
| 出力先 | システムクリップボード |
| テキスト形式 | プレーンテキスト |
| 画像形式 | クリップボード画像データ |
| 文字コード | UTF-8 |

### 基本仕様（画像保存）

| 項目 | 内容 |
|-----|------|
| ファイル形式 | PNG, JPEG, SVG, WebP, BMP, TIFF, GIF |
| デフォルトファイル名 | `image.{extension}` |
| 出力方法 | ファイルダイアログ経由 |

### MIME Type対応

| MIME Type | 拡張子 | 説明 |
|-----------|-------|------|
| image/png | .png | PNG画像 |
| image/jpeg, image/jpg | .jpg | JPEG画像 |
| image/gif | .gif | GIF画像 |
| image/svg+xml | .svg | SVG画像 |
| image/webp | .webp | WebP画像 |
| image/bmp | .bmp | BMP画像 |
| image/tiff | .tiff | TIFF画像 |

## 帳票レイアウト

### レイアウト概要

セル出力の形式に応じてコピーまたは保存される内容が決定される。

### コピー対象データ

| No | MIME Type | 出力形式 | 処理 |
|----|-----------|---------|------|
| 1 | image/* | 画像データ | クリップボードに画像として貼り付け |
| 2 | text/plain | プレーンテキスト | クリップボードにテキストとして貼り付け |
| 3 | application/json | JSONテキスト | クリップボードにテキストとして貼り付け |
| 4 | text/html | HTMLテキスト | クリップボードにテキストとして貼り付け |
| 5 | その他 | バイナリデータ | Base64デコード後テキスト |

### 保存対象データ（画像のみ）

| No | 条件 | 保存データ | ファイル形式 |
|----|------|----------|------------|
| 1 | MIME Typeがimage/*で開始 | outputItem.data | MIME Typeに対応する拡張子 |

## 出力条件

### コピー条件

| 条件名 | 説明 | 必須 |
|-------|------|-----|
| 出力存在 | セルに出力が存在する | Yes |
| MIME Type選択済み | pickedMimeTypeが設定されている | No |
| 信頼済み出力 | isTrustedがtrue | No（フォールバック使用） |

### 画像保存条件

| 条件名 | 説明 | 必須 |
|-------|------|-----|
| MIME Typeがimage/* | 画像形式のMIME Type | Yes |
| outputItem存在 | 出力アイテムが存在 | Yes |

### 改ページ条件

N/A（クリップボード/単一ファイル出力のため）

## データベース参照仕様

### 参照テーブル一覧

| テーブル名 | 用途 | 結合条件 |
|-----------|------|---------|
| N/A | メモリ内出力データを直接取得 | - |

### データ取得元

#### ICellOutputViewModel

| 参照項目 | 帳票項目との対応 | 取得方法 | 備考 |
|---------|----------------|---------|------|
| pickedMimeType | MIME Type | ICellOutputViewModel | 選択されたMIME Type |
| model.outputs | 出力データ | ICellOutputViewModel | 出力アイテム配列 |
| model.outputId | 出力ID | ICellOutputViewModel | 識別子 |

## 計算仕様

### 計算項目一覧

| 項目名 | 計算式 | 端数処理 | 備考 |
|-------|-------|---------|------|
| テキストデコード | VSBuffer.wrap(data).toString() | - | バイナリ→テキスト変換 |

## 処理フロー

### コピーフロー

```mermaid
flowchart TD
    A[Copy Cell Outputアクション] --> B[notebookEditor取得]
    B --> C[outputViewModel取得]
    C --> D{outputViewModel存在?}
    D -->|No| E[アクティブセルから取得]
    D -->|Yes| F[mimeType取得]
    E --> F
    F --> G{mimeType開始がimage/?}
    G -->|Yes| H[focusNotebookCell]
    H --> I[copyOutputImage]
    G -->|No| J[copyCellOutput]
    J --> K[clipboardService.writeText]
    I --> L[完了]
    K --> L
```

### 画像保存フロー

```mermaid
flowchart TD
    A[Save Imageアクション] --> B[notebookEditor取得]
    B --> C[outputViewModel取得]
    C --> D{mimeTypeがimage/*?}
    D -->|No| E[処理終了]
    D -->|Yes| F[outputItem取得]
    F --> G{outputItem存在?}
    G -->|No| H[エラーログ]
    G -->|Yes| I[拡張子決定]
    I --> J[デフォルトURI構築]
    J --> K[showSaveDialog]
    K --> L{ユーザー選択}
    L -->|キャンセル| M[処理終了]
    L -->|保存先選択| N[fileService.writeFile]
    N --> O[成功ログ]
```

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 表示メッセージ | 対処方法 |
|----------|---------|--------------|---------|
| 出力なし | outputViewModelが取得できない | (処理中断) | セル出力を確認 |
| MIME Type不一致 | 画像保存時にimage/*でない | (処理中断) | 画像出力を選択 |
| outputItem不存在 | 指定MIME Typeの出力がない | "Could not find output item with mime type" | - |
| 保存失敗 | ファイル書き込みエラー | "Failed to save image output" | 保存先確認 |

## パフォーマンス要件

| 項目 | 内容 |
|-----|------|
| 想定データ件数 | 1出力/操作 |
| 目標コピー時間 | 100ms以内 |
| 目標保存時間 | 1秒以内 |

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

- 信頼されていない出力はisTrustedフラグで識別
- クリップボードへのアクセスはユーザーアクション起点
- ファイル保存はダイアログ経由でユーザー確認あり

## 備考

- コピーコマンドID: `notebook.cellOutput.copy`
- 保存コマンドID: `notebook.cellOutput.saveImage`
- 画像コピー時はfocusNotebookCellでフォーカス設定が必要
- メニュー表示条件はNOTEBOOK_CELL_HAS_OUTPUTS, NOTEBOOK_CELL_OUTPUT_MIMETYPEで制御

---

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

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

### 推奨読解順序

#### Step 1: アクション定義を理解する

コピー/保存アクションの定義を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | cellOutputActions.ts | `src/vs/workbench/contrib/notebook/browser/controller/cellOutputActions.ts` | COPY_OUTPUT_COMMAND_ID (行26) |
| 1-2 | cellOutputActions.ts | `src/vs/workbench/contrib/notebook/browser/controller/cellOutputActions.ts` | SAVE_OUTPUT_IMAGE_COMMAND_ID (行182) |

**読解のコツ**: コマンドIDとメニュー表示条件（when句）を確認。

#### Step 2: コピー処理を理解する

コピー処理の実装を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | cellOutputActions.ts | `src/vs/workbench/contrib/notebook/browser/controller/cellOutputActions.ts` | CopyCellOutputAction (行56-96) |
| 2-2 | cellOutputTextHelper.ts | `src/vs/workbench/contrib/notebook/browser/viewModel/cellOutputTextHelper.ts` | copyCellOutput()関数 |

**主要処理フロー**:
- **行70-94**: run()メソッドで条件分岐
- **行87-90**: 画像の場合はfocusNotebookCell + copyOutputImage
- **行92**: テキストの場合はcopyCellOutput

#### Step 3: 画像保存処理を理解する

画像保存の実装を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | cellOutputActions.ts | `src/vs/workbench/contrib/notebook/browser/controller/cellOutputActions.ts` | SaveCellOutputImageAction (行184-267) |

**主要処理フロー**:
- **行214-220**: MIME Type検証
- **行229-240**: mimeToExt マッピング
- **行247-253**: showSaveDialog
- **行259-262**: fileService.writeFile

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

```
Copy Cell Output コマンド (notebook.cellOutput.copy)
    │
    └─ CopyCellOutputAction.run()
           │
           ├─ getNotebookEditorFromContext()
           │
           ├─ getOutputViewModelFromContext()
           │
           └─ 条件分岐
                  │
                  ├─ [image/*] notebookEditor.copyOutputImage()
                  │
                  └─ [その他] copyCellOutput()
                         │
                         └─ clipboardService.writeText()

Save Image コマンド (notebook.cellOutput.saveImage)
    │
    └─ SaveCellOutputImageAction.run()
           │
           ├─ getNotebookEditorFromContext()
           │
           ├─ getOutputViewModelFromContext()
           │
           ├─ mimeType検証 (image/*のみ)
           │
           ├─ 拡張子決定 (mimeToExtマッピング)
           │
           ├─ fileDialogService.showSaveDialog()
           │
           └─ fileService.writeFile()
```

### データフロー図

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

ICellOutputViewModel ┌─────────────────────┐
                     │                     │
  ─────────────────▶│ CopyCellOutput      │──────▶ クリップボード
                     │   Action            │        (テキスト or 画像)
                     │                     │
                     └─────────────────────┘

ICellOutputViewModel ┌─────────────────────┐
                     │                     │
  ─────────────────▶│ SaveCellOutput      │──────▶ image.{ext}
                     │   ImageAction       │        (画像ファイル)
                     │                     │
                     └─────────────────────┘
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| cellOutputActions.ts | `src/vs/workbench/contrib/notebook/browser/controller/cellOutputActions.ts` | ソース | アクション定義 |
| cellOutputTextHelper.ts | `src/vs/workbench/contrib/notebook/browser/viewModel/cellOutputTextHelper.ts` | ソース | テキストコピーヘルパー |
| notebookBrowser.ts | `src/vs/workbench/contrib/notebook/browser/notebookBrowser.ts` | ソース | ノートブックエディタインターフェース |
| notebookContextKeys.ts | `src/vs/workbench/contrib/notebook/browser/common/notebookContextKeys.ts` | ソース | コンテキストキー定義 |
| coreActions.ts | `src/vs/workbench/contrib/notebook/browser/controller/coreActions.ts` | ソース | コアアクション定義 |
