人员登记词汇表存在的问题

人员登记词汇表存在的问题

我最后一个问题涉及建立人员登记册使用 \index{name@name and surname} 生成姓名索引

Christian 评论说,使用Glossaries。我读了它并得到了一个概念验证。然后我尝试将 POC 编码到宏中。宏可以工作,但不幸的是,使用我的宏插入的每个词汇表条目都会得到 listet 作为符号,使用最后插入的人的名字。

“手动”插入名称可以按预期进行。


编辑


我看不出手动插入和宏代码的区别。请帮帮我。

Nicola Talbot 指出,这个问题可能与作为词汇表条目内容的动态变量,确实如此。上述问题的答案解决了我的问题的一部分,因为现在人名被插入到了词汇表中(而不是只对所有条目使用姓氏)。

由于我只会收集名字,所以我不期望收集任何脆弱的表达。因此,我决定(出于简单的原因)通常关闭后期扩展并添加

\glsexpandfields

致我的 MWE。

不幸的是,所有自动收集的条目仍然位于符号下方,我仍然不知道为什么。我认为这与上面链接的问题有显著的不同,因此没有重复。

梅威瑟:

\documentclass[12pt]{article}
\usepackage[ngerman]{babel}
\usepackage[T1]{fontenc}


\RequirePackage[final]{hyperref} % should be last package
\RequirePackage[nopostdot]{glossaries} % This is one of the seldom
                                % exceptions. 

\makeatletter

%%% Any time, you call the persons name again, you can use the
%%% glossary command.
%%%
%%% Arguments
%%%   #1: Lastname (mandatory)

%%%
%%% The book shall contain a list of all persons, which were
%%% mentioned.  The register should be sorted alphabetically, which in
%%% turn requires Makeindex or Xindy.  As I haven't used Xindy before,
%%% I will stay with Makeindex.  Both programms have difficulties, to
%%% sort names, which contain special characters as is the case for
%%% Henrie Poincaré.  Therefore, we must have a fool proof sorting
%%% entry.  Glossries relies on the fact, that an entry for the
%%% register is defined, before it is used.  Therefore, we can use the
%%% \initpers command, whenever a persons name is used for the first
%%% time.  Any following usage can be done with the normal \pers
%%% command. 
%%%
%%% Create the glossaries files.
\makeglossaries 

%% UPDATED!!!    
%% Protected fields like name have to be expanded before usage.
%% c.f. http://ctan.space-pro.be/tex-archive/macros/latex/contrib/glossaries/glossaries-user.html#sec:expansion
\glsexpandfields

%%% \initpers is the command, which is used, whenever a person is
%%% named in the document for the first time.  It will a) define the
%%% glossary entry, b) insert an entry into the register and finally
%%% c) will print the name into the text.  Makeindex/Glossaries does
%%% need the following arguments in a key=<value> manner:
%%%   1) label (uniqe identifier, used also for sorting purposes)
%%%      must be ASCII only, may be identical to 2)
%%%   2) name (may be identical to the label), will be inserted into
%%%      the document, may contain LaTeX specials and non ASCII
%%%      characters. 
%%%   3) description, i.e. the text, which should be printed into the
%%%      register.  The description can contain further information,
%%%      which wasn't in the document before.  IN our case, this will
%%%      be the surname and any further information
%%%      4) sorting key (if not given by the label) 
%%% Whenever a new name is introduced, its full name has to be
%%% inserted, but on the other hand, in some cases, only the last name
%%% has to be inserted into the document itself.  Therefore, we must
%%%
%%% NEW:
%%%   #1: Label (optional, only used, when Lastname contains non ASCII
%%%       characters) 
%%%   #2: Lastname (mandatory
%%%   #3: Surname (mandatory)
%%%   #4: Additional Info (mandatory but may be empty)

