我希望我所用的术语对于我的问题是正确的。
我正在开发一个模板,它有需要用户设置的变量。并非所有用户都有相同数量的变量。用户是学生。例如:有些学生可能没有共同指导老师。我的模板将检查该变量是否已定义,然后打印所需的内容。
我有一个 MWE。
\documentclass{article}
\usepackage{xspace}
\def\mySupervisor{John Smith\xspace}
\newcommand{\theSupervisor}{Jackie Chan\xspace}
\begin{document}
\ifdefined\mySupervisor
\noindent\rule{5cm}{1pt}\\
The Supervisor\\
\mySupervisor
\else
SELF Supervision.
\fi
\end{document}
我的问题:
- 这是做这种事的正确方法吗?
- 我使用的方法有什么怪癖吗?
- 有没有更好的办法?
- 我感觉
\newcommand{}
这里不太好?
答案1
我建议expl3
使用来自或可选的属性列表key-value
接口,这意味着可以使用类似 的内容设置某些键\SetupData{supervisor={foo},name={foobar}}
,但这意味着需要进行大量预定义。这样,就不必为每个键定义单独的宏。
该\SetupData
宏使用任何可能的键名,例如birth date
,并将数据存储到属性列表中。\IfStudentDataGivenTF
等宏检查是否给出了键,并相应地进行分支。
该\SetStudentData
宏的行为类似于键 - 值接口,但设置所有键而无需事先定义它们。
\documentclass{article}
\usepackage{xcolor}
\usepackage{xspace}
\usepackage{xparse}
\ExplSyntaxOn
\prop_new:N \g_khalid_student_prop
\keys_define:nn {STUDENTDATA} {
supervisor .code:n={\prop_gput:Nnn \g_khalid_student_prop {supervisor} {#1}},
name .code:n={\prop_gput:Nnn \g_khalid_student_prop {name} {#1}}
}
\NewDocumentCommand{\setupdata}{+m}{%
\keys_set:nn { STUDENTDATA } {#1}
}
\prg_new_conditional:Nnn \khalid_if_studentdatagiven:n { T,F, TF } {
\prop_if_in:NnTF {\g_khalid_student_prop } {#1} {
\prg_return_true:
}
{
\prg_return_false:
}
}
\cs_new:Npn \retrievestudentdata#1{%
\prop_item:Nn \g_khalid_student_prop {#1}
}
\NewDocumentCommand{\IfStudentDataGivenTF}{m+m+m}{%
\khalid_if_studentdatagiven:nTF {#1} {#2} {#3}
}
\NewDocumentCommand{\IfStudentDataGivenT}{m+m}{%
\khalid_if_studentdatagiven:nT {#1} {#2}
}
\NewDocumentCommand{\IfStudentDataGivenF}{m+m}{%
\khalid_if_studentdatagiven:nF {#1} {#2}
}
\NewDocumentCommand{\ClearStudentData}{}{%
\prop_gclear:N \g_khalid_student_prop
}
\cs_generate_variant:Nn \prop_gput:Nnn {Nox,Nxx}
\NewDocumentCommand{\SetStudentData}{+m}{
\seq_set_from_clist:Nn \l_tmpa_seq {#1}
\seq_map_inline:Nn \l_tmpa_seq {
\seq_set_split:Nnn \l_tmpb_seq {=} {##1}
\prop_gput:Nxx \g_khalid_student_prop {\seq_item:Nn \l_tmpb_seq {1} } {\seq_item:Nn \l_tmpb_seq {2} }
}
}
\ExplSyntaxOff
\begin{document}
\setupdata{supervisor={Jackie Chan\xspace}, name={Gandalf the Grey}}
\IfStudentDataGivenTF{supervisor}{%
\noindent\rule{5cm}{1pt}
The Supervisor
\retrievestudentdata{supervisor}
}{%
SELF Supervision
}
\IfStudentDataGivenT{name}{%
Name:
\retrievestudentdata{name}
}
\ClearStudentData
\SetStudentData{date of birth=2018/02/30, place of birth={Middle Earth}}
\IfStudentDataGivenT{date of birth}{%
\colorbox{yellow}{Date of birth: \retrievestudentdata{date of birth}}
\colorbox{green}{Place of birth: \retrievestudentdata{place of birth}}
}
\end{document}