# Working with keys instead of \def

I have looked around on TeX.SX and I have learnt a lot of things. One of the things I have not yet mastered is how to use the key=value function that packages like keyval or xkeyval offer or even pgfkeys. Here is a MWE with the style I designed last year based on something I read online, can't remember where.

MWE

\documentclass{article}
\usepackage{tmpsty}
\university{University Name}
\department{Department Name}
\coursetitle{Course Name}
\coursecode{Course Code}
\coursesession{Semester Running}
\assessmenttitle{Assessment Title}
\begin{document}
\course
sample test
\end{document}


Syle File Used

\NeedsTeXFormat{LaTeX2e}

\ProvidesPackage{tmpsty}[2013/09/24 Standard Style File For Assessments At SHJC]
\RequirePackage[T1]{fontenc}
\RequirePackage[latin9]{inputenc}
\RequirePackage[letterpaper,tmargin=2cm,bmargin=2cm,lmargin=2.5cm,rmargin=2.5cm]{geometry}
\RequirePackage{amsmath,amssymb,amsfonts}
\RequirePackage{booktabs,array}
\RequirePackage[dvipsnames,table]{xcolor}
\RequirePackage{graphicx}
\RequirePackage{mwe}
%----------------------------------------------------------------------------------
%                               Some Definitions
%----------------------------------------------------------------------------------
\def\university#1{\gdef\@university{#1}}
\def\department#1{\gdef\@department{#1}}
%
\def\coursetitle#1{\gdef\@coursetitle{#1}}
\def\coursecode#1{\gdef\@coursecode{#1}}
\def\coursesection#1{\gdef\@coursesection{#1}}
%
\def\coursesession#1{\gdef\@coursesession{#1}}
\def\assessmenttitle#1{\gdef\@assessmenttitle{#1}}
%----------------------------------------------------------------------------------
%----------------------------------------------------------------------------------
\global\let\university\@empty
\global\let\department\@empty
\global\let\coursetitle\@empty
\global\let\coursecode\@empty
\global\let\coursesection\@empty
\global\let\coursesession\@empty
\global\let\assessmenttitle\@empty
%
\global\let\university\relax
\global\let\department\relax
\global\let\coursetitle\relax
\global\let\coursecode\relax
\global\let\coursesection\relax
\global\let\coursesession\relax
\global\let\assessmenttitle\relax
%
\begin{center}
\begin{tabular}{>{\raggedright}m{2.65cm}>{\centering}m{10cm}>{\raggedleft}m{2.65cm}}
%\includegraphics[scale=0.22]{example-image}
&
\textbf{\LARGE\@university}\par\vskip5pt%
{\Large\bfseries\@department}%
&
\includegraphics[scale=0.22]{example-image}
\end{tabular}
\end{center}
%
}
%----------------------------------------------------------------------------------
%                               Assessment Information
%----------------------------------------------------------------------------------
\newcommand{\course}{%
\begin{center}
\textbf{%
\@coursetitle\ (\@coursecode)\\
\@coursesession\\
\@assessmenttitle%
}
\end{center}%
}
\newcommand{\handout}{%
\begin{center}
\textbf{%
\@coursetitle\ (\@coursecode)\\[1.5ex]
\@assessmenttitle%
}
\end{center}%
}
%----------------------------------------------------------------------------------%
%                               End of File                                        %
%----------------------------------------------------------------------------------%
\endinput


I know that it is a common understanding that using \def is a bad practice and that \newcommand is better but am willing to accept suggestions on how to tweak or achieve the definitions stated in the tmpsty.sty file in a different way or more importantly how to use the key=value style of defining user entries.

-
You should read How to create a command with key values? – Werner Feb 10 '14 at 20:07
@Werner thanks. I will read it and try the suggested ways. :-) – azetina Feb 10 '14 at 20:10

A possible solution with LaTeX3 key-value interface:

## tmpsty.sty

\NeedsTeXFormat{LaTeX2e}