\newcommand{\pers}[1]{%
  \Gls{#1}}%
\newcommand{\initpers}[4][\@nil]{%
  %% Reset the internal variables
  \def\dntpers@label{}%
  \def\dntpers@name{}%
  %% Check, if the optional argument is in use and is the arguments
  %% accordingly.
  \def\@tmp{#1}%
  \ifx\@tmp\@nnil
    \def\dntpers@label{#2}%
  \else
    % use the optional argument as label, ...
    \def\dntpers@label{#1}%
  \fi
  \def\dntpers@name{#2}%
  %% Define the Glossar entry
  \newglossaryentry{\dntpers@label}{%
    name=\dntpers@name,
    % sort=\dntpers@label,
    description={#3 #4}}%
  %% Print the name
  #3 \gls{\dntpers@label}%
}%

\newcommand{\personenregister}{%
  \glossarystyle{listgroup}
  \printglossary[title=Personenregister]
}

\makeatother

\begin{document}

\newglossaryentry{Works}{
  name=Works,
  sort=Works,
  description={I have no idea, where the fuking difference comes
    from!}}
\gls{Works}

\initpers{Arrow}{Kenneth}{},
\initpers{Arthur}{Brian}{},
\initpers{Casti}{John}{},
\initpers{Gell-Mann}{Murray}{},
\initpers{Holland}{John}{},
\initpers[Help]{Kauffmann}{Stuart}{},
\initpers{Foo}{Bar}{Baz}

\personenregister

\end{document}% 

结果在此处输入图片描述


编辑


这是添加上述代码行后的输出\glsexpandfields。现在缺少姓氏。

在此处输入图片描述

答案1

我认为有两个问题。第一个是扩展问题(在作为词汇表条目内容的动态变量) 但我认为另一个问题可能是当您修改文档时,下一次运行 LaTeX 会从临时.glsdefs文件中获取旧定义。当在环境中定义条目document以允许在文档开头列出词汇表时,会创建此文件。

由于文档末尾有列表,因此最好使用glossaries-extrawith docdef=restricted,但你必须删除.glsdefs文件否则,您将继续在文档开头输入过时的信息。

这是一个用于确保扩展的修改版本\protected@edef(我已将过时的版本更改\glossarystyle为较新的版本\setglossarystyle):

\documentclass[12pt]{article}
\usepackage[ngerman]{babel}
\usepackage[T1]{fontenc}

\RequirePackage[final]{hyperref}
\RequirePackage[docdef=restricted]{glossaries-extra} 

\makeglossaries 

\makeatletter

\newcommand{\pers}[1]{%
  \Gls{#1}}%
\newcommand{\initpers}[4][\@nil]{%
  %% Reset the internal variables
  \def\dntpers@label{}%
  \def\dntpers@name{}%
  %% Check, if the optional argument is in use and is the arguments
  %% accordingly.
  \def\@tmp{#1}%
  \ifx\@tmp\@nnil
    \def\dntpers@label{#2}%
  \else
    % use the optional argument as label, ...
    \def\dntpers@label{#1}%
  \fi
  \def\dntpers@name{#2}%
  %% Define the Glossar entry
  \protected@edef\@dodef{\noexpand\newglossaryentry{\dntpers@label}{%
    name=\dntpers@name,
    % sort=\dntpers@label,
    description={#3 #4}}}%
  \@dodef
  %% Print the name
  #3 \gls{\dntpers@label}%
}%

\newcommand{\personenregister}{%
  \setglossarystyle{listgroup}%
  \printglossary[title=Personenregister]
}

\makeatother

\begin{document}
\initpers{Arrow}{Kenneth}{},
\initpers{Arthur}{Brian}{},
\initpers{Casti}{John}{},
\initpers{Gell-Mann}{Murray}{},
\initpers{Holland}{John}{},
\initpers[Help]{Kauffmann}{Stuart}{},
\initpers{Foo}{Bar}{Baz}

\personenregister

\end{document}

文件图像

如果您想在姓氏后面加逗号,该glossaries-extra包提供了一个方便的钩子,用于在字段后面附加材料name(在名称上使用的封装格式命令内):

\newcommand{\glsxtrpostnamegeneral}{,}

在列表显示之前这可以发生在任何地方。

笔记:由于您已经使用过,\usepackage[ngerman]{babel}请注意这会使快捷方式处于"活动状态。不幸的是,这是一个特殊字符makeindex,需要转义。该glossaries包尝试在内部转义所有索引特殊字符,但只有当它们具有正常含义时才能这样做。当条目在序言中定义时,这不会导致问题,因为babel直到环境启动时才会激活快捷方式document,但如果它们恰好包含任何这些字符,则会导致文档中定义的条目出现问题。

这意味着您需要小心,如果您的任何名称包含变音符号,即使您正在使用,inputenc因为扩展会将这些字符转换为其内部表示。

\initpers对使用的稍加修改的版本\expandonce仅执行一级扩展,\dntpers@name可以防止 UTF-8 字符被扩展:

\newcommand{\initpers}[4][\@nil]{%
  %% Reset the internal variables
  \def\dntpers@label{}%
  \def\dntpers@name{}%
  %% Check, if the optional argument is in use and is the arguments
  %% accordingly.
  \def\@tmp{#1}%
  \ifx\@tmp\@nnil
    \def\dntpers@label{#2}%
  \else
    % use the optional argument as label, ...
    \def\dntpers@label{#1}%
  \fi
  \def\dntpers@name{#2}%
  %% Define the Glossar entry
  \protected@edef\@dodef{\noexpand\newglossaryentry{\dntpers@label}{%
    name=\expandonce\dntpers@name,
    description={#3 #4}}}%
  \@dodef
  %% Print the name
  #3 \gls{\dntpers@label}%
}%

但是,由于makeindex不支持 UTF-8,我猜您要么使用标签作为排序值,要么使用"makeindex开关-g

这是第一种情况(UTF-8 支持并按标签排序):

\documentclass[12pt]{article}
\usepackage[ngerman]{babel}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}

\RequirePackage[final]{hyperref}
\RequirePackage[docdef=restricted]{glossaries-extra} 

\makeglossaries 

\makeatletter

\newcommand{\pers}[1]{%
  \Gls{#1}}%
\newcommand{\initpers}[4][\@nil]{%
  %% Reset the internal variables
  \def\dntpers@label{}%
  \def\dntpers@name{}%
  %% Check, if the optional argument is in use and is the arguments
  %% accordingly.
  \def\@tmp{#1}%
  \ifx\@tmp\@nnil
    \def\dntpers@label{#2}%
  \else
    % use the optional argument as label, ...
    \def\dntpers@label{#1}%
  \fi
  \def\dntpers@name{#2}%
  %% Define the Glossar entry
  \protected@edef\@dodef{\noexpand\newglossaryentry{\dntpers@label}{%
    name=\expandonce\dntpers@name,
    sort=\expandonce\dntpers@label,
    description={#3 #4}}}%
  \@dodef
  %% Print the name
  #3 \gls{\dntpers@label}%
}%

\newcommand{\glsxtrpostnamegeneral}{,}

\newcommand{\personenregister}{%
  \setglossarystyle{listgroup}%
  \printglossary[title=Personenregister]
}

\makeatother

\begin{document}
\initpers[Arrow]{Ärrow}{Kenneth}{},
\initpers{Arthur}{Brian}{},
\initpers{Casti}{John}{},
\initpers{Gell-Mann}{Murray}{},
\initpers{Holland}{John}{},
\initpers[Help]{Kauffmann}{Stuart}{},
\initpers{Foo}{Bar}{Baz}

\personenregister

\end{document}

文件图像

这是第二种情况。它用于将 的转义字符从\GlsSetQuote更改为(可能在您的文档中尚未激活)。makeindex"+

\documentclass[12pt]{article}
\usepackage[ngerman]{babel}
\usepackage[T1]{fontenc}

\RequirePackage[final]{hyperref}
\RequirePackage[docdef=restricted]{glossaries-extra} 

\GlsSetQuote{+}

\makeglossaries 

\makeatletter

\newcommand{\pers}[1]{%
  \Gls{#1}}%
\newcommand{\initpers}[4][\@nil]{%
  %% Reset the internal variables
  \def\dntpers@label{}%
  \def\dntpers@name{}%
  %% Check, if the optional argument is in use and is the arguments
  %% accordingly.
  \def\@tmp{#1}%
  \ifx\@tmp\@nnil
    \def\dntpers@label{#2}%
  \else
    % use the optional argument as label, ...
    \def\dntpers@label{#1}%
  \fi
  \def\dntpers@name{#2}%
  %% Define the Glossar entry
  \protected@edef\@dodef{\noexpand\newglossaryentry{\dntpers@label}{%
    name=\expandonce\dntpers@name,
    description={#3 #4}}}%
  \@dodef
  %% Print the name
  #3 \gls{\dntpers@label}%
}%

\newcommand{\glsxtrpostnamegeneral}{,}

\newcommand{\personenregister}{%
  \setglossarystyle{listgroup}%
  \printglossary[title=Personenregister]
}

\makeatother

\begin{document}
\initpers[Arrow]{"Arrow}{Kenneth}{},
\initpers{Arthur}{Brian}{},
\initpers{Casti}{John}{},
\initpers{Gell-Mann}{Murray}{},
\initpers{Holland}{John}{},
\initpers[Help]{Kauffmann}{Stuart}{},
\initpers{Foo}{Bar}{Baz}

\personenregister

\end{document}

(结果与前面的例子相同。)

请注意,makeindex需要使用 来运行-g,它makeglossaries会自动执行。

最后,如果你选择最后一种方法,我建议你改为\Gls如果\gls你所有的名字都以大写字母开头。如果\pers{Arrow}将以下内容添加到示例中,问题就会出现:

\begin{document}
\initpers[Arrow]{"Arrow}{Kenneth}{},
\initpers{Arthur}{Brian}{},
\initpers{Casti}{John}{},
\initpers{Gell-Mann}{Murray}{},
\initpers{Holland}{John}{},
\initpers[Help]{Kauffmann}{Stuart}{},
\initpers{Foo}{Bar}{Baz}

\pers{Arrow}

\personenregister

\end{document}

结果如下:

肯尼斯·阿罗、布赖恩·阿瑟、约翰·卡斯蒂、默里·盖尔曼、约翰·霍兰德、斯图尔特·考夫曼、Bar Foo“Arrow

上部外壳被应用到 上,"这会破坏它,所以你最终得到的"Arrow不是 Ärrow。替代方法是:

\initpers[Arrow]{{"A}rrow}{Kenneth}{}

相关内容