我正在尝试使用 来pgfkeys
收集将传递给 的信息clist
。但是,我无法让它正常工作。似乎我在列表周围得到了括号,并且无法\clist_map_inline:Nn
按预期解析其参数。
以下是 MWE:
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\clist_new:N \l_ae_itemize_element_clist
\cs_new:Npn \_ae_itemize:n #1
{
\clist_set:Nn \l_ae_itemize_element_clist {#1}
\begin{itemize}
\clist_map_inline:Nn \l_ae_itemize_element_clist { \item ##1 }
\end{itemize}
}
\NewDocumentCommand{\aeItemizeElements}{m}
{ \_ae_itemize:n {#1} }
\ExplSyntaxOff
\usepackage{pgfkeys}
\pgfkeys
{
/ae/list example/.cd,
title/.initial =,
content/.initial = {},
}
\def\aeSet#1{\pgfkeys{/ae/list example/.cd,#1}}
\def\aeGet#1{\pgfkeysvalueof{/ae/list example/#1}}
\NewDocumentCommand{\aeItemizeA}{ m }
{\aeSet{#1}%%'
\noindent\textbf{\aeGet{title}}%%'
\aeItemizeElements{\aeGet{content}}
}
\pagestyle{empty}
\begin{document}
\aeItemizeA{title=Works as expected,content=\textbf{only one item}}
\aeItemizeA{title=Not iterating over content,content={first item, second item}}
\end{document}
为了使第二个列表格式正确,我可以这样做
\clist_set:Nx \l_ae_itemize_element_clist {#1}
但由于内容扩展,第一个列表会崩溃。
有没有办法自动去除外括号(如果有),但不扩展内容,或者如果没有外括号则不执行任何操作?
答案1
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\clist_new:N \l_ae_itemize_element_clist
\cs_new:Npn \_ae_itemize:n #1
{
\clist_set:No \l_ae_itemize_element_clist {\romannumeral`\^^@#1}
\begin{itemize}
\clist_map_inline:Nn \l_ae_itemize_element_clist { \item ##1 }
\end{itemize}
}
\NewDocumentCommand{\aeItemizeElements}{m}
{ \_ae_itemize:n {#1} }
\ExplSyntaxOff
\usepackage{pgfkeys}
\pgfkeys
{
/ae/list example/.cd,
title/.initial =,
content/.initial = {},
}
\def\aeSet#1{\pgfkeys{/ae/list example/.cd,#1}}
\def\aeGet#1{\pgfkeysvalueof{/ae/list example/#1}}
\NewDocumentCommand{\aeItemizeA}{ m }
{\aeSet{#1}%%'
\noindent\textbf{\aeGet{title}}%%'
\aeItemizeElements{\aeGet{content}}
}
\pagestyle{empty}
\begin{document}
\aeItemizeA{title=Works as expected,content=\textbf{only one item}}
\aeItemizeA{title=Not iterating over content,content={first item, second item}}
\end{document}
答案2
这是一个pgfkeys
仅有的方法(还有一点点pgffor
针对.list
处理程序的方法)。
这个\romannumeral
技巧用于获取content
密钥的内容而不扩展它(我们不能edef
这样做,因为可能存在无法扩展的内容(如\textbf
))。这仅用于测试content
密钥的内容。否则就不需要它。
下面给出的是 -less版本\rumannumeral
,但有两个扩展名(包括九个\expandafter
s)。
需要\aeGet{content}
将其扩展四次才能了解其内容。
\pgfkeysvalueof{/ae/list example/content}
\csname pgfk@/ae/list example/content\endcsname
\pgfk@/ae/list example/content
<content>
当然,您可以通过提供原始\csname
版本(类似于\romannumeral
-less 版本\def\aeTemp
)来缩短它。
代码
\documentclass{article}
\usepackage{pgfkeys,pgffor}
\def\aeSet{\pgfqkeys{/ae/list example}}
\def\aeGet#1{\pgfkeysvalueof{/ae/list example/#1}}
\aeSet{
title/.initial=,
content/.initial=,
itemize/.code={\item #1}%
}
\newcommand{\aeItemizeA}[1]{%
\begingroup
\aeSet{#1}
\noindent\textbf{\aeGet{title}}%
\expandafter\def\expandafter\aeTemp\expandafter{\romannumeral-`0\aeGet{content}}%
% or:
% \expandafter\expandafter\expandafter\def
% \expandafter\expandafter\expandafter\aeTemp
% \expandafter\expandafter\expandafter{\csname pgfk@/ae/list example/content\endcsname}%
\itemize
\ifx\aeTemp\empty
\item \itshape empty!
\else
\aeSet{itemize/.list/.expand twice/.expand twice=\aeGet{content}}
\fi
\enditemize
\endgroup
}
\pagestyle{empty}
\begin{document}
\aeItemizeA{title=No entry given!}
\aeItemizeA{title=Works as expected,content=\textbf{only one item}}
\aeItemizeA{title=Not iterating over content,content={first item, second item}}
\end{document}
输出
答案3
pgfkeys
我认为,没有它会更容易。
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\clist_new:N \l_ae_itemize_element_clist
\cs_generate_variant:Nn \clist_map_inline:nn { f }
\cs_new:Npn \_ae_itemize:n #1
{
\begin{itemize}
\clist_map_inline:fn {#1} { \item ##1 }
\end{itemize}
}
\NewDocumentCommand{\aeItemizeElements}{m}
{ \_ae_itemize:n {#1} }
\keys_define:nn { ae/list }
{
title .tl_set:N = \l_ae_list_title_tl,
title .initial:n = {},
content .tl_set:N = \l_ae_list_content_tl,
content .initial:n = {},
}
\NewDocumentCommand{\aeSet}{m}
{
\keys_set:nn { ae/list } { #1 }
}
\NewDocumentCommand{\aeItemizeA}{ m }
{
\group_begin:
\aeSet{#1}
\noindent\textbf{\l_ae_list_title_tl}
\aeItemizeElements{\l_ae_list_content_tl}
\group_end:
}
\ExplSyntaxOff
\pagestyle{empty}
\begin{document}
\aeItemizeA{title=Works as expected,content=\textbf{only one item}}
\aeItemizeA{title=Iterating over content,content={first item, second item}}
\newcommand{\test}{Item A, Item B}
\aeItemizeA{title=This has a control sequence for content, content=\test}
\end{document}