初めてのTypst：構文の基礎から応用

# Typstはいいぞ
Typstという組版ソフトがイケてるので布教したいけど、日本語の資料が少ないので書きました。
私は簡単なメモや資料など、論文以外の文書はlatexから乗り換えてTypstを使っています。

**この記事のメイントピックは、知っておくと応用力、理解力が変わってくる、独特な構文について解説している部分です。前半は飛ばして頂いて構いません。**
[メイントピックへのリンク](https://qiita.com/naoppy/items/55a0df837858e553d430#%E7%B0%A1%E5%8D%98%E3%81%AA%E6%A7%8B%E6%96%87%E7%B4%B9%E4%BB%8B)

# Typstの何がいいのか
- 環境構築が非常に容易
    - VSCodeで拡張を入れるだけ
    - 軽量
- 自由自在に拡張できる
    - プログラミングライクな構文で、レイアウトを思い通りに調整できる
    - 独自にプラグインを作れる(らしい)
- 構文の親和性
    - latexに近い構文ながら、latexより読みやすい・書きやすい
    - エラーメッセージがわかりやすい
- 変更の即時反映
    - 出力結果を見ながら書くことができる

例:
```
$ {x in RR | x "is natural" and x < 10} $
```
と書けば
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/212534/b62443af-75d8-be97-d123-84fe2728a616.png)
このような出力が得られます。数式を心の中で読むのと全く同じように、自然に書くことができます。

# 環境構築
TypstのgithubからCLIをダウンロードするか、Typstのwebアプリ上で書くか(Overleafみたいな感じ)、VSCodeの拡張で「Tinymist Typst」を入れるかの3択です。
私は最後を強くお勧めします。Tinymist Typst拡張を入れることで、VSCode上でtypstの構文がハイライトされ、右上にレビューを表示ボタンが生えるので、これで出力を見ながら書くことができます。

なお、typstの拡張子は `filename.typ` です。

# Typstの歩き方
Typstは日々進化しているので、適当な記事よりは公式のドキュメントを見たほうがいいです。

まず [公式チュートリアル](https://typst.app/docs/tutorial/) に目を通しましょう。

その後は、構文エラーで困ったら [Syntaxのページ](https://typst.app/docs/reference/syntax/) を、数学関連で困ったら Math、レイアウトで困ったらLayoutの部分を読めば解決できると思います。

機能追加の要望や、バグ報告、質問などは、公式コミュニティディスコードにスレ立てすることで解決できます！ぜひ活用してください。
実際、私も数学の記号が欲しくて機能追加の要望を出したらPRにまとめてもらい、追加されたことがあります。

# 簡単な構文紹介
latexに通常のモードと数式モードがあるように、typstには マークアップモード、数式モード、コードモード の3状態があります。

## 数式モード
数式は `$ (sin x)/x $` とドルマークで囲った間に記述します。latexと同じですね。
この `$` で囲まれた部分が数式モードです。
インライン数式はドルマークの後にスペース無しで、ディスプレイ数式は両端のドルマークの横にスペースを入れることで表現します。

## 関数呼び出し
マークアップモードと数式モードの中では関数呼び出しは `#func(arg1, ...)` と「#」を最初につけて呼び出します。
コードモードでは最初の「#」は必要ありません。
関数呼び出しの引数内では既にコードモードなので、関数の引数の中でさらに関数を呼ぶ場合「#」は要りません。

## コードモード内でマークアップモード
関数内 や 関数呼び出しの引数の中 ではコードモードになっていますが、その中で `[]` で囲った部分はマークアップモードになります。

例
```
#heading(level: 2, "あいうえお") // コードモードで文字列 "あいうえお" を渡している
// 上下は同じ
#heading(level: 2, [あいうえお]) // マークアップモードで あいうえお を渡している。
```

## コメント
コメントはC言語などと同じで、`//` で一行コメントを、`/*  */` で複数行コメントを表します。

## 関数引数の糖衣構文
Kotlinとかでよくあるんですが、関数の最後の引数を外に展開してかけます。

例:
```
par(justify: true, [
== 見出し2
あいうえお
])
```
は以下のようにも書けます。
```
par(justify: true)[
== 見出し2
あいうえお
]
```
一見 par関数に渡されてないように見えますが、これで大丈夫です。



## set rule
```
#set text(size: 14pt, lang: "ja")
```
のような構文です。これ以降の関数のデフォルト引数を指定したものに変更する効果があります。
コードモードでは先頭の「#」は要りません。
トップレベルにsetを書くとグローバルに変更されますが、ネストされた呼び出しの中に書くとその外に影響は出ません。影響範囲はスコープ内で閉じています。

## show-set rule
setルールで設定する対象を絞るのが、show-setルールです。例えば、見出し(heading)の文字のサイズを変えたい場合
```
#show heading: set text(size: 20pt)
```
とすることで、heading内のtextだけに対して設定できます。

## show rule
show単体はもっと強力で、指定したクラスの表示そのものを差し替えることができます。
```
#show heading: it => {
    quote(block: true, it.body)
}
```
とすれば、見出しが全て引用に変わってしまいます！
他にも、見出しの中でも2つ目に大きいサイズの見出しだけ変えるときは、whereセレクターと組み合わせて
```
#show heading.where(level: 2): it => {
    quote(block: true, it.body)
}
```
とすれば、見出しの大きさ2のものだけに適用できます。

## show-everything rule
ドキュメント全体を関数へ渡すとき(関数でラップするとき)に使います。
```
#show func1
// 以下のすべてのドキュメント全体が、一気にfunc1に渡される
...
```

# ここまでのまとめ: 実際の例
```:template.typ
#let mytemplate(
    author, // writer's name
    doc
    ) = {
    set page(
        paper: "a4",
        margin: (x: 25mm, y: 25mm),
        columns: 1,
        numbering: "1 / 1",
        number-align: center + bottom,
    )

    set par(
        justify: true
    )

    set document(
        author: author, 
        date: auto,
    )
    
    // 数式のフォント設定
    show math.equation: set text(font: "New Computer Modern Math")

    // 日本語の文字は原ノ味明朝に
    let jp_font = "Harano Aji Mincho"
    show regex("[\p{scx:Han}\p{scx:Hira}\p{scx:Kana}]"): set text(
        font: jp_font, 
        lang: "ja", 
    )

    set heading(numbering: none)
    show heading.where(level: 1): set text(size: 17pt)
    show heading.where(level: 2): set text(size: 14pt)

    doc
}
```

```:main.typ
#import "./template.typ": mytemplate
#show: doc => mytemplate("Naoki Otani", doc)

// ここから本文
= Chap1
== Section1
あいうえお
```

`template.typ` 内の関数に紙のサイズやフォントの設定などを書いておき、それを `main.typ` で show-everything ルールを使って適用しています。
このようにするとテンプレートを使いまわして統一感のある資料が作れます。
日本語についてですが、typstデフォルトのままだと中国語っぽいフォントになっているので、正規表現で日本語だけ取り出してそこだけフォントを変えるようにしています。

# 外部パッケージ
安心してください、latexのように大量のパッケージを使うことは普通ありません。まだtypstの外部ライブラリは未成熟なのもありますが…

唯一おすすめできるライブラリは physicaです。これは微分, 偏微分, テンソル、ベクトル解析など数学・物理関連の記号を使いやすくまとめてあります。


# おわりに
間違ってたら教えてください！みんなTypstはいいぞ～！
個人的にTypstの構文はFlutterとKotlinのハーフ感を感じる。