我想创建一个包含“静态”内容的清单,但对于此清单的每个实例,我希望能够选中或取消选中清单中的某些项目。因为我想学习 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}