我正在编写一个使用该类的模板report
,并使用多个包自定义排版。我在一个单独的user-data.tex
文件中定义一些数据,该文件在之后加载documentclass
:
\def\thesis{Master} %<PhD> or <Master>
\def\thesistitle{The title of the thesis}
\def\author{AName AFirst ASecond}
\def\authormail{[email protected]}
\def\school{Master and Doctoral School}
\def\date{City, month year}
\def\logo-university{univ.pdf}
这些变量/常量用于提供两个不同的标题页,包含在页脚中titlesec
,或由用户随时使用。
这样可以吗(只使用\def
)?还是我应该使用\global
, \newcommand
... 或任何其他格式?除了普通格式,您还会将它们放置在任何其他格式中吗tex
?
根据评论,我修改\newcommand*
并重命名了一些宏:
\newcommand*\thesis{Master} %<PhD> or <Master>
\newcommand*\thesistitle{The title of the thesis}
\newcommand*\authors{AName AFirst ASecond}
\newcommand*\authorsmail{[email protected]}
\newcommand*\school{Master and Doctoral School}
\newcommand*\titledate{City, month year}
\newcommand*\university{univ.pdf}
在@Andrew回答之后,我正在使用
\providecommand*\@school{No SCHOOL defined}
\newcommand*\School[1]{\renewcommand*\@school{#1}}
就在包的开始处,让用户\newcommand*\@school{Something}
在加载之前或\School{Something}
加载之后进行定义。
正如 @barbara 猜测的那样,我将模板移动到了*.sty
作为包加载的位置:
软件包
\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{mypkg}
%If not previously defined, default value applied
\providecommand*{\@mythesis}{No THESIS TYPE defined}
\providecommand*{\@myauthor}{No AUTHOR defined}
%Command to modify the field at any point after this
\newcommand*\MyThesis[1]{\renewcommand*\@mythesis{#1}}
\newcommand*\MyAuthor[1]{\renewcommand*\@myauthor{#1}}
%Command to access the field
\newcommand*\showDF[1]{\csname @#1\endcsname}
%The content may be supplied in a separate file with \Thesis
\@input{data.dat}
\endinput
主文本
\documentclass[a4paper,titlepage,11pt,twoside,openright]{report}
% A field may defined before loading the package
\makeatletter
\newcommand\@mythesis{My title before loading}
\makeatother
%If it not defined, the package does it
\usepackage{mypkg}
\begin{document}
% The variable may be directly accessed
\makeatletter\@mythesis\makeatother
% The content may be rewritten
\MyThesis{PhD}
% Reading with the provided command
\showDF{mythesis}
\showDF{myauthor}
\end{document}
可以。用户可以在加载包之前定义内容,也可以在单独的文件中定义,或者在加载包之后的任何时间使用“辅助命令”定义。但是,我想:
-使用命令自动定义与字段关联的命令。新问题这里。
- 让用户能够在加载包时将字段作为选项。我尝试过xkeyval
:
\define@key{fam}{thesis}[Master]{\Thesis{#1}}
\ProcessOptionsX<fam>
将主文件中的加载更改为:
\usepackage[thesis=PhD]{mypkg}
上述代码可以正常工作,但对于包含多个单词的字段除外,因为它们之间的空格已被删除。我该如何让它与 一起使用,即\usepackage[title=A title with several words]{mypkg}
。我尝试过 和{A title with several words}
,"A title with several words"
但它不起作用。
使用方法这答案,我现在有这个“工厂”功能来一次创建所有命令:
\usepackage{etoolbox}
\newcommand\forcsvlistargs[2]{ \expandafter\providecommand\csname \detokenize{#1}aux\endcsname[1]{
\csname \detokenize{#1}\endcsname##1\relax}
\forcsvlist{\csname \detokenize{#1}aux\endcsname}{#2}
}
\newcommand\newDF[2]{ \expandafter\providecommand\csname th#1\endcsname{No \MakeUppercase{#2} defined}
\expandafter\newcommand\csname TH#2\endcsname[1]{\expandafter\renewcommand\csname th#1\endcsname{##1}} }
\forcsvlistargs{newDF}{{{typ}{type}}, {{date}{date}}, {{tit}{title}}, {{sch}{school}},
{{aut}{author}}, {{eaut}{eauthor}} }
答案1
我有一些(内部)类可以执行类似这样的操作。我首先要定义一个命令,如下所示:
\newcommand\School[1]{\def\@school{#1}}
以便“用户”可以使用它\School{My wonderful school}
来覆盖默认值。在内部,该类\@school
在需要打印学校名称时使用它。
接下来,如果这是合理的,我会让班级为学校设置一个合理的默认值,如下所示
\School{My Wonderful School}
在课堂上。事实上,更好的形式可能是使用
\providescommand\@school{My Wonderful School}
尽管我认为使用“辅助命令”更清晰。
我使用这种方法的一个地方是教程表,其中许多变量都依赖于其他变量。对于这些情况,我为类定义了一个选项,用于一次性设置所有这些变量。因此,“用户”以以下方式开始他们的文件
\documentclass[somecourse,solutions]{mytutorials}
然后里面mytutorials.cls
我有
\DeclareOption{somecourse}{
\CourseName{An exciting counrse}
\Semester{Semester 2}
\CourseNumber{Math 987123}
}
\DeclareOption{solutions}{
...
}
要处理所有选项,您需要类似以下内容:
\DeclareOption*{\PassOptionsToClass{\CurrentOption}{article}}
\ProcessOptions
这使得我可以搭载article.cls
并传递文件中未定义的选项。
最后,根据您的用例,您可能希望自动从当前目录中的文件中加载一组默认值。如果您使用\include
或,\input
那么当文件不存在时,您将遇到问题。相反,您可以在类文件中使用\@input
:
\@input{defaults.dat}
如果文件“defaults.dat”存在,则加载该文件,否则不执行任何操作。此文件将按原样包含,因此使用此技巧存在危险,因为如果文件包含垃圾,则一切都会中断。当然,为了涵盖此文件不存在的情况,您需要设置合理的默认值。
(顺便说一句,对于您自己的内部变量,使用它们确实没有坏处\def
——而且也更容易。当然,您应该首先确保您没有覆盖其他任何东西!)