新的命令,嵌套的命令。(本例:电子邮件命令)

新的命令,嵌套的命令。(本例:电子邮件命令)

我想创建一个可以像这样使用的电子邮件命令:

\documentclass{article}
\usepackage[utf8]{inputenc}
\usepackage{hyperref}
\newcommand{\YourEmail}[2]{\newcommand{\Email#2}{\href{mailto:#1}{#1}}}

\YourEmail{[email protected]}{I}
\YourEmail{[email protected]}{II}

\begin{document}
Lots of text. But here I link to \EmailI. Here comes \EmailII.
\end{document}

我希望能够轻松地编辑之前的电子邮件\begin{document},然后引用它们。我想要类似\author{}\Author命令的东西。

答案1

您可以使用以下\expandafter\newcommand\csname command\endcsname命令创建一个新命令:

\documentclass{article}
\usepackage[utf8]{inputenc}
\usepackage{hyperref}
\newcommand\YourEmail[2]{%
  \expandafter\newcommand\csname Email#2\endcsname{%
    \href{mailto:#1}{#1}%
  }%
}

\YourEmail{[email protected]}{I}
\YourEmail{[email protected]}{II}

\begin{document}
Lots of text. But here I link to \EmailI. Here comes \EmailII.
\end{document}

在此处输入图片描述

答案2

尝试

\makeatletter
\newcommand{\YourEmail}[2]{\@namedef{Email#2}{\href{mailto:#1}{#1}}}
\makeatother

答案3

\documentclass{article}
\usepackage[utf8]{inputenc}
\usepackage{hyperref}
\usepackage{xparse}

%----------------------------------------------------------------------
% \CsNameToCsToken<stuff not in curly braces>{Token}
% ->
% <stuff not in curly braces>\Token
% 
% Examples:
%
% \CsNameToCsToken\newcommand*{foobar}... -> \newcommand*\foobar...
% \CsNameToCsToken{foobar} -> \foobar
% \CsNameToCsToken\show{foobar} -> \show\foobar
% \CsNameToCsToken\string{foobar} -> \string\foobar
% \CsNameToCsToken\global\long\def{foobar} -> \global\long\def\foobar
% \CsNameToCsToken\CsNameToCsToken\global\let{foo}={bar}
%   -> \CsNameToCsToken\global\let\foo={bar}
%   -> \global\let\foo=\bar
%......................................................................
\newcommand\exchangeargs[2]{#2#1}
\newcommand\innerCsNameToCsToken[2]{%
  \expandafter\exchangeargs\expandafter{\csname#2\endcsname}{ #1}%
}%
\csname @ifdefinable\endcsname\CsNameToCsToken{%
  \long\def\CsNameToCsToken#1#{\romannumeral0\innerCsNameToCsToken{#1}}%
}%
%----------------------------------------------------------------------

\makeatletter
\NewDocumentCommand{\StoreEmail}{vm}{%
  \@bsphack
  \CsNameToCsToken\newcommand*{Email#2}[0]{\href{mailto:#1}{#1}}%
  %\CsNameToCsToken\CsNameToCsToken\global\let{Email#2}={Email#2}%
  \@esphack
}
\makeatother
\newcommand{\RetrieveEmail}[1]{\CsNameToCsToken{Email#1}}

\StoreEmail{[email protected]}{I}
\StoreEmail{[email protected]}{II}
\StoreEmail{[email protected]}{1}
\StoreEmail{[email protected]}{2}
\StoreEmail{[email protected]}{!foobar!}


\begin{document}

Here I link to \RetrieveEmail{I}.

Here comes \RetrieveEmail{II}.

This is \RetrieveEmail{1}.

There is also \RetrieveEmail{2}.

And one more: \RetrieveEmail{!foobar!}.

\smallskip\hrule\smallskip

Here I link to \csname EmailI\endcsname.

Here comes \csname EmailII\endcsname.

This is \csname Email1\endcsname.

There is also \csname Email2\endcsname.

And one more: \csname Email!foobar!\endcsname.

\smallskip\hrule\smallskip

Here I link to \EmailI. 

Here comes \EmailII.

\end{document}

在此处输入图片描述


如果您希望能够在整个文档中定义和使用电子邮件地址,您可以定义一个类似于 LaTeX 的\label机制\ref

如果这样做,则需要至少编译两次文档,直到电子邮件地址?出现在生成的 .pdf 文件中。

\NeedsTeXFormat{LaTeX2e}[2018/12/01]
\documentclass{article}
\usepackage[utf8]{inputenc}
\usepackage{hyperref}
\usepackage{xparse}

%----------------------------------------------------------------------
% \CsNameToCsToken<stuff not in curly braces>{Token}
% ->
% <stuff not in curly braces>\Token
% 
% Examples:
%
% \CsNameToCsToken\newcommand*{foobar}... -> \newcommand*\foobar...
% \CsNameToCsToken{foobar} -> \foobar
% \CsNameToCsToken\show{foobar} -> \show\foobar
% \CsNameToCsToken\string{foobar} -> \string\foobar
% \CsNameToCsToken\global\long\def{foobar} -> \global\long\def\foobar
% \CsNameToCsToken\CsNameToCsToken\global\let{foo}={bar}
%   -> \CsNameToCsToken\global\let\foo={bar}
%   -> \global\let\foo=\bar
%......................................................................
\newcommand\exchangeargs[2]{#2#1}
\newcommand\innerCsNameToCsToken[2]{%
  \expandafter\exchangeargs\expandafter{\csname#2\endcsname}{ #1}%
}%
\csname @ifdefinable\endcsname\CsNameToCsToken{%
  \long\def\CsNameToCsToken#1#{\romannumeral0\innerCsNameToCsToken{#1}}%
}%
%----------------------------------------------------------------------
\makeatletter
\NewDocumentCommand{\StoreEmail}{vm}{%
  \@bsphack
  \protected@write\@auxout{}{\string\EMAILLABEL{#2}{#1}}%
  \@esphack
}%
\NewDocumentCommand{\EMAILLABEL}{mv}{%
  \@new@email@l@bel{Email}{#1}{\href{mailto:#2}{#2}}%
}%
\newcommand*\Emailchangedmessage{}%
\AtVeryEndDocument{\Emailchangedmessage}%
\newcommand\@new@email@l@bel[3]{%
  \ifx\@newl@bel\@testdef\expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi
  {%
    \def\reserved@a{#3}%
    \CsNameToCsToken\ifx{#1@#2}\reserved@a\else
      \gdef\Emailchangedmessage{%
        \@latex@warning@no@line {E-Mail-Addresses may have changed. Rerun to get E-Mail-Addresses right}%
      }%
    \fi
  }{%
    {%
      \@ifundefined{#1@#2}\relax{%
        \gdef\@multiplelabels{%
          \@latex@warning@no@line{There were multiply-defined E-Mail-Addresses}%
        }%
        \@latex@warning@no@line{E-Mail-Addresses `#2' multiply defined}%
      }%
      \CsNameToCsToken\gdef{#1@#2}{#3}%
    }%
  }%
}%
\newcommand\@Emailundefined{}%
\newcommand\G@Emailundefinedtrue{%
  \gdef\@Emailundefined{\@latex@warning@no@line {There were undefined E-Mail-Addresses}}%
}%
\AtEndDocument{\@Emailundefined}%
\NewDocumentCommand{\RetrieveEmail}{m}{%
  \CsNameToCsToken\ifx{Email@#1}\relax
      \protect\G@Emailundefinedtrue
      \nfss@text{\reset@font\bfseries ??}%
      \@latex@warning {E-Mail-Address `#1' on page \thepage \space undefined}%
  \else
    \CsNameToCsToken{Email@#1}\null 
  \fi
}%
\makeatother

\begin{document}

Here I link to \RetrieveEmail{I}.

Here comes \RetrieveEmail{II}.

This is \RetrieveEmail{1}.

There is also \RetrieveEmail{2}.

And one more: \RetrieveEmail{!foobar!}.

\StoreEmail{[email protected]}{I}
\StoreEmail{[email protected]}{II}
\StoreEmail{[email protected]}{1}
\StoreEmail{[email protected]}{2}
\StoreEmail{[email protected]}{!foobar!}

\end{document}

在此处输入图片描述

答案4

这是一个expl3实现。您可以使用任何字符串作为参考字符串,而不必担心宏后的空格。

\documentclass{article}
%\usepackage{xparse} % not necessary for LaTeX 2020-10-01 or later
\usepackage{hyperref}

\ExplSyntaxOn

\prop_new:N \g_vebjorn_email_prop

\NewDocumentCommand{\NewEmail}{mm}
 {% #1 = reference string, #2 = email address
  \prop_gput:Nnn \g_vebjorn_email_prop { #1 } { #2 }
 }
\NewDocumentCommand{\Email}{m}
 {% #1 = reference string
  \exp_args:Ne \href
   {mailto\c_colon_str\prop_item:Nn \g_vebjorn_email_prop { #1 } }
   {\prop_item:Nn \g_vebjorn_email_prop { #1 } }
 }

\ExplSyntaxOff

\NewEmail{1}{[email protected]}
\NewEmail{dude}{[email protected]}

\begin{document}

Lots of text. But here I link to \Email{1}. Here comes \Email{dude}.

\end{document}

在此处输入图片描述

图片演示了鼠标悬停时显示链接。

相关内容