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