# Typst テンプレートのフォーム

独自の Typst 関数にフォームを付けると、レポートを書く人は、関数呼び出しの構文ではなく、ラベル付きのフィールドをビジュアルモードで目にします。

Typst のテンプレートには、表紙、情報ボックス、承認ブロックなど、独自の関数が付属していることがよくあります。レポートを書く人は、`#info-box(title: "Supply risk", tone: "risk")[...]` のようにそれを呼び出します。テンプレートを保守している場合は、各関数の引数を一度記述しておけます。すると、ビジュアルモードがその関数のすべての呼び出しをフォームとして表示します。ラベル付きのフィールド、固定の選択肢のためのリスト、はい / いいえのためのスイッチです。フィールドを編集すると、`.typ` ファイルのその 1 つの引数だけが書き換えられるので、レポートは普通の Typst ソースのままで、同じようにコンパイルされます。

## 読む人に見えるもの

単独の行に書かれた呼び出しは**カード**になります。カードのヘッダーには、フォームの名前と、指定した場合は、ボックスのタイトルのような短い要約が表示されます。各引数には、ラベルとコントロールのある行が付きます。

文の途中の呼び出し、たとえば `#badge("review")` は、テキストの行の中で**チップ**になります。チップをクリックすると、同じフィールドが小さなポップオーバーで開きます。

テキストのフィールドとマークアップのフィールドは、Enter（複数行のフィールドでは ⌘ Enter または Ctrl Enter）を押すか、フィールドから離れると保存されます。Esc を押すと、元の値に戻ります。リストとスイッチは、すぐに保存されます。変更はどれも、元に戻す操作 1 回分になります。

呼び出しの中にカーソルを移すと、ほかのビジュアルモードの要素と同じように、そのソースが表示されます。カードの**ソースで編集**でも同じことができます。

## フォームを宣言する場所

宣言できる場所は 2 つあり、形式は同じです。

- **パッケージの中。** パッケージの `typst.toml` に `[tool.oleafly]` セクションを追加します。Typst は `[tool.*]` セクションをほかのツール用に取っておくので、パッケージはどこでも変わらずインストールでき、コンパイルできます。これは `@local` パッケージと、Typst Universe の `@preview` パッケージで使えます。
- **プロジェクトの中。** プロジェクトの中に通常の `.typ` ファイルとして置いたテンプレートには、プロジェクトのルートに `oleafly-forms.toml` を作成します。この場合、各フォームは、関数を定義するファイルも `module` で指定します。

パッケージのフォーム:

```toml
[tool.oleafly]
schema = 1

[[tool.oleafly.forms]]
function = "info-box"
label = "Info box"
summary = "title"

  [[tool.oleafly.forms.fields]]
  arg = "title"
  kind = "text"
  label = "Heading"
  placeholder = "Short heading"
  required = true

  [[tool.oleafly.forms.fields]]
  arg = "tone"
  kind = "choice"
  label = "Tone"
  default = "note"
  options = [{ value = "note", label = "Note" }, { value = "risk", label = "Risk" }, "neutral"]

  [[tool.oleafly.forms.fields]]
  arg = 0
  kind = "content"
  label = "Text"
```

プロジェクトのフォーム（`oleafly-forms.toml` の中）:

```toml
[tool.oleafly]
schema = 1

[[tool.oleafly.forms]]
module = "template/memo.typ"
function = "memo-header"
label = "Memo header"
fields = [
  { arg = "to", kind = "text", label = "To" },
  { arg = "subject", kind = "text", label = "Subject" },
]
```

## キー

`schema = 1` は必須です。これがないファイル、または別の数字のファイルは無視されます。

`[[tool.oleafly.forms]]` の各エントリには、次のキーがあります。

| キー | 必須 | 意味 |
| --- | --- | --- |
| `function` | はい | 関数の名前。Typst の識別子 1 つとして書きます。ハイフンも使えます。 |
| `module` | `oleafly-forms.toml` のみ | 関数を定義するプロジェクト内のファイル。プロジェクトのルートからの相対パスで、フォルダの区切りには `/` を使います。 |
| `label` | いいえ | カードとチップに表示されるフォームの名前。省略すると、関数の名前になります。 |
| `summary` | いいえ | ラベルの隣にその値が表示される引数。フィールドの `arg` と同じように書きます。 |
| `fields` | はい | 1 つ以上のフィールド。 |

各フィールドには、次のキーがあります。

