はじめに
Typstはシンプルな文法で美しいPDFを高速に作成できる新しい組版ツールです。LaTeXより直感的で、リアルタイムプレビューや数式・図表・テンプレートも標準対応。研究論文から同人誌まで、効率よくプロ品質の文書制作が可能です。
Typst用のトンボとして markly package https://typst.app/universe/package/markly/ がありますが日本の印刷所に対応していません。
そこで markly をベースに作ってみました。
(ただし、まだトンボ付きPDFデータを印刷所に出していません(^^; 2025/11/23
tonbo.typのダウンロードはこちら
トンボって?
代表的な印刷所様より以下の様なテンプレが用意されています(下記サンプルはB5サイズ用)
・日光企画様が用意されているテンプレ
https://www.nikko-pc.com/site/home-hd-2/home-tombo/

・ねこのしっぽ様が用意されているテンプレ
https://www.shippo.co.jp/neko/order/download.shtml

今回は、Re:VIEWの TechBooster様のTemplateを参考にトンボを作りました。
(なんで?私がRe:VIEWのトンボを使用していたのでTypstで合わせてみました)

使い方
前提としてkanata様のTypstを完全に理解して技術同人誌を書く。
を読んでTypstについて理解してもらってテンプレートを流用してtonbo.typを追加させてトンボを付けていきます。
main.typ に組み込む場合は、#impoirt "tonbo.typ" 〜 #show: tonbo.page-setup.with(markly-context)の行を追加します。
書籍サイズがA5の場合の印刷サイズはB5、書籍サイズがB5の場合の印刷サイズはA4の様に1サイズ大きい用紙を設定します。
let markly-context ディクショナリーにキーと値を設定します。
tonbo キー:トンボを付ける/付けない
stock-size キー:印刷する用紙サイズ
content-size キー:書籍の用紙サイズ
top-margin,bottom-margin,inside-margin,outside-margin キー:余白
他のtypファイルに、set page()の記載があるとmarginの設定が変わってしまうのでコメントアウトしておく必要があります。
#import "template.typ": * // テンプレートのインポート
#show: init // テンプレートの初期設定処理
#import "tonbo.typ"
#let markly-context = tonbo.setup(
tonbo: true, // とんぼ(トンボ)を表示するかどうかを設定します。 true,false
//stock-size: "A4", // 印刷する用紙サイズを設定します。
//content-size: "B5", // 書籍の用紙サイズを設定します。
stock-size: "B5", // 印刷する用紙サイズを設定します。
content-size: "A5", // 書籍の用紙サイズを設定します。
// 余白の設定
top-margin: 15mm, // 上余白(天)
bottom-margin: 15mm, // 下余白(地)
inside-margin: 20mm, // ページ内側の余白(のど、とじしろ)
outside-margin: 12mm, // ページ外側の余白(小口)
)
#show: tonbo.page-setup.with(markly-context)
#display_title() // タイトルの表示
#pagebreak() // ページの区切り
#display_table_of_contents() // 目次の表示
#pagebreak() // ページの区切り
#include "chapter01.typ" // 1章のインポート
#pagebreak() // ページの区切り
#include "chapter02.typ" // 2章のインポート
#pagebreak() // ページの区切り
#display_colophon() // 奥付の表示
トンボの印刷仕様
印刷用紙と書籍サイズについて
書籍サイズがA5の場合の印刷サイズはB5、書籍サイズがB5の場合の印刷サイズはA4の様に1サイズ大きい用紙を使用する仕様になっています。
下図はイメージになります。
stockは印刷サイズ、contentは書籍サイズの用語としてtonbo.typ のソースファイル内の変数名として使用しています。

トンボ名称
tonbo.typ のソースファイル内では、各トンボには以下の様な名前を付けました。位置によってそのままの呼び名になっています。

トンボ名
tonbo.typ のソースファイルには、裁断するラインはcut、塗りたしトンボはbleedという変数を使用しています。
塗りたしとは用紙の縁いっぱいに画像を貼り付けたい時に画像をはみ出して画像を配置するラインです。

プログラム
#page-setup(markly-context, body)
#show: tonbo.page-setup.with(markly-context) から呼ばれる部分です。
#set page() では印刷用紙の大きさと書籍用紙の大きさをマージンの設定によって定義しています。
markly-context 辞書に設定されたパラメータは、markly-context.at("キー") で読み込みます。
width: と height: のパラメータには印刷する用紙の大きさを指定しています。
margin:() の設定マップ top, bottom, inside, outside では、印刷用紙の大きさから書籍用紙の大きさを引き、さらに 2 で割ることで、余白(トンボ表示部分)を設定しています。
そして、実際の文字の位置は、main.typ 内の top-margin, bottom-margin, inside-margin, outside-margin で定義した余白設定により、書籍用紙のサイズからマージンを取って文字を配置します。
#let page-setup(markly-context, body) = {
set page(
//トンボの設定
width: markly-context.at("stock-width"), // stock 印刷用紙サイズ
height: markly-context.at("stock-height"),
margin: (
top: (markly-context.at("stock-height") - markly-context.at("content-height"))
/ 2 + markly-context.at("top-margin") , //上余白(天)
bottom: (markly-context.at("stock-height") - markly-context.at("content-height
")) / 2 + markly-context.at("bottom-margin") , // 下余白(地)
inside: (markly-context.at("stock-width") - markly-context.at("content-width")
) / 2 + markly-context.at("inside-margin"), // ページ内側の余白(のど、とじしろ)
outside: (markly-context.at("stock-width") - markly-context.at("content-width"
)) / 2 + markly-context.at("outside-margin"), // ページ外側の余白(小口)
),
tonno.typのmargin設定で留意する点は、以下の様に印刷サイズと書籍サイズの余白マージンにページレイアウトの余白(top-margin,bottom-margin,inside-margin,outside-magin)を含んでいます。現状のTypstではcut部分の余白とページレイアウトの余白を別物で管理できないためこの様な設定を行なっています。

//トンボの設定
background: if markly-context.at("tonbo") {marks(markly-context) },
この部分で markly-context 辞書のtonboを参照して true 設定時にmarks()でトンボを表示しています。
//隠しノンブルの設定
header: if markly-context.at("tonbo") {
context {
if calc.odd(here().page()){ // 奇数ページ
[
#set text(7pt,font: "Arial")
#place(left, dx:-markly-context.at("inside-margin"), dy:markly-context.at("stock-height")/2)[#rotate(-90deg)[#here().page()]]
]
} else { // 偶数ページ
[
#set text(7pt,font: "Arial")
#place(right, dx: markly-context.at("inside-margin"), dy:markly-context.at("stock-height")/2)[#rotate(-90deg)[#here().page()]]
]
}
}
},
こん部分は、markly-context 辞書のtonboを参照して true 設定時に隠しノンブルを表示しています。
marimoさんのソースファイルを参照しています。
columns: 1, // 段組み
numbering: "1", // ページ番号(ノンブル)
number-align: center, // ページ番号(ノンブル)の位置
この部分では、本文の段組みやページ番号、ページ位置を設定しています。本文の設定を tonbo.typ 内のソースファイルに記載する必要があるため、あまり美しい構成とは言えず、改善の余地があります。
#let setup()
デフォルトの変数を定義しています。
基本的に触る必要はありません。
#let setup(
tonbo: true, // とんぼ(トンボ)を表示するかどうかを設定します。 true,false
//stock-size: "A4", // 印刷する用紙サイズを設定します。
//content-size: "B5", // 書籍の用紙サイズを設定します。
stock-size: "B5", // 印刷する用紙サイズを設定します。
content-size: "A5", // 書籍の用紙サイズを設定します。
stock-width: 182mm, // 値はダミー
stock-height: 257mm, // 値はダミー
content-width: 148mm, // 値はダミー
content-height: 210mm, // 値はダミー
// 塗り足しマーク(bleed marks)と断裁マーク(cut marks)の間隔を設定する
bleed: 3mm, // 塗りたし
// 断裁マーク(たちきり)(cut marks)とテキストとの距離を設定する
// 2025/11/15 margin: で使ってないので、削除方向
//margin-width: 3mm,
//margin-height: 3mm,
margin-width: 5mm,
margin-height: 5mm,
// content-size 書籍の用紙サイズに適用する余白の設定
top-margin: 15mm, // 上余白(天)
bottom-margin: 15mm, // 下余白(地)
inside-margin: 20mm, // ページ内側の余白(のど、とじしろ)
outside-margin: 12mm, // ページ外側の余白(小口)
bleed-marks: true, // bleed 塗りたしトンボ 表示有効/無効フラグ
cut-marks: true, // cut カットトンボ 表示有効/無効フラグ
) = {
markly-context 辞書のtonboを参照して true 設定時に、用意サイズを元に印刷する用紙の高さと幅の設定と書籍の用紙の高さと幅のサイズを設定します。
tonboがfalseの時は、stockとcontntのサイズを同じにしてトンボを表示しない様にしています。
※変な処理なので tonbo 変数だけでトンボの表示・非表示としたほうが良いですね。
if tonbo == true {
// 印刷する用紙サイズを設定します。
if stock-size == "A5" {
stock-width = 148mm
stock-height = 210mm
} else if stock-size == "B5" {
stock-width = 182mm
stock-height = 257mm
} else if stock-size == "A4" {
stock-width = 210mm
stock-height = 297mm
}
} else { // tonbo が無効な時は、大きさを stock = content するとトンボが表示されない
if content-size == "A5" {
stock-width = 148mm
stock-height = 210mm
} else if scontent-size == "B5" {
stock-width = 182mm
stock-height = 257mm
} else if content-size == "A4" {
stock-width = 210mm
stock-height = 297mm
}
}
// 書籍の用紙サイズを設定します。
if content-size == "A5" {
content-width = 148mm
content-height = 210mm
} else if content-size == "B5" {
content-width = 182mm
content-height = 257mm
}
// cut カットトンボ
let cut-top-left = (slug-width, stock-height - slug-height)
let cut-top-right = (stock-width - slug-width, stock-height - slug-height)
let cut-bottom-left = (slug-width, slug-height)
let cut-bottom-right = (stock-width - slug-width, slug-height)
draw-marks(cut-top-left, cut-top-right, cut-bottom-left, cut-bottom-right)
// コーナートンボ作成 beed ライン
let draw-marks(top-left, top-right, bottom-left, bottom-right, color:black) = {
// Top Left 上左
let from = top-left
from.at(1) += mark-standoff
let to = from
to.at(1) += mark-length
line(from, to, stroke: Line-Width + color) //縦線
let from = top-left
from.at(0) -= mark-standoff
let to = from
to.at(0) -= mark-length
line(from, to, stroke: Line-Width + color) //横線
let cut-top-left = (slug-width, stock-height - slug-height)
この cut-top-left 変数は、Typstのタプル(tuple)という複数の値をひとまとめにしたデータ構造が使われています。
let from = top-left
fromに代入することで、
from.at(0)で、slug-width
from.at(1)で、stock-height - slug-height
の値を取得できます。
line ファンクションのメモ
fromの原点は左下で、toは長さです。
最後に
とりあえず、Typstでトンボが付けられる様になったかと思います。
改良点としては
・パッケージ化できないか?
・カラー対応?(lineをCMYで書けば良い?)
・印刷所に提出してちゃんと作れるか。
・書籍スタイルの設定をtypst.typのpage-setup()内に記載する方法がいまいち。
・トンボの有無の処理がいまいち
⭐️スペシャルサンクス
Chad Skeeters様、marklyをベースにしました。
https://typst.app/universe/package/markly/
kanata様、tenplate.typ ファイルの一緒の配布許可ありがとうございました。
https://techbookfest.org/organization/5642855536132096
marimo様、Typstで技術同人誌を書こう!すぐに役立つ20のトピックの
隠しノンブルを参考にさせてもらいました。
https://techbookfest.org/organization/2Lb8ait6GBQhyvKHB6d3rD


