---
description: Typstのスクリプト記述機能を用いて、ドキュメントを自動化しましょう。
---

# スクリプト記述

Typstには強力なスクリプト言語が組み込まれています。これにより、ドキュメントを自動化し、コードを使用してより洗練されたスタイルを作成できます。
以下は、スクリプト記述の概念の概要です。

## 式 { #expressions }

Typstでは、マークアップとコードが一体となっています。
最も一般的な要素以外のものは　_関数_ を使って作成されます。
これを可能な限り便利にするため、Typstはコード式をマークアップに埋め込むためのコンパクトな構文を提供しています。式はハッシュ(`#`)で始まり、
この式が終了すると通常のマークアップの解析が再開されます。
式の直後に通常の文字列として解釈されるべき文字が続く場合、セミコロン(`;`)を使って式を強制的に終了できます。

```example
#emph[Hello] \
#emoji.face \
#"hello".len()
```

上記の例では、[関数呼び出し]($function)、
[フィールドアクセス]($scripting/#fields)、
そして[メソッド呼び出し]($scripting/#methods)などのいくつかの使用可能な式を示しています。
この章の残りでは、より多くの種類の式について説明します。
いくつかの種類の式はハッシュ構文と互換性がありません(例えば二項演算子式)。
このような式をマークアップに埋め込むためには、`[#(1+2)]`のように丸括弧を使用します。

## ブロック { #blocks }
コードを構造化し、マークアップを埋め込むために、Typstは次の二種類の _ブロック_ を提供します。

- **コードブロック** `{{ let x = 1; x + 2 }}` \
  コードを書く際には、計算を複数のステートメントに分割したり、中間変数を作成したりすることがあるでしょう。
  コードブロックを使用すると、複数の式を一つのブロックにまとめられます。ブロック内の個々の式は改行またはセミコロンで区切られます。
  コードブロック内の個々の式の出力値は結合され、ブロックの値を決定します。
  `{let}`バインディングのように有用な出力のない式は`{none}`を生成し、これはどの値とも影響なく結合できます。

- **コンテンツブロック** `{[*Hey* there!]}` \
  コンテンツブロックを使用すると、マークアップやコンテンツをプログラム的な値として扱い、変数に保存したり、[関数]($function)に渡したりできます。
  コンテンツブロックは角括弧で囲まれ、任意のマークアップを含められます。
  コンテンツブロックは[content]($content)型の値を生成します。
  任意の数のコンテンツブロックを可変長引数として関数に渡せます。つまり、`{list[A][B]}`は`{list([A], [B])}`と等価です。

コンテンツブロックとコードブロックは任意にネストできます。以下の例では、`{[hello]}`が`{a + [ the ] + b}`の出力と結合され、`{[hello from the *world*]}`が生成されます。


```example
#{
  let a = [from]
  let b = [*world*]
  [hello ]
  a + [ the ] + b
}
```

## バインディングと分割 { #bindings }
前述のように、変数は`{let}`バインディングで定義できます。
変数には`=`記号のあとに続く式の値が代入されます。値の代入は任意であり、値が代入されなければ変数は`{none}`として初期化されます。
`{let}`キーワードは、[カスタム名前付き関数]($function/#defining-functions)を作成するためにも使用できます。
変数は、それが含まれるブロックの残りの部分(または、変数が含まれるブロックがない場合はファイル全体)の中でアクセスできます。

```example
#let name = "Typst"
This is #name's documentation.
It explains #name.

#let add(x, y) = x + y
Sum is #add(2, 3).
```

letバインディングは[配列]($array)や[辞書]($dictionary)の分割にも使用できます。
この場合、代入の左辺は配列や辞書と同じ形式でなければなりません。
`..`演算子はパターン内で一度だけ、配列や辞書の残りの項目を受け取るために使用できます。

```example
#let (x, y) = (1, 2)
The coordinates are #x, #y.

#let (a, .., b) = (1, 2, 3, 4)
The first element is #a.
The last element is #b.

#let books = (
  Shakespeare: "Hamlet",
  Homer: "The Odyssey",
  Austen: "Persuasion",
)

#let (Austen,) = books
Austen wrote #Austen.

#let (Homer: h) = books
Homer wrote #h.

#let (Homer, ..other) = books
#for (author, title) in other [
  #author wrote #title.
]
```

分割パターンでアンダースコアを使用して、要素を破棄できます。

```example
#let (_, y, _) = (1, 2, 3)
The y coordinate is #y.
```

分割は関数の引数リスト内でも機能します。

```example
#let left = (2, 4, 5)
#let right = (3, 2, 6)
#left.zip(right).map(
  ((a,b)) => a + b
)
```

そして通常の代入の左辺でも機能します。これは、変数の値を交換するなどの場合に便利です。

```example
#{
  let a = 1
  let b = 2
  (a, b) = (b, a)
  [a = #a, b = #b]
}
```

## 条件式 { #conditionals }

条件式を使用すると、ある条件が満たされているかどうかに応じて、異なるものを表示したり計算したりできます。
Typstは`{if}`式、`{else if}`式、および`{else}`式をサポートしています。
条件が`{true}`の場合、条件式は`if`の部分の結果が得られ、そうでない場合は`else`の部分の結果が得られます。

```example
#if 1 < 2 [
  This is shown
] else [
  This is not.
]
```

各条件分岐は、その本文としてコードブロックまたはコンテンツブロックを含められます。

- `{if condition {..}}`
- `{if condition [..]}`
- `{if condition [..] else {..}}`
- `{if condition [..] else if condition {..} else [..]}`

## ループ { #loops }

ループを使用すると、コンテンツを繰り返したり、何かを反復的に計算したりできます。
Typstは、`{for}`ループと`{while}`ループの2つのループをサポートしています。
前者は指定されたコレクションを反復するのに対し、後者は条件が満たされている限り反復を続けます。
ブロックと同様に、ループは各反復からの結果を一つの値に _結合_ します。

以下の例では、forループによって作成された3つの文が1つのコンテンツ値に結合され、whileループの中の長さ1の配列が1つの大きな配列に結合されます。

```example
#for c in "ABC" [
  #c is a letter.
]

#let n = 2
#while n < 10 {
  n = (n * 2) - 1
  (n,)
}
```

forループはさまざまなコレクションを反復処理できます。

- `{for value in array {..}}` \
  [配列]($array)内の各項目を反復処理します。[letバインディング]($scripting/#bindings)で説明されている分割構文もここで使用できます。

- `{for pair in dict {..}}` \
  [辞書]($dictionary)のキーと値のペアを反復処理します。ペアは`{for (key, value) in dict {..}}`を使用しても分割できます。これは、すべてのキーと値のペアの一時配列を作成しないため、`{for pair in dict.pairs() {..}}`よりも効率的です。

- `{for letter in "abc" {..}}` \
  [文字列]($str)の各文字を反復処理します。厳密に言うと、文字列の書記素クラスタの反復処理を行います。ほとんどの場合、書記素クラスタは単一のコードポイントに対応します。しかし、書記素クラスタは複数のコードポイントを含むことがあります。例えば、国旗の絵文字などです。

- `{for byte in bytes("😀") {..}}` \
  [文字列]($str)から変換されたり、エンコーディングなしでファイルから[読み取る]($read)ことができる[バイト]($bytes)を反復処理します。各バイト値は`{0}`から`{255}`までの[整数]($int)です。

ループの実行を制御するために、Typstは`{break}`と`{continue}`ステートメントを提供しています。
前者はループを早期終了し、後者はループの次の反復を開始します。

```example
#for letter in "abc nope" {
  if letter == " " {
    break
  }

  letter
}
```

ループの本体はコードブロックまたはコンテンツブロックにできます。

- `{for .. in collection {..}}`
- `{for .. in collection [..]}`
- `{while condition {..}}`
- `{while condition [..]}`

## フィールド { #fields }
_ドット記法_ を使用することで値のフィールドにアクセスできます。[コンテンツ]($content)型の値については、[fields]($content.fields)関数を使用してフィールドを一覧表示できます。

対象の値は以下のいずれかです。
- 指定されたキーを持つ[辞書]($dictionary)、
- 指定された修飾子を持つ[記号]($symbol)、
- 指定された定義を含む[モジュール]($module)、
- 指定されたフィールドを持つ要素で構成された[コンテンツ]($content)。利用可能なフィールドは、その要素が構築された際に与えられた[要素関数]($function/#element-functions)の引数と一致します。

```example
#let it = [= Heading]
#it.body \
#it.depth \
#it.fields()

#let dict = (greet: "Hello")
#dict.greet \
#emoji.face

```

## メソッド { #methods }
メソッド呼び出しは、値の[型]($type)で定義された関数を呼び出す便利な方法です。
例えば、[`str.len`]($str.len)関数は下記の2つの同等の方法で呼び出せます。

```example
#str.len("abc") is the same as
#"abc".len()
```

メソッド呼び出しの構造は`{value.method(..args)}`であり、これと等価である完全な関数呼び出しは`{type(value).method(value, ..args)}`です。各型のドキュメントには、その型に関連付けられた関数が一覧表示されています。現在、独自のメソッドは定義できません

```example
#let values = (1, 2, 3, 4)
#values.pop() \
#values.len() \

#("a, b, c"
    .split(", ")
    .join[ --- ])

#"abc".len() is the same as
#str.len("abc")
```

特定の値に対して呼び出された際に、その値を変更する特別な関数がいくつかあります(例: [`array.push`]($array.push))。
これらの関数は、_必ず_ メソッド形式で呼び出す必要があります。
場合によっては、メソッドが副作用のためだけに呼び出されるとき、その戻り値は無視されるべきです(結合に加わるべきではありません)。
値を破棄する標準的な方法は、`{let _ = array.remove(1)}`のように
letバインディングを使用することです。

## モジュール { #modules }

Typstプロジェクトを、_モジュール_ と呼ばれる複数のファイルに分割できます。
モジュールは他のモジュールの内容や定義を複数の方法で参照できます。

- **インクルード：** `{include "bar.typ"}` \
  パス`bar.typ`にあるファイルを評価し、その結果として得られる[コンテンツ]($content)を返します。

- **インポート：** `{import "bar.typ"}` \
  パス`bar.typ`にあるファイルを評価し、その結果として得られる
  [モジュール]($module)を現在のスコープに`bar`(拡張子なしのファイル名)として挿入します。次のように、`as`キーワードを使用してモジュール名を変更できます。
  `{import "bar.typ" as baz}`
  You can import nested items using dot notation: `{import "bar.typ": baz.a}`.

- **アイテムのインポート:** `{import "bar.typ": a, b}` \
  パス`bar.typ`にあるファイルを評価して、変数`a`と`b`の値
  (これらは`bar.typ`で、例えば`{let}`バインディングを通じて定義されている必要があります)
  を抽出し、現在のファイルで定義します。  `a, b`を`*`に置き換えると、モジュールで定義されたすべての変数が読み込まれます。
  次のように、`as`キーワードを使用してモジュール名を変更できます。
  `{import "bar.typ": a as one, b as two}`

以下の例に示すように、パスの代わりに[モジュール値]($module)を使用できます。

```example
#import emoji: face
#face.grin
```

## パッケージ { #packages }
プロジェクト間でビルド中のブロックを再利用するために、Typstの _パッケージ_ を作成してインポートできます。
パッケージのインポートは、名前空間、名前、バージョンの3つの組み合わせとして指定されます。

```example
>>> #let add(x, y) = x + y
<<< #import "@preview/example:0.1.0": add
#add(2, 7)
```

`preview`名前空間には、コミュニティで共有されているパッケージが含まれています。すべての利用可能なコミュニティパッケージは[Typst Universe]($universe)にあります。

Typstをローカルで使用している場合、独自のシステムローカルパッケージを作成できます。詳細については、[パッケージリポジトリ](https://github.com/typst/packages)を参照してください。

## 演算子 { #operators }

以下の表は、使用可能なすべての単項および二項演算子の効果、引数の個数（単項あるいは二項）、および優先度（高いほど強く結合）を示しています。

|   演算子   | 効果                                 | 引数の個数 | 優先度 |
| :--------: | ------------------------------------ | :--------: | :----: |
|   `{-}`    | 負号                                 |    単項    |   7    |
|   `{+}`    | 効果なし (対称性のために存在)        |    単項    |   7    |
|   `{*}`    | 乗算                                 |    二項    |   6    |
|   `{/}`    | 除算                                 |    二項    |   6    |
|   `{+}`    | 加算                                 |    二項    |   5    |
|   `{-}`    | 減算                                 |    二項    |   5    |
|   `{==}`   | 等価性の評価                         |    二項    |   4    |
|   `{!=}`   | 非等価性の評価                       |    二項    |   4    |
|   `{<}`    | 小なりの評価                         |    二項    |   4    |
|   `{<=}`   | 以下の評価                           |    二項    |   4    |
|   `{>}`    | 大なりの評価                         |    二項    |   4    |
|   `{>=}`   | 以上の評価                           |    二項    |   4    |
|   `{in}`   | コレクション内に存在することの評価   |    二項    |   4    |
| `{not in}` | コレクション内に存在しないことの評価 |    二項    |   4    |
|  `{not}`   | 論理否定                             |    単項    |   3    |
|  `{and}`   | 短絡論理積                           |    二項    |   3    |
|   `{or}`   | 短絡論理和                           |    二項    |   2    |
|   `{=}`    | 代入                                 |    二項    |   1    |
|   `{+=}`   | 加算代入                             |    二項    |   1    |
|   `{-=}`   | 減算代入                             |    二項    |   1    |
|   `{*=}`   | 乗算代入                             |    二項    |   1    |
|   `{/=}`   | 除算代入                             |    二項    |   1    |

[semver]: https://semver.org/
