初めてTypstのテンプレートを作る

# Typstとは

Typstは広くいえば組版用の言語(ソフトウエアというべき？)で、数式機能や作図機能が豊富で使いやすいため、特にTeXの後継として使用している人が多い印象です。

https://typst.app/

# 使うきっかけ

私は仕事でしょっちゅう積分を解くとか線形代数をやるとか、それでできた仕様説明書を作るとかしています。普段はMarkdownで色々記述していましたが、複雑な数式でときどき融通が効かないことがあったり、簡単な図でもいちいちパワポで作成した図を貼ったりしなければならないのが若干ストレスでした。

Typstは数式の記法が優れているだけでなく、作図のパッケージも使いやすいらしいため、一度インストールして確かめてみました。その時の備忘録として書いているので、本当に初心者だという人向けの導入になればいいかなと思います。

# インストール

仕事ではWindows, 家ではMacですが、どちらもVisual Studio Codeの拡張機能でTinymist Typstを入れて環境構築を完了しました。

# とりあえず書いてみる

記法については先駆者が色々と説明してくれているので、そちらをご覧ください。
書いてみた感想は、「描画が鬼のように速い！！」です。ただ文字しか打ち込んでいないので、その程度で断定するのも良くないですが、TeXコンパイルの手間はないし、markdownの描画より速いかもしれないくらいです。

# テンプレート

テンプレートはウェブサイトでいうところのCSSのようなもので、文書のスタイルを設定するシートです。文書本体中に直書きすることもできますが、テンプレートとして別ファイルにしておくと、使い回す時に便利です。

文書本体と同じく`*.typ`のテキストファイルにスタイルを記載し、文書本体からテンプレートをインポートして反映させます。

公式サイトには大量のテンプレートが転がっています。基本的にはそれの中から自分の望みに近いものを選んで使うのがいいと思います。
公式のテンプレートは

```
#import "@preview/<テンプレート名>"
```

を打つだけで反映できます。特段インストールなどは必要ないです。
テンプレートは以下から探してください。

https://typst.app/universe/search/

ドキュメントに企業ロゴを入れたいなど、特殊な要件がある場合は、自作で作るのもありかと思います。

# テンプレートの準備と反映

自作でテンプレートを作るには少し勝手が違います。公式テンプレートを少し読んでみると、作るべきものと文書への反映は以下のようになっています。

## 公式テンプレートを読んでみる

試しに[charged-ieee](https://typst.app/universe/package/charged-ieee)のGitHubを見てみると、文書本体の先頭は以下のようになっています。

```typescript
#import "template_test.typ": ieee

#show: ieee.with(
  title: [・・・],
  abstract: [
    ・・・
  ],
  authors: (
    (
      name: "Martin Haug",
      department: [Co-Founder],
      organization: [Typst GmbH],
      location: [Berlin, Germany],
      email: "haug@typst.app",
    ),
    (
      ・・・
    ),
  ),
  index-terms: ("Scientific writing", "Typesetting", "Document creation", "Syntax"),
)
```

`#show: ieee.with()`で何やら関数を呼び出すような形をしており、タイトルや著者などが引数になっています。`#`で始まるものは関数で、`#show`は指定要素をスタイリングしますよ的な意味だと解釈した。

テンプレートファイル側はどうなっているかというと、

```typescript
#let ieee(
  title: [Paper Title],
  authors: (),
  abstract: none,
  index-terms: (),
  paper-size: "us-letter",
  bibliography: none,
  figure-supplement: [Fig.],
  body,
) = {
  set document(title: title, author: authors.map(author => author.name))
  set text(font: "TeX Gyre Termes", size: 10pt, spacing: .35em)
  set enum(numbering: "1)a)i)")
  //中略//
  body
```

`#let`で新しく`ieee`というスタイルを定義して、引数に色々しています。これらの引数を文書側で指定していたわけですね。最後の`body`は文書本体そのものを指していて、これは特に設定なくデフォルトで使えます。

テンプレートの内容は、`set`などでタイトルなど諸々のスタイリングの設定をして、最後に`body`を反映させて、文書全体にスタイリングを適応します。スタイリングの設定は上から順に処理されるっぽく、順番を間違えると変な順序でタイトルが表示されたりするので注意です。

## 自作してみる

タイトルセクションが必要ない場合は特段引数がいらないので、試しに以下のようにしておきます。

```typescript:my_template.typ
#let my_template(body) = {
  set par(leading: 2em)
  body
}
```

```typescript: test.typ
#import "template_test.typ": *
#show: my_template.with()

= Test1

#lorem(20)
```

こうした時の動作は、`#show: my_template.with()`でテンプレートのスタイルを反映するように指示し、テンプレートは文書本体`body`を受け取り、`set par(leading: 2em)`でパラグラフ部分の行間を2emにし、その設定を反映したのち`body`を描画します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/530192/76de6ed1-e211-4d84-a2de-f6a46f22539c.png)

テンプレートの処理は上から順に進むので、行間の設定の前に`body`を書くとこのように行間の設定が反映されません。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/530192/de637c7f-b1fc-4824-950a-1ff7b601b1aa.png)

引数をつけてみましょう。

```typescript:my_template.typ
#let my_template(title: [Title], body) = {
  align(
    center,
    par(text(title, size: 20pt)),
  )

  set par(leading: 1em)
  body
}
```

これでタイトルを引数で受け取り、`text`でフォントサイズを指定したテキストブロックを作り、それを`align`でcenterに指定し、中央揃えにします。するとこうなります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/530192/1d75edfa-b744-47fd-89c5-ab3bf596eadd.png)

なかなかいい感じになりました。他にも、`body`のように元から使える変数としては`heading`などがあり、これでカウンタの有無や数字の種類なども設定できます。

# まとめ

かなり簡単にでしたが、テンプレート自作の感覚だけは紹介できたかなと思います。具体的にドキュメントを作成したときの感想は、また後日書ければいいなと思います。(多分書かない)