使用 \index{name@name and surname} 生成姓名索引

使用 \index{name@name and surname} 生成姓名索引

我正在尝试生成一本书中使用的人名索引。

首次出现时,会使用人物的全名(即名字和姓氏以及可能的附加说明)来介绍该人物,之后在文中只会使用该人的姓名。

我打算使用老旧的 makeindex 来生成索引,因为不需要其他索引。因此我编写了宏,一个用于人的初次出现,一个用于以后的所有出现。初次出现宏使用姓名和姓氏作为强制参数,第二个宏仅使用姓名作为强制参数。

\index我认为,通过-command 使用@类似这样的方式写入姓名会很聪明\index{#2@#2}(假设,人员姓名始终存储在 #2 中,其姓氏存储在 #3 中)。因此,对于初始外观,索引将如下所示:

\index{#2@#2, #3}

这是进一步露面的呼吁:

\index{#2}

不幸的是,Makeindex 不会将它们识别为唯一名称。即使我将第二个宏更改为使用 also @

\index{#2@#2}

将显示为同名的第二个条目。

哪里出了问题?我必须改变什么?

以下是 MWE:

\documentclass[a4paper]{scrartcl}
\usepackage[main=english]{babel}
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage{makeidx}
\usepackage{ifthen}


%% Definition of macros
%% Initpers is used, when the person is first mentioned.  It takes 4
%% arguments:
%%   #1: Output in the text (optional)
%%   #2: Name (mandatory)
%%   #3: Surname (mandatory)
%%   #4: Description (mandatory but most of the time empty)
%% 
\newcommand{\initpers}[4][]{%
  % output the name and surname into the text.  If the optional
  % argument #1 is given, use this, else use the mandatory arguments
  % #2 and #3
  \ifthenelse{\equal{#1}{}}{
    {#3 #2}}{%
    #1}%
  % Now, insert Name, Surname and the Description (if given) into the index.
  \ifthenelse{\equal{#4}{}}{%
    \index{#2@#2, #3}}{%
    \index{#2@#2, #3 (#4)}}%
}%
%% This macro shall be used, whenever a person, which was already
%% introduced, shall be mentioned again.  In this case, only the name
%% is used.  
\newcommand{\pers}[1]{%
  % output the name into the text, enter it into the index.
  % #1\index{#1}
  #1\index{#1@#1}%
}%

% generate the index
\makeindex
\begin{document}
This is some text, in which I will reflect on the book ``The two
cultures'' by \initpers{Snow}{Charles Percy}{}.  This book \dots

%% For the sake of this example, lets assume, we mention Mr. Snow
%% later on
\newpage
This was also mentioned by \pers{Snow} as described earlier.

\printindex

\end{document}

这是令人遗憾的结果,因为尽管这是一个人并且应该列为斯诺,查尔斯·珀西,1,2,但它却包含了斯诺先生的两个条目:

在此处输入图片描述

答案1

我的解决方案将名称和潜在描述存储到expl3属性列表中,并处理索引格式。如果没有描述,则提取普通格式,否则在\index- 调用中添加描述。

这样,就Index被“压缩”了。

我还曾经\NewDocumentCommand在 的末尾提供一个可选参数\InitPerson

\displayname\descriptionformat\nodescriptionformat只是为了防止吞噬\ExplSyntaxOn...\ExplSyntaxOff制度中的空白的包装器。

\documentclass[a4paper]{scrartcl}
\usepackage[main=english]{babel}
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage{makeidx}

\usepackage{ifthen}

\usepackage{xparse}




%% Definition of macros
%% Initpers is used, when the person is first mentioned.  It takes 4
%% arguments:
%%   #1: Output in the text (optional)
%%   #2: Name (mandatory)
%%   #3: Surname (mandatory)
%%   #4: Description (mandatory but most of the time empty)
%% 
\newcommand{\initpersold}[4][]{%
  % output the name and surname into the text.  If the optional
  % argument #1 is given, use this, else use the mandatory arguments
  % #2 and #3
  \ifthenelse{\equal{#1}{}}{
    {#3 #2}}{%
    #1}%
  % Now, insert Name, Surname and the Description (if given) into the index.
  \ifthenelse{\equal{#4}{}}{%
    \index{#2@#2, #3}}{%
    \index{#2@#2, #3 (#4)}}%
}%
%% This macro shall be used, whenever a person, which was already
%% introduced, shall be mentioned again.  In this case, only the name
%% is used.  
\newcommand{\persold}[1]{%
  % output the name into the text, enter it into the index.
  % #1\index{#1}
  #1\index{#1@#1}%
}%

\newcommand{\displayname}[2]{%
  #1 #2%
}



\newcommand{\descriptionformat}[3]{%
  #1, #2 (#3)%
}

\newcommand{\nodescriptionformat}[2]{%
  #1, #2%
}

\ExplSyntaxOn

\newcommand{\propextractname}[1]{%
  \prop_item:Nn \g_jan_person_prop {#1}%
}

\newcommand{\propextractdescription}[1]{%
   \displayname{\prop_item:Nn \g_jan_person_prop {#1}}{(\prop_item:Nn \g_jan_person_prop {#1-description})}%
}


\prop_new:N \g_jan_person_prop
\seq_new:N \g_jan_personused_seq

\NewDocumentCommand{\InitPerson}{o+m+m+o}{%
  \IfNoValueTF{#1}{%
    \displayname{#3}{#2}%
  }{%
    #1%
  }%
  \IfValueTF{#4}{%
    \prop_gput:Nnn \g_jan_person_prop {#2-description} {#4}
    \index{\descriptionformat{#2}{#3}{#4}} 
  }{
    \index{\nodescriptionformat{#2}{#3}}
  }
  \prop_gput:Nnn \g_jan_person_prop {#2} {#3}
}

\NewDocumentCommand{\Person}{+m}{%
  #1%
  \prop_if_in:NnTF \g_jan_person_prop {#1} 
  {
    \prop_if_in:NnTF \g_jan_person_prop {#1-description}  
    {
      \typeout{Yes: #1}
      \index{#1,~\propextractdescription{#1}}
    }{
      \index{#1,~\propextractname{#1}}
    }
  }{
    \index{#1}
  }
}

\ExplSyntaxOff

\makeindex
\begin{document}

This is some text, in which I will reflect on the book ``The two
cultures'' by \InitPerson{Snow}{Charles Percy}.  This book \dots

\InitPerson{Vader}{Darth}[Father of Luke Skywalker]


%% For the sake of this example, lets assume, we mention Mr. Snow
%% later on
\clearpage
This was also mentioned by \Person{Snow} as described earlier.

The arch villain \Person{Vader}

\clearpage 
\Person{Snow} 

\printindex

\end{document}

在此处输入图片描述

答案2

之前的部分@仅用于排序,但\index{a@aa}\index{a@aabb}不同的項目。

Christian Hupfer 提出的代码可以简化。您也许应该重新考虑将第一个可选参数提供给时会发生什么\initpers

\documentclass[a4paper]{scrartcl}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage[main=english]{babel}

\usepackage{makeidx} % or imakeidx
\usepackage{xparse}

\ExplSyntaxOn
%% Definition of macros
%% Initpers is used, when the person is first mentioned.  It takes 4
%% arguments:
%%   #1: Output in the text (optional)
%%   #2: Family name (mandatory)
%%   #3: Given name (mandatory)
%%   #4: Description (optional)
%% 
\NewDocumentCommand{\initpers}{ommo}
 {
  % output the name and surname into the text.  If the optional
  % argument #1 is given, use this, else use the mandatory arguments
  % #2 and #3
  \IfNoValueTF { #1 }
   {
    % no optional argument, print given name and family name
    #3~#2
   }
   {
    % optional argument, print just it
    #1
   }
  % store the data
  \prop_gput:Nnn \g_jan_persons_prop { #2 familyname } { #2 } 
  \prop_gput:Nnn \g_jan_persons_prop { #2 givenname } { #3 } 
  \IfValueT { #4 }
   {
    \prop_gput:Nnn \g_jan_persons_prop { #2 description } { #4 }
   }
  \index{#2@\usename{#2}}
 }

\NewDocumentCommand{\pers}{m}
 {
  % output the name into the text, enter it into the index.
  % #1\index{#1}
  #1\index{#1@\usename{#1}}
 }

\NewDocumentCommand{\usename}{m}
 {
  \prop_item:Nn \g_jan_persons_prop { #1 familyname }
  ,\c_space_tl
  \prop_item:Nn \g_jan_persons_prop { #1 givenname }
  \prop_if_in:NnTF \g_jan_persons_prop { #1 description }
   {
    \c_space_tl (\prop_item:Nn \g_jan_persons_prop { #1 description })
   }
 }
\prop_new:N \g_jan_persons_prop

\ExplSyntaxOff
% generate the index
\makeindex

\begin{document}
This is some text, in which I will reflect on the book ``The two
cultures'' by \initpers{Snow}{Charles Percy}.  This book \dots

We also talk about \initpers{Vader}{Darth}[Father of Luke Skywalker]
and \initpers[Stendhal]{Beyle}{Henri}

%% For the sake of this example, lets assume, we mention Mr. Snow
%% later on
\clearpage
This was also mentioned by \pers{Snow} as described earlier

And we also have \pers{Vader} and \pers{Beyle}.

\printindex

\end{document}

在此处输入图片描述

相关内容