使用键代替 \def

使用键代替 \def

我浏览了 TeX.SX,学到了很多东西。我还没有掌握的一件事是如何使用key=value软件包提供的功能,例如keyvalxkeyval甚至pgfkeys。这是一个 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}

使用的 Style 文件

\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

我知道,人们普遍认为使用\def是一种不好的做法,这样\newcommand做更好,但我愿意接受关于如何tmpsty.sty以不同方式调整或实现​​文件中所述的定义,或者更重要的是如何使用key=value定义用户条目的样式的建议。

答案1

使用 LaTeX3 键值接口的可能解决方案:

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

inputenc我删除了对和 的调用fontenc;特别是前者,永远不应放在包或类中,因为它会限制使用。我还简化了标题的排版。

为了测试目的,我添加了showframe选项geometry,并在生产版本中将其删除。

测试.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}

您可以看到,缺失的(注释掉的)元素使 LaTeX 打印“?Session?”。还可能发出警告或错误消息。

在此处输入图片描述

评论

你的方法没有什么不好;使用\def并不被认为是邪恶的,本身;主要问题是,这样定义的命令可能会与您加载的包中定义的其他命令发生冲突。使用键值接口肯定可以避免这种情况:只有用于收集数据的主要命令必须以可能冲突的方式定义;我选择了\documentdata,这可能是安全的。无论如何,\NewDocumentCommand都会引发错误。

相关内容