| キー | 必須 | 意味 |
| --- | --- | --- |
| `arg` | はい | 名前付き引数には名前（`"title"`）、位置引数には番号（`0` が最初）。末尾の `[...]` ブロックは、括弧の中の引数のあとに続く位置引数として数えられます。 |
| `kind` | はい | `text`、`content`、`choice`、`number`、`toggle` のいずれか。 |
| `label` | はい | フィールドのラベル。 |
| `help` | いいえ | フィールドの下に表示される短い注記。 |
| `placeholder` | いいえ | 空のフィールドに表示される灰色のテキスト。 |
| `required` | いいえ | `true` にすると、空のフィールドが不足として示され、**消去**ボタンが非表示になります。Oleafly が引数を自分で追加することはありません。 |
| `default` | いいえ | 引数が省略されたときに関数が使う値。表示されるだけで、書き込まれることはありません。 |

種類と、それぞれの追加のキー:

- `text` は、Typst の文字列を書き込みます。`multiline = true` を付けると、大きなボックスになります。
- `content` は、Typst のマークアップを編集し、`[...]` ブロックとして書き込みます。文字列の引数は、文字列のままです。
- `choice` には `options` が必要です。文字列のリスト、またはラベルが値と異なる場合は `{ value, label }` のテーブルです。値は文字列として書き込まれます。
- `number` は、`integer`、`min`、`max`、`step` を取ります。数値に単位はありません。
- `toggle` は、`true` または `false` を書き込みます。

## どの呼び出しにフォームが付くか

Oleafly は、レポート自身の、ファイルの最上位にある `#import` と `#let` の行をたどります。

- `#import "@local/acme-report:0.1.0" as acme` によって、`#acme.info-box(...)` がフォームになります。
- `#import "@local/acme-report:0.1.0": info-box, status-badge as badge` によって、`#info-box(...)` と `#badge(...)` がフォームになります。
- `#import "@local/acme-report:0.1.0": *` によって、パッケージがフォームを宣言しているすべての関数が、フォームになります。
- `#import "template/memo.typ": memo-header` は、`module` が `template/memo.typ` のプロジェクトのフォームと一致します。パスは、レポート自身のフォルダから読まれ、`/` で始まる場合はプロジェクトのルートから読まれます。

パッケージのバージョンは、完全に一致する必要があります。ファイルの後ろの方にある同じ名前の `#let` は、その位置からフォームを置き換えます。パッケージを再 import している別のファイル経由で到達する呼び出しは、ソースのテキストのままです。

ビジュアルモードがすでに描画している Typst の要素、たとえば `table` や `figure` と同じ名前の関数は、素の名前で呼び出すと、組み込みの見た目のままです。`#acme.table(...)` や名前を変えた import には、引き続きフォームが付きます。

## 読み取り専用で表示されるフィールド

フォームから安全に編集できない引数があります。その行には、ソースと理由が表示され、**ソースで編集**でその場所に移動します。

- **ソース内で計算されています**: 値が、`title: data.title` のような式です。
- **別の種類の値として書かれています**: たとえば、フォームがテキストを想定している場所に、数値が書かれています。
- **選択肢にない値です**: `options` に載っていない値です。
- **スプレッド引数で設定されています**: `..args` を含む呼び出しは、フォームから見えない値を渡すので、すべてのフィールドが読み取り専用になります。

フィールドを追加すべき場所に追加できないとき、たとえば欠けている引数のあとの位置引数の場合は、フォームがその旨を示し、**ソースで追加**を表示します。

## 定義の間違い

`oleafly-forms.toml` や、取り込んだパッケージの `typst.toml` を Oleafly で開くと、問題はそれぞれの行にマーカーとして表示されます。未知の種類、ラベルの欠落、重複したフォーム、プロジェクトの外にある `module` などです。壊れたフォームは除外され、ほかのフォームは動作し続けます。256 KB を超えるファイルは読み込まれません。

## テンプレートを共有する

Oleafly は、コンパイラが使うのと同じフォルダから、パッケージのフォームを読み込みます。`@local` パッケージを持っていない共同執筆者には、通常のソースが表示され、エラーは出ません。プロジェクトの全員とフォームを共有するには、**Typst パッケージ**のダイアログを開き、**プロジェクトフォルダのパッケージを使う**をオンにして、**パッケージをプロジェクトに取り込む**を選びます。パッケージとそのフォームは、プロジェクトの `typst-packages` フォルダに入って受け渡されます（[Typst プロジェクト](/docs/typst/)を参照）。
