summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/source/latex/l3experimental/xcoffins/xcoffins.dtx
diff options
context:
space:
mode:
Diffstat (limited to 'Master/texmf-dist/source/latex/l3experimental/xcoffins/xcoffins.dtx')
-rw-r--r--Master/texmf-dist/source/latex/l3experimental/xcoffins/xcoffins.dtx855
1 files changed, 855 insertions, 0 deletions
diff --git a/Master/texmf-dist/source/latex/l3experimental/xcoffins/xcoffins.dtx b/Master/texmf-dist/source/latex/l3experimental/xcoffins/xcoffins.dtx
new file mode 100644
index 00000000000..8d66d6f6bed
--- /dev/null
+++ b/Master/texmf-dist/source/latex/l3experimental/xcoffins/xcoffins.dtx
@@ -0,0 +1,855 @@
+% \iffalse meta-comment
+%
+%% File: xcoffins.dtx Copyright(C) 2010,2011 The LaTeX3 Project
+%%
+%% It may be distributed and/or modified under the conditions of the
+%% LaTeX Project Public License (LPPL), either version 1.3c of this
+%% license or (at your option) any later version. The latest version
+%% of this license is in the file
+%%
+%% http://www.latex-project.org/lppl.txt
+%%
+%% This file is part of the "l3experimental bundle" (The Work in LPPL)
+%% and all files in that bundle must be distributed together.
+%%
+%% The released version of this bundle is available from CTAN.
+%%
+%% -----------------------------------------------------------------------
+%%
+%% The development version of the bundle can be found at
+%%
+%% http://www.latex-project.org/svnroot/experimental/trunk/
+%%
+%% for those people who are interested.
+%%
+%%%%%%%%%%%
+%% NOTE: %%
+%%%%%%%%%%%
+%%
+%% Snapshots taken from the repository represent work in progress and may
+%% not work or may contain conflicting material! We therefore ask
+%% people _not_ to put them into distributions, archives, etc. without
+%% prior consultation with the LaTeX Project Team.
+%%
+%% -----------------------------------------------------------------------
+%%
+%
+%<*driver|package>
+\RequirePackage{xparse,l3coffins}
+\GetIdInfo$Id: xcoffins.dtx 2349 2011-05-11 18:44:37Z joseph $
+ {L3 Experimental design-level coffins}
+%</driver|package>
+%<*driver>
+\documentclass[full]{l3doc}
+\usepackage{xcoffins} % Not yet part of expl3, so not in l3doc
+\NewCoffin \ExampleCoffin
+\NewCoffin \SmallCoffin
+\NewCoffin \OutputCoffin
+\NewCoffin \RedCoffin
+\NewCoffin \BlueCoffin
+\NewCoffin \GreenCoffin
+\NewCoffin \YellowCoffin
+\NewCoffin \OrangeCoffin
+\begin{document}
+ \DocInput{\jobname.dtx}
+\end{document}
+%</driver>
+% \fi
+%
+% \title{^^A
+% The \textsf{xcoffins} package\\ Design-level coffins^^A
+% \thanks{This file describes v\ExplFileVersion,
+% last revised \ExplFileDate.}^^A
+% }
+%
+% \author{^^A
+% The \LaTeX3 Project\thanks
+% {^^A
+% E-mail:
+% \href{mailto:latex-team@latex-project.org}
+% {latex-team@latex-project.org}^^A
+% }^^A
+% }
+%
+% \date{Released \ExplFileDate}
+%
+% \maketitle
+%
+% \begin{documentation}
+%
+% \section{Introduction: the coffin concept}
+%
+% In \LaTeX3 terminology, a \enquote{coffin} is a box containing
+% typeset material. Along with the box itself, the coffin structure
+% includes information on the size and shape of the box, which makes
+% it possible to align two or more coffins easily. This is achieved
+% by providing a series of `poles' for each coffin. These
+% are horizontal and vertical lines through the coffin at defined
+% positions, for example the top or horizontal centre. The points
+% where these poles intersect are called \enquote{handles}. Two
+% coffins can then be aligned by describing the relationship between
+% a handle on one coffin with a handle on the second. In words, an
+% example might then read
+% \begin{quote}
+% Align the top-left handle of coffin A with the bottom-right
+% handle of coffin B.
+% \end{quote}
+%
+% The locations of coffin handles are much easier to understand
+% visually. Figure~\ref{fgr:handles} shows the standard handle
+% positions for a coffin typeset in horizontal mode (left) and in
+% vertical mode (right). Notice that the later case results in a greater
+% number of handles being available. As illustrated, each handle
+% results from the intersection of two poles. For example, the centre
+% of the coffin is marked |(hc,vc)|, \emph{i.e.}~it is the
+% point of intersection of the horizontal centre pole with the
+% vertical centre pole. New handles are generated automatically when
+% poles are added to a coffin: handles are \enquote{dynamic} entities.
+% \begin{figure}
+% \hfil
+% \begin{minipage}{0.4\textwidth}
+% \SetHorizontalCoffin\ExampleCoffin
+% {\color{black!10!white}\rule{1 in}{1 in}}
+% \DisplayCoffinHandles\ExampleCoffin{blue}
+% \end{minipage}
+% \hfil
+% \begin{minipage}{0.4\textwidth}
+% \SetVerticalCoffin\ExampleCoffin{1 in}
+% {\color{black!10!white}\rule{1 in}{1 in}}
+% \DisplayCoffinHandles\ExampleCoffin{blue}
+% \end{minipage}
+% \hfil
+% \caption{Standard coffin handles: left, horizontal coffin; right,
+% vertical coffin}
+% \label{fgr:handles}
+% \end{figure}
+%
+%\section{Creating and setting coffins}
+%
+% Before any alignment can take place, coffins must be created and
+% their contents must be created. All coffin operations are local
+% to the current \TeX{} group with the exception of coffin creation.
+% Coffins are also \enquote{colour safe}: in contrast to the code-level
+% \cs{box_\ldots} functions there is no need to add additional grouping
+% to coffins when dealing with colour.
+%
+% \begin{function}{\NewCoffin}
+% \begin{syntax}
+% \cs{NewCoffin} \meta{coffin}
+% \end{syntax}
+% Before a \meta{coffin} can be used, it must be allocated using
+% \cs{NewCoffin}. The name of the \meta{coffin} should be a
+% control sequence (starting with the escape character, usually
+% |\|), for example
+% \begin{verbatim}
+% \NewCoffin\MyCoffin
+% \end{verbatim}
+% Coffins are allocated globally, and an error will be raised if the
+% name of the \meta{coffin} is not globally-unique.
+% \end{function}
+%
+% \begin{function}{\SetHorizontalCoffin}
+% \begin{syntax}
+% \cs{SetHorizontalCoffin} \meta{coffin} \Arg{material}
+% \end{syntax}
+% Typesets the \meta{material} in horizontal mode, storing the result
+% in the \meta{coffin}. The standard poles for the \meta{coffin} are
+% then set up based on the size of the typeset material.
+% \end{function}
+%
+% \begin{function}{\SetVerticalCoffin}
+% \begin{syntax}
+% \cs{SetVerticalCoffin} \meta{coffin} \Arg{width} \Arg{material}
+% \end{syntax}
+% Typesets the \meta{material} in vertical mode constrained to the
+% given \meta{width} and stores the result in the \meta{coffin}. The
+% standard poles for the \meta{coffin} are then set up based on the
+% size of the typeset material.
+% \end{function}
+%
+% \section{Controlling coffin poles}
+%
+% A number of standard poles are automatically generated when the coffin
+% is set or an alignment takes place. The standard poles for all coffins
+% are:
+% \begin{itemize}[font = \ttfamily]
+% \item[l] a pole running along the left-hand edge of the bounding
+% box of the coffin;
+% \item[hc] a pole running vertically through the centre of the coffin
+% half-way between the left- and right-hand edges of the bounding
+% box (\emph{i.e.}~the \enquote{horizontal centre});
+% \item[r] a pole running along the right-hand edge of the bounding
+% box of the coffin;
+% \item[b] a pole running along the bottom edge of the bounding
+% box of the coffin;
+% \item[vc] a pole running horizontally through the centre of the
+% coffin half-way between the bottom and top edges of the bounding
+% box (\emph{i.e.}~the \enquote{vertical centre});
+% \item[t] a pole running along the top edge of the bounding
+% box of the coffin;
+% \item[H] a pole running along the baseline of the typeset material
+% contained in the coffin.
+% \end{itemize}
+% In addition, coffins containing vertical-mode material also
+% feature poles which reflect the richer nature of these systems:
+% \begin{itemize}
+% \item[B] a pole running along the baseline of the material at the
+% bottom of the coffin.
+% \item[T] a pole running along the baseline of the material at the top
+% of the coffin.
+% \end{itemize}
+%
+% \begin{function}{\SetHorizontalPole}
+% \begin{syntax}
+% \cs{SetHorizontalPole} \meta{coffin} \Arg{pole} \Arg{offset}
+% \end{syntax}
+% Sets the \meta{pole} to run horizontally through the \meta{coffin}.
+% The \meta{pole} will be located at the \meta{offset} from the
+% bottom edge of the bounding box of the \meta{coffin}. The
+% \meta{offset} should be given as a dimension expression; this may
+% include the terms \cs{TotalHeight}, \cs{Height}, \cs{Depth} and
+% \cs{Width}, which will evaluate to the appropriate dimensions of
+% the \meta{coffin}. For example, to create a pole running
+% horizontally through the coffin at one third of the distance from
+% the base of the coffin to the top, the appropriate instruction would
+% be
+% \begin{verbatim}
+% \SetHorizontalPole \MyCoffin {height/3} {\TotalHeight/3}
+% \end{verbatim}
+% Note that poles which run \emph{horizontally} are described in terms
+% of their \emph{vertical} location in the coffin. Also notice that
+% the total height of the coffin is described by the sum of
+% \cs{Height} and \cs{Depth}: these are both measured from the
+% horizontal baseline of the material in the coffin.
+% \end{function}
+%
+% \begin{function}{\SetVerticalPole}
+% \begin{syntax}
+% \cs{SetVerticalPole} \meta{coffin} \Arg{pole} \Arg{offset}
+% \end{syntax}
+% Sets the \meta{pole} to run vertically through the \meta{coffin}.
+% The \meta{pole} will be located at the \meta{offset} from the
+% left-hand edge of the bounding box of the \meta{coffin}. The
+% \meta{offset} should be given as a dimension expression; this may
+% include the terms \cs{TotalHeight}, \cs{Height}, \cs{Depth} and
+% \cs{Width}, which will evaluate to the appropriate dimensions of
+% the \meta{coffin}. For example, to create a pole running vertically
+% through the coffin at one third of the distance from the left-hand
+% edge, the appropriate instruction would be
+% \begin{verbatim}
+% \SetVerticalPole \MyCoffin {width/3} {\Width/3}
+% \end{verbatim}
+% Note that poles which run \emph{vertically} are described in terms
+% of their \emph{horizontal} location in the coffin.
+% \end{function}
+%
+% \begin{function}{\TotalHeight}
+% \begin{syntax}
+% \cs{TotalHeight}
+% \end{syntax}
+% Within the \meta{offset} argument of \cs{SetHorizontalPole} and
+% \cs{SetVerticalPole}, \cs{TotalHeight} will give the distance from
+% the base to the top of the bounding box of the relevant coffin.
+% \end{function}
+%
+% \begin{function}{\Height}
+% \begin{syntax}
+% \cs{Height}
+% \end{syntax}
+% Within the \meta{offset} argument of \cs{SetHorizontalPole} and
+% \cs{SetVerticalPole}, \cs{Height} will give the distance from the
+% baseline to the top of the bounding box of the relevant coffin.
+% \end{function}
+%
+% \begin{function}{\Depth}
+% \begin{syntax}
+% \cs{Depth}
+% \end{syntax}
+% Within the \meta{offset} argument of \cs{SetHorizontalPole} and
+% \cs{SetVerticalPole}, \cs{Depth} will give the distance from the
+% baseline to the bottom of the bounding box of the relevant coffin.
+% \end{function}
+%
+% \begin{function}{\Width}
+% \begin{syntax}
+% \cs{Width}
+% \end{syntax}
+% Within the \meta{offset} argument of \cs{SetHorizontalPole} and
+% \cs{SetVerticalPole}, \cs{Width} will give the distance from the
+% right edge to the left edge of the bounding box of the relevant
+% coffin.
+% \end{function}
+%
+% \section{Rotating coffins}
+%
+% \begin{function}{\RotateCoffin}
+% \begin{syntax}
+% \cs{RotateCoffin} \meta{coffin} \Arg{angle}
+% \end{syntax}
+% Rotates the \meta{coffin} by the given \meta{angle} (given in
+% degrees counter-clockwise). This process will rotate both the
+% coffin content and poles. Multiple rotations will not result in
+% the bounding box of the coffin growing unnecessarily.
+%
+% The effect of rotation on a coffin is illustrated in
+% Figure~\ref{fgr:rotation}. As is shown, the coffin handles will
+% remain correctly positioned relative to the content of the coffin.
+% The \enquote{top} of a rotated coffin may of course no longer be the
+% edge closest to the top of the physical page.
+% \begin{figure}
+% \hfil
+% \SetHorizontalCoffin\ExampleCoffin
+% {^^A
+% \color{black!10!white}\rule{0.5 in}{1 in}^^A
+% \color{black!20!white}\rule{0.5 in}{1 in}^^A
+% }
+% \begin{minipage}{0.4\textwidth}
+% \DisplayCoffinHandles\ExampleCoffin{blue}
+% \end{minipage}
+% \hfil
+% \begin{minipage}{0.4\textwidth}
+% \RotateCoffin\ExampleCoffin{45}
+% \DisplayCoffinHandles\ExampleCoffin{blue}
+% \end{minipage}
+% \hfil
+% \caption{Coffin rotation: left, unrotated; right, rotated by
+% $45$\textdegree.}
+% \label{fgr:rotation}
+% \end{figure}
+% \end{function}
+%
+% \section{Resizing coffins}
+%
+% \begin{function}{\ResizeCoffin}
+% \begin{syntax}
+% \cs{RotateCoffin} \meta{coffin} \Arg{width} \Arg{total-height}
+% \end{syntax}
+% Resized the \meta{coffin} to \meta{width} and \meta{total-height},
+% both of which should be given as dimension expressions. These may
+% include the terms \cs{TotalHeight}, \cs{Height}, \cs{Depth} and
+% \cs{Width}, which will evaluate to the appropriate dimensions of
+% the \meta{coffin}.
+% \end{function}
+%
+% \begin{function}{\ScaleCoffin}
+% \begin{syntax}
+% \cs{ScaleCoffin} \meta{coffin} \Arg{x-scale} \Arg{y-scale}
+% \end{syntax}
+% Scales the \meta{coffin} by a factors \meta{x-scale} and
+% \meta{y-scale} in the horizontal and vertical directions,
+% respectively. The two scale factors should be given as real numbers.
+% \end{function}
+%
+% \cs{ResizeCoffin} and \cs{ScaleCoffin} can be used interchangeably:
+% whether scale factors or absolute values are the best form for the
+% resizing will depend upon the context (Figure~\ref{fgr:resizing}).
+% \begin{figure}
+% \hfil
+% \SetHorizontalCoffin\ExampleCoffin
+% {^^A
+% \color{black!10!white}\rule{0.5 in}{1 in}^^A
+% \color{black!20!white}\rule{0.5 in}{1 in}^^A
+% }
+% \begin{minipage}{0.4\textwidth}
+% \ResizeCoffin \ExampleCoffin {4 cm} {3 cm}
+% \DisplayCoffinHandles \ExampleCoffin {blue}
+% \end{minipage}
+% \hfil
+% \begin{minipage}{0.4\textwidth}
+% \ScaleCoffin \ExampleCoffin {2.0} {0.5}
+% \DisplayCoffinHandles \ExampleCoffin {blue}
+% \end{minipage}
+% \hfil
+% \caption{Coffin resizing: left, resized to exactly $4$\,cm by
+% $6$\,cm; right, scaled a factors of $2$ and $0.5$ in
+% $x$ and $y$, respectively (example coffin as in
+% Figure~\ref{fgr:rotation}).}
+% \label{fgr:resizing}
+% \end{figure}
+%
+% \section{Joining coffins}
+%
+% The key operation for coffins is joining coffins to each other. This
+% is always carried out such that the first coffin is the
+% \enquote{parent}, and is updated by the alignment. The second
+% \enquote{child} coffin is not altered by the alignment process.
+%
+% \begin{function}{\JoinCoffins}
+% \begin{syntax}
+% \cs{JoinCoffins} *
+% ~~\meta{coffin1} [ \meta{coffin1-pole1} , \meta{coffin1-pole2} ]
+% ~~\meta{coffin2} [ \meta{coffin2-pole1} , \meta{coffin2-pole2} ]
+% ~~( \meta{x-offset} , \meta{y-offset} )
+% \end{syntax}
+% Joining of two coffins is carried out by the \cs{JoinCoffins}
+% function, which takes two mandatory arguments: the \enquote{parent}
+% \meta{coffin1} and the \enquote{child} \meta{coffin2}. All of the
+% other arguments shown are optional.
+%
+% The standard \cs{JoinCoffins} functions joins \meta{coffin2} to
+% \meta{coffin1} such that the bounding box of \meta{coffin1} after the
+% process will expand. The new bounding box will be the smallest
+% rectangle covering the bounding boxes of the two input coffins.
+% When the starred variant of \cs{JoinCoffins} is used, the bounding
+% box of \meta{coffin1} is not altered, \emph{i.e.}~\meta{coffin2} may
+% protrude outside of the bounding box of the updated \meta{coffin1}.
+% The difference between the two forms of alignment is best illustrated
+% using a visual example. In Figure~\ref{fgr:alignment}, the two
+% processes are contrasted. In both cases, the small red coffin has been
+% aligned with the large grey coffin. In the left-hand illustration,
+% the \cs{JoinCoffins} function was used, resulting in an expanded
+% bounding box. In contrast, on the right \cs{AttachCoffin} was used,
+% meaning that the bounding box does not include the area of the
+% smaller coffin.
+% \begin{figure}
+% \fboxsep 0 pt\relax
+% \SetHorizontalCoffin\ExampleCoffin
+% {\color{black!20!white}\rule{1 in}{1 in}}
+% \SetHorizontalCoffin \SmallCoffin
+% {\color{red!20!white}\rule{0.1 in}{0.1 in}}
+% \hfil
+% \begin{minipage}{0.4\textwidth}
+% \centering
+% \JoinCoffins\ExampleCoffin[vc,r]\SmallCoffin[vc,l]
+% \fbox{\TypesetCoffin\ExampleCoffin}
+% \end{minipage}
+% \hfil
+% \begin{minipage}{0.4\textwidth}
+% \centering
+% \JoinCoffins*\ExampleCoffin[vc,r]\SmallCoffin[vc,l]
+% \fbox{\TypesetCoffin\ExampleCoffin}%
+% \end{minipage}
+% \hfil
+% \caption{Contrast between \cs{JoinCoffins} (left) and
+% \cs{JoinCoffins*} (right); the bounding box of the coffin is show
+% in black.}
+% \label{fgr:alignment}
+% \end{figure}
+%
+% The alignment is carried out by first calculating \meta{handle1}, the
+% point of intersection of \meta{coffin1-pole1} and
+% \meta{coffin1-pole2}, and \meta{handle2}, the point of intersection
+% of \meta{coffin2-pole1} and \meta{coffin2-pole2}. If the two
+% \meta{poles} are not specified, \cs{JoinCoffins} will use the
+% default value |(H,l)|, \emph{i.e.}~the reference point used by \TeX\
+% for the underlying box. Once the two \meta{handles} have been
+% located, \meta{coffin2} is then attached to \meta{coffin1} such that
+% the relationship between \meta{handle1} and \meta{handle2} is
+% described by the \meta{x-offset} and \meta{y-offset}. This
+% \meta{offset} is an optional argument, and if it is not given then
+% |(0 pt, 0 pt)| is used.
+% \end{function}
+%
+% Notice that when \cs{JoinCoffins} is used the new bounding box is
+% the smallest rectangle containing the bounding boxes of the two input
+% coffins. As a result, it will include additional white space unless
+% one coffin entirely overlaps the other (Figure~\ref{fgr:bounding},
+% left). Rotation of coffins will take account of the extent of the
+% material after rotation when re-calculating the bounding box. This
+% means that no \emph{unnecessary} white space will be added on
+% rotation (Figure~\ref{fgr:bounding}, right).
+% \begin{figure}
+% \fboxsep 0 pt\relax
+% \SetHorizontalCoffin\ExampleCoffin
+% {\color{black!20!white}\rule{1 in}{1 in}}
+% \SetHorizontalCoffin\SmallCoffin
+% {\color{red!20!white}\rule{0.1 in}{0.1 in}}
+% \JoinCoffins\ExampleCoffin[vc,r]\SmallCoffin[vc,l]
+% \hfil
+% \begin{minipage}{0.4\textwidth}
+% \centering
+% \fbox{\TypesetCoffin\ExampleCoffin}
+% \end{minipage}
+% \hfil
+% \begin{minipage}{0.4\textwidth}
+% \centering
+% \RotateCoffin\ExampleCoffin{135}
+% \fbox{\TypesetCoffin\ExampleCoffin}
+% \end{minipage}
+% \hfil
+% \caption{The effect of rotation of a joined coffin: the black line
+% shows the coffin bounding box.}
+% \label{fgr:bounding}
+% \end{figure}
+%
+% As part of the joining procedure, the poles of the two input coffins
+% are preserved within the structure of the updated coffin. In this way
+% it is possible to carry out complex alignment procedures. The poles of
+% a coffin after alignment may therefore be divided into three groups:
+% \begin{enumerate}
+% \item The \enquote{native} poles of the updated coffin, such as
+% \texttt{l}, \texttt{r}, \texttt{hc}, \emph{etc}.
+% \item Poles derived from \meta{coffin1}, such as
+% \texttt{\meta{coffin1}-l}, \texttt{\meta{coffin1}-r},
+% \texttt{\meta{coffin1}-hc}, \emph{etc.}
+% \item Poles derived from \meta{coffin2}, such as
+% \texttt{\meta{coffin2}-l}, \texttt{\meta{coffin2}-r},
+% \texttt{\meta{coffin2}-hc}, \emph{etc.}
+% \end{enumerate}
+%
+% Applying this ability allows a series of joining operations to
+% take place, as illustrated in Figure~\ref{fgr:nested}. In this
+% example, the scheme used for alignment was as follows:
+% \begin{verbatim}
+% \SetHorizontalCoffin\OutputCoffin{}
+% \SetHorizontalCoffin\RedCoffin
+% {\color{red!20!white}\rule{0.2 in}{0.2 in}}
+% \JoinCoffins\OutputCoffin[vc,hc]\RedCoffin[vc,hc]
+% \SetHorizontalCoffin\BlueCoffin
+% {\color{blue!20!white}\rule{0.2 in}{0.2 in}}
+% \JoinCoffins\OutputCoffin[\RedCoffin-vc,\RedCoffin-hc]
+% \BlueCoffin[b,l]
+% \SetHorizontalCoffin\GreenCoffin
+% {\color{green!20!white}\rule{0.2 in}{0.2 in}}
+% \JoinCoffins\OutputCoffin[\BlueCoffin-vc,\BlueCoffin-hc]
+% \GreenCoffin[b,l]
+% \SetHorizontalCoffin\YellowCoffin
+% {\color{yellow!20!white}\rule{0.2 in}{0.2 in}}
+% \JoinCoffins\OutputCoffin[\GreenCoffin-vc,\GreenCoffin-hc]
+% \YellowCoffin[b,l]
+% \SetHorizontalCoffin \OrangeCoffin
+% {\color{orange!20!white}\rule{0.2 in}{0.2 in}}
+% \JoinCoffins\OutputCoffin[\BlueCoffin-t,\BlueCoffin-l]
+% \OrangeCoffin[b,r]
+% \TypesetCoffin\OutputCoffin
+% \end{verbatim}
+% This process begins by setting up \cs{OutputCoffin} to hold the joined
+% output. Each join then takes place placing the new addition relative
+% to the previous one. As each coffin joined has a unique name it is
+% possible to align relative to each one of the component parts of the
+% assembly. This is illustrated by the addition of the final
+% \cs{OrangeCoffin} based on the earlier placement of the
+% \cs{BlueCoffin}.
+% \begin{figure}
+% \centering
+% \SetHorizontalCoffin\OutputCoffin{}
+% \SetHorizontalCoffin\RedCoffin
+% {\color{red!20!white}\rule{0.2 in}{0.2 in}}
+% \JoinCoffins\OutputCoffin[vc,hc]\RedCoffin[vc,hc]
+% \SetHorizontalCoffin\BlueCoffin
+% {\color{blue!20!white}\rule{0.2 in}{0.2 in}}
+% \JoinCoffins\OutputCoffin[\RedCoffin-vc,\RedCoffin-hc]
+% \BlueCoffin[b,l]
+% \SetHorizontalCoffin\GreenCoffin
+% {\color{green!20!white}\rule{0.2 in}{0.2 in}}
+% \JoinCoffins\OutputCoffin[\BlueCoffin-vc,\BlueCoffin-hc]
+% \GreenCoffin[b,l]
+% \SetHorizontalCoffin\YellowCoffin
+% {\color{yellow!20!white}\rule{0.2 in}{0.2 in}}
+% \JoinCoffins\OutputCoffin[\GreenCoffin-vc,\GreenCoffin-hc]
+% \YellowCoffin[b,l]
+% \SetHorizontalCoffin \OrangeCoffin
+% {\color{orange!20!white}\rule{0.2 in}{0.2 in}}
+% \JoinCoffins\OutputCoffin[\BlueCoffin-t,\BlueCoffin-l]
+% \OrangeCoffin[b,r]
+% \TypesetCoffin\OutputCoffin
+% \caption{Aligning coffins using poles from previous operations.}
+% \label{fgr:nested}
+% \end{figure}
+%
+% \section{Typesetting coffins}
+%
+% \begin{function}{\TypesetCoffin}
+% \begin{syntax}
+% \cs{TypesetCoffin}
+% ~~\meta{coffin} [ \meta{pole1} , \meta{pole2} ]
+% ~~( \meta{x-offset} , \meta{y-offset} )
+% \end{syntax}
+% Typesetting is carried out by first calculating \meta{handle}, the
+% point of intersection of \meta{pole1} and \meta{pole2}. This is an
+% optional argument, and if not given then |(H,l)|, the \TeX{}
+% reference point of the underlying box, is used. The coffin
+% is then typeset such that the relationship between the current
+% reference point in the document and the \meta{handle} is described
+% by the \meta{x-offset} and \meta{y-offset}. This \meta{offset} is
+% optional, and if not given |(0 pt, 0 pt)| is used. Typesetting a
+% coffin is therefore analogous to carrying out an alignment where the
+% \enquote{parent} coffin is the current insertion point.
+% \end{function}
+%
+% \section{Diagnostic functions}
+%
+% Diagnostic data for following the coffin-building process is
+% available both graphically and at the terminal. This reflects the
+% fact that coffins are visual constructs.
+%
+% \begin{function}{\DisplayCoffinHandles}
+% \begin{syntax}
+% \cs{DisplayCoffinHandles} \meta{coffin} \Arg{colour}
+% \end{syntax}
+% This function first calculates the intersections between all of
+% the \meta{poles} of the \meta{coffin} to give a set of
+% \meta{handles}. It then prints the \meta{coffin} at the current
+% location in the source, with the position of the \meta{handles}
+% marked on the coffin. The \meta{handles} will be labelled as part
+% of this process: the locations of the \meta{handles} and the labels
+% are both printed in the \meta{colour} specified.
+% \end{function}
+%
+% \begin{function}{\MarkCoffinHandle}
+% \begin{syntax}
+% \cs{MarkCoffinHandle} \meta{coffin}
+% ~~[ \meta{pole1} , \meta{pole2} ] \Arg{colour}
+% \end{syntax}
+% This function first calculates the \meta{handle} for the
+% \meta{coffin} as defined by the intersection of \meta{pole1} and
+% \meta{pole2}. It then marks the position of the \meta{handle}
+% on the \meta{coffin}. The \meta{handle} will be labelled as part of
+% this process: the location of the \meta{handle} and the label are
+% both printed in the \meta{colour} specified. If no \meta{poles} are
+% give, the default |(H,l)| is used.
+% \end{function}
+%
+% \begin{function}{\ShowCoffinStructure}
+% \begin{syntax}
+% \cs{ShowCoffinStructure} \meta{coffin}
+% \end{syntax}
+% This function shows the structural information about the
+% \meta{coffin} in the terminal. The width, height and depth of the
+% typeset material are given, along with the location of all of the
+% poles of the coffin. For example, for the rotated coffin in
+% Figure~\ref{fgr:rotation}, the output of \cs{ShowCoffinStructure}
+% is:
+% \begin{verbatim}
+% Size of coffin \ExampleCoffin:
+% > ht = 72.26999pt
+% > dp = 0.0pt
+% > wd = 72.26999pt
+%
+% Poles of coffin \ExampleCoffin:
+% > l => {0pt}{0pt}{0pt}{1000pt}
+% > B => {0pt}{0pt}{1000pt}{0pt}
+% > H => {0pt}{0pt}{1000pt}{0pt}
+% > T => {0pt}{0pt}{1000pt}{0pt}
+% > hc => {36.135pt}{0pt}{0pt}{1000pt}
+% > r => {72.26999pt}{0pt}{0pt}{1000pt}
+% > vc => {0pt}{36.135pt}{1000pt}{0pt}
+% > t => {0pt}{72.26999pt}{1000pt}{0pt}
+% > b => {0pt}{0.0pt}{1000pt}{0pt}.
+% <argument> ...ffin_show_aux:w \l_coffin_tmp_tl }
+% \end{verbatim}
+% Notice that the poles of a coffin are defined by four values:
+% the $x$ and $y$ co-ordinates of a point that the pole
+% passes through and the $x$- and $y$-components of a
+% vector denoting the direction of the pole. It is the ratio between
+% the later, rather than the absolute values, which determines the
+% direction of the pole.
+% \end{function}
+%
+% \end{documentation}
+%
+% \begin{implementation}
+%
+% \section{Implementation}
+%
+% \begin{macrocode}
+%<*package>
+% \end{macrocode}
+%
+% \begin{macrocode}
+\ProvidesExplPackage
+ {\ExplFileName}{\ExplFileDate}{\ExplFileVersion}{\ExplFileDescription}
+% \end{macrocode}
+%
+%
+% \begin{variable}
+% {
+% \l_coffin_A_hpole_tl ,
+% \l_coffin_A_vpole_tl ,
+% \l_coffin_B_hpole_tl ,
+% \l_coffin_B_vpole_tl ,
+% \l_coffin_bound_box_grow_bool ,
+% \l_coffin_hoffset_dim ,
+% \l_coffin_voffset_dim
+% }
+% Key--value definitions for the alignment system. With the exception
+% of \texttt{grow-bounding-box}, all of these have to be given with a
+% value.
+% \begin{macrocode}
+\keys_define:nn { coffin }
+ {
+ coffin1-hpole .tl_set:N = \l_coffin_A_hpole_tl ,
+ coffin1-hpole .value_required: ,
+ coffin1-vpole .tl_set:N = \l_coffin_A_vpole_tl ,
+ coffin1-vpole .value_required: ,
+ coffin2-hpole .tl_set:N = \l_coffin_B_hpole_tl ,
+ coffin2-hpole .value_required: ,
+ coffin2-vpole .tl_set:N = \l_coffin_B_vpole_tl ,
+ coffin2-vpole .value_required: ,
+ grow-bounding-box .bool_set:N = \l_coffin_bound_box_grow_bool ,
+ grow-bounding-box .default:n = true ,
+ hoffset .dim_set:N = \l_coffin_hoffset_dim ,
+ hoffset .value_required: ,
+ voffset .dim_set:N = \l_coffin_voffset_dim ,
+ voffset .value_required:
+ }
+\keys_set:nn { coffin }
+ {
+ coffin1-hpole = H ,
+ coffin1-vpole = l ,
+ coffin2-hpole = H ,
+ coffin2-vpole = l ,
+ grow-bounding-box = true ,
+ hoffset = 0 pt ,
+ voffset = 0 pt
+ }
+% \end{macrocode}
+% \end{variable}
+%
+% A lot of this is more-or-less just passing data straight through.
+%
+% \begin{macro}{\NewCoffin}
+% This is a very easy conversion.
+% \begin{macrocode}
+\NewDocumentCommand \NewCoffin { m }
+ { \coffin_new:N #1 }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SetHorizontalCoffin}
+% \begin{macro}{\SetVerticalCoffin}
+% These are again straight-forward translations.
+% \begin{macrocode}
+\NewDocumentCommand \SetHorizontalCoffin { m +m }
+ { \hcoffin_set:Nn #1 {#2} }
+\NewDocumentCommand \SetVerticalCoffin { m m +m }
+ { \vcoffin_set:Nnn #1 {#2} {#3} }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\SetHorizontalPole}
+% \begin{macro}{\SetVerticalPole}
+% Again straight-forward
+% \begin{macrocode}
+\NewDocumentCommand \SetHorizontalPole { m m m }
+ { \coffin_set_horizontal_pole:Nnn #1 {#2} {#3} }
+\NewDocumentCommand \SetVerticalPole { m m m }
+ { \coffin_set_vertical_pole:Nnn #1 {#2} {#3} }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\JoinCoffins}
+% The \cs{JoinCoffins} function needs to do a bit of work on the input
+% syntax, as there are a number of optional arguments to worry about.
+% The idea here is that \cs{JoinCoffins} can be used to either expand
+% the bounding box of \meta{coffin1} or add \meta{coffin2} without any
+% expansion of the bounding box. There are also the two handle positions
+% and the offset to sort out.
+% \begin{macrocode}
+\NewDocumentCommand \JoinCoffins
+ {
+ o
+ s
+ m
+ > { \SplitArgument { 1 } { , } } O { H , l }
+ m
+ > { \SplitArgument { 1 } { , } } O { H , l }
+ > { \SplitArgument { 1 } { , } } D ( ) { 0 pt , 0 pt }
+ }
+ {
+ \IfNoValueTF {#1}
+ {
+ \IfBooleanTF #2
+ { \coffin_attach:NnnNnnnn #3 #4 #5 #6 #7 }
+ { \coffin_join:NnnNnnnn #3 #4 #5 #6 #7 }
+ }
+ {
+ \group_begin:
+ \keys_set:nn { coffin } {#1}
+ \tl_set:Nx \l_coffin_tmp_tl
+ {
+ \group_end:
+ \bool_if:NTF \l_coffin_bound_box_grow_bool
+ { \coffin_join:NnnNnnnn }
+ { \coffin_attach:NnnNnnnn }
+ \exp_not:N #3
+ { \exp_not:o { \l_coffin_A_hpole_tl } }
+ { \exp_not:o { \l_coffin_A_vpole_tl } }
+ \exp_not:N #5
+ { \exp_not:o { \l_coffin_B_hpole_tl } }
+ { \exp_not:o { \l_coffin_B_vpole_tl } }
+ { \dim_use:N \l_coffin_hoffset_dim }
+ { \dim_use:N \l_coffin_voffset_dim }
+ }
+ \l_coffin_tmp_tl
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\TypesetCoffin}
+% For typesetting coffins there are two optional arguments, both of
+% which need to be split. This is a simpler case of the code needed for
+% \cs{JoinCoffins}.
+% \begin{macrocode}
+\NewDocumentCommand \TypesetCoffin
+ {
+ m
+ > { \SplitArgument { 1 } { , } } O { H , l }
+ > { \SplitArgument { 1 } { , } } D ( ) { 0 pt , 0 pt }
+ }
+ { \coffin_typeset:Nnnnn #1 #2 #3 }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\RotateCoffin}
+% \begin{macro}{\ResizeCoffin}
+% \begin{macro}{\ScaleCoffin}
+% Mores straight-forward copies.
+% \begin{macrocode}
+\NewDocumentCommand \RotateCoffin { m m }
+ { \coffin_rotate:Nn #1 {#2} }
+\NewDocumentCommand \ResizeCoffin { m m m }
+ { \coffin_resize:Nnn #1 {#2} {#3} }
+\NewDocumentCommand \ScaleCoffin { m m m }
+ { \coffin_scale:Nnn #1 {#2} {#3} }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\DisplayCoffinHandles}
+% Displaying all of the handles is a bit easier, as there is no need
+% to worry about the handle.
+% \begin{macrocode}
+\NewDocumentCommand \DisplayCoffinHandles { m m }
+ {
+ \cs_if_exist:cTF { l_coffin_poles_ \int_value:w #1 _prop }
+ { \coffin_display_handles:Nn #1 {#2} }
+ { \msg_kernel_error:nx { unknown-coffin } { \token_to_str:N #1 } }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\MarkCoffinHandle}
+% Marking a handle requires a bit of work with the input, so that
+% the design-level interface is \enquote{nice}.
+% \begin{macrocode}
+\NewDocumentCommand \MarkCoffinHandle
+ { m > { \SplitArgument { 1 } { , } } O { H , l } m }
+ {
+ \cs_if_exist:cTF { l_coffin_poles_ \int_value:w #1 _prop }
+ { \coffin_mark_handle:Nnnn #1 #2 {#3} }
+ { \msg_kernel_error:nx { unknown-coffin } { \token_to_str:N #1 }
+ }
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\ShowCoffinStructure}
+% Back again to easy-to-implement functions.
+% \begin{macrocode}
+\NewDocumentCommand \ShowCoffinStructure { m }
+ { \coffin_show_structure:N #1 }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macrocode}
+%</package>
+% \end{macrocode}
+%
+% \end{implementation}
+%
+% \PrintIndex \ No newline at end of file