Как расширить макрос для адресов электронной почты для поддержки нескольких аргументов?

Как расширить макрос для адресов электронной почты для поддержки нескольких аргументов?

Я подготовил следующие макросы для форматирования адресов электронной почты в заголовке электронного письма.

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

Макросы можно использовать, как показано в следующих примерах. Обратите внимание, что []используются для необязательных аргументов вместо {}.

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

Отформатированный вывод выглядит следующим образом:

«Доу, Джон» <[email protected]>
От:«Доу, Джон» <[email protected]>
От:<[email protected]>
К:«Доу, Джон» <[email protected]>
К:<[email protected]>

Как можно расширить макрос, чтобы использовать его с несколькими адресами электронной почты? Следующий пример должен объяснить проблему. Как вы можете видеть из третьего примера, появление псевдонима индивидуально для каждой записи электронной почты.

К:«Доу, Джон» <[email protected]>, "Доу, Джейн" <[email protected]>
К:<[email protected]>, <[email protected]>
К:<[email protected]>, "Доу, Джейн" <[email protected]>

Поскольку я новичок в использовании макросов в Latex, вы также можете улучшить мои команды или оставить комментарии, чтобы сделать это.


Обновлять:

Работая с несколькими электронными письмами, я понял, что это тоже может случиться, что естьнетАдрес электронной почтыданный, толькопсевдоним электронной почты. Это происходит, когда кто-то пересылает электронные письма, например, как внутренний разговор в компании. Тем не менее, я принимаю этот формат как допустимый заголовок электронного письма. Видите ли вы возможность включить эту схему в макросы? Вот пример.

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

решение1

Я бы использовал другой синтаксис для случаев одного адреса и нескольких адресов:

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

введите описание изображения здесь

решение2

Это решение использует foreachотТикЗ / ПГФ. Вы указываете имена и адреса электронной почты в виде списка формы name/mail,name/mailи т. д.:

Код

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

Результат

введите описание изображения здесь


Редактировать 1:Небольшое обобщение: Теперь можно повторно использовать \emailдля других определений. Я не представляю, как это сделать с необязательными параметрами, так как их количество не равно параметрам.

Код

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

Результат

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

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

введите описание изображения здесь


Редактировать 2: А сейчас нечто соверешнно другое:
Это решение использует xstring, формат списка (name)email;.
Обратите внимание, что вы такженеобходимо завершить список точкой с запятой;

Код

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

Результат

введите описание изображения здесь

Связанный контент