9

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.

enter image description here

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}
    \schoolheader
    \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}}
%----------------------------------------------------------------------------------
%                               Header
%----------------------------------------------------------------------------------
\newcommand{\schoolheader}{%
    \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.

Werner
  • 603,163
azetina
  • 28,884

1 Answers1

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

\NewDocumentCommand{\schoolheader}{ }
 {
  \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}

\schoolheader

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

enter image description here

Comments

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.

egreg
  • 1,121,712
  • 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
  • I presumed that was the right interpretation and N is the type of input right? – azetina Feb 10 '14 at 23:13
  • @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
  • Wonderful. Your contribution to my understanding has been very helpful. I always wondered how you achieved such mastery of LaTeX and LaTeX 3. But I will study and review your MWE and also read on LaTeX 3. I guess those will be my new types of questions. Its time for me to break off from the norm :-) – azetina Feb 10 '14 at 23:30
  • I don't think you need the comma after assessmenttitle .initial:n = ?Assessment~Title?. – azetina Feb 12 '14 at 15:30
  • @azetina No, that's not needed, but I always put one, so I don't forget it in case I add some other key definition. – egreg Feb 12 '14 at 15:32