# @file Makefile
#
# Makefile for typesetting LaTeX documents. Requires GNU Make 3.81 on Linux.
# See "make help".
#
# This file is provided under the MIT License:
#
# MIT License
#
# Copyright (c) 2018-2024 Takahiro Ueda
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
#

MAKEFILE4LATEX_VERSION = 0.11.2-dev

define help_message
Makefile for LaTeX ($(MAKEFILE4LATEX_VERSION))

Usage
  make [<targets...>]

Targets
  all (default):
    Build all documents in the current directory.

  all-recursive:
    Build all documents in the source tree.

  dvi, ps, pdf, eps, svg, jpg, png:
    Build all documents with the specified file format in the current directory.

  help:
    Show this message.

  clean:
    Delete all files created by this Makefile.

  mostlyclean:
    Delete only intermediate files created by this Makefile.

  pretty:
    Run code prettifiers for source files in the current directory.

  lint:
    Run linters for source files in the current directory.

  dist:
    Create tar-gzipped archives for arXiv submission.

  watch:
    Watch the changes and automatically rebuild documents.

  upgrade:
    Upgrade the setup.

See also
  https://github.com/tueda/makefile4latex
endef

# The default target of this Makefile tries to create this type of files from
# all *.tex:
# - dvi
# - ps
# - pdf (default)
default_target = pdf

# The toolchain for typesetting:
# - latex_dvips
# - latex_dvipdf
# - platex_dvips
# - platex_dvipdfmx
# - uplatex_dvips
# - uplatex_dvipdfmx
# - pdflatex (default)
# - xelatex
# - lualatex
# - luajitlatex
# Aliases:
# - latex -> latex_dvips
# - platex -> platex_dvips
# - uplatex -> uplatex_dvips
TOOLCHAIN = pdflatex

# Specify a commit range for latexdiff.
DIFF =

# Number of iterations for typesetting.
MAXREPEAT = 5

# Build directory.
BUILDDIR =

# Use latex-dev if DEV is defined.
DEV =

# (for debugging) Keep temporary directories if its value is non-empty.
KEEP_TEMP =

# Specify the color mode in the output:
# - always
# - never
# - auto (default)
COLOR =

# Specify whether *-eps-converted-to.pdf files are moved to BUILDDIR.
# - always
# - never
# - auto (default)
USE_BUILDDIR_FOR_EPSTOPDF =

# Files not to be included in a distribution.
NODISTFILES =

# Extra files to be included in a distribution.
EXTRADISTFILES =

# Files to be copied in "anc" directory in a distribution.
ANCILLARYFILES =

# Additional files to mostly-clean.
MOSTLYCLEANFILES =

# Additional files to clean.
CLEANFILES =

# Additional directories to mostly-clean.
MOSTLYCLEANDIRS =

# Additional directories to clean.
CLEANDIRS = .cache _cache cache

# Prerequisite Make targets in the current directory.
PREREQUISITE =

# Prerequisite Make targets in subdirectories.
PREREQUISITE_SUBDIRS = NONE

# Postprocessing Make targets.
POSTPROCESS =

# List of prettifier commands/rules, invoked by "make pretty".
PRETTIFIERS = latexindent

# List of linter commands/rules, invoked by "make lint".
LINTS = chktex

# List of test scripts/rules, invoked by "make check".
TESTS =

# Options for test scripts. Called as $(call TESTS_OPT,test_name,test_param).
TESTS_OPT =

# List of command line parameters for test scripts. If not empty, test scripts
# will be executed for each parameter.
TESTS_PARAMS =

# The following variables will be guessed if empty.
# XXX: in the current implementation, $(init_toolchain) overrides some of them.
TARGET =
SUBDIRS =
LATEX =
DVIPS =
DVIPDF =
PS2PDF =
DVISVGM =
PDFTOPPM =
GS =
BIBTEX =
BIBER =
SORTREF =
MAKEINDEX =
MAKEGLOSSARIES =
BIB2GLS =
LATEXINDENT =
CHKTEX =
ASPELL =
HUNSPELL =
TEXTLINT =
REDPEN =
KPSEWHICH =
AXOHELP =
PDFCROP =
EBB =
EXTRACTBB =
CONVBKMK =
LATEXPAND =
LATEXDIFF =
SOFFICE =
WGET =
CURL =

# Command options.
LATEX_OPT = -interaction=nonstopmode -halt-on-error
PDFLATEX_DVI_OPT = -output-format=dvi
DVIPS_OPT = -Ppdf -z
DVIPDF_OPT =
PS2PDF_OPT = -dPDFSETTINGS=/prepress -dEmbedAllFonts=true
DVISVGM_OPT = -n
PDFTOPPM_OPT = -singlefile
PDFTOPPM_JPG_OPT = -jpeg
PDFTOPPM_PNG_OPT = -png
GS_OPT =
BIBTEX_OPT =
BIBER_OPT =
SORTREF_OPT =
MAKEINDEX_OPT =
MAKEGLOSSARIES_OPT =
BIB2GLS_OPT =
LATEXINDENT_OPT = -l -wd -s
CHKTEX_OPT =
ASPELL_OPT =
HUNSPELL_OPT =
TEXTLINT_OPT = --cache
REDPEN_OPT =
KPSEWHICH_OPT =
AXOHELP_OPT =
PDFCROP_OPT =
EBB_OPT =
EXTRACTBB_OPT =
CONVBKMK_OPT = -g
LATEXPAND_OPT = --expand-usepackage
LATEXDIFF_OPT =
SOFFICE_OPT =
WGET_OPT =
CURL_OPT =

