多个假名选项

多个假名选项

我正在寻找类似的东西问题,定义宏来为人们打印假名,但我不确定如何修改它(或者它是否实际上是我所追求的正确方法)。

我希望有一个宏可以识别像 \AnGo

按原样发布时,应该打印假名,因此
\AnGo>> “Edwin Smith”

[sh] 当发出打印简短表格的选项时
\AnGo[sh]>> “Ted”

[real]打印实际姓名的另一种选择...
\AnGo[real]>> “Antonio Gonzales”

这里最好的方法是什么?

答案1

这是一个可能的解决方案:

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn
\NewDocumentCommand{\definepseudonym}{mmmm}
 {% #1 = command, #2 = pseudonym, #3 = short name, #4 = real name
  \NewDocumentCommand{#1}{O{pseudonym}}
   {
    \str_case:nn { ##1 }
     {
      {pseudonym}{#2}
      {sh}{#3}
      {real}{#4}
     }
   }
 }
\ExplSyntaxOff

\definepseudonym{\AnGo}{Edwin Smith}{Ted}{Antonio Gonzalez}

\begin{document}

\AnGo[real] was known as \AnGo\ abbreviated in \AnGo[sh].

\end{document}

在此处输入图片描述

这是一个可扩展的解决方案。除了假名之外,您还可以定义任意数量的属性。

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn

\NewDocumentCommand{\definepseudonym}{mmm}
 {% #1 = command name, #2 = pseudonym, #3 = other names
  \cs_new:cpn { #1 } { \genericpseudonym{#1} }
  \prop_gclear_new:c { g_pseudonym_#1_prop }
  \prop_gset_from_keyval:cn { g_pseudonym_#1_prop } { #3 }
  \prop_gput:cnn { g_pseudonym_#1_prop } { pseudonym } { #2 }
 }
\NewDocumentCommand{\genericpseudonym}{mO{pseudonym}}
 {
  \pseudonym_get:nn { #1 } { #2 }
 }

\cs_new:Nn \pseudonym_get:nn
 {
  \prop_item:cn { g_pseudonym_#1_prop } { #2 }
 }
\ExplSyntaxOff

\definepseudonym{AnGo}{Edwin Smith}{
  sh=Ted,
  real=Antonio Gonzalez,
  birthplace=Somewhere,
}

\begin{document}

\AnGo[real] was known as \AnGo\ abbreviated in \AnGo[sh].
He was born in \AnGo[birthplace].

\end{document}

在此处输入图片描述

答案2

无需附加软件包的方法:

\documentclass[a4paper]{article}
\makeatletter
%%----------------------------------------------------------------------
\newcommand\UD@firstoftwo[2]{#1}%
\newcommand\UD@secondoftwo[2]{#2}%
%%----------------------------------------------------------------------
%% Check whether argument is empty:
%%......................................................................
%% \UD@CheckWhetherNull{<Argument which is to be checked>}%
%%                     {<Tokens to be delivered in case that argument
%%                       which is to be checked is empty>}%
%%                     {<Tokens to be delivered in case that argument
%%                       which is to be checked is not empty>}%
%%   The gist of this macro comes from Robert R. Schneck's \ifempty-macro:
%%   <https://groups.google.com/forum/#!original/comp.text.tex/kuOEIQIrElc/lUg37FmhA74J>
\newcommand\UD@CheckWhetherNull[1]{%
  \romannumeral0\expandafter\UD@secondoftwo\string{\expandafter
  \UD@secondoftwo\expandafter{\expandafter{\string#1}\expandafter
  \UD@secondoftwo\string}\expandafter\UD@firstoftwo\expandafter{\expandafter
  \UD@secondoftwo\string}\expandafter\expandafter\UD@firstoftwo{ }{}%
  \UD@secondoftwo}{\expandafter\expandafter\UD@firstoftwo{ }{}\UD@firstoftwo}%
}%
%%----------------------------------------------------------------------
%% Check whether argument contains no exclamation mark which is not nested 
%% in braces:
%%......................................................................
%% \UD@CheckWhetherNoExclam{<Argument which is to be checked>}%
%%                         {<Tokens to be delivered in case that argument
%%                           contains no exclamation mark>}%
%%                         {<Tokens to be delivered in case that argument
%%                           contains exclamation mark>}%
%%
\newcommand\UD@GobbleToExclam{}\long\def\UD@GobbleToExclam#1!{}%
\newcommand\UD@CheckWhetherNoExclam[1]{%
  \expandafter\UD@CheckWhetherNull\expandafter{\UD@GobbleToExclam#1!}%
}%
%%----------------------------------------------------------------------
%%  \@PseudonymFork grabs the first thing behind a
%%  a token-sequence of pattern  !!pseudonym!sh!real!
%%......................................................................
\newcommand\@PseudonymFork{}
\long\def\@PseudonymFork#1!!pseudonym!sh!real!#2#3!!!!{#2}%
%%----------------------------------------------------------------------
%% \PseudonymFork
%%......................................................................
\newcommand\PseudonymFork[5]{%
  \UD@CheckWhetherNoExclam{#1}{%
    \@PseudonymFork!#1!pseudonym!sh!real!{%
                                           \PseudonymForkError
                                           {No identifier in optional argument}%
                                           {#2}%
                                           \PseudonymFork{#2}{#2}{#3}{#4}{#5}%
                                         }%<-case #1 is empty/has no tokens.
                   !!#1!sh!real!{#3}%<-case #1 = pseudonym.
                   !!pseudonym!#1!real!{#4}%<-case #1 = sh.
                   !!pseudonym!sh!#1!{#5}%<-case #1 = real.
                   !!pseudonym!sh!real!{%
                                         \PseudonymForkError
                                         {Identifier `#1' unknown}%
                                         {#2}%
                                         \PseudonymFork{#2}{#2}{#3}{#4}{#5}%
                                       }%<-case #1 = something else without exclamation-mark.
                   !!!!%
  }{\PseudonymForkError{Identifier `#1' unknown}{#2}\PseudonymFork{#2}{#2}{#3}{#4}{#5}}%<-case #1 = something else with exclamation-mark.
}%
\newcommand\PseudonymForkError[2]{%
  \begingroup
  \def\UD@tempa{#1}%
  \@onelevel@sanitize\UD@tempa
  \@latex@error{%
    \string\PseudonymFork:\MessageBreak
    \UD@tempa\on@line,\MessageBreak
    thus default identifier `#2' used instead%
  }{%
    Either omit the optional argument or specify "sh" or "real"
    or "pseudonym".\MessageBreak
    Specifying "sh" yields the short form.\MessageBreak
    Specifying "real" yields the real name.\MessageBreak
    Specifying "pseudonym" yields the pseudonym.\MessageBreak
    Omitting the optional argument yields the \PseudonymFork{#2}{#2}{pseudonym}{short form}{real name}.%
  }%
  \endgroup
}%
%%----------------------------------------------------------------------
%% \DefinePseudonym{<macro name>}%
%%                 {<default>}%
%%                 {<pseudonym>}%
%%                 {<short form>}%
%%                 {<real name>}%
%%----------------------------------------------------------------------
\DeclareRobustCommand\DefinePseudonym[5]{%
  \@bsphack
  \UD@CheckWhetherNoExclam{#2}{%
     \@PseudonymFork
     !#2!pseudonym!sh!real!{\UD@firstoftwo}%
     !!#2!sh!real!{\UD@secondoftwo}%
     !!pseudonym!#2!real!{\UD@secondoftwo}%
     !!pseudonym!sh!#2!{\UD@secondoftwo}%
     !!pseudonym!sh!real!{\UD@firstoftwo}%
     !!!!%
  }{\UD@firstoftwo}%
  {\DefinePseudonymError{#2}}%
  {\@ifdefinable{#1}{\DeclareRobustCommand#1[1][#2]{\PseudonymFork{##1}{#2}{#3}{#4}{#5}}}}%
  \@esphack
}%
\newcommand\DefinePseudonymError[1]{%
  \begingroup
  \def\UD@tempa{#1}%
  \@onelevel@sanitize\UD@tempa
  \@latex@error{%
    \string\DefinePseudonym:\MessageBreak
    Default-identifier\UD@CheckWhetherNull{#1}{}{ `\UD@tempa'} incorrect\on@line!\MessageBreak
    Use one of the identifiers "pseudonym", "sh" or "real" instead%
  }{%
    Specify either "sh" or "real" or "pseudonym".\MessageBreak
    Specifying "sh" yields that the short form will be the default.\MessageBreak
    Specifying "real" yields that the real name will be the default.\MessageBreak
    Specifying "pseudonym" yields that the pseudonym will be the default.%
  }%
  \endgroup
}%
%%----------------------------------------------------------------------
\makeatother

\begin{document}

\noindent
\verb|\DefinePseudonym{|%
\textit{$\langle$macro name$\rangle$}%
\verb|}{|%
\textit{$\langle$default$\rangle$}%
\verb|}{|%
\textit{$\langle$pseudonym$\rangle$}%
\verb|}{|%
\textit{$\langle$short~form$\rangle$}%
\verb|}{|%
\textit{$\langle$real~name$\rangle$}%
\verb|}|
\bigskip     

\noindent
\verb|\DefinePseudonym{\AnGo}{pseudonym}{Edwin Smith}{Ted}{Antonio Gonzales}|
\DefinePseudonym{\AnGo}{pseudonym}{Edwin Smith}{Ted}{Antonio Gonzales}%

\noindent\hrulefill\null

\noindent
   % Error and default; default is pseudonym:
%\verb|\AnGo[unknown specifier]|: \AnGo[unknown specifier]\\
   % Error and default; default is pseudonym:
%\verb|\AnGo[]|: \AnGo[]\\
   % default; default is pseudonym:
\verb|\AnGo|: \AnGo\\
   % pseudonym:
\verb|\AnGo[pseudonym]|: \AnGo[pseudonym]\\
   % short form:
\verb|\AnGo[sh]|: \AnGo[sh]\\
   % real name:
\verb|\AnGo[real]|: \AnGo[real]

\end{document}

在此处输入图片描述

答案3

稍微变化一下egreg 的回答\definepseudonym允许您在未提供可选参数的情况下在调用默认值时指定:

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn
\NewDocumentCommand{\definepseudonym}{mO{pseudonym}mm}
 {% #1 = command name
  % #2 = default used in case of not providing the optional argument
  % #3 = pseudonym
  % #4 = other names
  \exp_args:Nc{\NewDocumentCommand}{#1}{O{#2}}
   {
    \prop_item:cn { g_pseudonym_#1_prop } { ##1 }
   }
  \prop_gclear_new:c { g_pseudonym_#1_prop }
  \prop_gset_from_keyval:cn { g_pseudonym_#1_prop } { #4 }
  \prop_gput:cnn { g_pseudonym_#1_prop } { pseudonym } { #3 }
 }
\ExplSyntaxOff

\definepseudonym{AnGo}[pseudonym]{Edwin Smith}{
  sh=Ted,
  real=Antonio Gonzalez,
  birthplace=Somewhere,
}

\begin{document}

\AnGo[real] was known as \AnGo[pseudonym] abbreviated in \AnGo[sh].
He was born in \AnGo[birthplace].

Applying \verb|\AnGo| without optional argument yields the pseudonym: \AnGo

This is because within \verb|\definepseudonym|'s second argument, which is 
optional, "pseudonym" was specified as the default which is to be used when
not providing an optional argument.

If instead of "pseudonym", e.g., "real" was specified here, then
\verb|\AnGo| without optional argument would yield the real
name/the value of the "real"-property.

\end{document}

另一种变体是,“假名”属性不与其他属性/其他名称分开处理:

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn
\NewDocumentCommand{\definepseudonym}{mO{pseudonym}m}
 {% #1 = command name
  % #2 = default used in case of not providing the optional argument
  % #3 = property-value-list
  \exp_args:Nc{\NewDocumentCommand}{#1}{O{#2}}
   {
    \prop_item:cn { g_pseudonym_#1_prop } { ##1 }
   }
  \prop_gclear_new:c { g_pseudonym_#1_prop }
  \prop_gset_from_keyval:cn { g_pseudonym_#1_prop } { #3 }
 }
\ExplSyntaxOff

\definepseudonym{AnGo}[pseudonym]{
  pseudonym=Edwin Smith,
  sh=Ted,
  real=Antonio Gonzalez,
  birthplace=Somewhere,
}

\begin{document}

\AnGo[real] was known as \AnGo[pseudonym] abbreviated in \AnGo[sh].
He was born in \AnGo[birthplace].

Applying \verb|\AnGo| without optional argument yields the pseudonym: \AnGo

This is because within \verb|\definepseudonym|'s second argument, which is 
optional, "pseudonym" was specified as the default which is to be used when
not providing an optional argument.

If instead of "pseudonym", e.g., "real" was specified here, then
\verb|\AnGo| without optional argument would yield the real
name/the value of the "real"-property.

\end{document}

另一种变化是让您为假名宏的可选参数指定一个全局默认值,在调用时可以通过在第二个参数\definepseudonym中指定默认属性来覆盖该默认值:\definepseudonym

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn
\cs_generate_variant:Nn \prop_item:Nn {cx}
\tl_new:N {\jan_GlobalPseudonymDefault}
\tl_gset:Nn {\jan_GlobalPseudonymDefault} {pseudonym}
\NewDocumentCommand{\SetGlobalPseudonymDefault}{m}{\tl_gset:Nn {\jan_GlobalPseudonymDefault} {#1}}
\NewDocumentCommand{\definepseudonym}{mm}
 {% #1 = command name
  % #2 = property-value-list
  \exp_args:Nc{\NewDocumentCommand}{#1}{O{default}}
   {
    \prop_item:cn { g_pseudonym_#1_prop } { ##1 }
   }
  \prop_gclear_new:c { g_pseudonym_#1_prop }
  \prop_gset_from_keyval:cn { g_pseudonym_#1_prop } { #2 }
  \prop_if_in:cnTF{ g_pseudonym_#1_prop }{ default }{}{%
   \prop_gput:cnV { g_pseudonym_#1_prop } { default } { \jan_GlobalPseudonymDefault }
  }
  \prop_gput:cnx { g_pseudonym_#1_prop } { default }
  { \prop_item:cx { g_pseudonym_#1_prop } { \prop_item:cn { g_pseudonym_#1_prop } { default } } }
 }
\ExplSyntaxOff

% The global default is initialized to "peseudonym" but we change it
% to the real name:
\SetGlobalPseudonymDefault{real}

\definepseudonym{AnGo}{
  pseudonym=Edwin Smith,
  sh=Ted,
  real=Antonio Gonzalez,
  birthplace=Somewhere,
  % Override the global default:
  %default=sh,
  default=pseudonym,
}

\begin{document}

\AnGo[real] was known as \AnGo[pseudonym] abbreviated in \AnGo[sh].
He was born in \AnGo[birthplace].

Applying \verb|\AnGo| without optional argument yields the pseudonym: \AnGo

This is because within \verb|\definepseudonym|'s second argument, pseudonym
was specified as the value of the default-property.

If the default-property would not have been specified here, it would have
got the value stored in \verb|\jan_GlobalPseudonymDefault|, which in turn
can be changed globally via \verb|\SetGlobalPseudonymDefault|.

\end{document}

相关内容