0

I hope I've used the right terms for my question.

I'm working on a template and it has variables which need to be setup by the user. Not all users have the same amount of variables. Users are students. Example: Some students may not have a co-supervisor. My template will check if that variable was defined or not and then print what is required.

I have an 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}

My questions:

  1. Is this the right way to do this sort of thing?
  2. Are there any quirks to the method I've used?
  3. Is there a better way?
  4. I'm under the impression that \newcommand{} is not good here?
  • Do not mix \def and \newcommand this way. Use the latter. Is the user really supposed to define the command him/herself? – TeXnician Feb 24 '18 at 19:01
  • I've put the variable definition but they should change the name or comment it out if it doesn't apply to them. – Khalid Hussain Feb 24 '18 at 19:03
  • I would suggest a key-value interface rather here – user31729 Feb 24 '18 at 19:08
  • @ChristianHupfer Can you please elaborate? – Khalid Hussain Feb 24 '18 at 19:08
2

I suggest a property list from expl3 and optionally using a key-value interface, meaning that some keys can be set with something like \SetupData{supervisor={foo},name={foobar}}, however this means a lot of predefinition. This way, no separate macros for each of the keys have to be defined.

The \SetupData macro uses any possible key name, e.g. birth date, and stores the data to the property list. The \IfStudentDataGivenTF etc. macros check whether the key is given and branch accordingly.

The \SetStudentData macro behaves similar to the key - value interface, but sets all keys without defining them before.

\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}

enter image description here

  • 1
    What are the benefits of such a method over creating a file of all the variables and then using \input in any file where you need them? – Khalid Hussain Feb 24 '18 at 19:33
  • @KhalidHussain: You can incorporate this code in a package of your own and use the package in any of your template files, in addition, you can create the keys on the fly, when you need them – user31729 Feb 24 '18 at 19:35

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.