summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/doc/latex/pkgloader/pkgloader.tex
blob: 1e186cf1ce1cb44250df5717d6ea4f68fcd8f250 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \iffalse %%%%
%                                                                              %
%  Copyright (c) 2014 - Michiel Helvensteijn   (www.mhelvens.net)              %
%                                                                              %
%  https://github.com/mhelvens/latex-pkgloader                                 %
%                                                                              %
%  This work 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.3 or later is part of all distributions of LaTeX              %
%  version 2005/12/01 or later.                                                %
%                                                                              %
%  This work has the LPPL maintenance status `maintained'.                     %
%                                                                              %
%  The Current Maintainer of this work is Michiel Helvensteijn.                %
%                                                                              %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \fi %%%%

\documentclass[a4paper]{pkgloader-packagedoc}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Setup                                                                        %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\def\nt#1{\ensuremath{\hbox{\footnotesize$\langle$}\mathit{#1}\hbox{\footnotesize$\rangle$}}}
\def\|{\ \mid\ }

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Global Changes                                                               %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\changes{0.1.0}{2014/01/29}
  {initial version}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\begin{document}                                                               %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\maketitle

\section {Introduction}  % % % % % % % % % % % % % % % % % % % % % % % % % % % %

\LaTeX\ can be extended by loading packages
using a \lstinline+\usepackage+, \lstinline+\RequirePackage+ or \lstinline+\RequirePackageWithOptions+ command.
Packages can add definitions, change existing ones, or otherwise extend functionality of the language.

While the Turing-complete power of the \TeX\ family is quite useful at times, it does
make it all too easy for independent package authors to step on each others
toes. CTAN is full of conceptually independent packages that cannot be
loaded together, or break if they are not loaded in a specific order.

Yet, until now, there has been no automated package management to speak of.
Document authors are usually told to avoid certain package combinations,
or to load packages in some specific order.
Occasionally, package authors patch their code to be aware of specific
other packages, circumventing known conflicts.
But this makes maintenance more difficult, because these package authors
are `mixing concerns'; they put code related to other packages into their
own package. And it is all done in an ad-hoc fashion.

Enter \lstinline+pkgloader+.



\subsection {Package Description} % % % % % % % % % % % % % % % % % % % % % %

Here is an example of main file for a \LaTeX\ document
which uses \lstinline+pkgloader+:

\begin{latex}
\documentclass{article}

\RequirePackage{pkgloader}
    \usepackage{xltxtra}
    \usepackage[xetex]{graphicx}
     $\smash{\raisebox{-1pt}{\small\vdots}}$
\LoadPackagesNow

\begin{document} $\ldots$ \end{document}
\end{latex}

The idea is to load \lstinline+pkgloader+ before loading any other package.
It can then intercept all package loading requests, analyze them
and load them properly, taking this burden off the shoulders of
the average document author.

Between the second and sixth lines, the loading of all packages
is postponed. The \lstinline+\LoadPackagesNow+ command then
loads the packages in some valid order. During this process,
`conflict resolving' code may also be run, meant specifically to make
other packages work together properly. If the above code were
compiled without \lstinline+pkgloader+ (using the \XeTeX\ engine, as of this writing),
the given order between \lstinline+xltxtra+ and \lstinline+graphicx+ would
cause an error.
%%
The main advantage to this approach is that the complexity of dealing
with package conflicts is moved to the \lstinline+pkgloader+ package and handled
in a systematic manner.

If you are a document author, this may be all you need to know to use
\lstinline+pkgloader+. If you are interested in more advanced functionality,
read on!


\subsection {The \texttt{pkgloader} Area} % % % % % % % %

\describeanymacro
	{\ttfamily\bfseries\textbackslash RequirePackage\!\!\!\!\!}
	{{\ttfamily{\bfseries\{}pkgloader{\bfseries\}}\quad\ldots\quad{\bfseries\textbackslash LoadPackagesNow}}}

The \lstinline+pkgloader+ area is the area between
\lstinline+\RequirePackage{pkgloader}+ and
\lstinline+\LoadPackagesNow+.
Within it, the three traditional package-loading commands
are `hijacked', recording information rather than loading
packages directly. Also, a \lstinline+\Load+ command is
available, which offers more flexibility in regulating
package loading behavior.

|pkgloader| accepts sets of rules coming from outside
packages, though support is still somewhat limited.
Any |pkgloader-|\nt{something}|.sty| file can be loaded
within the |pkgloader| area by passing \nt{something}
as a package option. The file |pkgloader-recommended.sty|
is loaded this way by default. You can overwrite this by
passing |recommended=false| as an option. For example:

