latex.mkの推敲
[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
50 #LaTeXオプション
51 LATEXFLAG ?=
52 DVIPDFMXFLAG ?=
53 EXTRACTBBFLAGS ?=
54 BIBTEXFLAG ?=
55 MENDEXFLAG ?=
56
57 tex-warning:
58         @$(ECHO) "check current directory, or set TEXTARGET in Makefile."
59
60 # ファイル名から拡張子を除いた部分
61 BASE = $(basename $<)
62
63 # TeX中間ファイルの拡張子
64 #   .aux: 相互参照
65 #   .fls: tex -recorderで生成されるファイルリスト
66 #   .lof: 図リスト(\tableoffigures)
67 #   .lot: 表リスト(\tableoftables)
68 #   .out: hyperrefパッケージ
69 #   .toc: 目次(\tableofcontents)
70 #   .log: ログ
71 TEX_INT := .aux .fls .lof .lot .out .toc .log
72 # 索引中間ファイルの拡張子
73 #   .idx: auxから作成
74 #   .ind: idxから作成
75 #   .ilg: 索引ログ
76 IND_INT := .idx .ind .ilg
77 # BiBTeX中間ファイルの拡張子
78 #   .bbl: auxから作成
79 #   .blg: BiBTeXログ
80 BIB_INT := .bbl .blg
81
82 ALL_INTERFILES = $(addprefix *,$(TEX_INT) $(IND_INT) $(BIB_INT) .d .*_prev)
83
84 .SECONDARY: $(wildcard ALL_INTERFILES)
85
86 # \tableofcontents命令をTeXファイルから検索する
87 toc = \
88   $(shell \
89     $(SED) -e '/^\s*%/d' -e 's/\([^\]\)\s*%.*/\1/g' $(BASE).tex $(intex) | \
90     $(SED) -e '/\\begin{verbatim}/,/\\end{verbatim}/d' | \
91     $(SED) -n -e 's/.*\(\\tableofcontents\)/\1/p' \
92   )
93
94 # \listoffigures命令をTeXファイルから検索する
95 lof = \
96   $(shell \
97     $(SED) -e '/^\s*%/d' -e 's/\([^\]\)\s*%.*/\1/g' $(BASE).tex $(intex) | \
98     $(SED) -e '/\\begin{verbatim}/,/\\end{verbatim}/d' | \
99     $(SED) -n -e 's/.*\(\\listoffigures\)/\1/p' \
100   )
101
102 # \listoftables命令をTeXファイルから検索する
103 lot = \
104   $(shell \
105      $(SED) -e '/^\s*%/d' -e 's/\([^\]\)\s*%.*/\1/g' $(BASE).tex $(intex) | \
106      $(SED) -e '/\\begin{verbatim}/,/\\end{verbatim}/d' | \
107      $(SED) -n -e 's/.*\(\\listoftables\)/\1/p' \
108    )
109
110 # \makeindex命令をTeXファイルから検索する
111 makeindex = \
112   $(shell \
113     $(SED) -e '/^\s*%/d' -e 's/\([^\]\)\s*%.*/\1/g' $(BASE).tex $(intex) | \
114     $(SED) -e '/\\begin{verbatim}/,/\\end{verbatim}/d' | \
115     $(SED) -n -e 's/.*\(\\makeindex\)/\1/p' \
116   )
117
118 # \bibliography命令で読み込まれる文献データベースファイルをTeXファイルから検索する
119 bibdb = \
120   $(addsuffix .bib,$(basename $(strip $(shell \
121      $(SED) -e '/^\s*%/d' -e 's/\([^\]\)\s*%.*/\1/g' $(BASE).tex $(intex) | \
122      $(SED) -e '/\\begin{verbatim}/,/\\end{verbatim}/d' | \
123      $(SED) -n -e 's/\\bibliography\(\[[^]]*\]\)\{0,1\}{[^}]*}/&\n/pg' | \
124      $(SED) -n -e 's/.*{\([^}]*\)}$$/\1/p' | \
125      $(SED) -e 's/,/ /g' \
126    ))))
127
128 # hyperrefパッケージ読み込みをTeXファイルから検索する
129 hyperref = \
130   $(shell \
131     $(SED) -e '/^\s*%/d' -e 's/\([^\]\)\s*%.*/\1/g' $(BASE).tex $(intex) | \
132     $(SED) -e '/\\begin{verbatim}/,/\\end{verbatim}/d' | \
133     $(SED) -n -e 's/.*\(\\usepackage\(\[[^]]*\]\)\{0,1\}{hyperref}\)/\1/p'\
134   )
135
136 # $(BASE).texで使われるLaTeX中間ファイル
137 INTERFILES = \
138   $(strip \
139     $(if $(toc),$(BASE).toc) \
140     $(if $(lof),$(BASE).lof) \
141     $(if $(lot),$(BASE).lot) \
142     $(if $(makeindex),$(BASE).ind) \
143     $(if $(bibdb),$(BASE).bbl) \
144     $(if $(hyperref),$(BASE).out) \
145   )
146
147 INTERFILES_PREV = $(addsuffix _prev,$(INTERFILES))
148
149 # \include命令で読み込まれるTeXファイル
150 includetex = \
151   $(strip $(addsuffix .tex,$(shell \
152     $(SED) -e '/^\s*%/d' -e 's/\([^\]\)\s*%.*/\1/g' $(BASE).tex | \
153     $(SED) -e '/\\begin{verbatim}/,/\\end{verbatim}/d' | \
154     $(SED) -n -e 's/\\include\(\[[^]]*\]\)\{0,1\}{[^}]*}/&\n/pg' | \
155     $(SED) -n -e 's/.*{\([^}]*\)}$$/\1/p' \
156   )))
157
158 # \input命令で読み込まれるTeXファイル
159 define get_inputtex
160   $(strip $(shell \
161     $(SED) -e '/^\s*%/d' -e 's/\([^\]\)\s*%.*/\1/g' $1 | \
162     $(SED) -e '/\\begin{verbatim}/,/\\end{verbatim}/d' | \
163     $(SED) -n -e 's/\\input\(\[[^]]*\]\)\{0,1\}{[^}]*}/&\n/pg' | \
164     $(SED) -n -e 's/.*{\([^}]*\)}$$/\1/p' \
165   ))
166 endef
167
168 inputtex = $(call get_inputtex,$(BASE).tex $(includetex))
169
170 # \include命令または\input命令で読み込まれるTeXファイル
171 intex = $(strip $(includetex) $(inputtex))
172
173 # \includegraphics命令で読み込まれるグラフィックファイル
174 ingraphics = \
175   $(strip $(shell \
176     $(SED) -e '/^\s*%/d' -e 's/\([^\]\)\s*%.*/\1/g' $(BASE).tex $(intex) | \
177     $(SED) -e '/\\begin{verbatim}/,/\\end{verbatim}/d' | \
178     $(SED) -n -e 's/\\includegraphics\(\[[^]]*\]\)\{0,1\}{[^}]*}/&\n/pg' | \
179     $(SED) -n -e 's/.*{\([^}]*\)}$$/\1/p' \
180   ))
181
182 # LaTeX処理(コンパイル)
183 LATEXCMD = $(LATEX) -interaction=batchmode $(LATEXFLAG) $(BASE).tex
184 COMPILE.tex = $(ECHO) $(LATEXCMD); $(LATEXCMD) >/dev/null 2>&1 || ($(CAT) $(BASE).log; exit 1)
185
186 # 相互参照未定義の警告
187 WARN_UNDEFREF := 'There were undefined references\.'
188
189 # LaTeX処理
190 # ログファイルに警告がある場合は警告がなくなるまで、最大CNTで指定された回数分、処理を実行する
191 CNT := 3
192 COMPILES.tex = \
193   @(for i in `$(SEQ) 1 $(CNT)`; do \
194       if test -s $@ -a -s $(BASE).log; then \
195         $(GREP) -e $(WARN_UNDEFREF) $(BASE).log || exit 0; \
196       else \
197         $(ECHO) '$@ and/or $(BASE).log does not exist.'; \
198       fi; \
199       $(COMPILE.tex); \
200     done)
201
202 # DVI -> PDF
203 # 出力結果は.logファイルへ出力
204 DVIPDFCMD = $(DVIPDFMX) $(DVIPDFMXFLAG) $(BASE).dvi
205 COMPILE.dvi = $(ECHO) $(DVIPDFCMD); $(DVIPDFCMD) >>$(BASE).log 2>&1 || ($(CAT) $(BASE).log; exit 1)
206
207 # 索引中間ファイル(.ind)作成
208 MENDEXCMD = $(MENDEX) $(MENDEXFLAG) $(BASE).idx
209 COMPILE.idx = $(ECHO) $(MENDEXCMD); $(MENDEXCMD) >/dev/null 2>&1 || ($(CAT) $(BASE).ilg; exit 1)
210
211 # 文献リスト中間ファイル(.bbl)作成
212 BIBTEXCMD = $(BIBTEX) $(BIBTEXFLAG) $(BASE).aux
213 COMPILE.bib = $(ECHO) $(BIBTEXCMD); $(BIBTEXCMD) >/dev/null 2>&1 || ($(CAT) $(BASE).blg; exit 1)
214
215 # ターゲットファイルと必須ファイルを比較し、内容が異なる場合はターゲットファイルの内容を必須ファイルに置き換える
216 CMPPREV = $(CMP) $@ $< || $(CP) -p -v $< $@
217
218 # 依存関係を.dファイルに書き出す
219 %.d: %.tex
220         @$(ECHO) '$@ is created by scanning $<.'
221 # .dファイルの依存関係
222         @$(ECHO) '$(BASE).d: $(BASE).tex' >$@
223 # 中間ファイルの依存関係
224         $(if $(INTERFILES),@( \
225       $(ECHO); \
226       $(ECHO) '# LaTeX Intermediate Files'; \
227       $(ECHO) '$(BASE).dvi:: $(INTERFILES_PREV)'; \
228       $(ECHO) ' @$$(COMPILE.tex)'; \
229       $(ECHO); \
230       $(ECHO) '$(BASE).dvi:: $(BASE).aux'; \
231       $(ECHO) ' @$$(COMPILES.tex)'; \
232     ) >>$@)
233 # 画像ファイルの依存関係
234         $(if $(ingraphics),@( \
235       $(ECHO); \
236       $(ECHO) '# IncludeGraphic Files - .pdf, .eps, .jpeg/.jpg, .png'; \
237       $(ECHO) '#           .xbb Files - .pdf, .jpeg/.jpg, .png'; \
238       $(ECHO) '$(BASE).aux: $(ingraphics)'; \
239       $(if $(filter-out %.eps,$(ingraphics)), \
240         $(ECHO); \
241         $(ECHO) '$(BASE).aux: $(addsuffix .xbb,$(basename $(filter-out %.eps,$(ingraphics))))'; \
242       ) \
243     ) >>$@)
244         $(if $(intex),@( \
245       $(ECHO); \
246       $(ECHO) '# Files called from \include or \input - .tex'; \
247       $(ECHO) '$(BASE).aux: $(intex)'; \
248     ) >>$@)
249 # 文献処理用ファイルの依存関係
250         $(if $(bibdb),@( \
251       $(ECHO); \
252       $(ECHO) '# Bibliography files: .aux, BIBDB -> .bbl -> .div'; \
253       $(ECHO) '$(BASE).bbl: $(bibdb) $(BASE).tex'; \
254     ) >>$@)
255
256 # 変数TEXTARGETSで指定されたターゲットファイルに対応する
257 # .dファイルをインクルードし、依存関係を取得する
258 # ターゲット末尾に clean、.xbb、.tex、.d が含まれている場合は除く
259 ifeq (,$(filter %clean %.xbb %.tex %.d,$(MAKECMDGOALS)))
260   -include $(addsuffix .d,$(basename $(TEXTARGETS)))
261 endif
262
263 # auxファイル作成
264 %.aux: %.tex
265         @$(COMPILE.tex)
266
267 %.dvi: %.aux
268         @$(COMPILES.tex)
269
270 %.dvi: %.tex
271         @$(COMPILE.tex)
272         @$(COMPILES.tex)
273
274 # PDFファイル作成
275 %.pdf: %.dvi
276         @$(COMPILE.dvi)
277
278 # バウンディング情報ファイル作成
279 # pdf、jpeg/jpg、pngファイルに対応
280 %.xbb: %.pdf
281         $(EXTRACTBB) $(EXTRACTBBFLAGS) $<
282
283 %.xbb: %.jpeg
284         $(EXTRACTBB) $(EXTRACTBBFLAGS) $<
285
286 %.xbb: %.jpg
287         $(EXTRACTBB) $(EXTRACTBBFLAGS) $<
288
289 %.xbb: %.png
290         $(EXTRACTBB) $(EXTRACTBBFLAGS) $<
291
292 # 目次中間ファイル作成
293 %.toc: %.tex
294         @$(MAKE) -s $(BASE).aux
295
296 %.toc_prev: %.toc
297         @$(CMPPREV)
298
299 # 図リスト中間ファイル作成
300 %.lof: %.tex
301         @$(MAKE) -s $(BASE).aux
302
303 %.lof_prev: %.lof
304         @$(CMPPREV)
305
306 # 表リスト中間ファイル作成
307 %.lot: %.tex
308         @$(MAKE) -s $(BASE).aux
309
310 %.lot_prev: %.lot
311         @$(CMPPREV)
312
313 # 索引中間ファイル作成
314 %.idx: %.tex
315         @$(MAKE) -s $(BASE).aux
316
317 %.idx_prev: %.idx
318         @$(CMPPREV)
319
320 %.ind: %.idx_prev
321         @$(COMPILE.idx)
322
323 %.ind_prev: %.ind
324         @$(CMPPREV)
325
326 # BiBTeX中間ファイル作成
327 %.bbl: %.tex
328         @$(MAKE) -s $(BASE).aux
329         @$(COMPILE.bib)
330
331 %.bbl_prev: %.bbl
332         @$(CMPPREV)
333
334 # hyperref中間ファイル作成
335 %.out: %.tex
336         @$(MAKE) -s $(BASE).aux
337
338 %.out_prev: %.out
339         @$(CMPPREV)
340
341 # tex-cleanターゲット
342 tex-clean:
343         $(RM) $(ALL_INTERFILES)
344 ifeq (,$(filter %.dvi,$(TEXTARGETS)))
345         $(RM) *.dvi
346 endif
347
348 # xbb-cleanターゲット
349 xbb-clean:
350         $(RM) *.xbb
351
352 # tex-distcleanターゲット
353 tex-distclean: tex-clean xbb-clean
354 ifneq (,$(filter %.dvi,$(TEXTARGETS)))
355         $(RM) *.dvi
356 endif
357         $(RM) $(TEXTARGETS)