Markdown → PDF の手引き¶
jtypeset-md は Markdown を typeset で組版して PDF にします。見出しの採番・目次・索引・脚注・表・図・数式・ルビなど、
レポートや小説に必要な要素を Markdown の記法(と少しの拡張)で書けます。
1. インストール¶
pip install "jtypeset[md]" # markdown-it-py / mdit-py-plugins / PyYAML
pip install "jtypeset[md,highlight]" # + Pygments(コードブロックの色付け。無くても単色で組める)
pip install matplotlib # 任意: 数式を MicroTeX でなく matplotlib の mathtext で組むとき
確認:
jtypeset-md --help
2. 最初の 1 枚¶
hello.md:
---
title: はじめての組版
author: 名前
paper: A5
---
# 見出し
本文は既定で一字下げになり、行末は両端揃えです。**強調**、*斜体*、`コード`、リンクは
[typeset](https://github.com/wamsoft/jtypeset) のように書けます(URL は脚注に落ちます)。
- 箇条書き
- 二つ目
> 引用。
jtypeset-md hello.md # hello.pdf ができる
jtypeset-md hello.md --png 120 # hello_p1.png … も出す(確認用)
**強調** の太字は、同じ書体の Bold(data/NotoSerifJP-Bold.otf、Windows の游明朝 Demibold、Linux の Noto CJK Bold など)が
見つかればそれを使い、無ければ合成します。
フォントを指定しなければ、カレントの data/ の Noto → OS のフォント(Windows: 游明朝・游ゴシック、macOS: ヒラギノ、
Linux: Noto CJK)の順に探します。見つからなければエラーになるので、--font か front matter の fonts で指定してください。
絵文字は data/ の Noto 絵文字フォント(make fontdata)か OS のカラー絵文字フォント(Segoe UI Emoji / Apple Color Emoji /
Noto Color Emoji)が見つかれば自動でフォールバックに加わり、PDF / SVG / PNG のどれでもカラーで組まれます(縦組みでは正立)。
3. コマンドラインオプション¶
| オプション | 内容 |
|---|---|
-o OUT |
出力 PDF(既定: 入力と同名の .pdf) |
--paper A4\|A5\|B5\|B6\|文庫\|新書\|148x210mm |
判型 |
--landscape |
横置き |
--vertical |
縦組み |
--columns N |
段数 |
--font PATH(複数可) |
フォントファイル。最初のものが本文の第一候補。TTC も可 |
--font-body KEY --font-heading KEY |
本文・見出しの family(読み込んだフォントのキー) |
--size PT |
本文サイズ |
--toc |
先頭に目次 |
--no-numbering |
見出しを採番しない |
--no-indent |
段落の一字下げをしない |
--math <handler> |
数式ハンドラ(auto / microtex / mathtext / none / command:<cmd>) |
--png DPI |
各ページを PNG にも出す |
--guides |
版面と段の枠を描く(レイアウト確認用) |
コマンドラインの指定は front matter より優先します。
4. front matter(文書の設定)¶
Markdown の先頭に --- で囲んだ YAML を書きます。キーは snake_case でも kebab-case でも構いません。
---
title: 組版エンジン評価レポート
author: 組版基盤チーム
date: 2026 年 9 月 8 日
paper: A4 # A4 / A5 / B5 / B6 / 文庫 / 新書 / "148x210mm"
landscape: false
writing: horizontal # horizontal / vertical
direction: auto # auto / ltr / rtl(段落の基底方向。行内のアラビア文字・ヘブライ文字は常に双方向で並ぶ)
wrap: mixed # mixed / char / word / none(折返し: 既定は和文が字ごと・欧文が語ごと)
lang: ja # 本文の言語(BCP47)
hyphenation: hyph-en-us.tex # 欧文のハイフネーション(TeX のパターン。{en: 〜.tex} と言語ごとにも書ける)
# 本文が lang: ja でも、最初に読んだ言語のパターンで欧文の単語を割る
kinsoku: strict # strict / normal / loose(禁則の強さ。狭い段では normal / loose で行末が揃いやすい)
ruby-offset: 0 # ルビと親文字の間隔(親文字の em)
columns: 1
column-gap: 0 # 段間(pt。0 で既定)
margin: 20 # mm。{top: 25, bottom: 20, inner: 22, outer: 18} も可
fonts: # フォントファイル(相対パスは Markdown の場所から)
- fonts/NotoSerifJP-Regular.otf
- {path: fonts/NotoSansJP-Regular.otf, key: sans}
- {path: C:/Windows/Fonts/YuGothM.ttc, key: yugo, index: 0}
- {path: fonts/NotoSerifJP-Bold.otf, key: serif-b, family: [serif], weight: 700} # 同じ family の太字(**強調** で使われる)
- {path: fonts/NotoSansSC-Regular.otf, key: sans-sc, languages: [zh]} # 中国語のテキストで先に試す
- {path: fonts/big.otf, key: big, lazy: true} # lazy: true でも初回使用時まで開かない
font-languages: {zh: [sans-sc]} # 言語 → 先に試す family(宣言の languages と同じ意味)
font-body: [serif] # 本文の family(キー)。最初に無い字は次へフォールバック
font-heading: [sans]
font-mono: [sans]
size: 10.5
line-height: 1.75
indent: true # 一字下げ
justify: true # 両端揃え
toc: true # 先頭に目次(本文の [toc] でも置ける)
toc-depth: 2
numbering: true # 見出しの採番(1. / 1.1 / 1.1.1)
heading-page-break: 0 # このレベル以下の見出しで改ページ(1 なら章ごとに改ページ)
header: "{title}" # 柱。"" (空文字)で無し。null は既定(題名)と同じ。{page} {pages} {title} {author} {date} が使える
footer: "{page} / {pages}"
links: footnote # footnote / inline / none
math:
handler: auto # auto(MicroTeX があれば使う)/ microtex / mathtext / command(command: "...")/ none
highlight: true # コードブロックの色付け(Pygments)
highlight-style: default # Pygments のスタイル名
tab-width: 4
footnote-per-page: false # 脚注番号をページごとに 1 から
footnote-marker-format: "{n}"
footnote-label-format: "{n} "
figure-format: "図 {n}"
table-format: "表 {n}"
equation-format: "({n})"
---
キーの一覧は jtypeset.md.Options のフィールドです(python -c "import jtypeset.md as m; help(m.Options)")。
5. 記法¶
見出し・参照・しおり¶
# 章の見出し {#sec-intro}
## 節の見出し
### 項の見出し
numbering: true(既定)なら 1. 1.1 1.1.1 と採番され、PDF のしおり(アウトライン)になります。
末尾の {#label} を付けると本文から参照できます:
第 {ref:sec-intro} 章({page:sec-intro} ページ)を参照。
{ref:label} は番号、{page:label} はページ番号に置き換わります。図・表・数式・見出しのどれにも使えます。
{ をそのまま出したいときはコードスパン(`{…}`)に入れてください(コードは置換の対象外)。
段落¶
- 段落は空行で区切ります。既定で一字下げ(
indent: falseで無し)、両端揃え(justify: falseで行頭揃え) - 行末に空白 2 つ、または
<br>で段落内の改行 - 強調は太字、斜体は欧文だけが傾きます(和文は立てたまま)。
インラインコードはゴシック体 ~~打消し線~~(<s><del>でも)と<u>下線</u>(<ins>でも)。縦組みの下線は右側の傍線になります- リンク
[表示](URL)は表示文字を本文に置き、URL を脚注へ落とします(links: inlineで本文に、noneで捨てる)
箇条書き¶
- 項目
- 項目
- 入れ子は 4 空白で
1. 番号付き
2. 二つ目。折り返した行は番号のぶん下がった位置から始まる
コードブロック¶
```python
def hello():
print("タブは 4 桁のタブ位置に展開される")
```
背景付き・空白保持で組まれます。言語名があり Pygments が入っていれば色が付きます(highlight: false で切る)。
コードの中の {…} は置換されません。
表(GFM)¶
| 項目 | 説明 | 値 |
|:-----|:-----|---:|
| A | 左揃え | 1 |
| B | セル内は 1 段落 | 22 |
表: キャプションは直後の「表: 〜」で書く {#tab-a}
列幅は内容から自動で決まり(3 列以上は版面いっぱい)、ヘッダ行はページをまたぐと繰り返されます。
段より高い行は途中で分けて続きます。セル内で | を書くときは \|。
画像¶

文中の画像  は行の高さに合わせて行内に置かれる。
画像だけの段落は図になり、{fig} の番号(図 1)とキャプションが付きます。版面より大きい画像は段に合わせて縮みます。
PNG / JPEG / BMP / GIF を読めます(JPEG は PDF にそのまま入ります)。
脚注¶
本文[^1]。
[^1]: 注の本文。**強調**やコードも書ける。
記号は上付きの番号、注はその行が載った段の末尾に集まり、本文との間に短い罫が入ります。
番号は文書を通して連番(footnote-per-page: true でページごとに 1 から)。
数式¶
行内の数式 $e^{i\pi} + 1 = 0$ と、別行立て:
$$
\int_{-\infty}^{\infty} e^{-x^2}\,dx = \sqrt{\pi}
$$ (eq-gauss)
式 {ref:eq-gauss} を参照。
既定では同梱の MicroTeX(LaTeX 数式のレンダラ)が組み、数式のグリフは数式フォント(Computer Modern 系)として PDF に埋め込まれます。
分数・根号・積分・総和・行列(pmatrix)・場合分け(cases)・ギリシャ文字・\mathbf \text{} などが使えます。
math でハンドラを切り替えられます(無い環境では [tex] の代替テキストになるだけで、組版は止まりません)。
math: {handler: auto}(既定)— MicroTeX があればそれ、無ければ何もしないmath: {handler: microtex}— 同梱の MicroTeX。res_dirで数式フォントの場所を差し替え可math: {handler: mathtext}— matplotlib の mathtext(pip install matplotlib)。TeX のサブセットmath: {handler: command, command: "..."}— 外部コマンド。要求(JSON ファイル)を引数に受け、SVG を標準出力に書く。 MathJax / dvisvgm / Typst など、SVG を吐けるものなら何でも接続できます。要求の形式とベースラインの伝え方は Python ガイド の「外部オブジェクト」を参照math: {handler: none}— 数式を組まない
ルビ・縦組み向けの記法¶
|組版《くみはん》 ← 青空文庫形式(| でも可)
漢字《かんじ》 ← 直前の漢字の連続に付く
{東京|とうきょう} ← 波括弧形式
縦組み(writing: vertical)では数字や欧文は横倒しになり、ルビは右側、脚注は段の左端に付きます。
縦中横や圏点は Markdown 記法を用意していないので、必要なら Python API(Annotation)で組んでください。
改ページ・段組・目次・索引¶
<!-- pagebreak --> 改ページ(<!-- newpage --> でも同じ)
<!-- columnbreak --> 改段
<!-- columns: 2 --> ここから 2 段組(ページ単位で切り替わる)
[toc] 目次をここに(<!-- toc --> でも同じ)
[index] 索引をここに。本文の {index:よみ|用語} を集める
索引の項目は本文に {index:くみはん|組版}(読み|用語)と書きます。読みでかなの五十音順(欧文は A–Z)に並び、
見出し文字(あ・か・さ…)を挟んで用語とページ番号を点線で結びます。
6. Python から呼ぶ¶
from jtypeset.md import convert_file, convert_text, build_flow, Options
pages, warnings = convert_file("report.md", "report.pdf", Options(), png_dpi=110,
overrides={"paper": "A5", "writing": "vertical"})
for w in warnings:
print(w)
# Flow を取り出して自分で手を加える
conv = build_flow(open("report.md", encoding="utf-8").read(), base_dir=".")
conv.flow.add_page_break()
pages = conv.layout()
7. 困ったとき¶
| 症状 | 見るところ |
|---|---|
no font could be loaded |
--font か front matter の fonts でフォントファイルを指定する。TTC も可 |
| 文字が豆腐(□)になる | そのフォントに無い字。font-body に別のフォントのキーを続けて書くとフォールバックする |
font not embedded: … (fsType: Restricted License embedding) |
埋め込みが許可されていないフォント。別のフォントを使う |
数式が [tex: …] のまま |
math のハンドラが無い、または失敗。警告メッセージに原因が出る |
| 表の列が狭い/広い | 列数が 3 以上なら版面いっぱいに広がる。セルの内容の自然幅で配分されるので、長い語を分けるか列を減らす |
| 版面を確認したい | --guides で版面と段の枠を描く |
| 図がページの先頭に送られる | 図+キャプションが残りに入らないと次の段へ移る。図を小さくするか位置を変える |