😎

学校のレポートをTypstで書こう

2024/07/06に公開

Typstはいいぞ

何がいいの(Wordに比べて)

  • 節番号・図番号・表番号の扱いが便利すぎる
  • Markdown風で書きやすすぎる
  • 同じことを書いたら同じ結果になる安心感
  • 式が書きやすい / きれい

環境構築 for Windows

Typstのインストール

Windowsキーを押して、アプリの検索から"PowerShell"と入力してPowerShellを開きます
開いたら、winget install --id Typst.Typstと入力してEnterしてください。使用許諾契約の同意を求められたら、yと入力しEnterしてください。

VSCodeのインストール

VSCodeがない場合はインストールしてください。https://code.visualstudio.com/Download からかんたんにダウンロードできます。

VSCodeがインストールできたら、左側のバーにある

このボタンをクリックし、拡張機能の検索画面を開きます。入力ボックスに「Tinymist」と入力して、

この拡張機能をインストールしてください。

作業フォルダを作っておく

まっさらなフォルダで作業したほうが楽なので、好きな場所に好きな名前のフォルダを作りましょう。レポートのタイトルとかにしておくと良いと思います。

実際に書く

作った作業フォルダをVSCodeで開きます。VSCodeの「ファイル」メニューから「フォルダを開く」でできます。

開けたら、左側バーの

このアイコンを押して、画面左側にカーソルを持っていくと

これが出てくるので、一番左側のファイルが作れそうなボタンを押して、main.typ(ファイル名は何でもいいですが)と入力してください。基本的にはこのファイルにゴリゴリ書いていきます。

main.typファイルをクリックして開くと、右上に

このボタンがあるはずなのでクリックしてください。
すると、画面左側にプレビューが表示されます。

ためしにtypファイルにHello, World!と打ってみるとリアルタイムでプレビューされるのがわかると思います。Ctrl+Sで保存すると自動でpdfファイルが生成されます。

おまじない

typファイルの頭に#set text(lang: "ja")と書いておくとだいたいのものを日本の文書っぽいスタイルにしてくれるので書いておきましょう。
フォントがおかしい場合はとりあえず#set text(font: "フォント名", lang: "ja")と書いておいてください。

文章を装飾する

_Italic 斜体_\
*Bold 太字*
- 箇条書き
- 箇条書き
- 箇条書き
+ 数字付き箇条書き
+ 数字付き箇条書き
+ 数字付き箇条書き

見出しを入れる

= 見出し

== 見出し(小)
=== 見出し(超小)
=== 見出し(超小)

== 見出し(小)
=== 見出し(超小)
=== 見出し(超小)

= 見出し
...


設定すると番号は自動で振られるようにできます(振り方は後述)

数式を入れる

一行に収めたい数式なら$y = a x ^ 2 + b x + c$、複数行にしたい数式なら
$
a x ^ 2 + b x + c &= 0\
x &= (- b plus.minus sqrt(b ^ 2 - 4 a c)) / (2 a)
$

画像を入れる

作業フォルダ(typファイルがあるところと同じフォルダ)に画像ファイルを入れておき、

#image("画像のファイル名.png")

で呼び出せます。図番号を自動で入れることもできて、

#figure(
  caption: "画像のタイトル",
  image("画像のファイル名.png")
)


画像のサイズを調整するには

#figure(
  caption: "画像のタイトル",
  image("画像のファイル名.png", width: 100pt, height: 100pt)
)

のようにできます(widthheightはどちらかのみでも可)

表を入れる

#table(
  columns: 2,
  table.header([回転角目盛の範囲], [LED点灯個数]),
  [0〜20], [1],
  [20〜40], [2],
  [40〜60], [3],
  [60〜80], [4],
  [80〜100], [6],
)

こんな複雑な表も

#table(
  columns: 4,
  table.cell([], colspan: 2, rowspan: 2),
  table.cell([上下方向の位置], colspan: 2),
  [下],
  [上],
  table.cell([左右方向の位置], rowspan: 2),
  [左],
  [1600 ms],
  [800 ms],
  [右],
  [400 ms],
  [200 ms],
)

[]の代わりにtable.cell()を使うようにして、専有する幅と高さをcolspanrowspanで指定してやるといけます。

表も図のように#figureを使って表番号を自動で振るようにできます。

#figure(
  caption: "表のタイトル",
  table(
    columns: 2,
    table.header([回転角目盛の範囲], [LED点灯個数]),
    [0〜20],
    [1],
    [20〜40],
    [2],
    [40〜60],
    [3],
    [60〜80],
    [4],
    [80〜100],
    [6]
  )
)


ただ、表のタイトルは上に出してほしいので、設定でいじって上にします(後述)

figureを参照する

たとえば何かを表で示して、文章からその表について話したいとき、普通に「表1に示した〜」と書くと、その前に新しく表を入れたときにすべてチェックしなければいけなくなって大変です。Typstには、figureにIDを振って自分の好きな名前で参照する機能があります。

