0

So what I have works, but I am looking for a cleaner / better approach.

I have a titlepage which needs a \maketitle in the form of a table (Tabular actually). However, when options are missing they should just be removed from the table. Similarly if no options are given, no table should be printed.

For instance

\def\@author{Jane doe}
\def\@date{\today}
\def\@verifier{Joe Doe}

Should produce

enter image description here

While

\def\@author{Jane doe}
\def\@date{}
\def\@verifier{}

becomes

enter image description here

This is my current idea, presented in as minimal of an example as I could make

\documentclass{article}
\usepackage{etoolbox}
\usepackage{booktabs}

\makeatletter \def@author{} \def@date{} \def@verifier{} % Comment out the lines bellow to test \def@author{Jane doe} \def@date{\today} \def@verifier{Joe Doe}

\newcommand{\maketitletable}{ % \newcommand{\authorname}{author} \newcommand{\datename}{date} \newcommand*{\verifiername}{verifier} % \ifstrempty{@author@date@verifier}{}{ \noindent \begin{tabular}{p{0.2\textwidth} p{0.2\textwidth} p{\dimexpr 0.6\textwidth - 4\tabcolsep}}\toprule \ifdefempty{@author}{}{& \authorname{} & @author \} \ifdefempty{@date}{}{& \datename{} & @date \} \ifdefempty{@verifier}{}{& \verifiername{} & @verifier \} \bottomrule \end{tabular}% } } \makeatother

\begin{document} \maketitletable \end{document}

Just for reference, In my real code I do something like the following (I have many more)

\usepackage{xparse}
\ExplSyntaxOn
    % Provide keys.
    \keys_define:nn { babylonia }
      {
        author         .tl_set:N  = \@author,
        author         .initial:n = {},
        date           .tl_set:N  = \@date,
        date           .initial:n = {},
        verifier       .tl_set:N  = \@verifier,
      }
    % Provide key setting command.
    \NewDocumentCommand\OUSsetup{ m }{
      \keys_set:nn { babylonia } { #1 }
    }
\ExplSyntaxOff

and then

\makeatletter

\renewcommand{\maketitle}{% ... minimal working example goes in here ... }

\makeatother

Before finally setting

\OUSsetup{
  author    = Jane Doe,
  date      = 01.12.2021,
  verifier  = Joe Doe,
}

\begin{document}

\maketitle

\end{document}

I am guessing this makes no difference to how the table is implemented.

N3buchadnezzar
  • 11,348
  • 7
  • 55
  • 114
  • So I guess you want some way to avoid the repetition? Be careful, sometimes the actual code is so complex it's unreadable (although with expl3 etc. it's less bad) -- can we assume \Xname always equal X? – user202729 Jun 18 '22 at 11:31
  • Actually if you already use keyval it has the .code:n interface to simply specify the code to be executed. If the user specifies the keys in correct order (unlikely?) just use that to typeset the rows directly – user202729 Jun 18 '22 at 11:32
  • Yes, we can always assume \Xname always equals X as these are defined by me. I just want to avoid some of the repetition =) And no, we can not rely on the users to input the keys in the correct order. Also a bit messy to avoid printing the bottomrule / toprule when no keys are present. Note that not every key in \OUSsetup will be in the table. – N3buchadnezzar Jun 18 '22 at 11:43

2 Answers2

2

Here is a possible solution with tabularray package:

\documentclass{article}
\usepackage{etoolbox}
\usepackage{tabularray}
\UseTblrLibrary{booktabs}

\makeatletter

\def@author{} \def@date{} \def@verifier{}

\def\authorname{author} \def\datename{date} \def\verifiername{verifier}