\begin{latex}
\RequirePackage[recommended=false, my-better-rules]{pkgloader}
     $\smash{\raisebox{-1pt}{\small\vdots}}$
\LoadPackagesNow
\end{latex}

This area does not play by the recommended package loading
rules, but uses the rules in |pkgloader-my-better-rules.sty|
instead.



\subsection {Package Loading Requests} % % % % % % % %


\marginnote{\ttfamily\bfseries\textbackslash usepackage\\
	\textbackslash RequirePackage\\
	\textbackslash RequirePackageW{\ldots}s}\noindent
For requesting specific packages inside the |pkgloader| area,
just use the three commands always used
for this purpose: \lstinline+\usepackage+, \lstinline+\RequirePackage+ and
\lstinline+\RequirePackageWithOptions+. Their syntax and effective semantics
are the same as they have always been. Their effects are just delayed,
reordered and perhaps modified by the active rules.



\subsection {Package Loading Rules} % % % % % % % %

\marginnote{\ttfamily\bfseries\textbackslash Load}\noindent
Each invocation if the \lstinline+\Load+ command sets up a rule about
a package or packages, which are not necessarily ever loaded.
These rules can come from any number of different sources.
A central registry will be maintained together with \lstinline+pkgloader+ itself
in the form of |pkgloader-recommended.sty|,
specifying well-known conflicts and resolutions.
Individual package authors, however, can supply their own rules,
as can document authors. Though ideally, for the
average document author, things should `just work'.

The \lstinline+\Load+ command expects the following syntax:

\vskip\abovedisplayskip
\begingroup
\centering
\begin{tabular}{r@{\ \ \ \ }r@{\ \ \ \ }l}
	\nt{load}           &$::=$&   \lstinline+\Load+$\ \nt{package}\ \ \nt{clause}_1\ \ldots\ \nt{clause}_i$        \\
	                    &$ \|$&   \lstinline+\Load error+ $\ \ \ \,\nt{clause}_1\ \ldots\ \nt{clause}_i$         \\[2mm]
	
	\nt{package}        &$::=$&   \lstinline+[+$\;\nt{options}\;$\lstinline+] {+$\;\nt{pkg}\;$\lstinline+} [+$\;\nt{version}\;$\lstinline+]+     \\[2mm]
	
	\nt{clause}         &$::=$&   $\nt{order}\ \ \|\ \ \nt{condition}\ \ \|\ \ \nt{reason}$              \\[2mm]
	
	\nt{order}          &$::=$&   \lstinline+before {+ $\nt{pkg}_1\,$\lstinline+, +$\ldots\,$\lstinline+, +$\nt{pkg}_j$ \lstinline+}+            \\
		                &$ \|$&   \lstinline+after  {+ $\nt{pkg}_1\,$\lstinline+, +$\ldots\,$\lstinline+, +$\nt{pkg}_j$ \lstinline+}+            \\
		                &$ \|$&   \lstinline+early+                                                                \\
		                &$ \|$&   \lstinline+late+                                                                 \\[2mm]
	
	\nt{condition}      &$::=$&   \lstinline+always+                           $\ \ \|\ \ $
	                              \lstinline+if loaded+                        $\ \ \|\ \ $
	                              \lstinline+if {+ $\nt{\phi}$ \lstinline+}+   \\[2mm]
	
	\nt{\phi}           &$::=$&   $\nt{pkg}$                                   $\ \ \|\ \ $
		                          $\nt{\phi}\ $\lstinline+&&+$\ \nt{\phi}$     $\ \ \|\ \ $
		                          $\nt{\phi}\ $\lstinline+||+$\ \nt{\phi}$     $\ \ \|\ \ $
		                          \lstinline+!+$\;\nt{\phi}$                   $\ \ \|\ \ $
		                          \lstinline+(+$\;\nt{\phi}\;$\lstinline+)+                                                  \\[2mm]
	
	\nt{reason}         &$::=$&   \lstinline+because {+ $\nt{token{-}list}$ \lstinline+}+    
\end{tabular}
\endgroup
\vskip\belowdisplayskip

\noindent
\nt{pkg} represents a package name.
\nt{token{-}list} should expand to a human-readable text without formatting.

\marginnote{\ttfamily\bfseries if}\noindent
The \( \nt{condition} \) clause determines under which package loading
conditions any and all parts of a rule are invoked.
Here is an example of the use of the \( \nt{condition} \) clause:
\begin{latex}
\Load {res-ie-lst} if {inputenc && listings}
\Load {fixltx2e}   always
\end{latex}

\lstinline+res-ie-lst+ (a fictional package built specifically to resolve the
conflict between \lstinline+inputenc+ and \lstinline+listings+) will be loaded if requested
specifically, or if both \lstinline+inputenc+ and \lstinline+listings+ are loaded. The \lstinline+fixltx2e+ package is
always loaded, as it was created to smooth over some mistakes in the
\LaTeXe\ core.

\marginnote{\ttfamily\bfseries always\\ if loaded}
The \lstinline+always+ keyword makes a rule unconditional. The \lstinline+if loaded+
directive makes a rule conditional on its package already being loaded anyway.
This can be used to order two packages only when they are being loaded by other
means, and is actually the default behavior (in other words, \lstinline+if loaded+
really does nothing).

\marginnote{\ttfamily\bfseries before\\ after}
The \lstinline+before+ and \lstinline+after+ keywords should be pretty straightforward. They
can be used for things like:
\begin{latex}
\Load {xltxtra} after {graphicx}
\end{latex}
which fixes the loading order between these two packages when they are both loaded.

\marginnote{\ttfamily\bfseries early\\ late}
But the set of \LaTeX\ packages is constantly growing, and it appears that
some big packages should almost always be loaded early in the process,
and others should almost always be loaded late. Therefore the \lstinline+early+
and \lstinline+late+ stages are provided as a fallback mechanism. If two packages
are not related by an explicit application order, their loading order
may still be decided by their relative stages: \lstinline+early+ before `normal' before \lstinline+late+.
That way, conflicts may be avoided in a majority of cases.
This is implemented with |pkgloader-early| and |pkgloader-late| stubs in
the loading order graph.

