我想简化一个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 个参数,它就会填充值。
你能帮我把它做成 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}