% \iffalse meta-comment % %<*dtx> \ProvidesFile{latex-make.dtx} [2021/10/26 v2.4.3 Python 3 as default] % % \fi % \iffalse %<*driver> \documentclass[a4paper]{ltxdoc} \usepackage{a4wide} \usepackage[utf8]{inputenc} \usepackage[T1]{fontenc} \usepackage{pdfswitch} \usepackage{lmodern} \usepackage{array} \usepackage{tabularx} \usepackage{boxedminipage} \EnableCrossrefs \CodelineIndex \RecordChanges \setcounter{IndexColumns}{2} % make a twocolumn index \setlength{\columnseprule}{0pt} % no rules between columns ... \setlength{\columnsep}{2em} % ... but more spacing instead. \setcounter{unbalance}{4} \setlength{\IndexMin}{100pt} %%%%\OnlyDescription % uncomment this line to suppress printing the source code \makeatletter % don't show underfull hboxes in index/glossary: \g@addto@macro{\IndexParms}{\hbadness=10000} \g@addto@macro{\GlossaryParms}{\hbadness=10000} \makeatother \newenvironment{source}[1][.9\linewidth]{% \begin{center}% \begin{boxedminipage}[c]{#1}\tt% \vspace{1em}% \hspace{2em}\begin{minipage}[c]{#1}\tt% }{% \end{minipage}% \vspace{1em}% \end{boxedminipage}% \end{center}% } \sloppy \begin{document} \DocInput{latex-make.dtx} \PrintIndex \PrintChanges \end{document} % % \fi % % \GetFileInfo{latex-make.dtx} % % \DoNotIndex{\#,\$,\%,\&,\@,\\,\{,\},\^,\_,\~,\ } % \DoNotIndex{\def,\long,\edef,\xdef,\gdef,\let,\global} % \DoNotIndex{\if,\ifnum,\ifdim,\ifcat,\ifmmode,\ifvmode,\ifhmode,% % \iftrue,\iffalse,\ifvoid,\ifx,\ifeof,\ifcase,\else,\or,\fi,\loop,\do} % \DoNotIndex{\box,\copy,\setbox,\unvbox,\unhbox,\hbox,% % \vbox,\vtop,\vcenter} % \DoNotIndex{\@empty,\immediate,\write} % \DoNotIndex{\egroup,\bgroup,\expandafter,\begingroup,\endgroup} % \DoNotIndex{\divide,\advance,\multiply,\count,\dimen} % \DoNotIndex{\relax,\space,\string} % \DoNotIndex{\csname,\endcsname,\@spaces,\openin,\openout,% % \closein,\closeout} % \DoNotIndex{\catcode,\endinput} % \DoNotIndex{\jobname,\message,\read,\the,\noexpand} % \DoNotIndex{\hsize,\vsize,\hskip,\vskip,\kern,\hfil,\hfill,\hss} % \DoNotIndex{\m@ne,\z@,\@m,\z@skip,\@ne,\tw@,\p@} % \DoNotIndex{\DeclareRobustCommand,\DeclareOption,\newcommand,\newcommand*} % \DoNotIndex{\newcount,\newif,\newlinechar,\newread,\newtoks,\newwrite} % \DoNotIndex{\dp,\wd,\ht,\vss,\unskip,\ifthenelse} % % \DoNotIndex{\@filef@und,\@nameddef,\@tempa} % \DoNotIndex{\define@key,\equal,\ExecuteOptions} % \DoNotIndex{\filename@area,\filename@base,\filename@ext,\filename@parse} % \DoNotIndex{\Gin@exclamation,\Gin@getbase,\Gin@scalex,\Gin@scaley} % \DoNotIndex{\Gread@eps,\Gread@pdf,\Gscale@box} % \DoNotIndex{\IfFileExists,\ifpdf,\input,\InputIfFileExists} % \DoNotIndex{\MessageBreak,\PackageWarning,\PackageWarningNoLine} % \DoNotIndex{\ProcessOptions,\RequirePackage,\typeout} % \DoNotIndex{\(,\),\.,\1,\t,\n,\^^J} % \catcode\endlinechar 12\DoNotIndex{\ % }\catcode\endlinechar 10{} % \catcode`\$=12 % \DoNotIndex{\$} % \catcode`\$=3 % \DoNotIndex{\DeclareGraphicsExtensions,\DeclareGraphicsRule} % % % \title{The \LaTeX.mk Makefile\\ % and related script tools\thanks{This file % has version number \fileversion, last % revised \filedate.}} % \author{Vincent \textsc{Danjean} \and Arnaud \textsc{Legrand}} % \date{\filedate} % \maketitle % \begin{abstract} % This package allows to compile all kind and complex \LaTeX\space % documents with the help of a Makefile. Dependencies are % automatically tracked with the help of the |texdepends.sty| package. % \end{abstract} % \CheckSum{346} % % \changes{v2.0.0}{2006/03/09}{First autocommented version} % \changes{v2.1.0}{2008/01/28}{That's the question} % \changes{v2.1.1}{2009/11/08}{Improve error message} % \changes{v2.1.2}{2012/03/17}{Switch from perl to python} % \changes{v2.2.0}{2016/02/08}{Support to install LaTeX-Make locally} % \changes{v2.2.1}{2016/02/09}{Improve configure} % \changes{v2.2.2}{2016/02/09}{Fix bugs} % \changes{v2.2.3}{2017/01/08}{Add LuaLaTeX support} % \changes{v2.2.4}{2018/05/29}{Fix directory permissions on install} % \changes{v2.2.5}{2018/09/04}{fix output format of figdepth.py} % \changes{v2.3.0}{2018/10/17}{Add DEPENDS-EXCLUDE, add doc and % support for local texmf tree} % \changes{v2.4.0}{2020/06/01}{Support inkscape version >= 1.0} % \changes{v2.4.1}{2020/07/10}{Fix encoding problem with latexfilter.pl} % \changes{v2.4.2}{2021/01/03}{No changes in latex-make.dtx} % \changes{v2.4.3}{2021/04/18}{Switch to T1 font encoding and lmodern font} % \changes{v2.4.3}{2021/04/18}{Use python3 instead of python} % % \makeatletter % \def\SpecialOptionIndex#1{\@bsphack % \index{#1\actualchar{\protect\ttfamily#1} % (option)\encapchar usage}% % \index{options:\levelchar{\protect\ttfamily#1}\encapchar % usage}\@esphack} % \def\SpecialFileIndex#1{\@bsphack % \index{#1\actualchar{\protect\ttfamily#1} % (file)\encapchar usage}% % \index{files:\levelchar{\protect\ttfamily#1}\encapchar % usage}\@esphack} % \def\SpecialMainOptionIndex#1{\@bsphack\special@index{#1\actualchar % {\string\ttfamily\space#1} % (option)\encapchar main}% % \special@index{options:\levelchar{% % \string\ttfamily\space#1}\encapchar % main}\@esphack} % \def\option{\begingroup % \catcode`\\12 % \MakePrivateLetters \mym@cro@ \iffalse} % \long\def\mym@cro@#1#2{\endgroup \topsep\MacroTopsep \trivlist % \edef\saved@macroname{\string#2}% % \def\makelabel##1{\llap{##1}}% % \if@inlabel % \let\@tempa\@empty \count@\macro@cnt % \loop \ifnum\count@>\z@ % \edef\@tempa{\@tempa\hbox{\strut}}\advance\count@\m@ne \repeat % \edef\makelabel##1{\llap{\vtop to\baselineskip % {\@tempa\hbox{##1}\vss}}}% % \advance \macro@cnt \@ne % \else \macro@cnt\@ne \fi % \edef\@tempa{\noexpand\item[% % #1% % \noexpand\PrintMacroName % \else % \noexpand\PrintEnvName % \fi % {\string#2}]}% % \@tempa % \global\advance\c@CodelineNo\@ne % #1% % \SpecialMainIndex{#2}\nobreak % \DoNotIndex{#2}% % \else % \SpecialMainOptionIndex{#2}\nobreak % \fi % \global\advance\c@CodelineNo\m@ne % \ignorespaces} % \let\endoption \endtrivlist % \def\DescribeOption{\leavevmode\@bsphack\begingroup\MakePrivateLetters % \Describe@Option} % \def\Describe@Option#1{\endgroup % \marginpar{\raggedleft\PrintDescribeEnv{#1}}% % \SpecialOptionIndex{#1}\@esphack\ignorespaces} % \def\DescribeFile{\leavevmode\@bsphack\begingroup\MakePrivateLetters % \Describe@Option} % \def\Describe@File#1{\endgroup % \marginpar{\raggedleft\PrintDescribeEnv{#1}}% % \SpecialFileIndex{#1}\@esphack\ignorespaces} % \makeatother % \MakeShortVerb{\|} % % \tableofcontents % \newpage % \section{Introduction} % % |latex-make| is a collection of \LaTeX{} packages, scripts and % Makefile fragments that allows to easily compile \LaTeX{} documents. % The best feature is that \textbf{\emph{dependencies are % automatically tracked}}\footnote{Dependencies are tracked with % the help of the |texdepend.sty| package that is automatically % loaded: no need to specify it with |\textbackslash usepackage\{\}| % in your documents.}. % \par % These tools can be used to compile small \LaTeX{} documents % as well as big ones (such as, for example, a thesis with summary, tables of % contents, list of figures, list of tabulars, multiple indexes and % multiple bibliographies). % % \section{Quick start} % % \subsection{First (and often last) step} % When you want to use |latex-make|, most of the time you have to % create a |Makefile| with the only line: \par % \begin{source} % include LaTeX.mk % \end{source} % % Then, the following targets are available: |dvi|, |ps|, |pdf|, % \emph{file}|.dvi|, \emph{file}|.ps|, \emph{file}|.pdf|, etc., % |clean| and |distclean|. % \par % % All \LaTeX{} documents of the current directory should be compilable % with respect to their dependencies. If something fails, please, % provide me the smallest example you can create to show me what is % wrong. % \par\medskip % % \paragraph{Tip:} % If you change the dependencies inside your document (for example, if % you change |\include{first}| into |\include{second}|), you may have % to type |make distclean| before being able to recompile your % document. Else, |make| can fail, trying to build or found the old % |first.tex| file. % \paragraph{Shared work} % If you work with other people that do not have installed (and do not % want to install) \LaTeX-Make, you can use the % |LaTeX-Make-local-install| target in |LaTeX.mk| to install required % files in a local TEXMF tree. You can them commit this % tree into your control version system. Then, in your |Makefile|, % replace the single line\par % \begin{source} % include LaTeX.mk % \end{source} % with something like\par % \begin{source}\small % export TEXMFHOME:=\$(CURDIR)/relpath/to/local/tree/texmf\\ % include \$(shell env TEXMFHOME=\$(TEXMFHOME) $\backslash$\\ % \hspace*{12ex}kpsewhich -format texmfscripts LaTeX.mk) % \end{source} % If you have a previous value for |TEXMFHOME| that you do not want to % override, you can use the following (more complexe) snipset\par % \begin{source}\small % \# Adapt the following line to find the local texmf tree\\ % LOCAL\_TEXMF:=\$(CURDIR)/\$(firstword \$(wildcard texmf $\backslash$\\ % \hspace*{16ex}../texmf ../../texmf ../../../texmf))\\ % \# Get the old TEXMFHOME value\\ % TEXMFHOME:=\$(shell kpsewhich -var-value TEXMFHOME)\\ % \# If the new tree is already in it, do nothing, else add it\\ % ifeq (\$(filter \$(LOCAL\_TEXMF)//%,\$(TEXMFHOME)),)\\ % TEXMFHOME := \$(LOCAL\_TEXMF)\$(addprefix :,\$(TEXMFHOME))\\ % \# display info so that users know what to define in order to\\ % \# compile documents directly with (pdf)latex\\ % \$(warning export TEXMFHOME=\$(TEXMFHOME))\\ % export TEXMFHOME\\ % endif\\ % ~\\ % include \$(shell env TEXMFHOME=\$(TEXMFHOME) $\backslash$\\ % \hspace*{12ex}kpsewhich -format texmfscripts LaTeX.mk) % \end{source} % Doing so, all co-authors will be able to use \LaTeX-Make without % installing it. However, note that: % \begin{itemize} % \item you wont beneficit of an update of \LaTeX-Make in your system % (you will continue to use the locally installed files) ; % \item there is no support for upgrading locally installed files (but % reexecuting the installation should do a correct upgrade most of % the time) ; % \item if a user tries to compile the \LaTeX{} source code directly % with |[pdf]latex|, he must before either have LaTeX-Make installed % or define and export |TEXMFHOME|. % \end{itemize} % % Another possibility is to install package files (|*.sty|) into a % directory pointed by |TEXINPUTS|, scripts files (|*.py|) into a % directory pointed bt |TEXMFSCRIPTS|, and to directly include % |LaTeX.mk|. For example: % \begin{source}\small % \# use local files by default\\ % \# packages in sty/ subdir and scripts in bin/\\ % TEXINPUTS:=sty\$(addprefix :,\$(TEXINPUTS))::\\ % TEXMFSCRIPTS:=bin\$(addprefix :,\$(TEXMFSCRIPTS))::\\ % export TEXINPUTS\\ % export TEXMFSCRIPTS\\ % \# Force using local LaTeX.mk and not system-wide LaTeX.mk if available\\ % include \$(CURDIR)/LaTeX.mk % \end{source} % \subsection{Customization} % Of course, lots of things can be customized. Here are the most % useful ones. Look at the section \ref{sec:reference} for more detailed % and complete possibilities. % \par % Customization is done through variables in the |Makefile| set % \emph{before} including |LaTeX.mk|. Setting them after can sometimes % work, but not always and it is not supported.\par % % \newcommand{\variable}[4][\texttt]{% % \paragraph*{#3}% % \addcontentsline{toc}{subsubsection}{#3}% % \hfill \hbox{#1{\textbf{#2}}}\par\medskip% % \textbf{Example:}\hspace{1em} |#4|\par\medskip } % % \variable{LU\_MASTERS}% % {Which \LaTeX{} documents to compile}% % {LU\_MASTERS=figlatex texdepends latex-make}% % This variable contains the basename of the \LaTeX{} documents to % compile. \par % If not set, |LaTeX.mk| looks for all |*.tex| files containing the % |\documentclass| command. % % \variable[]{\emph{master}\texttt{\_MAIN}}% % {Which \LaTeX{} main source for a document}% % {figlatex\_MAIN=figlatex.dtx}% % There is one such variable per documents declared in |LU_MASTERS|. % It contains the file against which the |latex| (or |pdflatex|, etc.) % program must be run. \par % If not set, \emph{master}|.tex| is used. % % \variable{LU\_FLAVORS}% % {Which flavors must be compiled}% % {LU\_FLAVORS=DVI DVIPDF}% % A flavor can be see as a kind of document (postscript, PDF, DVI, % etc.) and the way to create it. For example, a PDF document can be % created directly from the |.tex| file (with |pdflatex|), from a % |.dvi| file (with |dvipdfm|) or from a postscript file (with % |ps2pdf|). This would be three different flavors. % \par % Some flavors are already defined in |LaTeX.mk|. Other flavors can be % defined by the user (see section~\ref{sec:def_flavors}). The list of % predefined flavors can be see in the table~\ref{tab:flavors}. A % flavor can depend on another. For example, the flavor creating a % postscript file from a DVI file depends on the flavor creating a DVI % file from a \LaTeX{} file. This is automatically handled. % \par % If not set, |PS| and |PDF| are used (and |DVI| due to |PS|). %\def\extrarowheight{2pt} % \begin{table}[htbp] % \centering % % \begin{tabular}{|c|c|l|l|} % \hline % Flavor & dependency & program variable & Transformation \\ % \hline \hline % DVI & & LATEX & |.tex| $\Rightarrow$ |.dvi| \\ % \hline % PS & DVI & DVIPS & |.dvi| $\Rightarrow$ |.ps| \\ % \hline % PDF & & PDFLATEX & |.tex| $\Rightarrow$ |.pdf| \\ % \hline % LUALATEX & & LUALATEX & |.tex| $\Rightarrow$ |.pdf| \\ % \hline % DVIPDF & DVI & DVIPDFM & |.dvi| $\Rightarrow$ |.pdf| \\ % \hline % \end{tabular} % \par\smallskip % \begin{minipage}[t]{0.8\linewidth} % \em For example, the |DVI| flavor transforms a |*.tex| file into % a |*.dvi| file with the |Makefile| command % |$(LATEX) $(LATEX_OPTIONS)| % \end{minipage} % % \caption{Predefined flavors} % \label{tab:flavors} % % \end{table} % % \variable[]{\emph{prog}/\emph{prog}\texttt{\_OPTIONS}} % {Which programs are called and with which options}% % { % \begin{minipage}[t]{0.5\linewidth} % DVIPS=dvips\\DVIPS\_OPTIONS=-t a4 % \end{minipage} % } % Each flavor has a program variable name that is used by |LaTeX.mk| % to run the program. Another variable with the suffix |\_OPTIONS| is % also provided if needed. See the table~\ref{tab:flavors} the look % for the program variable name associated to the predefined flavors. % \par % Other programs are also run in the same manner. For example, the % |makeindex| program is run from |LaTeX.mk| with the help of the % variables |MAKEINDEX| and |MAKEINDEX_OPTIONS|. % % \variable[]{\emph{master}\texttt{\_}\emph{prog}/\emph{master}\texttt{\_}\emph{prog}\texttt{\_OPTIONS}} % {Per target programs and options}% % { % \begin{minipage}[t]{0.5\linewidth} % figlatex\_DVIPS=dvips\\ % figlatex\_DVIPS\_OPTIONS=-t a4 % \end{minipage} % } % Note that, if defined, \emph{master}\texttt{\_}\emph{prog} will % \textbf{\emph{replace}} \emph{prog} whereas % \emph{master}\texttt{\_}\emph{prog}\texttt{\_OPTIONS} will % \textbf{\emph{be added to}} \emph{prog}\texttt{\_OPTIONS} (see % section \ref{sec:variables} for more details). % % \variable[]{\texttt{DEPENDS}/\emph{master}\texttt{\_DEPENDS}} % {Global and per target dependencies}% % { % \begin{minipage}[t]{0.5\linewidth} % DEPENDS=texdepends.sty\\ % figlatex\_DEPENDS=figlatex.tex % \end{minipage} % } % All flavor targets will depend to theses files. This should not be % used as dependencies are automatically tracked. % %\section{Reference manual} %\label{sec:reference} % % \subsection{Flavors} % \subsubsection{What is a flavor ?} % A flavor can be see as a kind of document (postscript, PDF, DVI, % etc.) and the way to create it. Several property are attached to % each flavor. Currently, there exists two kinds of flavors: % \begin{description} % \item[TEX-flavors:] these flavors are used to compile a % \texttt{*.tex} file into a target. A \LaTeX{} compiler % (\texttt{latex}, \texttt{pdflatex}, etc.) is used; % \item[DVI-flavors:] these flavors are used to compile a file % produced by a TEX-flavors into an other file. Examples of such % flavors are all the ones converting a DVI file into another format % (postscript, PDF, etc.). % \end{description} % Several properties are attached to each flavors. Most are common, a % few a specific to the kind of the flavor. % \begin{description} % \item[Name:] the name of the flavor. It is used to declare dependencies % between flavors (see below). It also used to tell which flavor % should be compiled for each document (see the \texttt{FLAVORS} % variables); % \item[Program variable name:] name of the variable that will be used % to run the program of this flavor. This name is used for the % program and also for the options (variable with the % \texttt{\_OPTIONS} suffix); % \item[Target extension:] extension of the target of the flavor. The % dot must be added if wanted; % \item[Master target:] if not empty, all documents registered for the % flavor will be built when this master target is called; % \item[XFig extensions to clean (\emph{TEX-flavor only}):] files % extensions of figures that will be cleaned for the \texttt{clean} % target. Generally, there is \texttt{.pstex\_t .pstex} when using % \texttt{latex} and \texttt{.pdftex\_t .pdftex} when using % \texttt{pdflatex}; % \item[Dependency \emph{DVI-flavor only}:] name of the TEX-flavor the % one depends upon. % \end{description} % % \subsubsection{Defining a new flavor} % \label{sec:def_flavors} % To define a new flavor named \texttt{NAME}, one just have to declare % a \texttt{lu-define-flavor-NAME} that calls and evaluates the % \texttt{lu-create-flavor} with the right parameters, ie: % \begin{itemize} % \item name of the flavor; % \item kind of flavor (\texttt{tex} or \texttt{dvi}); % \item program variable name; % \item target extension; % \item master target; % \item XFig extensions to clean \emph{or} TEX-flavor to depend upon. % \end{itemize} % % \par % % For example, \texttt{LaTeX.mk} already defines: % \paragraph{DVI flavor} % \begin{source}[0.9\linewidth] % define lu-define-flavor-DVI\\ % \hspace*{2ex}\$\$(eval \$\$(call lu-create-flavor,DVI,tex,LATEX,.dvi,dvi,\textbackslash\\ % \hspace*{4ex}.pstex\_t .pstex))\\ % endef % \end{source} % \subparagraph{Tip:} the \texttt{LATEX} program variable name means % that the program called will be the one in the \texttt{LATEX} % variable and that options in the \texttt{LATEX\_OPTIONS} variable % will be used. % % \paragraph{PDF flavor} % \begin{source}[0.9\linewidth] % define lu-define-flavor-PDF\\ % \hspace*{2ex}\$\$(eval \$\$(call lu-create-flavor,PDF,tex,PDFLATEX,.pdf,pdf,\textbackslash\\ % \hspace*{4ex}.pdftex\_t .\$\$(\_LU\_PDFTEX\_EXT)))\\ % endef % \end{source} % % \paragraph{LuaLaTeX flavor} % \begin{source}[0.9\linewidth] % define lu-define-flavor-LUALATEX\\ % \hspace*{2ex}\$\$(eval \$\$(call lu-create-flavor,LUALATEX,tex,LUALATEX,.pdf,pdf,\textbackslash\\ % \hspace*{4ex}.pdftex\_t .\$\$(\_LU\_PDFTEX\_EXT)))\\ % endef % \end{source} % % \paragraph{PS flavor} % \begin{source}[0.9\linewidth] % define lu-define-flavor-PS\\ % \hspace*{2ex}\$\$(eval \$\$(call lu-create-flavor,PS,dvi,DVIPS,.ps,ps,DVI))\\ % endef % \end{source} % \subparagraph{Tip:} for DVI-flavors, the program will be invoked with % with the option \texttt{-o \emph{target}} and with the name of the % file source in argument. % % \paragraph{DVIPDF flavor} % \begin{source}[0.9\linewidth] % define lu-define-flavor-DVIPDF\\ % \hspace*{2ex}\$\$(eval \$\$(call lu-create-flavor,DVIPDF,dvi,DVIPDFM,.pdf,pdf,DVI))\\ % endef % \end{source} % % % \subsection{Variables} % \label{sec:variables} % \texttt{LaTeX.mk} use a generic mechanism to manage variables, so % that lots of thing can easily be customized per document and/or per % flavor. % \subsubsection{Two kind of variables} % \texttt{LaTeX.mk} distinguish two kind of variables. The first one % (called SET-variable) is for variables where only \emph{one} value % can be set. For example, this is the case for a variable that % contain the name of a program to launch. The second one (called % ADD-variable) is for variables where values can be cumulative. For % example, this will be the case for the options of a program. % \par % % For each variable used by \texttt{LaTeX.mk}, there exists several % variables that can be set in the Makefile so that the value will be % used for all documents, only for one document, only for one flavor, % etc. % % \newcounter{nbvars}% % \newenvironment{descvars}{% % \par % \noindent% % \bgroup% % \setcounter{nbvars}{0}% % \renewcommand{\emph}[1]{{\it ##1}} % \renewcommand{\variable}[3][;]{% % \stepcounter{nbvars}% % \arabic{nbvars}&\textbf{##2}&##3##1\\% % } % \begin{tabular}{clp{0.5\linewidth}} % }{% % \end{tabular} % \egroup % \par\medskip % } % % \paragraph{SET-variable.} For each SET-variable \texttt{\emph{NAME}}, we % can find in the Makfile: % \begin{descvars} % \variable{\texttt{LU\_\emph{target}\_\emph{NAME}}}{per document % and per flavor value}% % \variable{\texttt{TD\_\emph{target}\_\emph{NAME}}}{per document % and per flavor value filled by the \texttt{texdepends} \LaTeX{} % package}% % \variable{\texttt{LU\_\emph{master}\_\emph{NAME}}}{per document % value}% % \variable{\texttt{\emph{master}\_\emph{NAME}}}{per document % value}% % \variable{\texttt{LU\_FLAVOR\_\emph{flavor}\_\emph{NAME}}}{per % flavor value}% % \variable{\texttt{LU\_\emph{NAME}}}{global value}% % \variable{\texttt{\emph{NAME}}}{global value}% % \variable[.]{\texttt{\_LU\_\ldots\emph{NAME}}}{internal % \texttt{LaTeX.mk} default values}% % \end{descvars} % The first set variable will be used. % % \subparagraph{Tip:} in case of flavor context or document context, % only relevant variables will be checked. For example, the % SET-variable \texttt{MAIN} that give the main source of the document % will be evaluated in document context, so only 4, 5, 6, 7 and 8 will % be used (and I cannot see any real interest in using 6 or 7 for this % variable). % % \subparagraph{Tip2:} in case of context of index (when building % indexes or glossary), there exists several other variables per index % to add to this list (mainly ending with \texttt{\_{\it kind}\_{\it % indexname}\_{\it NAME}} or \texttt{\_{\it kind}\_{\it NAME}}). % Refer to the sources if you really need them. % % \paragraph{ADD-variable.} An ADD-variable is cumulative. The user % can replace or add any values per document, per flavor, etc. % \begin{descvars} % \variable{\texttt{LU\_\emph{target}\_\emph{NAME}}}{replacing per % document and per flavor values}% % \variable{\texttt{\emph{target}\_\emph{NAME}}}{cumulative per % document and per flavor values}% % \variable{\texttt{LU\_\emph{master}\_\emph{NAME}}}{replacing per % document values}% % \variable{\texttt{\emph{master}\_\emph{NAME}}}{cumulative per % document values}% % \variable{\texttt{LU\_FLAVOR\_\emph{flavor}\_\emph{NAME}}}{replacing % per flavor values}% % \variable{\texttt{FLAVOR\_\emph{flavor}\_\emph{NAME}}}{cumulative % per flavor values}% % \variable{\texttt{LU\_\emph{NAME}}}{replacing global values}% % \variable{\texttt{\emph{NAME}}}{cumulative global values}% % \end{descvars} % \subparagraph{Tip:} if not defined, \texttt{LU\_\emph{variable}} % defaults to ``\texttt{\$(\emph{variable}) % \$(\_LU\_\emph{variable})}'' and \texttt{\_LU\_\emph{variable}} % contains default values managed by \texttt{LaTeX.mk} and the % \texttt{texdepends} \LaTeX{} package. % \subparagraph{Example:} the ADD-variable \texttt{FLAVORS} is invoked % in document context to know which flavors needs to be build for each % document. This means that \texttt{LU\_{\it master}\_FLAVORS} will be % used. % \begin{source} % \# We override default value for MASTERS\\ % LU\_MASTERS=foo bar baz\\ % \# By default, only the DVIPDF flavor will be build\\ % FLAVORS=DVIPDF\\ % ~\\ % bar\_FLAVORS=PS\\ % LU\_baz\_FLAVORS=PDF\\ % \# there will be rules to build\\ % \# * foo.dvi and foo.pdf\\ % \# ~ (the DVIPDF flavor depends on the DVI flavor)\\ % \# * bar.dvi, bar.pdf and bar.ps\\ % \# ~ (the PS flavor is added to global flavors)\\ % \# * baz.pdf\\ % \# ~ (the PDF flavor will be the only one for baz) % include LaTeX.mk % \end{source} % \subsubsection{List of used variables} % Here are most of the variables used by \texttt{LaTeX.mk}. Users % should only have to sometimes managed the first ones. The latter are % described here for information only (and are subject to % modifications). Please, report a bug if some of them are not % correctly pickup by the \texttt{texdepends} \LaTeX{} package and % \texttt{LaTeX.mk}. % % \newenvironment{describevars}{% % \par % \noindent% % \bgroup% % \renewcommand{\emph}[1]{{\it ##1}}% % \newcommand{\default}[1]{\newline\textbf{Default: }##1} % \renewcommand{\variable}[4]{% % \textbf{\texttt{##1}}&##2&##3&##4\\% % } % \begin{tabular}{cccp{0.5\linewidth}} % Name & Kind &% % \multicolumn{1}{m{4em}}{\begin{center}Context of % use\end{center}} & % \multicolumn{1}{c}{Description} \\ % \hline % \hline % }{% % \end{tabular} % \egroup % \par\medskip % } % % \begin{describevars} % \variable{MASTERS}{ADD}{Global}{List of documents to compile. % These values will be used as jobname. \default{basename of % \texttt{*.tex} files containing the \texttt{\textbackslash % documentclass} pattern}}% % \variable{FLAVORS}{ADD}{Document}{List of flavors for each % document. \default{\texttt{PS PDF}}}% % \variable{MAIN}{SET}{Document}{Master \texttt{tex} source % file\default{\texttt{\emph{master}.tex}}}% % \variable{DEPENDS}{ADD}{Target}{List of dependencies}% % \variable{DEPENDS\_EXCLUDE}{ADD}{Target}{Dependencies to % forget. Useful when LaTeX Make wrongly auto-detect false dependencies}% % \variable{\emph{progvarname}}{SET}{Target}{Program to launch for % the corresponding flavor}% % \variable{\emph{progvarname}\_OPTIONS}{ADD}{Target}{Options to use % when building the target}% % \variable{STYLE}{SET}{Index}{Name of the index/glossary style file % to use (\texttt{.ist}, etc.)}% % \hline % \variable{TARGET}{SET}{Index}{Name of the index/glossary file to % produce (\texttt{.ind}, \texttt{.gls}, etc.)}% % \variable{SRC}{SET}{Index}{Name of the index/glossary file source % (\texttt{.idx}, \texttt{.glo}, etc.)}% % \variable{FIGURES}{ADD}{Target}{Lists of figures included}% % \variable{BIBFILES}{ADD}{Target}{Lists of bibliography files used % (\texttt{.bib})}% % \variable{BIBSTYLES}{ADD}{Target}{Lists of bibliography style % files used (\texttt{.bst})}% % \variable{BBLFILES}{ADD}{Target}{Lists of built bibliography files % (\texttt{.bbl})}% % \variable{INPUT}{ADD}{Target}{Lists of input files (\texttt{.cls}, % \texttt{.sty}, \texttt{.tex}, etc.)}% % \variable{OUTPUTS}{ADD}{Target}{Lists of output files % (\texttt{.aux}, etc.)}% % \variable{GRAPHICSPATH}{ADD}{Target}{\texttt{\textbackslash % graphicspath\{\}} arguments}% % \variable{GPATH}{ADD}{Target}{List of directories from % \texttt{GRAPHICSPATH} without \texttt{\{} and \texttt{\}}, % separated by spaces}% % \variable{INDEXES}{ADD}{Target}{Kinds of index (\texttt{INDEX}, % \texttt{GLOSS}, etc.)}% % \variable{INDEXES\_\emph{kind}}{ADD}{Target}{List of indexes or % glossaries}% % \variable{WATCHFILES}{ADD}{Target}{List of files that trigger a % rebuild if modified (\texttt{.aux}, etc.)}% % \variable{REQUIRED}{ADD}{Target}{List of new dependencies found by % the \texttt{texdepends} \LaTeX{} package}% % \variable{MAX\_REC}{SET}{Target}{Maximum level of recursion % authorized}% % \variable{REBUILD\_RULES}{ADD}{Target}{List of rebuild rules to % use (can be modified by the \texttt{texdepends} \LaTeX{} % package}% % \variable{EXT}{SET}{Flavor}{Target file extension of the flavor}% % \variable{DEPFLAVOR}{SET}{Flavor}{TEX-flavor a DVI-flavor depend % upon}% % \variable{CLEANFIGEXT}{ADD}{Flavor}{Extensions of figure files to % remove on clean}% % \end{describevars} % % \newpage % \section{FAQ} % % \newenvironment{question}[2]{ % \subsection{#1} % \texttt{}\llap{$\Rightarrow$ \quad }\emph{#2}\par\bigskip}{ % } % % \begin{question}{No rule to make target `LU\_WATCH\_FILES\_SAVE'}{When % using |LaTeX.mk|, I got the error:\\ % |make[1]: *** No rule to make target `LU\_WATCH\_FILES\_SAVE'. Stop.|} % % |make| is called in such a way that does not allow correct recursive % calls. As one can not know by advance how many times \LaTeX{}, % bib\TeX{}, etc. will need to be run, |latex-make| use recursive % invocations of |make|. This means that in the |LaTeX.mk| makefile, % there exist rules such as: % \begin{source} % \$(MAKE) INTERNAL\_VARIABLE=value internal\_target % \end{source} % In order |latex-make| to work, this invocation of |make| must read % the same rules and variable definitions as the main one. This means % that calling "|make -f LaTeX.mk foo.pdf|" in a directory with only % |foo.tex| will not work. Recursive invocations of make will not load % |LaTeX.mk|, will search for a |Makefile| in the current directory % and will complain about being unable to build the % |LU_WATCH_FILES_SAVE| internal target. % % \par\medskip % The solution is to call |make| so that recursive invocations will % read the same variables and rules. For example:\\ % |make -f LaTeX.mk MAKE="make -f LaTeX.mk" foo.pdf|\\ % or (if there is no |Makefile| in the directory):\\ % |env MAKEFILES=LaTeX.mk make foo.pdf|\\ % % \end{question} % % \StopEventually{ % } % \newpage % \section{Implementation} % % \subsection{LaTeX.mk} % \begin{macrocode} %<*makefile> ####[ Check Software ]################################################ ifeq ($(filter else-if,$(.FEATURES)),) $(error GNU Make 3.81 needed. Please, update your software.) exit 1 endif # Some people want to call our Makefile snippet with # make -f LaTeX.mk # This should not work as $(MAKE) is call recursively and will not read # LaTeX.mk again. We cannot just add LaTeX.mk to MAKEFILES as LaTeX.mk # should be read AFTER a standard Makefile (if any) that can define some # variables (LU_MASTERS, ...) that LaTeX.mk must see. # So I introduce an HACK here that try to workaround the situation. Keep in # mind that this hack is not perfect and does not handle all cases # (for example, "make -f my_latex_config.mk -f LaTeX.mk" will not recurse # correctly) ifeq ($(foreach m,$(MAKEFILES), $(m)) $(lastword $(MAKEFILE_LIST)),$(MAKEFILE_LIST)) # We are the first file read after the ones from MAKEFILES # So we assume we are read due to "-f LaTeX.mk" LU_LaTeX.mk_NAME := $(lastword $(MAKEFILE_LIST)) # Is this Makefile correctly read for recursive calls ? ifeq ($(findstring -f $(LU_LaTeX.mk_NAME),$(MAKE)),) $(info ********************************************************************************) $(info Warning: $(LU_LaTeX.mk_NAME) called directly. I suppose that you run:) $(info Warning: $(MAKE) -f $(LU_LaTeX.mk_NAME) $(MAKECMDGOALS)) $(info Warning: or something similar that does not allow recursive invocation of make) $(info Warning: ) $(info Warning: Trying to enable a workaround. This ACK will be disabled in a future) $(info Warning: release. Consider using another syntax, for example:) $(info Warning: $(MAKE) -f $(LU_LaTeX.mk_NAME) MAKE="$(MAKE) -f $(LU_LaTeX.mk_NAME)" $(MAKECMDGOALS)) $(info ********************************************************************************) MAKE+= -f $(LU_LaTeX.mk_NAME) endif endif ####[ Configuration ]################################################ # list of messages categories to display LU_SHOW ?= warning #info debug debug-vars # Select GNU/BSD/MACOSX utils (cp, rm, mv, ...) LU_UTILS ?= $(shell ( /bin/cp --heelp > /dev/null 2>&1 && echo GNU ) || echo BSD ) export LU_UTILS ####[ End of configuration ]################################################ # Modifying the remaining of this document may endanger you life!!! ;) #--------------------------------------------------------------------- # Controling verbosity ifdef VERB MAK_VERB := $(VERB) else #MAK_VERB := debug #MAK_VERB := verbose #MAK_VERB := normal MAK_VERB := quiet #MAK_VERB := silent endif #--------------------------------------------------------------------- # MAK_VERB -> verbosity ifeq ($(MAK_VERB),debug) COMMON_PREFIX = echo " ======> building " $@ "<======" ; \ printf "%s $(@F) due to:$(foreach file,$?,\n * $(file))\n" $1; set -x; # COMMON_HIDE := set -x; COMMON_CLEAN := set -x; SHOW_LATEX:=true else ifeq ($(MAK_VERB),verbose) COMMON_PREFIX = echo " ======> building " $@ "<======" ; \ printf "%s $(@F) due to:$(foreach file,$?,\n * $(file))\n" $1; # COMMON_HIDE :=# COMMON_CLEAN :=# SHOW_LATEX:=true else ifeq ($(MAK_VERB),normal) COMMON_PREFIX =# COMMON_HIDE := @ COMMON_CLEAN :=# SHOW_LATEX:=true else ifeq ($(MAK_VERB),quiet) COMMON_PREFIX = @ echo " ======> building " $@ "<======" ; # echo "due to $?" ; COMMON_HIDE := @ COMMON_CLEAN :=# SHOW_LATEX:= else # silent COMMON_PREFIX = @ COMMON_HIDE := @ COMMON_CLEAN := @ SHOW_LATEX:= endif endif endif endif #--------------------------------------------------------------------- # Old LaTeX have limitations _LU_PDFTEX_EXT ?= pdftex ######################################################################### # Utilities LU_CP=$(LU_CP_$(LU_UTILS)) LU_MV=$(LU_MV_$(LU_UTILS)) LU_RM=$(LU_RM_$(LU_UTILS)) LU_CP_GNU ?= cp -a -- LU_MV_GNU ?= mv -- LU_RM_GNU ?= rm -f -- LU_CP_BSD ?= cp -p LU_MV_BSD ?= mv LU_RM_BSD ?= rm -f LU_CP_MACOSX ?= /bin/cp -p LU_MV_MACOSX ?= /bin/mv LU_RM_MACOSX ?= /bin/rm -f lu-show=\ $(if $(filter $(LU_SHOW),$(1)), \ $(if $(2), \ $(if $(filter-out $(2),$(MAKELEVEL)),,$(3)), \ $(3))) lu-show-infos=\ $(if $(filter $(LU_SHOW),$(1)), \ $(if $(2), \ $(if $(filter-out $(2),$(MAKELEVEL)),,$(warning $(3))), \ $(warning $(3)))) lu-show-rules=$(call lu-show-infos,info,0,$(1)) lu-show-flavors=$(call lu-show-infos,info,0,$(1)) lu-show-var=$(call lu-show-infos,debug-vars,, * Set $(1)=$($(1))) lu-show-read-var=$(eval $(call lu-show-infos,debug-vars,, Reading $(1) in $(2) ctx: $(3)))$(3) lu-show-readone-var=$(eval $(call lu-show-infos,debug-vars,, Reading $(1) for $(2) [one value]: $(3)))$(3) lu-show-set-var=$(call lu-show-infos,debug-vars,, * Setting $(1) for $(2) to value: $(3)) lu-show-add-var=$(call lu-show-infos,debug-vars,, * Adding to $(1) for $(2) values: $(value 3)) lu-show-add-var2=$(call lu-show-infos,warning,, * Adding to $(1) for $(2) values: $(value 3)) lu-save-file=$(call lu-show,debug,,echo "saving $1" ;) \ if [ -f "$1" ];then $(LU_CP) "$1" "$2" ;else $(LU_RM) "$2" ;fi lu-cmprestaure-file=\ if cmp -s "$1" "$2"; then \ $(LU_MV) "$2" "$1" ; \ $(call lu-show,debug,,echo "$1" not modified ;) \ else \ $(call lu-show,debug,,echo "$1" modified ;) \ if [ -f "$2" -o -f "$1" ]; then \ $(RM) -- "$2" ; \ $3 \ fi ; \ fi lu-clean=$(if $(strip $(1)),$(RM) $(1)) define lu-bug # description $$(warning Internal error: $(1)) $$(error You probably found a bug. Please, report it.) endef ######################################################################### ######################################################################### ######################################################################### ######################################################################### ################## ######################### ################## Variables ######################### ################## ######################### ######################################################################### ######################################################################### ######################################################################### ######################################################################### ######################################################################### # # _LU_FLAVORS_DEFINED : list of available flavors # _LU_FLAV_*_'flavname' : per flavor variables # where * can be : # PROGNAME : variable name for programme (and .._OPTIONS for options) # EXT : extension of created file # TARGETNAME : global target # DEPFLAVOR : flavor to depend upon # CLEANFIGEXT : extensions to clean for fig figures _LU_FLAVORS_DEFINED = $(_LU_FLAVORS_DEFINED_TEX) $(_LU_FLAVORS_DEFINED_DVI) # INDEXES_TYPES = GLOSS INDEX # INDEXES_INDEX = name1 ... # INDEXES_GLOSS = name2 ... # INDEX_name1_SRC # GLOSS_name2_SRC define _lu-getvalues# 1:VAR 2:CTX (no inheritage) $(if $(filter-out undefined,$(origin LU_$2$1)),$(LU_$2$1),$($2$1) $(_LU_$2$1_MK) $(TD_$2$1)) endef define lu-define-addvar # 1:suffix_fnname 2:CTX 3:disp-debug 4:nb_args 5:inherited_ctx 6:ctx-build-depend define lu-addtovar$1 # 1:VAR 2:... $4: value _LU_$2$$1_MK+=$$($4) $$(call lu-show-add-var,$$1,$3,$$(value $4)) endef define lu-def-addvar-inherited-ctx$1 # 1:VAR 2:... $6 _LU_$2$$1_INHERITED_CTX=$$(sort \ $$(foreach ctx,$5,$$(ctx) $$(if $$(filter-out undefined,$$(origin \ LU_$$(ctx)$$1)),,\ $$(_LU_$$(ctx)$$1_INHERITED_CTX)))) $$$$(call lu-show-var,_LU_$2$$1_INHERITED_CTX) endef define lu-getvalues$1# 1:VAR 2:... $$(if $$(filter-out undefined,$$(origin _LU_$2$$1_INHERITED_CTX)),,$$(eval \ $$(call lu-def-addvar-inherited-ctx$1,$$1,$$2,$$3,$$4,$$5,$$6)\ ))$$(call lu-show-read-var,$$1,$3,$$(foreach ctx,\ $(if $2,$2,GLOBAL) $$(if $$(filter-out undefined,$$(origin LU_$2$$1)),,\ $$(_LU_$2$$1_INHERITED_CTX))\ ,$$(call _lu-getvalues,$$1,$$(filter-out GLOBAL,$$(ctx))))) endef endef # Global variable # VAR (DEPENDS) $(eval $(call lu-define-addvar,-global,,global,2)) # Per flavor variable # FLAVOR_$2_VAR (FLAVOR_DVI_DEPENDS) # 2: flavor name # Inherit from VAR (DEPENDS) $(eval $(call lu-define-addvar,-flavor,FLAVOR_$$2_,flavor $$2,3,\ GLOBAL,\ $$(eval $$(call lu-def-addvar-inherited-ctx-global,$$1)) \ )) # Per master variable # $2_VAR (source_DEPENDS) # 2: master name # Inherit from VAR (DEPENDS) $(eval $(call lu-define-addvar,-master,$$2_,master $$2,3,\ GLOBAL,\ $$(eval $$(call lu-def-addvar-inherited-ctx-global,$$1)) \ )) # Per target variable # $2$(EXT of $3)_VAR (source.dvi_DEPENDS) # 2: master name # 3: flavor name # Inherit from $2_VAR FLAVOR_$3_VAR (source_DEPENDS FLAVOR_DVI_DEPENDS) $(eval $(call lu-define-addvar,,$$2$$(call lu-getvalue-flavor,EXT,$$3)_,target $$2$$(call lu-getvalue-flavor,EXT,$$3),4,\ $$2_ FLAVOR_$$3_,\ $$(eval $$(call lu-def-addvar-inherited-ctx-master,$$1,$$2)) \ $$(eval $$(call lu-def-addvar-inherited-ctx-flavor,$$1,$$3)) \ )) # Per index/glossary variable # $(2)_$(3)_VAR (INDEX_source_DEPENDS) # 2: type (INDEX, GLOSS, ...) # 3: index name # Inherit from VAR (DEPENDS) $(eval $(call lu-define-addvar,-global-index,$$2_$$3_,index $$3[$$2],4,\ GLOBAL,\ $$(eval $$(call lu-def-addvar-inherited-ctx-global,$$1)) \ )) # Per master and per index/glossary variable # $(2)_$(3)_$(4)_VAR (source_INDEX_source_DEPENDS) # 2: master name # 3: type (INDEX, GLOSS, ...) # 4: index name # Inherit from $2_VAR $3_$4_VAR (source_DEPENDS INDEX_source_DEPENDS) $(eval $(call lu-define-addvar,-master-index,$$2_$$3_$$4_,index $$2/$$4[$$3],5,\ $$2_ $$3_$$4_,\ $$(eval $$(call lu-def-addvar-inherited-ctx-master,$$1,$$2)) \ $$(eval $$(call lu-def-addvar-inherited-ctx-global-index,$$1,$$3,$$4)) \ )) # Per target and per index/glossary variable # $(2)$(EXT of $3)_$(4)_$(5)_VAR (source.dvi_INDEX_source_DEPENDS) # 2: master name # 3: flavor name # 4: type (INDEX, GLOSS, ...) # 5: index name # Inherit from $2$(EXT of $3)_VAR $(2)_$(3)_$(4)_VAR # (source.dvi_DEPENDS source_INDEX_source_DEPENDS) $(eval $(call lu-define-addvar,-index,$$2$$(call lu-getvalue-flavor,EXT,$$3)_$$4_$$5_,index $$2$$(call lu-getvalue-flavor,EXT,$$3)/$$5[$$4],6,\ $$2$$(call lu-getvalue-flavor,EXT,$$3)_ $$2_$$4_$$5_,\ $$(eval $$(call lu-def-addvar-inherited-ctx,$$1,$$2,$$3)) \ $$(eval $$(call lu-def-addvar-inherited-ctx-master-index,$$1,$$2,$$4,$$5)) \ )) define lu-setvar-global # 1:name 2:value _LU_$(1) ?= $(2) $$(eval $$(call lu-show-set-var,$(1),global,$(2))) endef define lu-setvar-flavor # 1:name 2:flavor 3:value _LU_FLAVOR_$(2)_$(1) ?= $(3) $$(eval $$(call lu-show-set-var,$(1),flavor $(2),$(3))) endef define lu-setvar-master # 1:name 2:master 3:value _LU_$(2)_$(1) ?= $(3) $$(eval $$(call lu-show-set-var,$(1),master $(2),$(3))) endef define lu-setvar # 1:name 2:master 3:flavor 4:value _LU_$(2)$$(call lu-getvalue-flavor,EXT,$(3))_$(1)=$(4) $$(eval $$(call lu-show-set-var,$(1),master/flavor $(2)/$(3),$(4))) endef define lu-getvalue # 1:name 2:master 3:flavor $(call lu-show-readone-var,$(1),master/flavor $(2)/$(3),$(or \ $(LU_$(2)$(call lu-getvalue-flavor,EXT,$(3))_$(1)), \ $(TD_$(2)$(call lu-getvalue-flavor,EXT,$(3))_$(1)), \ $(LU_$(2)_$(1)), \ $($(2)_$(1)), \ $(LU_FLAVOR_$(3)_$(1)), \ $(LU_$(1)), \ $($(1)), \ $(_LU_$(2)$(call lu-getvalue-flavor,EXT,$(3))_$(1)), \ $(_LU_$(2)_$(1)), \ $(_LU_FLAVOR_$(3)_$(1)), \ $(_LU_$(1))\ )) endef define lu-getvalue-flavor # 1:name 2:flavor $(call lu-show-readone-var,$(1),flavor $(2),$(or \ $(LU_FLAVOR_$(2)_$(1)), \ $(LU_$(1)), \ $($(1)), \ $(_LU_FLAVOR_$(2)_$(1)), \ $(_LU_$(1))\ )) endef define lu-getvalue-master # 1:name 2:master $(call lu-show-readone-var,$(1),master $(2),$(or \ $(LU_$(2)_$(1)), \ $($(2)_$(1)), \ $(LU_$(1)), \ $($(1)), \ $(_LU_$(2)_$(1)), \ $(_LU_$(1))\ )) endef define lu-getvalue-index # 1:name 2:master 3:flavor 4:type 5:indexname $(call lu-show-readone-var,$(1),master/flavor/index $(2)/$(3)/[$(4)]$(5),$(or \ $(LU_$(2)$(call lu-getvalue-flavor,EXT,$(3))_$(4)_$(5)_$(1)), \ $(LU_$(2)_$(4)_$(5)_$(1)), \ $(TD_$(2)$(call lu-getvalue-flavor,EXT,$(3))_$(4)_$(5)_$(1)), \ $($(2)_$(4)_$(5)_$(1)), \ $(LU_$(4)_$(5)_$(1)), \ $($(4)_$(5)_$(1)), \ $(LU_$(2)$(call lu-getvalue-flavor,EXT,$(3))_$(4)_$(1)), \ $(LU_$(2)_$(4)_$(1)), \ $($(2)_$(4)_$(1)), \ $(LU_$(4)_$(1)), \ $($(4)_$(1)), \ $(LU_$(2)_$(1)), \ $($(2)_$(1)), \ $(LU_FLAVOR_$(3)_$(1)), \ $(LU_$(1)), \ $($(1)), \ $(_LU_$(2)$(call lu-getvalue-flavor,EXT,$(3))_$(4)_$(5)_$(1)), \ $(_LU_$(2)_$(4)_$(5)_$(1)), \ $(_LU_$(4)_$(5)_$(1)), \ $(_LU_$(2)$(call lu-getvalue-flavor,EXT,$(3))_$(4)_$(1)), \ $(_LU_$(2)_$(4)_$(1)), \ $(_LU_FLAVOR_$(3)_$(4)_$(1)), \ $(_LU_$(4)_$(1)), \ $(_LU_$(2)$(call lu-getvalue-flavor,EXT,$(3))_$(1)), \ $(_LU_$(2)_$(1)), \ $(_LU_FLAVOR_$(3)_$(1)), \ $(_LU_$(1))\ )) endef define lu-call-prog # 1:varname 2:master 3:flavor [4:index] $(call lu-getvalue,$(1),$(2),$(3)) $(call lu-getvalues,$(1)_OPTIONS,$(2),$(3)) endef define lu-call-prog-index # 1:varname 2:master 3:flavor 4:type 5:indexname $(call lu-getvalue$(if $(4),-index),$(1),$(2),$(3),$(4),$(5)) \ $(call lu-getvalues$(if $(4),-index),$(1)_OPTIONS,$(2),$(3),$(4),$(5)) endef define lu-call-prog-flavor # 1:master 2:flavor $(call lu-call-prog,$(call lu-getvalue,VARPROG,$(1),$(2)),$(1),$(2)) endef ######################################################################### ######################################################################### ######################################################################### ######################################################################### ################## ######################### ################## Global variables ######################### ################## ######################### ######################################################################### ######################################################################### ######################################################################### ######################################################################### ######################################################################### # Globals variables $(eval $(call lu-setvar-global,LATEX,latex)) $(eval $(call lu-setvar-global,PDFLATEX,pdflatex)) $(eval $(call lu-setvar-global,LUALATEX,lualatex)) $(eval $(call lu-setvar-global,DVIPS,dvips)) $(eval $(call lu-setvar-global,DVIPDFM,dvipdfm)) $(eval $(call lu-setvar-global,BIBTEX,bibtex)) #$(eval $(call lu-setvar-global,MPOST,TEX="$(LATEX)" mpost)) $(eval $(call lu-setvar-global,FIG2DEV,fig2dev)) #$(eval $(call lu-setvar-global,SVG2DEV,svg2dev)) $(eval $(call lu-setvar-global,EPSTOPDF,epstopdf)) $(eval $(call lu-setvar-global,MAKEINDEX,makeindex)) # workaround the fact that $(shell ...) ignore locally exported variables # get only the variables with plain names _LU_MAKE_ENV := $(shell echo '$(.VARIABLES)' | awk -v RS=' ' '/^[a-zA-Z0-9]+$$/') _LU_SHELL_EXPORT := $(foreach v,$(_LU_MAKE_ENV),$(v)='$($(v))') _lu_run_kpsewhich=$(shell $(_LU_SHELL_EXPORT) kpsewhich -format $1 $2) # Look first into the TDS (texmfscripts), then in PATH for our program # At each location, we prefer with suffix than without define _lu_which # VARNAME progname ifeq ($(origin _LU_$(1)_DEFAULT), undefined) _LU_$(1)_DEFAULT := $$(firstword $$(wildcard \ $$(call _lu_run_kpsewhich,texmfscripts,$(2)) \ $$(call _lu_run_kpsewhich,texmfscripts,$$(basename $(2))) \ $$(foreach dir,$$(subst :, ,$$(PATH)), \ $$(dir)/$(2) $$(dir)/$$(basename $(2))) \ ) $(2)) export _LU_$(1)_DEFAULT _LU_$(1)_DEFAULT_OLD := $$(firstword $$(wildcard \ $$(addprefix bin/,$(2) $$(basename $(2))) \ $$(addprefix ./,$(2) $$(basename $(2))))) $$(if $$(filter-out $$(_LU_$(1)_DEFAULT), $$(_LU_$(1)_DEFAULT_OLD)),\ $$(if $$(_lu_scripts_warnings),, \ $$(eval _lu_scripts_warnings:=done) \ $$(warning By default, this version of LaTeX-Make do not use \ scripts in $$(dir $$(_LU_$(1)_DEFAULT_OLD)) anymore.) \ $$(warning For example $$(_LU_$(1)_DEFAULT) is used instead of $$(_LU_$(1)_DEFAULT_OLD))\ $$(warning If you want to keep the old behavior, add into your \ Makefile something like:)\ $$(warning export TEXMFSCRIPTS:=$$(dir $$(_LU_$(1)_DEFAULT_OLD))$$$$(addprefix :,$$$$(TEXMFSCRIPTS))::))) #$$(warning _LU_$(1)_DEFAULT=$$(_LU_$(1)_DEFAULT)) endif $$(eval $$(call lu-setvar-global,$(1),$$(_LU_$(1)_DEFAULT))) endef $(eval $(call _lu_which,GENSUBFIG,gensubfig.py)) $(eval $(call _lu_which,FIGDEPTH,figdepth.py)) $(eval $(call _lu_which,GENSUBSVG,gensubfig.py)) $(eval $(call _lu_which,SVGDEPTH,svgdepth.py)) $(eval $(call _lu_which,SVG2DEV,svg2dev.py)) $(eval $(call _lu_which,LATEXFILTER,latexfilter.py)) # Rules to use to check if the build document (dvi or pdf) is up-to-date # This can be overruled per document manually and/or automatically #REBUILD_RULES ?= latex texdepends bibtopic bibtopic_undefined_references $(eval $(call lu-addtovar-global,REBUILD_RULES,latex texdepends)) # Default maximum recursion level $(eval $(call lu-setvar-global,MAX_REC,6)) ######################################################################### ######################################################################### ######################################################################### ######################################################################### ################## ######################### ################## Flavors ######################### ################## ######################### ######################################################################### ######################################################################### ######################################################################### ######################################################################### ######################################################################### define lu-create-texflavor # 1:name 2:tex_prog 3:file_ext # 4:master_cible 5:fig_extention_to_clean _LU_FLAVORS_DEFINED_TEX += $(1) $(eval $(call lu-setvar-flavor,VARPROG,$(1),$(2))) $(eval $(call lu-setvar-flavor,EXT,$(1),$(3))) $(eval $(call lu-setvar-flavor,TARGETNAME,$(1),$(4))) $(eval $(call lu-addtovar-flavor,CLEANFIGEXT,$(1),$(5))) $(eval $(call lu-addtovar-flavor,CLEANSVGEXT,$(1),$(5))) endef define lu-create-dviflavor # 1:name 2:dvi_prog 3:file_ext # 4:master_cible 5:tex_flavor_depend $$(eval $$(call lu-define-flavor,$(5))) _LU_FLAVORS_DEFINED_DVI += $(1) $(eval $(call lu-setvar-flavor,VARPROG,$(1),$(2))) $(eval $(call lu-setvar-flavor,EXT,$(1),$(3))) $(eval $(call lu-setvar-flavor,TARGETNAME,$(1),$(4))) $(eval $(call lu-setvar-flavor,DEPFLAVOR,$(1),$(5))) endef define lu-create-flavor # 1:name 2:type 3..7:options $$(if $$(filter $(1),$(_LU_FLAVORS_DEFINED)), \ $$(call lu-show-flavors,Flavor $(1) already defined), \ $$(call lu-show-flavors,Creating flavor $(1) ($(2))) \ $$(eval $$(call lu-create-$(2)flavor,$(1),$(3),$(4),$(5),$(6),$(7)))) endef define lu-define-flavor # 1:name $$(eval $$(call lu-define-flavor-$(1))) endef define lu-flavor-rules # 1:name $$(call lu-show-flavors,Defining rules for flavor $(1)) $$(if $$(call lu-getvalue-flavor,TARGETNAME,$(1)), \ $$(call lu-getvalue-flavor,TARGETNAME,$(1)): \ $$(call lu-getvalues-flavor,TARGETS,$(1))) $$(if $$(call lu-getvalue-flavor,TARGETNAME,$(1)), \ .PHONY: $$(call lu-getvalue-flavor,TARGETNAME,$(1))) endef define lu-define-flavor-DVI # $$(eval $$(call lu-create-flavor,DVI,tex,LATEX,.dvi,dvi,\ .pstex_t .pstex)) endef define lu-define-flavor-PDF # $$(eval $$(call lu-create-flavor,PDF,tex,PDFLATEX,.pdf,pdf,\ .pdftex_t .$$(_LU_PDFTEX_EXT))) endef define lu-define-flavor-LUALATEX # $$(eval $$(call lu-create-flavor,LUALATEX,tex,LUALATEX,.pdf,pdf,\ .pdftex_t .$$(_LU_PDFTEX_EXT))) endef define lu-define-flavor-PS # $$(eval $$(call lu-create-flavor,PS,dvi,DVIPS,.ps,ps,DVI)) endef define lu-define-flavor-DVIPDF # $$(eval $$(call lu-create-flavor,DVIPDF,dvi,DVIPDFM,.pdf,pdf,DVI)) endef $(eval $(call lu-addtovar-global,FLAVORS,PDF PS)) ######################################################################### ######################################################################### ######################################################################### ######################################################################### ################## ######################### ################## Masters ######################### ################## ######################### ######################################################################### ######################################################################### ######################################################################### ######################################################################### ######################################################################### define _lu-do-latex # 1:master 2:flavor 3:source.tex 4:ext(.dvi/.pdf) exec 3>&1; \ run() { \ printf "Running:" 1>&3 ; \ for arg; do \ printf "%s" " '$$arg'" 1>&3 ; \ done ; echo 1>&3 ; \ "$$@" ; \ }; \ doit() { \ $(RM) -v "$(1)$(4)_FAILED" \ "$(1)$(4)_NEED_REBUILD" \ "$(1)$(4).mk" ;\ ( echo X | \ run $(call lu-call-prog-flavor,$(1),$(2)) \ --interaction errorstopmode \ --jobname "$(1)" \ '\RequirePackage[extension='"$(4)"']{texdepends}\input'"{$(3)}" || \ touch "$(1)$(4)_FAILED" ; \ if grep -sq '^! LaTeX Error:' "$(1).log" ; then \ touch "$(1)$(4)_FAILED" ; \ fi \ ) | $(call lu-call-prog,LATEXFILTER,$(1),$(2)) ; \ NO_TEXDEPENDS_FILE=0 ;\ if [ ! -f "$(1)$(4).mk" ]; then \ NO_TEXDEPENDS_FILE=1 ;\ fi ;\ sed -e 's,\\openout[0-9]* = \([^`].*\),TD_$(1)$(4)_OUTPUTS += \1,p;s,\\openout[0-9]* = `\(.*\)'"'.,TD_$(1)$(4)_OUTPUTS += \1,p;d" \ "$(1).log" >> "$(1)$(4).mk" ;\ if [ -f "$(1)$(4)_FAILED" ]; then \ echo "*************************************" ;\ echo "Building $(1)$(4) fails" ;\ echo "*************************************" ;\ echo "Here are the last lines of the log file" ;\ echo "If this is not enought, try to" ;\ echo "call 'make' with 'VERB=verbose' option" ;\ echo "*************************************" ;\ echo "==> Last lines in $(1).log <==" ; \ sed -e '/^[?] X$$/,$$d' \ -e '/^Here is how much of TeX'"'"'s memory you used:$$/,$$d' \ < "$(1).log" | tail -n 20; \ return 1; \ fi; \ if [ "$$NO_TEXDEPENDS_FILE" = 1 ]; then \ echo "*************************************" ;\ echo "texdepends does not seems be loaded" ;\ echo "Either your (La)TeX installation is wrong or you found a bug." ;\ echo "If so, please, report it (with the result of shell command 'kpsepath tex')";\ echo "Aborting compilation" ;\ echo "*************************************" ;\ touch "$(1)$(4)_FAILED" ; \ return 1 ;\ fi ;\ }; doit endef .PHONY: clean-build-fig ########################################################## define lu-master-texflavor-index-vars # MASTER FLAVOR TYPE INDEX ext(.dvi/.pdf) $$(call lu-show-rules,Setting flavor index vars for $(1)/$(2)/[$(3)]$(4)) $$(eval $$(call lu-addtovar,DEPENDS,$(1),$(2), \ $$(call lu-getvalue-index,TARGET,$(1),$(2),$(3),$(4)))) $$(eval $$(call lu-addtovar,WATCHFILES,$(1),$(2), \ $$(call lu-getvalue-index,SRC,$(1),$(2),$(3),$(4)))) endef #################################################### define lu-master-texflavor-index-rules # MASTER FLAVOR TYPE INDEX ext(.dvi/.pdf) $$(call lu-show-rules,Setting flavor index rules for $(1)/$(2)/[$(3)]$(4)) $$(if $$(_LU_DEF_IND_$$(call lu-getvalue-index,TARGET,$(1),$(2),$(3),$(4))), \ $$(call lu-show-rules,=> Skipping: already defined in flavor $$(_LU_DEF_IND_$$(call lu-getvalue-index,TARGET,$(1),$(2),$(3),$(4)))), \ $$(eval $$(call _lu-master-texflavor-index-rules\ ,$(1),$(2),$(3),$(4),$(5),$$(call lu-getvalue-index,TARGET,$(1),$(2),$(3),$(4))))) endef define _lu-master-texflavor-index-rules # MASTER FLAVOR TYPE INDEX ext TARGET $(6): \ $$(call lu-getvalue-index,SRC,$(1),$(2),$(3),$(4)) \ $$(wildcard $$(call lu-getvalue-index,STYLE,$(1),$(2),$(3),$(4))) $$(COMMON_PREFIX)$$(call lu-call-prog-index,MAKEINDEX,$(1),$(2),$(3),$(4)) \ $$(addprefix -s ,$$(call lu-getvalue-index,STYLE,$(1),$(2),$(3),$(4))) \ -o $$@ $$< _LU_DEF_IND_$(6)=$(2) clean:: $$(call lu-clean,$$(call lu-getvalue-index,TARGET,$(1),$(2),$(3),$(4)) \ $$(addsuffix .ilg,$$(basename \ $$(call lu-getvalue-index,SRC,$(1),$(2),$(3),$(4))))) endef #################################################### define lu-master-texflavor-index # MASTER FLAVOR INDEX ext(.dvi/.pdf) $$(eval $$(call lu-master-texflavor-index-vars,$(1),$(2),$(3),$(4))) $$(eval $$(call lu-master-texflavor-index-rules,$(1),$(2),$(3),$(4))) endef ########################################################## ########################################################## define lu-master-texflavor-vars # MASTER FLAVOR ext(.dvi/.pdf) $$(call lu-show-rules,Setting flavor vars for $(1)/$(2)) -include $(1)$(3).mk $$(eval $$(call lu-addtovar,DEPENDS,$(1),$(2), \ $$(call lu-getvalues,FIGURES,$(1),$(2)) \ $$(call lu-getvalues,BIBFILES,$(1),$(2)) \ $$(wildcard $$(call lu-getvalues,INPUTS,$(1),$(2))) \ $$(wildcard $$(call lu-getvalues,BIBSTYLES,$(1),$(2))) \ $$(call lu-getvalues,BBLFILES,$(1),$(2))\ )) $$(eval $$(call lu-addtovar-flavor,TARGETS,$(2),$(1)$(3))) $$(eval $$(call lu-addtovar,GPATH,$(1),$(2), \ $$(subst },,$$(subst {,,$$(subst }{, ,\ $$(call lu-getvalue,GRAPHICSPATH,$(1),$(2))))))) $$(if $$(sort $$(call lu-getvalues,SUBFIGS,$(1),$(2))), \ $$(eval include $$(addsuffix .mk,$$(sort \ $$(call lu-getvalues,SUBFIGS,$(1),$(2)))))) $$(eval $$(call lu-addtovar,WATCHFILES,$(1),$(2), \ $$(filter %.aux, $$(call lu-getvalues,OUTPUTS,$(1),$(2))))) $$(foreach type,$$(call lu-getvalues,INDEXES,$(1),$(2)), \ $$(foreach index,$$(call lu-getvalues,INDEXES_$$(type),$(1),$(2)), \ $$(eval $$(call lu-master-texflavor-index-vars,$(1),$(2),$$(type),$$(index),$(3))))) endef #################################################### define lu-master-texflavor-rules # MASTER FLAVOR ext(.dvi/.pdf) $$(call lu-show-rules,Defining flavor rules for $(1)/$(2)) $$(call lu-getvalues,BBLFILES,$(1),$(2)): \ $$(sort $$(call lu-getvalues,BIBFILES,$(1),$(2)) \ $$(wildcard $$(call lu-getvalues,BIBSTYLES,$(1),$(2)))) $(1)$(3): %$(3): \ $$(filter-out $$(call lu-getvalues,DEPENDS_EXCLUDE,$(1),$(2)), \ $$(call lu-getvalues,DEPENDS,$(1),$(2)) \ $$(call lu-getvalues,REQUIRED,$(1),$(2))) \ $$(if $$(wildcard $(1)$(3)_FAILED),LU_FORCE,) \ $$(if $$(wildcard $(1)$(3)_NEED_REBUILD),LU_FORCE,) \ $$(if $$(wildcard $(1)$(3)_NEED_REBUILD_IN_PROGRESS),LU_FORCE,) $$(if $$(filter-out $$(LU_REC_LEVEL),$$(call lu-getvalue,MAX_REC,$(1),$(2))),, \ $$(warning *********************************) \ $$(warning *********************************) \ $$(warning *********************************) \ $$(warning Stopping generation of $$@) \ $$(warning I got max recursion level $$(call lu-getvalue,MAX_REC,$(1),$(2))) \ $$(warning Set LU_$(1)_$(2)_MAX_REC, LU_MAX_REC_$(1) or LU_MAX_REC if you need it) \ $$(warning *********************************) \ $$(warning *********************************) \ $$(warning *********************************) \ $$(error Aborting generation of $$@)) $$(MAKE) LU_REC_MASTER="$(1)" LU_REC_FLAVOR="$(2)" LU_REC_TARGET="$$@"\ LU_WATCH_FILES_SAVE $$(COMMON_PREFIX)$$(call _lu-do-latex\ ,$(1),$(2),$$(call lu-getvalue-master,MAIN,$(1)),$(3)) $$(MAKE) LU_REC_MASTER="$(1)" LU_REC_FLAVOR="$(2)" LU_REC_TARGET="$$@"\ LU_WATCH_FILES_RESTORE $$(MAKE) LU_REC_MASTER="$(1)" LU_REC_FLAVOR="$(2)" LU_REC_TARGET="$$@"\ $(1)$(3)_NEED_REBUILD ifneq ($(LU_REC_TARGET),) $(1)$(3)_NEED_REBUILD_IN_PROGRESS: $$(COMMON_HIDE)touch $(1)$(3)_NEED_REBUILD_IN_PROGRESS $$(addprefix LU_rebuild_,$$(call lu-getvalues,REBUILD_RULES,$(1),$(2))): \ $(1)$(3)_NEED_REBUILD_IN_PROGRESS .PHONY: $(1)$(3)_NEED_REBUILD $(1)$(3)_NEED_REBUILD: \ $(1)$(3)_NEED_REBUILD_IN_PROGRESS \ $$(addprefix LU_rebuild_,$$(call lu-getvalues,REBUILD_RULES,$(1),$(2))) $$(COMMON_HIDE)$(RM) $(1)$(3)_NEED_REBUILD_IN_PROGRESS $$(COMMON_HIDE)if [ -f "$(1)$(3)_NEED_REBUILD" ];then\ echo "********************************************" ;\ echo "*********** New build needed ***************" ;\ echo "********************************************" ;\ cat "$(1)$(3)_NEED_REBUILD" ; \ echo "********************************************" ;\ fi $$(MAKE) LU_REC_LEVEL=$$(shell expr $$(LU_REC_LEVEL) + 1) \ $$(LU_REC_TARGET) endif clean-build-fig:: $$(call lu-clean,$$(foreach fig, \ $$(basename $$(wildcard $$(filter %.fig, \ $$(call lu-getvalues,FIGURES,$(1),$(2))))), \ $$(addprefix $$(fig),$$(call lu-getvalues-flavor,CLEANFIGEXT,$(2))))) $$(call lu-clean,$$(foreach svg, \ $$(basename $$(wildcard $$(filter %.svg, \ $$(call lu-getvalues,FIGURES,$(1),$(2))))), \ $$(addprefix $$(svg),$$(call lu-getvalues-flavor,CLEANSVGEXT,$(2))))) clean:: clean-build-fig $$(call lu-clean,$$(call lu-getvalues,OUTPUTS,$(1),$(2)) \ $$(call lu-getvalues,BBLFILES,$(1),$(2)) \ $$(addsuffix .mk,$$(call lu-getvalues,SUBFIGS,$(1),$(2))) \ $$(patsubst %.bbl,%.blg,$$(call lu-getvalues,BBLFILES,$(1),$(2)))) $$(call lu-clean,$$(wildcard $(1).log)) distclean:: $$(call lu-clean,$$(wildcard $(1)$(3) $(1)$(3)_FAILED \ $(1)$(3)_NEED_REBUILD $(1)$(3)_NEED_REBUILD_IN_PROGRESS)) $$(foreach type,$$(call lu-getvalues,INDEXES,$(1),$(2)), \ $$(foreach index,$$(call lu-getvalues,INDEXES_$$(type),$(1),$(2)), \ $$(eval $$(call lu-master-texflavor-index-rules,$(1),$(2),$$(type),$$(index),$(3))))) endef #################################################### define lu-master-texflavor # MASTER FLAVOR ext(.dvi/.pdf) $$(eval $$(call lu-master-texflavor-vars,$(1),$(2),$(3))) $$(eval $$(call lu-master-texflavor-rules,$(1),$(2),$(3))) endef ########################################################## ########################################################## define lu-master-dviflavor-vars # MASTER FLAVOR ext(.ps) $$(call lu-show-rules,Setting flavor vars for \ $(1)/$(2)/$$(call lu-getvalue-flavor,DEPFLAVOR,$(2))) # $$(eval $$(call lu-addvar,VARPROG,$(1),$(2))) # $$(eval $$(call lu-addvar,$$(call lu-getvalue,VARPROG,$(1),$(2)),$(1),$(2))) $$(eval $$(call lu-addtovar-flavor,TARGETS,$(2),$(1)$(3))) endef #################################################### define lu-master-dviflavor-rules # MASTER FLAVOR ext(.ps) $$(call lu-show-rules,Defining flavor rules for \ $(1)/$(2)/$$(call lu-getvalue-flavor,DEPFLAVOR,$(2))) $(1)$(3): %$(3): %$$(call lu-getvalue-flavor,EXT,$$(call lu-getvalue-flavor,DEPFLAVOR,$(2))) $$(call lu-call-prog-flavor,$(1),$(2)) -o $$@ $$< distclean:: $$(call lu-clean,$$(wildcard $(1)$(3))) endef #################################################### define lu-master-dviflavor # MASTER FLAVOR ext(.ps) $$(eval $$(call lu-master-dviflavor-vars,$(1),$(2),$(3))) $$(eval $$(call lu-master-dviflavor-rules,$(1),$(2),$(3))) endef ########################################################## ########################################################## define lu-master-vars # MASTER $$(call lu-show-rules,Setting vars for $(1)) $$(eval $$(call lu-setvar-master,MAIN,$(1),$(1).tex)) $$(eval $$(call lu-addtovar-master,DEPENDS,$(1),\ $$(call lu-getvalue-master,MAIN,$(1)))) _LU_$(1)_DVI_FLAVORS=$$(filter $$(_LU_FLAVORS_DEFINED_DVI),\ $$(sort $$(call lu-getvalues-master,FLAVORS,$(1)))) _LU_$(1)_TEX_FLAVORS=$$(filter $$(_LU_FLAVORS_DEFINED_TEX),\ $$(sort $$(call lu-getvalues-master,FLAVORS,$(1)) \ $$(LU_REC_FLAVOR) \ $$(foreach dvi,$$(call lu-getvalues-master,FLAVORS,$(1)), \ $$(call lu-getvalue-flavor,DEPFLAVOR,$$(dvi))))) $$(foreach flav,$$(_LU_$(1)_TEX_FLAVORS), $$(eval $$(call \ lu-master-texflavor-vars,$(1),$$(flav),$$(call lu-getvalue-flavor,EXT,$$(flav))))) $$(foreach flav,$$(_LU_$(1)_DVI_FLAVORS), $$(eval $$(call \ lu-master-dviflavor-vars,$(1),$$(flav),$$(call lu-getvalue-flavor,EXT,$$(flav))))) endef #################################################### define lu-master-rules # MASTER $$(call lu-show-rules,Defining rules for $(1)) $$(foreach flav,$$(_LU_$(1)_TEX_FLAVORS), $$(eval $$(call \ lu-master-texflavor-rules,$(1),$$(flav),$$(call lu-getvalue-flavor,EXT,$$(flav))))) $$(foreach flav,$$(_LU_$(1)_DVI_FLAVORS), $$(eval $$(call \ lu-master-dviflavor-rules,$(1),$$(flav),$$(call lu-getvalue-flavor,EXT,$$(flav))))) endef #################################################### define lu-master # MASTER $$(eval $$(call lu-master-vars,$(1))) $$(eval $$(call lu-master-rules,$(1))) endef ########################################################## #$(warning $(call LU_RULES,example)) $(eval $(call lu-addtovar-global,MASTERS,\ $$(shell grep -l '\\documentclass' *.tex 2>/dev/null | sed -e 's/\.tex$$$$//'))) ifneq ($(LU_REC_TARGET),) _LU_DEF_MASTERS = $(LU_REC_MASTER) _LU_DEF_FLAVORS = $(LU_REC_FLAVOR) $(FLAV_DEPFLAVOR_$(LU_REC_FLAVOR)) else _LU_DEF_MASTERS = $(call lu-getvalues-global,MASTERS) _LU_DEF_FLAVORS = $(sort $(foreach master,$(_LU_DEF_MASTERS),\ $(call lu-getvalues-master,FLAVORS,$(master)))) endif $(foreach flav, $(_LU_DEF_FLAVORS), $(eval $(call lu-define-flavor,$(flav)))) $(foreach master, $(_LU_DEF_MASTERS), $(eval $(call lu-master-vars,$(master)))) $(foreach flav, $(_LU_FLAVORS_DEFINED), $(eval $(call lu-flavor-rules,$(flav)))) $(foreach master, $(_LU_DEF_MASTERS), $(eval $(call lu-master-rules,$(master)))) ##################################################################"" # Gestion des subfigs %< $$@' \ -s $*.subfig $*.fig < $^ > $@ %MAKEFILE %< $$@' \ -s $*.subfig $*.svg < $^ > $@ %MAKEFILE clean:: $(call lu-clean,$(FIGS2CREATE_LIST)) $(call lu-clean,$(FIGS2CREATE_LIST:%.fig=%.pstex)) $(call lu-clean,$(FIGS2CREATE_LIST:%.fig=%.pstex_t)) $(call lu-clean,$(FIGS2CREATE_LIST:%.fig=%.$(_LU_PDFTEX_EXT))) $(call lu-clean,$(FIGS2CREATE_LIST:%.fig=%.pdftex_t)) $(call lu-clean,$(FIGS2CREATE_LIST:%.svg=%.pstex)) $(call lu-clean,$(FIGS2CREATE_LIST:%.svg=%.pstex_t)) $(call lu-clean,$(FIGS2CREATE_LIST:%.svg=%.$(_LU_PDFTEX_EXT))) $(call lu-clean,$(FIGS2CREATE_LIST:%.svg=%.pdftex_t)) .PHONY: LU_FORCE clean distclean LU_FORCE: @echo "Previous compilation failed. Rerun needed" #$(warning $(MAKEFILE)) distclean:: clean %< $@ %MAKEFILE ######################################################################### # Les flavors LU_REC_LEVEL ?= 1 ifneq ($(LU_REC_TARGET),) export LU_REC_FLAVOR export LU_REC_MASTER export LU_REC_TARGET export LU_REC_LEVEL LU_REC_LOGFILE=$(LU_REC_MASTER).log LU_REC_GENFILE=$(LU_REC_MASTER)$(call lu-getvalue-flavor,EXT,$(LU_REC_FLAVOR)) lu-rebuild-head=$(info *** Checking rebuild with rule '$(subst LU_rebuild_,,$@)') lu-rebuild-needed=echo $(1) >> "$(LU_REC_GENFILE)_NEED_REBUILD" ; .PHONY: $(addprefix LU_rebuild_,latex texdepends bibtex) LU_rebuild_latex: $(call lu-rebuild-head) $(COMMON_HIDE)if grep -sq 'Rerun to get'\ "$(LU_REC_LOGFILE)" ; then \ $(call lu-rebuild-needed\ ,"$@: new run needed (LaTeX message 'Rerun to get...')") \ fi LU_rebuild_texdepends: $(call lu-rebuild-head) $(COMMON_HIDE)if grep -sq '^Package texdepends Warning: .* Check dependencies again.$$'\ "$(LU_REC_LOGFILE)" ; then \ $(call lu-rebuild-needed,"$@: new depends required") \ fi LU_rebuild_bibtopic: $(call lu-rebuild-head) % % \end{macrocode} % This part is not needed: already checked with the |lu_rebuild_latex| rule % \begin{macrocode} %<*notused> $(COMMON_HIDE)if grep -sq 'Rerun to get indentation of bibitems right'\ "$(LU_REC_LOGFILE)" ; then \ $(call lu-rebuild-needed,"$@: new run needed") \ fi $(COMMON_HIDE)if grep -sq 'Rerun to get cross-references right'\ "$(LU_REC_LOGFILE)" ; then \ $(call lu-rebuild-needed,"$@: new run needed") \ fi % %<*makefile> $(COMMON_HIDE)sed -e '/^Package bibtopic Warning: Please (re)run BibTeX on the file(s):$$/,/^(bibtopic) *and after that rerun LaTeX./{s/^(bibtopic) *\([^ ]*\)$$/\1/p};d' \ "$(LU_REC_LOGFILE)" | while read file ; do \ touch $$file.aux ; \ $(call lu-rebuild-needed,"bibtopic: $$file.bbl outdated") \ done LU_rebuild_bibtopic_undefined_references: $(call lu-rebuild-head) $(COMMON_HIDE)if grep -sq 'There were undefined references'\ "$(MASTER_$(LU_REC_MASTER)).log" ; then \ $(call lu-rebuild-needed,"$@: new run needed") \ fi .PHONY: LU_WATCH_FILES_SAVE LU_WATCH_FILES_RESTORE LU_WATCH_FILES_SAVE: $(COMMON_HIDE)$(foreach file, $(sort \ $(call lu-getvalues,WATCHFILES,$(LU_REC_MASTER),$(LU_REC_FLAVOR))), \ $(call lu-save-file,$(file),$(file).orig);) LU_WATCH_FILES_RESTORE: $(COMMON_HIDE)$(foreach file, $(sort \ $(call lu-getvalues,WATCHFILES,$(LU_REC_MASTER),$(LU_REC_FLAVOR))), \ $(call lu-cmprestaure-file,"$(file)","$(file).orig",\ echo "New $(file) file" >> $(LU_REC_GENFILE)_NEED_REBUILD;\ );) endif %< You must ensure your TEXMFHOME contains this path <==" % % \end{macrocode} % \subsection{figdepth} % % \begin{macrocode} %<*figdepth> #!/usr/bin/env python3 #coding=utf8 """ stdin : the original xfig file stdout : the output xfig file args : all depths we want to keep """ from __future__ import print_function import optparse import os.path import sys def main(): parser = optparse.OptionParser() (options, args) = parser.parse_args() depths_to_keep = set() for arg in args: depths_to_keep.add(arg) comment = '' display = True def show(depth, line): if depth in depths_to_keep: print(comment+line, end='') return True else: return False for line in sys.stdin: if line[0] == '#': comment += line continue if line[0] in "\t ": if display: print(line, end='') else: Fld = line.split(' ', 9999) if not Fld[0] or Fld[0] not in ('1', '2', '3', '4', '5'): print(comment+line, end='') display = True elif Fld[0] == '4': display = show(Fld[3], line) else: display = show(Fld[6], line) comment = '' if __name__ == "__main__": main() % % \end{macrocode} % \subsection{gensubfig} % \begin{macrocode} %<*gensubfig> #!/usr/bin/env python3 #coding=utf8 """ Arguments passes : - fichier image (image.fig ou image.svg) - -s fichier subfig (image.subfig) - -p chemin du script pour generer les sous-images (svgdepth.py ou figdepth.py) Sortie standard : - makefile pour creer les sous-images (au format .fig ou .svg), et pour les supprimer """ from __future__ import print_function from optparse import OptionParser import os.path def main(): parser = OptionParser(usage='usage: %prog [options] svg file', description='Creates a\ Makefile generating subfigures using figdepth.py or svgdepth.py') parser.add_option("-s", "--subfig", dest="subfig", help="subfig file") parser.add_option("-p", "--depth", dest="depth", help="full path of depth script") (options, args) = parser.parse_args() if len(args) < 1: parser.error("incorrect number of arguments") if not options.subfig: parser.error("no subfig file specified") if not options.depth: parser.error("no depth script specified") (root, ext) = os.path.splitext(args[0]) sf_name = options.subfig ds_name = options.depth varname = '%s_FIGS' % root.upper() subfigs = [] for line in open(options.subfig, 'r'): t = line.find('#') # looking for comments if t > -1: line = line[0:t] # remove comments... line = line.strip() #remove blank chars if line == '': continue subfigs.append(line) count = 1 for subfig in subfigs: print("%s_%d%s: %s%s %s" % (root, count, ext, root, ext, sf_name)) print("\t%s %s" % (ds_name, subfig)) print("") count += 1 print("%s := $(foreach n, " % varname, end='') count = 1 for subfig in subfigs: print('%d ' % count, end='') count += 1 print(", %s_$(n)%s)" % (root, ext)) print("FILES_TO_DISTCLEAN += $(%s)" % varname) print("FIGS2CREATE_LIST += $(%s)" % varname) print("$(TEMPORAIRE): $(%s)" % varname) if __name__ == "__main__": main() % % \end{macrocode} % \subsection{svg2dev} % \begin{macrocode} %<*svg2dev> #!/usr/bin/env python3 #coding=utf8 from optparse import OptionParser import shutil import os import subprocess svg2eps = 'inkscape %s -C --export-filename=%s.eps --export-type=eps --export-latex' svg2pdf = 'inkscape %s -C --export-filename=%s.pdf --export-type=pdf --export-latex' def create_image(input_filename, output_filename, mode, ext): subprocess.Popen(mode % (input_filename, output_filename), stdout=subprocess.PIPE, shell=True).communicate()[0] o_ext = output_filename + '.' + ext o = output_filename o_ext_tex = output_filename + '.' + ext + '_tex' o_t = output_filename + '_t' shutil.move(o_ext, o) fin = open(o_ext_tex, 'r') fout = open(o_t, 'w') #\includegraphics[width=\unitlength,page=1]{logo.pdftex} for line in fin: # FIXME: be more conservative in the replacement # (in case '{'+o_ext+'}' appeares somewhere else) out = line.replace('{'+os.path.basename(o_ext)+'}', '{'+os.path.basename(o)+'}') fout.write(out) fin.close() fout.close() os.remove(o_ext_tex) def main(): parser = OptionParser() parser.add_option("-L", "--format", dest="outputFormat", metavar="FORMAT", help="output format", default="spstex") parser.add_option("-p", "--portrait", dest="portrait", help="dummy arg") (options, args) = parser.parse_args() if len(args) != 2: return (input_filename, output_filename) = args fmt = options.outputFormat portrait = options.portrait if fmt == 'eps': create_image(input_filename, output_filename, svg2eps, 'eps') elif fmt == 'spstex' or fmt == 'pstex': create_image(input_filename, output_filename, svg2eps, 'eps') elif fmt == 'spstex_t' or fmt == 'pstex_t': pass elif fmt == 'spdftex' or fmt == 'pdftex': create_image(input_filename, output_filename, svg2pdf, 'pdf') elif fmt == 'spdftex_t' or fmt == 'pdftex_t': pass if __name__ == "__main__": main() % % \end{macrocode} % \subsection{latexfilter} % |latexfilter.py| is a small python program that hides most of the output % of \TeX/\LaTeX{} output. It only display info, warnings, errors % and underfull/overfull hbox/vbox. % \begin{macrocode} %<*latexfilter> #!/usr/bin/env python3 #coding=utf8 """ stdin : the original LaTeX log file stdout : the output filtered log file """ from __future__ import print_function import optparse import os.path import re import sys import io def main(): parser = optparse.OptionParser() (options, args) = parser.parse_args() display = 0 in_display = 0 start_line = '' warnerror_re = re.compile(r"^(LaTeX|Package|Class)( (.*))? (Warning:|Error:)") fullbox_re = re.compile(r"^(Underfull|Overfull) \\[hv]box") accu = '' # PDFLaTeX log file is not really in latin-1 (in T1 more exactly) # but all bytes are corrects in latin-1, so python won't stop # while parsing log. # Without specifying this encoding (ie using default utf-8), we # can get decode errors (UnicodeDecodeError: 'utf-8' codec can't decode byte...) with io.open(sys.stdin.fileno(),'r',encoding='latin-1') as sin: for line in sin: if display > 0: display -= 1 if line[0:4].lower() in ('info', 'warn') or line[0:5].lower() == 'error': display = 0 line_groups = warnerror_re.match(line) if line_groups: start_line = line_groups.group(3) if not start_line: start_line = '' if line_groups.group(2): start_line = "(" + start_line + ")" display = 1 in_display = 1 elif (start_line != '') and (line[0:len(start_line)] == start_line): display = 1 elif line == "\n": in_display = 0 elif line[0:4] == 'Chap': display = 1 elif fullbox_re.match(line): display = 2 if display: print(accu, end="") accu = line elif in_display: print(accu[0:-1], end="") accu = line if __name__ == "__main__": main() % % \end{macrocode} % \subsection{svgdepth} % \begin{macrocode} %<*svgdepth> #!/usr/bin/env python3 #coding=utf8 import sys import xml.parsers.expat layers = [] for arg in sys.argv: layers.append(arg) parser = xml.parsers.expat.ParserCreate() class XmlParser(object): def __init__(self, layers): self.state_stack = [True] self.last_state = True self.layers = layers def XmlDeclHandler(self, version, encoding, standalone): sys.stdout.write("\n" % (version, encoding)) def StartDoctypeDeclHandler(self, doctypeName, systemId, publicId, has_internal_subset): if publicId != None: sys.stdout.write("\n" %\ (doctypeName, publicId, systemId)) else: sys.stdout.write("\n" % (doctypeName, systemId)) def StartElementHandler(self, name, attributes): if name.lower() == 'g': r = self.last_state and ('id' not in attributes or \ attributes['id'] in self.layers) self.last_state = r self.state_stack.append(r) if not self.last_state: return s = "" for k, v in attributes.items(): s += ' %s="%s"' % (k, v) sys.stdout.write("<%s%s>" % (name, s)) def EndElementHandler(self, name): r = self.last_state if name.lower() == 'g': self.state_stack = self.state_stack[0:-1] self.last_state = self.state_stack[-1] if not r: return sys.stdout.write("" % (name)) def CharacterDataHandler(self, data): if not self.last_state: return sys.stdout.write(data) my_parser = XmlParser(layers) parser.XmlDeclHandler = my_parser.XmlDeclHandler parser.StartDoctypeDeclHandler = my_parser.StartDoctypeDeclHandler parser.StartElementHandler = my_parser.StartElementHandler parser.EndElementHandler = my_parser.EndElementHandler parser.CharacterDataHandler = my_parser.CharacterDataHandler for line in sys.stdin: parser.Parse(line, False) parser.Parse('', True) % % \end{macrocode} % \Finale \endinput