使用 Makefile 测试定义的标签 (r@) 和无限次传递

使用 Makefile 测试定义的标签 (r@) 和无限次传递

.aux我的问题可能与文件及其相关\newlabel。以下是我可以描述的。

  • 我的 .PDF 构建方式是通过 Makefile;我插入了 MWE 来显示发生了什么。

  • 情况是,每当用户给出“ ”警告时,我都需要避免在环境中\label为用户发出命令,例如:\item\begin{enumerate}multiply defined

  • 何时\label{itm:i}是第一次\item使用\roman(计数器的表示enumi) - 以及第九次使用\alph;并且

  • 我对每个都使用了所有五个(,,,,,):这种独特\alph情况会[递归地]迭代地自动发生。\Alph\roman\Roman\arabic\itemTeX

  • (我的问题是无限次通过make:我解释一下如何。)

  • \ifcsname r@#1\endcsname我使用一些\newcommandx 生成\labels - 或\@ifundefined{r@#1}{}{}-的对,其中#1是标签。

MWE 如下。

\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

当我运行命令行“ pdflatex mwe.tex ; pdflatex mwe.tex”时,第二遍之后它typeout就是之后的样子\endinput

  • 当我运行pdflatex命令行“ make clobber clean && make”时,该过程陷入无限循环。

如下Makefile

# 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 $@
  • \label我尝试使用一些未使用的前缀而不是来定义与每个命令相关联的单独命令r@,即mwe@。 有了make,就不再有无限的传递了。然而,这也行不通,因为在这两种情况下都有 的multiply defined警告LaTeX,这显然不应该,因为 需要由或\label来保护。\@ifundefined\ifcsname\endcsname

修改后的 MWE 如下(完全相同,除了3=mwe@而不是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

我如何才能真正保护重新发出的\label命令?“enumerate-item-alpha...arabic”上下文可能被忽略。因此,我还插入了\labeling的测试用例\section

感谢大家的帮助。谢谢。

  • Makefile在规则中使用制表符!我已经放了一个diff命令中的“ .tex.pdf”后缀规则,在mwe.auxmwe.auxprev文件之间,其比较(cmp命令)似乎是重新运行的标准$(MAKE). 输出diff总是相同的,仅在相同的行上在减号和加号之间切换。

任何一个:

--- 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}}

或者:

--- 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}}

答案1

您可以保护重新发出相同的命令。但您不应该使用的内部行为,\label因为上次运行的所有标签都是在\begin{document}读取 .aux 文件时定义的。

\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

答案2

沿着这\newlabel条路,我可以真的做正确的事情。我重新定义了\@newl@bel#1#2#3它,以便将标签拆分itm:tst:oneitmtst:one(否则诉诸原始LaTeX定义),测试itm(不是,例如sec),然后在我的自动机制(被事物混淆)导致警告LaTeX的情况下取消对原始定义的调用;否则再次诉诸原始定义。再次感谢您的建议。\[aA]lph/[rR]omanmultiply defined LaTeXLaTeX

相关内容