The following example uses the \( \nt{order} \) clause
in addition to the \( \nt{condition} \) clause:
\begin{latex}
\Load {res-ie-lst} if {inputenc && listings}
                after {inputenc ,  listings}
\Load {fixltx2e} always early
\end{latex}
An important observation about the loading order is that it
might form a cycle when contradictory ordering rules are specified:
\begin{latex}
\Load {pkg1} after {pkg2}
\Load {pkg2} after {pkg1}
\end{latex}
In practice this could happen if the authors of \lstinline+pkg1+ and \lstinline+pkg2+
independently discover a conflict, and both try to solve it by patching
their code and having their own package be loaded last. \lstinline+pkgloader+
can provide a clear error message when this happens, allowing the
two package authors to seek contact and collaborate on a solution.

\marginnote{\ttfamily\bfseries error}
Now, about the \lstinline+error+ keyword.
Initially all package combinations are valid. But if two packages
are irredeemably incompatible, their combination can be made to trigger
an error message by a command such as the following:
\begin{latex}
\Load error if {algorithms && pseudocode}
\end{latex}
These two packages provide almost identical functionality and conflict
on many command-names. It was generally agreed upon that they should
never be loaded together. Document authors should simply choose one
or the other.

\marginnote{\ttfamily\bfseries because}
Finally, the \( \nt{reason} \) clause can be used to supply a
human-readable explanation of a rule.
We finish the above examples by providing reasons:
\begin{latex}[basewidth=.598em]
\Load {res-ie-lst} if {inputenc && listings}
                after {inputenc ,  listings}
      because {it allows the use of 1 byte unicode
               characters in code listings}

\Load {fixltx2e} always early
      because {it fixes some imperfections in LaTeX2e}

\Load error when {algorithms && pseudocode}
      because {they provide almost identical functionality
               and conflict on many command names}
\end{latex}
In the future, reasons will be extracted automatically to
generate documentation. For now, they are displayed with error
messages related to the rule in question.


\subsection {Status} % % % % % % % %

So far, \lstinline+pkgloader+ seems to work as expected, but has not
yet been tested as extensively as it should be. Therefore, bug-reports
on the |pkgloader| issue tracker on Github would be most welcome.
Also, lots more recommended package loading rules are needed.

I nonetheless decided to publish the package now, because I've been
promising to do so for a while now:

\begin{center}
	\url{http://tex.stackexchange.com/questions/123174}
\end{center}

\noindent
I hope that, with feedback and community collaboration,
use of this package will become widespread and package
authors will be able to work in a more modular fashion.

\emph{Future versions} of |pkgloader| will be able to deal with
document classes, to intelligently merge package options
and to track packages loaded by other packages in order
to better inform the user --- perhaps even fix problems
by carrying information into the next run through auxiliary files.
But most of this will depend on feedback.



%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\end{document}                                                                 %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%