Nouvelle commande, commandes imbriquées. (Ce cas: commande e-mail)

Oct 22 2020

Je veux créer une commande Email qui peut être utilisée comme ceci:

\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}

Ce que je veux, c'est qu'il soit facile de modifier les e-mails avant \begin{document}et de simplement les référencer. Je veux quelque chose comme les commandes \author{}et \Author.

Réponses

3 DG' Oct 22 2020 at 04:17

Vous pouvez utiliser \expandafter\newcommand\csname command\endcsnamepour créer une nouvelle commande:

\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}

3 DonHosek Oct 22 2020 at 04:05

Essayer

\makeatletter
\newcommand{\YourEmail}[2]{\@namedef{Email#2}{\href{mailto:#1}{#1}}}
\makeatother
2 UlrichDiez Oct 22 2020 at 05:05
\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}


Si vous souhaitez être en mesure de définir et d' utiliser E-Mail-adresses à travers l'ensemble du document, vous pouvez définir un mécanisme analogue à de LATEX \label- \ref-Mécanisme.

Si vous faites cela, vous devez compiler le document au moins deux fois jusqu'à ce que les adresses e-mail ?n'apparaissent pas dans le fichier .pdf résultant.

\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}

1 egreg Oct 22 2020 at 05:00

Voici une expl3implémentation. Vous pouvez utiliser n'importe quelle chaîne de caractères comme chaîne de référence et ne pas avoir à vous soucier des espaces après les macros.

\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'image montre que le survol montre le lien.