loading . . . Typstで遊ぼう > この記事は Typst で書いていたものの写しであり書きかけであり更新中です。
kawaii ロゴ: https://gist.github.com/fenjalien/1463a19ba2b91d061ed35e295494e0b3
## Typst で作る表紙の例
> 色々できないことも多い(縦書きなど)
* * *
# はじめに
## Typst とは
Typst は、科学技術文書の作成に特化した、現代的な組版(くみはん)システムです。Markdown のようにシンプルな構文と、LaTeX のようにパワフルで柔軟な表現力を兼ね備えています。リアルタイムでの高速なコンパイルが特徴です。
## Typst の利点
* _学習の容易さ:_ 直感的で覚えやすい構文を採用しており、初心者でもすぐに使い始めることができます。
* _高速なコンパイル:_ 変更を即座にプレビューに反映するため、トライ&エラーが容易です。
* _強力なスクリプティング:_ 変数、関数、ループ、条件分岐といったプログラミング機能が組み込まれており、動的で再利用性の高いコンテンツを作成できます。
* _統一されたエコシステム:_ パッケージ管理機能が内蔵されており、外部のライブラリやテンプレートを簡単に導入できます。
## インストール
Typst は、Web アプリケーションとしてブラウザ上で利用する方法と、ローカル環境にインストールして利用する方法があります。詳細は公式サイトを参照してください。
* _Web アプリケーション:_ https://typst.app/
* _ローカルへのインストール:_ https://github.com/typst/typst?tab=readme-ov-file#installation
## コマンドライン上での使い方
以下のコマンドで対象の Typst ファイルから pdf を出力します。
Terminal window
typst compile example.typ
以下のコマンドは対象の Typst ファイルを監視して変更があるたびにコンパイルをして pdf を更新し続けます。
Terminal window
typst watch example.typ
## vscode 拡張 Tinymist Typst の導入
vscode 上で Typst を快適に編集するための拡張機能_Tinymist Typst_を導入すると、構文ハイライトや補完機能が利用可能になります。 リアルタイムプレビュー機能もあり、Typst のドキュメントを編集しながら即座に結果を確認できます。
* * *
vscode 上の右上にある**虫眼鏡のついたプレビューアイコン** をクリックすると現在のファイルのリアルタイムプレビュー画面が右側に表示されます。 プレビュー画面の文などの要素をクリックすると該当箇所のファイルの行へ移動でき、 ファイル内の要素をクリックするとプレビュー画面がその位置へスクロールします。
プレビュー画面の右上にある**四角に右上矢印のアイコン** をクリックするとプレビュー画面は外部ブラウザに表示されるようになります。 クリックでジャンプする機能はブラウザ上でもそのまま利用できます。
* * *
# Typst の基本なマークアップ
## 見出し
= の数で見出しのレベルを表現します。
= 章 (レベル1)
== 節 (レベル2)
=== 項 (レベル3)
## テキストの装飾
Typst では、簡単な記号でテキストを装飾できます。
### 強調
*強調*
### 斜体
_イタリック_
### 下線
#underline[下線]
### 打ち消し線
#strike[打ち消し線]
### URL
URL https://example.com
### 改行・エスケープ文字
`\`を使います。
このように改行できます。\ 文中では\ スペースを一つ空けます。\
\$←のようなTypstで利用されている文字を書きたい場合のエスケープ文字としても利用されます。
## コードブロック
`(バッククォート 1 つ)で囲んだ文字はインラインコードになります。
`これはインライン`です。
``` (バッククォート 3 つ) で囲んだ行はコードブロックを形成します。言語を指定するとシンタックスハイライトが適用されます。
//これはブロックです。
//シンタックスハイライトが適用されています。
#include <stdio.h>
void main(int argc, char *argv[])
{
char *str = "hello world!";
puts(str);
}
## リスト
`-` (ハイフン) や `+`(プラス) でリストを作成します。インデントすることでネストも可能です。
- 順序なしリスト
- ネストされたリスト
- 順序付きリスト
+ 番号は自動で振られます
+ 2番目の項目
## 用語リスト
/ Typst : 今注目されている新しい組版システム。2019年に開発が開始され、2023年3月にベータ版が一般公開された。Rustで書かれており、シンプルな文法やコンパイルの速さが利点。
/ Rust : メモリ安全性を保証しつつ、低レベルのシステムプログラミングが可能な言語。所有権システムを採用しており、ガベージコレクタ#footnote("コンピュータプログラムが動的に確保したメモリ領域のうち、不要になった領域を自動的に解放する機能です。")がなくてもメモリリークやデータ競合を防ぐ。
/ ねこ : @nyan-image
## 数式
`$` で数式を囲みます。1 行でインライン数式、複数行でブロック数式になります。
/ インライン数式 : $E = m c^2$ はインライン数式です。
/ ブロック数式 :
これはブロック数式です。
$
sum_(i=1)^n i = (n(n+1)) / 2
$
## 参照
`<ラベル名>` で要素にラベルを付け、`@ラベル名` で参照します。数式や図、セクションなど、あらゆる要素にラベルを付けられます。
#figure(
image("../img/nyan4.jpg", width: 3cm),
caption: [参照されるねこ],
) <nyan-image>
#align(center)[@nyan-image をこのように参照できます。]
## ページ設定
`#set page()` ルールで、用紙サイズ、余白、ヘッダー、フッターなどを設定できます。
#set page(
paper: "a4",
margin: (x: 2.5cm, y: 3cm),
header: align(right)[Typst Manual],
footer: align(center)[#counter(page).display("1")]
)
## 段組
`#columns()` 関数で多段組を実現できます。`#colbreak()` で段を区切ります。
#import "@preview/roremu:0.1.0": roremu
#columns(2)[
#roremu(100)
#colbreak()
#roremu(100)
]
このように長い文章は折り返され、指定した段数で区切られます。 `#lorem()`(ここで使っているのは外部パッケージの`#roremu`)は指定された文字数の例文を表示する関数です。
* * *
# 関数
## Typst における関数
@layout_section や @ref-section にあるような`#`で始まる文は関数を表します。 内蔵の関数や以下のように`#let`を使って自作の関数を定義し利用することができます。
#let test(body) = { [渡された文字列は#body] }
- #test("テスト")
- #test[#text(fill: red, weight: "bold", [test])]
引数の渡し方は複数あります。以下は body に引数が割り当てられます。
#test("テスト")
このようにマークアップ文全体をを渡すこともできます。これも自動的に body に割り当てられます。
#test[#text(fill: red, weight: "bold", [test])]
以下のように複数の引数がある場合も自動的に body に割り当てられます。引数の初期値も設定でき省略時にこれが参照されます。
#let test2( var: false, body) = {
if var {
[varはTrueです。]
} else {
[varはFalseです。]
}
body
}
- #test2[引数]
- #test2(var: true)[引数]
`{ }`で区切られたブロック内はコードブロックなので関数に`#`をつけずに呼び出します。マークアップ文を使う場合は`[ ]`で囲みます。
* コンテントブロック(Content block)`[...]` : 関数は`#`をつけて使う。`#text(fill: red)[*Hey* there!]`
* コードブロック(Code block)`{...}` : 関数は`#`をつけずに使う。`text(fill: red)[*Hey* there!]`
## マークアップ関数の一覧
### 目次
// target で作りたい目次の要素を指定する。`depth`は目次を作るレベルの深さを数値で指定する。
#outline(target: heading, depth: 2)
### 水平方向のスペース
#h(1fr)```
### 垂直方向のスペース
```typst
#v(0.2em)
### 中央揃え
#aligncenter
### 取り消し線
#strike[文字列]
### 下線
#underline[文字列]
### 大文字化
#upper[apple]
### 小文字化
#lower[APPLE]
### スモールキャピタル
#smallcaps[Smallcaps]
### 上付き文字
2#super[2]
### 下付き文字
2#sub[2]
### ハイライト
#highlight[文字列]
### 引用
#quoteblock: true, attribution: [名前]
### 囲み
#boxstroke: 0.5pt + black, outset: 0.3em
### ダミーテキストを 10 単語生成
#lorem(10)
### 今日の日付を取得
#datetime.today()
### 水平線
#line(stroke: 1pt + black, start: (5%,0%), end: (95%,0%))
## スクリプト
Typst はスクリプト言語としての機能も持っています。変数、ループ、条件分岐などを利用して、コンテンツを動的に生成できます。
### for 関数
#let users = ("Alice", "Bob", "Charlie")
#for user in users {
[こんにちは、#text(fill: red)[#user] さん!]
}
### if 関数
#let a=32
#let b=64
#align(center)[#if a < b { [aはbより小さいです。] }]
### 単純な画像表示関数を定義
#let nyan(size: 5cm) = {image("../img/nyan4.jpg", width:size)}
#align(center)[#nyan(size: 2.5cm)]
## image 関数
`#image()` 関数で画像を挿入します。`#figure()` と組み合わせることで、キャプションや図番号を付与できます。
#figure(
image("../img/nyan4.jpg", width: 3cm),
caption: [ねこです]
)
## 図形関数
`#rect()` や `#circle()` などの関数で、基本的な図形を簡単に描画できます。
#align(center)[
#grid(columns: 3,
[#square(size: 1cm, fill: blue)],
[#circle(radius: 0.5cm, fill: red)],
[#polygon(
(0cm, 1cm), (0.5cm, 0cm), (1cm, 1cm),
fill: green,
)]
)]
## 色の指定方法
関数の引数に`color`がある場合、色を指定できます。`fill`は塗りつぶしです。`stroke`は枠線です。`3pt + black`のように`+`で属性を追加できます。
#rect(fill: red, stroke: 3pt + black, radius: 1em)
#line(stroke: 3pt + green, start: (0%,0%), end: (50%, -4em))
`rgb("#000000")`のように RGB 値で指定することもできます。透明度を含めた`rgb("#000000aa")`のような指定方法もあります。
#grid(columns: 2,
polygon(
(0cm, 1cm), (0.5cm, 0cm), (1cm, 1cm),
fill: rgb("#0000cc"),
),
circle(radius: 0.5cm , fill: rgb("#0000cc55"))
)
グラデーションを指定するには`gradient`を利用します。グラデーションの種類を`gradient.linear`のように指定します。 グラデーションの方向は`angle: 90deg`のように角度で指定します。
#rect(fill: gradient.linear(red, blue,angle: 90deg), radius: 1em,)
## table 関数
`#table()` 関数で柔軟な表を作成できます。
#table(
columns: (auto, 1fr, 1fr),
stroke: 0.5pt,
align: (left),
[*No.*],[*項目*],[*説明*],
[1], [Typst], [組版システム],
[2], [Markdown], [軽量マークアップ言語],
[3], [LaTeX], [組版システム],
)
## grid 関数
`#columns()`関数よりも柔軟なレイアウトをしたい場合利用できます。
#set rect(
inset: 8pt,
fill: rgb("e4e5ea"),
width: 100%,
)
#grid(
columns: (60pt, 1fr, 2fr),
rows: (auto, 60pt),
gutter: 3pt,
rect[Fixed width, auto height],
rect[1/3 of the remains],
rect[2/3 of the remains],
rect(height: 100%)[Fixed height],
grid.cell(
colspan: 2,
image("../img/nyan4.jpg", width: 100%),
),
)
## footnote 関数
脚注をつけることができます。
Astro#footnote("SSGだけでなくSSRもできる静的サイトジェネレーター")もありますがTypstは使えません。
## ファイルの分割
`#for` 関数と `#include` 関数を使って分割されたファイルを読み込みします。
複数のファイルに分割することで項目ごとに編集管理しやすくできます。
// ファイルのパスを配列にする
#let chapters = (
"content/text-format.typ",
"content/heading.typ",
"content/list.typ",
"content/codeblock.typ",
"content/formula.typ",
)
= ここからchaptersが配列順にそれぞれ並ぶ
#for chapter in (chapters) {
include(chapter)
}
## リストのループ
別ファイルからリストを読み込み`#for`ループを利用して用語リストとテーブルに表示してみます。`#table`関数では`..#for`と書くことで配列を渡します。
### import される Typst ファイル
#let locales=(
( name:"日本",str:"首都は東京です。",),
( name:"アメリカ",str:"首都はワシントンD.C.です。",),
( name:"フランス",str:"首都はパリです。",),
( name:"イギリス",str:"首都はロンドンです。",),
( name:"ドイツ",str:"首都はベルリンです。",),
( name:"中国",str:"首都は北京です。",),
( name:"韓国",str:"首都はソウルです。",),
)
### コード
#import "../import/locales.typ": locales
#for c in locales {
terms.item(text(c.name),text(c.str))
}
#table(
columns: (auto, 1fr),
stroke: 1pt+gray,
align: (left),
[*国名*],[*首都*],
..for (name,str) in locales {
(name,str)
}
)
## 外部データの読み込み
Typst は以下のデータを読み込むことができます。
* cbor
* csv
* json
* read
* toml
* xml
* yaml
### 読み込むデータ
[
{
"name": "ねこ",
"path": "../img/e670ceab9f15d95ce92d718ba046aaac3142aac3.jpg",
"description": "クリスマスにゃんこだにゃん"
},
{
"name": "きつね",
"path": "../img/2022-0106-01.jpg",
"description": "見せつけてくるきつね"
},
{
"name": "ティファ",
"path": "../img/c2b7d960c6205cb3d973fe0b3c51b477ecf75202.jpg",
"description": "FF担当"
},
{
"name": "ブリジット",
"path": "../img/1e4697102be08c9174a60f109b4e6558e838bf81.jpg",
"description": "格ゲー"
}
]
### コード
#let columnimage(data) = columns(
2,
for img in data{
block(
width: 100%,
clip: true,
square(
radius: 1em,
width: 100%,
height: auto,
inset: 0.5cm,
fill: if img.name == "ねこ" {
yellow
} else {
aqua
},
highlight(fill:rgb("#77ffff"), text(strong(underline(img.name))))
+"\n"+
text(img.description)
+align(center, rotate(8deg, image(img.path, fit:"cover", width: 80%))),
)
)
}
)
#columnimage(json("../json/animals.json"))
* * *
# 外部パッケージ
## codly コードブロック装飾
codly – Typst Universe Codly is a beautiful code presentation template with many features like smart indentation, line numbering, highlighting, etc. https://typst.app/universe/package/codly
以下のようにインポートと初期化を行うことでコードブロックのスタイルが変化します。
#import "@preview/codly:1.3.0": *
#import "@preview/codly-languages:0.1.1": *
#show: codly-init.with()
Rust の例
一部分のハイライト
#codly(highlights: (
(line: 4, start: 2, end: none, fill: red),
(line: 5, start: 13, end: 19, fill: green, tag: "(a)"),
(line: 5, start: 26, fill: blue, tag: "(b)"),
))
## Rubby ルビをふる
rubby – Typst Universe Add ruby (furigana) next to base text. https://typst.app/universe/package/rubby/
### 初期化
#import "@preview/rubby:0.10.2": get-ruby
#let ruby = get-ruby(
size: 0.5em, // Ruby font size
dy: 0em, // Vertical offset of the ruby
pos: top, // Ruby position (top or bottom)
alignment: "center", // Ruby alignment ("center", "start", "between", "around")
delimiter: "|", // The delimiter between words
auto-spacing: true, // Automatically add necessary space around words
)
### ルビのふりかた
ルビはRubbyを#ruby[り|よう][利|用]する。
## wrap-it 回り込み
wrap-it – Typst Universe Wrap text around figures and content https://typst.app/universe/package/wrap-it/
### 初期化
#import "@preview/wrap-it:0.1.1": wrap-content
### 使用例
#let wrap_fig = [
#figure(
image("../../img/nyan4.jpg",width:5cm),
caption: [画像],
)<fig:nyan4>
]
#let wrap_body = [#lorem(100)]
#wrap-content(wrap_fig, wrap_body,align: bottom + left, column-gutter: 1em)
* @fig:nyan4 *
## showybox 様々なボックス描画
showybox – Typst Universe Colorful and customizable boxes for Typst https://typst.app/universe/package/showybox
様々な枠線を作ることができるパッケージです。
### 初期化
#import "@preview/showybox:2.0.4": showybox
### 使用例
#showybox(
[Hello world!]
)
#showybox(
frame: (
border-color: red.darken(50%),
title-color: red.lighten(60%),
body-color: red.lighten(80%)
),
title-style: (
color: black,
weight: "regular",
align: center
),
shadow: (
offset: 3pt,
),
title: "Red-ish showybox with separated sections!",
lorem(20),
lorem(12)
)
#showybox(
frame: (
dash: "dashed",
border-color: red.darken(40%)
),
body-style: (
align: center
),
sep: (
dash: "dashed"
),
shadow: (
offset: (x: 2pt, y: 3pt),
color: yellow.lighten(70%)
),
[This is an important message!],
[Be careful outside. There are dangerous bananas!]
)
* * *
# 付録
## 地震情報を掲載する
気象庁の地震情報を取得できるアドレス https://www.jma.go.jp/bosai/quake/data/list.json から json ファイルを取得してテーブル表示します。
### json ファイルの取得
Terminal window
wget https://www.jma.go.jp/bosai/quake/data/list.json
リストは 1000 件と長すぎるため表示する範囲は`slice`で限定しました。
#let earthquake-list(num) = {
set text(
size: 0.8em,
)
let earthquakes = json("json/list.json")
[== 最近の地震 #num 件]
table(
stroke: 0.5pt,
align: left,
columns: (auto,auto,auto,auto),
[*地震発生時刻*], [*震源地*], [*マグニチュード*], [*最大震度*],
..for (at,anm,mag,maxi) in earthquakes.slice(0,num){
(at,anm,mag,maxi)
}
)
}
#earthquake-list(10) https://ubanis.com/note/typst/typst_de_asobou/