我最后一个问题涉及建立人员登记册使用 \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-extra
with 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}
结果如下:
上部外壳被应用到 上,"
这会破坏它,所以你最终得到的"Arrow
不是 Ärrow。替代方法是:
\initpers[Arrow]{{"A}rrow}{Kenneth}{}