将宏从序言转换为 cls 文件

将宏从序言转换为 cls 文件

我想简化一个cls文件,希望您能给我一些指点。

我是如何到达这一点的

几年前,我从不同的地方找到了几个论文 cls 文件,并将它们调整为可供我们学生使用的模板。其中一个模板使用了一种在我看来很冗长的编码风格,我正在尝试调整和简化类文件,而不会导致作者不得不修改他们的序言。

我无法使用xparse它,用户界面必须保持原样。

我们现在所拥有的东西是可行的,但对我来说却显得很麻烦。

作者可以在标题页中插入最多 5 个前几度。我们让作者在序言中写

\priorcreds{BA, 1999}{MA, 2004}{MS, 2004}{}{}

需要空白{}是因为cls文件是固定的。它需要输入 5 个可能的先前度数。这是必需的,因为文件cls有这个部分,将每个输入转换为 5 个变量之一

\def\@priorcreda{\@latex@warning{No prior credential information given}}
\def\priorcreds#1#2#3#4#5{
\renewcommand\@priorcreda{#1}
\newcommand\@priorcredb{#2}
\newcommand\@priorcredc{#3}
\newcommand\@priorcredd{#4}
\newcommand\@priorcrede{#5}
}

然后,一个新命令会找到这些命名变量并将它们编织在一起

\newcommand\@priorcredsshow{
\begin{center}
\ifx\@priorcreda\@empty
\relax
\else
\vskip 0.25em
{\small \@priorcreda} \par
\fi% 
\ifx\@priorcredb\@empty
\relax
\else
\vskip 0.25em
{\small \@priorcredb} \par
\fi% 
\ifx\@priorcredc\@empty
\relax
\else
\vskip 0.25em
{\small \@priorcredc} \par
\fi% 
\ifx\@priorcredd\@empty
\relax
\else
\vskip 0.25em
{\small \@priorcredd} \par
\fi% 
\ifx\@priorcrede\@empty
\relax
\else
\vskip 0.25em
{\small \@priorcrede} \par
\fi% 
\end{center}
}

然后在这个\renewcommand{\maketitle}部分里,先前的信用被拉进了标题页

{{\small \@priorcredsshow} \par}

这看起来很乏味,因为用户必须填写空参数{}
,而且由于所有这些剪切和粘贴的代码,编辑 cls 文件也很乏味。

基于 \@ifnextchar 的替代方案

我四处寻找替代方案,找到了一个合理的想法。这篇文章可以接受可变数量参数的命令演示 \@ifnextchar 处理用户输入激起了我的好奇心。我制作了一个 mre,其中魔法\@ifnextchar在序言中,宏调用在文档中。

\documentclass{article}

\makeatletter
\newcommand{\showpriorcreds}[1]{%
 \vskip 0.24em%
{\begin{center}\small{}#1\par\end{center}}\checknextarg}
\newcommand{\checknextarg} {\@ifnextchar\bgroup{\gobblenextarg}{}}
\newcommand{\gobblenextarg}[1]{
\vskip 0.24em
{\begin{center}\small{}#1\par\end{center}}\@ifnextchar\bgroup{\gobblenextarg}{}}%


\begin{document}

Here's an example of showpriorcreds
\showpriorcreds{BA}{BS}{ABC}{PhD}

That was the previous example

\showpriorcreds{MD}{ABD}{DPHIL}{ACC}

\end{document}

输出就是我想要的。它非常灵活,因此如果作者只输入 1 个参数或 5 个参数,它就会填充值。 \@ifnextchar 的用法

你能帮我把它做成 cls 文件吗?

现在我想知道以下内容。我可以将类似的函数放入 cls 文件中吗?我正在仔细阅读指南,但我不明白一些基本的东西。我希望结果是,用户在 PREAMBLE 中插入

\priorcreds{MD}{ABD}{DPHIL}{ACC}

然后 cls 文件会将该信息放入标题页设置中。这应该与标准类文件中使用 \@author 或 \@title 的方式相同,本例的不同之处在于传入的参数是一系列值。

这里面有好几部分我都搞不懂,我的最小类文件甚至连一个合理的文档都没有。我无法理解用户前言中的信息是如何{MD}{ABD}{DPHIL}{ACC}传递到类结构中的,以便\priorcredshow函数可以在标题页中间使用。

我第二次使用 cls 文件的原因是

\documentclass{kuexample}

\makeatletter
\author{Paul J}
\title{Monstrously Awesome}
\priorcreds{BA}{BS}{ABC}{PhD}

\begin{document}

This is the document body
% it compiles if I put call in body of document
% but i never get title page
%%\priorcreds{BA}{BS}{ABC}{PhD}
\end{document}

我的小类文件明显是错误的

% kuexample

%-------------------------- identification ---------------------
\NeedsTeXFormat{LaTeX2e}
\ProvidesClass{kuexample}[2018/03/29 kuexample]
%-------------------------- initial code -----------------------
\DeclareOption*{\PassOptionsToClass{\CurrentOption}{report}}
\ProcessOptions\relax
\LoadClass[letterpaper]{report}
% As an alternative to the above could use next line for twosided output
%\LoadClass[letterpaper,twoside,openright]{report}

\raggedbottom

%% PACKAGE REQUIREMENTS %%

%% Required to set margins
\RequirePackage{geometry}

%
% DECLARATIONS

%%priorcreds adaptation 20180328
\newcommand{\priorcreds}[1]{%
\vskip 0.24em%
{\begin{center}\small{}#1\par\end{center}}\checknextarg}
\newcommand{\checknextarg} {\@ifnextchar\bgroup{\gobblenextarg}{}}
\newcommand{\gobblenextarg}[1]{%
\vskip 0.24em%
{\begin{center}\small{}#1\par\end{center}}\@ifnextchar\bgroup{\gobblenextarg}{}}


\newcommand\@priorcredshow{
  \@priorcreds
}

% Define text area of page and margin offsets
%
\setlength{\topmargin}{0.0in}
\setlength{\oddsidemargin}{0.33in}
\setlength{\evensidemargin}{-0.08in}
\setlength{\textheight}{9.0in}
\setlength{\textwidth}{6.0in}

%
% Environments
%

% This macro defines an environment for front matter that is always 
% single column even in a double-column document.

\newenvironment{alwayssingle}{%
       \@restonecolfalse
       \if@twocolumn\@restonecoltrue\onecolumn
       \else\if@openright\cleardoublepage\else\clearpage\fi
       \fi}%
       {\if@restonecol\twocolumn
       \else\newpage\thispagestyle{empty}\fi}

%define title page layout
\renewcommand{\maketitle} {%
\begin{alwayssingle}
  \begin{singlespace} 
    \renewcommand{\footnotesize}{\small}
    \renewcommand{\footnoterule}{\relax}
    \thispagestyle{empty}
  \null\vfill
  \begin{center}
    {\Large {\bfseries {\@title}} \par}
  \vskip 1.5em%
    {{\Large \@author} \par}
  \vskip 0.5em%
     {\@priorcredshow}
\vfill

  \setcounter{footnote}{0}%
  \global\let\thanks\relax
  \global\let\maketitle\relax
  \global\let\@maketitle\relax
  \global\let\@author\@empty
  \global\let\@date\@empty
  \global\let\@title\@empty
  \global\let\title\relax
  \global\let\author\relax
  \global\let\date\relax
  \global\let\and\relax
\end{singlespace}
\end{alwayssingle}}

答案1

界面是非常很尴尬。如果先前的凭证数量超过五个怎么办?

但是,您可以使用 来实现\@ifnextchar

kuexample.cls

\NeedsTeXFormat{LaTeX2e}
\ProvidesClass{kuexample}[2018/03/29 kuexample]
%-------------------------- initial code -----------------------
\DeclareOption*{\PassOptionsToClass{\CurrentOption}{report}}
\ProcessOptions\relax
\LoadClass[letterpaper]{report}
% As an alternative to the above could use next line for twosided output
%\LoadClass[letterpaper,twoside,openright]{report}

\RequirePackage{setspace}

\raggedbottom

%% PACKAGE REQUIREMENTS %%

%% Required to set margins
\RequirePackage{geometry}

%
% DECLARATIONS

%%priorcreds adaptation 20180328
\def\@priorcreda{\@latex@warning{No prior credential information given}}
\def\@priorcreds@list{} % initialize
\def\priorcreds#{\@priorcreds} % the trailing # requires \priorcreds to be followed by {
\def\@priorcreds#1{\def\@priorcreda{{#1}}\@priorcreds@go}
\def\@priorcreds@go{\@ifnextchar\bgroup{\@priorcreds@add}{}}
\def\@priorcreds@add#1{%
  \ifx\@priorcreds@list\@empty
    \g@addto@macro\@priorcreds@list{{#1}}%
  \else
    \g@addto@macro\@priorcreds@list{,{#1}}%
  \fi
  \@priorcreds@go
}


\newcommand\@priorcredshow{%
  \par{\small
  \@priorcreda % this always exists
  \@for\next:=\@priorcreds@list\do{%
    \par\vspace{0.24em}%
    \next
  \par}}%
  \end{center}
}

% Define text area of page and margin offsets
%
\setlength{\topmargin}{0.0in}
\setlength{\oddsidemargin}{0.33in}
\setlength{\evensidemargin}{-0.08in}
\setlength{\textheight}{9.0in}
\setlength{\textwidth}{6.0in}

%
% Environments
%

% This macro defines an environment for front matter that is always 
% single column even in a double-column document.

\newenvironment{alwayssingle}{%
       \@restonecolfalse
       \if@twocolumn\@restonecoltrue\onecolumn
       \else\if@openright\cleardoublepage\else\clearpage\fi
       \fi}%
       {\if@restonecol\twocolumn
       \else\newpage\thispagestyle{empty}\fi}

%define title page layout
\renewcommand{\maketitle} {%
\begin{alwayssingle}
  \begin{singlespace} 
    \renewcommand{\footnotesize}{\small}
    \renewcommand{\footnoterule}{\relax}
    \thispagestyle{empty}
  \null\vfill
  \begin{center}
    {\Large {\bfseries {\@title}} \par}
  \vskip 1.5em
    {{\Large \@author} \par}
  \vskip 0.5em
     \@priorcredshow
\vfill

  \setcounter{footnote}{0}%
  \global\let\thanks\relax
  \global\let\maketitle\relax
  \global\let\@maketitle\relax
  \global\let\@author\@empty
  \global\let\@date\@empty
  \global\let\@title\@empty
  \global\let\title\relax
  \global\let\author\relax
  \global\let\date\relax
  \global\let\and\relax
\end{singlespace}
\end{alwayssingle}}

kuexample.tex

\documentclass{kuexample}

\begin{document}

\title{Test}
\author{Me}
\priorcreds{MD, 1920}{ABD, 2001}{DPHIL}{ACC}{X}{Y}{Z}{AAA}{BBB}

\maketitle

\end{document}

输出

在此处输入图片描述

评论

语法如下

\priorcreds{{A}{B}{C}{D}}

或者

\priorcreds{A|B|C|D}

会更加友好。

答案2

您可以使用xparse。这只会影响您实现用户界面的方式:它不会破坏向后兼容性。

当前代码的问题在于,在文档尚未开始时,使用序言中的命令会尝试立即排版内容。此外,您的类无法加载setspace(或定义singlespace),并且定义\maketitle无法结束center环境。

此外,您的文档缺少\maketitle,所以标题页从未排版,因为您从未要求 LaTeX 对其进行排版。

这是一个支持您想要的语法、保持向后兼容性并且可以无错误编译的版本。

\begin{filecontents}{kuexample.cls}
\NeedsTeXFormat{LaTeX2e}
\ProvidesClass{kuexample}[2018/03/29 kuexample]
%-------------------------- initial code -----------------------
\DeclareOption*{\PassOptionsToClass{\CurrentOption}{report}}
\ProcessOptions\relax
\LoadClass[letterpaper]{report}
% As an alternative to the above could use next line for twosided output
%\LoadClass[letterpaper,twoside,openright]{report}

\raggedbottom

%% PACKAGE REQUIREMENTS %%

%% Required to set margins
\RequirePackage{geometry,setspace,xparse}

%
% DECLARATIONS

%%priorcreds adaptation 20180328
\newcommand\@showpriorcreds{}
\NewDocumentCommand\priorcreds {mgggg}{%
  \renewcommand\@showpriorcreds{%
    \gobblenextarg{#1}%
    \IfValueT{#2}{\gobblenextarg{#2}}%
    \IfValueT{#3}{\gobblenextarg{#3}}%
    \IfValueT{#4}{\gobblenextarg{#4}}%
    \IfValueT{#5}{\gobblenextarg{#5}}%
  }}
\newcommand{\gobblenextarg}[1]{%
  \vskip 0.24em%
  \begin{center}\small#1\par\end{center}%
}


% Define text area of page and margin offsets
%
\setlength{\topmargin}{0.0in}
\setlength{\oddsidemargin}{0.33in}
\setlength{\evensidemargin}{-0.08in}
\setlength{\textheight}{9.0in}
\setlength{\textwidth}{6.0in}

%
% Environments
%

% This macro defines an environment for front matter that is always 
% single column even in a double-column document.

\newenvironment{alwayssingle}{%
  \@restonecolfalse
  \if@twocolumn\@restonecoltrue\onecolumn
  \else\if@openright\cleardoublepage\else\clearpage\fi
  \fi
}{%
  \if@restonecol\twocolumn
  \else\newpage\thispagestyle{empty}\fi
}

%define title page layout
\renewcommand{\maketitle} {%
  \begin{alwayssingle}
    \begin{singlespace} 
      \renewcommand{\footnotesize}{\small}
      \renewcommand{\footnoterule}{\relax}
      \thispagestyle{empty}
      \null\vfill
      \begin{center}
        {\Large\bfseries\@title\par}
        \vskip 1.5em%
        {\Large\@author}\par
        \vskip 0.5em%
        \@showpriorcreds
        \vfill

        \setcounter{footnote}{0}%
        \global\let\thanks\relax
        \global\let\maketitle\relax
        \global\let\@maketitle\relax
        \global\let\@author\@empty
        \global\let\@date\@empty
        \global\let\@title\@empty
        \global\let\title\relax
        \global\let\author\relax
        \global\let\date\relax
        \global\let\and\relax
      \end{center}
    \end{singlespace}
  \end{alwayssingle}}
\endinput
\end{filecontents}
\documentclass{kuexample}

\makeatletter
\author{Paul J}
\title{Monstrously Awesome}
\priorcreds{BA}{BS}{ABC}{PhD}

\begin{document}
\maketitle

This is the document body

\end{document}

拥有学位的 Paul J 尝试第五次

相关内容