如何在不扩展内容的情况下删除外括号?

如何在不扩展内容的情况下删除外括号?

我正在尝试使用 来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,但有两个扩展名(包括九个\expandafters)。

需要\aeGet{content}将其扩展四次才能了解其内容。

  1. \pgfkeysvalueof{/ae/list example/content}
  2. \csname pgfk@/ae/list example/content\endcsname
  3. \pgfk@/ae/list example/content
  4. <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}

在此处输入图片描述

相关内容