¿Cómo extender una macro para que las direcciones de correo electrónico admitan múltiples argumentos?

¿Cómo extender una macro para que las direcciones de correo electrónico admitan múltiples argumentos?

Preparé las siguientes macros para formatear direcciones de correo electrónico en un encabezado de correo electrónico.

\usepackage{xifthen}% Provides \ifthenelse and \isempty

% E-Mail header strings with format.
\newcommand{\fromString}{\textbf{From:} }
\newcommand{\toString}{\textbf{To:} }

% E-Mail with or without alias.
\newcommand{\email}[2][]{%
    \ifthenelse{\isempty{#1}}%
        {<#2>}% E-Mail only
    {"#1" <#2>}% Alias and E-Mail
}

% E-Mail header From:    
\newcommand{\emailFrom}[2][]{%
    \ifthenelse{\isempty{#1}}%
        {\fromString \email{#2}\\}% E-Mail only
    {\fromString \email[#1]{#2}\\}% Alias and E-Mail
}

% E-Mail header To:
\newcommand{\emailTo}[2][]{%
    \ifthenelse{\isempty{#1}}%
        {\toString \email{#2}\\}% E-Mail only
    {\toString \email[#1]{#2}\\}% Alias and E-Mail
}

Las macros se pueden utilizar como se ilustra en los siguientes ejemplos. Tenga en cuenta que []se utilizan para argumentos opcionales en lugar de {}.

\email[Doe, John]{[email protected]}
\emailFrom[Doe, John]{[email protected]}
\emailFrom{[email protected]}
\emailTo[Doe, John]{[email protected]}
\emailTo{[email protected]}

La salida formateada se ve así:

"Gama, John" <[correo electrónico protegido]>
De:"Gama, John" <[correo electrónico protegido]>
De:<[correo electrónico protegido]>
A:"Gama, John" <[correo electrónico protegido]>
A:<[correo electrónico protegido]>

¿Cómo podría ampliar la macro para poder usarla con varias direcciones de correo electrónico? El siguiente ejemplo debería explicar el problema. Como puede ver en el tercer ejemplo, la aparición del alias es individual para cada entrada de correo electrónico.

A:"Gama, John" <[correo electrónico protegido]>, "Cierra, Jane" <[correo electrónico protegido]>
A:<[correo electrónico protegido]>, <[correo electrónico protegido]>
A:<[correo electrónico protegido]>, "Cierra, Jane" <[correo electrónico protegido]>

Como soy nuevo en el uso de macros en látex, también puedes mejorar mis comandos en general o dejar comentarios para hacerlo.


Actualizar:

Mientras trabajaba con varios correos electrónicos me di cuenta de que también puede pasar, que hayNodirección de correo electrónicodado, Solo elalias de correo electrónico. Esto sucede cuando alguien reenvía correos electrónicos, por ejemplo, como una conversación interna en una empresa. Sin embargo, acepto este formato como encabezado de correo electrónico válido. ¿Ves alguna posibilidad de incluir este esquema en las macros? Aquí hay un ejemplo.

From: John Doe
Subject: Re: E-Mail headers
Date: Wed, 22 Aug 2012 23:42:00 +0200
To: Jane Doe

Respuesta1

Usaría una sintaxis diferente para los casos de una dirección y varias direcciones:

\documentclass{article}
\usepackage[T1]{fontenc}
\makeatletter
\newif\if@emailenv
\newenvironment{emails}[1][\ignorespaces]
  {\set@email@separator{#1}\@emailenvtrue\begin{flushleft}}
  {\end{flushleft}}
\def\set@email@separator#1{%
  \def\email@separator{#1\def\email@separator{,}}}
\newcommand{\@email}[2][]{%
  \if@emailenv\else\begin{flushleft}\fi
  \email@separator\space
  \if\relax\detokenize{#1}\relax\else"#1" \fi
  \texttt{<#2>}%
  \if@emailenv\ignorespaces\else\end{flushleft}\fi
}
\newcommand{\email}{%
  \if@emailenv\else\set@email@separator{\ignorespaces}\fi\@email}
\newcommand{\emailTo}{%
  \if@emailenv\else\set@email@separator{\textbf{To:}}\fi\@email}
\newcommand{\emailFrom}{%
  \if@emailenv\else\set@email@separator{\textbf{From:}}\fi\@email}
\newcommand{\emailsFrom}{\emails[\textbf{From:}]}
\newcommand{\emailsTo}{\emails[\textbf{To:}]}
\let\endemailsFrom\endemails
\let\endemailsTo\endemails
\makeatother

\begin{document}
\email{[email protected]}

\email[Doe, John]{[email protected]}

\emailTo{[email protected]}

\emailTo[Doe, John]{[email protected]}

\emailFrom{[email protected]}

\emailFrom[Doe, John]{[email protected]}



\begin{emails}
\email{[email protected]}
\email[Doe, John]{[email protected]}
\email[Doe, Jane]{[email protected]}
\end{emails}

\begin{emailsTo}
\email{[email protected]}
\email[Doe, John]{[email protected]}
\email[Doe, Jane]{[email protected]}
\end{emailsTo}

\begin{emailsFrom}
\email{[email protected]}
\email[Doe, John]{[email protected]}
\email[Doe, Jane]{[email protected]}
\end{emailsFrom}

\end{document}

ingrese la descripción de la imagen aquí

Respuesta2

Esta solución utiliza foreachdesdeTikZ/PGF. Usted especifica los nombres y correos electrónicos como una lista del formulario name/mail,name/maily así sucesivamente:

El código

\documentclass[parskip]{scrartcl}
\usepackage[margin=15mm]{geometry}
\usepackage{tikz}
\usepackage{xifthen}

\newcommand{\toString}{\textbf{To:} }

\newcommand{\emailto}[1]% list ; "/" separates mail and name, "," separates people
{   \xdef\maillist{}% empty maillist
    \foreach \x/\y [count=\c] in {#1}% for each iteration over the name/mail list, increase \c by one
    {   \ifthenelse{\c=1}% if first iteration... 
            {\xdef\addcomma{}}% leave out comma
            {\xdef\addcomma{,}}% else put one
        \ifthenelse{\equal{\x}{}}% if no name given
            {\xdef\maillist{\maillist\addcomma$<$\y$>$}}% put just <mail>
            {\xdef\maillist{\maillist\addcomma"\x"$<$\y$>$}}% else put "name"<mail>
    }
    \toString\maillist% output of the final list
}

\begin{document}

\emailto{John Doe/[email protected],Jane Dane/[email protected],/[email protected]}

\end{document}

El resultado

ingrese la descripción de la imagen aquí


Edición 1:Una pequeña generalización: ahora puedes reutilizarla \emailpara otras definiciones. No tengo idea de cómo hacer esto con parámetros opcionales, ya que su número no es igual a los parámetros.

El código

\newcommand{\email}[1]% list ; "/" separates mail and name, "," separates people
{   \xdef\maillist{}% empty maillist
    \foreach \x/\y [count=\c] in {#1}% for each iteration over the name/mail list, increase \c by one
    {   \ifthenelse{\c=1}% if first iteration... 
            {\xdef\addcomma{}}% leave out comma
            {\xdef\addcomma{,}}% else put one
        \ifthenelse{\equal{\x}{}}% if no name given
            {\xdef\maillist{\maillist\addcomma$<$\y$>$}}% put just <mail>
            {\xdef\maillist{\maillist\addcomma"\x"$<$\y$>$}}% else put "name"<mail>
    }
}

\newcommand{\emailto}[1]
{   \email{#1}
    \textbf{To: }\maillist
}

\newcommand{\emailfrom}[1]
{   \email{#1}
    \textbf{From: }\maillist
}

El resultado

\emailto{John Doe/[email protected],Jane Dane/[email protected],/[email protected]}

\emailfrom{John Doe/[email protected],Jane Dane/[email protected],/[email protected]}

ingrese la descripción de la imagen aquí


Edición 2: Y ahora para algo completamente diferente:
Esta solución utiliza xstring, el formato de lista es (name)email;.
Tenga en cuenta que usted tambiéndebe terminar la lista con un punto y coma;

El código

\documentclass[parskip]{scrartcl}
\usepackage[margin=10mm]{geometry}
\usepackage{xifthen}
\usepackage{xstring}
\usepackage{xcolor}

\newcommand{\email}[1]% (<name>)<email>;(<name>)<email>
{   \xdef\mylist{#1} % set mylist to the input
    \xdef\myentry{} % empty myentry
    \xdef\myname{} % empty myname
    \xdef\myemail{} % empty myemail
    \xdef\myoutput{} % empty myoutput
    \xdef\mynumber{} % empty mynumber
    \StrBefore{\mylist}{;}[\myentry]  % get everything in mylist before ; and save it to myentry, so this should be the first person, e.g (name)mail
    \StrLen{\myentry}[\mynumber] % save length of myentry to mynumber
    \whiledo{\mynumber>0} % while myentry is not empty (e.g. length > 0)
    {   \StrBetween{\myentry}{(}{)}[\myname] % extract what is between ( and ) in myentry and save it to myname
        \StrPosition{\myentry}{)}[\mynumber] % save position of ) to mynumber
        \ifthenelse{\mynumber>0} % if the character ) is found in myentry
            {   \StrBehind{\myentry}{)}[\myemail]} % then get everything behind ), e.g the email
            { \xdef\myemail{\myentry}}% otherwise (e.g. no name present) set myemail to myentry
        \StrLen{\myname}[\mynumber] % set mynumber to the length of mynem
        \ifthenelse{\mynumber>0} % if length of myname is non-zero (e.g one was provided)
            {   \xdef\myoutput{\myoutput"\myname"$<$\myemail$>$}} % then print "name"<mail>
            { \xdef\myoutput{\myoutput$<$\myemail$>$}}  % else print <mail>
        \StrBehind{\mylist}{;}[\mylist] % delete everything up to the first ; e.g the entry that was just worked with
        \StrBefore{\mylist}{;}[\myentry] % new myentry is everything before the next ;
        \StrLen{\myentry}[\mynumber] % determine length of myentry and save that number to mynumber
        \ifthenelse{\mynumber>0} % if a new myentry is present (e.g not end of list)
            {   \xdef\myoutput{\myoutput,}} % then add a comma
            {} % else do nothing
        }
    %\myoutput  % after all entrys were processed, output the result
}

\newcommand{\eMailTo}[1]%
{   \email{#1}
    \textbf{To: }\myoutput
}

\newcommand{\eMailFromColor}[2][green!50!gray]%
{   \email{#2}
    \textcolor{#1}{\textbf{From: }\myoutput}
}

\begin{document}

\eMailTo{(Doe, John)[email protected];(Dane, J. A. N. E)[email protected];[email protected];}

\eMailFromColor{(Doe, John)[email protected];(Dane, J. A. N. E)[email protected];[email protected];}

\eMailFromColor[red!80!black]{(Doe, John)[email protected];(Dane, J. A. N. E)[email protected];[email protected];}

\end{document}

El resultado

ingrese la descripción de la imagen aquí

información relacionada