使用 pgfkeys 创建清单 -> 如果需要,可以使用多个 /.is

使用 pgfkeys 创建清单 -> 如果需要,可以使用多个 /.is

我想创建一个包含“静态”内容的清单,但对于此清单的每个实例,我希望能够选中或取消选中清单中的某些项目。因为我想学习 PGFKeys,所以我尝试这样做:

\documentclass{article}

\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}

\usepackage{wasysym}
\usepackage{multicol}
\usepackage{pgf}

\newcommand{\itemChecked}{\item[\XBox]}
\newcommand{\itemUnchecked}{\item[\Square]}

\newif\ifcheckA
\newif\ifcheckB
\newif\ifcheckC
\newif\ifcheckD

\pgfkeys{/mychecklist/.is family, /mychecklist,
          checkA/.is if = checkA, A/.style={checkA=true},
          checkB/.is if = checkB, B/.style={checkB=true},
          checkC/.is if = checkC, C/.style={checkC=true},         
          checkD/.is if = checkD, D/.style={checkD=true},         
%%        
          default/.style = {checkA=false, checkB=false, checkC=false, checkD=false}}


\newcommand{\itemif}[1]{#1 \itemChecked \else \itemUnchecked \fi}
%\newcommand{\itemif}[1]{\ifcheck#1 \itemChecked \else \itemUnchecked \fi} %  <- not working: \itemif{A} ...

\newcommand{\mylist}[1]{
    \pgfkeys{/mychecklist, default, #1} 
    \begin{multicols}{2}
        \begin{itemize}
            \itemif{\ifcheckA} Here is Text A
            \itemif{\ifcheckB} Here is Text B
            \itemif{\ifcheckC} Here is Text C
            \itemif{\ifcheckD} Here is Text D
        \end{itemize}
    \end{multicols} 
}


\begin{document}
\mylist{A,D}
\end{document}

这给了我以下输出: 输出 ...这正是我想要的!

但:在我看来,这段代码非常混乱且效率低下(尤其是当我想添加超过四个项目时!)。我相信有一种更简洁的方法来解决这个问题。我已经尝试使用 -loop \foreach,但我认为扩展时存在一些问题:

\documentclass{article}

\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}

\usepackage{wasysym}
\usepackage{multicol}
\usepackage{pgf}

\newcommand{\itemChecked}{\item[\XBox]}
\newcommand{\itemUnchecked}{\item[\Square]}

\pgfkeys{/mychecklist/.is family, /mychecklist, default/.style={}}

\AtBeginDocument{   % <- without this the \foreach loop doesn't work!
    \foreach \i in {A, B, C, D}{
        \newif{\ifcheck\i}
        \pgfkeys{ /mychecklist,
                  {check\i}/.is if = {check\i}, {\i}/.style={check{\i}=true},           
                  default/.append style = {{check\i}=false}}
    }


    \newcommand{\itemif}[1]{#1 \itemChecked \else \itemUnchecked \fi}
    %\newcommand{\itemif}[1]{\ifcheck#1 \itemChecked \else \itemUnchecked \fi} %  <- not working: \itemif{A} ...

    \newcommand{\mylist}[1]{
        \pgfkeys{/mychecklist, default, #1} 
        \begin{multicols}{2}
            \begin{itemize}
                \itemif{\ifcheckA} Here is Text A
                \itemif{\ifcheckB} Here is Text B
                \itemif{\ifcheckC} Here is Text C
                \itemif{\ifcheckD} Here is Text D
            \end{itemize}
        \end{multicols} 
    }
}

\begin{document}
\mylist{A,D}
\end{document}

提前致谢!

答案1

这里的诀窍是使用\csname ifcheck#1\endcsname而不是\ifcheck#1

\documentclass{article}

\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}

\usepackage{wasysym}
\usepackage{multicol}
\usepackage{pgf}
\usepackage{pgffor}
\newcommand{\itemChecked}{\item[\XBox]}
\newcommand{\itemUnchecked}{\item[\Square]}


\pgfkeys{/mychecklist/.is family}
\def\checklistkeys#1{\pgfkeys{/mychecklist,#1}}
\checklistkeys{
  default/.style={},
  add choice/.style={
    /utils/exec={\expandafter\newif\csname ifcheck#1\endcsname},
    check#1/.is if=check#1,
    #1/.style={check#1=true},
    default/.append style={check#1=false},
  },
}

\checklistkeys{add choice/.list={A,B,C,D}}

\newcommand{\itemif}[1]{\csname ifcheck#1\endcsname \itemChecked \else \itemUnchecked \fi}

\newcommand{\mylist}[1]{
  \pgfkeys{/mychecklist,default,#1} 
  \begin{multicols}{2}
    \begin{itemize}
      \itemif{A} Here is Text A
      \itemif{B} Here is Text B
      \itemif{C} Here is Text C
      \itemif{D} Here is Text D
    \end{itemize}
  \end{multicols} 
}


\begin{document}
\mylist{A,D}
\end{document}

相关内容