LaTeX de 余白のない PDF を作って画像に変換 (1)
PDF から画像を作りたいなら,スクリーンショットすれば良いかもしれない.しかし,1 つ 1 つスクショしてトリミングするのは非常に面倒くさい.大量になれば尚更である.
TeX で PDF を作成するなら,そのまま画像にまでしてしまおう!! というのが本記事のモチベーションになる.
記事が長くなってしまったので,本記事では LaTeX から余白のない PDF を作成するのみとしています.
PDF を画像 (PNG/ SVG) に変換する方法は次の記事で紹介します.
表や数式,TikZ などの余白のない PDF を作る方法として以下の 3 つを紹介したい.
- standalone クラス
- preview パッケージ
- トリミング (pdfcrop)
次の項でどの方法を利用するのが良いか示している.
Summary
目的とタイプセット方法,利用するパッケージなどが明らかな方が目次を見るよりも明瞭な気がしてきたので表にした.
以下の表で 6 つの項目に対するオススメの方法を示しておく.
画像にしたいコンテンツ | LuaLaTeX | (u)pLaTeX +dvipdfmx |
---|---|---|
行内数式 | standalone, preview | standalone |
別行立て数式 | preview | トリミング |
表 | standalone, preview | standalone |
キャプション付き表 | preview | トリミング |
TikZ | standalone, preview | トリミング, (standalone) |
文章 | トリミング, preview | トリミング |
" トリミング " としている箇所は A4 などで通常通りに作成してから,pdfcrop でトリミングすることを指している.
(u)pLaTeX+dvipdfmx の注意点
: まったく利用できないわけではないが,いくつかの点で期待通りの結果を得られない場合がある.特定のフォント等で使用したい場合を除いては LuaLaTeX を利用した方が良いだろう.
あるいは,トリミングすることを主軸に考えた方が有用だろう.
standalone では余白がなく出力サイズがコンテンツの最大の高さ/ 幅に合わせられている.
しかし,preview では余白が少しだけ作成される.
○ standalone クラス
standalone バンドル(クラスとパッケージの両方がある)は docmute や subfiles と同じようにファイルを分割することでそれぞれのタイプセットを軽くするためのものになっている.(実は一部 preview パッケージを利用しているようだ)
ただし,docmute や subfiles と大きく異なる点として,standalone が扱うものは 1 つのページそのものではなく,ドキュメントを構成するコンテンツのみを作成する (表や TikZ による描画を余白がない PDF にする) ことが出来る点にある.
これを利用して,表や TikZ による描画を余白なしに PDF を作成することを考えたい.
本来はここで作成した表などを挿入したいドキュメントに戻して作成することになるが,ここでは最終的に画像を作成したいだけなのでドキュメントに挿入する方法は述べない.
cf. The standalone pakcage, §5 Usage of the standalone class
基本的な使い方は以下のようになる.
\documentclass{standalone}
%
% some packages
%
\begin{document}
% tabular, formular, TikZ ...etc
\end{document}
複数のオプションを指定する場合には ,
で区切る.
■ 各種設定
▽ dvipdfmx の利用
タイプセットには (u)pLaTeX+dvipdfmx を利用しても問題ないようだ.ただし,DVI に依存するパッケージを利用する際には dvipdfmx をグローバルオプションとして読み込ませておく必要がある.(パッケージのドキュメントには dvipdfmx への言及はなされていないが,実行することは可能となっている)
以下のようにドキュメントクラスを読み込もう.
\documentclass[dvipdfmx]{standalone}
ただし,複数ページに渡る場合には,1 ページ目のサイズが 2 ページ目以降にも反映されるという問題が生じてしまう.
特にこだわりがなければ LuaLaTeX を利用するか,単数ページのみを作成するようにしよう.
▽ クラスの変更
基本的なドキュメントクラスは article となっている.
これを変更できる.class
オプションを利用しよう.
例
: jsarticle に変更することを考える.このときのタイプセットは upLaTeX+dvipdfmx で行う.
\documentclass[dvipdfmx,uplatex,class=jsarticle]{standalone}
class
で読み込むクラスに必要なオプションは class=hoge
より前に挿入する必要がある.
▽ 余白を作る
余白がまったくないので,PDF を生成するとギリギリに出力される.
画像として利用する場合には少しだけ余白があった方が良いだろう.(また,出力すると少し見切れていることがある)
border
オプションを利用すれば良い.例として,周囲 1mm の余白を設定する.
\documentclass[border=1mm]{standalone}
以下のいずれかのようにしても良い.
border=<length (all sides)>
border={<length (left/right)> <length (bottom/top)>}
border={<length (left)> <length (bottom)> <length (right)> <length (top)>}
ちなみに margin
でも border
と同じ結果を得る.
▽ 複数コンテンツの作成
standalone ではコンテンツ全体が 1 つのブロックであり,1 つのページに表示されるべきであると想定しているため,そのままでは複数ページの作成は出来ない.
multi
オプションを利用しよう.
このオプションは 1 つのページにしたいコンテンツを任意の環境に挿入することで得られる.
任意の環境名は,既存の環境名でも自作の環境名でも問わない.
\documentclass[multi=hoge]{standalone}
% some packages
\begin{document}
%
% Created here as a new page
\begin{hoge}
% content
\end{hoge}
%
% Created here as a new page
\begin{hoge}
% content
\end{hoge}
% more hoge environments ...
\end{document}
(u)pLaTeX+dvipdfmx を利用する場合は,1 ページ目のサイズが 2 ページ目以降にも反映されるため注意が必要.
■ 数式
equation 環境や align 環境などの別行立ての数式環境を利用することが出来ない.
したがって,利用できるのは行内環境のみになる.
そのため,以下のように $
で囲み \displaystyle
でディスプレイスタイルに変更する必要がある.
$\displaystyle
% Equation
$
あるいは,multi
オプションを利用して複数の数式を同時に作成したい場合には,math 環境を利用すると良いだろう.これは LaTeX 標準の行内数式環境である.
また,amsmath を読み込んでいても問題ない.
\documentclass[multi=math]{standalone}
% It doesn't matter if you load amsmath
\begin{document}
%
% Created here as a new page
\begin{math}\displaystyle
% Equation
\end{math}
%
% Created here as a new page
\begin{math}\displaystyle
% Equation
\end{math}
% more math environments ...
\end{document}
しかし,行内数式しか用いることが出来ないために以下のような数式を生成することは出来ない.
- 式番号付きの数式
- amsmath から提供される align 環境などの
&
で関係演算子などを揃えた数式 (数式環境内で使用される-ed
環境や行列環境は除く)
したがって,これらのような数式を作りたい場合には,次の preview パッケージを利用するかトリミングすることを考えると良いだろう.
■ 表
表を作成する場合には tabular 環境を利用すれば良い.
ここで table 環境を利用する必要はない.(というよりも利用できない)
%
% DO NOT surround in table environment
%
\begin{tabular}
% table contents
\end{tabular}
preview パッケージでは table 環境を利用することが出来るようになる.利用したい場合には参照してほしい.
■ TikZ
TikZ を利用する場合は tikz
オプションを利用する.このオプションを有効にするとき,multi=tikzpicture,varwidth=false
と同じになる.
このオプションによって TikZ が自動的に読み込まれ,tikzpicture 環境を利用することが出来るようになる.
また,複数の tikzpicture 環境を用いると複数ページの PDF を得ることが出来る.
\documentclass[tikz]{standalone}
% some packages
\begin{document}
%
% Each tikzpicture environment switches pages
%
% first TikZ
\begin{tikzpicture}
% tikz
\end{tikzpicture}
%
% second TikZ
\begin{tikzpicture}
% tikz
\end{tikzpicture}
% more tikzpictures ...
\end{document}
ただし,(u)pLaTeX+dvipdfmx を利用する場合には少し勝手が異なるようである.
tikzpicture 環境が 1 つのみであれば tikz
オプションの利用で問題ないが,複数の tikzpicture 環境を利用する場合には正常にオプションが機能しないようだ.
したがって,multi=tikzpicture
を有効にして \usepackage{tikz}
とすれば良い.
\documentclass[multi=tikzpicture,dvipdfmx]{standalone}
\usepackage{tikz}
% some packages
\begin{document}
% tikzpicture environments
\end{document}
しかし,この場合であっても 1 ページ目のサイズが 2 ページ目以降にも反映されるため注意が必要.(単数ページの作成の時のみ有用だろう)
やはり,LuaLaTeX を利用すればすべて解決!
○ preview パッケージ
preview パッケージを利用すると standalone で不可能だった番号付き数式や tabel 環境を利用することが出来る.
ただし,このパッケージは dvipdfmx を利用して上手く余白を消すことが出来ない.
上の記事では dvipdfmx であっても利用できるように解決している.ただし,TeX Live のみでは解決しないことに注意したい.
以下では LuaLaTeX でタイプセットすることを前提に preview パッケージを利用することを想定する.
preview パッケージは以下のように読み込む.active
と tightpage
オプションは有効にしておく.これら無しでは余白を取り除くことが出来ない.
基本的には preview 環境内のコンテンツを余白のない 1 ページとして出力する.
\usepackage{article}
\usepackage[active,tightpage]{preview}
% some packages
\begin{document}
%
% Created here as a new page
\begin{preview}
% tabular, formular, TikZ ...etc
\end{preview}
%
% Created here as a new page
\begin{preview}
% tabular, formular, TikZ ...etc
\end{preview}
% more preview environments
\end{document}
■ 番号付きの数式
オプションから displaymath
または textmath
とすれば,別行立て数式,行内数式がページを変えて出力される.
これらの数式は preview 環境で囲う必要はない.(オプションを指定しない場合には preview 環境で囲う必要がある)
\documentclass{article}
\usepackage{amsmath}
% It doesn't matter if you load amsmath
% Loading order; amsmath --> preview with `displaymath` option
\usepackage[active,tightpage,displaymath,textmath]{preview}
\begin{document}
%
% Created here as a new page
$ \alpha $
%
% Created here as a new page
\begin{equation}
% Numbered equation
\end{equation}
%
% Created here as a new page
\begin{align}
% Numbered equaitons
\end{align}
% more mathematics environments ...
\end{document}
これで出力すると式番号が付与されている.
amsmath から提供されている *
付きの環境では式番号は付与されない.ただし,式番号を付与しない場合には右側が切り取られてしまう.
displaymath
オプションを使用せずに preview 環境を利用すると解消されるが,この場合では align 環境を使用した数式の上側に余計は空白が作られてしまうようだ.
あるいは,mathtools の showonlyrefs
オプションを用いれば式番号なしでも右幅を切り取られない結果を得ることが出来る.
\documentclass{article}
\usepackage{amsmath}
\usepackage{mathtools}
\mathtoolsset{showonlyrefs}
\usepackage[active,tightpage,displaymath,textmath]{preview}
\begin{document}
%
\begin{equation}
% single equation
\end{equation}
%
\begin{align}
% multi equations
\end{align}
\end{document}
また,式番号を必要な式のみに出力したい場合には \noeqref
を利用すれば良い.
式番号を必要な式のみ出力する例 (折りたたみ)
以下の例では \label
と \noeqref
を合わせた \onlylabel
を作成したうえでタイプセットしている.
1, 3, 4, 7 番目のみに式番号を与えている.
\documentclass{jlreq}
\usepackage{amsmath}
\usepackage{mathtools}
\mathtoolsset{showonlyrefs=true}
\usepackage[active,tightpage,displaymath]{preview}
\newcommand{\onlylabel}[1]{
\noeqref{#1}
\label{#1}
}
\begin{document}
%
% First page
\begin{align}
f(x)
& =
ax^2 +bx +c
\onlylabel{first}
\\
& =
a\left( x^2 +\frac{b}{a}x \right) +c
% \onlylabel{second}
\\
& =
a\left( x +\frac{b}{2a} \right)^2 -\frac{b^2}{4a} +c
\onlylabel{third}
\end{align}
%
% Second page
% @ f(x)=0
\begin{align}
0
& =
a\left( x +\frac{b}{2a} \right)^2 -\frac{b^2 -4ac}{4a}
\onlylabel{4th}
\\
\left( x +\frac{b}{2a} \right)^2
& =
\frac{b^2 -4ac}{4a^2}
% \onlylabel{5th}
\\
x +\frac{b}{2a}
& =
\pm\frac{\sqrt{b^2 -4ac}}{2a}
% \onlylabel{6th}
\end{align}
%
% Third page
\begin{equation}
x
=
\frac{-b \pm\sqrt{b^2 -4ac}}{2a}
\onlylabel{7th}
\end{equation}
%
\end{document}
First page |
---|
Second page |
---|
Third page |
---|
以下のような警告が表示されなくなるまでタイプセットを繰り返せば完了する.
Label(s) may have changed. Rerun to get cross-references right.
■ table 環境
standalone では tabel 環境を利用できなかったが,preview パッケージでは利用することが出来る.
floats
オプションを利用する.このとき,preview 環境で囲う必要はない.
\documentclass{article}
\usepackage[active,tightpage,float]{preview}
% some packages
\begin{document}
\begin{table}
\centering
\caption{CAPTION}
\begin{tabular}
% table contents
\end{tabular}
\end{table}
\end{document}
キャプションの番号も機能している.ただし,レイアウトが少し残念な形になるように思われる.(テスト方法が悪かったか?)
■ TikZ
preview パッケージでももちろん TikZ で描画したものを出力することが出来る.
\documentclass{article}
\usepackage[active,tightpage]{preview}
\usepackage{tikz}
\begin{document}
%
% Created here as a new page
\begin{preview}
\begin{tikzpicture}
% tikz ...
\end{tikzpicture}
\end{preview}
%
% Created here as a new page
\begin{preview}
\begin{tikzpicture}
% tikz ...
\end{tikzpicture}
\end{preview}
% more preview environment with tikzpicture
\end{document}
■ 最大幅を揃える
PowerPoint などに PNG 画像として利用したいとする場合,横の最大幅を揃えておくと楽に挿入できると思われる.
これを実現してみよう.下に要件と解決方法を示す.
-
複数 preview 環境の幅を揃える
↳ 0pt の直線を引く
-
それぞれのコンテンツを中央揃えにする
↳ center 環境を利用する
以上から,以下のように preview 環境を利用すれば良い.
\begin{preview}
\begin{center}
% tabular, formular, TikZ ...etc
\end{center}
\rule{\linewidth}{0pt}
\end{preview}
あるいはこれを swpreview(Same width preview) 環境として定義しても良いだろう.
\newenvironment{swpreview}
{
\preview
\center
}
{
\endcenter
\rule{\linewidth}{0pt}
\endpreview
}
このようなテクニックは standalone では上手くできないようだ.これは standalone では 1 つのページに複数のコンテンツがある場合,横並びになってしまうからだ.
○ トリミングする
jsarticle などで作成して A4 サイズの PDF を作成して余白部分をトリミングで取り除きたい.
pdfcrop を利用してトリミングしよう.これは TeX Live にも収録されている.
詳しい使い方は $ texdoc pdfcrop
とするか $ pdfcrop --help
とすれば見ることが出来る.
コマンドラインでは以下のように利用する.
$ pdfcrop test.pdf
test-crop.pdf
が出力される.同じファイル名で出力したい場合は test.pdf
を続けて追加する.
これにはページ番号も加味してトリミングされるため,ページ番号は消去しておいた方が良い.
TeX ファイルでページ番号が出力されないように以下をプリアンブルに追加する.
\pagestyle{empty}
また,数式に式番号を付与したい場合,用紙サイズを B5 にするなど A4 より少し小さくすると良い感じの大きさになる (気がする)
\newpage
で改ページにすれば複数ページの PDF を作成できる.複数ページの PDF もいっきにトリミングすることが出来る.
■ 余白を残す
--margings
オプションでドキュメント内の構造から左,上,右,下の順で余白 (単位: bp) を設定することが出来る.
これらの数値が 2 つの場合は左右,上下で等しい値,1 つの場合は上下左右で等しい値としてみなされる.
$ pdfcrop --margins "10 5" test.pdf
左右に 10bp,上下に 5bp の余白が作られる.
任意 PDF のトリミング
: もしも,コマンドラインで任意の PDF をトリミングしたい場合には余白をマイナスにして欲しいところを逐次確認しながら切り出すことになる.
凄く面倒くさい.
これに関してはオンライン上のサービスを利用した方が懸命である.PDF を見ながら切り取ることが出来る.
また,PDF に含まれている画像を出したい場合であれば,トリミングするよりも画像抽出を考えた方が懸命である.
Poppler ライブラリの pdfimages を利用して抽出しよう.
■ VSCode でトリミング
コマンドラインをいちいち操作するのは面倒なので,VSCode +LaTeX Workshop で LaTeX 環境を構築しているならば,これを recipe から使えるようにしたい.
settings.json で以下のようにする.(TeX をタイプセットする tool や recipe は含めていないので注意.適宜挿入してほしい.)
"latex-workshop.latex.recipes": [
// Recipes for compiling TeX to PDF
// ... ...
{
"name": "Trimming PDF",
"tools": [
"pdftrimming",
]
},
],
"latex-workshop.latex.tools": [
// Tools for compiling TeX to PDF
// ... ...
{// Trimming PDF
"name": "pdftrimming",
"command": "pdfcrop",
"args": [
"--margins",
"10 5",
"%DOC%.pdf",
"%DOC%.pdf",
]
},
],
デフォルトでは "-crop" がファイル名に加わってしまうので,同じファイル名にするために "%DOC%.pdf"
を加えている.
まとめ
(u)pLaTeX+dvipdfmx を利用しているといくつか不具合が出てしまう方法が多い印象を受ける気がする.
好きなタイプセット方法を利用すれば良いと思うが,日本語文を打たない場合ならば,なおさら LuaLaTeX でタイプセットした方が有用だろうと思われる.
この記事の続きにあたる記事では,VSCode で利用する tools と recipes を本記事で紹介した pdfcrop も含めて紹介している.