\newcommand*{\mycheckempty}[1]{\ifcsempty{@#1}{}{\csuse{#1name}\strut}}

\newcommand{\maketitletable}{% \ifstrempty{@author@date@verifier}{}{% \noindent \begin{booktabs}{ colspec={X[2]X[2]X[6]}, stretch=0, rowsep=0pt, column{2}={cmd=\mycheckempty}, } \toprule & author & @author \ & date & @date \ & verifier & @verifier \ \bottomrule \end{booktabs}% }% } \makeatother

\begin{document}

\makeatletter

\def@author{Jane doe} \def@date{\today} \def@verifier{Joe Doe} \maketitletable

\bigskip

\def@author{Jane doe} \def@date{} \def@verifier{} \maketitletable

\makeatother

\end{document}

enter image description here

L.J.R.
  • 10,932
1

The simplest solution (least modification to the existing code) would be to simply define an auxiliary macro (because of issues the macro must be defined outside, and some other issues with TikZ \foreach)

%! TEX program = lualatex
\documentclass{article}
\usepackage{etoolbox}
\usepackage{booktabs}

\makeatletter \def@author{} \def@date{} \def@verifier{} % Comment out the lines bellow to test \def@author{Jane doe} \def@date{\today} \def@verifier{Joe Doe}

\newcommand\printrow[1]{% ← this is the auxiliary macro ======== \ifcsempty{@#1}{}{ & \csuse{#1name} & \csuse{@#1} \ }% % ↑ ↑ ↑ ↑ ↑ ↑ ↑ might be replaced with simply #1 if you're sure }

\newcommand{\maketitletable}{ % \newcommand{\authorname}{author} \newcommand{\datename}{date} \newcommand*{\verifiername}{verifier} % \ifstrempty{@author@date@verifier}{}{ \noindent \begin{tabular}{p{0.2\textwidth} p{0.2\textwidth} p{\dimexpr 0.6\textwidth - 4\tabcolsep}}\toprule \printrow{author} % ======== use it like this \printrow{date} \printrow{verifier} \bottomrule \end{tabular}% } } \makeatother

\begin{document} \maketitletable \end{document}

Alternative solution with expl3.

%! TEX program = lualatex
\documentclass{article}
\usepackage{etoolbox}
\usepackage{booktabs}

\makeatletter \def@author{} \def@date{} \def@verifier{} % Comment out the lines bellow to test \def@author{Jane doe} \def@date{\today} \def@verifier{Joe Doe}

\ExplSyntaxOn \prg_generate_conditional_variant:Nnn \tl_if_empty:n {x} {F}

\cs_set_protected:Npn __process_item:n #1 { \tl_if_empty:cF {@#1} { & \use:c{#1name} & \use:c {@#1} \ } }

\newcommand{\maketitletable}{ % \newcommand{\authorname}{author} \newcommand{\datename}{date} \newcommand*{\verifiername}{verifier} % \tl_if_empty:xF{@author@date@verifier}{ \noindent \begin{tabular}{p{0.2\textwidth} p{0.2\textwidth} p{\dimexpr 0.6\textwidth - 4\tabcolsep}}\toprule \clist_map_function:nN {author, date, verifier} __process_item:n \bottomrule \end{tabular}% } } \makeatother \ExplSyntaxOff

\begin{document} \maketitletable \end{document}

Note that using \clist_map_inline directly will not work (Misplaced \noalign.) because of some low level TeX reasons (roughly speaking, at high revel \\ \bottomrule does work, while \\ \relax \bottomrule doesn't, and \clist_map_inline does some unexpandable things between \\ and \bottomrule)

user202729
  • 7,143
  • Generally speaking I recommend learning expl3 over e.g. etoolbox or similar. In this case at least the command naming scheme are more consistent – user202729 Jun 18 '22 at 12:10
  • I tried to define some commands using & but as you mentioned there are plenty issues with expandability. I see you recommend avoiding etoolbox (which I agree with), but why are we still using \ifstrempty? Could we have used \tl_if_empty:cF? – N3buchadnezzar Jun 18 '22 at 12:17
  • Ah I didn't notice that one. – user202729 Jun 18 '22 at 12:17