LaTeX
\makeatletter 和 \makeatother
如果你做了一些 LaTeX 编程,可能遇到过这两个命令:\makeatletter
和 \makeatother
。
在 TeX 中,@
字符默认属于 catcode 11 类别。这意味着你可以将它用作宏名称。LaTeX 利用这个 catcode 规则来规定:所有不希望用户访问的内部宏,其名称中至少包含一个 @
字符。在文档中,LaTeX 会将 @
的 catcode 改为 12。
因此,当你需要访问 LaTeX 内部宏时,必须将所有访问私有函数的命令放在 \makeatletter
和 \makeatother
之间。它们仅在常规文档中有意义,在包或类文件中不需要。
\documentclass{...}
% ...
\begin{document}
\makeatletter
\@author
\makeatother
\end{document}
创建你自己的包
你的包可以像其他任何包一样在文档中使用,方法是使用 \usepackage
命令。编写包基本上是将文档前言中的内容复制到一个以 .sty
结尾的独立文件中。
下面是一个简单的 custom.sty
文件,作为示例包:
\NeedsTeXFormat{LaTeX2e}[1994/06/01]
\ProvidesPackage{custom}[2013/01/13 Custom Package]
\RequirePackage{lmodern}
%% 'sans serif' 选项
\DeclareOption{sans}{
\renewcommand{\familydefault}{\sfdefault}
}
%% 'roman' 选项
\DeclareOption{roman}{
\renewcommand{\familydefault}{\rmdefault}
}
%% 全局缩进选项
\newif\if@neverindent\@neverindentfalse
\DeclareOption{neverindent}{
\@neverindenttrue
}
\ExecuteOptions{roman}
\ProcessOptions\relax
%% LaTeX 或 TeX 之后的代码
% ...
\newlength{\pardefault}
\setlength{\pardefault}{\parindent}
\newcommand{\neverindent}{ \setlength{\parindent}{0pt} }
\newcommand{\autoindent}{ \setlength{\parindent}{\pardefault} }
\if@neverindent
\neverindent
\fi
% ...
\endinput
解释:
-
\NeedsTeXFormat{...}
指定至少需要的 TeX 或 LaTeX 版本来运行此包。可选的日期用于更精确地指定版本。 -
\ProvidesPackage{<name>}[<version>]
通过该命令包声明自己,<name>
应与文件本身的基名一致,<version>
应使用YYYY/MM/DD
格式的日期。 -
\RequirePackage
等同于\usepackage
。 -
\DeclareOption
是定义的用户参数。 -
\ExecuteOptions{...}
设定默认选项。 -
\ProcessOptions\relax
结束选项处理。
一旦包准备好,我们可以在任何文档中使用它。只需通过 \usepackage{mypack}
导入新包。确保 custom.sty
文件与正在编译的 LaTeX 源文件在同一目录。
\documentclass{...}
\usepackage[neverindent,sans]{custom}
% ...
\begin{document}
Blah...
\end{document}
对于更方便的使用,可以将包放置在 $TEXMFHOME
(默认是 ~/texmf
)目录下,符合 TeX 目录结构(TDS)。文件路径为:
$TEXMFHOME/tex/latex/custom/custom.sty
在 Windows 上,~
通常是 C:\Users\username
。
你可能需要运行 texhash
(或等效命令)以使 TeX 分发版索引新文件,从而使其在任何文档中可用。这使得你可以像上面那样使用包,而不必将包放在文档的同一目录中。
创建你自己的类文件
你也可以创建自己的类文件。这个过程与创建包类似,你可以通过在文档前言中调用自定义类文件:
\documentclass{myclass}
类文件的名称将是 myclass.cls
。我们来写一个简单的例子,使用之前定义的 custom.sty
:
\NeedsTeXFormat{LaTeX2e}
\ProvidesClass{myclass}[2011/12/23 My Class]
%% 文章选项
\DeclareOption{10pt}{
\PassOptionsToClass{\CurrentOption}{article}
}
%% 自定义包选项
\DeclareOption{sans}{
\PassOptionsToPackage{\CurrentOption}{custom}
}
\DeclareOption{neverindent}{
\PassOptionsToPackage{\CurrentOption}{custom}
}
%% 回退
\DeclareOption*{
\ClassWarning{myclass}{Unknown option '\CurrentOption'}
}
%% 执行默认选项
\ExecuteOptions{10pt}
%% 处理给定选项
\ProcessOptions\relax
%% 加载基础类
\LoadClass[a4paper]{article}
%% 加载其他包和命令
\RequirePackage{custom}
%% 额外的 TeX/LaTeX 代码...
\endinput
解释:
-
\ProvidesClass
是\ProvidesPackage
的对应命令。 -
\PassOptionsToClass
和\PassOptionsToPackage
用于在加载类或包时自动传递相应的选项。 -
\DeclareOption*
允许处理未实现的选项。 -
\ClassWarning
会在 TeX 编译器输出中显示相应的消息。 -
\LoadClass
指定唯一的父类(如果有)。
钩子
类和包也有钩子:
\AtEndOfPackage
\AtEndOfClass
它们与文档钩子类似。详细信息请参见 LaTeX Hooks。