glossaries
支持交叉引用条目。特别是,如果我在另一个词汇表中使用一个条目,而只在文档中明确包含第二个条目,glossaries
仍然可以确定它应该包含词汇表中的第一个条目。
但是,这需要运行 2 次makeglossaries
:
- 编译 ->
makeglossaries
-> 编译 ->makeglossaries
-> 编译
否则列表中将会缺少第一个条目。
到目前为止,这并不是特别成问题:只需记住运行makeglossaries
两次,并在其间重新编译。
但是,如果第一个交叉引用条目本身交叉引用了第三个条目,事情就会变得复杂。现在应该包括第三个条目,但makeglossaries
需要额外运行一次。此外,如果第三个条目交叉引用了第四个条目,则还需要再运行一次。对于任何第五个、第六个...条目也是如此。
例如:
\begin{filecontents}{mygloss.tex}
\newglossaryentry{animal}{%
name = animal,
description = {A living organism. Cf.~\gls{plant}}}
\newglossaryentry{apple}{%
name = apple,
description = {A type of \gls{fruit}}}
\newglossaryentry{fruit}{%
name = fruit,
description = {A method of seed-dispersal favoured by some \glspl{plant}}}
\newglossaryentry{plant}{%
name = plant,
description = {A living organism. Cf.~\gls{animal}}}
\end{filecontents}
\documentclass{article}
\usepackage{glossaries}
\makeglossaries
\loadglsentries{mygloss}
\begin{document}
An \gls{apple} a day keeps the doctor away.
\printglossaries
\end{document}
不幸的是,glossaries
当使用未包含在词汇表中的条目时,不会提供任何警告。例如,它不会告诉我fruit
在第一个编译周期之后对的引用未定义。它只是默默地包含fruit
在定义中,apple
而不在词汇表中包含定义fruit
。
对于使用复杂条目数据库的复杂文档来说,跟踪这一点变得相当困难。
如何才能最轻松、最可靠地确定何时需要额外的编译周期?
我想知道的一个可能性是创建一个 shell 脚本来比较以下命令的结果:
grep glossentry <filename>.glo | wc -l
grep glossentry <filename>.gls | wc -l
grep
并得出结论:当且仅当两个结果相等时,无需进一步运行。
但是,我不确定这是否通常可靠,尤其是涉及多个.glo
和.gls
文件时。我也不清楚是否有更简便的方法来确定是否需要另一次运行。
答案1
这实际上不是一个答案,但它实际上不属于问题的一部分,并且对于评论来说太长了。
我编写了一个 shell 脚本,即使条目内有多个嵌套的交叉引用,它也会尝试生成词汇表。这是高度实验性的。它只在一个最小示例上进行了测试。它将会崩溃。如果您可以建议改进方法(无需用另一种语言重写脚本),请发表评论。
买者自负...
按照目前的写法,该脚本做出以下假设:
TeX Live 二进制文件可在 中找到
/usr/local/texlive/bin/
。在我的系统之外的其他系统上,这种情况不太可能发生。sed
,,,,,,,,,grep
等都可以。uniq
sort
wc
printf
echo
getopt
find
xargs
在所有合理正常的类 Unix 系统上都应该是正确的。bash
可用作/bin/bash
。在所有合理正常的类 Unix 系统上都应该是正确的。文件名是合理的,不包含任何奇怪、奇怪或有问题的字符。在所有具有合理理智用户的系统上都应该是正确的。
要使用该脚本,如果您确实希望这样做,您需要将其保存为文件,<super-makeglossaries>
然后使其可执行:
chmod +x super-makeglossaries
保存脚本~/bin/
或在使用时提供脚本的完整路径。
语法非常简单。只有 2 个选项:
-h
或--help
提供最低限度的帮助;-o
或者--options
如果你想要将选项传递给pdflatex
。通常,你会希望引用这些。
例如:
super-makeglossaries -o "--synctex=1" <filename>
理论上应该继续运行,直到pdflatex --synctex=1
所有词汇表条目都稳定下来。“理论上”的意思是“根据我目前的希望”,而不是“根据我制定的理论”。makeglossaries
<filename>
<filename>.tex
不要使用我之前发布的版本。它甚至对我都不起作用。它对其他人来说,工作的可能性微乎其微。这是当前的代码,至少可能对我有用:
#!/bin/bash -
#set -x
PATH=/usr/local/texlive/bin:/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin
export PATH
allan=0
options=""
pdflatex=/usr/local/texlive/bin/pdflatex
makeglossaries=/usr/local/texlive/bin/makeglossaries
usage="Usage: $0 [OPTION] FILE
makeglossaries wrapper which will run pdflatex and makeglossaries until cross-referenced entries are stable.
Options:
-h --help print this message and exit
-o --options options to be passed to pdflatex
FILE should be a TeX file, specified with or without the .tex extension."
error () {
echo "$@" 1>&2
((allan++))
usage_and_exit $allan
}
usage () {
printf %b "$usage\n"
}
usage_and_exit () {
usage
exit $1
}
tex_error () {
echo "$@" 1>&2
((allan++))
exit $allan
}
find_gen () {
find $(dirname "$1") -maxdepth 1 -type f -readable -name "$(basename $1).*.$2"
find $(dirname "$1") -maxdepth 1 -type f -readable -name "$(basename $1).$2"
}
gen_exists () {
n=1
k=$(find_gen "$1" "$2" | wc -l)
[[ $k -ne 0 ]] && n=0
return $n
}
[[ -x $pdflatex ]] || error Ni allaf ffeindio "$pdflatex".
[[ -x $makeglossaries ]] || error Ni allaf ffeindio "$makeglossaries".
tempargs=$(getopt -o ho: --long help,options: -- "$@")
if [ $? != 0 ];
then
usage_and_exit
fi
eval set -- "$tempargs"
while true
do
case "$1"
in
-h | --help)
usage;
exit $allan;;
-o | --opt | --opti | --optn | --option | --options)
options="$2"
shift;
shift;;
--)
shift;
break;;
*)
error Unrecognised option "$1".
esac
done
args="$@"
[[ "$#" != 1 ]] && error Mae angen o leiaf un enw ffeil ac nid mwy nag un!
enw=${1%.tex}
gen_exists "$enw" glo
if [ $? != 0 ]
then
printf %b "Running pdfLaTeX, $makeglossaries and pdfLaTeX to create glossary.\n"
$pdflatex $options $enw || tex_error pdfLaTeX exited with errors.
$makeglossaries $enw || tex_error $makeglossaries exited with errors.
$pdflatex $options $enw || tex_error pdfLaTeX exited with errors.
else
gen_exists "$enw" gls
if [ $? != 0 ]
then
printf %b "Running $makeglossaries and pdfLaTeX to create glossary.\n"
$makeglossaries $enw || tex_error $makeglossaries exited with errors.
$pdflatex $options $enw || tex_error pdfLaTeX exited with errors.
fi
fi
$(gen_exists "$enw" glo) || error Ni allaf ffeindio .glo!
$(gen_exists "$enw" gls) || error Ni allaf ffeindio .gls!
gloentries=$(find_gen "$enw" glo | xargs grep glossentry | sed 's/|setentrycounter.*$//' | sort | uniq | wc -l)
glsentries=$(find_gen "$enw" gls | xargs grep glossentry | wc -l)
while [ ! "$gloentries" == "$glsentries" ]
do
printf %b "Rerunning $makeglossaries and pdfLaTeX to resolve cross-references.\n"
$makeglossaries $enw || tex_error $makeglossaries exited with errors.
$pdflatex $options $enw || tex_error pdfLaTeX exited with errors.
gloentries=$(find_gen "$enw" glo | xargs grep glossentry | sed 's/|setentrycounter.*$//' | sort | uniq | wc -l)
glsentries=$(find_gen "$enw" gls | xargs grep glossentry | wc -l)
done
exit $allan
# vim: set nospell:
答案2
实际上不可能为glossaries
所有这些嵌套的依赖级别提供警告,但hyperref
如果某个条目已被使用但未出现在词汇表中,则添加会发出警告。
例子:
\documentclass{article}
\usepackage[hidelinks]{hyperref}
\usepackage{glossaries}
\makeglossaries
\newglossaryentry{animal}{%
name = animal,
description = {A living organism. Cf.~\gls{plant}}}
\newglossaryentry{apple}{%
name = apple,
description = {A type of \gls{fruit}}}
\newglossaryentry{fruit}{%
name = fruit,
description = {A method of seed-dispersal favoured by some
\glspl{plant}}}
\newglossaryentry{plant}{%
name = plant,
description = {A living organism. Cf.~\gls{animal}}}
\begin{document}
An \gls{apple} a day keeps the doctor away.
\printglossaries
\end{document}
第一次pdflatex
运行时,pdfTeX 会产生以下警告:
pdfTeX warning (dest): name{glo:apple} has been referenced but does not exist,
replaced by a fixed one
这是因为hyperref
插入了内部超链接,但目标不存在。此时,只有apple
被使用。其他条目(包括fruit
)尚未使用。fruit
直到创建词汇表后,才会使用该条目。然后 pdfTeX 会发出警告
pdfTeX warning (dest): name{glo:fruit} has been referenced but does
not exist, replaced by a fixed one
这对嵌套依赖关系没有帮助。这里的问题是,它直到处理条目描述时才glossaries
知道该apple
条目需要该条目,而直到该条目进入词汇表时它才会执行该操作。fruit
apple
apple
glossaries-extra
扩展包的包提供glossaries
了解决此类问题的方法,但仅当依赖项由键指示时才有效see
。例如:
% arara: pdflatex
% arara: makeglossaries
% arara: pdflatex
\documentclass{article}
\usepackage{glossaries-extra}
\makeglossaries
\newglossaryentry{animal}{%
name = animal,
description = {A living organism},
see=[cf.]{plant}}
\newglossaryentry{apple}{%
name = apple,
description = {A type of \gls{fruit}},
see={fruit}}
\newglossaryentry{fruit}{%
name = fruit,
description = {A method of seed-dispersal favoured by some
\glspl{plant}},
see={plant}}
\newglossaryentry{plant}{%
name = plant,
description = {A living organism},
see=[cf.]{animal}}
\begin{document}
An \gls{apple} a day keeps the doctor away.
\printglossaries
\end{document}
这仅需要pdflatex
,makeglossaries
和pdflatex
即可产生:
这会将交叉引用放入位置列表中,这可能不是您想要的,但.gls
如果需要,它确实使文件更容易使用脚本进行后期处理。.gls
此示例的文件包含:
\glossarysection[\glossarytoctitle]{\glossarytitle}\glossarypreamble
\begin{theglossary}\glossaryheader
\glsgroupheading{A}\relax \glsresetentrylist %
\glossentry{animal}{\glossaryentrynumbers{\relax
\setentrycounter[]{page}\glsxtrunusedformat{1}\delimN
\glsseeformat[cf.]{plant}{Z}}}%
\glossentry{apple}{\glossaryentrynumbers{\relax
\setentrycounter[]{page}\glsnumberformat{1}\delimN
\glsseeformat[\seename ]{fruit}{Z}}}\glsgroupskip
\glsgroupheading{F}\relax \glsresetentrylist %
\glossentry{fruit}{\glossaryentrynumbers{\relax
\setentrycounter[]{page}\glsxtrunusedformat{1}\delimN
\glsseeformat[\seename ]{plant}{Z}}}\glsgroupskip
\glsgroupheading{P}\relax \glsresetentrylist %
\glossentry{plant}{\glossaryentrynumbers{\relax
\setentrycounter[]{page}\glsxtrunusedformat{1}\delimN
\glsseeformat[cf.]{animal}{Z}}}%
\end{theglossary}\glossarypostamble
因此,位置列表中的每个交叉引用都采用以下形式\\delimN\\s*\\n\\s+\\glsseeformat\[.+?\]\{.+?\}{Z}