\ProvidesPackage{tmpsty}[2013/09/24 Standard Style File For Assessments At SHJC]
\RequirePackage[letterpaper,tmargin=2cm,bmargin=2cm,lmargin=2.5cm,rmargin=2.5cm,showframe]{geometry}
\RequirePackage{amsmath,amssymb,amsfonts}
\RequirePackage{booktabs,array}
\RequirePackage[dvipsnames,table]{xcolor}
\RequirePackage{graphicx}
\RequirePackage{xparse}

\ExplSyntaxOn
\keys_define:nn { tmpsty }
{
university .tl_gset:N = \g_tmpsty_university_tl,
department .tl_gset:N = \g_tmpsty_department_tl,
coursetitle .tl_gset:N = \g_tmpsty_coursetitle_tl,
coursecode .tl_gset:N = \g_tmpsty_coursecode_tl,
coursesection .tl_gset:N = \g_tmpsty_coursesection_tl,
coursesession .tl_gset:N = \g_tmpsty_coursesession_tl,
assessmenttitle .tl_gset:N = \g_tmpsty_assessmenttitle_tl,
university .initial:n = ?University?,
department .initial:n = ?Department?,
coursetitle .initial:n = ?Title?,
coursesection .initial:n = ?Section?,
coursesession .initial:n = ?Session?,
assessmenttitle .initial:n = ?Assessment~Title?,
}

\NewDocumentCommand{\documentdata}{ m }
{
\keys_set:nn { tmpsty } { #1 }
}

{
\begin{center}
\setlength{\tabcolsep}{0pt}
\begin{tabular}{
m{2.5cm}
>{\centering}m{ \dim_eval:n { \textwidth - 5cm } }
m{2.5cm}
}
\includegraphics[width=\linewidth]{example-image}
&
\textbf{ \LARGE \g_tmpsty_university_tl } \\[5pt]
\textbf{ \Large \g_tmpsty_department_tl }
&
\includegraphics[width=\linewidth]{example-image}
\end{tabular}
\end{center}
}

\NewDocumentCommand{\course}{ }
{
\begin{center}
\bfseries
\g_tmpsty_coursetitle_tl \ ( \g_tmpsty_coursecode_tl )\\
\g_tmpsty_coursesession_tl \\
\g_tmpsty_assessmenttitle_tl
\end{center}
}
\NewDocumentCommand{\handout}{ }
{
\begin{center}
\bfseries
\g_tmpsty_coursetitle_tl \ ( \g_tmpsty_coursecode_tl )\\[1.5ex]
\g_tmpsty_assessmenttitle_tl
\end{center}
}
\ExplSyntaxOff
\endinput


I have removed the calls to inputenc and fontenc; the former, in particular, should never be placed in a package or class, as it limits usage. I've also simplified the typesetting of the header.

For testing purposes I added the showframe option to geometry, remove it in a production version.

## test.tex

\documentclass{article}
\usepackage{tmpsty}

\documentdata{
university=University Name,
department=Department Name,
coursetitle=Course Name,
coursecode=Course Code,
%  coursesession=Semester Running,
assessmenttitle=Assessment Title
}
\begin{document}

\course

sample test

\end{document}


You can see that the missing (commented out) element makes LaTeX printing “?Session?”. It would be possible to also issue a warning or an error message.

There's nothing bad in your approach; using \def is not to be considered evil, per se; the main problem is that commands so defined could conflict with others defined by packages you load. This is surely avoided by using a key-value interface: only the main command for collecting the data has to be defined in a possibly conflicting way; I chose \documentdata, which is probably safe. In any case, \NewDocumentCommand would raise an error.
Most impressive! I am so happy to see a MWE that I can expand on. I appreciate the comments as well. I am still learning LaTeX 3 programming so it will take me a while to grasp what .tl_gset:N represents piece by piece. Thanks for your kind contribution. – azetina Feb 10 '14 at 23:04
@azetina key .tl_gset:N = \g_x_y_tl is a shorthand that means: globally define the token list variable \g_x_y_tl to the value given to key (when keys are evaluated). – egreg Feb 10 '14 at 23:10
@azetina Yes, in this case the expected input after = in the key definition: a single token. For .initial:n a token list is expected, which is then loaded in the variable previously defined as the initial value; braces are not necessary, unless a comma is needed in the argument. – egreg Feb 10 '14 at 23:17