# ANSI escape code for colorization.
CL_NORMAL = [0m
CL_NOTICE = [32m
CL_WARN   = [35m
CL_ERROR  = [31m

.SUFFIXES:
.SUFFIXES: .log .bb .xbb .pdf .odt .eps .ps .jpg .png .svg .dvi .fmt .tex .cls .sty .ltx .dtx

DEPDIR = .dep
DIFFDIR = .diff

# $(call cache,VARIABLE) expands $(VARIABLE) with caching.
# See https://www.cmcrossroads.com/article/makefile-optimization-eval-and-macro-caching
cache = $(if $(is_cached-$1),,$(eval is_cached-$1 := 1)$(eval cached_val-$1 := $($1)))$(cached_val-$1)

# $(call type,EXEC-FILE) gives the path to the executable if found,
# otherwise empty.
type = $(if $(strip $1),$(strip \
	$(eval type_retval := $(shell which '$(strip $1)' 2>/dev/null)) \
	$(if $(filter-out $(firstword $(type_retval)),$(type_retval)), \
		$(eval type_retval := '$(type_retval)') \
	) \
	$(type_retval) \
))

# $(call switch,STRING,STRING1,VALUE1,STRING2,VALUE2,...) evaluates the value of
# VALUEi corresponding to the first STRINGi that matches to STRING.
# Limitation: up to 4 STRING-VALUE pairs.
switch = \
	$(if $(filter $2,$1),$3, \
		$(if $(filter $4,$1),$5, \
			$(if $(filter $6,$1),$7, \
				$(if $(filter $8,$1),$9, \
				) \
			) \
		) \
	)

# $(call pathsearch,PROG-NAME,NOERROR-IF-NOT-FOUND,NAME1,...) tries to find
# the given executable.
# Limitation: up to 7 NAMEs.
pathsearch = $(strip \
	$(eval retval := ) \
	$(call pathsearch_impl,$3,$4,$5,$6,$7,$8,$9) \
	$(if $2$(retval),,$(eval retval := \
		$(call error_message,$1 not found); \
		exit 1; :)) \
	$(retval) \
)

pathsearch_impl = \
	$(if $(retval),,$(eval retval := $(call type,$1))) \
	$(if $(retval),,$(if $(strip $2 $3 $4 $5 $6 $7 $8 $9),$(call pathsearch_impl,$2,$3,$4,$5,$6,$7,$8,$9)))

# $(target) gives all targets.
target = $(call cache,target_impl)

target_impl = $(strip \
	$(target_impl_from_ltx) \
	$(target_impl_from_tex) \
)

target_impl_from_ltx = $(srcltxfiles:.ltx=.fmt)

target_impl_from_tex = $(strip \
	$(eval retval := ) \
	$(if $(retval),,$(eval retval := $(TARGET))) \
	$(if $(retval),,$(eval retval := $(srctexfiles:.tex=.$(default_target)))) \
	$(retval) \
)

# $(target_basename) gives the result of $(basename $(target)).
target_basename = $(call cache,target_basename_impl)

target_basename_impl = $(basename $(target))

# $(srctexfiles) gives all LaTeX source files.
# They have the ".tex" file extension and
# (1) contain "documentclass", or
# (2) begin with "%&" (including a format file).
srctexfiles = $(call cache,srctexfiles_impl)

srctexfiles_impl = $(strip $(sort \
	$(shell grep documentclass -l *.tex 2>/dev/null) \
	$(shell awk 'FNR==1{if ($$0~"%&") print FILENAME;}' *.tex 2>/dev/null) \
))

# $(srcltxfiles) gives all .ltx files.
srcltxfiles = $(call cache,srcltxfiles_impl)

srcltxfiles_impl = $(wildcard *.ltx)

# $(srcdtxfiles) gives all .dtx files.
srcdtxfiles = $(call cache,srcdtxfiles_impl)

srcdtxfiles_impl = $(wildcard *.dtx)

ifneq ($(DIFF),)

# $(diff_target) gives all latexdiff target files.
diff_target = $(call cache,diff_target_impl)

diff_target_impl = $(strip $(shell \
	$(call get_rev,$(DIFF),_rev1,_rev2,false); \
	if [ -n "$$_rev1" ]; then \
		for _f in $(srctexfiles); do \
			if [ -z "$$_rev2" ]; then \
				if git show "$$_rev1:./$$_f" >/dev/null 2>&1; then \
					echo $${_f%.*}-diff.$(default_target); \
				fi; \
			else \
				if git show "$$_rev1:./$$_f" >/dev/null 2>&1 && git show "$$_rev2:./$$_f" >/dev/null 2>&1; then \
					echo $${_f%.*}-diff.$(default_target); \
				fi ; \
			fi; \
		done; \
	fi \
))

# $(call get_rev,REV-STR,REV1-VAR,REV2-VAR) decomposes the given Git revision(s)
# into 2 variables.
# $(call get_rev,REV-STR,REV1-VAR,REV2-VAR,false) performs the same but without
# checking the revision string.
get_rev = \
	$(if $4,, \
		if [ -z "$1" ]; then \
			$(call error_message,Git revision not given); \
			exit 1; \
		fi; \
	) \
	$2=; \
	$3=; \
	if expr "$1" : '.*[^.]\.\.[^.]' >/dev/null; then \
		$2=$$(expr "$1" : '\(.*[^.]\)\.\.'); \
		$3=$$(expr "$1" : '.*[^.]\.\.\([^.].*\)'); \
	elif expr "$1" : '.*[^.]\.\.$$' >/dev/null; then \
		$2=$$(expr "$1" : '\(.*[^.]\)\.\.'); \
	else \
		$2="$1"; \
	fi; \
	if [ -n "$$$2" ]; then \
		if git cat-file -e "$$$2" 2>/dev/null; then :; else \
			$(call error_message,invalid Git revision: $$$2); \
			exit 1; \
		fi; \
	fi; \
	if [ -n "$$$3" ]; then \
		if git cat-file -e "$$$3" 2>/dev/null; then :; else \
			$(call error_message,invalid Git revision: $$$3); \
			exit 1; \
		fi; \
	fi

endif

# $(subdirs) gives all subdirectories.
subdirs = $(call cache,subdirs_impl)

subdirs_impl = $(strip \
	$(eval retval := ) \
	$(if $(retval),,$(eval retval := $(SUBDIRS))) \
	$(if $(retval),,$(eval retval := $(dir $(wildcard */Makefile)))) \
	$(retval) \
)

# $(call run_testsuite,PREFIX) runs all rules for targets starting with PREFIX
# in the current Makefile.
# $(run_testsuite) is equivalent to $(call run_testsuite,test_).
run_testsuite = \
	for test in $(call all_testsuite,$(if $1,$1,test_)); do \
		echo "Testing $$test..."; \
		$(MAKE) --silent clean; \
		$(MAKE) --always-make --no-print-directory $$test || exit 1; \
	done

all_testsuite = $(shell $(MAKE) -pq _FORCE | sed -n '/^$1/p' | sed 's/:.*//')

assert_true = \
	$(if $(strip $1),:,false)

assert_false = \
	$(if $(strip $1),false,:)

assert_eq = \
	$(if $(and $(findstring $1,$2),$(findstring $2,$1)),echo '$1==$2';:,echo '$1!=$2';false)

assert_success = \
	$(strip $1)

assert_fail = \
	if { $(strip $1); }; then false; else :; fi

# $(is_texlive) is "1" if TeX Live is used, otherwise empty.
is_texlive = $(call cache,is_texlive_impl)

is_texlive_impl = $(strip \
	$(shell $(TEX) --version 2>/dev/null | grep -q 'TeX Live' && echo 1) \
)

# $(is_miktex) is "1" if MiKTeX is used, otherwise empty.
is_miktex = $(call cache,is_miktex_impl)

is_miktex_impl = $(strip \
	$(shell $(TEX) --version 2>/dev/null | grep -q 'MiKTeX' && echo 1) \
)

# $(has_gnu_grep) is "1" if GNU grep is available, otherwise empty.
has_gnu_grep = $(call cache,has_gnu_grep_impl)

has_gnu_grep_impl = $(strip \
	$(shell grep --version 2>/dev/null | grep -q 'GNU' && echo 1) \
)

# $(call rule_exists,RULE) is "1" if RULE exists, otherwise empty.
rule_exists = \
	$(shell $(MAKE) -n $1 >/dev/null 2>&1 && echo 1)

# $(call uppercase,STR) converts STR to uppercase.
uppercase = \
	$(shell echo '$1' | tr a-z A-Z)

# $(call lowercase,STR) converts STR to lowercase.
lowercase = \
	$(shell echo '$1' | tr A-Z a-z)

# $(call sanitize,STR) replaces special characters in STR with underscores.
sanitize = \
	$(shell echo '$1' | sed 's/[^a-zA-Z0-9]/_/g')

# $(init_toolchain) initializes the toolchain.
init_toolchain = $(call cache,init_toolchain_impl)

init_toolchain_impl = $(strip \
	$(eval $(init_toolchain_$(TOOLCHAIN))) \
	$(if $(typeset_mode),,$(error unknown TOOLCHAIN=$(TOOLCHAIN))) \
)

init_toolchain_latex = \
	$(init_toolchain_latex_dvips)

init_toolchain_latex_dvips = \
	$(eval typeset_mode = dvips) \
	$(eval tex_format = latex)

init_toolchain_latex_dvipdf = \
	$(eval typeset_mode = dvipdf) \
	$(eval tex_format = latex)

init_toolchain_platex = \
	$(init_toolchain_platex_dvips)

init_toolchain_platex_dvips = \
	$(eval typeset_mode = dvips_convbkmk) \
	$(eval tex_format = platex) \
	$(eval LATEX = platex) \
	$(eval BIBTEX = pbibtex) \
	$(eval MAKEINDEX = mendex)

init_toolchain_platex_dvipdfmx = \
	$(eval typeset_mode = dvipdf) \
	$(eval tex_format = platex) \
	$(eval LATEX = platex) \
	$(eval DVIPDF = dvipdfmx) \
	$(eval BIBTEX = pbibtex) \
	$(eval MAKEINDEX = mendex)

init_toolchain_uplatex = \
	$(init_toolchain_uplatex_dvips)

init_toolchain_uplatex_dvips = \
	$(eval typeset_mode = dvips_convbkmk) \
	$(eval tex_format = uplatex) \
	$(eval LATEX = uplatex) \
	$(eval BIBTEX = upbibtex) \
	$(eval MAKEINDEX = upmendex)

init_toolchain_uplatex_dvipdfmx = \
	$(eval typeset_mode = dvipdf) \
	$(eval tex_format = uplatex) \
	$(eval LATEX = uplatex) \
	$(eval DVIPDF = dvipdfmx) \
	$(eval BIBTEX = upbibtex) \
	$(eval MAKEINDEX = upmendex)

init_toolchain_pdflatex = \
	$(eval typeset_mode = pdflatex) \
	$(eval tex_format = pdflatex) \
	$(eval LATEX = pdflatex)

init_toolchain_xelatex = \
	$(eval typeset_mode = pdflatex) \
	$(eval tex_format = xelatex) \
	$(eval LATEX = xelatex)

init_toolchain_lualatex = \
	$(eval typeset_mode = pdflatex) \
	$(eval tex_format = lualatex) \
	$(eval LATEX = lualatex) \
	$(eval BIBTEX = upbibtex) \
	$(eval MAKEINDEX = upmendex)

init_toolchain_luajitlatex = \
	$(eval typeset_mode = pdflatex) \
	$(eval tex_format = luajitlatex) \
	$(eval LATEX = luajittex) \
	$(eval LATEX_OPT := --fmt=luajitlatex.fmt $(LATEX_OPT)) \
	$(eval BIBTEX = upbibtex) \
	$(eval MAKEINDEX = upmendex)

# The typeset mode: "dvips" or "dvips_convbkmk" or "dvipdf" or "pdflatex".
typeset_mode =

# The TeX format.
tex_format =

# $(call pathsearch2,PROG-NAME,VAR-NAME,NAME1,...) is basically pathsearch after
# calling init_toolchain.
pathsearch2 = $(strip \
	$(init_toolchain) \
	$(call pathsearch,$1,,$($2),$3,$4,$5,$6,$7,$8,$9) \
)

# $(latex)
latex = $(call cache,latex_impl)

latex_impl = $(strip \
	$(latex_noopt) $(LATEX_OPT) \
	$(if $(findstring -recorder,$(LATEX_OPT)),,-recorder) \
)

# (latex_noopt) doesn't include $(LATEX_OPT).
latex_noopt = $(call cache,latex_noopt_impl)$(if $(BUILDDIR), -output-directory=$(BUILDDIR))

latex_noopt_impl = $(init_toolchain)$(call pathsearch,latex$(if $(DEV),-dev),,$(LATEX)$(if $(DEV),-dev),latex$(if $(DEV),-dev))

# $(dvips)
dvips = $(call cache,dvips_impl) $(DVIPS_OPT)

dvips_impl = $(call pathsearch2,dvips,DVIPS,dvips,dvipsk)

# $(dvipdf)
dvipdf = $(call cache,dvipdf_impl) $(DVIPDF_OPT)

dvipdf_impl = $(call pathsearch2,dvipdf,DVIPDF,dvipdf,dvipdfm,dvipdfmx)

# $(ps2pdf)
ps2pdf = $(call cache,ps2pdf_impl) $(PS2PDF_OPT)

ps2pdf_impl = $(call pathsearch2,ps2pdf,PS2PDF,ps2pdf)

# $(dvisvgm)
dvisvgm = $(call cache,dvisvgm_impl) $(DVISVGM_OPT)

dvisvgm_impl = $(call pathsearch2,dvisvgm,DVISVGM,dvisvgm)

# $(pdftoppm)
pdftoppm = $(call cache,pdftoppm_impl) $(PDFTOPPM_OPT)

pdftoppm_impl = $(call pathsearch2,pdftoppm,PDFTOPPM,pdftoppm)

# $(gs)
gs = $(call cache,gs_impl) $(GS_OPT)

gs_impl = $(call pathsearch2,gs,GS,gs,gswin32,gswin64,gsos2)

# $(bibtex)
bibtex = $(call cache,bibtex_impl) $(BIBTEX_OPT)

bibtex_impl = $(call pathsearch2,bibtex,BIBTEX,bibtex)

# $(biber)
biber = $(call cache,biber_impl) $(BIBER_OPT)

biber_impl = $(call pathsearch2,biber,BIBER,biber)

# $(sortref)
sortref = $(call cache,sortref_impl) $(SORTREF_OPT)

sortref_impl = $(call pathsearch2,sortref,SORTREF,sortref)

# $(makeindex)
makeindex = $(call cache,makeindex_impl) $(MAKEINDEX_OPT)

makeindex_impl = $(call pathsearch2,makeindex,MAKEINDEX,makeindex)

# $(makeglossaries)
makeglossaries = $(call cache,makeglossaries_impl) $(MAKEGLOSSARIES_OPT)

makeglossaries_impl = $(call pathsearch2,makeglossaries,MAKEGLOSSARIES,makeglossaries)

# $(bib2gls)
bib2gls = $(call cache,bib2gls_impl) $(BIB2GLS_OPT)

bib2gls_impl = $(call pathsearch2,bib2gls,BIB2GLS,bib2gls)

# $(latexindent)
latexindent = $(call cache,latexindent_impl) $(LATEXINDENT_OPT)

latexindent_impl = $(call pathsearch2,latexindent,LATEXINDENT,latexindent)

# $(chktex)
chktex = $(call cache,chktex_impl) $(CHKTEX_OPT)

chktex_impl = $(call pathsearch2,chktex,CHKTEX,chktex)

# $(aspell)
aspell = $(call cache,aspell_impl) $(ASPELL_OPT)

aspell_impl = $(call pathsearch2,aspell,ASPELL,aspell)

# $(hunspell)
hunspell = $(call cache,hunspell_impl) $(HUNSPELL_OPT)

hunspell_impl = $(call pathsearch2,hunspell,HUNSPELL,hunspell)

# $(textlint)
textlint = $(call cache,textlint_impl) $(TEXTLINT_OPT)

textlint_impl = $(call pathsearch2,textlint,TEXTLINT,node_modules/.bin/textlint,\
$(shell git rev-parse --show-toplevel 2>/dev/null)/node_modules/.bin/textlint,\
$(shell git rev-parse --show-superproject-working-tree 2>/dev/null)/node_modules/.bin/textlint,\
../node_modules/.bin/textlint,\
../../node_modules/.bin/textlint,\
textlint)

# $(redpen)
redpen = $(call cache,redpen_impl) $(REDPEN_OPT)

redpen_impl = $(call pathsearch2,redpen,REDPEN,redpen)

# $(kpsewhich)
kpsewhich = $(call cache,kpsewhich_impl) $(KPSEWHICH_OPT)

kpsewhich_impl = $(call pathsearch2,kpsewhich,KPSEWHICH,kpsewhich)

# $(axohelp)
axohelp = $(call cache,axohelp_impl) $(AXOHELP_OPT)

axohelp_impl = $(call pathsearch2,axohelp,AXOHELP,axohelp)

# $(pdfcrop)
pdfcrop = $(call cache,pdfcrop_impl) $(PDFCROP_OPT)

pdfcrop_impl = $(call pathsearch2,pdfcrop,PDFCROP,pdfcrop)

# $(ebb)
ebb = $(call cache,ebb_impl) $(EBB_OPT)

ebb_impl = $(call pathsearch2,ebb,EBB,ebb)

# $(extractbb)
extractbb = $(call cache,extractbb_impl) $(EXTRACTBB_OPT)

extractbb_impl = $(call pathsearch2,extractbb,EXTRACTBB,extractbb)

# $(convbkmk)
convbkmk = $(call cache,convbkmk_impl) $(CONVBKMK_OPT)

convbkmk_impl = $(call pathsearch2,convbkmk,CONVBKMK,convbkmk)

# $(latexpand)
latexpand = $(call cache,latexpand_impl) $(LATEXPAND_OPT)

latexpand_impl = $(call pathsearch2,latexpand,LATEXPAND,latexpand)

# $(latexdiff)
latexdiff = $(call cache,latexdiff_impl) $(LATEXDIFF_OPT)

latexdiff_impl = $(call pathsearch2,latexdiff,LATEXDIFF,latexdiff)

# $(download) <OUTPUT-FILE> <URL>
download = $(strip \
	$(if $(_download_wget_found)$(_download_curl_found),,$(call _download_init)) \
	$(if $(_download_wget_found), \
		$(_download_wget_found) $(WGET_OPT) -O \
	, \
		$(if $(_download_curl_found), \
			$(_download_curl_found) $(CURL_OPT) -L -o \
		, \
			$(call error_message,both wget and curl not found); exit 1; \
		) \
	) \
)

_download_init = $(strip \
	$(if $(_download_wget_found),,$(eval _download_wget_found := $(call pathsearch,wget,true,$(WGET),wget))) \
	$(if $(_download_wget_found)$(_download_curl_found),,$(eval _download_curl_found := $(call pathsearch,curl,true,$(CURL),curl))) \
)

_download_wget_found =
_download_curl_found =

# $(soffice)
soffice = $(call cache,soffice_impl) $(SOFFICE_OPT)

soffice_impl = $(call pathsearch2,soffice,SOFFICE, \
	soffice, \
	/cygdrive/c/Program Files/LibreOffice 6/program/soffice, \
	/cygdrive/c/Program Files (x86)/LibreOffice 6/program/soffice, \
	/cygdrive/c/Program Files/LibreOffice 5/program/soffice, \
	/cygdrive/c/Program Files (x86)/LibreOffice 5/program/soffice, \
	/cygdrive/c/Program Files/LibreOffice 4/program/soffice, \
	/cygdrive/c/Program Files (x86)/LibreOffice 4/program/soffice \
)

# $(Makefile) gives the name of this Makefile.
Makefile = $(call cache,Makefile_impl)

Makefile_impl = $(firstword $(MAKEFILE_LIST))

# $(mostlycleanfiles) gives all intermediately generated files, to be deleted by
# "make mostlyclean".
#   .aux - LaTeX auxiliary file
#   .auxlock - TikZ externalization aux file lock
#   .ax1 - axodraw2 auxiliary (axohelp input) file
#   .ax2 - axohelp output file
#   .bak[0-9]* - latexindent backup file
#   .bbl - BibTeX output file
#   .bcf - by biblatex package
#   .blg - BibTeX log file
#   .end - ?
#   .fls - LaTeX recorder file
#   .fmt - TeX format file
#   .glg - glossary log file
#   .glo - glossary entries
#   .gls - glossary output
#   .glsdefs - glossary output
#   .glstex - by bib2gls
#   .idx - index entries
#   .ilg - index log file
#   .ind - index output
#   .ist - index style file
#   .lof - list of figures
#   .log - (La)TeX log file
#   .lot - list of tables
#   .nav - Beamer navigation items
#   .out - Beamer outlines
#   .run.xml - by logreq package
#   .snm - Beamer page labels
#   .spl - by elsarticle class
#   .toc - table of contents
#   .*.vrb - Beamer verbatim materials
#   .xdy - by xindy
#   Notes.bib - by revtex package
#   *-blx.aux - by biblatex package
#   -blx.bib - by biblatex package
#   _ref.tex - by sortref
#   .bmc - by dviout
#   .pbm - by dviout
#   -eps-converted-to.pdf - by epstopdf
#   -indent.log - by latexindent+makefile4latex
mostlycleanfiles = $(call cache,mostlycleanfiles_impl)

mostlycleanfiles_impl = $(wildcard $(strip \
	$(srctexfiles:.tex=.aux) \
	$(srctexfiles:.tex=.auxlock) \
	$(srctexfiles:.tex=.ax1) \
	$(srctexfiles:.tex=.ax2) \
	$(srctexfiles:.tex=.bak[0-9]*) \
	$(srctexfiles:.tex=.bbl) \
	$(srctexfiles:.tex=.bcf) \
	$(srctexfiles:.tex=.blg) \
	$(srctexfiles:.tex=.end) \
	$(srctexfiles:.tex=.fls) \
	$(srctexfiles:.tex=.fmt) \
	$(srctexfiles:.tex=.glg) \
	$(srctexfiles:.tex=.glo) \
	$(srctexfiles:.tex=.gls) \
	$(srctexfiles:.tex=.glsdefs) \
	$(srctexfiles:.tex=.glstex) \
	$(srctexfiles:.tex=.idx) \
	$(srctexfiles:.tex=.ilg) \
	$(srctexfiles:.tex=.ind) \
	$(srctexfiles:.tex=.ist) \
	$(srctexfiles:.tex=.lof) \
	$(srctexfiles:.tex=.log) \
	$(srctexfiles:.tex=.lot) \
	$(srctexfiles:.tex=.nav) \
	$(srctexfiles:.tex=.out) \
	$(srctexfiles:.tex=.run.xml) \
	$(srctexfiles:.tex=.snm) \
	$(srctexfiles:.tex=.spl) \
	$(srctexfiles:.tex=.synctex) \
	$(srctexfiles:.tex=.synctex.gz) \
	$(srctexfiles:.tex=.toc) \
	$(srctexfiles:.tex=.*.vrb) \
	$(srctexfiles:.tex=.xdy) \
	$(srctexfiles:.tex=Notes.bib) \
	$(srctexfiles:.tex=*-blx.aux) \
	$(srctexfiles:.tex=*-blx.bbl) \
	$(srctexfiles:.tex=*-blx.blg) \
	$(srctexfiles:.tex=-blx.bib) \
	$(srctexfiles:.tex=_ref.tex) \
	$(srcltxfiles:.ltx=.log) \
	*.bmc \
	*.pbm \
	*-convbkmk.ps \
	*-eps-converted-to.pdf \
	*.bb \
	*.xbb \
	*_tmp.??? \
	*-indent.log \
	*/*-eps-converted-to.pdf \
	$(srctexfiles:.tex=-figure*.dpth) \
	$(srctexfiles:.tex=-figure*.log) \
	$(srctexfiles:.tex=-figure*.md5) \
	$(srctexfiles:.tex=-figure*.pdf) \
	$(srctexfiles:.tex=-diff.dvi) \
	$(srctexfiles:.tex=-diff.ps) \
	$(srctexfiles:.tex=-diff.pdf) \
	$(MOSTLYCLEANFILES) \
))

# $(cleanfiles) gives all generated files to be deleted by "make clean".
cleanfiles = $(call cache,cleanfiles_impl)

cleanfiles_impl = $(wildcard $(strip \
	$(srctexfiles:.tex=.tar.gz) \
	$(srctexfiles:.tex=.pdf) \
	$(srctexfiles:.tex=.ps) \
	$(srctexfiles:.tex=.eps) \
	$(srctexfiles:.tex=.dvi) \
	$(srctexfiles:.tex=.svg) \
	$(srctexfiles:.tex=.jpg) \
	$(srctexfiles:.tex=.png) \
	$(srcltxfiles:.ltx=.fmt) \
	$(srcdtxfiles:.dtx=.cls) \
	$(srcdtxfiles:.dtx=.sty) \
	$(CLEANFILES) \
	$(mostlycleanfiles) \
))

# $(color) gives the color mode in the output:
# - always
# - never
# - auto (default)
#
# Usually controlled via $(COLOR) given on the command line or
# in the user configuration files.
#
# For compatibility with previous versions:
# - fall back to $(MAKE_COLORS), if $(COLOR) is empty,
# - allow "none", which is translated to "never".
#
# NOTE: use of MAKE_COLORS is deprecated. In future, MAKE_COLORS might be
# used for customizing colorings, like LS_COLORS or GCC_COLORS.
#
color = $(call cache,color_impl)
color_impl = $(strip \
	$(if $(_get_color), \
		$(if $(or \
			$(findstring always,$(_get_color)), \
			$(findstring never,$(_get_color)), \
			$(findstring auto,$(_get_color)) \
		), \
			$(_get_color) \
		,$(if $(findstring none,$(_get_color)), \
			never \
		, \
			$(warning unrecognized COLOR=$(_get_color)) \
			auto \
		)) \
	, \
		auto \
	) \
)
_get_color = $(if $(COLOR),$(COLOR),$(MAKE_COLORS))

# $(color_enabled) is a shell script snippet that returns the exit code 0 if
# coloring is enabled, otherwise returns a non-zero value.
color_enabled = \
	$(if $(findstring always,$(color)), \
		: \
	,$(if $(findstring never,$(color)), \
		false \
	, \
		[ -t 1 ] \
	))

# $(call colorize,COMMAND-WITH-COLOR,COMMAND-WITHOUT-COLOR) invokes the first
# command when coloring is enabled, otherwise invokes the second command.
colorize = \
	$(if $(findstring always,$(color)), \
		$1 \
	,$(if $(findstring never,$(color)), \
		$2 \
	, \
		if [ -t 1 ]; then \
			$1; \
		else \
			$2; \
		fi \
	))

# $(call notification_message,MESSAGE) prints a notification message.
notification_message = \
	$(call colorize, \
		printf "\033$(CL_NOTICE)$1\033$(CL_NORMAL)\n" >&2 \
	, \
		echo "$1" >&2 \
	)

# $(call warning_message,MESSAGE) prints a warning message.
warning_message = \
	$(call colorize, \
		printf "\033$(CL_WARN)Warning: $1\033$(CL_NORMAL)\n" >&2 \
	, \
		echo "Warning: $1" >&2 \
	)

# $(call error_message,MESSAGE) prints an error message.
error_message = \
	$(call colorize, \
		printf "\033$(CL_ERROR)Error: $1\033$(CL_NORMAL)\n" >&2 \
	, \
		echo "Error: $1" >&2 \
	)

# $(call set_title,TITLE) changes the window title. (Default: do nothing.)
set_title = :

# $(call exec,COMMAND) invokes the command with checking the exit status.
# $(call exec,COMMAND,false) invokes the command but skips the check.
# $(call exec,COMMAND,,COLOR_FILTER) and $(call exec,COMMAND,false,COLOR_FILTER)
# use COLOR_FILTER for the stdout.
exec = \
	$(if $(and $(findstring not found,$1),$(findstring exit 1,$1)), \
		$1 \
	, \
		failed=false; \
		$(call colorize, \
			printf "\033$(CL_NOTICE)$1\033$(CL_NORMAL)\n"; \
			exec 3>&1; \
			pipe_status=`{ { $1 3>&- 4>&-; echo $$? 1>&4; } $(call colorize_output_join,$3) | \
					$(call colorize_output,$3) >&3; } 4>&1`; \
			exec 3>&-; \
			[ "$$pipe_status" = 0 ] || failed=: \
		, \
			echo "$1"; \
			$1 || failed=: \
		) \
		$(if $2,,; $(check_failed)) \
	)

# $(check_failed)
check_failed = $$failed && { [ -n "$$dont_delete_on_failure" ] || rm -f $@; exit 1; }; :

# $(colorize_output) gives sed commands for colorful output.
# $(colorize_output,COLOR_FILTER) gives an application specific filter.
colorize_output = $(colorize_output_$1)

colorize_output_ = cat

# $(colorize_output,COLOR_FILTER) gives "2>&1" to combine the stderr into the stdout, if needed for the COLOR_FILTER.
colorize_output_join = $(if $(colorize_output_$1_join),2>&1,)

# Errors for LaTeX:
#   "! ...": TeX
# Warnings for LaTeX:
#   "LaTeX Warning ...": \@latex@warning
#   "Package Warning ...": \PackageWarning or \PackageWarningNoLine
#   "Class Warning ...": \ClassWarning or \ClassWarningNoLine
#   "No file ...": \@input{filename}
#   "No pages of output.": TeX
#   "Underfull ...": TeX
#   "Overfull ...": TeX
#   "pdfTeX warning ...": pdfTeX
colorize_output_latex = \
	sed 's/^\(!.*\)/\$\$\x1b$(CL_ERROR)\1\$\$\x1b$(CL_NORMAL)/; \
	s/^\(LaTeX[^W]*Warning.*\|Package[^W]*Warning.*\|Class[^W]*Warning.*\|No file.*\|No pages of output.*\|Underfull.*\|Overfull.*\|.*pdfTeX warning.*\)/\$\$\x1b$(CL_WARN)\1\$\$\x1b$(CL_NORMAL)/'

# Errors for BibTeX:
#   "I couldn't open database file ..."
#   "I couldn't open file name ..."
#   "I found no database files---while reading file ..."
#   "I found no \bibstyle command---while reading file ..."
#   "I found no \citation commands---while reading file ..."
#   "Repeated entry--- ..."
# Warnings for BibTeX:
#   "Warning-- ..."
colorize_output_bibtex = \
	sed 's/^\(I couldn.t open database file.*\|I couldn.t open file name.*\|I found no database files---while reading file.*\|I found no .bibstyle command---while reading file.*\|I found no .citation commands---while reading file.*\|Repeated entry---.*\)/\$\$\x1b$(CL_ERROR)\1\$\$\x1b$(CL_NORMAL)/; \
	s/^\(Warning--.*\)/\$\$\x1b$(CL_WARN)\1\$\$\x1b$(CL_NORMAL)/'

# Warnings for dvipdfmx:
#   "dvipdfmx:warning: ..." (stderr)
colorize_output_dvipdf = \
	sed 's/^\(dvipdfmx:warning: .*\)/\$\$\x1b$(CL_WARN)\1\$\$\x1b$(CL_NORMAL)/'

colorize_output_dvipdf_join = 1

# Errors for ChkTeX:
#   "Error ... in ... line ...:"
# Warnings for ChkTeX:
#   "Warning ... in ... line ...:"
colorize_output_chktex = \
	sed 's/^\(Error .* in.* line.*:.*\)/\$\$\x1b$(CL_ERROR)\1\$\$\x1b$(CL_NORMAL)/; \
	s/^\(Warning .* in.* line.*:.*\)/\$\$\x1b$(CL_WARN)\1\$\$\x1b$(CL_NORMAL)/'

# For RedPen:
#   "...:...: ValidationError[...], ..."
colorize_output_redpen = \
	sed 's/^\(.*: ValidationError\[.*\]\)\(.*\)/\$\$\x1b$(CL_ERROR)\1\$\$\x1b$(CL_WARN)\2\$\$\x1b$(CL_NORMAL)/'

# $(call cmpver,VER1,OP,VER2) compares the given two version numbers.
cmpver = { \
	cmpver_ver1_="$1"; \
	cmpver_ver2_="$3"; \
	$(call cmpver_fmt_,cmpver_ver1_); \
	$(call cmpver_fmt_,cmpver_ver2_); \
	$(if $(filter -eq,$2), \
		[ $$cmpver_ver1_ = $$cmpver_ver2_ ]; \
	, \
		$(if $(filter -ne,$2), \
			[ $$cmpver_ver1_ != $$cmpver_ver2_ ]; \
		, \
			cmpver_small_=`{ echo $$cmpver_ver1_; echo $$cmpver_ver2_; } | sort | head -1`; \
			$(if $(filter -le,$2),[ $$cmpver_small_ = $$cmpver_ver1_ ];) \
			$(if $(filter -lt,$2),[ $$cmpver_small_ = $$cmpver_ver1_ ] && [ $$cmpver_ver1_ != $$cmpver_ver2_ ];) \
			$(if $(filter -ge,$2),[ $$cmpver_small_ = $$cmpver_ver2_ ];) \
			$(if $(filter -gt,$2),[ $$cmpver_small_ = $$cmpver_ver2_ ] && [ $$cmpver_ver1_ != $$cmpver_ver2_ ];) \
		) \
	) \
	}

# $(call cmpver_fmt_,VAR)
cmpver_fmt_ = \
	$1=`expr "$$$1" : '[^0-9]*\([0-9][0-9]*\(\.[0-9][0-9]*\)*\)' | sed 's/\./ /g'`; \
	$1=`printf '%05d' $$$1`

##

ifneq ($(subdirs),)

# $(call make_for_each_subdir,TARGET) invokes Make for the given target
# (if exists) in all subdirectories.
make_for_each_subdir = \
	for dir in $(subdirs); do \
		if $(MAKE) -n -C $$dir $1 >/dev/null 2>&1; then \
			$(MAKE) -C $$dir $1; \
		fi; \
	done

else

make_for_each_subdir = :

endif

##

ifeq ($(DIFF),)

all: $(target)
	@$(if $(POSTPROCESS),$(MAKE) --no-print-directory postprocess,:)

else

all: $(diff_target)

endif

all-recursive:
	@$(call make_for_each_subdir,all-recursive)
	@$(MAKE) all

help: export help_message1 = $(help_message)
help:
	@echo "$$help_message1"

dvi: $(target_basename:=.dvi)

ps: $(target_basename:=.ps)

eps: $(target_basename:=.eps)

svg: $(target_basename:=.svg)

jpg: $(target_basename:=.jpg)

png: $(target_basename:=.png)

pdf: $(target_basename:=.pdf)

dist: $(target_basename:=.tar.gz)

fmt: $(target_basename:=.fmt)

$(target_basename:=.dvi) \
$(target_basename:=.ps) \
$(target_basename:=.eps) \
$(target_basename:=.svg) \
$(target_basename:=.jpg) \
$(target_basename:=.png) \
$(target_basename:=.pdf): | prerequisite

prerequisite: _prerequisite
	@$(call make_for_each_subdir,$(PREREQUISITE_SUBDIRS))

postprocess: _postprocess

mostlyclean:
	@$(call make_for_each_subdir,mostlyclean)
	@$(if $(mostlycleanfiles),$(call exec,rm -f $(mostlycleanfiles)))
	@$(if $(wildcard $(DEPDIR) $(DIFFDIR) $(BUILDDIR) $(MOSTLYCLEANDIRS)), \
		$(call exec,rm -rf $(wildcard $(DEPDIR) $(DIFFDIR) $(BUILDDIR) $(MOSTLYCLEANDIRS))) \
	)

clean:
	@$(call make_for_each_subdir,clean)
	@$(if $(cleanfiles),$(call exec,rm -f $(cleanfiles)))
	@$(if $(wildcard $(DEPDIR) $(DIFFDIR) $(BUILDDIR) $(MOSTLYCLEANDIRS) $(CLEANDIRS)), \
		$(call exec,rm -rf $(wildcard $(DEPDIR) $(DIFFDIR) $(BUILDDIR) $(MOSTLYCLEANDIRS) $(CLEANDIRS))) \
	)

pretty:
	@pretty_ok=:; \
	$(foreach prettifier,$(PRETTIFIERS), \
		$(if $(wildcard $(prettifier)), \
			$(call _pretty_run,./$(prettifier)) \
		,$(if $(and $(filter-out pretty,$(prettifier)),$(call rule_exists,$(prettifier))), \
			$(call _pretty_rule,$(prettifier)) \
		,$(if $(call rule_exists,_builtin_pretty_$(prettifier)), \
			$(call _pretty_builtin_rule,$(prettifier)) \
		, \
			$(call _pretty_run,$(prettifier)) \
		))) \
	) \
	$$pretty_ok

# $(call _pretty_run,EXECUTABLE) runs EXECUTABLE.
_pretty_run = \
	$(foreach texfile,$(call _rule_wildcard,$1), \
		$(call exec,$1 $(texfile),false); \
		$$failed && pretty_ok=false; \
	)

# $(call _pretty_rule,RULE) runs RULE.
_pretty_rule = \
	$(foreach texfile,$(call _rule_wildcard,$1), \
		$(call colorize, \
			printf "\033$(CL_NOTICE)$(MAKE) $1 1=$(texfile)\033$(CL_NORMAL)\n" \
		, \
			echo "$(MAKE) $1 1=$(texfile) " \
		); \
		$(MAKE) --no-print-directory $1 1="$(texfile)" || pretty_ok=false; \
	)

# $(call _pretty_builtin_rule,RULE) runs the builtin RULE.
_pretty_builtin_rule = \
	$(foreach texfile,$(call _rule_wildcard,$1), \
		$(MAKE) --no-print-directory _builtin_pretty_$1 1=$(texfile) || pretty_ok=false; \
	)

# $(call _rule_wildcard,RULE,DEFAULT_PATTERN) gives target files for RULE.
# $(call _rule_wildcard,RULE) is the same but with DEFAULT_PATTERN=*.tex.
_rule_wildcard = \
	$(wildcard $(or $($(call uppercase,$(call sanitize,$1))_TARGET),$2,*.tex))

# NOTE: $(ensure_build_dir) needed for old versions, latexindent < 3.22.2.
#       See https://github.com/cmhughes/latexindent.pl/issues/452.
_builtin_pretty_latexindent:
	@$(ensure_build_dir)
	@$(call exec,$(latexindent)$(if $(BUILDDIR), -c $(BUILDDIR)) -g "$1-indent.log" $1)

lint:
	@lint_ok=:; \
	$(foreach lint,$(LINTS), \
		$(if $(wildcard $(lint)), \
			$(call _lint_run,./$(lint)) \
		,$(if $(and $(filter-out lint,$(lint)),$(call rule_exists,$(lint))), \
			$(call _lint_rule,$(lint)) \
		,$(if $(call rule_exists,_builtin_lint_$(lint)), \
			$(call _lint_builtin_rule,$(lint)) \
		, \
			$(call _lint_run,$(lint)) \
		))) \
	) \
	$$lint_ok

# $(call _lint_run,EXECUTABLE) runs EXECUTABLE.
_lint_run = \
	$(foreach texfile,$(call _rule_wildcard,$1), \
		$(call exec,$1 $(texfile),false); \
		$$failed && lint_ok=false; \
	)

# $(call _lint_rule,RULE) runs RULE.
_lint_rule = \
	$(foreach texfile,$(call _rule_wildcard,$1), \
		$(call colorize, \
			printf "\033$(CL_NOTICE)$(MAKE) $1 1=$(texfile)\033$(CL_NORMAL)\n" \
		, \
			echo "$(MAKE) $1 1=$(texfile) " \
		); \
		$(MAKE) --no-print-directory $1 1="$(texfile)" || lint_ok=false; \
	)

# $(call _lint_builtin_rule,RULE) runs the builtin RULE.
_lint_builtin_rule = \
	$(foreach texfile,$(call _rule_wildcard,$1), \
		$(MAKE) --no-print-directory _builtin_lint_$1 1=$(texfile) || lint_ok=false; \
	)

# Check common mistakes about spacing after periods (deprecated).
_builtin_lint_check_periods:
	@$(call colorize, \
		printf "\033$(CL_NOTICE)check_periods $1\033$(CL_NORMAL)\n" \
	, \
		echo "check_periods $1" \
	)
	@grep_opts=; \
	$(if $(has_gnu_grep), \
		if $(color_enabled); then \
			grep_opts=--color=always; \
		fi; \
	) \
	if grep -n $$grep_opts '[A-Z][A-Z][A-Z]*)\?\.' $1; then \
		$(call error_message,most likely wrong spacing after periods. You may need to insert \\@); \
		exit 1; \
	fi

_builtin_lint_chktex:
	@$(call exec,$(chktex) $1,,chktex)

_builtin_lint_aspell:
	@$(aspell) -v >/dev/null 2>&1
	@$(call colorize, \
		printf "\033$(CL_NOTICE)$(aspell) -a -t <$1\033$(CL_NORMAL)\n" \
	, \
		echo "$(aspell) -a -t <$1" \
	)
	@$(call _grep_misspellings,$1,$(aspell) -a -t <"$1" | tail -n +2 | cut -d ' ' -f 2 | grep -v '*' | sed '/^$$/d')

# $(call _grep_misspellings,FILE,CHECKER) searches for misspelled words listed
# by the CHECKER command in FILE, and aborts if there are misspelled words.
_grep_misspellings = \
	_grep_expr=$$($2 | sort | uniq | awk '{printf "-e %s ",$$0}'); \
	if [ -n "$$_grep_expr" ]; then \
		_grep_opts=; \
		$(if $(has_gnu_grep), \
			_grep_opts=-w; \
			if $(color_enabled); then \
				_grep_opts="$$_grep_opts --color=always"; \
			fi; \
		) \
		grep -n $$_grep_opts $$_grep_expr "$1"; \
		exit 1; \
	fi

_builtin_lint_hunspell:
	@$(hunspell) -v >/dev/null 2>&1
	@$(call colorize, \
		printf "\033$(CL_NOTICE)$(hunspell) -l -t $1\033$(CL_NORMAL)\n" \
	, \
		echo "$(hunspell) -l -t $1" \
	)
	@$(call _grep_misspellings,$1,$(hunspell) -l -t "$1")

_builtin_lint_textlint:
	@if $(color_enabled); then \
		$(call exec,$(textlint) --color $1); \
	else \
		$(call exec,$(textlint) --no-color $1); \
	fi

_builtin_lint_redpen:
	@$(call exec,$(redpen) $1,,redpen)

check:
	@$(call make_for_each_subdir,check)
	@$(foreach test,$(TESTS), \
		$(if $(wildcard $(test)), \
			$(call _check_run,./$(test)) \
		,$(if $(and $(filter-out check,$(test)),$(call rule_exists,$(test))), \
			$(call _check_rule,$(test)) \
		, \
			$(call _check_run,$(test)) \
		)) \
	)

# $(call _check_run,EXECUTABLE) runs EXECUTABLE.
_check_run = \
	$(if $(TESTS_PARAMS), \
		$(foreach param,$(TESTS_PARAMS), \
			$(call exec,$1 $(call TESTS_OPT,$1,$(param)) $(param)); \
		) \
	, \
		$(call exec,$1 $(call TESTS_OPT,$1)); \
	)

# $(call _check_rule,RULE) runs RULE.
_check_rule = \
	$(if $(TESTS_PARAMS), \
		$(foreach param,$(TESTS_PARAMS), \
			$(call colorize, \
				printf "\033$(CL_NOTICE)$(MAKE) $1 1=\"$(call TESTS_OPT,$1,$(param)) $(param)\"\033$(CL_NORMAL)\n" \
			, \
				echo "$(MAKE) $1 1=\"$(call TESTS_OPT,$1,$(param)) $(param)\"" \
			); \
			$(MAKE) --no-print-directory $1 1="$(call TESTS_OPT,$1,$(param)) $(param)" || exit 1; \
		) \
	, \
		$(call colorize, \
			printf "\033$(CL_NOTICE)$(MAKE) $1 1=\"$(call TESTS_OPT,$1)\"\033$(CL_NORMAL)\n" \
		, \
			echo "$(MAKE) $1 1=\"$(call TESTS_OPT,$1)\"" \
		); \
		$(MAKE) --no-print-directory $1 1="$(call TESTS_OPT,$1)" || exit 1; \
	)

# The "watch" mode. Try to update .log files instead of .pdf/.dvi files,
# otherwise make would continuously try to typeset for sources previously
# failed.
#
# NOTE: making .log files requires BUILDDIR=$(BUILDDIR) because the pattern rule
# needs the value when the rule is defined (before including user configuration
# files).
watch:
	@$(init_toolchain)
	@if $(if $(srctexfiles:.tex=.$(default_target)),:,false); then \
		$(call set_title,watching); \
		if $(MAKE) -q -s $(srctexfiles:.tex=.$(default_target)); then :; else \
			$(call set_title,running); \
			if time $(SHELL) -c "$(MAKE) -s $(srctexfiles:.tex=.$(default_target)) && $(MAKE) -s postprocess"; then \
				$(call set_title,watching); \
			else \
				$(call set_title,failed); \
			fi; \
		fi; \
		$(ensure_build_dir); \
		touch $(addprefix $(build_prefix),$(srctexfiles:.tex=.log)); \
		$(print_watching_message); \
		$(define_wait_command); \
		while :; do \
			$$MAKEFILE4LATEX_WAIT_COMMAND; \
			if $(MAKE) -q -s BUILDDIR=$(BUILDDIR) $(addprefix $(build_prefix),$(srctexfiles:.tex=.log)); then :; else \
				$(call set_title,running); \
				if time $(SHELL) -c "$(MAKE) -s BUILDDIR=$(BUILDDIR) $(addprefix $(build_prefix),$(srctexfiles:.tex=.log)) && $(MAKE) -s postprocess"; then \
					$(call set_title,watching); \
				else \
					$(call set_title,failed); \
				fi; \
				$(print_watching_message); \
			fi; \
		done \
	else \
		echo "No files to watch"; \
	fi

print_watching_message = $(call colorize, \
	printf "Watching for $(srctexfiles:.tex=.$(default_target)). \033$(CL_NOTICE)Press Ctrl+C to quit\033$(CL_NORMAL)\n" \
, \
	echo "Watching for $(srctexfiles:.tex=.$(default_target)). Press Ctrl+C to quit" \
)

# $(call define_wait_command) defines $MAKEFILE4LATEX_WAIT_COMMAND in
# the current shell as follows:
# (1) If $(MAKEFILE4LATEX_WAIT_COMMAND) is defined at the level of
#     Makefile (from the configuration files or command line options),
#     then use it.
# (2) If $MAKEFILE4LATEX_WAIT_COMMAND is defined at the level of
#     the shell (i.e., as the environment variable), then use it.
# (3) Otherwise, provide the default command "sleep 1".
define_wait_command = \
	$(if $(MAKEFILE4LATEX_WAIT_COMMAND), \
		MAKEFILE4LATEX_WAIT_COMMAND="$(MAKEFILE4LATEX_WAIT_COMMAND)" \
	, \
		if [ -z "$$MAKEFILE4LATEX_WAIT_COMMAND" ]; then \
			MAKEFILE4LATEX_WAIT_COMMAND="sleep 1"; \
		fi \
	)

# Upgrade files in the setup. (Be careful!)
# Files to be upgraded must have a tag like
#
#   latest-raw-url: https://raw.githubusercontent.com/tueda/makefile4latex/master/Makefile
#
# When the current directory is a Git repository and doesn't have the .gitignore
# file, this target downloads that of the Makefile4LaTeX repository.
#
# If the Makefile with a fixed version is used, then we need to prevent the
# upgrade from replacing the versioned Makefile. In the current implementation,
# we stop upgrading files that have names ending with "Makefile", assuming they
# all must not be upgraded. For now, we ignore the case with a commit hash
# starting with "v", which usually means a version tag like "v0.3.2".
upgrade:
	@$(call make_for_each_subdir,upgrade)
	@for file in * .* $(_cached_Makefile); do \
		case "$$file" in \
			*.swp|*.tmp|*~) \
				continue \
				;; \
			*Makefile) \
				case "$(MAKEFILE4LATEX_REVISION)" in \
					v*) \
						continue \
						;; \
				esac; \
				case "$(MAKEFILE4LATEX_VERSION)" in \
					*-dev) \
						;; \
					*) \
						continue \
						;; \
				esac; \
				;; \
		esac; \
		if [ -f "$$file" ] && [ ! -L "$$file" ]; then \
			if grep -q 'latest-raw-url *: *.' "$$file" >/dev/null 2>&1; then \
				url=$$(grep 'latest-raw-url *: *.' "$$file" | head -1 | sed 's/.*latest-raw-url *: *//' | sed 's/ .*//'); \
				$(call upgrade,$$file,$$url); \
			fi \
		fi; \
	done
	@if [ -d .git ] && [ ! -f .gitignore ]; then \
		$(call upgrade,.gitignore,https://raw.githubusercontent.com/tueda/makefile4latex/master/.gitignore); \
	fi

# $(call upgrade,FILE,URL) tries to upgrade the given file.
upgrade = \
	$(download) "$1.tmp" "$2" && { \
		if diff -q "$1" "$1.tmp" >/dev/null 2>&1; then \
			$(call notification_message,$1 is up-to-date); \
			rm -f "$1.tmp"; \
		else \
			mv -v "$1.tmp" "$1"; \
			$(call notification_message,$1 is updated); \
		fi; \
		:; \
	}

_FORCE:

_run_testsuite:
	@$(run_testsuite)

.PHONY : all all-recursive check clean dist dvi eps fmt help jpg lint mostlyclean pdf png pretty ps prerequisite postprocess svg upgrade watch _FORCE _run_testsuite

# $(call typeset,LATEX-COMMAND) tries to typeset the document.
# $(call typeset,LATEX-COMMAND,false) doesn't delete the output file on failure.
typeset = \
	rmfile=$@; \
	rmauxfile=; \
	rmtmpfile=; \
	$(if $2,rmfile=;dont_delete_on_failure=1;) \
	$(ensure_build_dir); \
	oldfile_prefix=$*.tmp$$$$; \
	trap 'rm -f $$rmfile $$rmauxfile $$rmtmpfile $(build_prefix)$$oldfile_prefix*' 0 1 2 3 15; \
	failed=false; \
	if [ -f '$@' ]; then \
		need_latex=$(if $(filter-out %.ref %.bib %.bst %.idx %.glo,$?),:,false); \
		need_bibtex=$(if $(filter %.bib %.bst,$?),:,false); \
		need_biber=$(if $(filter %.bcf,$?),:,false); \
		need_sortref=$(if $(filter %.ref,$?),:,false); \
		need_makeindex=$(if $(filter %.idx,$?),:,false); \
		need_makeglossaries=$(if $(filter %.glo,$?),:,false); \
		need_bib2gls=false; \
		need_axohelp=$(if $(filter %.ax2,$?),:,false); \
		if $$need_bibtex || $$need_biber || $$need_sortref; then \
			[ ! -f '$(build_prefix)$*.aux' ] && need_latex=:; \
		fi; \
	else \
		need_latex=:; \
		need_bibtex=false; \
		need_biber=false; \
		need_sortref=false; \
		need_makeindex=false; \
		need_makeglossaries=false; \
		need_bib2gls=false; \
		need_axohelp=false; \
	fi; \
	$(call do_latex,$1,false); \
	if $$failed && $(check_noreffile); then \
		need_sortref=:; \
		failed=false; \
	else \
		$(check_failed); \
	fi; \
	i=1; \
	while [ $$i -lt $(MAXREPEAT) ]; do \
		$(do_bibtex); \
		$(do_biber); \
		$(do_sortref); \
		$(do_makeindex); \
		$(do_makeglossaries); \
		$(do_bib2gls); \
		$(do_axohelp); \
		$(call do_latex,$1); \
		i=$$((i + 1)); \
	done; \
	if $$need_latex || $$need_bibtex || $$need_biber || $$need_sortref \
			|| $$need_makeindex || $$need_makeglossaries || $$need_bib2gls \
			|| $$need_axohelp; then \
		$(call warning_message,Typesetting did not finish after $(MAXREPEAT) iterations. The document may be incomplete.); \
	fi; \
	rmfile=; \
	touch $@; \
	$(call mk_fls_dep,$@,$(build_prefix)$*.fls); \
	$(call mk_blg_dep,$@,$(build_prefix)$*.blg); \
	$(check_reffile) && $(call mk_ref_dep,$@,$*.ref); \
	:

# $(ensure_build_dir) creates $(BUILDDIR) if necessary.
ensure_build_dir = $(if $(BUILDDIR),mkdir -p $(BUILDDIR),:)

# $(build_prefix) is "$(BUILDDIR)/" if BUILDDIR is given, otherwise empty.
build_prefix = $(if $(BUILDDIR),$(BUILDDIR)/,)

# $(mv_target) moves the target file from BUILDDIR if BUILDDIR is defined.
# It also ensures that the target file exists in the working directory.
# $(call mv_target,FILE) moves FILE, instead of the target file.
# $(call mv_target,FILE,false) doesn't ensure that the file exists in the
# working directory.
mv_target = $(strip \
	$(if $1, \
		$(if $(BUILDDIR), \
			if [ -f $(BUILDDIR)/$1 ]; then mv $(BUILDDIR)/$1 $1; fi \
			$(if $2,,; [ -f $1 ]) \
		, \
			$(if $2,:,[ -f $1 ]) \
		) \
	, \
		$(if $@, \
			$(call mv_target,$@,$2) \
		, \
			: \
		) \
	) \
)

# $(_use_builddir_for_epstopdf) gives the canonicalized value of $(USE_BUILDDIR_FOR_EPSTOPDF) as:
# - 1
# - (empty)
_use_builddir_for_epstopdf = $(call cache,_use_builddir_for_epstopdf_impl)

_use_builddir_for_epstopdf_impl = $(strip \
	$(if $(BUILDDIR), \
		$(if $(findstring always,$(USE_BUILDDIR_FOR_EPSTOPDF)), \
			1 \
		,$(if $(findstring never,$(USE_BUILDDIR_FOR_EPSTOPDF)), \
			\
		, \
			$(if $(USE_BUILDDIR_FOR_EPSTOPDF), \
				$(if $(findstring auto,$(USE_BUILDDIR_FOR_EPSTOPDF)),, \
					$(warning unrecognized USE_BUILDDIR_FOR_EPSTOPDF=$(USE_BUILDDIR_FOR_EPSTOPDF)) \
				) \
			) \
			$(if $(is_texlive), \
				1 \
			, \
				\
			) \
		)) \
	, \
		\
	) \
)

# $(set_texinputs_for_epstopdf) sets TEXIPUTS, if adequate.
set_texinputs_for_epstopdf = $(strip \
	$(if $(_use_builddir_for_epstopdf), \
		TEXINPUTS=.:$(BUILDDIR):$$TEXINPUTS: && export TEXINPUTS \
	, \
		: \
	) \
)

# $(mv_epstopdf) moves *-eps-converted-to.pdf files to BUILDDIR, if adequate.
mv_epstopdf = $(strip \
	$(if $(_use_builddir_for_epstopdf), \
		{ mv *-eps-converted-to.pdf $(BUILDDIR) >/dev/null 2>&1 || :; } \
	, \
		: \
	) \
)

# $(call do_backup,FILE) creates a backup file for "$(build_prefix)/FILE".
do_backup = \
	[ -f '$(build_prefix)$1' ] && cp '$(build_prefix)$1' "$(build_prefix)$$oldfile_prefix$(suffix $1)"

# $(call check_modified,FILE) checks if "$(build_prefix)/FILE" was modified
# in comparison with the backup file.
check_modified = \
	$(call check_modified_impl,"$(build_prefix)$$oldfile_prefix$(suffix $1)",'$(build_prefix)$1')

check_modified_impl = \
	if [ -f $1 ] || [ -f $2 ]; then \
		if diff -q -N $1 $2 >/dev/null 2>&1; then \
			false; \
		else \
			:; \
		fi; \
	else \
		false; \
	fi

# $(call set_aux_file,FILE) sets the current auxiliary file to
# "$(build_prefix)$/FILE", which will be deleted if the current task fails.
set_aux_file = \
	rmauxfile=$(build_prefix)$1

# $(reset_aux_file) resets the current auxiliary file.
reset_aux_file = \
	rmauxfile=

# $(call copy_build_temp_file,FILE) copies $(build_prefix)$/FILE to the current
# directory if exists.
copy_build_temp_file = \
	$(if $(BUILDDIR), \
		if [ -f $(BUILDDIR)/$1 ]; then \
			cp $(BUILDDIR)/$1 .; \
			rmtmpfile="$$rmtmpfile $1"; \
		fi \
	, \
		: \
	)

# $(clear_build_temp_files) deletes temporary files copied from BUILDDIR.
clear_build_temp_files = \
	$(if $(BUILDDIR), \
		rm -f $$rmtmpfile; \
		rmtmpfile= \
	, \
		: \
	)

# $(call do_latex,LATEX-COMMAND)
# $(call do_latex,LATEX-COMMAND,false) skips the check.
do_latex = \
	if $$need_latex; then \
		need_latex=false; \
		$(call do_backup,$*.aux); \
		$(call do_backup,$*.toc); \
		$(call do_backup,$*.lof); \
		$(call do_backup,$*.lot); \
		$(call do_backup,$*.idx); \
		$(call do_backup,$*.glo); \
		$(call do_backup,$*.glstex); \
		$(call do_backup,$*.ax1); \
		$(call exec,$1 $<,$2,latex); \
		if $(call check_modified,$*.aux); then \
			if $(check_biblatex); then \
				if $(check_biblatex_rerun_bibtex); then \
					need_bibtex=:; \
				elif $(check_biblatex_rerun_biber); then \
					need_biber=:; \
				fi; \
			elif $(check_bblfile); then \
				need_bibtex=:; \
			fi; \
			$(check_reffile) && need_sortref=:; \
			if $(check_glstexfile); then \
				need_bib2gls=:; \
			else \
				$(check_glsfile) && need_makeglossaries=:; \
			fi; \
		else \
			$(check_nobblfile) && need_bibtex=:; \
		fi; \
		if $(call check_modified,$*.idx); then \
			$(check_indfile) && need_makeindex=:; \
		fi; \
		if $(call check_modified,$*.glo); then \
			$(check_glsfile) && need_makeglossaries=:; \
		fi; \
		if $(call check_modified,$*.ax1); then \
			$(check_ax2file) && need_axohelp=:; \
		fi; \
		{ $(check_rerun) || $(call check_modified,$*.toc) || $(call check_modified,$*.lof) || $(call check_modified,$*.lot); } && need_latex=:; \
	fi

# $(do_bibtex)
# NOTE: when BUILDDIR is used, we run bibtex in the current directory with
# temporarily copied .aux and Notes.bib files.
do_bibtex = \
	if $$need_bibtex; then \
		need_bibtex=false; \
		$(call do_backup,$*.bbl); \
		$(call set_aux_file,$*.bbl); \
		$(if $(BUILDDIR), \
			$(call copy_build_temp_file,$*.aux); \
			$(call copy_build_temp_file,$*Notes.bib); \
			$(call copy_build_temp_file,$*-blx.bib); \
			for f in $(BUILDDIR)/$**-blx.aux; do \
				ff=$$(basename $$f); \
				$(call copy_build_temp_file,$$ff); \
			done; \
			$(call exec,$(bibtex) $*,,bibtex); \
			mv $*.bbl $*.blg $(BUILDDIR)/; \
			for f in $**-blx.aux; do \
				if [ -f $$f ]; then \
					ff=$$(basename $$f .aux); \
					$(call exec,$(bibtex) $$ff,,bibtex); \
					mv $$ff.bbl $$ff.blg $(BUILDDIR)/; \
				fi; \
			done; \
			$(clear_build_temp_files); \
		, \
			$(call exec,$(bibtex) $*,,bibtex); \
			for f in $**-blx.aux; do \
				if [ -f $$f ]; then \
					ff=$$(basename $$f .aux); \
					$(call exec,$(bibtex) $$ff,,bibtex); \
				fi; \
			done; \
		) \
		$(reset_aux_file); \
		$(call check_modified,$*.bbl) && need_latex=:; \
	fi

# $(do_biber)
do_biber = \
	if $$need_biber; then \
		need_biber=false; \
		$(call do_backup,$*.bbl); \
		rmauxfile=$(build_prefix)$*.bbl; \
		$(if $(BUILDDIR), \
			$(call exec,$(biber) --output-directory $(BUILDDIR) $*); \
		, \
			$(call exec,$(biber) $*); \
		) \
		rmauxfile=; \
		$(call check_modified,$*.bbl) && need_latex=:; \
	fi

# $(do_sortref)
# NOTE: though the sortref script doesn't require any restriction on 'ref-file',
# we only support main-doc.tex + main-doc.ref -> main-doc_ref.tex.
do_sortref = \
	if $$need_sortref; then \
		need_sortref=false; \
		$(call do_backup,$*_ref.tex); \
		$(if $(BUILDDIR), \
			$(call exec,$(sortref) $(BUILDDIR)/$* $*.ref); \
			cp $(BUILDDIR)/$*_ref.tex .; \
		, \
			$(call exec,$(sortref) $* $*.ref); \
		) \
		$(call check_modified,$*_ref.tex) && need_latex=:; \
	fi

# $(do_makeindex)
# NOTE: when BUILDDIR is used, we run makeindex in the current directory with
# the temporarily copied .idx file.
do_makeindex = \
	if $$need_makeindex; then \
		need_makeindex=false; \
		$(call do_backup,$*.ind); \
		$(call set_aux_file,$*.ind); \
		$(if $(BUILDDIR), \
			$(call copy_build_temp_file,$*.idx); \
			$(call exec,$(makeindex) $*); \
			mv $*.ind $*.ilg $(BUILDDIR)/; \
			$(clear_build_temp_files); \
		, \
			$(call exec,$(makeindex) $*); \
		) \
		$(reset_aux_file); \
		$(call check_modified,$*.ind) && need_latex=:; \
	fi

# $(do_makeglossaries)
do_makeglossaries = \
	if $$need_makeglossaries; then \
		need_makeglossaries=false; \
		$(call do_backup,$*.gls); \
		$(if $(BUILDDIR), \
			$(call exec,$(makeglossaries) -d $(BUILDDIR) $*) \
		, \
			$(call exec,$(makeglossaries) $*) \
		); \
		$(call check_modified,$*.gls) && need_latex=:; \
	fi

# $(do_bib2gls)
do_bib2gls = \
	if $$need_bib2gls; then \
		need_bib2gls=false; \
		$(call do_backup,$*.glstex); \
		$(call set_aux_file,$*.glstex); \
		$(if $(BUILDDIR), \
			$(call copy_build_temp_file,$*.aux); \
			$(call exec,$(bib2gls) $*); \
			mv $*.glg $*.glstex $(BUILDDIR)/; \
			$(clear_build_temp_files); \
		, \
			$(call exec,$(bib2gls) $*); \
		) \
		$(reset_aux_file); \
		$(call check_modified,$*.glstex) && need_latex=:; \
	fi

# $(do_axohelp)
do_axohelp = \
	if $$need_axohelp; then \
		need_axohelp=false; \
		$(call do_backup,$*.ax2); \
		$(call exec,$(axohelp) $(build_prefix)$*); \
		$(call check_modified,$*.ax2) && need_latex=:; \
	fi

# $(call do_kpsewhich,FULLPATH-DEST-VAR,FILE)
do_kpsewhich = \
	fullpath_kpsewhich_impl=`$(kpsewhich) "$2"`; \
	if [ -z "$$fullpath_kpsewhich_impl" ]; then \
		$(call error_message,$2 not found); \
		exit 1; \
	fi; \
	$1=$$fullpath_kpsewhich_impl

# $(call mk_fls_dep,TARGET,FLS-FILE) saves dependencies from a .fls file.
mk_fls_dep = \
	if [ -f '$2' ]; then \
		mkdir -p $(DEPDIR); \
		{ \
			for f in `grep INPUT '$2' | sed 's/INPUT *\(\.\/\)\?//' | sort | uniq`; do \
				case $$f in \
					*:*|/*) ;; \
					*.fmt|*.run.xml) ;; \
					*) \
						$(call dep_entry,$1,$$f); \
						;; \
				esac; \
			done; \
		} | sort >$(DEPDIR)/$1.fls.d; \
	fi

# $(call mk_blg_dep,TARGET,BLG-FILE) saves dependencies from a .blg file.
mk_blg_dep = \
	if [ -f '$2' ]; then \
		mkdir -p $(DEPDIR); \
		{ \
			for f in `{ grep 'Database file [^:]*:' '$2'; grep 'The style file:' '$2'; } | sed 's/[^:]*://'`; do \
				$(call dep_entry,$1,$$f); \
			done; \
		} | sort >$(DEPDIR)/$1.blg.d; \
	fi

# $(call mk_glg_dep,TARGET,GLG-FILE) saves dependencies from a .glg file.
# NOTE: currently not used. We need some trick to find which executable
# (bibtex or bib2gls, maybe both?) should be run when a .bib dependency is
# updated.
mk_glg_dep = \
	if [ -f '$2' ] && grep -q 'bib2gls' '$2'; then \
		mkdir -p $(DEPDIR); \
		{ \
			for f in $$(grep 'Reading .*\.bib' '$2' | sed 's/Reading *//'); do \
				$(call dep_entry,$1,$$f); \
			done; \
		} | sort >$(DEPDIR)/$1.glg.d; \
	fi

# $(call mk_ref_dep,TARGET,REF-FILE) saves dependencies from a .ref file.
mk_ref_dep = \
	if [ -f '$2' ]; then \
		mkdir -p $(DEPDIR); \
		$(call dep_entry,$1,$2) | sort >$(DEPDIR)/$1.ref.d; \
	fi

# $(call dep_entry,TARGET,DEPENDENCY) prints a dependency entry.
# NOTE: DEPENDENCY can be a shell variable.
dep_entry = \
	if [ -f "$2" ]; then \
		echo "$1 : \$$(wildcard $2)"; \
		echo "$(build_prefix)$(basename $1).log : \$$(wildcard $2)"; \
	fi

# $(call grep_lines,PATTERN,FILE) greps PATTERN and prints lines around matches
# without new line characters.
# NOTE: the grep -B NUM option is not in POSIX.
grep_lines = \
	grep -B 3 $1 $2 | tr -d '\n'

# NOTE: latex may fail due to a missing _ref.tex.
check_noreffile = $(call grep_lines,'_ref.tex','$(build_prefix)$*.log') | grep "File \`$*_ref.tex' not found" >/dev/null 2>&1

check_biblatex = grep 'Package: biblatex' '$(build_prefix)$*.log' >/dev/null 2>&1

check_biblatex_rerun_biber = grep 'Please (re)run Biber' '$(build_prefix)$*.log' >/dev/null 2>&1

check_biblatex_rerun_bibtex = grep 'Please (re)run BibTeX' '$(build_prefix)$*.log' >/dev/null 2>&1

check_bblfile = $(call grep_lines,'.bbl','$(build_prefix)$*.log') | grep '$*.bbl' >/dev/null 2>&1

check_nobblfile = $(call grep_lines,'.bbl','$(build_prefix)$*.log') | grep 'No file $*.bbl' >/dev/null 2>&1

check_reffile = $(call grep_lines,'_ref.tex','$(build_prefix)$*.log') | grep '$*_ref.tex' >/dev/null 2>&1

check_indfile = $(call grep_lines,'.ind','$(build_prefix)$*.log') | grep '$*.ind' >/dev/null 2>&1

check_glsfile = $(call grep_lines,'.gls','$(build_prefix)$*.log') | grep '$*.gls\.' >/dev/null 2>&1

check_glstexfile = $(call grep_lines,'.glstex','$(build_prefix)$*.log') | grep '$*.glstex' >/dev/null 2>&1

# axodraw2.sty uses primitive control sequences for reading .ax2 file, instead
# of \input, without writing any jobname.ax2 in the log file. So we look for
# jobname.ax1; if it is found in the log file, it means axodraw2.sty tries to
# read jobname.ax2.
check_ax2file = $(call grep_lines,'.ax1','$(build_prefix)$*.log') | grep '$*.ax1' >/dev/null 2>&1

check_rerun = grep 'Rerun\|Please rerun LaTeX' '$(build_prefix)$*.log' | grep -v 'Package: rerunfilecheck\|rerunfilecheck.sty' >/dev/null 2>&1

#NOTE: xelatex doesn't work with -output-format=dvi.

.tex.dvi:
	@$(init_toolchain)
	@$(call switch,$(typeset_mode), \
		dvips, \
			$(call typeset,$(latex)) && \
			$(mv_target), \
		dvips_convbkmk, \
			$(call typeset,$(latex)) && \
			$(mv_target), \
		dvipdf, \
			$(call typeset,$(latex)) && \
			$(mv_target), \
		pdflatex, \
			$(call typeset,$(latex) $(PDFLATEX_DVI_OPT)) && \
			$(mv_target), \
	)

.tex.ps:
	@$(init_toolchain)
	@$(call switch,$(typeset_mode), \
		dvips, \
			$(call typeset,$(latex)) && \
			$(call exec,$(dvips) $(build_prefix)$*.dvi), \
		dvips_convbkmk, \
			$(call typeset,$(latex)) && \
			$(call exec,$(dvips) $(build_prefix)$*.dvi -o $(build_prefix)$*.ps) && \
			$(call exec,$(convbkmk) $(build_prefix)$*.ps) && \
			mv $(build_prefix)$*-convbkmk.ps $*.ps, \
		dvipdf, \
			$(call typeset,$(latex)) && \
			$(call exec,$(dvips) $(build_prefix)$*.dvi), \
		pdflatex, \
			$(call typeset,$(latex) $(PDFLATEX_DVI_OPT)) && \
			$(call exec,$(dvips) $(build_prefix)$*.dvi), \
	)

.tex.pdf:
	@$(init_toolchain)
	@$(call switch,$(typeset_mode), \
		dvips, \
			$(call typeset,$(latex)) && \
			$(call exec,$(dvips) $(build_prefix)$*.dvi -o $(build_prefix)$*.ps) && \
			$(call exec,$(ps2pdf) $(build_prefix)$*.ps), \
		dvips_convbkmk, \
			$(call typeset,$(latex)) && \
			$(call exec,$(dvips) $(build_prefix)$*.dvi -o $(build_prefix)$*.ps) && \
			$(call exec,$(convbkmk) $(build_prefix)$*.ps) && \
			mv $(build_prefix)$*-convbkmk.ps $(build_prefix)$*.ps && \
			$(call exec,$(ps2pdf) $(build_prefix)$*.ps), \
		dvipdf, \
			$(call typeset,$(latex)) && \
			$(call exec,$(dvipdf) $(build_prefix)$*.dvi,,dvipdf), \
		pdflatex, \
			$(set_texinputs_for_epstopdf) && \
			$(call typeset,$(latex)) && \
			$(mv_target) && \
			$(mv_epstopdf), \
	)

# This always updates the timestamp of the target (.log).
$(build_prefix)%.log : %.tex
	@$(MAKE) -s $*.$(default_target)
	@touch $@

.dvi.eps:
	@$(init_toolchain)
	@trap 'rm -f $*.tmp.ps $*.tmp.pdf' 0 1 2 3 15; \
	$(call exec,$(dvips) -o $*.tmp.ps $<); \
	$(call exec,$(gs) -sDEVICE=pdfwrite -dPDFSETTINGS=/prepress -dEPSCrop -o $*.tmp.pdf $*.tmp.ps); \
	if $(call cmpver,`$(gs) --version`,-lt,9.15); then \
		$(call exec,$(gs) -sDEVICE=epswrite -o $@ $*.tmp.pdf); \
	else \
		$(call exec,$(gs) -sDEVICE=eps2write -o $@ $*.tmp.pdf); \
	fi

.dvi.svg:
	@$(init_toolchain)
	@$(call exec,$(dvisvgm) $<)

.pdf.jpg:
	@$(init_toolchain)
	@$(call exec,$(pdftoppm) $(PDFTOPPM_JPG_OPT) $< $*)

.pdf.png:
	@$(init_toolchain)
	@$(call exec,$(pdftoppm) $(PDFTOPPM_PNG_OPT) $< $*)

# Experimental (TeXLive)
.ltx.fmt:
	@$(init_toolchain)
	@$(ensure_build_dir)
	@$(call exec,$(latex_noopt) -ini -jobname='$*' '&$(notdir $(basename $(latex_noopt))) $<\dump',,latex)
	@$(mv_target)
	@$(call exec,rm -f $*.pdf)

# Experimental (TeXLive)
#
# Example:
#   $ cat foo.tex
#   %&foo
#   \documentclass{beamer}
#   \begin{document}
#   \begin{frame}
#   Your presentation here.
#   \end{frame}
#   \end{document}
#   $ make clean
#   $ time make foo.pdf
#   $ make clean
#   $ time { make foo.fmt && make foo.pdf; }
#
# Note: axodraw2 checks if .ax2 file exists when loaded, which becomes a problem
#   if one includes it in a format file: whether or not .ax2 file exists is
#   stores in a format file.
#
.tex.fmt:
	@$(init_toolchain)
	@$(ensure_build_dir)
	@$(call exec,$(latex_noopt) -ini -jobname='$*' '&$(tex_format)' mylatexformat.ltx '$<',,latex)
	@$(mv_target)
	@$(call exec,rm -f $*.pdf)

.dtx.cls:
	@$(ensure_build_dir)
	@$(call exec,$(latex_noopt) $(basename $<).ins,,latex)
	@$(mv_target)

.dtx.sty:
	@$(ensure_build_dir)
	@$(call exec,$(latex_noopt) $(basename $<).ins,,latex)
	@$(mv_target)

.odt.pdf:
	@$(call exec,$(soffice) --headless --nologo --nofirststartwizard --convert-to pdf $<)

.jpg.bb:
	$(ebb) $<

.png.bb:
	$(ebb) $<

.pdf.bb:
	$(ebb) $<

.jpg.xbb:
	$(extractbb) $<

.png.xbb:
	$(extractbb) $<

.pdf.xbb:
	$(extractbb) $<

# A distribution (for arXiv) needs to include
# 1. The main tex file.
# 2. Files that the main tex file depends on, except
#    - files with absolute paths, which are considered as system files,
#    - files created by LaTeX during typesetting, e.g., *.aux files,
#    - *.ax2 file unless "\pdfoutput=1" is explicitly used.
#    This default behaviour may be overwritten by EXTRADISTFILES and
#    NODISTFILES. Note that .bbl, .ind, .gls files etc. should be included in
#    the distribution.
#    See https://arxiv.org/help/submit_tex#bibtex
# 3. "PoSlogo.pdf" without "\pdfoutput=1" most likely indicates that
#    "PoSLogo.ps" should be also included for the PoS class.
# 4. 00README.XXX file if exists, and
#    - Files listed in 00README.XXX with "ignore".
#    See https://arxiv.org/help/00README
# 5. Files listed in ANCILLARYFILES are included under a subdirectory "anc".
#    See https://arxiv.org/help/ancillary_files
%.tar.gz: %.$(default_target)
	@tmpdir=tmp$$$$; \
	mkdir $$tmpdir || exit 1; \
	$(if $(KEEP_TEMP),,trap 'rm -rf $$tmpdir' 0 1 2 3 15;) \
	pdfoutput=false; \
	if head -5 "$*.tex" | sed 's/%.*//' | grep -q '\pdfoutput=1'; then \
		pdfoutput=:; \
	fi; \
	if [ ! -f '$(build_prefix)$*.fls' ]; then \
		$(call error_message,$(build_prefix)$*.fls not found. Delete $*.$(default_target) and then retry); \
		exit 1; \
	fi; \
	dep_files=; \
	for f in `grep INPUT '$(build_prefix)$*.fls' | sed 's/^INPUT *//' | sed '/^\(extractbb\|kpsewhich\)/d' | sed 's|^\.\/||' | sort | uniq`; do \
		case $$f in \
			*:*|/*|*.aux|*.lof|*.lot|*.nav|*.out|*.spl|*.toc|*.vrb|*-eps-converted-to.pdf|*.run.xml) ;; \
			*) \
				case $$f in \
					*.ax2) \
						$$pdfoutput || continue; \
						;; \
					PoSlogo.pdf) \
						if $$pdfoutput; then :; else \
							if [ -f PoSlogo.ps ]; then \
								$(call add_dist,PoSlogo.ps,$$tmpdir,dep_files); \
							fi; \
						fi; \
						;; \
				esac; \
				$(call add_dist,$$f,$$tmpdir,dep_files); \
		esac; \
	done; \
	for ff in $(EXTRADISTFILES); do \
		$(call do_kpsewhich,f,$$ff); \
		cp "$$f" "$$tmpdir/" || exit 1; \
		dep_files="$$dep_files $$f"; \
	done; \
	if [ -f 00README.XXX ]; then \
		cp "00README.XXX" "$$tmpdir/" || exit 1; \
		dep_files="$$dep_files 00README.XXX"; \
		for f in `grep ignore 00README.XXX | sed 's/ *ignore *$$//'`; do \
			cp --parents "$$f" "$$tmpdir/" || rsync -R "$$f" "$$tmpdir" || exit 1; \
			dep_files="$$dep_files $$f"; \
		done; \
	fi; \
	for f in $(ANCILLARYFILES); do \
		[ -d "$$tmpdir/anc" ] || mkdir "$$tmpdir/anc"; \
		cp "$$f" "$$tmpdir/anc/" || exit 1; \
		dep_files="$$dep_files $$f"; \
	done; \
	mkdir -p $(DEPDIR); \
	{ \
		for f in $$dep_files; do \
			echo "$@ : \$$(wildcard $$f)"; \
		done; \
	} >$(DEPDIR)/$@.d; \
	cd $$tmpdir || exit 1; \
	$(call exec,tar cfv - --exclude $@ * | gzip -9 -n >$@,false); \
	cd .. || exit 1; \
	$(check_failed); \
	mv $$tmpdir/$@ $@

# $(call add_dist,FILE,TMPDIR,DEP_FILES_VAR) copies FILE to TMPDIR and add it to
# DEP_FILES_VAR, if it is not in NODISTFILES.
add_dist = { \
		tmp_ok=:; \
		for tmp_ff in $(NODISTFILES); do \
			if [ "x$1" = "x$$tmp_ff" ]; then \
				tmp_ok=false; \
				break; \
			fi; \
		done; \
		if $$tmp_ok; then \
			tmp_d=`dirname "$1"`; \
			$(if $(BUILDDIR), \
				if [ "$$tmp_d" = "$(BUILDDIR)" ]; then \
					tmp_d=.; \
				fi; \
			) \
			mkdir -p "$2/$$tmp_d"; \
			cp "$1" "$2/$$tmp_d" || exit 1; \
			$3="$$$3 $1"; \
		fi; \
		:; \
	}

ifneq ($(DIFF),)

# Take a LaTeX-diff of two Git revisions (or a Git revision and the current
# working copy) given in the DIFF variable and typeset the resultant document.
# Limitation: though DIFF=rev1..rev2 is supported, the original LaTeX source
# file needs to exist as long as we want to use the rule *.tex -> *-diff.*.
%-diff.$(default_target): %.tex _FORCE
	@$(call get_rev,$(DIFF),_rev1,_rev2); \
	if [ -n "$$_rev1" ]; then \
		if git show "$$_rev1:./$<" >/dev/null 2>&1; then :; else \
			$(call error_message,$< not in $$_rev1); \
			exit 1; \
		fi; \
	fi; \
	if [ -n "$$_rev2" ]; then \
		if git show "$$_rev2:./$<" >/dev/null 2>&1; then :; else \
			$(call error_message,$< not in $$_rev2); \
			exit 1; \
		fi; \
	fi; \
	_tmpdir=tmp$$$$; \
	$(if $(KEEP_TEMP),,trap 'rm -rf $$_tmpdir' 0 1 2 3 15;) \
	_git_root=$$(git rev-parse --show-cdup).; \
	_git_prefix=$$(git rev-parse --show-prefix); \
	if [ -z "$$_rev2" ]; then \
		$(call expand_latexdiff_repo,$$_rev1); \
		$(MAKE) -f $(Makefile) $*.tar.gz || exit 1; \
		mkdir $$_tmpdir; \
		(cd $$_tmpdir && tar xfz ../$(DIFFDIR)/$$_rev1/$$_git_prefix/$*.tar.gz); \
		(cd $$_tmpdir && tar xfz ../$*.tar.gz); \
		$(call latexdiff_copy_cache,$(DIFFDIR)/$$_rev1/$$_git_prefix,$$_tmpdir); \
		$(call latexdiff_copy_cache,.,$$_tmpdir); \
		cp $(DIFFDIR)/$$_rev1/$$_git_prefix/$*-expanded.tex $$_tmpdir/$*-expanded-old.tex; \
		$(call expand_latex_source,$<,$$_tmpdir/$*-expanded-new.tex); \
		$(call latexdiff_insubdir,$$_tmpdir,$<,$*-expanded-old.tex,$*-expanded-new.tex,$*-diff.tex,$*-diff.$(default_target),$(DIFF)..); \
	else \
		$(call expand_latexdiff_repo,$$_rev1); \
		$(call expand_latexdiff_repo,$$_rev2); \
		mkdir $$_tmpdir; \
		(cd $$_tmpdir && tar xfz ../$(DIFFDIR)/$$_rev1/$$_git_prefix/$*.tar.gz); \
		(cd $$_tmpdir && tar xfz ../$(DIFFDIR)/$$_rev2/$$_git_prefix/$*.tar.gz); \
		$(call latexdiff_copy_cache,$(DIFFDIR)/$$_rev1/$$_git_prefix,$$_tmpdir); \
		$(call latexdiff_copy_cache,$(DIFFDIR)/$$_rev2/$$_git_prefix,$$_tmpdir); \
		cp $(DIFFDIR)/$$_rev1/$$_git_prefix/$*-expanded.tex $$_tmpdir/$*-expanded-old.tex; \
		cp $(DIFFDIR)/$$_rev2/$$_git_prefix/$*-expanded.tex $$_tmpdir/$*-expanded-new.tex; \
		$(call latexdiff_insubdir,$$_tmpdir,$<,$*-expanded-old.tex,$*-expanded-new.tex,$*-diff.tex,$*-diff.$(default_target),$(DIFF)); \
	fi

# $(call latexdiff_copy_cache,SOURCE-DIRECTORY,DESTINATION-DIRECTORY) copies
# cache files (i.e., eps-to-pdf) used in typesetting.
latexdiff_copy_cache = \
	for _f in $$(find "$2" -name '*.eps'); do \
		_ff="$1/$$(basename "$$_f" .eps)-eps-converted-to.pdf"; \
		if [ -f "$$_ff" ]; then \
			cp "$$_ff" $$(dirname "$$_f"); \
		fi; \
	done

# $(call expand_latexdiff_repo,REVISION)
# Uses: $*, $$_git_root, $$_git_prefix
expand_latexdiff_repo = \
	mkdir -p $(DIFFDIR); \
	if [ -d $(DIFFDIR)/$1 ]; then \
		git -C $(DIFFDIR)/$1 fetch origin; \
		case $1 in \
			*HEAD*) \
				git -C $(DIFFDIR)/$1 reset --hard origin/$1; \
				;; \
			*) \
				git -C $(DIFFDIR)/$1 reset --hard $1; \
				;; \
		esac; \
	else \
		git clone $$_git_root $(DIFFDIR)/$1; \
		git -C $(DIFFDIR)/$1 checkout $1; \
	fi; \
	rm -f $(DIFFDIR)/$1/$$_git_prefix/$(Makefile); \
	cp $(Makefile) $(DIFFDIR)/$1/$$_git_prefix/$(Makefile); \
	$(MAKE) -C $(DIFFDIR)/$1/$$_git_prefix -f $(Makefile) $*.tar.gz || exit 1; \
	case $1 in \
		*HEAD*) \
			rm -f $(DIFFDIR)/$1/$$_git_prefix/$*-expanded.tex; \
			;; \
	esac; \
	(cd $(DIFFDIR)/$1/$$_git_prefix && $(call expand_latex_source,$*.tex,$*-expanded.tex))

# $(call expand_latex_source,IN-TEX-FILE,OUT-TEX-FILE) expands a LaTeX source.
# Optionally a .bbl file is also expanded if exists.
expand_latex_source = { \
	if [ -f "$2" ]; then :; else \
		_tmp_latexexpand_fbody="$1"; \
		_tmp_latexexpand_fbody=$${_tmp_latexexpand_fbody%.*}; \
		$(if $(BUILDDIR), \
			if [ -f "$(BUILDDIR)/$$_tmp_latexexpand_fbody.bbl" ]; then \
				_tmp_latexexpand_fbody="$(BUILDDIR)/$$_tmp_latexexpand_fbody"; \
			fi; \
		) \
		if [ -f "$$_tmp_latexexpand_fbody.bbl" ]; then \
			if head "$$_tmp_latexexpand_fbody.bbl" | grep -q biber; then \
				$(call exec,$(latexpand) --biber "$$_tmp_latexexpand_fbody.bbl" "$1" >"$2.tmp"); \
			else \
				$(call exec,$(latexpand) --expand-bbl "$$_tmp_latexexpand_fbody.bbl" "$1" >"$2.tmp"); \
			fi; \
		else \
			$(call exec,$(latexpand) "$1" >"$2.tmp"); \
		fi; \
		mv "$2.tmp" "$2"; \
	fi \
}

# $(call latexdiff_insubdir,DIRECTORY,ORIG-TEX-FILE,OLD-TEX-FILE,NEW-TEX-FILE,TEMP-DIFF-TEX-FILE,TARGET-FILE,REVISIONS)
# performs latexdiff and then make for the target-diff file.
# When --math-markup=N is not given in LATEXDIFF_OPT, this code repeats
# the process with decreasing --math-markup from 3 to 0 until it succeeds.
# Similarly it also tries --allow-spaces if not given.
latexdiff_insubdir = \
	rm -f $1/$2; \
	cp $(Makefile) $1/$(Makefile); \
	[ -f .latex.mk ] && cp .latex.mk $1/; \
	[ -f latex.mk ] && cp latex.mk $1/; \
	$(if $(findstring --math-markup=,$(LATEXDIFF_OPT)), \
		$(if $(findstring --allow-spaces,$(LATEXDIFF_OPT)), \
			$(call latexdiff_insubdir_none,$1,$2,$3,$4,$5,$6,$7) \
		, \
			$(call latexdiff_insubdir_spaces,$1,$2,$3,$4,$5,$6,$7) \
		) \
	, \
		$(if $(findstring --allow-spaces,$(LATEXDIFF_OPT)), \
			$(call latexdiff_insubdir_math,$1,$2,$3,$4,$5,$6,$7) \
		, \
			$(call latexdiff_insubdir_math_spaces,$1,$2,$3,$4,$5,$6,$7) \
		) \
	) \
	mv $1/$6 .; \
	if [ -f "$6" ]; then \
		$(call notification_message,$6 generated for $7); \
	else \
		exit 1; \
	fi

latexdiff_insubdir_none = \
	(cd $1 && $(call exec,$(latexdiff) $3 $4 >$5)) || exit 1; \
	$(MAKE) -C $1 -f $(Makefile) $6 || exit 1;

latexdiff_insubdir_spaces = \
	(cd $1 && $(call exec,$(latexdiff) $3 $4 >$5)) || exit 1; \
	if $(MAKE) -C $1 -f $(Makefile) $6; then :; else \
		(cd $1 && $(call exec,$(latexdiff) --allow-spaces $3 $4 >$5)) || exit 1; \
		$(MAKE) -C $1 -f $(Makefile) $6 || exit 1; \
	fi;

latexdiff_insubdir_math = \
	(cd $1 && $(call exec,$(latexdiff) --math-markup=3 $3 $4 >$5)) || exit 1; \
	if $(MAKE) -C $1 -f $(Makefile) $6; then :; else \
		(cd $1 && $(call exec,$(latexdiff) --math-markup=2 $3 $4 >$5)) || exit 1; \
		if $(MAKE) -C $1 -f $(Makefile) $6; then :; else \
			(cd $1 && $(call exec,$(latexdiff) --math-markup=1 $3 $4 >$5)) || exit 1; \
			if $(MAKE) -C $1 -f $(Makefile) $6; then :; else \
				(cd $1 && $(call exec,$(latexdiff) --math-markup=0 $3 $4 >$5)) || exit 1; \
				$(MAKE) -C $1 -f $(Makefile) $6 || exit 1; \
			fi; \
		fi; \
	fi;

latexdiff_insubdir_math_spaces = \
	(cd $1 && $(call exec,$(latexdiff) --math-markup=3 $3 $4 >$5)) || exit 1; \
	if $(MAKE) -C $1 -f $(Makefile) $6; then :; else \
		(cd $1 && $(call exec,$(latexdiff) --math-markup=2 $3 $4 >$5)) || exit 1; \
		if $(MAKE) -C $1 -f $(Makefile) $6; then :; else \
			(cd $1 && $(call exec,$(latexdiff) --math-markup=1 $3 $4 >$5)) || exit 1; \
			if $(MAKE) -C $1 -f $(Makefile) $6; then :; else \
				(cd $1 && $(call exec,$(latexdiff) --math-markup=0 $3 $4 >$5)) || exit 1; \
				if $(MAKE) -C $1 -f $(Makefile) $6; then :; else \
					(cd $1 && $(call exec,$(latexdiff) --math-markup=3 --allow-spaces $3 $4 >$5)) || exit 1; \
					if $(MAKE) -C $1 -f $(Makefile) $6; then :; else \
						(cd $1 && $(call exec,$(latexdiff) --math-markup=2 --allow-spaces $3 $4 >$5)) || exit 1; \
						if $(MAKE) -C $1 -f $(Makefile) $6; then :; else \
							(cd $1 && $(call exec,$(latexdiff) --math-markup=1 --allow-spaces $3 $4 >$5)) || exit 1; \
							if $(MAKE) -C $1 -f $(Makefile) $6; then :; else \
								(cd $1 && $(call exec,$(latexdiff) --math-markup=0 --allow-spaces $3 $4 >$5)) || exit 1; \
								$(MAKE) -C $1 -f $(Makefile) $6 || exit 1; \
							fi; \
						fi; \
					fi; \
				fi; \
			fi; \
		fi; \
	fi;

endif

-include $(DEPDIR)/*.d
-include ~/.latex.mk
-include ~/latex.mk
-include .latex.mk
-include latex.mk

_prerequisite: $(PREREQUISITE)

_postprocess: $(POSTPROCESS)

.PHONY: _prerequisite _postprocess