Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

My question probably has to do with .aux files and \newlabel therein. Here is what I can describe.

  • The way my .PDF builds is via a Makefile; I inserted an MWE to show what happens.

  • The situation is that I need do avoid issuing \label commands for user's \items in a \begin{enumerate} environment whenever they give "multiply defined" warnings, e.g.:

  • when \label{itm:i} is for the first \item - using \roman (representation of counter enumi) - as well as for the ninth - using \alph; and

  • I employ the use of all five (\alph, \Alph, \roman, \Roman, \arabic) for each \item: this TeXnique happens [recursively,] iteratively, automatically.

  • (My problem is with infinite passes through make: I explain how.)

  • I use the pairs \ifcsname r@#1\endcsname in some \newcommandx that generates \labels - or \@ifundefined{r@#1}{}{} -, where #1 would be the label.

The MWE is the following.

\documentclass[10pt]{article}

\usepackage{paralist,alphalph,xargs}

\def\alph#1{\alphalph{\value{#1}}}
\def\Alph#1{\AlphAlph{\value{#1}}}

\makeatletter

\newcommandx\mwelabel[3][2=itm,3=r@]{%
\@ifundefined{#3#2:#1}{\label{#2:#1}}{%
\typeout{avoided #2:#1}}}

\newcommandx\MweLabel[3][2=itm,3=r@]{%
\ifcsname#3#2:#1\endcsname%
\typeout{skipped #2:#1}\else%
\label{#2:#1}\fi}

\makeatother

\begin{document}

\section{MWE}\mwelabel{one}[sec]

TEXT

\subsection{Mwe} \MweLabel{one}[sec]

Text

\section{Mwe} \MweLabel{two}[sec]

See subsection \ref{sec:one}.

\begin{enumerate}[(a)]
\setcounter{enumi}{24}
\item twenty-five \mwelabel{tst:one}
\item twenty-six \mwelabel{tst:two}
\item twenty-seven
\end{enumerate}

text

\begin{enumerate}[(A)]
\setcounter{enumi}{29}
\item thirty \MweLabel{tst:one}
\item thirty-one \MweLabel{tst:two}
\item thirty-two
\end{enumerate}

See items \ref{itm:tst:one} and \ref{itm:tst:two}.

\end{document}

\endinput

avoided sec:one
skipped sec:one
skipped sec:two
avoided itm:tst:one
avoided itm:tst:two
skipped itm:tst:one
skipped itm:tst:two

When I run the command line "pdflatex mwe.tex ; pdflatex mwe.tex", after the second pass it typeouts what is after \endinput.

  • When I run pdflatex through, instead, the command line "make clobber clean && make", the process goes into an infinite loop.

The Makefile is the following.

# A Makefile for building TeX documents
#

DOC = mwe
TARGETS = $(DOC).pdf
#QUIET = >/dev/null

##  commondefs  ###############################################################
#

-include commondefs
#

MDIRT = *~ core *.stamp _*.* tmp.inputs
LDIRT = *.aux* *.log*
DIRT = $(MDIRT) $(LDIRT)
RM = rm -f

.SUFFIXES: .tex .aux .stamp .pdf

SEP=:
#SEP=\;         # for MikTeX+Cygwin
PDFLATEX = TEXINPUTS=.$(SEP) pdflatex $(QUIET) -shell-escape #-halt-on-error

##  Makefile  #################################################################
#
###############################################################################

.DEFAULT: all
.PHONY: all
.SECONDARY: $(filter-out $(TARGETS), $(DOC).pdf)

all: $(TARGETS)

FDIRT = mwe.pdf

TEXS = *.tex
DEPS = $(DOC).stamp

$(DOC).pdf: $(TEXS) $(DEPS)

#
###############################################################################


##  commonrules  ##############################################################
#

-include commonrules

# Some basic recursive rules for building, installing, and cleaning up
# a source tree
#
subdirs:
    @sub="$(SUBDIRS)"; \
    for i in $$sub; do if test -n "$$i"; then \
          (cd $$i; make); \
    fi; done;

clean: localclean
    @sub="$(SUBDIRS)"; \
    for i in $$sub; do if test -n "$$i"; then \
          (cd $$i; make $@); \
    fi; done;

localclean:
    $(RM) $(DIRT)

clobber: localclean
    @sub="$(SUBDIRS)"; \
    for i in $$sub; do if test -n "$$i"; then \
          (cd $$i; make $@); \
    fi; done;
    $(RM) $(TARGETS)
    $(RM) -r auto


# Rules for TeX files
#
# The line that runs LATEX needs to run inside a subshell to turn off
# "make"'s status checking. It blows away .aux because the .aux file
# created is bad and also breaks biblatex. It touches .stamp to force a
# rebuild.
.tex.pdf:
    @if test -r "$*.aux"; \
       then cp $*.aux $*.auxprev; \
       else echo > $*.auxprev; \
    fi
    @echo "$(PDFLATEX) $<"
    @sh -c "$(PDFLATEX) $< || (rm -f $*.aux; sleep 1; touch $*.stamp; exit 1)"
    @-cmp -s $*.aux $*.auxprev; \
    if test $$? = 1; \
    then \
        #diff -urN $*.aux $*.auxprev; \
        sleep 1; \
        echo "==> Rebuilding $@"; \
        touch $*.stamp; \
        $(MAKE) $@; \
    else \
        echo "==> No need to rebuild $@"; \
    fi
    @rm -f $*.auxprev

.tex.stamp: # backward compatibility
    touch $@
  • I tried defining separate commands associated with each \label using some unused prefix instead of r@, i.e., mwe@. With make there are no longer infinite passes. However, this does not work either, since in both cases there are multiply defined warnings from LaTeX, that obviously should not be, because the \label is to be guarded by \@ifundefined or \ifcsname\endcsname.

The modified MWE is the following (identical, except 3=mwe@ instead of 3=r@).

\documentclass[10pt]{article}

\usepackage{paralist,alphalph,xargs}

\def\alph#1{\alphalph{\value{#1}}}
\def\Alph#1{\AlphAlph{\value{#1}}}

\makeatletter

\newcommandx\mwelabel[3][2=itm,3=mwe@]{%
\@ifundefined{#3#2:#1}{\@namedef{#3#2:#1}{}\label{#2:#1}}{%
\typeout{avoided #2:#1}}}

\newcommandx\MweLabel[3][2=itm,3=mwe@]{%
\ifcsname#3#2:#1\endcsname%
\typeout{skipped #2:#1}\else%
\@namedef{#3#2:#1}{}\label{#2:#1}\fi}

\makeatother

\begin{document}

\section{MWE}\mwelabel{one}[sec]

TEXT

\subsection{Mwe} \MweLabel{one}[sec]

Text

\section{Mwe} \MweLabel{two}[sec]

See subsection \ref{sec:one}.

\begin{enumerate}[(a)]
\setcounter{enumi}{24}
\item twenty-five \mwelabel{tst:one}
\item twenty-six \mwelabel{tst:two}
\item twenty-seven
\end{enumerate}

text

\begin{enumerate}[(A)]
\setcounter{enumi}{29}
\item thirty \MweLabel{tst:one}
\item thirty-one \MweLabel{tst:two}
\item thirty-two
\end{enumerate}

See items \ref{itm:tst:one} and \ref{itm:tst:two}.

\end{document}

\endinput

skipped sec:one

How can I really guard reissuing \label commands? The "enumerate-item-alph...arabic" context could probably be ignored. I have thus also inserted test cases for \labeling \sections.

Appreciate all help. Thank s.

  • Makefile uses tabs in rules! I have put a diff command in the ".tex.pdf" suffix rule, between the mwe.aux and mwe.auxprev files, whose comparison (the cmp command) seems to be the criterion to rerun $(MAKE). The output of diff is always the same, only switching between minus and plus on the same lines.

Either:

--- mwe.aux 2013-05-30 16:46:01.080584663 +0300
+++ mwe.auxprev 2013-05-30 16:46:00.920586664 +0300
@@ -1,4 +1,10 @@
 \relax 
 \@writefile{toc}{\contentsline {section}{\numberline {1}MWE}{1}}
+\newlabel{sec:one}{{1}{1}}
 \@writefile{toc}{\contentsline {subsection}{\numberline {1.1}Mwe}{1}}
 \@writefile{toc}{\contentsline {section}{\numberline {2}Mwe}{1}}
+\newlabel{sec:two}{{2}{1}}
+\newlabel{itm:tst:one}{{y}{1}}
+\newlabel{itm:tst:two}{{z}{1}}
+\newlabel{itm:tst:one}{{AD}{1}}
+\newlabel{itm:tst:two}{{AE}{1}}

or:

--- mwe.aux 2013-05-30 16:46:01.595578225 +0300
+++ mwe.auxprev 2013-05-30 16:46:01.439580175 +0300
@@ -1,10 +1,4 @@
 \relax 
 \@writefile{toc}{\contentsline {section}{\numberline {1}MWE}{1}}
-\newlabel{sec:one}{{1}{1}}
 \@writefile{toc}{\contentsline {subsection}{\numberline {1.1}Mwe}{1}}
 \@writefile{toc}{\contentsline {section}{\numberline {2}Mwe}{1}}
-\newlabel{sec:two}{{2}{1}}
-\newlabel{itm:tst:one}{{y}{1}}
-\newlabel{itm:tst:two}{{z}{1}}
-\newlabel{itm:tst:one}{{AD}{1}}
-\newlabel{itm:tst:two}{{AE}{1}}
share|improve this question
add comment

2 Answers 2

You can guard reissuing the same command. But you should not use the internal behaviour of \label as all labels of the last run are defined at \begin{document} when your .aux file is read.

\makeatletter

\newcommandx\mwelabel[3][2=itm,3=myr@]{%
  \@ifundefined{#3#2:#1}{%
    \label{#2:#1}%
    \expandafter\def\csname #3#2:#1\endcsname{something}%
  }{%
    \typeout{avoided #2:#1}%
  }%
}

\newcommandx\MweLabel[3][2=itm,3=r@]{%
  \ifcsname#3#2:#1\endcsname%
    \typeout{skipped #2:#1}%
  \else%
    \label{#2:#1}%
    \expandafter\def\csname #3#2:#1\endcsname{something}%
  \fi
}

\makeatother
share|improve this answer
    
Welcome to TeX.SX! –  mafp May 30 '13 at 14:51
    
Welcome to Tex.SX! Thanks for your answer, especially reminding me about ".aux only preamble" thing. It seems your reply is just my second MWE, and it would thus be wrong. –  sjbiaga Jun 2 '13 at 18:54
add comment

Following the \newlabel track, I could really do the correct thing. I redefined \@newl@bel#1#2#3 so that it splits labels like itm:tst:one into itm and tst:one (or else resorts to the original LaTeX definition), tests for itm (not to be, e.g., sec) and then cancels invocation of the original LaTeX definition in cases when my automated mechanism (confused by \[aA]lph/[rR]oman thing) led to multiply defined LaTeX warnings; or otherwise resorts again to the original LaTeX definition. Thanks again for your suggestions.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.