LED点灯個数を @LED点灯個数 に示した。
#figure(
  caption: "LED点灯個数",
  table(
    columns: 2,
    table.header([回転角目盛の範囲], [LED点灯個数]),
    [0〜20],
    [1],
    [20〜40],
    [2],
    [40〜60],
    [3],
    [60〜80],
    [4],
    [80〜100],
    [6],
  )
)<LED点灯個数> // ←ここがIDになっている

tableではなくimageでも同様に参照することが可能です。後述する設定をすると節や式でも同様のことができます。

コンテンツを横並びにする

#gridを使います。

#grid(
  columns: 2,
  gutter: 20pt, // 左のコンテンツと右のコンテンツの隙間の大きさ
  align: horizon, // 上下中央に揃える(お好みで)
  [
    ==== 点灯するLEDの個数
    - ボリュームの回転角目盛に応じて、 @LED点灯個数 に示す個数のLEDが点灯する。
    - 点灯個数は点灯開始位置から素子の記号がアルファベット順で後の方向に向かうように数えるものとする。
    - 素子Jまで点灯させても指定した個数に達しない場合は素子Cから不足した個数を点灯させる。例えば、点灯開始位置がI、個数が6の場合はI, J, C, D, E, Fが点灯する。
  ],
  [
    #figure(
      caption: "LED点灯個数",
      table(
        columns: 2,
        table.header([回転角目盛の範囲], [LED点灯個数]),
        [0〜20],
        [1],
        [20〜40],
        [2],
        [40〜60],
        [3],
        [60〜80],
        [4],
        [80〜100],
        [6],
      )
    )<LED点灯個数>
  ],
)

ページ全体の設定をする

ファイルの上にゴテゴテ書くことでいろいろ設定できます。自分の設定はコレです。

#let serif = ("Times New Roman", "Noto Serif CJK JP")
#let sans = ("Inter", "Noto Sans CJK JP")

#set page(numbering: "- 1/1 -")

#set text(11pt, font: serif, lang: "ja")
#set par(first-line-indent: 1em)

#set heading(numbering: "1.")
#show heading: it => {
  it
  v(5pt)
}
#show heading: set text(font: sans)

#set math.equation(numbering: "(1)")
#show math.equation: set text(font: ("New Computer Modern Math", ..serif))

#set table(inset: 7pt, align: horizon)
#show figure.where(kind: table): set figure.caption(position: top)

#set grid(gutter: 10pt, align: horizon)
#show "、": ","
#show "。": "."

ひとつずつあっさり解説すると、

#let serif = ("Times New Roman", "Noto Serif CJK JP")
#let sans = ("Inter", "Noto Sans CJK JP")

フォント設定を変数に入れてます。serifが明朝で、sansがゴシックです。使うときは、自分のデバイスにあるフォントに書き換えてください。

#set page(numbering: "- 1/1 -")

これはページ番号フォーマットの設定です。- 今のページ数/総ページ数 -みたいにしてくれます。

#set text(11pt, font: serif, lang: "ja")

フォントや文字サイズを指定しています。

#set par(first-line-indent: 1em)

各段落で段落の頭が一文字開くようになります。が、少しバグっていて、効いたり効かなかったりします。気になる場合は https://zenn.dev/mkpoli/articles/34a5ea47468979 を参考にしてください。

#set heading(numbering: "1.")
#show heading: it => {
  it
  v(5pt)
}
#show heading: set text(font: sans)

見出しの設定です。見出しに自動で1.とか2.とか1.1.とかつけてくれるようにしたり、見出しの下が少し窮屈に感じたので5pt開けたりしています。
見出しの番号をつけるように設定することで、<ID>@IDによる参照を使うことができるようになります。

#set math.equation(numbering: "(1)")
#show math.equation: set text(font: ("New Computer Modern Math", ..serif))

数式の設定です。式番号をつけるように設定したり、数式用のフォントを指定したりしています(例によってここも自分のデバイスにあるフォントに置き換えてください)
式番号をつけるように設定することで、<ID>@IDによる参照を使うことができるようになります。

#set table(inset: 7pt, align: horizon)
#show figure.where(kind: table): set figure.caption(position: top)

表の設定です。余白や文字揃え、キャプションの位置を上に指定しています。

#set grid(gutter: 10pt, align: horizon)

gridで毎回余白や揃え方を設定するのが面倒なので、デフォルト値を設定しています。

#show "、": ","
#show "。": "."

「、。」を「,.」に置き換えています(←すごい)。

Metroを使う

typファイルの頭に

#import "@preview/metro:0.1.0": *

