买者自负...

买者自负...

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​​​​​​sortwcprintfechogetoptfindxargs在所有合理正常的类 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条目需要该条目,而直到该条目进入词汇表时它才会执行该操作。fruitappleapple

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}

这仅需要pdflatexmakeglossariespdflatex即可产生:

文件图像

这会将交叉引用放入位置列表中,这可能不是您想要的,但.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}

相关内容