![xparse を使用してカスタム \author 形式を解析する方法は?](https://rvso.com/image/370305/xparse%20%E3%82%92%E4%BD%BF%E7%94%A8%E3%81%97%E3%81%A6%E3%82%AB%E3%82%B9%E3%82%BF%E3%83%A0%20%5Cauthor%20%E5%BD%A2%E5%BC%8F%E3%82%92%E8%A7%A3%E6%9E%90%E3%81%99%E3%82%8B%E6%96%B9%E6%B3%95%E3%81%AF%3F.png)
次のように \author コマンドの使用を許可します。
\author{John Doe <[email protected]>, Someone Else <[email protected]>}
そして、後で値を次のように解析します。
\textsf{\textbf{John Doe}, \href{[email protected]}{Email: [email protected]}\\}
\textsf{\textbf{Someone Else}, \href{[email protected]>}{Email: [email protected]>}\\}
私はすでにパッケージを使用して同様のことを試しましたxparse
:
\NewDocumentCommand{\printauthors}{ >{\SplitList{,}} m }{%
\ProcessList{#1}{\printauthor}%
}
\NewDocumentCommand{\printauthor}{m}{ >{\SplitList{<}} m }{%
\textsf{\textbf{#1}, \href{#2}{Email: #2}\\}
}
\printauthors{\theauthor}
最小限のドキュメント:
\documentclass{article}
\usepackage{titling}
\usepackage{xparse}
\title{mwe}
\author{John Doe <[email protected]>, Someone Else <[email protected]>}
\NewDocumentCommand{\printauthors}{ >{\SplitList{,}} m }{%
\ProcessList{#1}{\printauthor}%
}
\NewDocumentCommand{\printauthor}{ >{\SplitList{<}} m }{%
\textsf{\textbf{#1}, \href{#2}{Email: #2}\\}
}
\begin{document}
\thetitle
\printauthors{\theauthor}
\end{document}
しかし、そのようには動作しないようです。何が間違っているのでしょうか? もっと良い方法はあるのでしょうか?
答え1
カンマで分割してメールを解析することができます。正規表現を使用すると (ほぼ) 簡単です。
\documentclass{article}
\usepackage{titling}
\usepackage{xparse}
\usepackage{hyperref}
\ExplSyntaxOn
\NewDocumentCommand{\printauthors}{}
{
\seq_gset_from_clist:NV \g_bauer_authors_seq \theauthor
\seq_clear:N \l__bauer_authors_out_seq
\seq_map_inline:Nn \g_bauer_authors_seq
{
\bauer_authors_parseemail:n { ##1 }
}
\seq_use:Nn \l__bauer_authors_out_seq { \\ }
}
\cs_generate_variant:Nn \seq_gset_from_clist:Nn { NV }
\seq_new:N \g_bauer_authors_seq
\seq_new:N \l__bauer_authors_out_seq
\cs_new_protected:Nn \bauer_authors_parseemail:n
{
\tl_set:Nn \l_tmpa_tl { #1 }
\regex_replace_once:nnN
{ ([^<]*) } % anything up to <
{ \c{bauer_authors_format_author:n}\cB\{\1\cE\} }
\l_tmpa_tl
\regex_replace_once:nnN
{ \<(.*)\> } % anything between < >
{ ,\ \c{bauer_authors_format_email:n}\cB\{\1\cE\} }
\l_tmpa_tl
\seq_put_right:NV \l__bauer_authors_out_seq \l_tmpa_tl
}
\cs_new_protected:Nn \bauer_authors_format_author:n
{
\textsf { \textbf {\tl_trim_spaces:n { #1 } } }
}
\cs_new_protected:Nn \bauer_authors_format_email:n
{
\href{mailto:#1}{Email:~\texttt{#1}}
}
\ExplSyntaxOff
\title{mwe}
\author{
John Doe <[email protected]>,
Someone Else <[email protected]>,
No Mail
}
\begin{document}
\begin{flushleft}
{\LARGE\thetitle\\}
\bigskip
\printauthors
\end{flushleft}
\end{document}
それぞれのセグメントは次のように変換されます
\bauer_authors_format_author:n { <name> }, \bauer_authors_format_email:n { <email> }
そして、\printauthors
すべてのセグメントを で区切ります\\
。
キー値引数を使用した別のアプローチ。他の属性を受け入れるように拡張できます。
\documentclass{article}
\usepackage{titling}
\usepackage{xparse}
\usepackage{hyperref}
\ExplSyntaxOn
\NewDocumentCommand{\authorlist}{m}
{% a sequence of key-value items
\keys_set:nn { bauer/authors } { #1 }
}
\NewDocumentCommand{\printauthors}{}
{
\seq_map_function:NN \g_bauer_authors_seq \__bauer_authors_print:n
}
\seq_new:N \g_bauer_authors_seq
\tl_new:N \l__bauer_authors_temp_tl
\keys_define:nn { bauer/authors }
{
author .code:n = \__bauer_authors_setup:n { #1 },
email .code:n = \__bauer_authors_email:n { #1 },
}
\cs_new_protected:Nn \__bauer_authors_setup:n
{
\tl_gset:Nx \l__bauer_authors_temp_tl { \tl_to_str:n { #1 } }
\seq_gput_right:NV \g_bauer_authors_seq \l__bauer_authors_temp_tl
\prop_new:c { g_bauer_authors_ \l__bauer_authors_temp_tl _prop }
\prop_gput:cnn
{ g_bauer_authors_ \l__bauer_authors_temp_tl _prop }
{ author }
{ #1 }
}
\cs_new_protected:Nn \__bauer_authors_email:n
{
\prop_gput:cnn
{ g_bauer_authors_ \l__bauer_authors_temp_tl _prop }
{ email }
{ #1 }
}
\cs_new_protected:Nn \__bauer_authors_print:n
{
\bauer_authors_format_author:n
{
\prop_item:cn { g_bauer_authors_#1_prop } { author }
}
\prop_if_in:cnT { g_bauer_authors_#1_prop } { email }
{
,~ % separation
\bauer_authors_format_email:n
{
\prop_item:cn { g_bauer_authors_#1_prop } { email }
}
}
\\ % new line
}
\cs_new_protected:Nn \bauer_authors_format_author:n
{
\textsf { \textbf {\tl_trim_spaces:n { #1 } } }
}
\cs_new_protected:Nn \bauer_authors_format_email:n
{
\href{mailto:#1}{Email:~\texttt{#1}}
}
\ExplSyntaxOff
\title{mwe}
\authorlist{
author = John Doe,
email = [email protected],
author = Someone Else,
email = [email protected],
author = No Mail
}
\begin{document}
\begin{flushleft}
{\LARGE\thetitle\\}
\bigskip
\printauthors
\end{flushleft}
\end{document}
各著者にはプロパティ リストが割り当てられ、シーケンスは著者のインデックス作成に使用されます。