と書いておくと、Metroを使うことができます。単位をいい感じにしてくれるライブラリです。これを使うことで、#unit("kohm")と書くことで単位を表示したり#qty(1, "kohm")と書くことで単位付きの値を表示したりできます。
普通に1 kΩと書くのではだめなのかと思われるかもしれませんが、半角スペースを書くのを忘れそうだったり、Ωと文字で打つのが気持ち悪い気がしたので使っています。
あと、#qty("4.70", "ohm", e: 3)とすることで指数表記もかんたんです(4.70 * 10^3 Ωになります)。
数式内でも使えます。

$
#qty("5.00", "V") - (#qty("4.70", "ohm", e: 3) times #qty("1.00", "A", e: -6))
$

独自のコマンドを定義する

自分はこんな感じのコマンドを作って使っています。

#let title(content) = {
  set align(center)
  set text(weight: "black", size: 2em, font: sans)
  [#content]
}

#let name(date, content) = {
  set align(right)
  [#date.display("[year]年[month padding:space]月[day padding:space]日")\
    #content]
}

#let withid(caption, content, id: none) = [
  #figure(caption: caption, content)#label(if id == none { caption } else { id })
]

#let img(caption, type: "png", id: none, src: none, width: auto, height: 150pt) = [
  #withid(
    caption,
    image(
      if src == none { if id == none { caption } else { id } } else { src } + "." + type,
      width: width,
      height: height,
    ),
    id: id
  )
]

使い方を解説すると、

#let title(content) = {
  set align(center)
  set text(weight: "black", size: 2em, font: sans)
  [#content]
}

これは文書の一番最初のタイトルを表示するのに使うやつです。
#title("マイクロコンピュータの利用")みたいに使います。


#let name(date, content) = {
  set align(right)
  [#date.display("[year]年[month padding:space]月[day padding:space]日")\
    #content]
}

これは執筆者と日付を表示するのに使うやつです。
#name(datetime(year: 2024, month: 7, day: 6), "霧雨 魔理沙")みたいに使います。


#let withid(caption, content, id: none) = [
  #figure(caption: caption, content)#label(if id == none { caption } else { id })
]

これはIDを毎回つけるのが面倒だったので作ったやつです。自分の場合はほぼ常にキャプションとIDが同じなので、毎回2度書かなくてもいいようにしました。

@表の説明 に示した。
#figure(
  caption: "表の説明"
  table(
    // 略
  )
)<表の説明>

これを

@表の説明 に示した。
#withid("表の説明", table(
  // 略
))

これにできます。
ただ、ごくまれにキャプションとIDを別にしたいこともあるので、

@ID に示した。
withid("表の説明", table(
  // 略
), id: "ID")

とできるようにもしてみました。


#let img(caption, type: "png", id: none, src: none, width: auto, height: 150pt) = [
  #withid(
    caption,
    image(
      if src == none { if id == none { caption } else { id } } else { src } + "." + type,
      width: width,
      height: height,
    ),
    id: id
  )
]

これも似たようなものです。

#figure(
  caption: "図の説明",
  image("図の説明.png", height: 150pt)
)<図の説明>

#img("図の説明")

にできます。

テンプレート(full)(コピペ用)

#import "@preview/metro:0.1.0": *

#let serif = ("Times New Roman", "Noto Serif CJK JP")
#let sans = ("Inter", "Noto Sans CJK JP")

#set page(numbering: "- 1/1 -")

#set text(11pt, font: serif, lang: "ja")
#set par(first-line-indent: 1em)

#set heading(numbering: "1.")
#show heading: it => {
  it
  v(5pt)
}
#show heading: set text(font: sans)

#set math.equation(numbering: "(1)")
#show math.equation: set text(font: ("New Computer Modern Math", ..serif))

#set table(inset: 7pt, align: horizon)
#show figure.where(kind: table): set figure.caption(position: top)

#set grid(gutter: 10pt, align: horizon)
#show "、": ","
#show "。": "."

#let title(content) = {
  set align(center)
  set text(weight: "black", size: 2em, font: sans)
  [#content]
}

#let name(date, content) = {
  set align(right)
  [#date.display("[year]年[month padding:space]月[day padding:space]日")\
    #content]
}

#let withid(caption, content, id: none) = [
  #figure(caption: caption, content)#label(if id == none { caption } else { id })
]

#let img(caption, type: "svg", id: none, src: none, width: auto, height: 150pt) = [
  #withid(
    caption,
    image(
      if src == none { if id == none { caption } else { id } } else { src } + "." + type,
      width: width,
      height: height,
    ),
    id: id
  )
]

#title("タイトル")
#name(datetime(year: 2024, month: 7, day: 6), "霧雨 魔理沙")

おまけ: Draw.ioをVSCode内で使う

回路図などをかんたんに作成することができます。Webでやるよりもエクスポートいらずで快適です。
VSCodeの拡張機能のところから「Draw.io Integration」と検索しインストールしてください。
インストールできたら、作業フォルダに「ファイル名.drawio.png」というファイルを作り開きます。するといつものDraw.ioの画面が出てきます。あとはここで編集するだけです。

おわり

Typstはいいぞ

Discussion