13ce75b29f50d3f3fa988177328a8900d3b437ff
[makefiles.git] / latex_mk / latex.mk
1 # latex.mk
2 # LaTeX処理(コンパイル)を行う
3 #
4 # == 使い方 ==
5 # 1. texソースファイルと同じディレクトリーに本ファイル(latex.mk)をコピーする
6 # 2. Makefileに変数TEXTARGETS と「include latex.mk」を記述する
7 # 3. texソースファイルと同じディレクトリーで、make コマンドを実行する
8 #
9 # == 機能 ==
10 # - 読み込むべき中間ファイルがないことや相互参照未定義の警告がある場合、LaTeX処理を最大4回繰り返す
11 # - \includegraphics命令がTeXファイルに含まれる場合、グラフィックファイルを挿入
12 #   -- 挿入されたグラフィックファイルが更新されたときは、処理を開始
13 #   -- 挿入されたグラフィックファイルがないときは、処理を中止
14 #   -- 挿入されたグラフィックファイルに対するバウンディング情報ファイル(.xbb)を作成
15 # - \include、\input命令がTeXファイルに含まれる場合、TeXファイルを挿入
16 #   -- 挿入されたTeXファイルが更新されたときは、処理を開始
17 #   -- 挿入されたTeXファイルがないときは、処理を中止
18 # - \makeindex命令が含まれる場合、mendexで索引を作成
19 # - \bibliography命令が含まれる場合、BiBTeXで文献一覧を作成
20 #
21 # == 擬似ターゲット ==
22 # - tex-clean: TeX中間ファイル(auxなど)を削除。ターゲットに.dviが含まれていないときは.dviファイルを削除
23 # - xbb-clean: バウンディング情報ファイル(.xbb)を削除
24 # - tex-distclean: TeX中間ファイル、バウンディング情報ファイル、ターゲットファイル(PDF、.dvi)を削除
25 #
26 # === Makefile -- sample ===
27 # TEXTARGETS := report.tex
28 #
29 # all: $(TEXTARGETS)
30 #
31 # include latex.mk
32 .PHONY: tex-warning tex-clean tex-distclean
33
34 # シェルコマンド
35 CAT := cat
36 CMP := cmp -s
37 CP := cp
38 ECHO := /bin/echo
39 GREP := grep
40 SED := sed
41 SEQ := seq
42
43 # LaTeXコマンド
44 LATEX := platex
45 DVIPDFMX := dvipdfmx
46 EXTRACTBB := extractbb
47 BIBTEX := pbibtex
48 MENDEX := mendex
49 KPSEWHICH := kpsewhich
50
51 #LaTeXオプション
52 LATEXFLAG ?=
53 DVIPDFMXFLAG ?=
54 EXTRACTBBFLAGS ?=
55 BIBTEXFLAG ?=
56 MENDEXFLAG ?=
57
58 tex-warning:
59         @$(ECHO) "check current directory, or set TEXTARGET in Makefile."
60
61 # ファイル名から拡張子を除いた部分
62 BASE = $(basename $<)
63
64 # TeX中間ファイルの拡張子
65 #   .aux: 相互参照
66 #   .fls: tex -recorderで生成されるファイルリスト
67 #   .lof: 図リスト(\tableoffigures)
68 #   .lot: 表リスト(\tableoftables)
69 #   .out: hyperrefパッケージ
70 #   .toc: 目次(\tableofcontents)
71 #   .log: ログ
72 TEX_INT := .aux .lof .lot .out .toc .log
73 # 索引中間ファイルの拡張子
74 #   .idx: auxから作成
75 #   .ind: idxから作成
76 #   .ilg: 索引ログ
77 IND_INT := .idx .ind .ilg
78 # BiBTeX中間ファイルの拡張子
79 #   .bbl: auxから作成
80 #   .blg: BiBTeXログ
81 BIB_INT := .bbl .blg
82
83 ALL_INTERFILES = $(addprefix *,$(TEX_INT) $(IND_INT) $(BIB_INT) .fls .d .*_prev)
84
85 .SECONDARY: $(wildcard ALL_INTERFILES)
86
87 # ファイル名から拡張子を除いた部分
88 BASE = $(basename $<)
89
90 # .flsファイルから、INPUT/OUTPUTファイルを取得。ただし、$TEXMFDISTのファイルを除く
91 IOFILES = \
92   $(sort $(filter-out $(BASE).tex $(BASE).aux, \
93     $(shell \
94       $(SED) -n -e 's/^\(INPUT\|OUTPUT\) \(.\{1,\}\)/\2/gp' $(BASE).fls | \
95       $(GREP) -v `$(KPSEWHICH) -expand-var '$$TEXMFROOT'` \
96   )))
97
98 # .flsファイルから、INPUTファイルを取得。ただし、$TEXMFDISTのファイルを除く
99 INPUTFILES = \
100   $(sort $(filter-out $(BASE).tex $(BASE).aux, \
101     $(shell \
102       $(SED) -n -e 's/^INPUT \(.\{1,\}\)/\1/gp' $(BASE).fls | \
103       $(GREP) -v `$(KPSEWHICH) -expand-var '$$TEXMFROOT'` \
104   )))
105
106 # $(BASE).texで使われるLaTeX中間ファイル
107 INTERFILES = \
108   $(sort \
109     $(subst .idx,.ind, \
110       $(filter $(addprefix $(BASE),.lof .lot .out .toc .idx .ind .bbl),$(IOFILES)) \
111   ))
112
113 INTERFILES_PREV = $(addsuffix _prev,$(INTERFILES))
114
115 # TeXファイル - .tex
116 TEXFILES = $(filter %.tex,$(INPUTFILES))
117
118 # 画像ファイル - .pdf、.eps、.jpg/jpeg、.png、および.xbb
119 GRAPHICFILES = \
120   $(sort \
121     $(shell \
122       $(SED) -e '/^\s*%/d' -e 's/\([^\]\)\s*%.*/\1/g' $(BASE).tex $(TEXFILES) | \
123       $(SED) -e '/\\begin{verbatim}/,/\\end{verbatim}/d' | \
124       $(SED) -n -e 's/\\includegraphics\(\[[^]]*\]\)\{0,1\}{[^}]*}/&\n/pg' | \
125       $(SED) -n -e 's/.*{\([^}]*\)}$$/\1/p' \
126     ) \
127     $(filter %.pdf %.eps %.jpeg %.jpg %.png %.bmp,$(INPUTFILES)) \
128   )
129
130 # そのほかの読み込みファイル
131 OTHERFILES = $(filter-out %.aux $(INTERFILES) $(TEXFILES) $(GRAPHICFILES),$(INPUTFILES))
132
133 # \bibliography命令で読み込まれる文献データベースファイルをTeXファイルから検索する
134 bibdb = \
135   $(addsuffix .bib,$(basename $(sort $(shell \
136      $(SED) -e '/^\s*%/d' -e 's/\([^\]\)\s*%.*/\1/g' $(BASE).tex $(TEXFILES) | \
137      $(SED) -e '/\\begin{verbatim}/,/\\end{verbatim}/d' | \
138      $(SED) -n -e 's/\\bibliography\(\[[^]]*\]\)\{0,1\}{[^}]*}/&\n/pg' | \
139      $(SED) -n -e 's/.*{\([^}]*\)}$$/\1/p' | \
140      $(SED) -e 's/,/ /g' \
141    ))))
142
143 # LaTeX処理(コンパイル)
144 LATEXCMD = $(LATEX) -interaction=batchmode $(LATEXFLAG) $(BASE).tex
145 COMPILE.tex = $(ECHO) $(LATEXCMD); $(LATEXCMD) >/dev/null 2>&1 || ($(CAT) $(BASE).log; exit 1)
146
147 FLSCMD = $(LATEX) -interaction=nonstopmode -recorder $(BASE).tex
148 CREATE.fls = $(ECHO) $(FLSCMD); $(FLSCMD) 1>/dev/null 2>&1; $(RM) $(addprefix $(BASE),$(TEX_INT) $(IND_INT) $(BIB_INT) .dvi)
149
150 # 相互参照未定義の警告
151 WARN_UNDEFREF := 'There were undefined references\.'
152
153 # LaTeX処理
154 # ログファイルに警告がある場合は警告がなくなるまで、最大CNTで指定された回数分、処理を実行する
155 CNT := 3
156 COMPILES.tex = \
157   @(for i in `$(SEQ) 1 $(CNT)`; do \
158       if test -s $@ -a -s $(BASE).log; then \
159         $(GREP) -e $(WARN_UNDEFREF) $(BASE).log || exit 0; \
160       else \
161         $(ECHO) '$@ and/or $(BASE).log does not exist.'; \
162       fi; \
163       $(COMPILE.tex); \
164     done)
165
166 # DVI -> PDF
167 # 出力結果は.logファイルへ出力
168 DVIPDFCMD = $(DVIPDFMX) $(DVIPDFMXFLAG) $(BASE).dvi
169 COMPILE.dvi = $(ECHO) $(DVIPDFCMD); $(DVIPDFCMD) >>$(BASE).log 2>&1 || ($(CAT) $(BASE).log; exit 1)
170
171 # 索引中間ファイル(.ind)作成
172 MENDEXCMD = $(MENDEX) $(MENDEXFLAG) $(BASE).idx
173 COMPILE.idx = $(ECHO) $(MENDEXCMD); $(MENDEXCMD) >/dev/null 2>&1 || ($(CAT) $(BASE).ilg; exit 1)
174
175 # 文献リスト中間ファイル(.bbl)作成
176 BIBTEXCMD = $(BIBTEX) $(BIBTEXFLAG) $(BASE).aux
177 COMPILE.bib = $(ECHO) $(BIBTEXCMD); $(BIBTEXCMD) >/dev/null 2>&1 || ($(CAT) $(BASE).blg; exit 1)
178
179 # ターゲットファイルと必須ファイルを比較し、内容が異なる場合はターゲットファイルの内容を必須ファイルに置き換える
180 CMPPREV = $(CMP) $@ $< || $(CP) -p -v $< $@
181
182 # 依存関係を.dファイルに書き出す
183 %.d: %.fls_prev
184         @$(ECHO) '$@ is created by scanning $(subst _prev,,$^).'
185 # .dファイルの依存関係
186         @$(ECHO) '$(BASE).d: $(BASE).fls_prev' >$@
187         $(if $(TEXFILES),@( \
188       $(ECHO); \
189       $(ECHO) '# Files called from \include or \input - .tex'; \
190       $(ECHO) '$(BASE).aux: $(TEXFILES)'; \
191     ) >>$@)
192         $(if $(OTHERFILES),@( \
193       $(ECHO); \
194       $(ECHO) '# Files other'; \
195       $(ECHO) '$(BASE).aux: $(OTHERFILES)'; \
196     ) >>$@)
197 # 画像ファイルの依存関係
198         $(if $(GRAPHICFILES),@( \
199       $(ECHO); \
200       $(ECHO) '# IncludeGraphic Files - .pdf, .eps, .jpeg/.jpg, .png'; \
201       $(ECHO) '#           .xbb Files - .pdf, .jpeg/.jpg, .png'; \
202       $(ECHO) '$(BASE).aux: $(GRAPHICFILES)'; \
203       $(if $(filter-out %.eps,$(GRAPHICFILES)), \
204         $(ECHO); \
205         $(ECHO) '$(BASE).aux: $(addsuffix .xbb,$(basename $(filter-out %.eps,$(GRAPHICFILES))))'; \
206       ) \
207     ) >>$@)
208 # 文献処理用ファイルの依存関係
209         $(if $(bibdb),@( \
210         $(ECHO); \
211         $(ECHO) '# Bibliography files: .aux, BIBDB -> .bbl -> .div'; \
212         $(ECHO) '$(BASE).bbl: $(bibdb) $(BASE).tex'; \
213       ) >>$@)
214 # 中間ファイルの依存関係
215         $(if $(strip $(INTERFILES) $(bibdb)),@( \
216       $(ECHO); \
217       $(ECHO) '# LaTeX Intermediate Files'; \
218       $(ECHO) '$(BASE).dvi:: $(sort $(INTERFILES_PREV) $(if $(bibdb),$(BASE).bbl_prev))'; \
219       $(ECHO) ' @$$(COMPILE.tex)'; \
220       $(ECHO); \
221       $(ECHO) '$(BASE).dvi:: $(BASE).aux'; \
222       $(ECHO) ' @$$(COMPILES.tex)'; \
223     ) >>$@)
224
225 # 変数TEXTARGETSで指定されたターゲットファイルに対応する
226 # .dファイルをインクルードし、依存関係を取得する
227 # ターゲット末尾に clean、.xbb、.tex、.d が含まれている場合は除く
228 ifeq (,$(filter %clean %.xbb %.tex %.d %.fls %.fls_prev,$(MAKECMDGOALS)))
229   -include $(addsuffix .d,$(basename $(TEXTARGETS)))
230 endif
231
232 # auxファイル作成
233 %.aux: %.tex
234         @$(COMPILE.tex)
235
236 %.dvi: %.aux
237         @$(COMPILES.tex)
238
239 %.dvi: %.tex
240         @$(COMPILE.tex)
241         @$(COMPILES.tex)
242
243 # PDFファイル作成
244 %.pdf: %.dvi
245         @$(COMPILE.dvi)
246
247 # バウンディング情報ファイル作成
248 # pdf、jpeg/jpg、pngファイルに対応
249 extractbb:
250         $(MAKE) -s $(addsuffix .xbb,$(basename $(wildcard $(addprefix *,.pdf .jpg .jpeg .png))))
251
252 %.xbb: %.pdf
253         $(EXTRACTBB) $(EXTRACTBBFLAGS) $<
254
255 %.xbb: %.jpeg
256         $(EXTRACTBB) $(EXTRACTBBFLAGS) $<
257
258 %.xbb: %.jpg
259         $(EXTRACTBB) $(EXTRACTBBFLAGS) $<
260
261 %.xbb: %.png
262         $(EXTRACTBB) $(EXTRACTBBFLAGS) $<
263
264 # ファイル一覧作成
265 %.fls: %.tex
266         @-$(CREATE.fls)
267
268 %.fls_prev: %.fls
269         @$(CMPPREV)
270
271 # 目次中間ファイル作成
272 %.toc: %.tex
273         @$(MAKE) -s $(BASE).aux
274
275 %.toc_prev: %.toc
276         @$(CMPPREV)
277
278 # 図リスト中間ファイル作成
279 %.lof: %.tex
280         @$(MAKE) -s $(BASE).aux
281
282 %.lof_prev: %.lof
283         @$(CMPPREV)
284
285 # 表リスト中間ファイル作成
286 %.lot: %.tex
287         @$(MAKE) -s $(BASE).aux
288
289 %.lot_prev: %.lot
290         @$(CMPPREV)
291
292 # 索引中間ファイル作成
293 %.idx: %.tex
294         @$(MAKE) -s $(BASE).aux
295
296 %.idx_prev: %.idx
297         @$(CMPPREV)
298
299 %.ind: %.idx_prev
300         @$(COMPILE.idx)
301
302 %.ind_prev: %.ind
303         @$(CMPPREV)
304
305 # BiBTeX中間ファイル作成
306 %.bbl: %.tex
307         @$(MAKE) -s $(BASE).aux
308         @$(COMPILE.bib)
309
310 %.bbl_prev: %.bbl
311         @$(CMPPREV)
312
313 # hyperref中間ファイル作成
314 %.out: %.tex
315         @$(MAKE) -s $(BASE).aux
316
317 %.out_prev: %.out
318         @$(CMPPREV)
319
320 # tex-cleanターゲット
321 tex-clean:
322         $(RM) $(ALL_INTERFILES)
323 ifeq (,$(filter %.dvi,$(TEXTARGETS)))
324         $(RM) *.dvi
325 endif
326
327 # xbb-cleanターゲット
328 xbb-clean:
329         $(RM) *.xbb
330
331 # tex-distcleanターゲット
332 tex-distclean: tex-clean xbb-clean
333 ifneq (,$(filter %.dvi,$(TEXTARGETS)))
334         $(RM) *.dvi
335 endif
336         $(RM) $(TEXTARGETS)