![使用 Makefile 测试定义的标签 (r@) 和无限次传递](https://linux22.com/image/269378/%E4%BD%BF%E7%94%A8%20Makefile%20%E6%B5%8B%E8%AF%95%E5%AE%9A%E4%B9%89%E7%9A%84%E6%A0%87%E7%AD%BE%20(r%40)%20%E5%92%8C%E6%97%A0%E9%99%90%E6%AC%A1%E4%BC%A0%E9%80%92.png)
.aux
我的问题可能与文件及其相关\newlabel
。以下是我可以描述的。
我的 .PDF 构建方式是通过 Makefile;我插入了 MWE 来显示发生了什么。
情况是,每当用户给出“ ”警告时,我都需要避免在环境中
\label
为用户发出命令,例如:\item
\begin{enumerate}
multiply defined
何时
\label{itm:i}
是第一次\item
使用\roman
(计数器的表示enumi
) - 以及第九次使用\alph
;并且我对每个都使用了所有五个(,,,,,):这种独特
\alph
情况会[递归地]迭代地自动发生。\Alph
\roman
\Roman
\arabic
\item
TeX
(我的问题是无限次通过
make
:我解释一下如何。)\ifcsname r@#1\endcsname
我使用一些\newcommandx
生成\label
s - 或\@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”上下文可能被忽略。因此,我还插入了\label
ing的测试用例\section
。
感谢大家的帮助。谢谢。
Makefile
在规则中使用制表符!我已经放了一个diff
命令中的“.tex.pdf
”后缀规则,在mwe.aux
和mwe.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:one
为itm
和tst:one
(否则诉诸原始LaTeX
定义),测试itm
(不是,例如sec
),然后在我的自动机制(被事物混淆)导致警告LaTeX
的情况下取消对原始定义的调用;否则再次诉诸原始定义。再次感谢您的建议。\[aA]lph/[rR]oman
multiply defined
LaTeX
LaTeX