Nuovo comando, comandi annidati. (Questo caso: comando e-mail)
Voglio creare un comando di posta elettronica che possa essere utilizzato in questo modo:
\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}
Quello che voglio è che sia facile modificare le e-mail prima \begin{document}e fare riferimento a esse. Voglio qualcosa come i comandi \author{}e \Author.
Risposte
Puoi usare \expandafter\newcommand\csname command\endcsnameper creare un nuovo comando:
\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}
Provare
\makeatletter
\newcommand{\YourEmail}[2]{\@namedef{Email#2}{\href{mailto:#1}{#1}}}
\makeatother
\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}
Nel caso in cui desideri essere in grado di definire e utilizzare gli indirizzi di posta elettronica in tutto il documento, puoi definire un meccanismo analogo al \label- \ref-meccanismo di LaTeX .
In tal caso, è necessario compilare il documento almeno due volte fino a quando gli indirizzi di posta elettronica non vengono ?visualizzati nel file .pdf risultante.
\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}
Ecco expl3un'implementazione. Puoi usare qualsiasi stringa di caratteri come stringa di riferimento e non devi preoccuparti degli spazi dopo le macro.
\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}
L'immagine mostra che il passaggio del mouse mostra il collegamento.