%%% ==================================================================== %%% @LaTeX-file{ %%% author = "Scott Pakin", %%% version = "2.4", %%% date = "21 January 2024", %%% time = "16:37:48 PM MST", %%% filename = "dtxtut.tex", %%% checksum = "42847 2059 7542 69980" %%% email = "scott+dtx@pakin.org (Internet)", %%% codetable = "ISO/ASCII", %%% keywords = "LaTeX, packages, .ins files, .dtx files, %%% literate programming", %%% supported = "yes", %%% abstract = "This tutorial is intended for advanced %%% LaTeX 2e users who want to learn how to %%% create .ins and .dtx files for distributing %%% their homebrewed classes and style files.", %%% docstring = "The checksum field above contains a CRC-16 %%% checksum as the first value, followed by %%% the equivalent of the standard UNIX wc %%% (word count) utility output of lines, %%% words, and characters. This is produced by %%% Robert Solovay's checksum utility. This file %%% header was produced with the help of Nelson %%% Beebe's filehdr utility. Both checksum and %%% filehdr are available from CTAN %%% (http://www.ctan.org)." %%% %%% } %%% ==================================================================== \documentclass[11pt]{ltxguide} \usepackage{varioref} \usepackage{makeidx} \usepackage{alltt} \usepackage{tocbibind} \usepackage{upquote} \usepackage{microtype} \usepackage[bookmarksopen]{hyperref} \usepackage{hyperxmp} % Define this document's metadata. \title{How to Package Your \LaTeX{} Package} \author{Scott Pakin \texttt{}} \date{21 January 2024} \hypersetup{% pdftitle={How to Package Your LaTeX Package}, pdfauthor={Scott Pakin}, pdfcontactemail={scott+dtx@pakin.org}, pdfcontacturl={http://www.pakin.org/\xmptilde scott}, pdfsubject={Writing .ins and .dtx files for LaTeX}, pdfkeywords={LaTeX package documentation, literate programming, typesetting, installer files}, pdfcaptionwriter={Scott Pakin}, pdfcopyright={Copyright (C) 2015-2024 Scott Pakin}, pdflicenseurl={http://latex-project.org/lppl/}, pdflang={en-US} } % Define a term. \newcommand{\defn}[2][X]{% \ifx#1X \emph{#2}\index{#2}% \else \emph{#2}\index{#1}% \fi } % Make a version of \dots that allows a subsequent line break. \newcommand{\dotsbrk}{\dots\linebreak[0]} % If we have url.sty loaded, use that for formatting URLs. \ifx\url\undefined \else \let\URL=\url \fi % Define formatting for various packages. \newcommand{\DOC}{\textsf{Doc}\index{Doc@\textsf{Doc}}} \newcommand{\ds}{\textsf{DocStrip}\index{DocStrip@\textsf{DocStrip}}} \newcommand{\svrb}{\texttt{shortvrb}\index{shortvrb@\texttt{shortvrb}}} % Customize varioref's messages. \def\reftextbefore{on the preceding page} \def\reftextfacebefore{on the preceding page} \def\reftextcurrent{above} % We promise not to make any forward references. % Define some macros to help automate indexing. \makeindex {\catcode`\|=0 \catcode`\\=12 |gdef|bslash{\}} \newcommand{\defmacro}[1]{% % Define a macro. \texttt{\bslash#1}% \index{#1@\texttt{\string\bslash{}#1}}% } \newcommand{\usemacro}[1]{% % Use a macro. \texttt{\bslash#1}% \index{#1@\texttt{\string\bslash{}#1}}% } \newcommand{\indexmacro}[1]{% % Index a macro (no display). \index{#1@\texttt{\string\bslash{}#1}}% } {\catcode`\|=12 % Same as \indexmacro, but \gdef\indexmacroBegin#1{% % for ranges of text \index{#1@\texttt{\string\bslash{}#1}|(}% } \gdef\indexmacroEnd#1{% \index{#1@\texttt{\string\bslash{}#1}|)}% } } \newcommand{\defthing}[1]{% % Define a non-macro thing. \texttt{#1}% \index{#1@\texttt{#1}}% } \newcommand{\usething}[1]{% % Use a non-macro thing. \texttt{#1}% \index{#1@\texttt{#1}}% } \newcommand{\indexthing}[1]{% % Index a non-macro thing. \index{#1@\texttt{#1}}% } {\catcode`\|=12 % Same as \indexthing, but \gdef\indexthingBegin#1{% % for ranges of text \index{#1@\texttt{#1}|(}% } \gdef\indexthingEnd#1{% \index{#1@\texttt{#1}|)}% } } % Define shortcuts to index commonly used terms. \newcommand{\insfile}{% \texttt{.ins}\index{installer file}} \newcommand{\dtxfile}{% \texttt{.dtx}\index{documented LaTeX file@documented \string\LaTeX{} file}} \newcommand{\styfile}{% \texttt{.sty}\index{style file}} \newcommand{\clsfile}{% \texttt{.cls}\index{class file}} \newcommand{\CTAN}{% CTAN\index{Comprehensive \string\TeX{} Archive Network}} \newcommand{\swiftexel}{% \texttt{swiftex.el}\index{swiftex.el@\texttt{swiftex.el}}} \newcommand{\Emacs}{% Emacs\index{Emacs}} \newcommand{\latex}[1][\LaTeX]{% #1\index{LaTeX@\LaTeX}} % Prohibit TeX from splitting footnotes across pages. \interfootnotelinepenalty=10000 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \begin{document} \sloppy \maketitle \begin{abstract} This tutorial is intended for advanced \latex[\LaTeXe]{} users who want to learn how to create \insfile{} and \dtxfile{} files for distributing their homebrewed classes and style files. \end{abstract} \section{Introduction} \paragraph{Requirements} We assume that you already know how to \emph{program} in \latex\@. That is, you should know how to use \usemacro{newcommand}, \usemacro{newenvironment}, and preferably a smidgen of \TeX\@. You should also be familiar with ``\clsguide'', which is available from \CTAN{} (\URL{http://www.ctan.org}) and comes with most \latex[\LaTeXe]{} distributions in a file called |clsguide.pdf|. Finally, you should know how to install packages\index{package} that are shipped as a \dtxfile{} file plus a \insfile{} file. \paragraph{Terminology} \index{class file|(} A \defn[class file]{class \textnormal{(\clsfile{})} file} specifies a document's basic formatting: text block size and positioning on the page, typesetting of structural elements such as \verb|\section|, header and footer style, etc. Exactly only class file is used in a single document (with \usemacro{documentclass}). \index{class file|)} \index{style file|(} A \defn[style file]{style \textnormal{(\styfile{})} file} is primarily a collection of macro and environment definitions. Style files can override the class file's formatting decisions, provide new functionality, or change existing functionality. A document can load any number of style files (with \usemacro{usepackage}). \index{style file|)} \index{package|(} One or more class or style files (\eg a main style file that uses \usemacro{input} or \usemacro{RequirePackage} to load multiple helper files) and their documentation is called a \defn{package}. In the rest of this document, we use the notation ``\m{package}'' to represent the name of your package. Warning: In the \LaTeX\ community, the term ``package'' is sometimes also used to mean ``style file''. You may need to discern from context which definition is being used. \index{package|)} \paragraph{Motivation} The important parts of a package\index{package} are the code, the documentation of the code, and the user documentation. Using the \DOC{} and \ds{} programs, it's possible to combine all three of these into a single, \defn[documented LaTeX file@documented \string\LaTeX{} file]{documented \LaTeX \textnormal{(\dtxfile{})} file}. The primary advantage of a \dtxfile{} file is that it enables you to use arbitrary \latex{} constructs to comment\index{comments} your code. Hence, macros, environments, code stanzas, variables, and so forth can be explained using tables, figures, mathematics, and font changes. Code can be organized into sections using \latex's sectioning commands. \index{indexing|(} \DOC{} even facilitates generating a unified index that indexes both macro definitions (in the \latex{} code) and macro descriptions (in the user documentation). \index{indexing|)} This emphasis on writing verbose, nicely typeset comments\index{comments} for code---essentially treating a program as a book that describes a set of algorithms---is known as \defn{literate programming}~\cite{Knuth1984:literate} and has been in use since the early days of \TeX. This tutorial will teach you how to write basic \dtxfile{} files and the \insfile{} files that manipulate them. Although there is much overlap with chapter~14 of \emph{The \latex{} Companion}~\cite{Goossens1994:companion}, this document is structured as a step-by-step tutorial, while \emph{The \latex{} Companion} is more reference-like. Furthermore, this tutorial shows how to write a single file that serves as both documentation and driver file, which is a more typical usage of the \DOC{} system than using separate files. \index{installer file|(} \section{The \texttt{.ins} file} \label{sec:ins-file} The first step in preparing a package for distribution is to write an \defn[installer file]{installer \textnormal{(\insfile{})} file}. An installer file extracts the code from a \dtxfile{} file, uses \ds{} to strip off the comments\index{comments} and documentation, and outputs a \styfile{} file. The good news is that a \insfile{} file is typically fairly short and doesn't change significantly from one package\index{package} to another. \index{license|(} \insfile{} files usually start with comments\index{comments} specifying the copyright\index{copyright} and license information: \begin{verbatim} %% %% Copyright (C) %% %% This file may be distributed and/or modified under the %% conditions of the LaTeX Project Public License, either %% version 1.3 of this license or (at your option) any later %% version. The latest version of this license is in: %% %% http://www.latex-project.org/lppl.txt %% %% and version 1.3c or later is part of all distributions of %% LaTeX version 2008-05-04 or later. %% \end{verbatim} \noindent \index{package|(} The \latex{} Project Public License\index{LaTeX Project Public License@\LaTeX{} Project Public License} (LPPL) is the license under which most packages---and \latex{} itself---are distributed. Of course, you can release your package under any license you want; the LPPL is merely the most common license for \latex{} packages. The LPPL specifies that a user can do whatever he wants with your package---including sell it and give you nothing in return. The only restrictions are that he must give you credit for your work, and he must unambiguously identify modified versions of the code as such to avoid versioning confusion. \index{package|)} \index{license|)} \index{LPPL|see{\LaTeX{} Project Public License}} The next step is to load \ds: \begin{verbatim} \input docstrip.tex \end{verbatim} \indexmacroBegin{keepsilent} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \begin{decl} \defmacro{keepsilent} \end{decl} By default, \ds{} gives a line-by-line account of its activity. These messages aren't terribly useful, so most people turn them off: \begin{verbatim} \keepsilent \end{verbatim} \indexmacroEnd{keepsilent} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \indexmacroBegin{usedir} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \begin{decl} \defmacro{usedir} \arg{directory} \end{decl} A system administrator can specify the base directory under which all \TeX-related files should be installed, \eg |/usr/share/texmf|. (See ``\usemacro{BaseDirectory}'' in the \ds{} manual.) The \insfile{} file specifies where its files should be installed relative to that. The following is typical: \begin{verbatim} \usedir{tex/latex/} \end{verbatim} \indexmacroEnd{usedir} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \indexmacroBegin{preamble} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \indexmacroBegin{endpreamble} \begin{decl} \defmacro{preamble} \\ \m{text} \\ \defmacro{endpreamble} \end{decl} \index{comments|(} The next step is to specify a \defn{preamble}, which is a block of commentary that will be written to the top of every generated file: \begin{verbatim} \preamble This is a generated file. Copyright (C) This file may be distributed and/or modified under the conditions of the LaTeX Project Public License, either version 1.3 of this license or (at your option) any later version. The latest version of this license is in: http://www.latex-project.org/lppl.txt and version 1.3c or later is part of all distributions of LaTeX version 2008-05-04 or later. \endpreamble \end{verbatim} \index{comments|)} \noindent The preceding preamble would cause |.sty|\index{style file} to begin as follows: \begin{verbatim} %% %% This is file `.sty', %% generated with the docstrip utility. %% %% The original source files were: %% %% .dtx (with options: `package') %% %% This is a generated file. %% %% Copyright (C) %% %% This file may be distributed and/or modified under the %% conditions of the LaTeX Project Public License, either %% version 1.3 of this license or (at your option) any later %% version. The latest version of this license is in: %% %% http://www.latex-project.org/lppl.txt %% %% and version 1.3c or later is part of all distributions of %% LaTeX version 2008-05-04 or later. %% \end{verbatim} \indexmacroEnd{endpreamble} \indexmacroEnd{preamble} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \indexmacroBegin{generate} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \indexmacroBegin{file} \indexmacroBegin{from} \begin{decl} \defmacro{generate} |{|\defmacro{file} |{}| |{|\defmacro{from} |{}| |{}}}| \end{decl} We now reach the most important part of a \insfile{} file: the specification of what files to generate from the \dtxfile{} file. The following tells \ds{} to generate |.sty|\index{style file} from |.dtx| by extracting only those parts marked as ``|package|'' in the \dtxfile{} file. (Marking parts of a \dtxfile{} file is described in Section~\ref{sec:dtx-file}.) \label{code:generate} \begin{verbatim} \generate{\file{.sty}{\from{.dtx}{package}}} \end{verbatim}% \index{style file} \noindent \usemacro{generate} can extract any number of files from a given \dtxfile{} file. It can even extract a single file from multiple \dtxfile{} files. See the \ds{} manual for details. \indexmacroEnd{from} \indexmacroEnd{file} \indexmacroEnd{generate} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \indexmacroBegin{Msg} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \begin{decl} \defmacro{Msg} \arg{text} \end{decl} The next part of a \insfile{} file consists of commands to output a message to the user, telling him what files need to be installed and reminding him how to produce the user documentation. The following set of \usemacro{Msg} commands is typical: \begin{verbatim} \obeyspaces \Msg{****************************************************} \Msg{* *} \Msg{* To finish the installation you have to move the *} \Msg{* following file into a directory searched by TeX: *} \Msg{* *} \Msg{* .sty *} \Msg{* *} \Msg{* To produce the documentation run the file *} \Msg{* .dtx through LaTeX. *} \Msg{* *} \Msg{* Happy TeXing! *} \Msg{* *} \Msg{****************************************************} \end{verbatim}% \index{style file}% \indexmacroEnd{Msg} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Note the use of \usemacro{obeyspaces} to inhibit \TeX{} from collapsing multiple spaces into one. \indexmacroBegin{endbatchfile} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \begin{decl} \usemacro{endbatchfile} \end{decl} Finally, we tell \ds{} that we've reached the end of the \insfile{} file: \begin{verbatim} \endbatchfile \end{verbatim} \indexmacroEnd{endbatchfile} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Appendix~\ref{sec:skeleton-ins-file-style} lists a complete, skeleton \insfile{} file. Appendix~\ref{sec:skeleton-ins-file-class} is similar but contains slight modifications intended to produce a class (\clsfile) file instead of a style (\styfile) file. \index{installer file|)} \index{documented LaTeX file@documented \LaTeX{} file|(} \section{The \texttt{.dtx} file} \label{sec:dtx-file} \index{package|(} A \dtxfile{} file contains both the commented source code and the user documentation for the package. Running a \dtxfile{} file through |latex| typesets the user documentation, which usually also includes a nicely typeset version of the commented\index{comments} source code. \index{package|)} Due to some \DOC{} trickery, a \dtxfile{} file is actually evaluated \emph{twice}. The first time, only a small piece of \latex{} driver code is evaluated. The second time, \emph{comments}\index{comments} in the \dtxfile{} file are evaluated, as if there were no ``|%|'' preceding them. This can lead to a good deal of confusion when writing \dtxfile{} files and occasionally leads to some awkward constructions. Fortunately, once the basic structure of a \dtxfile{} file is in place, filling in the code is fairly straightforward. \subsection{Prologue} \index{comments|(} \dtxfile{} files generally begin with a copyright\index{copyright} and license\index{license} comment: \begin{verbatim} % \iffalse meta-comment % % Copyright (C) % % This file may be distributed and/or modified under the % conditions of the LaTeX Project Public License, either % version 1.3 of this license or (at your option) any later % version. The latest version of this license is in: % % http://www.latex-project.org/lppl.txt % % and version 1.3c or later is part of all distributions of % LaTeX version 2008-05-04 or later. % % \fi \end{verbatim} \index{comments|)} \noindent The \usemacro{iffalse} and |\fi| are needed because the second time the \dtxfile{} file is processed, |%| characters at the beginning of lines are ignored. To prevent the copyright\index{copyright}/license\index{license} from being evaluated as \latex{} code, we have to surround it with \usemacro{iffalse}\dotsbrk|\fi|. Adding ``\usething{meta-comment}'' after ``\usemacro{iffalse}'' is nothing more than a convention for indicating that the comment\index{comments} is intended to be read by a human, not by \DOC{}, \ds{}, or \latex. \indexmacroBegin{NeedsTeXFormat} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \indexmacroBegin{ProvidesPackage} \begin{decl} \defmacro{NeedsTeXFormat} \arg{format-name} \oarg{release-date} \\ \defmacro{ProvidesPackage} \arg{package-name} \oarg{release-info} \end{decl} The next few lines are also surrounded by \usemacro{iffalse}\dotsbrk|\fi| so as not to be processed by |latex| on the second pass through the \dtxfile{} file. However, these lines are intended not for a human reader, but for \ds{} (hence, no ``\usething{meta-comment}''): \label{code:ProvidesPackage} \begin{verbatim} % \iffalse %<>\NeedsTeXFormat{LaTeX2e}[2023-11-01] %<>\ProvidesPackage{} %<> [--
v ] % \end{verbatim}% \indexmacro{NeedsTeXFormat}% \indexmacro{ProvidesPackage} \noindent (We'll encounter the |\fi| shortly.) Remember the \usemacro{generate} line in the \insfile{} file (page~\pageref{code:generate})? It ended with the tag ``|package|''. This tells \ds{} to write lines that begin with ``|%<>|'' to the \styfile{} file, stripping off the ``|%<>|'' in the process. Hence, our \styfile{} file will include the following code right after the header comments: \begin{verbatim} \NeedsTeXFormat{LaTeX2e}[2023-11-01] \ProvidesPackage{} [--
v ] \end{verbatim}% \indexmacro{NeedsTeXFormat}% \indexmacro{ProvidesPackage} \noindent For example: \begin{verbatim} \NeedsTeXFormat{LaTeX2e}[2023-11-01] \ProvidesPackage{skeleton} [2002-03-25 v1.0 .dtx skeleton file] \end{verbatim}% \label{code:ProvidesPackage-example}% \indexmacro{NeedsTeXFormat}% \indexmacro{ProvidesPackage} \noindent \index{package|(} The \usemacro{NeedsTeXFormat} line ensures that the package won't run under a \TeX\ format other than \latex[\LaTeXe]. The optional date argument causes |latex| to output a warning message if the version of \latex[\LaTeXe] (which can be found via \latex[\LaTeXe]'s |\fmtversion| macro) is older than what the package was tested with: \begin{verbatim} LaTeX Warning: You have requested release `2239-09-30' of LaTeX, but only release `2023-11-01' is available. \end{verbatim} The date and version strings in the \usemacro{ProvidesPackage} line are used by \DOC{} to set the \usemacro{filedate} and \usemacro{fileversion} macros. Note the date\index{date format} format; \emph{YYYY-MM-DD} is used throughout \latex[\LaTeXe] and should be used in your packages as well.\footnote{Older versions of \latex[\LaTeXe] expected the \emph{YYYY/MM/DD} format, but the latest package/class author guide~\cite{LaTeX:clsguide} specifies that \emph{YYYY-MM-DD} should be used from now on.} \index{package|)} \indexmacroEnd{ProvidesPackage} \indexmacroEnd{NeedsTeXFormat} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \indexmacroBegin{EnableCrossrefs} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \indexmacroBegin{CodelineIndex} \indexmacroBegin{RecordChanges} \indexmacroBegin{DocInput} \begin{decl} \defmacro{EnableCrossrefs} \\ \defmacro{CodelineIndex} \\ \defmacro{RecordChanges} \\ \defmacro{DocInput} \arg{filename} \label{desc:CodelineIndex} \end{decl} Next comes the only part of the \dtxfile{} file that isn't commented out (\ie doesn't begin each line with ``|%|''): \begin{verbatim} %<<*driver>> \documentclass{ltxdoc} \usepackage{} \EnableCrossrefs \CodelineIndex \RecordChanges \begin{document} \DocInput{.dtx} \end{document} %<> % \fi \end{verbatim} The preceding code stanza is what |latex| evaluates on its first pass through the \dtxfile{} file. We'll now examine that stanza line-by-line: \begin{enumerate} \item Putting code between ``|%<<*driver>>|'' and ``|%<>|'' is a \ds{} shorthand for prefixing each line with ``|%<>|''. This demarcates the \DOC{} driver\index{driver code} code. \item The \usemacro{documentclass} should almost always be \usething{ltxdoc} as that loads \DOC{} and provides a few useful macros for formatting program documentation. \index{package|(} \item You should always \usemacro{usepackage} your style file. If you don't, \DOC{} won't see the package's \usemacro{ProvidesPackage} line and won't know how to set \usemacro{filedate} and \usemacro{fileversion} (see page~\pageref{code:GetFileInfo}). This is also where you should \usemacro{usepackage} any other packages needed to typeset the user documentation (as opposed to packages needed by your package). \index{package|)} \item \usemacro{EnableCrossrefs} tells \DOC{} that you want it to construct an index for your code---normally a good idea. The alternative is \usemacro{DisableCrossrefs}, which speeds up processing by a negligible amount. \item \usemacro{CodelineIndex} tells \DOC{} that the index should refer to program line numbers instead of page numbers. (The alternative is \usemacro{PageIndex}.) \usemacro{CodelineIndex} makes index entries easier to find at the expense of making the index less self-consistent (because descriptions of macros and environments are always indexed by page number). The index does, however, begin with a note of explanation. \item \label{item:RecordChanges} Page~\pageref{code:changes} discusses how to log the changes made in each revision of the package\index{package}. \usemacro{RecordChanges} tells \DOC{} that it should keep and aggregate the log entries. \item There should be only one command between the |\begin{document}| and |\end{document}|: a \usemacro{DocInput} call with which the \dtxfile{} file inputs itself. This enables a master file to \usemacro{DocInput} multiple files in order to produce a single document that covers more than one package\index{package} but contains a unified index\index{indexing}. Master documentation files are described~\vpageref{sec:master-files}. \end{enumerate} \indexmacroEnd{DocInput} \indexmacroEnd{RecordChanges} \indexmacroEnd{CodelineIndex} \indexmacroEnd{EnableCrossrefs} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \indexmacroBegin{OnlyDescription} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \begin{decl} \defmacro{OnlyDescription} \label{desc:OnlyDescription} \end{decl} Another command that sometimes appears in the preamble (\ie before the |\begin{document}|) is \usemacro{OnlyDescription}, which tells \DOC{} to typeset only the user documentation, not the package\index{package} code/comments\index{comments}. It's usually best to omit \usemacro{OnlyDescription} (or add it commented out). A user always can add it manually or even enable \usemacro{OnlyDescription} for \emph{all} \dtxfile{} files by adding the following to his \defthing{ltxdoc.cfg} file: \begin{verbatim} \AtBeginDocument{\OnlyDescription} \end{verbatim}% \indexmacro{AtBeginDocument} \indexmacroEnd{OnlyDescription} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \bigskip The remainder of this section covers |latex|'s second pass through the \dtxfile{} file. Consequently, all subsequent examples are prefixed with percent signs. \indexmacroBegin{changes} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \begin{decl} \defmacro{changes} \arg{version} \arg{date} \arg{description} \label{code:changes} \end{decl} \index{package|(} On page~\pageref{item:RecordChanges} we learned that \DOC{} has a mechanism for recording changes to the package. The command is ``|\changes{}{}{}|'', and it's common to use \usemacro{changes} for the initial version of the package to log the package's creation date: \index{package|)} \begin{verbatim} % \changes{v1.0}{2002/03/25}{Initial version} \end{verbatim} One nice feature of the \usemacro{changes} command is that it knows whether it was used internally to a macro/environment definition. As Figure~\ref{fig:change-history} shows, top-level changes are prefixed with ``General:'', and internal changes are prefixed with the name of the enclosing macro or environment. \begin{figure}[htbp] \centering \index{change history} \fbox{% \begin{minipage}[t]{0.75\textwidth} {\normalfont\Large\bfseries Change History\vskip 2.3ex plus 0.2ex} v1.0 \\ \hspace*{2em} General: Top-level comment \dotfill 1 \\ v1.2j \\ \hspace*{2em} \texttt{myMacro}: Internal macro comment \dotfill 5 \end{minipage}% }% \caption{Sample change history} \label{fig:change-history} \end{figure} \indexmacroEnd{changes} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \indexmacroBegin{GetFileInfo} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \indexmacroBegin{filedate} \indexmacroBegin{fileversion} \indexmacroBegin{fileinfo} \begin{decl} \defmacro{GetFileInfo} \arg{style-file} \label{code:GetFileInfo} \\[1ex] \defmacro{filedate} \\ \defmacro{fileversion} \\ \defmacro{fileinfo} \end{decl} Next, we tell \DOC{} to parse the \usemacro{ProvidesPackage} command (page~\pageref{code:ProvidesPackage}), calling the three components of \usemacro{ProvidesPackage}'s argument, respectively, \usemacro{filedate}, \usemacro{fileversion}, and \usemacro{fileinfo}: \begin{verbatim} % \GetFileInfo{.sty} \end{verbatim}% \index{style file}% \indexmacro{GetFileInfo} \noindent For instance, the \usemacro{ProvidesPackage} example shown~\vpageref{code:ProvidesPackage-example} would be parsed as follows: | |% \begin{tabular}{@{}l@{\qquad$\equiv$\qquad}l@{}} \usemacro{filedate} & 2002-03-25 \\ \usemacro{fileversion} & v1.0 \\ \usemacro{fileinfo} & .dtx skeleton file \end{tabular} \indexmacroEnd{fileinfo} \indexmacroEnd{fileversion} \indexmacroEnd{filedate} \indexmacroEnd{GetFileInfo} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \indexmacroBegin{DoNotIndex} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \index{indexing|(} \begin{decl} \defmacro{DoNotIndex} \arg{macro-name \textnormal{, \dots}} \end{decl} When producing an index, \DOC{} normally indexes \emph{every} control sequence (\ie backslashed word or symbol) in the code. The problem with this level of automation is that many control sequences are uninteresting from the perspective of understanding the code. For example, a reader probably doesn't want to see every location where |\if| is used---or |\the| or |\let| or |\begin| or any of numerous other control sequences. As its name implies, the \usemacro{DoNotIndex} command gives \DOC{} a list of control\index{control sequences} sequences that should not be indexed. \usemacro{DoNotIndex} can be used any number of times, and it accepts any number of control\index{control sequences} sequence names per invocation: \begin{verbatim} % \DoNotIndex{\#,\$,\%,\&,\@,\\,\{,\},\^,\_,\~,\ } % \DoNotIndex{\@ne} % \DoNotIndex{\advance,\begingroup,\catcode,\closein} % \DoNotIndex{\closeout,\day,\def,\edef,\else,\empty,\endgroup} \end{verbatim} \centerline{$\vdots$} \index{indexing|)} \indexmacroEnd{DoNotIndex} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \subsection{User documentation} We finally can start writing the user documentation. A typical beginning looks like this: \begin{verbatim} % \title{The \textsf{} package\thanks{This document % corresponds to \textsf{}~\fileversion, % dated~\filedate.}} % \author{ \\ \texttt{}} % % \maketitle \end{verbatim}% \indexmacro{title} \indexmacro{author} \indexmacro{maketitle} \noindent \index{package|(} The title certainly can be more creative, but note that it's common for package names to be typeset with \usemacro{textsf} and for \usemacro{thanks} to be used to specify the package version and date. This yields one of the advantages of literate\index{literate programming} programming: Whenever you change the package version (the optional second argument to \usemacro{ProvidesPackage}), the user documentation is updated accordingly. Of course, you still have to ensure manually that the user documentation accurately describes the updated package. \index{package|)} Write the user documentation as you would any \latex{} document, except that you have to precede each line with a ``|%|''. Note that the \usething{ltxdoc} document class is derived from |article| so the top-level sectioning command is \usemacro{section}, not \usemacro{chapter}. \indexmacroBegin{DescribeMacro} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \indexmacroBegin{DescribeEnv} \begin{decl} \defmacro{DescribeMacro} \arg{macro} \\ \defmacro{DescribeEnv} \arg{environment} \end{decl} \DOC{} provides a couple of commands to help format user documentation. If you include ``|\DescribeMacro{}|''\footnote{``\m{macro}'' should include the backslash.} within a paragraph, \DOC{} will stick ``\m{macro}'' in the margin to make it easy for a reader to see. \DOC{} also will add \m{macro} to the index and format the corresponding page number to indicate that this is where the macro is described (as opposed to the place in the source code where the macro is defined). \usemacro{DescribeEnv} is the analogous command for describing an environment. Both \usemacro{DescribeMacro} and \usemacro{DescribeEnv} can be used multiple times within a paragraph. \indexmacroEnd{DescribeEnv} \indexmacroEnd{DescribeMacro} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \indexmacroBegin{NewDocElement} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \begin{decl} \defmacro{NewDocElement} \oarg{options} \arg{element-name} \arg{env-name} \end{decl} While \latex{} documentation most commonly documents macros and environments, \usemacro{NewDocElement} facilitates documenting arbitrary package components. It defines a |\Describe|\m{element-name} macro analogous to \usemacro{DescribeMacro} and \usemacro{DescribeEnv} above. It then lets you use |\begin{|\m{env-name}|}|\dots\linebreak[1]|\end{|\m{env-name}|}| to demarcate instances of your new element, analogously to |\begin{macro}|\dots\linebreak[1]|\end{macro}| and |\begin{environment}|\dots\linebreak[1]|\end{environment}|, which are described \vpageref{code:macro-environment}. The \m{options} argument specifies, among other things, whether the new element is |macrolike| (begins with a backslash) or |envlike| (does not begin with a backslash). \indexmacroEnd{NewDocElement} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \indexmacroBegin{marg} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \indexmacroBegin{oarg} \indexmacroBegin{parg} \indexmacroBegin{meta} \begin{decl} \defmacro{marg} \arg{argument} \\ \defmacro{oarg} \arg{argument} \\ \defmacro{parg} \arg{argument} \\ \defmacro{meta} \arg{text} \end{decl} The \usething{ltxdoc} document class provides three commands to help typeset macro and environment syntax (Table~\ref{tbl:argument-formatting}). \usemacro{marg} formats mandatory arguments, \usemacro{oarg} formats optional arguments, and \usemacro{parg} formats picture arguments. All three of these utilize \usemacro{meta} to typeset the argument proper. \usemacro{meta} also is useful on its own. For example, ``\texttt{This needs a} |\meta{dimen}|.'' is typeset as ``This needs a \m{dimen}.'' \begin{table}[htbp] \centering \caption{Argument-formatting commands} \label{tbl:argument-formatting} \begin{tabular}{@{}ll@{}} \hline \multicolumn{1}{@{}c}{Command} & \multicolumn{1}{c@{}}{Result} \\ \hline \usemacro{marg}|{text}| & |{}| \\ \usemacro{oarg}|{text}| & |[]| \\ \usemacro{parg}|{text}| & |()| \\ \hline \end{tabular} \end{table} In addition to those commands, \DOC{} facilitates the typesetting of macro descriptions by automatically loading the \svrb{} package\index{package}. \svrb{} lets you use \verb+|+\dots\verb+|+ as a convenient shorthand for |\verb|\verb+|+\dots\verb+|+. For instance, ``\verb+|\mymacro|+ |\oarg{pos}| |\marg{width}| |\marg{text}|'' is typeset as follows: \begin{verbatim} \mymacro [] {} {} \end{verbatim} \noindent Like \usemacro{verb}, the \verb+|+\dots\verb+|+ shorthand does not work within \usemacro{footnote} or other fragile macros. \indexmacroEnd{meta} \indexmacroEnd{parg} \indexmacroEnd{oarg} \indexmacroEnd{marg} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \subsection{Code and commentary} \indexmacroBegin{MaybeStop} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \indexmacroBegin{Finale} \begin{decl} \defmacro{MaybeStop} |{}| \\ \defmacro{Finale} \end{decl} The package's\index{package} source code is delineated by putting it between \usemacro{MaybeStop}\footnote{In older versions of \DOC{}, \usemacro{MaybeStop} was called \usemacro{StopEventually}. The latter remains defined but is deprecated.} and \usemacro{Finale}. \usemacro{MaybeStop} takes an argument, which is a block of text to typeset after the code. If \usemacro{OnlyDescription} (page~\pageref{desc:OnlyDescription}) is specified, then nothing after the \usemacro{MaybeStop} will be output---including text that follows \usemacro{Finale}. \usemacro{MaybeStop}'s \m{text} parameter is therefore the mechanism for providing a piece of text that should be output regardless of whether or not a code listing is typeset. It commonly includes a bibliography section and/or one or both of the following two commands: \indexmacroEnd{Finale} \indexmacroEnd{MaybeStop} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \begin{decl} \defmacro{PrintChanges} \\ \defmacro{PrintIndex} \end{decl} \indexmacroBegin{PrintChanges} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \index{change history|(} \usemacro{PrintChanges} produces an unnumbered section called ``Change History''. (See Figure~\vref{fig:change-history}.) The Change History section aggregates all of the \usemacro{changes} commands in the \dtxfile{} file into a single list of per-version modifications. This makes it easy to keep track of what changed from version to version. \usemacro{PrintChanges} uses \latex's glossary mechanism. Running |latex| on |.dtx| produces change-history data in |.glo|. To produce the typeset change history (|.gls|), the user should run the \usething{makeindex} program as follows: \begin{verbatim} makeindex -s gglo.ist -o .gls .glo \end{verbatim} \index{change history|)} \indexmacroEnd{PrintChanges} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \indexmacroBegin{PrintIndex} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \index{indexing|(} \usemacro{PrintIndex} produces an unnumbered section called ``Index''. The index automatically includes entries for all macros and environments that are used, defined, or described in the document. All environments additionally are listed under ``environments''. Table~\ref{tbl:index-formatting} illustrates the way that various entries are formatted. In that table, ``27'' refers to a page number, and ``123'' refers to a line number.\footnote{If \texttt{\string\CodelineIndex} (page~\pageref{desc:CodelineIndex}) were not used then ``123'' would refer to a page number.} Note that macro/environment definitions and uses are included in the index only if the document includes a code listing (\ie if \usemacro{OnlyDescription} was not specified). \begin{table}[htbp] \centering \caption{Formatting of entries in the index} \label{tbl:index-formatting} \begin{tabular}{@{}llp{6cm}@{}} \hline Item & Function & Formatting in index \\ \hline Macro & Used & |\myMacro| \dotfill~123 \\ Macro & Defined & |\myMacro| \dotfill~\underline{123} \\ Macro & Described & |\myMacro| \dotfill~\textit{27} \\ Environment & Defined & |myEnv| (environment) \dotfill~\underline{123} \\ Environment & Described & |myEnv| (environment) \dotfill~\textit{27} \\ Explicit \texttt{\string\index} & --- & myItem \dotfill~27 \\ \hline \end{tabular} \end{table} The default formatting for an explicit \usemacro{index} command uses a roman page number. This leads to confusion, as roman page numbers otherwise indicate line numbers in the package source code. The solution is to specify ``|usage|'' formatting to the \usemacro{index} command, which typesets the page number in italics: \begin{verbatim} \index{explicit indexing|usage} \end{verbatim} Running |latex| on |.dtx| produces index data in |.idx|. To produce the typeset index (|.ind|), the user should run the \usething{makeindex} program as follows: \begin{verbatim} makeindex -s gind.ist -o .ind .idx \end{verbatim} A code index is a nice ``value added'' made possible by literate\index{literate programming} programming. It requires virtually no extra effort and greatly helps code maintainers find macro definitions and see what other macros a package\index{package} depends upon. \index{indexing|)} \indexmacroEnd{PrintIndex} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \indexthingBegin{macrocode} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \begin{decl} |\begin{macrocode}| \\ \m{code} \\ |\end{macrocode}| \end{decl} Code fragments listed between |\begin{macrocode}| and |\end{macrocode}| are extracted verbatim into the \styfile{} file. When typeset, the code fragments are shown with a running line counter to make it easy to refer to a specific line. Here are some key points to remember about the \usething{macrocode} environment: \begin{enumerate} \item There must be \emph{exactly} four spaces between the ``|%|'' and the ``|\begin{macrocode}|'' or ``|\end{macrocode}|''. Otherwise, \DOC{} won't detect the end of the code fragment.\footnote{Trivia: Only the \texttt{\string\end\string{macrocode\string}} needs this precise spacing and then only for typesetting the documentation. Nevertheless, it's good practice to use ``\texttt{\%\textvisiblespace\textvisiblespace\textvisiblespace\textvisiblespace}'' for the \texttt{\string\begin\string{macrocode\string}}, as well.} \item The lines of code within |\begin{macrocode}|\dotsbrk|\end{macrocode}| should not begin with ``|%|''. The code gets written exactly as it is to the \insfile{} file, with no |%|-stripping. \end{enumerate} The following is a sample code fragment. It happens to be a complete macro definition, but this is not necessary; any fragment of \latex{} code can appear within a \usething{macrocode} environment. \label{code:mymacro} \begin{verbatim} % \begin{macrocode} \newcommand{\mymacro}{This is a \LaTeX{} macro.} % \end{macrocode} \end{verbatim} \noindent \DOC{} formats the preceding code fragment as follows: \begin{tabbing} | |\={\tiny 9} \=\kill \> {\tiny 1} \> |\newcommand{\mymacro}{This is| \\ \> {\tiny 2} \> | a \LaTeX{} macro.}| \end{tabbing} \noindent Note that line numbers are unique across the entire program (as opposed to being reset at the top of each page). If \usemacro{PrintIndex} is used in the \dtxfile{} file containing the preceding definition of |\mymacro|, the index will automatically include entries for |\newcommand|, |\mymacro|, and |\LaTeX|, unless any of these are \usemacro{DoNotIndex}'ed. \indexthingEnd{macrocode} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \indexthingBegin{macro} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \indexthingBegin{environment} \begin{decl} |\begin{macro}{}| \\ \qquad $\vdots$ \\ |\end{macro}| \\ \\ |\begin{environment}{}| \\ \qquad $\vdots$ \\ |\end{environment}| \\ \end{decl} \label{code:macro-environment} The \usething{macro} and \usething{environment} environments are used to delineate a complete macro or environment definition. \usething{macro}/\usething{environment} environments generally contain one or more \usething{macrocode} environments interspersed with code documentation. The following is a more complete version of the \usething{macrocode} example shown~\vpageref{code:mymacro}. \begin{verbatim} % \begin{macro}{\mymacro} % We define a trivial macro, |\mymacro|, to illustrate % the use of the |macro| environment. % \begin{macrocode} \newcommand{\mymacro}{This is a \LaTeX{} macro.} % \end{macrocode} % \end{macro} \end{verbatim} \noindent The typeset version is shown below: \begin{tabbing} | \mymacro|\qquad\={\tiny 9} \= \kill | \mymacro| \> We define a trivial macro, |\mymacro|, to illustrate the \\ \> use of the \usething{macro} environment. \\ \> {\tiny 1} \> |\newcommand{\mymacro}{This is| \\ \> {\tiny 2} \> | a \LaTeX{} macro.}| \end{tabbing} \DOC{} typesets the macro/environment name in the margin for increased visibility. \DOC{} also adds the appropriate entries to the index. (See Table~\vref{tbl:index-formatting} for examples of how these entries are formatted.) Note that |\begin{macro}|\dotsbrk|\end{macro}| is not required to indicate a macro definition. It can also be used to indicate definitions of other control sequences such as counters, lengths, and boxes: \begin{verbatim} % \begin{macro}{myCounter} % This is an example of using the |macro| environment to format % something other than a macro. % \begin{macrocode} \newcounter{myCounter} % \end{macrocode} % \end{macro} \end{verbatim}% \indexthing{macrocode} \usething{macro} and \usething{environment} environments can be nested. This capability is useful not only for macros that define other macros, but also when defining a group of related datatypes that share a description: \begin{verbatim} % \begin{macro}{\thingheight} % \begin{macro}{\thingwidth} % \begin{macro}{\thingdepth} % These lengths keep track of the dimensions of our |\thing| % box. (Actually, we're just trying to show how to nest % |macro| environments.) % \begin{macrocode} \newlength{\thingheight} \newlength{\thingwidth} \newlength{\thingdepth} % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} \end{verbatim}% \indexthing{macro}% \indexthing{macrocode} As a convenience, recent versions of \DOC{} enable a single |\begin{macro}| to list more than one macro to be defined: \begin{verbatim} % \begin{macro}{\thingheight,\thingwidth,\thingdepth} % These lengths keep track of the dimensions of our |\thing| % box. (Actually, we're just trying to show how to nest % |macro| environments.) % \begin{macrocode} \newlength{\thingheight} \newlength{\thingwidth} \newlength{\thingdepth} % \end{macrocode} % \end{macro} \end{verbatim}% \indexthing{macro}% \indexthing{macrocode} \noindent Descriptionless \usething{macro} environments generally should be avoided, as the formatting is a little ugly: the macro name appears on its own line, to the left of an ``empty'' description, but the code doesn't start until the next line. There can be multiple \usething{macrocode} environments within a |\begin{macro}|\dotsbrk|\end{macro}| or |\begin{environment}|\dotsbrk|\end{environment}| block. \index{comments|(} This is the mechanism by which code can be commented internally to a macro/environment. (It's considered bad style to use ``|%|'' for comments within a \usething{macrocode} block.) Here's an example of the way that a nontrivial macro might be commented: \begin{verbatim} % \begin{macro}{\complexMacro} % Pretend that this is a very complex macro that needs % to have its various pieces documented. % \begin{macrocode} \newcommand{\complexMacro}{% % \end{macrocode} % Initialize all of our counters to zero. % \begin{macrocode} \setcounter{count@i}{0}% \setcounter{count@ii}{0}% \setcounter{count@iii}{0}% \setcounter{count@iv}{0}% % \end{macrocode} % \begin{macro}{\helperMacro} % Define a helper macro for |\complexMacro| to use. % \begin{macrocode} \def\helperMacro#1,#2,\relax{% \someOtherMacro{#1}{#2}% }% % \end{macrocode} % Do some really complicated processing. % \begin{macrocode} \end{verbatim}% \indexthing{macrocode} | |$\vdots$ \begin{verbatim} % \end{macrocode} % We're all finished now. % \begin{macrocode} } % \end{macrocode} % \end{macro} % \end{macro} \end{verbatim}% \indexthing{macrocode} \indexthingEnd{environment} \indexthingEnd{macro} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \index{comments|)} Note how the above defines |\helperMacro| within |\complexMacro|. The document introduces |\helperMacro| with a nested |\begin{macro}| that ends, as is customary, with an |\end{macro}| placed before the outer macro's |\end{macro}| as opposed to immediately after |\helperMacro's| final ``|}|''. Appendix~\ref{sec:skeleton-dtx-file-style} lists a complete, skeleton \dtxfile{} file that encapsulates a \styfile{} file and its documentation. \index{class file|(} \paragraph{Class files} The procedure to produce a class file from a \dtxfile{} file is far less straightforward than the procedure to produce a style file. The problem is that \usemacro{DocInput} relies on the |\usepackage{|\m{package}|}| line (more precisely, the \usemacro{ProvidesPackage} line within \m{package}|.sty|) to set the \usemacro{fileversion} and \usemacro{filedate} macros. However, a class file can't be loaded with |\usepackage|. Nor can we simply load it with |\documentclass{|\m{package}|}| because only one class can be loaded per document and we need that class to be \usething{ltxdoc}. The solution is to use \usemacro{ProvidesFile} to make the file version and date available to the \dtxfile{} file. Appendix~\ref{sec:skeleton-dtx-file-class} lists a complete, skeleton \dtxfile{} file that encapsulates a \clsfile{} file and its documentation. It resembles the skeleton file shown in Appendix~\ref{sec:skeleton-dtx-file-style} but has a differently structured header section. \index{class file|)} \index{documented LaTeX file@documented \LaTeX{} file|)} \section{Tips, tricks, and recommendations} \begin{itemize} \item Write lots of good documentation! It really helps others understand your code and the package\index{package} as a whole. \item If you believe the \latex{} community at large would be interested in your package then you should upload it to \CTAN{} at \URL{http://www.ctan.org/upload}. As a central repository of all things \TeX-related, \CTAN{} makes it easier for others to find your \latex{} package than if it were located on your personal home page. \index{documentation, prebuilt PDF|(} \item When distributing your package, be sure to include a |README|\index{README file@\texttt{README} file} file describing what your package does as well as \emph{prebuilt} documentation, preferably as a PDF file. Prebuilt documentation saves users the bother of having to download your package, install it, and build the documentation before even knowing what the package is supposed to do or if it meets their needs. \index{documentation, prebuilt PDF|)} \item Use \latex's sectioning commands to organize the code and clarify its structure (\eg |\subsection{|\texttt{Initialization macros}|}|, |\subsection{|\texttt{Helper functions}|}|, |\subsection{|\texttt{Exported macros and environments}|}|,~\dots). \index{comments|(} \item Although commentary really belongs only in the typeset documentation, it is also possible to write comments that are visible only in the \styfile{} file, in both the typeset documentation and the \styfile{} file, or only in the \dtxfile{} source. Table~\ref{tbl:comment-visibility} shows how to control comment visibility. \index{comments|)} \begin{table}[hbp] \centering \caption{Comment visibility} \label{tbl:comment-visibility} \newcommand{\yes}{Y}% \newcommand{\no}{N}% \index{style file}% \index{comments}% \begin{tabular}{@{}ccl@{}} \hline Appears & Appears \\ in docs & in \styfile{} & \raisebox{1.5ex}[0pt]{Mechanism} \\ \hline \no & \no & |% ^^A | \\[2ex] \no & \yes & |% \iffalse| \\ & & |%% | \\ & & |% \fi| \\[2ex] \yes & \no & |% | \\[2ex] \yes & \yes & |%% | \\ \hline \end{tabular} \end{table} \item All lines between |<<*package>>| and |<>|, except those within a \usething{macrocode} environment, should begin with ``|%|''. Don't use any blank lines; these would get written to the \styfile{} file (and oughtn't). \index{package|(} \index{"@@\texttt{"@}!in macro names|(} \item It is good practice for \latex{} programs to use ``|@|'' within the names of macros, lengths, counters, etc.\ that are declared globally, but intended to be used only internally to the package. This prevents a user from corrupting package state by inadvertently redefining package internals.\footnote{Within a \LaTeX{} document, ``|@|'' is set to category code~12 (``other''), not category code~11 (``letter''), so the user can't easily define or use a macro with ``|@|'' in its name.} Another good practice is to prefix all global names that are internal to the package with the name of the package (\eg ``|\@thing|'' instead of ``|\@thing|'' or---even worse---just ``|\thing|''). This helps avoid inter-package naming conflicts. Finally, because decimal digits are not normally allowed in macro names, it is common to use roman\index{roman numerals} numerals instead, for example: |\arg@i|, |\arg@ii|, |\arg@iii|, |\arg@iv|, etc. \index{"@@\texttt{"@}!in macro names|)} \index{package|)} \item You can use \usemacro{index} in the normal way to index things other than macros and environments. \item Because macro names can be long, consider using the \defthing{idxlayout} package to reduce the number of columns in the index. (It provides control over other aspects of index formatting, as well.) \item If you use \Emacs{} as your text editor, try out \swiftexel's |doctex-mode|\index{doctex-mode@\texttt{doctex-mode}}, an \Emacs{} mode designed specifically for writing \dtxfile{} files. \swiftexel{} is available from \CTAN{}. As a more primitive alternative, look up \Emacs's |string-rectangle| and |kill-rectangle| commands. These help a great deal with adding and removing a ``|%|'' at the beginning of every line in a region. \item Be sure to read ``The \ds{} Program'' and ``The |doc| and \svrb{} Packages'', the documentation for \ds{} and \DOC{}, respectively (provided in \dtxfile{} format, of course). These explain how to do more advanced things with \insfile{} and \dtxfile{} files than this tutorial covered. Some advanced topics include the following: \begin{itemize} \item Extracting multiple \styfile{} files from a single \dtxfile{} file. \item Putting different preambles in different \styfile{} files. \item Extracting something other than a \styfile{} file (\eg a configuration file or Python code) from a \dtxfile{} file. \item Changing the formatting of the typeset documentation. \end{itemize} \end{itemize} \section{Advanced packaging techniques} This section describes various bits of wizardry that can be accomplished with \DOC{} and \ds. Few packages require these techniques but they are included here for convenient reference. \subsection{Master documentation files} \label{sec:master-files} \DOC{} supports ``master'' documentation files that typeset multiple \dtxfile{} files. The advantage is that a set of related \dtxfile{} files can be typeset with continuous section numbering and a single, unified index. In fact, the \latex[\LaTeXe]{} source code itself is typeset using a master document (|source2e.tex|) that includes all of the myriad \dtxfile{} files that comprise \latex[\LaTeXe]. To help produce master documents, the \usething{ltxdoc} class provides a command called ``\usemacro{DocInclude}''. \usething{ltxdoc}'s \usemacro{DocInclude} is much like \DOC's \usemacro{DocInput}---it even uses it internally---but has the following additional features. \begin{itemize} \item \usemacro{PrintIndex} is automatically handled properly. \item Every \usemacro{DocInclude}'d file is given a title page. \item \usemacro{tableofcontents} works as expected. \dtxfile{} filenames are used as ``chapter'' names. \end{itemize} \noindent Note that \usemacro{DocInclude}, unlike \usemacro{DocInput}, assumes a \dtxfile{} extension. Appendix~\ref{sec:skeleton-master-file} presents a master-document skeleton that uses \usemacro{DocInclude} to typeset |.dtx|, |.dtx|, and |.dtx| as a single document. If you prefer a more manual approach (\eg if you dislike \usemacro{DocInclude}'s per-file title pages), you can still use \usemacro{DocInput}. \index{indexing|(} Just make sure to redefine \usemacro{PrintIndex} to do nothing; otherwise, each file will get its own index. After all of the \dtxfile{} files have been typeset, call the original \usemacro{PrintIndex} command to print a unified index: \begin{verbatim} \begin{document} \let\origPrintIndex=\PrintIndex \let\PrintIndex=\relax \DocInput{.dtx} \DocInput{.dtx} \DocInput{.dtx} \origPrintIndex \end{document} \end{verbatim}% \indexmacro{PrintIndex}% \indexmacro{DocInput} \index{indexing|)} \subsection{Single-file package distributions} \label{sec:single-file} Although \latex{} packages are typically distributed as both a~\insfile{} and a \dtxfile{} file, it is possible to distribute a package as a single file. The trick is to include the entire \insfile{} at the top of the \dtxfile{} file, right after the |%| lines: \begin{alltt} %\string<*batchfile\string> \string\begingroup \(\vdots\) \(\vdots\) \string\endgroup %\string \end{alltt} \noindent Omit the \usemacro{endbatchfile} to allow \latex{} to continue on with the rest of the \dtxfile{} file. Also, to avoid the ``\texttt{File} \m{sty-file} \texttt{already exists on the system. Overwrite it? [y/n]}'' message you can put ``\usemacro{askforoverwritefalse}'' before the first \usemacro{generate} command. (This will automatically overwrite the existing \styfile{} file. Wrapping the \usemacro{generate} command(s) within ``\usemacro{IfFileExists}|{|\m{sty-file}|}{}{|\dots|}|'' will suppress the overwriting.) You should also move the \styfile{} installation instructions to the end of the \dtxfile{} file so they don't scroll off the user's screen. You'll need to use \usemacro{typeout} as \usemacro{Msg} won't be defined: \begin{verbatim} % \Finale % % \typeout{**************************************************} % \typeout{*} % \typeout{* To finish the installation you have to move the} % \typeout{* following file into a directory searched by TeX:} % \typeout{*} % \typeout{* \space\space skeleton.sty} % \typeout{*} % \typeout{* Documentation is in skeleton.dvi.} % \typeout{*} % \typeout{* Happy TeXing!} % \typeout{**************************************************} \endinput \end{verbatim} \subsection{Class and style files with shared versioning information} Some packages contain both a \clsfile{} and \styfile{} file. It may be desirable to have these extracted from the same \dtxfile{} file and share the same versioning string. The \ds{} documentation explains how to extract multiple files from a single \usemacro{generate} call: \begin{verbatim} \generate{\file{.cls}{\from{.dtx}{class}} \file{.sty}{\from{.dtx}{package}}} \end{verbatim} Using a single versioning string for both the \clsfile{} and \styfile{} files can be accomplished by changing the following lines in the \dtxfile{} file shown in Appendix~\ref{sec:skeleton-dtx-file-class}: \begin{verbatim} %<>\NeedsTeXFormat{LaTeX2e}[2023-11-01] %<>\ProvidesClass{} %<<*class>> [--
v ] %<> \end{verbatim} The replacement code specifies which lines belong to the class file and which belong to the style file: \begin{verbatim} %<>\NeedsTeXFormat{LaTeX2e}[2023-11-01] %<>\ProvidesClass{} %<>\ProvidesPackage{} %<<*class|package>> [--
v ] %<> \end{verbatim} \subsection{Gallery of advanced packaging techniques} See the \dtxfile\ gallery on \CTAN\ \URL{https://www.ctan.org/tex-archive/info/dtxgallery} for examples of various packaging possibilities, including the following: \begin{itemize} \item single-file package distributions (cf.~Section~\ref{sec:single-file}) \item conditional code inclusion (cf.~Table~\ref{tbl:comment-visibility}) \item rearranging code for presentation in the documentation \end{itemize} \appendix \section{Skeleton files} This section contains complete skeletons of the types of files discussed in the rest of the document. These skeletons can be used as templates for creating your own packages.\index{package} \index{installer file|(} \subsection{A skeleton \texttt{.ins} file to generate a \texttt{.sty} file} \label{sec:skeleton-ins-file-style} \begin{verbatim} %% %% Copyright (C) %% %% This file may be distributed and/or modified under the %% conditions of the LaTeX Project Public License, either %% version 1.3 of this license or (at your option) any later %% version. The latest version of this license is in: %% %% http://www.latex-project.org/lppl.txt %% %% and version 1.3c or later is part of all distributions of %% LaTeX version 2008-05-04 or later. %% \input docstrip.tex \keepsilent \usedir{tex/latex/} \preamble This is a generated file. Copyright (C) This file may be distributed and/or modified under the conditions of the LaTeX Project Public License, either version 1.3 of this license or (at your option) any later version. The latest version of this license is in: http://www.latex-project.org/lppl.txt and version 1.3c or later is part of all distributions of LaTeX version 2008-05-04 or later. \endpreamble \generate{\file{.sty}{\from{.dtx}{package}}} \Msg{*********************************************************} \Msg{*} \Msg{* To finish the installation you have to move the} \Msg{* following file into a directory searched by TeX:} \Msg{*} \Msg{* \space\space .sty} \Msg{*} \Msg{* To produce the documentation run the file .dtx} \Msg{* through LaTeX.} \Msg{*} \Msg{* Happy TeXing!} \Msg{*********************************************************} \endbatchfile \end{verbatim} \subsection{A skeleton \texttt{.ins} file to generate a \texttt{.cls} file} \label{sec:skeleton-ins-file-class} \begin{verbatim} %% %% Copyright (C) %% %% This file may be distributed and/or modified under the %% conditions of the LaTeX Project Public License, either %% version 1.3 of this license or (at your option) any later %% version. The latest version of this license is in: %% %% http://www.latex-project.org/lppl.txt %% %% and version 1.3c or later is part of all distributions of %% LaTeX version 2008-05-04 or later. %% \input docstrip.tex \keepsilent \usedir{tex/latex/} \preamble This is a generated file. Copyright (C) This file may be distributed and/or modified under the conditions of the LaTeX Project Public License, either version 1.3 of this license or (at your option) any later version. The latest version of this license is in: http://www.latex-project.org/lppl.txt and version 1.3c or later is part of all distributions of LaTeX version 2008-05-04 or later. \endpreamble \generate{\file{.cls}{\from{.dtx}{class}}} \Msg{*********************************************************} \Msg{*} \Msg{* To finish the installation you have to move the} \Msg{* following file into a directory searched by TeX:} \Msg{*} \Msg{* \space\space .cls} \Msg{*} \Msg{* To produce the documentation run the file .dtx} \Msg{* through LaTeX.} \Msg{*} \Msg{* Happy TeXing!} \Msg{*********************************************************} \endbatchfile \end{verbatim} \index{installer file|)} \index{documented LaTeX file@documented \LaTeX{} file|(} \subsection{A skeleton \texttt{.dtx} file to generate a \texttt{.sty} file} \label{sec:skeleton-dtx-file-style} \begin{verbatim} % \iffalse meta-comment % % Copyright (C) % -------------------------------- % % This file may be distributed and/or modified under the % conditions of the LaTeX Project Public License, either version 1.3 % of this license or (at your option) any later version. % The latest version of this license is in: % % http://www.latex-project.org/lppl.txt % % and version 1.3c or later is part of all distributions of LaTeX % version 2008-05-04 or later. % % \fi % % \iffalse %<>\NeedsTeXFormat{LaTeX2e}[2023-11-01] %<>\ProvidesPackage{} %<> [--
v ] % %<<*driver>> \documentclass{ltxdoc} \usepackage{} \EnableCrossrefs \CodelineIndex \RecordChanges \begin{document} \DocInput{.dtx} \end{document} %<> % \fi % % \changes{v1.0}{--
}{Initial version} % % \GetFileInfo{.sty} % % \DoNotIndex{} % % \title{The \textsf{} package\thanks{This document % corresponds to \textsf{}~\fileversion, % dated \filedate.}} % \author{ \\ \texttt{}} % % \maketitle % % \begin{abstract} % Put text here. % \end{abstract} % % \section{Introduction} % % Put text here. % % \section{Usage} % % \DescribeMacro{\YOURMACRO} % Put description of macro |\YOURMACRO| here. % % \DescribeEnv{YOURENV} % Put description of environment |YOURENV| here. % % \MaybeStop{\PrintIndex} % % \section{Implementation} % % \begin{macro}{\YOURMACRO} % Put explanation of |\YOURMACRO|'s implementation here. % \begin{macrocode} \newcommand{\YOURMACRO}{} % \end{macrocode} % \end{macro} % % \begin{environment}{YOURENV} % Put explanation of |YOURENV|'s implementation here. % \begin{macrocode} \newenvironment{YOURENV}{}{} % \end{macrocode} % \end{environment} % % \Finale \endinput \end{verbatim} \subsection{A skeleton \texttt{.dtx} file to generate a \texttt{.cls} file} \label{sec:skeleton-dtx-file-class} \begin{verbatim} % \iffalse meta-comment % % Copyright (C) % -------------------------------- % % This file may be distributed and/or modified under the % conditions of the LaTeX Project Public License, either version 1.3 % of this license or (at your option) any later version. % The latest version of this license is in: % % http://www.latex-project.org/lppl.txt % % and version 1.3c or later is part of all distributions of LaTeX % version 2008-05-04 or later. % % \fi % % \iffalse %<<*driver>> \ProvidesFile{.dtx} %<> %<>\NeedsTeXFormat{LaTeX2e}[2023-11-01] %<>\ProvidesClass{} %<<*class>> [--
v ] %<> % %<<*driver>> \documentclass{ltxdoc} \EnableCrossrefs \CodelineIndex \RecordChanges \begin{document} \DocInput{.dtx} \end{document} %<> % \fi % % \changes{v1.0}{--
}{Initial version} % % \GetFileInfo{.dtx} % % \DoNotIndex{} % % \title{The \textsf{} class\thanks{This document % corresponds to \textsf{}~\fileversion, % dated \filedate.}} % \author{ \\ \texttt{}} % % \maketitle % % \begin{abstract} % Put text here. % \end{abstract} % % \section{Introduction} % % Put text here. % % \section{Usage} % % \DescribeMacro{\YOURMACRO} % Put description of macro |\YOURMACRO| here. % % \DescribeEnv{YOURENV} % Put description of environment |YOURENV| here. % % \MaybeStop{\PrintIndex} % % \section{Implementation} % % \begin{macro}{\YOURMACRO} % Put explanation of |\YOURMACRO|'s implementation here. % \begin{macrocode} \newcommand{\YOURMACRO}{} % \end{macrocode} % \end{macro} % % \begin{environment}{YOURENV} % Put explanation of |YOURENV|'s implementation here. % \begin{macrocode} \newenvironment{YOURENV}{}{} % \end{macrocode} % \end{environment} % % \Finale \endinput \end{verbatim} \index{documented LaTeX file@documented \LaTeX{} file|)} \subsection{A skeleton master-document file (\texttt{.tex})} \label{sec:skeleton-master-file} \begin{verbatim} \documentclass{ltxdoc} \usepackage{} \usepackage{} \usepackage{} \title{} \author{<you>} \EnableCrossrefs \CodelineIndex \RecordChanges \begin{document} \maketitle \begin{abstract} Put text here. \end{abstract} \tableofcontents \DocInclude{<file1>} \DocInclude{<file2>} \DocInclude{<file3>} \end{document} \end{verbatim} % The following was generated by BibTeX and slightly touched up by hand. \vfill \begin{thebibliography}{1} \bibitem{Goossens1994:companion} Michel Goossens, Frank Mittelbach, and Alexander Samarin. \newblock \emph{The {\LaTeX} Companion}. \newblock Addison~Wesley, Reading, Massachusetts, October~1, 1994. \newblock ISBN~\mbox{0-201-54199-8}. \bibitem{Knuth1984:literate} Donald~E. Knuth. \newblock Literate programming. \newblock \emph{The Computer Journal}, 27(2):97--111, May 1984. \newblock British Computer Society. Available from \URL{http://www.literateprogramming.com/knuthweb.pdf}. \bibitem{LaTeX:clsguide} \LaTeX\ Project Team. \newblock \LaTeX\ for package and class authors. \newblock Available from \URL{https://ctan.org/pkg/clsguide}, October~24, 2023. \end{thebibliography} % Print an index. \index{sty@\texttt{.sty}|see{style file}} \index{cls@\texttt{.cls}|see{class file}} \index{ins@\texttt{.ins}|see{installer file}} \index{dtx@\texttt{.dtx}|see{documented \LaTeX{} file}} \index{CTAN|see{Comprehensive \TeX{} Archive Network}} \printindex \end{document}