%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \iffalse %%%%
%                                                                              %
%  Copyright (c) 2018 - 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}
  
\changes{0.2.0}{2014/05/10}
  {an important release, which implements most features described in
   the pkgloader TUGBoat article, and fixes a ton of bugs}
  
\changes{0.3.0}{2014/08/31}
  {fixed the package to work with more recent releases of expl3,
   which removed the individual l3kernel .sty files; additionally,
   pkgloader now understands preferred loading orders of cleveref}
  
\changes{0.4.1}{2014/10/26}
  {integrates a number of new package loading rules contributed by the community}
  
\changes{0.5.0}{2014/11/30}
  {integrates a number of new package loading rules contributed by the community}

\changes{0.5.1}{2017/09/20}
  {fixed the package to work aafter \cs_new:Nn was changed to only allow 'N' and 'n' in function signatures (2016/08/20)}

\changes{0.6.0}{2018/03/24}
  {integrates a number of new package loading rules contributed by the community}

\changes{0.7.0}{2018/04/29}
  {integrates a number of new package loading rules contributed by the community}

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

\maketitle

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

\LaTeX\ can be extended by loading packages
using a \lstinline+\usepackage+, \lstinline+\RequirePackage+
or \lstinline+\RequirePackageWithOptions+ command. Similarly, documents load
a document class using \lstinline+\documentclass+, \lstinline+\LoadClass+
or \lstinline+\LoadClassWithOptions+.
Packages and classes can add definitions, change existing ones,
or otherwise extend functionality of the language.

While the Turing-complete power of the \TeX\ language 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+:

\newcommand{\morecode}{\hbox{\vphantom{\LARGE(}\smash{\ \small\vdots}}}
\newcommand{\anyorder}{
	\smash{\small\hbox{
		\(
			\qquad\left.\vrule height 1em depth 1.4em width 0pt\right\}
			\hbox{\textit{\rmfamily any order}}
		\)
}	}	}
\newcommand{\optional}{
	\smash{\small\raisebox{-.7\baselineskip}{
		\(
			\qquad\left.
				\begin{array}{l}\\[.8em]\end{array}
			\right\}
			\hbox{\textit{\rmfamily optional}}
		\)
}	}	}
\begin{latex}
\RequirePackage{pkgloader}
    \documentclass{article}
    \usepackage{algorithm}
    \usepackage{hyperref} $\anyorder$
    \usepackage{float}
\LoadPackagesNow $\hskip44.3pt\optional$
$\morecode$
\begin{document} $\hdots$ \end{document}
\end{latex}

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

Between the second and fifth line, the loading of all packages
and classes is postponed. The \lstinline+\LoadPackagesNow+ command then
loads the packages in some valid order. This also happens automatically
upon reaching the end of the preamble. 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+,
the given package order would cause errors.
%%
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 / Class Loading Requests} % % % % % % % %


\marginnote{\ttfamily\bfseries\textbackslash usepackage\\
	\textbackslash RequirePackage\\
	\textbackslash RequirePackageW{\ldots}s
	\textbackslash documentclass\\
	\textbackslash LoadClass\\
	\textbackslash LoadClassW{\ldots}s}\noindent
For requesting specific packages or classes inside the
|pkgloader| area, just use the commands always used
for this purpose:
	\lstinline+\usepackage+,
	\lstinline+\RequirePackage+ and
	\lstinline+\RequirePackageWithOptions+, as well as
	\lstinline+\documentclass+,
	\lstinline+\LoadClass+ and
	\lstinline+\LoadClassWithOptions+.
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 \emph{package loading rules}.



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

\marginnote{\ttfamily\bfseries\textbackslash Load}\noindent
Each invocation if the \lstinline+\Load+ command sets up a rule about
a class, 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 class+$\ \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 or class 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
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}                                                                 %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
