diff options
author | Karl Berry <karl@freefriends.org> | 2011-08-29 00:08:58 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2011-08-29 00:08:58 +0000 |
commit | 62ea3c38421c330e364e1b53c366715efe3c7554 (patch) | |
tree | f323abbf0bd2346b481fc35187c6ec2d50ce2d1a /Master/texmf-dist | |
parent | 0a90bbc7d05e8e767bb8992e0ed6180206ae2bc7 (diff) |
l3kernel 2678 (28aug11)
git-svn-id: svn://tug.org/texlive/trunk@23738 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist')
56 files changed, 5104 insertions, 1303 deletions
diff --git a/Master/texmf-dist/doc/latex/l3kernel/README b/Master/texmf-dist/doc/latex/l3kernel/README index 9281d08f4c1..86bd894c7bc 100644 --- a/Master/texmf-dist/doc/latex/l3kernel/README +++ b/Master/texmf-dist/doc/latex/l3kernel/README @@ -1,8 +1,7 @@ +An Experimental LaTeX3 Programming Convention +============================================= - An Experimental LaTeX3 Programming Convention - ============================================= - - 2011/05/10 + 2011/08/22 WHERE TO GET IT @@ -85,5 +84,5 @@ discussion should be directed to the LaTeX-L lists. ===================================================================== ---- Copyright 1998-2011 The LaTeX3 Project. All rights reserved --- +Copyright 1998-2011 The LaTeX3 Project. All rights reserved diff --git a/Master/texmf-dist/doc/latex/l3kernel/expl3.pdf b/Master/texmf-dist/doc/latex/l3kernel/expl3.pdf Binary files differindex 33e0e3d0264..c069babd84f 100644 --- a/Master/texmf-dist/doc/latex/l3kernel/expl3.pdf +++ b/Master/texmf-dist/doc/latex/l3kernel/expl3.pdf diff --git a/Master/texmf-dist/doc/latex/l3kernel/interface3.pdf b/Master/texmf-dist/doc/latex/l3kernel/interface3.pdf Binary files differnew file mode 100644 index 00000000000..0ef0de9cdc6 --- /dev/null +++ b/Master/texmf-dist/doc/latex/l3kernel/interface3.pdf diff --git a/Master/texmf-dist/doc/latex/l3kernel/interface3.tex b/Master/texmf-dist/doc/latex/l3kernel/interface3.tex new file mode 100644 index 00000000000..f4c4fa4e2bf --- /dev/null +++ b/Master/texmf-dist/doc/latex/l3kernel/interface3.tex @@ -0,0 +1,89 @@ +% \iffalse meta-comment +% +%% File: interfaces3.tex Copyright (C) 1990-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 "expl3 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 LaTeX3 Project. +%% +%% ----------------------------------------------------------------------- +% +% \fi + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% This document will typeset the LaTeX3 interface descriptions a single +% document. This will produce quite a large file (more than 170 pages +% currently). +% +% There is also a full version of the sources (source3.tex) which additionally +% also typesets the command implementations. +% +% Do not forget to generate the index (as explained on the terminal output +% near the end of the run)! +% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + +\documentclass{l3doc} +\listfiles + +\begin{document} + +\title{The \LaTeX3 Interfaces} +\author{% + The \LaTeX3 Project\thanks + {% + E-mail: + \href{mailto:latex-team@latex-project.org} + {latex-team@latex-project.org}% + }% +} + +\pagenumbering{roman} +\maketitle + +% +% First load all modules and typeset the documentation parts +% + +\input{source3body} % all the individual modules + +\clearpage + +\begingroup + \def\endash{--} + \catcode`\-\active + \def-{\futurelet\temp\indexdash} + \def\indexdash{\ifx\temp-\endash\fi} + \DelayPrintIndex +\endgroup + +\end{document} + + diff --git a/Master/texmf-dist/doc/latex/l3kernel/l3styleguide.pdf b/Master/texmf-dist/doc/latex/l3kernel/l3styleguide.pdf Binary files differnew file mode 100644 index 00000000000..13d7af542b8 --- /dev/null +++ b/Master/texmf-dist/doc/latex/l3kernel/l3styleguide.pdf diff --git a/Master/texmf-dist/doc/latex/l3kernel/l3styleguide.tex b/Master/texmf-dist/doc/latex/l3kernel/l3styleguide.tex new file mode 100644 index 00000000000..b93ebe3fe79 --- /dev/null +++ b/Master/texmf-dist/doc/latex/l3kernel/l3styleguide.tex @@ -0,0 +1,174 @@ +\iffalse meta-comment + +File l3styleguide.tex Copyright (C) 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 "expl3 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. + +\fi + +\documentclass{l3doc} +\usepackage{svn-multi} + +\svnid{$Id: l3styleguide.tex 2328 2011-05-08 07:01:23Z joseph $} +\def\filedate{\svnfileyear/\svnfilemonth/\svnfileday} + +\title{% + The \LaTeX3 kernel: style guide for code authors% + \thanks + {% + This file describes v\svnfilerev, + last revised \filedate. + }% +} +\author{% + The \LaTeX3 Project\thanks + {% + E-mail: + \href{mailto:latex-team@latex-project.org}% + {latex-team@latex-project.org}% + }% +} +\date{Released \filedate} + +\begin{document} + +\maketitle + +\tableofcontents + +\section{Introduction} + +This document is intended as a style guide for authors of code and +documentation for the \LaTeX3 kernel. It covers both aspects of coding +style and the formatting of the sources. The aim of providing these +guidelines is help ensure consistency of the code and sources from +different authors. Experience suggests that in the long-term this helps +with maintenance. There will of course be places where there are +exceptions to these guidelines: common sense should always be +applied! + +\section{Documentation style} + +\LaTeX3 source and documentation should be written using the document +class \cls{l3doc} in \file{dtx} format. This class provides a number +of logical mark up elements, which should be used where possible. +In the main, this is standard \LaTeX{} practice, but there are a +few points to highlight: +\begin{itemize} + \item + Where possible, use \cs{cs} to mark up control sequences + rather than using a verbatim environment. + \item + Arguments which are given in braces should be marked using + \cs{Arg} when code-level functions are discussed, but using + \cs{marg} for document functions. + \item + The names \TeX{}, \LaTeX{}, \emph{etc}.\ use the normal logical mark + up followed by an empty group (|{}|), with the exception of |\LaTeX3|, + where the number should follow directly. + \item + Where in line verbatim text is used, it should be marked up + using the \verb=|...|= construct (\emph{i.e.}~vertical bars delimit + the verbatim text). + \item In line quotes should be marked up using the \cs{enquote} + function. + \item + Where numbers in the source have a mathematical meaning, + they should be included in math mode. Such in-line math mode + material should be marked up using |$...$| and \emph{not} + |\(...\)|. +\end{itemize} + +Line length in the source files should to be under $80$ +characters where possible, as this helps keep everything on the screen +when editing files. In the \file{dtx} format, documentation lines start +with a \texttt{\%}, which is usually followed by a space to leave a +\enquote{comment margin} at the start of each line. + +As with code indenting (see later), nested environments and arguments +should be indented by (at least) two spaces to make the nature of the nesting +clear. Thus for example a typical arrangement for the \env{function} +environment might be +\begin{verbatim*} +\begin{function}{\seq_gclear:N, \seq_gclear:c} + \begin{syntax} + \cs{seq_gclear:N} \meta{sequence} + \end{syntax} + Clears all entries from the \meta{sequence} globally. +\end{function} +\end{verbatim*} +The \enquote{outer} \verb*|% \begin{function}| should have the customary +space after the |%| character at the start of the line. + +In general, a single \env{function} or \env{macro} environment should be +used for a group of closely-related functions, for example argument +specification variants. In such cases, a comma-separated list should be +used, as shown in the preceding example. + +\section{Format of the code itself} + +The requirement for less than $80$ characters per line applies to the code +itself as well as the surrounding documentation. A number of the general +style principals for \LaTeX3 code apply: these are described in the following +paragraph and an example is then given. + +With the exception of simple runs of parameter (|{#1}|, |#1#2|, +\emph{etc.}), everything should divided up using spaces to make the code +more readable. In general, these will be single spaces, but in some +places it makes more sense to align parts of the code to emphasise +similarity. (Tabs should not be used for introducing white space.) + +Each conceptually-separate step in a function should be on a separate +line, to make the meaning clearer. Hence the \texttt{false} branch +in the example uses two lines for the two auxiliary function uses. + +Within the definition, a two-space indent should be used to show each +\enquote{level} of code. Thus in the example \cs{tl_if_empty:nTF} is +indented by two spaces, but the two branches are indented by four +spaces. Within the \texttt{false} branch, the need for multiple lines +means that an additional two-space indent should be used to show that +these lines are all part of the brace group. + +The result of these lay-out conventions is code which will in general +look like the example: +\begin{verbatim*} +\cs_new_nopar:Npn \module_foo:nn #1#2 + { + \tl_if_empty:nTF {#1} + { \module_foo_aux:n { X #2 } } + { + \module_foo_aux:nn {#1} {#2} + \module_foo_aux:n {#1#2} + } + } +\end{verbatim*} + +\section{Code conventions} + +When using \cs{cs_generate_variant:Nn}, group related variants together +to make the pattern clearer. A common example is variants of a function +which has an \texttt{N}-type first argument: +\begin{verbatim*} +\cs_generate_variant:Nn \foo:Nn { NV , No } +\cs_generate_variant:Nn \foo:Nn { c , cV , co } +\end{verbatim*} + +There are cases where omitting braces from \texttt{o}-type arguments +is desirable for performance reasons. This should only be done if the +argument is a single token, thus for example +\begin{verbatim} +\tl_set:No \l_some_tl \l_some_other_tl +\end{verbatim} +remains clear and can be used where appropriate. + +\end{document} diff --git a/Master/texmf-dist/doc/latex/l3kernel/l3syntax-changes.pdf b/Master/texmf-dist/doc/latex/l3kernel/l3syntax-changes.pdf Binary files differnew file mode 100644 index 00000000000..48e130d080b --- /dev/null +++ b/Master/texmf-dist/doc/latex/l3kernel/l3syntax-changes.pdf diff --git a/Master/texmf-dist/doc/latex/l3kernel/l3syntax-changes.tex b/Master/texmf-dist/doc/latex/l3kernel/l3syntax-changes.tex new file mode 100644 index 00000000000..8be4aa773d1 --- /dev/null +++ b/Master/texmf-dist/doc/latex/l3kernel/l3syntax-changes.tex @@ -0,0 +1,73 @@ +\iffalse meta-comment + +File l3syntax-changes.tex Copyright (C) 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 "expl3 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. + +\fi + +\documentclass{l3doc} + +\usepackage{svn-multi} + +\svnid{$Id: l3syntax-changes.tex 2626 2011-08-18 19:22:19Z joseph $} +\def\filedate{\svnfileyear/\svnfilemonth/\svnfileday} + +\title{% + Syntax changes in \LaTeX3 functions + \thanks + {% + This file describes v\svnfilerev, + last revised \filedate. + }% +} +\author{% + The \LaTeX3 Project\thanks + {% + E-mail: + \href{mailto:latex-team@latex-project.org}% + {latex-team@latex-project.org}% + }% +} +\date{Released \filedate} + +\newcommand{\TF}{\textit{(TF)}} + +\begin{document} + +\maketitle + +This file lists functions whose syntax has changed after August 2011, +with an approximate date. + +\section{August 2011} + +\begin{itemize} + \item \cs{tl_if_single:n\TF} recognized any non-zero number of + explicit spaces as \meta{true}, and did not ignore trailing spaces. + Now it is \meta{true} for + \[ + \meta{optional spaces} + \meta{normal token or brace group} + \meta{optional spaces}. + \] + \item \cs{tl_reverse:n} stripped outer braces and lost unprotected spaces. + Now it keeps spaces, leaves unbraced single tokens unbraced, and + braced groups braced. + \item \cs{tl_trim_spaces:n} only removed one leading and trailing space. + Now removes recursively. Also, on the left it used to strip implicit + and explicit spaces with any character code. Now it strips only explicit + space characters $(32,10)$. + \end{itemize} + +\end{document}
\ No newline at end of file diff --git a/Master/texmf-dist/doc/latex/l3kernel/source3.pdf b/Master/texmf-dist/doc/latex/l3kernel/source3.pdf Binary files differindex cf5bd891a30..1a2a6307e59 100644 --- a/Master/texmf-dist/doc/latex/l3kernel/source3.pdf +++ b/Master/texmf-dist/doc/latex/l3kernel/source3.pdf diff --git a/Master/texmf-dist/doc/latex/l3kernel/source3.tex b/Master/texmf-dist/doc/latex/l3kernel/source3.tex new file mode 100644 index 00000000000..927e483cce9 --- /dev/null +++ b/Master/texmf-dist/doc/latex/l3kernel/source3.tex @@ -0,0 +1,106 @@ +% \iffalse meta-comment +% +%% File: source3.tex Copyright (C) 1990-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 "expl3 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 LaTeX3 Project. +%% +%% ----------------------------------------------------------------------- +% +% \fi + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% This document will typeset the LaTeX3 sources as a single document. +% This will produce quite a large file (more than 400 pages). +% +% There is also a shorter version (interface3.tex) that only typesets the +% command % interface descriptions. +% +% Do not forget to generate the index (as explained on the terminal output +% near the end of the run)! +% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\documentclass{l3doc} +\listfiles + +\begin{document} + +\title{The \LaTeX3 Sources} +\author{% + The \LaTeX3 Project\thanks + {% + E-mail: + \href{mailto:latex-team@latex-project.org} + {latex-team@latex-project.org}% + }% +} + +\pagenumbering{roman} +\maketitle + +% +% First load all modules and typeset the documentation parts +% + +\input{source3body} % all the individual modules + +% +% Now reload all modules and typeset the implementation parts +% + +\part{Implementation} + +\def\maketitle{} +\EnableImplementation +\DisableDocumentation +\DocInputAgain + +\clearpage +\pagestyle{headings} + +% Make TeX shut up. +\hbadness=10000 +\newcount\hbadness +\hfuzz=\maxdimen + +\PrintChanges +\clearpage + +\begingroup + \def\endash{--} + \catcode`\-\active + \def-{\futurelet\temp\indexdash} + \def\indexdash{\ifx\temp-\endash\fi} + + \DelayPrintIndex +\endgroup + +\end{document}
\ No newline at end of file diff --git a/Master/texmf-dist/doc/latex/l3kernel/source3body.tex b/Master/texmf-dist/doc/latex/l3kernel/source3body.tex new file mode 100644 index 00000000000..1caee5bd0e2 --- /dev/null +++ b/Master/texmf-dist/doc/latex/l3kernel/source3body.tex @@ -0,0 +1,392 @@ +% \iffalse meta-comment +% +%% File: source3body.tex Copyright (C) 1990-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 "expl3 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 LaTeX3 Project. +%% +%% ----------------------------------------------------------------------- +% +% \fi + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% This file is used by +% +% source3.tex % documentation including implementation +% +% interface3.tex % only interface documentation +% +% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + +\begin{abstract} + +\setlength\parindent{0pt} +\setlength\parskip{\baselineskip} + +\noindent +This is the reference documentation for the \pkg{expl3} +programming environment. The \pkg{expl3} modules set up an experimental +naming scheme for \LaTeX{} commands, which allow the \LaTeX{} programmer +to systematically name functions and variables, and specify the argument +types of functions. + +The \TeX{} and \eTeX{} primitives are all given a new name according to +these conventions. However, in the main direct use of the primitives is +not required or encouraged: the \pkg{expl3} modules define an +independent low-level \LaTeX3 programming language. + +At present, the \pkg{expl3} modules are designed to be loaded on top of +\LaTeXe{}. In time, a \LaTeX3 format will be produced based on this code. +This allows the code to be used in \LaTeXe{} packages \emph{now} while a +stand-alone \LaTeX3 is developed. + +\begin{bfseries} + While \pkg{expl3} is still experimental, the bundle is now regarded as + broadly stable. The syntax conventions and functions provided are now + ready for wider use. There may still be changes to some functions, but + these will be minor when compared to the scope of \pkg{expl3}. + + New modules will be added to the distributed version of \pkg{expl3} as + they reach maturity. +\end{bfseries} + +\end{abstract} + +\clearpage + +{% + \def\\{:}% fix "newlines" in the ToC + \tableofcontents +} + +\clearpage +\pagenumbering{arabic} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% Each of the following \DocInput lines includes a file with extension +% .dtx. Each of these files may be typeset separately. For instance +% pdflatex l3box.dtx +% will typeset the source of the LaTeX3 box commands. If you use the +% Makefile, the index will be generated automatically; e.g., +% make doc F=l3box +% +% If this file is processed, each of these separate dtx files will be +% contained as a part of a single document. +% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\makeatletter +\def\partname{Part} +\def\maketitle{\part{\@title}} +\let\thanks\@gobble +\let\DelayPrintIndex\PrintIndex +\let\PrintIndex\@empty +\makeatother + +\part{Introduction to \pkg{expl3} and this document} + +This document is intended to act as a comprehensive reference manual +for the \pkg{expl3} language. A general guide to the \LaTeX3 +programming language is found in \href{expl3.pdf}{expl3.pdf}. + +\section{Naming functions and variables} + +\LaTeX3 does not use \texttt{@} as a \enquote{letter} for defining +internal macros. Instead, the symbols |_| and \texttt{:} +are used in internal macro names to provide structure. The name of +each \emph{function} is divided into logical units using \texttt{_}, +while \texttt{:} separates the \emph{name} of the function from the +\emph{argument specifier} (\enquote{arg-spec}). This describes the arguments +expected by the function. In most cases, each argument is represented +by a single letter. The complete list of arg-spec letters for a function +is referred to as the \emph{signature} of the function. + +Each function name starts with the \emph{module} to which it belongs. +Thus apart from a small number of very basic functions, all \pkg{expl3} +function names contain at least one underscore to divide the module +name from the descriptive name of the function. For example, all +functions concerned with comma lists are in module \texttt{clist} and +begin \cs{clist_}. + +Every function must include an argument specifier. For functions which +take no arguments, this will be blank and the function name will end +\texttt{:}. Most functions take one or more arguments, and use the +following argument specifiers: +\begin{description} + \item[\texttt{D}] The \texttt{D} specifier means \emph{do not use}. + All of the \TeX{} primitives are initially \cs{let} to a \texttt{D} + name, and some are then given a second name. Only the kernel + team should use anything with a \texttt{D} specifier! + \item[\texttt{N} and \texttt{n}] These mean \emph{no manipulation}, + of a single token for \texttt{N} and of a set of tokens given in + braces for \texttt{n}. Both pass the argument though exactly as + given. Usually, if you use a single token for an \texttt{n} argument, + all will be well. + \item[\texttt{c}] This means \emph{csname}, and indicates that the + argument will be turned into a csname before being used. So + So \cs{foo:c} |{ArgumentOne}| will act in the same way as \cs{foo:N} + \cs{ArgumentOne}. + \item[\texttt{V} and \texttt{v}] These mean \emph{value + of variable}. The \texttt{V} and \texttt{v} specifiers are used to + get the content of a variable without needing to worry about the + underlying \TeX{} structure containing the data. A \texttt{V} + argument will be a single token (similar to \texttt{N}), for example + \cs{foo:V} \cs{MyVariable}; on the other hand, using \texttt{v} a + csname is constructed first, and then the value is recovered, for + example \cs{foo:v} |{MyVariable}|. + \item[\texttt{o}] This means \emph{expansion once}. In general, the + \texttt{V} and \texttt{v} specifiers are favoured over \texttt{o} + for recovering stored information. However, \texttt{o} is useful + for correctly processing information with delimited arguments. + \item[\texttt{x}] The \texttt{x} specifier stands for \emph{exhaustive + expansion}: the plain \TeX{} \cs{edef}. + \item[\texttt{f}] The \texttt{f} specifier stands for \emph{full + expansion}, and in contrast to \emph{x} stops at the first + non-expandable item without trying to execute it. + \item[\texttt{T} and \texttt{F}] For logic tests, there are the branch + specifiers \texttt{T} (\emph{true}) and \texttt{F} (\emph{false}). + Both specifiers treat the input in the same way as \texttt{n} (no + change), but make the logic much easier to see. + \item[\texttt{p}] The letter \texttt{p} indicates \TeX{} + \emph{parameters}. Normally this will be used for delimited + functions as \pkg{expl3} provides better methods for creating simple + sequential arguments. + \item[\texttt{w}] Finally, there is the \texttt{w} specifier for + \emph{weird} arguments. This covers everything else, but mainly + applies to delimited values (where the argument must be terminated + by some arbitrary string). +\end{description} +Notice that the argument specifier describes how the argument is +processed prior to being passed to the underlying function. For example, +\cs{foo:c} will take its argument, convert it to a control sequence and +pass it to \cs{foo:N}. + +Variables are named in a similar manner to functions, but begin with +a single letter to define the type of variable: +\begin{description} + \item[\texttt{c}] Constant: global parameters whose value should not + be changed. + \item[\texttt{g}] Parameters whose value should only be set globally. + \item[\texttt{l}] Parameters whose value should only be set locally. +\end{description} +Each variable name is then build up in a similar way to that of a +function, typically starting with the module\footnote{The module names are + not used in case of generic scratch registers defined in the data + type modules, e.g., the + \texttt{int} module contains some scratch variables called \cs{l_tmpa_int}, + \cs{l_tmpb_int}, and so on. In such a case adding the module name up front + to denote the module + and in the back to indicate the type, as in + \cs{l_int_tmpa_int} would be very unreadable.} name +and then a descriptive part. +Variables end with a short identifier to show the variable type: +\begin{description} + \item[\texttt{bool}] Either true or false. + \item[\texttt{box}] Box register. + \item[\texttt{clist}] Comma separated list. + \item[\texttt{coffin}] a \enquote{box with handles} --- a higher-level data + type for carrying out |box| alignment operations. + \item[\texttt{dim}] \enquote{Rigid} lengths. + \item[\texttt{fp}] floating-point values; + \item[\texttt{int}] Integer-valued count register. + \item[\texttt{prop}] Property list. + \item[\texttt{seq}] \enquote{Sequence}: a data-type used to implement lists + (with access at both ends) and stacks. + \item[\texttt{skip}] \enquote{Rubber} lengths. + \item[\texttt{stream}] An input or output stream (for reading from or + writing to, respectively). + \item[\texttt{tl}] Token list variables: placeholder for a token list. +\end{description} + +\subsection{Terminological inexactitude} + +A word of warning. In this document, and others referring to the \pkg{expl3} +programming modules, we often refer to \enquote{variables} and +\enquote{functions} as if they +were actual constructs from a real programming language. In truth, \TeX{} +is a macro processor, and functions are simply macros that may or may not take +arguments and expand to their replacement text. Many of the common variables +are \emph{also} macros, and if placed into the input stream will simply expand +to their definition as well~--- a \enquote{function} with no arguments and a +\enquote{token list variable} are in truth one and the same. On the other +hand, some \enquote{variables} are actually registers that must be +initialised and their values set and retrieved with specific functions. + +The conventions of the \pkg{expl3} code are designed to clearly separate the +ideas of \enquote{macros that contain data} and +\enquote{macros that contain code}, and a +consistent wrapper is applied to all forms of \enquote{data} whether they be +macros or +actually registers. This means that sometimes we will use phrases like +\enquote{the function returns a value}, when actually we just mean +\enquote{the macro expands to something}. Similarly, the term +\enquote{execute} might be used in place of \enquote{expand} +or it might refer to the more specific case of +\enquote{processing in \TeX's stomach} +(if you are familiar with the \TeX{}book parlance). + +If in doubt, please ask; chances are we've been hasty in writing certain +definitions and need to be told to tighten up our terminology. + +\section{Documentation conventions} + +This document is typeset with the experimental \pkg{l3doc} class; +several conventions are used to help describe the features of the code. +A number of conventions are used here to make the documentation clearer. + +Each group of related functions is given in a box. For a function with +a \enquote{user} name, this might read: +\begin{function}{\ExplSyntaxOn, \ExplSyntaxOff} + \begin{syntax} + \cs{ExplSyntaxOn} \dots{} \cs{ExplSyntaxOff} + \end{syntax} + The textual description of how the function works would appear here. The + syntax of the function is shown in mono-spaced text to the right of + the box. In this example, the function takes no arguments and so the + name of the function is simply reprinted. +\end{function} + +For programming functions, which use \texttt{_} and \texttt{:} in their name +there are a few additional conventions: If two related functions are given +with identical names but different argument specifiers, these are termed +\emph{variants} of each other, and the latter functions are printed in grey to +show this more clearly. They will carry out the same function but will take +different types of argument: +\begin{function}{\seq_new:N, \seq_new:c} + \begin{syntax} + \cs{seq_new:N} \meta{sequence} + \end{syntax} + When a number of variants are described, the arguments are usually + illustrated only for the base function. Here, \meta{sequence} indicates + that \cs{seq_new:N} expects the name of a sequence. From the argument + specifier, \cs{seq_new:c} also expects a sequence name, but as a + name rather than as a control sequence. Each argument given in the + illustration should be described in the following text. +\end{function} + +Some functions are fully expandable, which allows it to be used within +an \texttt{x}-type argument (in plain \TeX{} terms, inside an \cs{edef}). +These fully expandable functions are indicated in the documentation by +a star: +\begin{function}[EXP]{\cs_to_str:N} + \begin{syntax} + \cs{cs_to_str:N} \meta{cs} + \end{syntax} + As with other functions, some text should follow which explains how + the function works. Usually, only the star will indicate that the + function is expandable. In this case, the function expects a \meta{cs}, + shorthand for a \meta{control sequence}. +\end{function} + +Conditional (\texttt{if}) functions are normally defined in three variants, +with +\texttt{T}, \texttt{F} and \texttt{TF} argument specifiers. This allows +them to be used for different \enquote{true}/\enquote{false} branches, +depending on +which outcome the conditional is being used to test. To indicate this +without repetition, this information is given in a shortened form: +\begin{function}[EXP,pTF]{\xetex_if_engine:} + \begin{syntax} + \cs{xetex_if_engine:TF} \Arg{true code} \Arg{false code} + \end{syntax} + The underlining and italic of \texttt{TF} indicates that + \cs{xetex_if_engine:T}, \cs{xetex_if_engine:F} and + \cs{xetex_if_engine:TF} are all available. Usually, the illustration + will use the \texttt{TF} variant, and so both \meta{true code} + and \meta{false code} will be shown. The two variant forms \texttt{T} and + \texttt{F} take only \meta{true code} and \meta{false code}, respectively. + Here, the star also shows that this function is expandable. + With some minor exceptions, \emph{all} conditional functions in the + \pkg{expl3} modules should be defined in this way. +\end{function} + +Variables, constants and so on are described in a similar manner: +\begin{variable}{\l_tmpa_tl} + A short piece of text will describe the variable: there is no + syntax illustration in this case. +\end{variable} + +In some cases, the function is similar to one in \LaTeXe{} or plain \TeX{}. +In these cases, the text will include an extra \enquote{\textbf{\TeX{}hackers +note}} section: +\begin{function}[EXP]{\token_to_str:N} + \begin{syntax} + \cs{token_to_str:N} \meta{token} + \end{syntax} + The normal description text. + \begin{texnote} + Detail for the experienced \TeX{} or \LaTeXe\ programmer. In this + case, it would point out that this function is the \TeX{} primitive + \cs{string}. + \end{texnote} +\end{function} + +\section{Formal language conventions which apply generally} + +As this is a formal reference guide for \LaTeX3 programming, the descriptions +of functions are intended to be reasonably \enquote{complete}. However, there +is also a need to avoid repetition. Formal ideas which apply to general +classes of function are therefore summarised here. + +For tests which have a \texttt{TF} argument specification, the test if +evaluated to give a logically \texttt{TRUE} or \texttt{FALSE} result. +Depending on this result, either the \meta{true code} or the \meta{false code} +will be left in the input stream. In the case where the test is expandable, +and a predicate (|_p|) variant is available, the logical value determined by +the test is left in the input stream: this will typically be part of a larger +logical construct. + +\DisableImplementation + +\DocInput{l3bootstrap.dtx} +\DocInput{l3names.dtx} +\DocInput{l3basics.dtx} +\DocInput{l3expan.dtx} +\DocInput{l3prg.dtx} +\DocInput{l3quark.dtx} +\DocInput{l3token.dtx} +\DocInput{l3int.dtx} +\DocInput{l3skip.dtx} +\DocInput{l3tl.dtx} +\DocInput{l3seq.dtx} +\DocInput{l3clist.dtx} +\DocInput{l3prop.dtx} +\DocInput{l3box.dtx} +\DocInput{l3io.dtx} +\DocInput{l3msg.dtx} +\DocInput{l3keys.dtx} +\DocInput{l3file.dtx} +\DocInput{l3fp.dtx} +\DocInput{l3luatex.dtx} + +\endinput diff --git a/Master/texmf-dist/makeindex/l3kernel/l3doc.ist b/Master/texmf-dist/makeindex/l3kernel/l3doc.ist new file mode 100644 index 00000000000..e1496e34d73 --- /dev/null +++ b/Master/texmf-dist/makeindex/l3kernel/l3doc.ist @@ -0,0 +1,72 @@ +%% +%% This is file `l3doc.ist', +%% generated with the docstrip utility. +%% +%% The original source files were: +%% +%% l3doc.dtx (with options: `docist') +%% +%% +%% EXPERIMENTAL CODE +%% +%% Do not distribute this file without also distributing the +%% source files specified above. +%% +%% Do not distribute a modified version of this file. +%% +%% +%% File: l3doc.dtx Copyright (C) 1990-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 "expl3 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 LaTeX3 Project. +%% +%% ----------------------------------------------------------------------- +actual '=' +quote '!' +level '#' +preamble +"\n \\begin{theindex} \n \\makeatletter\\scan@allowedfalse\n" +postamble +"\n\n \\end{theindex}\n" +item_x1 "\\efill \n \\subitem " +item_x2 "\\efill \n \\subsubitem " +delim_0 "\\pfill " +delim_1 "\\pfill " +delim_2 "\\pfill " +lethead_prefix "{\\bfseries\\hfil " +lethead_suffix "\\hfil}\\nopagebreak\n" +lethead_flag 1 +heading_prefix "{\\bfseries\\hfil " +heading_suffix "\\hfil}\\nopagebreak\n" +headings_flag 1 + +page_precedence "rnaA" +%% +%% +%% End of file `l3doc.ist'. diff --git a/Master/texmf-dist/source/latex/l3kernel/expl3.dtx b/Master/texmf-dist/source/latex/l3kernel/expl3.dtx index 6de2ed0c0d2..0f30662fce5 100644 --- a/Master/texmf-dist/source/latex/l3kernel/expl3.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/expl3.dtx @@ -37,8 +37,8 @@ \RequirePackage{l3names} \def\ExplFileName{expl3} \def\ExplFileDescription{L3 Experimental code bundle wrapper} -\def\ExplFileDate{2011/08/17} -\def\ExplFileVersion{2607} +\def\ExplFileDate{2011/08/28} +\def\ExplFileVersion{2678} %</driver|package> %<*driver> \documentclass[full]{l3doc} @@ -725,6 +725,9 @@ % \explpkg{l3clist}{ % Methods for manipulating comma-separated token lists. % } +% \explpkg{l3coffins}{ +% Augmented box constructs for alignment operations. +% } % \explpkg{l3expan}{ % This is the argument expansion module discussed earlier in this % document. @@ -735,12 +738,9 @@ % \explpkg{l3io}{ % A module providing low level input and output functions. % } -% \explpkg{l3keyval}{ -% Low-level implementation for processing lists of the form -% \texttt{\{ key1=val1 , key2=val2 \}}. -% } % \explpkg{l3keys}{ -% Higher-level implementation of key--value methods: intended to work +% For processing lists of the form +% \texttt{\{ key1=val1 , key2=val2 \}}, intended to work % as a \LaTeX3 version of \pkg{xkeyval}/\pkg{kvoptions}, although % with input syntax more like that of \pkg{pgfkeys}. % } @@ -1010,10 +1010,10 @@ l3file, l3skip, l3box, - l3keyval, l3keys, l3fp, - l3luatex + l3luatex, + l3coffins } % \end{macrocode} % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3.ins b/Master/texmf-dist/source/latex/l3kernel/l3.ins deleted file mode 100644 index 9b28c54f15e..00000000000 --- a/Master/texmf-dist/source/latex/l3kernel/l3.ins +++ /dev/null @@ -1,68 +0,0 @@ -\iffalse meta-comment - -File l3.ins Copyright (C) 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 "expl3 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. - -\fi - -\input docstrip.tex -\askforoverwritefalse - -\preamble - -EXPERIMENTAL CODE - -Do not distribute this file without also distributing the -source files specified above. - -Do not distribute a modified version of this file. - -\endpreamble -% stop docstrip adding \endinput -\postamble -\endpostamble - -\keepsilent - -% ===== PACKAGE ONLY ====== -\generate{\file{expl3.sty} {\from{expl3.dtx} {package}}} -% ======================== -\generate{\file{l3bootstrap.sty}{\from{l3bootstrap.dtx}{package}}} -\generate{\file{l3names.sty} {\from{l3names.dtx} {package}}} -\generate{\file{l3basics.sty} {\from{l3basics.dtx} {package}}} -\generate{\file{l3expan.sty} {\from{l3expan.dtx} {package}}} -\generate{\file{l3tl.sty} {\from{l3tl.dtx} {package}}} -\generate{\file{l3seq.sty} {\from{l3seq.dtx} {package}}} -\generate{\file{l3int.sty} {\from{l3int.dtx} {package}}} -\generate{\file{l3quark.sty} {\from{l3quark.dtx} {package}}} -\generate{\file{l3prg.sty} {\from{l3prg.dtx} {package}}} -\generate{\file{l3clist.sty} {\from{l3clist.dtx} {package}}} -\generate{\file{l3token.sty} {\from{l3token.dtx} {package}}} -\generate{\file{l3prop.sty} {\from{l3prop.dtx} {package}}} -\generate{\file{l3msg.sty} {\from{l3msg.dtx} {package}}} -\generate{\file{l3io.sty} {\from{l3io.dtx} {package}}} -\generate{\file{l3file.sty} {\from{l3file.dtx} {package}}} -\generate{\file{l3skip.sty} {\from{l3skip.dtx} {package}}} -\generate{\file{l3box.sty} {\from{l3box.dtx} {package}}} -\generate{\file{l3keyval.sty} {\from{l3keyval.dtx} {package}}} -\generate{\file{l3keys.sty} {\from{l3keys.dtx} {package}}} -\generate{\file{l3fp.sty} {\from{l3fp.dtx} {package}}} -\generate{\file{l3luatex.sty} {\from{l3luatex.dtx} {package}}} - -\generate{\file{l3doc.cls} {\from{l3doc.dtx} {class}}} -\generate{\file{l3doc.ist} {\from{l3doc.dtx} {docist}}} - -\generate{\file{l3toks.sty} {\from{l3toks.dtx} {package}}} - -\endbatchfile diff --git a/Master/texmf-dist/source/latex/l3kernel/l3basics.dtx b/Master/texmf-dist/source/latex/l3kernel/l3basics.dtx index 52cc56c699a..62d8f1caca2 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3basics.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3basics.dtx @@ -35,7 +35,7 @@ % %<*driver|package> \RequirePackage{l3names} -\GetIdInfo$Id: l3basics.dtx 2493 2011-07-04 09:50:22Z bruno $ +\GetIdInfo$Id: l3basics.dtx 2665 2011-08-25 22:15:27Z joseph $ {L3 Experimental basic definitions} %</driver|package> %<*driver> @@ -1077,11 +1077,7 @@ % ~~\Arg{false code} % \end{syntax} % Compares the definition of two \meta{control sequences} and -% is logically \texttt{true} if the two are the same. The branching -% versions then leave either \meta{true code} or \meta{false code} -% in the input stream, as appropriate to the truth of the test and the -% variant of the function chosen. The logical truth of the test is left -% in the input stream by the predicate version. +% is logically \texttt{true} if the two are the same. % \end{function} % % \begin{function}[EXP,pTF]{\cs_if_exist:N, \cs_if_exist:c} @@ -1093,11 +1089,7 @@ % Tests whether the \meta{control sequence} is currently defined % (whether as a function or another control sequence type). Any % valid definition of \meta{control sequence} will evaluate as -% \texttt{true}. The branching versions then leave either -% \meta{true code} or \meta{false code} in the input stream, as -% appropriate to the truth of the test and the variant of the function -% chosen. The logical truth of the test is left in the input stream by -% the predicate version. +% \texttt{true}. % \end{function} % % \begin{function}[EXP,pTF]{\cs_if_free:N, \cs_if_free:c} @@ -1109,11 +1101,7 @@ % Tests whether the \meta{control sequence} is currently free to % be defined. This test will be \texttt{false} if the % \meta{control sequence} currently exists (as defined by -% \cs{cs_if_exist:N}). The branching versions then leave either -% \meta{true code} or \meta{false code} in the input stream, as -% appropriate to the truth of the test and the variant of the function -% chosen. The logical truth of the test is left in the input stream by -% the predicate version. +% \cs{cs_if_exist:N}). % \end{function} % % \subsection{Testing string equality} @@ -1133,11 +1121,7 @@ % \begin{verbatim} % \str_if_eq_p:xx { abc } { \tl_to_str:n { abc } } % \end{verbatim} -% is logically \texttt{true}. The branching versions then leave either -% \meta{true code} or \meta{false code} in the input stream, as -% appropriate to the truth of the test and the variant of the function -% chosen. The logical truth of the test is left in the input stream by -% the predicate version. All versions of these functions are fully +% is logically \texttt{true}. All versions of these functions are fully % expandable (including those involving an \texttt{x}-type % expansion). % \end{function} @@ -1148,30 +1132,21 @@ % \begin{syntax} % \cs{luatex_if_luatex:TF} \Arg{true code} \Arg{false code} % \end{syntax} -% Detects is the document is being compiled using \LuaTeX{}. The -% branching versions then leave either \meta{true code} or -% \meta{false code} in the input stream, as appropriate to the truth -% of the test and the variant of the function chosen. +% Detects is the document is being compiled using \LuaTeX{}. % \end{function} % % \begin{function}[EXP,TF]{\pdftex_if_engine:} % \begin{syntax} % \cs{pdftex_if_engine:TF} \Arg{true code} \Arg{false code} % \end{syntax} -% Detects is the document is being compiled using \pdfTeX{}. The -% branching versions then leave either \meta{true code} or -% \meta{false code} in the input stream, as appropriate to the truth -% of the test and the variant of the function chosen. +% Detects is the document is being compiled using \pdfTeX{}. % \end{function} % % \begin{function}[EXP,TF]{\xetex_if_engine:} % \begin{syntax} % \cs{xetex_if_engine:TF} \Arg{true code} \Arg{false code} % \end{syntax} -% Detects is the document is being compiled using \XeTeX{}. The -% branching versions then leave either \meta{true code} or -% \meta{false code} in the input stream, as appropriate to the truth -% of the test and the variant of the function chosen. +% Detects is the document is being compiled using \XeTeX{}. % \end{function} % % \begin{variable} diff --git a/Master/texmf-dist/source/latex/l3kernel/l3box.dtx b/Master/texmf-dist/source/latex/l3kernel/l3box.dtx index c2fb953d45b..8e5070145b4 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3box.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3box.dtx @@ -35,7 +35,7 @@ % %<*driver|package> \RequirePackage{l3names} -\GetIdInfo$Id: l3box.dtx 2595 2011-08-16 00:58:34Z bruno $ +\GetIdInfo$Id: l3box.dtx 2665 2011-08-25 22:15:27Z joseph $ {L3 Experimental boxes} %</driver|package> %<*driver> @@ -282,11 +282,6 @@ % \cs{box_if_empty:NTF} \meta{box} \Arg{true code} \Arg{false code} % \end{syntax} % Tests if \meta{box} is a empty (equal to \cs{c_empty_box}). -% The branching versions then leave either -% \meta{true code} or \meta{false code} in the input stream, as -% appropriate to the truth of the test and the variant of the function -% chosen. The logical truth of the test is left in the input stream by -% the predicate version. % \end{function} % % \begin{function}[EXP,pTF]{\box_if_horizontal:N, \box_if_horizontal:c} @@ -294,11 +289,7 @@ % \cs{box_if_horizontal_p:N} \meta{box} % \cs{box_if_horizontal:NTF} \meta{box} \Arg{true code} \Arg{false code} % \end{syntax} -% Tests if \meta{box} is a horizontal box. The branching -% versions then leave either \meta{true code} or \meta{false code} -% in the input stream, as appropriate to the truth of the test and -% the variant of the function chosen. The logical truth of the test -% is left in the input stream by the predicate version. +% Tests if \meta{box} is a horizontal box. % \end{function} % % \begin{function}[EXP,pTF]{\box_if_vertical:N, \box_if_vertical:c} @@ -306,11 +297,7 @@ % \cs{box_if_vertical_p:N} \meta{box} % \cs{box_if_vertical:NTF} \meta{box} \Arg{true code} \Arg{false code} % \end{syntax} -% Tests if \meta{box} is a vertical box. The branching -% versions then leave either \meta{true code} or \meta{false code} -% in the input stream, as appropriate to the truth of the test and -% the variant of the function chosen. The logical truth of the test -% is left in the input stream by the predicate version. +% Tests if \meta{box} is a vertical box. % \end{function} % % \section{The last box inserted} @@ -1114,7 +1101,7 @@ % % \begin{macro}{\vbox:n} % \TestFiles{m3box003.lvt} -% \begin{macro}{\vbox:n\vbox_top:n} +% \begin{macro}{\vbox_top:n} % \TestFiles{m3box003.lvt} % Put a vertical box directly into the input stream. % \begin{macrocode} diff --git a/Master/texmf-dist/source/latex/l3kernel/l3clist.dtx b/Master/texmf-dist/source/latex/l3kernel/l3clist.dtx index d031b15f552..bd15dbffb01 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3clist.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3clist.dtx @@ -36,7 +36,7 @@ % %<*driver|package> \RequirePackage{l3names} -\GetIdInfo$Id: l3clist.dtx 2498 2011-07-09 17:51:47Z joseph $ +\GetIdInfo$Id: l3clist.dtx 2666 2011-08-26 06:10:09Z joseph $ {L3 Experimental comma separated lists} %</driver|package> %<*driver> @@ -393,11 +393,7 @@ % \cs{clist_if_empty:NTF} \meta{comma list} % ~~\Arg{true code} \Arg{false code} % \end{syntax} -% Tests if the \meta{comma list} is empty (containing no items). The -% branching versions then leave either \meta{true code} or -% \meta{false code} in the input stream, as appropriate to the truth of -% the test and the variant of the function chosen. The logical truth of -% the test is left in the input stream by the predicate version. +% Tests if the \meta{comma list} is empty (containing no items). % \end{function} % % \begin{function}[EXP,pTF] @@ -409,11 +405,7 @@ % \end{syntax} % Compares the content of two \meta{comma lists} and % is logically \texttt{true} if the two contain the same list of -% entries in the same order. The branching versions then leave either -% \meta{true code} or \meta{false code} in the input stream, as -% appropriate to the truth of the test and the variant of the function -% chosen. The logical truth of the test is left in the input stream by -% the predicate version. +% entries in the same order. % \end{function} % % \begin{function}[TF]{ @@ -426,10 +418,6 @@ % ~~\Arg{true code} \Arg{false code} % \end{syntax} % Tests if the \meta{item} is present in the \meta{comma list}. -% Either the \meta{true code} or \meta{false code} is left in the input -% stream, as appropriate to the truth of the test and the variant of the -% function -% chosen. % \end{function} % % \section{Mapping to comma lists} diff --git a/Master/texmf-dist/source/latex/l3kernel/l3coffins.dtx b/Master/texmf-dist/source/latex/l3kernel/l3coffins.dtx new file mode 100644 index 00000000000..87df9402d1d --- /dev/null +++ b/Master/texmf-dist/source/latex/l3kernel/l3coffins.dtx @@ -0,0 +1,1983 @@ +% \iffalse meta-comment +% +%% File: l3coffins.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 "l3kernel 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{l3names,graphicx,color} +\GetIdInfo$Id: l3coffins.dtx 2624 2011-08-18 19:02:45Z joseph $ + {L3 Experimental coffin code layer} +%</driver|package> +%<*driver> +\documentclass[full]{l3doc} +\begin{document} + \DocInput{\jobname.dtx} +\end{document} +%</driver> +% \fi +% +% \title{^^A +% The \textsf{l3coffins} package\\ Coffin code layer^^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} +% +% The material in this module provides the low-level support system +% for coffins. For details about the design concept of a coffin, see +% the \pkg{xcoffins} module (in the \pkg{l3experimental} bundle). +% +% \section{Code-level coffin functions} +% +% \begin{function}{\coffin_new:N, \coffin_new:c} +% \begin{syntax} +% \cs{coffin_new:N} \meta{coffin} +% \end{syntax} +% Creates a new \meta{coffin} or raises an error if the name is +% already taken. The declaration is global. The \meta{coffin} will +% initially be empty. +% \end{function} +% +% \begin{function}{\coffin_clear:N, \coffin_clear:c} +% \begin{syntax} +% \cs{coffin_clear:N} \meta{coffin} +% \end{syntax} +% Clears the content of the \meta{coffin} within the current \TeX{} +% group level. +% \end{function} +% +%\begin{function} +% {\coffin_set_eq:NN, \coffin_set_eq:Nc, \coffin_set_eq:cN, \coffin_set_eq:cc} +% \begin{syntax} +% \cs{coffin_set_eq:NN} \meta{coffin1} \meta{coffin2} +% \end{syntax} +% Sets both the content and poles of \meta{coffin1} equal to those +% of \meta{coffin2} within the current \TeX\ group level. +% \end{function} +% +% \begin{function}{\hcoffin_set:Nn, \hcoffin_set:cn} +% \begin{syntax} +% \cs{hcoffin_set:Nn} \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}{\vcoffin_set:Nnn, \vcoffin_set:cnn} +% \begin{syntax} +% \cs{vcoffin_set:Nnn} \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} +% +% \begin{function} +% {\coffin_set_horizontal_pole:Nnn, \coffin_set_horizontal_pole:cnn} +% \begin{syntax} +% \cs{coffin_set_horizontal_pole:Nnn} \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}. +% \end{function} +% +% \begin{function} +% {\coffin_set_vertical_pole:Nnn, \coffin_set_vertical_pole:cnn} +% \begin{syntax} +% \cs{coffin_set_vertical_pole:Nnn} \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}. +% \end{function} +% +% \begin{function}{\coffin_rotate:Nn, \coffin_rotate:cn} +% \begin{syntax} +% \cs{coffin_rotate:Nn} \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. +% \end{function} +% +% \begin{function} +% { +% \coffin_attach:NnnNnnnn, \coffin_attach:cnnNnnnn, +% \coffin_attach:Nnncnnnn, \coffin_attach:cnncnnnn +% } +% \begin{syntax} +% \cs{coffin_attach:NnnNnnnn} +% ~~\meta{coffin1} \Arg{coffin1-pole1} \Arg{coffin1-pole2} +% ~~\meta{coffin2} \Arg{coffin2-pole1} \Arg{coffin2-pole2} +% ~~\Arg{x-offset} \Arg{y-offset} +% \end{syntax} +% This function carries out alignment such that the bounding box +% of \meta{coffin1} is not altered, \emph{i.e.}~\meta{coffin2} can +% protrude outside of the bounding box of the coffin. 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}. \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}. The two offsets should be given as dimension +% expressions. +% \end{function} +% +% \begin{function} +% { +% \coffin_join:NnnNnnnn, \coffin_join:cnnNnnnn, +% \coffin_join:Nnncnnnn, \coffin_join:cnncnnnn +% } +% \begin{syntax} +% \cs{coffin_join:NnnNnnnn} +% ~~\meta{coffin1} \Arg{coffin1-pole1} \Arg{coffin1-pole2} +% ~~\meta{coffin2} \Arg{coffin2-pole1} \Arg{coffin2-pole2} +% ~~\Arg{x-offset} \Arg{y-offset} +% \end{syntax} +% This function carries out alignment such that the bounding box +% of \meta{coffin1} after the process will expand. The new bounding +% box will cover the area contain the bounding boxes of the two +% original coffins. 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}. \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}. The two offsets should be given as dimension +% expressions. +% \end{function} +% +% \begin{function}{\coffin_typeset:Nnnnn, \coffin_typeset:cnnnn} +% \begin{syntax} +% \cs{coffin_typeset:Nnnnn} \meta{coffin} \Arg{pole1} \Arg{pole2} +% ~~\Arg{x-offset} \Arg{y-offset} +% \end{syntax} +% Typesetting is carried out by first calculating \meta{handle}, the +% point of intersection of \meta{pole1} and \meta{pole2}. 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}. The two offsets should +% be given as dimension expressions. Typesetting a coffin is +% therefore analogous to carrying out an alignment where the +% \enquote{parent} coffin is the current insertion point. +% \end{function} +% +% \begin{function}{\coffin_display_handles:cn, \coffin_display_handles:cn} +% \begin{syntax} +% \cs{coffin_display_handles:Nn} \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}{\coffin_mark_handle:Nnnn, \coffin_mark_handle:cnnn} +% \begin{syntax} +% \cs{coffin_mark_handle:Nnnn} \meta{coffin} \Arg{pole1} \Arg{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. +% \end{function} +% +% \begin{function}{\coffin_show_structure:N, \coffin_show_structure:c} +% \begin{syntax} +% \cs{coffin_show_structure:N} \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. +% +% 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{\pkg{l3coffins} Implementation} +% +% \begin{macrocode} +%<*initex|package> +% \end{macrocode} +% +% \begin{macrocode} +%<*package> +\ProvidesExplPackage + {\ExplFileName}{\ExplFileDate}{\ExplFileVersion}{\ExplFileDescription} +\package_check_loaded_expl: +%</package> +% \end{macrocode} +% +% \subsection{Coffins: data structures and general variables} +% +% \begin{variable}{\l_coffin_tmp_box} +% \begin{variable}{\l_coffin_tmp_dim} +% \begin{variable}{\l_coffin_tmp_fp} +% \begin{variable}{\l_coffin_tmp_tl} +% Scratch variables. +% \begin{macrocode} +\box_new:N \l_coffin_tmp_box +\dim_new:N \l_coffin_tmp_dim +\fp_new:N \l_coffin_tmp_fp +\tl_new:N \l_coffin_tmp_tl +% \end{macrocode} +% \end{variable} +% \end{variable} +% \end{variable} +% \end{variable} +% +% \begin{variable}{\c_coffin_corners_prop} +% The \enquote{corners}; of a coffin define the real content, as +% opposed to the \TeX{} bounding box. They all start off in the same +% place, of course. +% \begin{macrocode} +\prop_new:N \c_coffin_corners_prop +\prop_put:Nnn \c_coffin_corners_prop { tl } { { 0 pt } { 0 pt } } +\prop_put:Nnn \c_coffin_corners_prop { tr } { { 0 pt } { 0 pt } } +\prop_put:Nnn \c_coffin_corners_prop { bl } { { 0 pt } { 0 pt } } +\prop_put:Nnn \c_coffin_corners_prop { br } { { 0 pt } { 0 pt } } +% \end{macrocode} +% \end{variable} +% +% \begin{variable}{\c_coffin_poles_prop} +% Pole positions are given for horizontal, vertical and reference-point +% based values. +% \begin{macrocode} +\prop_new:N \c_coffin_poles_prop +\tl_set:Nn \l_coffin_tmp_tl { { 0 pt } { 0 pt } { 0 pt } { 1000 pt } } +\prop_put:Nno \c_coffin_poles_prop { l } { \l_coffin_tmp_tl } +\prop_put:Nno \c_coffin_poles_prop { hc } { \l_coffin_tmp_tl } +\prop_put:Nno \c_coffin_poles_prop { r } { \l_coffin_tmp_tl } +\tl_set:Nn \l_coffin_tmp_tl { { 0 pt } { 0 pt } { 1000 pt } { 0 pt } } +\prop_put:Nno \c_coffin_poles_prop { b } { \l_coffin_tmp_tl } +\prop_put:Nno \c_coffin_poles_prop { vc } { \l_coffin_tmp_tl } +\prop_put:Nno \c_coffin_poles_prop { t } { \l_coffin_tmp_tl } +\prop_put:Nno \c_coffin_poles_prop { B } { \l_coffin_tmp_tl } +\prop_put:Nno \c_coffin_poles_prop { H } { \l_coffin_tmp_tl } +\prop_put:Nno \c_coffin_poles_prop { T } { \l_coffin_tmp_tl } +% \end{macrocode} +% \end{variable} +% +% \begin{variable}{\l_coffin_calc_a_fp} +% \begin{variable}{\l_coffin_calc_b_fp} +% \begin{variable}{\l_coffin_calc_c_fp} +% \begin{variable}{\l_coffin_calc_d_fp} +% \begin{variable}{\l_coffin_calc_result_fp} +% Used for calculations of intersections and in other internal places. +% \begin{macrocode} +\fp_new:N \l_coffin_calc_a_fp +\fp_new:N \l_coffin_calc_b_fp +\fp_new:N \l_coffin_calc_c_fp +\fp_new:N \l_coffin_calc_d_fp +\fp_new:N \l_coffin_calc_result_fp +% \end{macrocode} +% \end{variable} +% \end{variable} +% \end{variable} +% \end{variable} +% \end{variable} +% +% \begin{variable}{\l_coffin_error_bool} +% For propagating errors so that parts of the code can work around them. +% \begin{macrocode} +\bool_new:N \l_coffin_error_bool +% \end{macrocode} +% \end{variable} +% +% \begin{variable}{\l_coffin_offset_x_dim} +% \begin{variable}{\l_coffin_offset_y_dim} +% The offset between two sets of coffin handles when typesetting. These +% values are corrected from those requested in an alignment for the +% positions of the handles. +% \begin{macrocode} +\dim_new:N \l_coffin_offset_x_dim +\dim_new:N \l_coffin_offset_y_dim +% \end{macrocode} +% \end{variable} +% \end{variable} +% +% \begin{variable}{\l_coffin_pole_a_tl} +% \begin{variable}{\l_coffin_pole_b_tl} +% Needed for finding the intersection of two poles. +% \begin{macrocode} +\tl_new:N \l_coffin_pole_a_tl +\tl_new:N \l_coffin_pole_b_tl +% \end{macrocode} +% \end{variable} +% \end{variable} +% +% \begin{variable}{\l_coffin_sin_fp} +% \begin{variable}{\l_coffin_cos_fp} +% Used for rotations to get the sine and cosine values. +% \begin{macrocode} +\fp_new:N \l_coffin_sin_fp +\fp_new:N \l_coffin_cos_fp +% \end{macrocode} +% \end{variable} +% \end{variable} +% +% \begin{variable}{\l_coffin_x_dim} +% \begin{variable}{\l_coffin_y_dim} +% \begin{variable}{\l_coffin_x_prime_dim} +% \begin{variable}{\l_coffin_y_prime_dim} +% For calculating intersections and so forth. +% \begin{macrocode} +\dim_new:N \l_coffin_x_dim +\dim_new:N \l_coffin_y_dim +\dim_new:N \l_coffin_x_prime_dim +\dim_new:N \l_coffin_y_prime_dim +% \end{macrocode} +% \end{variable} +% \end{variable} +% \end{variable} +% \end{variable} +% +% \begin{variable}{\l_coffin_x_fp} +% \begin{variable}{\l_coffin_y_fp} +% \begin{variable}{\l_coffin_x_prime_fp} +% \begin{variable}{\l_coffin_y_prime_fp} +% Used for calculations where there are clear $x$- and +% $y$-components, for example during vector rotation. +% \begin{macrocode} +\fp_new:N \l_coffin_x_fp +\fp_new:N \l_coffin_y_fp +\fp_new:N \l_coffin_x_prime_fp +\fp_new:N \l_coffin_y_prime_fp +% \end{macrocode} +% \end{variable} +% \end{variable} +% \end{variable} +% \end{variable} +% +% \begin{variable}{\l_coffin_Depth_dim} +% \begin{variable}{\l_coffin_Height_dim} +% \begin{variable}{\l_coffin_TotalHeight_dim} +% \begin{variable}{\l_coffin_Width_dim} +% Dimensions for the various parts of a coffin. +% \begin{macrocode} +\dim_new:N \l_coffin_Depth_dim +\dim_new:N \l_coffin_Height_dim +\dim_new:N \l_coffin_TotalHeight_dim +\dim_new:N \l_coffin_Width_dim +% \end{macrocode} +% \end{variable} +% \end{variable} +% \end{variable} +% \end{variable} +% +% \begin{macro}{\coffin_saved_Depth:} +% \begin{macro}{\coffin_saved_Height:} +% \begin{macro}{\coffin_saved_TotalHeight:} +% \begin{macro}{\coffin_saved_Width:} +% Used to save the meaning of \cs{Depth}, \cs{Height}, \cs{TotalHeight} +% and \cs{Width}. +% \begin{macrocode} +\cs_new_nopar:Npn \coffin_saved_Depth: { } +\cs_new_nopar:Npn \coffin_saved_Height: { } +\cs_new_nopar:Npn \coffin_saved_TotalHeight: { } +\cs_new_nopar:Npn \coffin_saved_Width: { } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \subsection{Basic coffin functions} +% +% There are a number of basic functions needed for creating coffins and +% placing material in them. This all relies on the following data +% structures. +% +% \begin{macro}{\coffin_if_exist:NT} +% Several of the higher-level coffin functions will give multiple +% errors if the coffin does not exist. A cleaner way to handle this +% is provided here: both the box and the coffin structure are +% checked. +% \begin{macrocode} +\cs_new_protected:Npn \coffin_if_exist:NT #1#2 + { + \cs_if_exist:NTF #1 + { + \cs_if_exist:cTF { l_coffin_poles_ \int_value:w #1 _prop } + { #2 } + { + \msg_kernel_error:nnx { coffin } { unknown-coffin } + { \token_to_str:N #1 } + } + } + { + \msg_kernel_error:nnx { coffin } { unknown-coffin } + { \token_to_str:N #1 } + } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\coffin_clear:N, \coffin_clear:c} +% Clearing coffins means emptying the box and resetting all of the +% structures. +% \begin{macrocode} +\cs_new_protected_nopar:Npn \coffin_clear:N #1 + { + \coffin_if_exist:NT #1 + { + \box_clear:N #1 + \coffin_reset_structure:N #1 + } + } +\cs_generate_variant:Nn \coffin_clear:N { c } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\coffin_new:N, \coffin_new:c} +% Creating a new coffin means making the underlying box and adding the +% data structures. These are created globally, as there is a need to +% avoid any strange effects if the coffin is created inside a group. +% This means that the usual rule about \cs{l_\ldots} variables has +% to be broken. +% \begin{macrocode} +\cs_new_protected_nopar:Npn \coffin_new:N #1 + { + \box_new:N #1 + \prop_clear_new:c { l_coffin_corners_ \int_value:w #1 _prop } + \prop_clear_new:c { l_coffin_poles_ \int_value:w #1 _prop } + \prop_gset_eq:cN { l_coffin_corners_ \int_value:w #1 _prop } + \c_coffin_corners_prop + \prop_gset_eq:cN { l_coffin_poles_ \int_value:w #1 _prop } + \c_coffin_poles_prop + } +\cs_generate_variant:Nn \coffin_new:N { c } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\hcoffin_set:Nn, \hcoffin_set:cn} +% Horizontal coffins are relatively easy: set the appropriate box, +% reset the structures then update the handle positions. +% \begin{macrocode} +\cs_new_protected:Npn \hcoffin_set:Nn #1#2 + { + \coffin_if_exist:NT #1 + { + \hbox_set:Nn #1 + { + \group_begin: +%<*initex> + \color_set_current: % TODO +%</initex> +%<*package> + \set@color +%</package> + #2 + \group_end: + } + \coffin_reset_structure:N #1 + \coffin_update_poles:N #1 + \coffin_update_corners:N #1 + } + } +\cs_generate_variant:Nn \hcoffin_set:Nn { c } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\vcoffin_set:Nnn, \vcoffin_set:cnn} +% Setting vertical coffins is more complex. First, the material is +% typeset with a given width. The default handles and poles are set as +% for a horizontal coffin, before finding the top baseline using a +% temporary box. +% \begin{macrocode} +\cs_new_protected:Npn \vcoffin_set:Nnn #1#2#3 + { + \coffin_if_exist:NT #1 + { + \vbox_set:Nn #1 + { + \dim_set:Nn \tex_hsize:D {#2} + \group_begin: +%<*initex> + \color_set_current: +%</initex> +%<*package> + \set@color +%</package> + #3 + \group_end: + } + \coffin_reset_structure:N #1 + \coffin_update_poles:N #1 + \coffin_update_corners:N #1 + \vbox_set_top:Nn \l_coffin_tmp_box { \vbox_unpack:N #1 } + \coffin_set_pole:Nnx #1 { T } + { + { 0 pt } + { \dim_eval:n { \box_ht:N #1 - \box_ht:N \l_coffin_tmp_box } } + { 1000 pt } + { 0 pt } + } + \box_clear:N \l_coffin_tmp_box + } + } +\cs_generate_variant:Nn \vcoffin_set:Nnn { c } +% \end{macrocode} +% \end{macro} +% +% \begin{macro} +% { +% \coffin_set_eq:NN, \coffin_set_eq:Nc, +% \coffin_set_eq:cN, \coffin_set_eq:cc +% } +% Setting two coffins equal is just a wrapper around other functions. +% \begin{macrocode} +\cs_new_protected_nopar:Npn \coffin_set_eq:NN #1#2 + { + \coffin_if_exist:NT #1 + { + \box_set_eq:NN #1 #2 + \coffin_set_eq_structure:NN #1 #2 + } + } +\cs_generate_variant:Nn \coffin_set_eq:NN { c , Nc , cc } +% \end{macrocode} +% \end{macro} +% +% \begin{variable}{\c_empty_coffin} +% \begin{variable}{\l_coffin_aligned_coffin} +% \begin{variable}{\l_coffin_aligned_internal_coffin} +% Special coffins: these cannot be set up earlier as they need +% \cs{coffin_new:N}. The empty coffin is set as a box as the full +% coffin-setting system needs some material which is not yet available. +% \begin{macrocode} +\coffin_new:N \c_empty_coffin +\hbox_set:Nn \c_empty_coffin { } +\coffin_new:N \l_coffin_aligned_coffin +\coffin_new:N \l_coffin_aligned_internal_coffin +% \end{macrocode} +% \end{variable} +% \end{variable} +% \end{variable} +% +% \subsection{Coffins: handle and pole management} +% +% \begin{macro}{\coffin_get_pole:NnN} +% A simple wrapper around the recovery of a coffin pole, with some +% error checking and recovery built-in. +% \begin{macrocode} +\cs_new_protected_nopar:Npn \coffin_get_pole:NnN #1#2#3 + { + \prop_get:cnNF + { l_coffin_poles_ \int_value:w #1 _prop } {#2} #3 + { + \msg_kernel_error:nnxx { coffin } { unknown-coffin-pole } + {#2} { \token_to_str:N #1 } + \tl_set:Nn #3 { { 0 pt } { 0 pt } { 0 pt } { 0 pt } } + } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\coffin_reset_structure:N} +% Resetting the structure is a simple copy job. +% \begin{macrocode} +\cs_new_protected_nopar:Npn \coffin_reset_structure:N #1 + { + \prop_set_eq:cN { l_coffin_corners_ \int_value:w #1 _prop } + \c_coffin_corners_prop + \prop_set_eq:cN { l_coffin_poles_ \int_value:w #1 _prop } + \c_coffin_poles_prop + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\coffin_set_eq_structure:NN} +% Setting coffin structures equal simply means copying the property +% list. +% \begin{macrocode} +\cs_new_protected_nopar:Npn \coffin_set_eq_structure:NN #1#2 + { + \prop_set_eq:cc { l_coffin_corners_ \int_value:w #1 _prop } + { l_coffin_corners_ \int_value:w #2 _prop } + \prop_set_eq:cc { l_coffin_poles_ \int_value:w #1 _prop } + { l_coffin_poles_ \int_value:w #2 _prop } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\coffin_set_user_dimensions:N} +% \begin{macro}{\coffin_end_user_dimensions:} +% \begin{macro}{\Depth} +% \begin{macro}{\Height} +% \begin{macro}{\TotalHeight} +% \begin{macro}{\Width} +% These make design-level names for the dimensions of a coffin easy to +% get at. +% \begin{macrocode} +\cs_new_protected_nopar:Npn \coffin_set_user_dimensions:N #1 + { + \cs_set_eq:NN \coffin_saved_Height: \Height + \cs_set_eq:NN \coffin_saved_Depth: \Depth + \cs_set_eq:NN \coffin_saved_TotalHeight: \TotalHeight + \cs_set_eq:NN \coffin_saved_Width: \Width + \cs_set_eq:NN \Height \l_coffin_Height_dim + \cs_set_eq:NN \Depth \l_coffin_Depth_dim + \cs_set_eq:NN \TotalHeight \l_coffin_TotalHeight_dim + \cs_set_eq:NN \Width \l_coffin_Width_dim + \dim_set:Nn \Height { \box_ht:N #1 } + \dim_set:Nn \Depth { \box_dp:N #1 } + \dim_set:Nn \TotalHeight { \box_ht:N #1 - \box_dp:N #1 } + \dim_set:Nn \Width { \box_wd:N #1 } + } +\cs_new_protected_nopar:Npn \coffin_end_user_dimensions: + { + \cs_set_eq:NN \Height \coffin_saved_Height: + \cs_set_eq:NN \Depth \coffin_saved_Depth: + \cs_set_eq:NN \TotalHeight \coffin_saved_TotalHeight: + \cs_set_eq:NN \Width \coffin_saved_Width: + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro} +% {\coffin_set_horizontal_pole:Nnn, \coffin_set_horizontal_pole:cnn} +% \begin{macro}{\coffin_set_vertical_pole:Nnn,\coffin_set_vertical_pole:cnn} +% \begin{macro}{\coffin_set_pole:Nnn, \coffin_set_pole:Nnx} +% Setting the pole of a coffin at the user/designer level requires a +% bit more care. The idea here is to provide a reasonable interface to +% the system, then to do the setting with full expansion. The +% three-argument version is used internally to do a direct setting. +% \begin{macrocode} +\cs_new_protected_nopar:Npn \coffin_set_horizontal_pole:Nnn #1#2#3 + { + \coffin_if_exist:NT #1 + { + \coffin_set_user_dimensions:N #1 + \coffin_set_pole:Nnx #1 {#2} + { + { 0 pt } { \dim_eval:n {#3} } + { 1000 pt } { 0 pt } + } + \coffin_end_user_dimensions: + } + } +\cs_new_protected_nopar:Npn \coffin_set_vertical_pole:Nnn #1#2#3 + { + \coffin_if_exist:NT #1 + { + \coffin_set_user_dimensions:N #1 + \coffin_set_pole:Nnx #1 {#2} + { + { \dim_eval:n {#3} } { 0 pt } + { 0 pt } { 1000 pt } + } + \coffin_end_user_dimensions: + } + } +\cs_new_protected_nopar:Npn \coffin_set_pole:Nnn #1#2#3 + { \prop_put:cnn { l_coffin_poles_ \int_value:w #1 _prop } {#2} {#3} } +\cs_generate_variant:Nn \coffin_set_horizontal_pole:Nnn { c } +\cs_generate_variant:Nn \coffin_set_vertical_pole:Nnn { c } +\cs_generate_variant:Nn \coffin_set_pole:Nnn { Nnx } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\coffin_update_corners:N} +% Updating the corners of a coffin is straight-forward as at this stage +% there can be no rotation. So the corners of the content are just those +% of the underlying \TeX{} box. +% \begin{macrocode} +\cs_new_protected_nopar:Npn \coffin_update_corners:N #1 + { + \prop_put:cnx { l_coffin_corners_ \int_value:w #1 _prop } { tl } + { { 0 pt } { \dim_use:N \box_ht:N #1 } } + \prop_put:cnx { l_coffin_corners_ \int_value:w #1 _prop } { tr } + { { \dim_use:N \box_wd:N #1 } { \dim_use:N \box_ht:N #1 } } + \prop_put:cnx { l_coffin_corners_ \int_value:w #1 _prop } { bl } + { { 0 pt } { \dim_eval:n { - \box_dp:N #1 } } } + \prop_put:cnx { l_coffin_corners_ \int_value:w #1 _prop } { br } + { { \dim_use:N \box_wd:N #1 } { \dim_eval:n { - \box_dp:N #1 } } } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\coffin_update_poles:N} +% This function is called when a coffin is set, and updates the poles to +% reflect the nature of size of the box. Thus this function only alters +% poles where the default position is dependent on the size of the box. +% It also does not set poles which are relevant only to vertical +% coffins. +% \begin{macrocode} +\cs_new_protected_nopar:Npn \coffin_update_poles:N #1 + { + \prop_put:cnx { l_coffin_poles_ \int_value:w #1 _prop } { hc } + { + { \dim_eval:n { 0.5 \box_wd:N #1 } } + { 0 pt } { 0 pt } { 1000 pt } + } + \prop_put:cnx { l_coffin_poles_ \int_value:w #1 _prop } { r } + { + { \dim_use:N \box_wd:N #1 } + { 0 pt } { 0 pt } { 1000 pt } + } + \prop_put:cnx { l_coffin_poles_ \int_value:w #1 _prop } { vc } + { + { 0 pt } + { \dim_eval:n { ( \box_ht:N #1 - \box_dp:N #1 ) / 2 } } + { 1000 pt } + { 0 pt } + } + \prop_put:cnx { l_coffin_poles_ \int_value:w #1 _prop } { t } + { + { 0 pt } + { \dim_use:N \box_ht:N #1 } + { 1000 pt } + { 0 pt } + } + \prop_put:cnx { l_coffin_poles_ \int_value:w #1 _prop } { b } + { + { 0 pt } + { \dim_eval:n { - \box_dp:N #1 } } + { 1000 pt } + { 0 pt } + } + } +% \end{macrocode} +% \end{macro} +% +% \subsection{Coffins: calculation of pole intersections} +% +% \begin{macro}{\coffin_calculate_intersection:Nnn} +% \begin{macro}[aux]{\coffin_calculate_intersection:nnnnnnnn} +% \begin{macro}[aux]{\coffin_calculate_intersection_aux:nnnnnN} +% The lead off in finding intersections is to recover the two poles +% and then hand off to the auxiliary for the actual calculation. There +% may of course not be an intersection, for which an error trap is +% needed. +% \begin{macrocode} +\cs_new_protected_nopar:Npn \coffin_calculate_intersection:Nnn #1#2#3 + { + \coffin_get_pole:NnN #1 {#2} \l_coffin_pole_a_tl + \coffin_get_pole:NnN #1 {#3} \l_coffin_pole_b_tl + \bool_set_false:N \l_coffin_error_bool + \exp_last_two_unbraced:Noo + \coffin_calculate_intersection:nnnnnnnn + \l_coffin_pole_a_tl \l_coffin_pole_b_tl + \bool_if:NT \l_coffin_error_bool + { + \msg_kernel_error:nn { coffin } { no-pole-intersection } + \dim_zero:N \l_coffin_x_dim + \dim_zero:N \l_coffin_y_dim + } + } +% \end{macrocode} +% The two poles passed here each have four values (as dimensions), +% ($a$, $b$, $c$, $d$) and +% ($a'$, $b'$, $c'$, $d'$). These are arguments +% $1$--$4$ and $5$--$8$, respectively. In both +% cases $a$ and $b$ are the co-ordinates of a point on the +% pole and $c$ and $d$ define the direction of the pole. Finding +% the intersection depends on the directions of the poles, which are +% given by $d / c$ and $d' / c'$. However, if one of the poles +% is either horizontal or vertical then one or more of $c$, $d$, +% $c'$ and $d'$ will be zero and a special case is needed. +% \begin{macrocode} +\cs_new_protected_nopar:Npn \coffin_calculate_intersection:nnnnnnnn + #1#2#3#4#5#6#7#8 + { + \dim_compare:nNnTF {#3} = { \c_zero_dim } +% \end{macrocode} +% The case where the first pole is vertical. So the $x$-component +% of the interaction will be at $a$. There is then a test on the +% second pole: if it is also vertical then there is an error. +% \begin{macrocode} + { + \dim_set:Nn \l_coffin_x_dim {#1} + \dim_compare:nNnTF {#7} = \c_zero_dim + { \bool_set_true:N \l_coffin_error_bool } +% \end{macrocode} +% The second pole may still be horizontal, in which case the +% $y$-component of the intersection will be $b'$. If not, +% \[ +% y = \frac{d'}{c'} \left ( x - a' \right ) + b' +% \] +% with the $x$-component already known to be |#1|. This calculation +% is done as a generalised auxiliary. +% \begin{macrocode} + { + \dim_compare:nNnTF {#8} = \c_zero_dim + { \dim_set:Nn \l_coffin_y_dim {#6} } + { + \coffin_calculate_intersection_aux:nnnnnN + {#1} {#5} {#6} {#7} {#8} \l_coffin_y_dim + } + } + } +% \end{macrocode} +% If the first pole is not vertical then it may be horizontal. If so, +% then the procedure is essentially the same as that already done but +% with the $x$- and $y$-components interchanged. +% \begin{macrocode} + { + \dim_compare:nNnTF {#4} = \c_zero_dim + { + \dim_set:Nn \l_coffin_y_dim {#2} + \dim_compare:nNnTF {#8} = { \c_zero_dim } + { \bool_set_true:N \l_coffin_error_bool } + { + \dim_compare:nNnTF {#7} = \c_zero_dim + { \dim_set:Nn \l_coffin_x_dim {#5} } +% \end{macrocode} +% The formula for the case where the second pole is neither horizontal +% nor vertical is +% \[ +% x = \frac{c'}{d'} \left ( y - b' \right ) + a' +% \] +% which is again handled by the same auxiliary. +% \begin{macrocode} + { + \coffin_calculate_intersection_aux:nnnnnN + {#2} {#6} {#5} {#8} {#7} \l_coffin_x_dim + } + } + } +% \end{macrocode} +% The first pole is neither horizontal nor vertical. This still leaves +% the second pole, which may be a special case. For those possibilities, +% the calculations are the same as above with the first and second poles +% interchanged. +% \begin{macrocode} + { + \dim_compare:nNnTF {#7} = \c_zero_dim + { + \dim_set:Nn \l_coffin_x_dim {#5} + \coffin_calculate_intersection_aux:nnnnnN + {#5} {#1} {#2} {#3} {#4} \l_coffin_y_dim + } + { + \dim_compare:nNnTF {#8} = \c_zero_dim + { + \dim_set:Nn \l_coffin_x_dim {#6} + \coffin_calculate_intersection_aux:nnnnnN + {#6} {#2} {#1} {#4} {#3} \l_coffin_x_dim + } +% \end{macrocode} +% If none of the special cases apply then there is still a need to +% check that there is a unique intersection between the two pole. This +% is the case if they have different slopes. +% \begin{macrocode} + { + \fp_set_from_dim:Nn \l_coffin_calc_a_fp {#3} + \fp_set_from_dim:Nn \l_coffin_calc_b_fp {#4} + \fp_set_from_dim:Nn \l_coffin_calc_c_fp {#7} + \fp_set_from_dim:Nn \l_coffin_calc_d_fp {#8} + \fp_div:Nn \l_coffin_calc_b_fp \l_coffin_calc_a_fp + \fp_div:Nn \l_coffin_calc_d_fp \l_coffin_calc_c_fp + \fp_compare:nNnTF + \l_coffin_calc_b_fp = \l_coffin_calc_d_fp + { \bool_set_true:N \l_coffin_error_bool } +% \end{macrocode} +% All of the tests pass, so there is the full complexity of the +% calculation: +% \[ +% x = \frac { a ( d / c ) - a' ( d' / c' ) - b + b' } +% { ( d / c ) - ( d' / c' ) } +% \] +% and noting that the two ratios are already worked out from the test +% just performed. There is quite a bit of shuffling from dimensions to +% floating points in order to do the work. The $y$-values is then +% worked out using the standard auxiliary starting from the +% $x$-position. +% \begin{macrocode} + { + \fp_set_from_dim:Nn \l_coffin_calc_result_fp {#6} + \fp_set_from_dim:Nn \l_coffin_calc_a_fp {#2} + \fp_sub:Nn \l_coffin_calc_result_fp + { \l_coffin_calc_a_fp } + \fp_set_from_dim:Nn \l_coffin_calc_a_fp {#1} + \fp_mul:Nn \l_coffin_calc_a_fp + { \l_coffin_calc_b_fp } + \fp_add:Nn \l_coffin_calc_result_fp + { \l_coffin_calc_a_fp } + \fp_set_from_dim:Nn \l_coffin_calc_a_fp {#5} + \fp_mul:Nn \l_coffin_calc_a_fp + { \l_coffin_calc_d_fp } + \fp_sub:Nn \l_coffin_calc_result_fp + { \l_coffin_calc_a_fp } + \fp_sub:Nn \l_coffin_calc_b_fp + { \l_coffin_calc_d_fp } + \fp_div:Nn \l_coffin_calc_result_fp + { \l_coffin_calc_b_fp } + \dim_set:Nn \l_coffin_x_dim + { \fp_to_dim:N \l_coffin_calc_result_fp } + \coffin_calculate_intersection_aux:nnnnnN + { \l_coffin_x_dim } + {#5} {#6} {#8} {#7} \l_coffin_y_dim + } + } + } + } + } + } +% \end{macrocode} +% The formula for finding the intersection point is in most cases the +% same. The formula here is +% \[ +% \#6 = \frac{\#5}{\#4} \left ( \#1 - \#2 \right ) + \#3 +% \] +% Thus |#4| and |#5| should be the directions of the pole while +% |#2| and |#3| are co-ordinates. +% \begin{macrocode} +\cs_new_protected_nopar:Npn \coffin_calculate_intersection_aux:nnnnnN + #1#2#3#4#5#6 + { + \fp_set_from_dim:Nn \l_coffin_calc_result_fp {#1} + \fp_set_from_dim:Nn \l_coffin_calc_a_fp {#2} + \fp_set_from_dim:Nn \l_coffin_calc_b_fp {#3} + \fp_set_from_dim:Nn \l_coffin_calc_c_fp {#4} + \fp_set_from_dim:Nn \l_coffin_calc_d_fp {#5} + \fp_sub:Nn \l_coffin_calc_result_fp { \l_coffin_calc_a_fp } + \fp_div:Nn \l_coffin_calc_result_fp { \l_coffin_calc_d_fp } + \fp_mul:Nn \l_coffin_calc_result_fp { \l_coffin_calc_c_fp } + \fp_add:Nn \l_coffin_calc_result_fp { \l_coffin_calc_b_fp } + \dim_set:Nn #6 { \fp_to_dim:N \l_coffin_calc_result_fp } + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \subsection{Aligning and typesetting of coffins} +% +% \begin{macro} +% { +% \coffin_join:NnnNnnnn, \coffin_join:cnnNnnnn, +% \coffin_join:Nnncnnnn , \coffin_join:cnncnnnn +% } +% This command joins two coffins, using a horizontal and vertical pole +% from each coffin and making an offset between the two. The result +% is stored as the as a third coffin, which will have all of its handles +% reset to standard values. First, the more basic alignment function is +% used to get things started. +% \begin{macrocode} +\cs_new_protected_nopar:Npn \coffin_join:NnnNnnnn #1#2#3#4#5#6#7#8 + { + \coffin_align:NnnNnnnnN + #1 {#2} {#3} #4 {#5} {#6} {#7} {#8} \l_coffin_aligned_coffin +% \end{macrocode} +% Correct the placement of the reference point. If the $x$-offset +% is negative then the reference point of the second box is to the left +% of that of the first, which is corrected using a kern. On the right +% side the first box might stick out, which will show up if it is wider +% than the sum of the $x$-offset and the width of the second box. +% So a second kern may be needed. +% \begin{macrocode} + \hbox_set:Nn \l_coffin_aligned_coffin + { + \dim_compare:nNnT { \l_coffin_offset_x_dim } < \c_zero_dim + { \tex_kern:D -\l_coffin_offset_x_dim } + \hbox_unpack:N \l_coffin_aligned_coffin + \dim_set:Nn \l_coffin_tmp_dim + { \l_coffin_offset_x_dim - \box_wd:N #1 + \box_wd:N #4 } + \dim_compare:nNnT \l_coffin_tmp_dim < \c_zero_dim + { \tex_kern:D -\l_coffin_tmp_dim } + } +% \end{macrocode} +% The coffin structure is reset, and the corners are cleared: only +% those from the two parent coffins are needed. +% \begin{macrocode} + \coffin_reset_structure:N \l_coffin_aligned_coffin + \prop_clear:c + { l_coffin_corners_ \int_value:w \l_coffin_aligned_coffin _ prop } + \coffin_update_poles:N \l_coffin_aligned_coffin +% \end{macrocode} +% The structures of the parent coffins are now transferred to the new +% coffin, which requires that the appropriate offsets are applied. That +% will then depend on whether any shift was needed. +% \begin{macrocode} + \dim_compare:nNnTF \l_coffin_offset_x_dim < \c_zero_dim + { + \coffin_offset_poles:Nnn #1 { -\l_coffin_offset_x_dim } { 0 pt } + \coffin_offset_poles:Nnn #4 { 0 pt } { \l_coffin_offset_y_dim } + \coffin_offset_corners:Nnn #1 { -\l_coffin_offset_x_dim } { 0 pt } + \coffin_offset_corners:Nnn #4 { 0 pt } { \l_coffin_offset_y_dim } + } + { + \coffin_offset_poles:Nnn #1 { 0 pt } { 0 pt } + \coffin_offset_poles:Nnn #4 + { \l_coffin_offset_x_dim } { \l_coffin_offset_y_dim } + \coffin_offset_corners:Nnn #1 { 0 pt } { 0 pt } + \coffin_offset_corners:Nnn #4 + { \l_coffin_offset_x_dim } { \l_coffin_offset_y_dim } + } + \coffin_update_vertical_poles:NNN #1 #4 \l_coffin_aligned_coffin + \coffin_set_eq:NN #1 \l_coffin_aligned_coffin + } +\cs_generate_variant:Nn \coffin_join:NnnNnnnn { c , Nnnc , cnnc } +% \end{macrocode} +% \end{macro} +% +% \begin{macro} +% { +% \coffin_attach:NnnNnnnn, \coffin_attach:cnnNnnnn, +% \coffin_attach:Nnncnnnn, \coffin_attach:cnncnnnn +% } +% \begin{macro}{\coffin_attach_mark:NnnNnnnn} +% A more simple version of the above, as it simply uses the size of the +% first coffin for the new one. This means that the work here is rather +% simplified compared to the above code. The function used when marking +% a position is hear also as it is similar but without the structure +% updates. +% \begin{macrocode} +\cs_new_protected_nopar:Npn \coffin_attach:NnnNnnnn #1#2#3#4#5#6#7#8 + { + \coffin_align:NnnNnnnnN + #1 {#2} {#3} #4 {#5} {#6} {#7} {#8} \l_coffin_aligned_coffin + \box_set_ht:Nn \l_coffin_aligned_coffin { \box_ht:N #1 } + \box_set_dp:Nn \l_coffin_aligned_coffin { \box_dp:N #1 } + \box_set_wd:Nn \l_coffin_aligned_coffin { \box_wd:N #1 } + \coffin_reset_structure:N \l_coffin_aligned_coffin + \prop_set_eq:cc + { l_coffin_corners_ \int_value:w \l_coffin_aligned_coffin _prop } + { l_coffin_corners_ \int_value:w #1 _prop } + \coffin_update_poles:N \l_coffin_aligned_coffin + \coffin_offset_poles:Nnn #1 { 0 pt } { 0 pt } + \coffin_offset_poles:Nnn #4 + { \l_coffin_offset_x_dim } { \l_coffin_offset_y_dim } + \coffin_update_vertical_poles:NNN #1 #4 \l_coffin_aligned_coffin + \coffin_set_eq:NN #1 \l_coffin_aligned_coffin + } +\cs_new_protected_nopar:Npn \coffin_attach_mark:NnnNnnnn #1#2#3#4#5#6#7#8 + { + \coffin_align:NnnNnnnnN + #1 {#2} {#3} #4 {#5} {#6} {#7} {#8} \l_coffin_aligned_coffin + \box_set_ht:Nn \l_coffin_aligned_coffin { \box_ht:N #1 } + \box_set_dp:Nn \l_coffin_aligned_coffin { \box_dp:N #1 } + \box_set_wd:Nn \l_coffin_aligned_coffin { \box_wd:N #1 } + \box_set_eq:NN #1 \l_coffin_aligned_coffin + } +\cs_generate_variant:Nn \coffin_attach:NnnNnnnn { c , Nnnc , cnnc } +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\coffin_align:NnnNnnnnN} +% The internal function aligns the two coffins into a third one, but +% performs no corrections on the resulting coffin poles. The process +% begins by finding the points of intersection for the poles for each +% of the input coffins. Those for the first coffin are worked out after +% those for the second coffin, as this allows the `primed' +% storage area to be used for the second coffin. The `real' box +% offsets are then calculated, before using these to re-box the +% input coffins. The default poles are then set up, but the final result +% will depend on how the bounding box is being handled. +% \begin{macrocode} +\cs_new_protected_nopar:Npn \coffin_align:NnnNnnnnN #1#2#3#4#5#6#7#8#9 + { + \coffin_calculate_intersection:Nnn #4 {#5} {#6} + \dim_set:Nn \l_coffin_x_prime_dim { \l_coffin_x_dim } + \dim_set:Nn \l_coffin_y_prime_dim { \l_coffin_y_dim } + \coffin_calculate_intersection:Nnn #1 {#2} {#3} + \dim_set:Nn \l_coffin_offset_x_dim + { \l_coffin_x_dim - \l_coffin_x_prime_dim + #7 } + \dim_set:Nn \l_coffin_offset_y_dim + { \l_coffin_y_dim - \l_coffin_y_prime_dim + #8 } + \hbox_set:Nn \l_coffin_aligned_internal_coffin + { + \box_use:N #1 + \tex_kern:D -\box_wd:N #1 + \tex_kern:D \l_coffin_offset_x_dim + \box_move_up:nn { \l_coffin_offset_y_dim } { \box_use:N #4 } + } + \coffin_set_eq:NN #9 \l_coffin_aligned_internal_coffin + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\coffin_offset_poles:Nnn} +% \begin{macro}[aux]{\coffin_offset_pole:Nnnnnnn} +% Transferring structures from one coffin to another requires that the +% positions are updated by the offset between the two coffins. This is +% done by mapping to the property list of the source coffins, moving +% as appropriate and saving to the new coffin data structures. The +% test for a |-| means that the structures from the parent coffins +% are uniquely labelled and do not depend on the order of alignment. +% The pay off for this is that |-| should not be used in coffin pole +% or handle names, and that multiple alignments do not result in a +% whole set of values. +% \begin{macrocode} +\cs_new_protected_nopar:Npn \coffin_offset_poles:Nnn #1#2#3 + { + \prop_map_inline:cn { l_coffin_poles_ \int_value:w #1 _prop } + { \coffin_offset_pole:Nnnnnnn #1 {##1} ##2 {#2} {#3} } + } +\cs_new_protected_nopar:Npn \coffin_offset_pole:Nnnnnnn #1#2#3#4#5#6#7#8 + { + \dim_set:Nn \l_coffin_x_dim { #3 + #7 } + \dim_set:Nn \l_coffin_y_dim { #4 + #8 } + \tl_if_in:nnTF {#2} { - } + { \tl_set:Nn \l_coffin_tmp_tl { {#2} } } + { \tl_set:Nn \l_coffin_tmp_tl { { #1 - #2 } } } + \exp_last_unbraced:NNo \coffin_set_pole:Nnx \l_coffin_aligned_coffin + { \l_coffin_tmp_tl } + { + { \dim_use:N \l_coffin_x_dim } { \dim_use:N \l_coffin_y_dim } + {#5} {#6} + } + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\coffin_offset_corners:Nnn} +% \begin{macro}[aux]{\coffin_offset_corners:Nnnnn} +% Saving the offset corners of a coffin is very similar, except that +% there is no need to worry about naming: every corner can be saved +% here as order is unimportant. +% \begin{macrocode} +\cs_new_protected_nopar:Npn \coffin_offset_corners:Nnn #1#2#3 + { + \prop_map_inline:cn { l_coffin_corners_ \int_value:w #1 _prop } + { \coffin_offset_corner:Nnnnn #1 {##1} ##2 {#2} {#3} } + } +\cs_new_protected_nopar:Npn \coffin_offset_corner:Nnnnn #1#2#3#4#5#6 + { + \prop_put:cnx + { l_coffin_corners_ \int_value:w \l_coffin_aligned_coffin _prop } + { #1 - #2 } + { + { \dim_eval:n { #3 + #5 } } + { \dim_eval:n { #4 + #6 } } + } + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\coffin_update_vertical_poles:NNN} +% \begin{macro}[aux]{\coffin_update_T:nnnnnnnnN} +% \begin{macro}[aux]{\coffin_update_B:nnnnnnnnN} +% The \texttt{T} and \texttt{B} poles will need to be recalculated +% after alignment. These functions find the larger absolute value for +% the poles, but this is of course only logical when the poles are +% horizontal. +% \begin{macrocode} +\cs_new_protected_nopar:Npn \coffin_update_vertical_poles:NNN #1#2#3 + { + \coffin_get_pole:NnN #3 { #1 -T } \l_coffin_pole_a_tl + \coffin_get_pole:NnN #3 { #2 -T } \l_coffin_pole_b_tl + \exp_last_two_unbraced:Noo \coffin_update_T:nnnnnnnnN + \l_coffin_pole_a_tl \l_coffin_pole_b_tl #3 + \coffin_get_pole:NnN #3 { #1 -B } \l_coffin_pole_a_tl + \coffin_get_pole:NnN #3 { #2 -B } \l_coffin_pole_b_tl + \exp_last_two_unbraced:Noo \coffin_update_B:nnnnnnnnN + \l_coffin_pole_a_tl \l_coffin_pole_b_tl #3 + } +\cs_new_protected_nopar:Npn \coffin_update_T:nnnnnnnnN #1#2#3#4#5#6#7#8#9 + { + \dim_compare:nNnTF {#2} < {#6} + { + \coffin_set_pole:Nnx #9 { T } + { { 0 pt } {#6} { 1000 pt } { 0 pt } } + } + { + \coffin_set_pole:Nnx #9 { T } + { { 0 pt } {#2} { 1000 pt } { 0 pt } } + } + } +\cs_new_protected_nopar:Npn \coffin_update_B:nnnnnnnnN #1#2#3#4#5#6#7#8#9 + { + \dim_compare:nNnTF {#2} < {#6} + { + \coffin_set_pole:Nnx #9 { B } + { { 0 pt } {#2} { 1000 pt } { 0 pt } } + } + { + \coffin_set_pole:Nnx #9 { B } + { { 0 pt } {#6} { 1000 pt } { 0 pt } } + } + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\coffin_typeset:Nnnnn, \coffin_typeset:cnnnn} +% Typesetting a coffin means aligning it with the current position, +% which is done using a coffin with no content at all. This is done +% using the same approach as \cs{coffin_align:NnnNnnnnN} but without the +% offset corrections (which would be thrown away). The same is true +% for overlaying coffins, which uses the known size of an empty +% box! +% \begin{macrocode} +\cs_new_protected_nopar:Npn \coffin_typeset:Nnnnn #1#2#3#4#5 + { + \coffin_align:NnnNnnnnN \c_empty_coffin { H } { l } + #1 {#2} {#3} {#4} {#5} \l_coffin_aligned_coffin + \hbox_set:Nn \l_coffin_aligned_coffin + { + \dim_compare:nNnT { \l_coffin_offset_x_dim } < \c_zero_dim + { \tex_kern:D -\l_coffin_offset_x_dim } + \hbox_unpack:N \l_coffin_aligned_coffin + \dim_set:Nn \l_coffin_tmp_dim + { \l_coffin_offset_x_dim + \box_wd:N #1 } + \dim_compare:nNnT { \l_coffin_tmp_dim } < \c_zero_dim + { \tex_kern:D -\l_coffin_tmp_dim } + } + \hbox_unpack:N \c_empty_box + \box_use:N \l_coffin_aligned_coffin + } +\cs_generate_variant:Nn \coffin_typeset:Nnnnn { c } +% \end{macrocode} +% \end{macro} +% +% \subsection{Rotating coffins} +% +% \begin{variable}{\l_coffin_bounding_prop} +% A property list for the bounding box of a coffin. This is only needed +% during the rotation, so there is just the one. +% \begin{macrocode} +\prop_new:N \l_coffin_bounding_prop +% \end{macrocode} +% \end{variable} +% +% \begin{variable}{\l_coffin_bounding_shift_dim} +% The shift of the bounding box of a coffin from the real content. +% \begin{macrocode} +\dim_new:N \l_coffin_bounding_shift_dim +% \end{macrocode} +% \end{variable} +% +% \begin{variable}{\l_coffin_left_corner_dim} +% \begin{variable}{\l_coffin_right_corner_dim} +% \begin{variable}{\l_coffin_bottom_corner_dim} +% \begin{variable}{\l_coffin_top_corner_dim} +% These are used to hold maxima for the various corner values: these +% thus define the minimum size of the bounding box after rotation. +% \begin{macrocode} +\dim_new:N \l_coffin_left_corner_dim +\dim_new:N \l_coffin_right_corner_dim +\dim_new:N \l_coffin_bottom_corner_dim +\dim_new:N \l_coffin_top_corner_dim +% \end{macrocode} +% \end{variable} +% \end{variable} +% \end{variable} +% \end{variable} +% +% \begin{macro}{\coffin_rotate:Nn, \coffin_rotate:cn} +% Rotating a coffin requires several steps which can be conveniently +% run together. The first step is to convert the angle given in degrees +% to one in radians. This is then used to set \cs{l_coffin_sin_fp} and +% \cs{l_coffin_cos_fp}, which are carried through unchanged for the rest +% of the procedure. +% \begin{macrocode} +\cs_new_protected_nopar:Npn \coffin_rotate:Nn #1#2 + { + \fp_set:Nn \l_coffin_tmp_fp {#2} + \fp_div:Nn \l_coffin_tmp_fp { 180 } + \fp_mul:Nn \l_coffin_tmp_fp { \c_pi_fp } + \fp_sin:Nn \l_coffin_sin_fp { \l_coffin_tmp_fp } + \fp_cos:Nn \l_coffin_cos_fp { \l_coffin_tmp_fp } +% \end{macrocode} +% The corners and poles of the coffin can now be rotated around the +% origin. This is best achieved using mapping functions. +% \begin{macrocode} + \prop_map_inline:cn { l_coffin_corners_ \int_value:w #1 _prop } + { \coffin_rotate_corner:Nnnn #1 {##1} ##2 } + \prop_map_inline:cn { l_coffin_poles_ \int_value:w #1 _prop } + { \coffin_rotate_pole:Nnnnnn #1 {##1} ##2 } +% \end{macrocode} +% The bounding box of the coffin needs to be rotated, and to do this +% the corners have to be found first. They are then rotated in the same +% way as the corners of the coffin material itself. +% \begin{macrocode} + \coffin_set_bounding:N #1 + \prop_map_inline:Nn \l_coffin_bounding_prop + { \coffin_rotate_bounding:nnn {##1} ##2 } +% \end{macrocode} +% At this stage, there needs to be a calculation to find where the +% corners of the content and the box itself will end up. +% \begin{macrocode} + \coffin_find_corner_maxima:N #1 + \coffin_find_bounding_shift: +%<*initex> + \hbox_set:Nn #1 { \box_rotate:Nn #1 {#2} } % TODO +%</initex> +%<*package> + \hbox_set:Nn #1 { \rotatebox {#2} { \box_use:N #1 } } +%</package> +% \end{macrocode} +% The correction of the box position itself takes place here. The idea +% is that the bounding box for a coffin is tight up to the content, and +% has the reference point at the bottom-left. The $x$-direction is +% handled by moving the content by the difference in the positions of +% the bounding box and the content left edge. The $y$-direction is +% dealt with by moving the box down by any depth it has acquired. +% \begin{macrocode} + \hbox_set:Nn #1 + { + \tex_kern:D \l_coffin_bounding_shift_dim + \tex_kern:D -\l_coffin_left_corner_dim + \box_move_down:nn { \l_coffin_bottom_corner_dim } + { \box_use:N #1 } + } +% \end{macrocode} +% If there have been any previous rotations then the size of the +% bounding box will be bigger than the contents. This can be corrected +% easily by setting the size of the box to the height and width of the +% content. +% \begin{macrocode} + \box_set_ht:Nn #1 + { \l_coffin_top_corner_dim - \l_coffin_bottom_corner_dim } + \box_set_dp:Nn #1 { 0 pt } + \box_set_wd:Nn #1 + { \l_coffin_right_corner_dim - \l_coffin_left_corner_dim } +% \end{macrocode} +% The final task is to move the poles and corners such that they are +% back in alignment with the box reference point. +% \begin{macrocode} + \prop_map_inline:cn { l_coffin_corners_ \int_value:w #1 _prop } + { \coffin_shift_corner:Nnnn #1 {##1} ##2 } + \prop_map_inline:cn { l_coffin_poles_ \int_value:w #1 _prop } + { \coffin_shift_pole:Nnnnnn #1 {##1} ##2 } + } +\cs_generate_variant:Nn \coffin_rotate:Nn { c } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\coffin_set_bounding:N} +% The bounding box corners for a coffin are easy enough to find: this +% is the same code as for the corners of the material itself, but +% using a dedicated property list. +% \begin{macrocode} +\cs_new_protected_nopar:Npn \coffin_set_bounding:N #1 + { + \prop_put:Nnx \l_coffin_bounding_prop { tl } + { { 0 pt } { \dim_use:N \box_ht:N #1 } } + \prop_put:Nnx \l_coffin_bounding_prop { tr } + { { \dim_use:N \box_wd:N #1 } { \dim_use:N \box_ht:N #1 } } + \dim_set:Nn \l_coffin_tmp_dim { - \box_dp:N #1 } + \prop_put:Nnx \l_coffin_bounding_prop { bl } + { { 0 pt } { \dim_use:N \l_coffin_tmp_dim } } + \prop_put:Nnx \l_coffin_bounding_prop { br } + { { \dim_use:N \box_wd:N #1 } { \dim_use:N \l_coffin_tmp_dim } } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\coffin_rotate_bounding:nnn} +% \begin{macro}{\coffin_rotate_corner:Nnnn} +% Rotating the position of the corner of the coffin is just a case +% of treating this as a vector from the reference point. The same +% treatment is used for the corners of the material itself and the +% bounding box. +% \begin{macrocode} +\cs_new_protected_nopar:Npn \coffin_rotate_bounding:nnn #1#2#3 + { + \coffin_rotate_vector:nnNN {#2} {#3} \l_coffin_x_dim \l_coffin_y_dim + \prop_put:Nnx \l_coffin_bounding_prop {#1} + { { \dim_use:N \l_coffin_x_dim } { \dim_use:N \l_coffin_y_dim } } + } +\cs_new_protected_nopar:Npn \coffin_rotate_corner:Nnnn #1#2#3#4 + { + \coffin_rotate_vector:nnNN {#3} {#4} \l_coffin_x_dim \l_coffin_y_dim + \prop_put:cnx { l_coffin_corners_ \int_value:w #1 _prop } {#2} + { { \dim_use:N \l_coffin_x_dim } { \dim_use:N \l_coffin_y_dim } } + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\coffin_rotate_pole:Nnnnnn} +% Rotating a single pole simply means shifting the co-ordinate of +% the pole and its direction. The rotation here is about the bottom-left +% corner of the coffin. +% \begin{macrocode} +\cs_new_protected_nopar:Npn \coffin_rotate_pole:Nnnnnn #1#2#3#4#5#6 + { + \coffin_rotate_vector:nnNN {#3} {#4} \l_coffin_x_dim \l_coffin_y_dim + \coffin_rotate_vector:nnNN {#5} {#6} + \l_coffin_x_prime_dim \l_coffin_y_prime_dim + \coffin_set_pole:Nnx #1 {#2} + { + { \dim_use:N \l_coffin_x_dim } { \dim_use:N \l_coffin_y_dim } + { \dim_use:N \l_coffin_x_prime_dim } + { \dim_use:N \l_coffin_y_prime_dim } + } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\coffin_rotate_vector:nnNN} +% A rotation function, which needs only an input vector (as dimensions) +% and an output space. The values \cs{l_coffin_cos_fp} and +% \cs{l_coffin_sin_fp} should previously have been set up correctly. +% Working this way means that the floating point work is kept to a +% minimum: for any given rotation the sin and cosine values do no +% change, after all. +% \begin{macrocode} +\cs_new_protected_nopar:Npn \coffin_rotate_vector:nnNN #1#2#3#4 + { + \fp_set_from_dim:Nn \l_coffin_x_fp {#1} + \fp_set_from_dim:Nn \l_coffin_y_fp {#2} + \fp_set_eq:NN \l_coffin_x_prime_fp \l_coffin_x_fp + \fp_set_eq:NN \l_coffin_tmp_fp \l_coffin_y_fp + \fp_mul:Nn \l_coffin_x_prime_fp { \l_coffin_cos_fp } + \fp_mul:Nn \l_coffin_tmp_fp { \l_coffin_sin_fp } + \fp_sub:Nn \l_coffin_x_prime_fp { \l_coffin_tmp_fp } + \fp_set_eq:NN \l_coffin_y_prime_fp \l_coffin_y_fp + \fp_set_eq:NN \l_coffin_tmp_fp \l_coffin_x_fp + \fp_mul:Nn \l_coffin_y_prime_fp { \l_coffin_cos_fp } + \fp_mul:Nn \l_coffin_tmp_fp { \l_coffin_sin_fp } + \fp_add:Nn \l_coffin_y_prime_fp { \l_coffin_tmp_fp } + \dim_set:Nn #3 { \fp_to_dim:N \l_coffin_x_prime_fp } + \dim_set:Nn #4 { \fp_to_dim:N \l_coffin_y_prime_fp } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\coffin_find_corner_maxima:N} +% \begin{macro}[aux]{\coffin_find_corner_maxima_aux:nn} +% The idea here is to find the extremities of the content of the +% coffin. This is done by looking for the smallest values for the bottom +% and left corners, and the largest values for the top and right +% corners. The values start at the maximum dimensions so that the +% case where all are positive or all are negative works out correctly. +% \begin{macrocode} +\cs_new_protected_nopar:Npn \coffin_find_corner_maxima:N #1 + { + \dim_set:Nn \l_coffin_top_corner_dim { -\c_max_dim } + \dim_set:Nn \l_coffin_right_corner_dim { -\c_max_dim } + \dim_set:Nn \l_coffin_bottom_corner_dim { \c_max_dim } + \dim_set:Nn \l_coffin_left_corner_dim { \c_max_dim } + \prop_map_inline:cn { l_coffin_corners_ \int_value:w #1 _prop } + { \coffin_find_corner_maxima_aux:nn ##2 } + } +\cs_new_protected_nopar:Npn \coffin_find_corner_maxima_aux:nn #1#2 + { + \dim_set_min:Nn \l_coffin_left_corner_dim {#1} + \dim_set_max:Nn \l_coffin_right_corner_dim {#1} + \dim_set_min:Nn \l_coffin_bottom_corner_dim {#2} + \dim_set_max:Nn \l_coffin_top_corner_dim {#2} + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\coffin_find_bounding_shift:} +% \begin{macro}[aux]{\coffin_find_bounding_shift_aux:nn} +% The approach to finding the shift for the bounding box is similar to +% that for the corners. However, there is only one value needed here and +% a fixed input property list, so things are a bit clearer. +% \begin{macrocode} +\cs_new_protected_nopar:Npn \coffin_find_bounding_shift: + { + \dim_set:Nn \l_coffin_bounding_shift_dim { \c_max_dim } + \prop_map_inline:Nn \l_coffin_bounding_prop + { \coffin_find_bounding_shift_aux:nn ##2 } + } +\cs_new_protected_nopar:Npn \coffin_find_bounding_shift_aux:nn #1#2 + { \dim_set_min:Nn \l_coffin_bounding_shift_dim {#1} } +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\coffin_shift_corner:Nnnn} +% \begin{macro}{\coffin_shift_pole:Nnnnnn} +% Shifting the corners and poles of a coffin means subtracting the +% appropriate values from the $x$- and $y$-components. For +% the poles, this means that the direction vector is unchanged. +% \begin{macrocode} +\cs_new_protected_nopar:Npn \coffin_shift_corner:Nnnn #1#2#3#4 + { + \prop_put:cnx { l_coffin_corners_ \int_value:w #1 _ prop } {#2} + { + { \dim_eval:n { #3 - \l_coffin_left_corner_dim } } + { \dim_eval:n { #4 - \l_coffin_bottom_corner_dim } } + } + } +\cs_new_protected_nopar:Npn \coffin_shift_pole:Nnnnnn #1#2#3#4#5#6 + { + \prop_put:cnx { l_coffin_poles_ \int_value:w #1 _ prop } {#2} + { + { \dim_eval:n { #3 - \l_coffin_left_corner_dim } } + { \dim_eval:n { #4 - \l_coffin_bottom_corner_dim } } + {#5} {#6} + } + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \subsection{Coffin diagnostics} +% +% \begin{variable}{\l_coffin_display_coffin} +% \begin{variable}{\l_coffin_display_coord_coffin} +% \begin{variable}{\l_coffin_display_pole_coffin} +% Used for printing coffins with data structures attached. +% \begin{macrocode} +\coffin_new:N \l_coffin_display_coffin +\coffin_new:N \l_coffin_display_coord_coffin +\coffin_new:N \l_coffin_display_pole_coffin +% \end{macrocode} +% \end{variable} +% \end{variable} +% \end{variable} +% +% \begin{variable}{\l_coffin_display_handles_prop} +% This property list is used to print coffin handles at suitable +% positions. The offsets are expressed as multiples of the basic offset +% value, which therefore acts as a scale-factor. +% \begin{macrocode} +\prop_new:N \l_coffin_display_handles_prop +\prop_put:Nnn \l_coffin_display_handles_prop { tl } + { { b } { r } { -1 } { 1 } } +\prop_put:Nnn \l_coffin_display_handles_prop { thc } + { { b } { hc } { 0 } { 1 } } +\prop_put:Nnn \l_coffin_display_handles_prop { tr } + { { b } { l } { 1 } { 1 } } +\prop_put:Nnn \l_coffin_display_handles_prop { vcl } + { { vc } { r } { -1 } { 0 } } +\prop_put:Nnn \l_coffin_display_handles_prop { vchc } + { { vc } { hc } { 0 } { 0 } } +\prop_put:Nnn \l_coffin_display_handles_prop { vcr } + { { vc } { l } { 1 } { 0 } } +\prop_put:Nnn \l_coffin_display_handles_prop { bl } + { { t } { r } { -1 } { -1 } } +\prop_put:Nnn \l_coffin_display_handles_prop { bhc } + { { t } { hc } { 0 } { -1 } } +\prop_put:Nnn \l_coffin_display_handles_prop { br } + { { t } { l } { 1 } { -1 } } +\prop_put:Nnn \l_coffin_display_handles_prop { Tl } + { { t } { r } { -1 } { -1 } } +\prop_put:Nnn \l_coffin_display_handles_prop { Thc } + { { t } { hc } { 0 } { -1 } } +\prop_put:Nnn \l_coffin_display_handles_prop { Tr } + { { t } { l } { 1 } { -1 } } +\prop_put:Nnn \l_coffin_display_handles_prop { Hl } + { { vc } { r } { -1 } { 1 } } +\prop_put:Nnn \l_coffin_display_handles_prop { Hhc } + { { vc } { hc } { 0 } { 1 } } +\prop_put:Nnn \l_coffin_display_handles_prop { Hr } + { { vc } { l } { 1 } { 1 } } +\prop_put:Nnn \l_coffin_display_handles_prop { Bl } + { { b } { r } { -1 } { -1 } } +\prop_put:Nnn \l_coffin_display_handles_prop { Bhc } + { { b } { hc } { 0 } { -1 } } +\prop_put:Nnn \l_coffin_display_handles_prop { Br } + { { b } { l } { 1 } { -1 } } +% \end{macrocode} +% \end{variable} +% +% \begin{variable}{\l_coffin_display_offset_dim} +% The standard offset for the label from the handle position when +% displaying handles. +% \begin{macrocode} +\dim_new:N \l_coffin_display_offset_dim +\dim_set:Nn \l_coffin_display_offset_dim { 2 pt } +% \end{macrocode} +% \end{variable} +% +% \begin{variable}{\l_coffin_display_x_dim} +% \begin{variable}{\l_coffin_display_y_dim} +% As the intersections of poles have to be calculated to find which +% ones to print, there is a need to avoid repetition. This is done +% by saving the intersection into two dedicated values. +% \begin{macrocode} +\dim_new:N \l_coffin_display_x_dim +\dim_new:N \l_coffin_display_y_dim +% \end{macrocode} +% \end{variable} +% \end{variable} +% +% \begin{variable}{\l_coffin_display_poles_prop} +% A property list for printing poles: various things need to be deleted +% from this to get a \enquote{nice} output. +% \begin{macrocode} +\prop_new:N \l_coffin_display_poles_prop +% \end{macrocode} +% \end{variable} +% +% \begin{variable}{\l_coffin_display_font_tl} +% Stores the settings used to print coffin data: this keeps things +% flexible. +% \begin{macrocode} +\tl_new:N \l_coffin_display_font_tl +%<*initex> +\tl_set:Nn \l_coffin_display_font_tl { } % TODO +%</initex> +%<*package> +\tl_set:Nn \l_coffin_display_font_tl { \sffamily \tiny } +%</package> +% \end{macrocode} +% \end{variable} +% +% \begin{variable}{\l_coffin_handles_tmp_prop} +% Used for displaying coffins, as the handles need to be stored in this +% case, at least temporarily. +% \begin{macrocode} +\prop_new:N \l_coffin_handles_tmp_prop +% \end{macrocode} +% \end{variable} +% +% \begin{macro}{\coffin_mark_handle:Nnnn, \coffin_mark_handle:cnnn} +% \begin{macro}[aux]{\coffin_mark_handle_aux:nnnnNnn} +% Marking a single handle is relatively easy. The standard attachment +% function is used, meaning that there are two calculations for the +% location. However, this is likely to be okay given the load expected. +% Contrast with the more optimised version for showing all handles which +% comes next. +% \begin{macrocode} +\cs_new_protected_nopar:Npn \coffin_mark_handle:Nnnn #1#2#3#4 + { + \hcoffin_set:Nn \l_coffin_display_pole_coffin + { +%<*initex> + \hbox:n { \tex_vrule:D width 1 pt height 1 pt \scan_stop: } % TODO +%</initex> +%<*package> + \color {#4} + \rule { 1 pt } { 1 pt } +%</package> + } + \coffin_attach_mark:NnnNnnnn #1 {#2} {#3} + \l_coffin_display_pole_coffin { hc } { vc } { 0 pt } { 0 pt } + \hcoffin_set:Nn \l_coffin_display_coord_coffin + { +%<*initex> + % TODO +%</initex> +%<*package> + \color {#4} +%</package> + \l_coffin_display_font_tl + ( \tl_to_str:n { #2 , #3 } ) + } + \prop_get:NnN \l_coffin_display_handles_prop + { #2 #3 } \l_coffin_tmp_tl + \quark_if_no_value:NTF \l_coffin_tmp_tl + { + \prop_get:NnN \l_coffin_display_handles_prop + { #3 #2 } \l_coffin_tmp_tl + \quark_if_no_value:NTF \l_coffin_tmp_tl + { + \coffin_attach_mark:NnnNnnnn #1 {#2} {#3} + \l_coffin_display_coord_coffin { l } { vc } + { 1 pt } { 0 pt } + } + { + \exp_last_unbraced:No \coffin_mark_handle_aux:nnnnNnn + \l_coffin_tmp_tl #1 {#2} {#3} + } + } + { + \exp_last_unbraced:No \coffin_mark_handle_aux:nnnnNnn + \l_coffin_tmp_tl #1 {#2} {#3} + } + } +\cs_new_protected_nopar:Npn \coffin_mark_handle_aux:nnnnNnn #1#2#3#4#5#6#7 + { + \coffin_attach_mark:NnnNnnnn #5 {#6} {#7} + \l_coffin_display_coord_coffin {#1} {#2} + { #3 \l_coffin_display_offset_dim } + { #4 \l_coffin_display_offset_dim } + } +\cs_generate_variant:Nn \coffin_mark_handle:Nnnn { c } +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\coffin_display_handles:Nn, \coffin_display_handles:cn} +% \begin{macro}[aux]{\coffin_display_handles_aux:nnnnnn} +% \begin{macro}[aux]{\coffin_display_handles_aux:nnnn} +% \begin{macro}[aux]{\coffin_display_attach:Nnnnn} +% Printing the poles starts by removing any duplicates, for which the +% \texttt{H} poles is used as the definitive version for the baseline +% and bottom. Two loops are then used to find the combinations of +% handles for all of these poles. This is done such that poles are +% removed during the loops to avoid duplication. +% \begin{macrocode} +\cs_new_protected_nopar:Npn \coffin_display_handles:Nn #1#2 + { + \hcoffin_set:Nn \l_coffin_display_pole_coffin + { +%<*initex> + \hbox:n { \tex_vrule:D width 1 pt height 1 pt \scan_stop: } % TODO +%</initex> +%<*package> + \color {#2} + \rule { 1 pt } { 1 pt } +%</package> + } + \prop_set_eq:Nc \l_coffin_display_poles_prop + { l_coffin_poles_ \int_value:w #1 _prop } + \coffin_get_pole:NnN #1 { H } \l_coffin_pole_a_tl + \coffin_get_pole:NnN #1 { T } \l_coffin_pole_b_tl + \tl_if_eq:NNT \l_coffin_pole_a_tl \l_coffin_pole_b_tl + { \prop_del:Nn \l_coffin_display_poles_prop { T } } + \coffin_get_pole:NnN #1 { B } \l_coffin_pole_b_tl + \tl_if_eq:NNT \l_coffin_pole_a_tl \l_coffin_pole_b_tl + { \prop_del:Nn \l_coffin_display_poles_prop { B } } + \coffin_set_eq:NN \l_coffin_display_coffin #1 + \prop_clear:N \l_coffin_handles_tmp_prop + \prop_map_inline:Nn \l_coffin_display_poles_prop + { + \prop_del:Nn \l_coffin_display_poles_prop {##1} + \coffin_display_handles_aux:nnnnnn {##1} ##2 {#2} + } + \box_use:N \l_coffin_display_coffin + } +% \end{macrocode} +% For each pole there is a check for an intersection, which here does +% not give an error if none is found. The successful values are stored +% and used to align the pole coffin with the main coffin for output. +% The positions are recovered from the preset list if available. +% \begin{macrocode} +\cs_new_protected_nopar:Npn \coffin_display_handles_aux:nnnnnn #1#2#3#4#5#6 + { + \prop_map_inline:Nn \l_coffin_display_poles_prop + { + \bool_set_false:N \l_coffin_error_bool + \coffin_calculate_intersection:nnnnnnnn {#2} {#3} {#4} {#5} ##2 + \bool_if:NF \l_coffin_error_bool + { + \dim_set:Nn \l_coffin_display_x_dim { \l_coffin_x_dim } + \dim_set:Nn \l_coffin_display_y_dim { \l_coffin_y_dim } + \coffin_display_attach:Nnnnn + \l_coffin_display_pole_coffin { hc } { vc } + { 0 pt } { 0 pt } + \hcoffin_set:Nn \l_coffin_display_coord_coffin + { +%<*initex> + % TODO +%</initex> +%<*package> + \color {#6} +%</package> + \l_coffin_display_font_tl + ( \tl_to_str:n { #1 , ##1 } ) + } + \prop_get:NnN \l_coffin_display_handles_prop + { #1 ##1 } \l_coffin_tmp_tl + \quark_if_no_value:NTF \l_coffin_tmp_tl + { + \prop_get:NnN \l_coffin_display_handles_prop + { ##1 #1 } \l_coffin_tmp_tl + \quark_if_no_value:NTF \l_coffin_tmp_tl + { + \coffin_display_attach:Nnnnn + \l_coffin_display_coord_coffin { l } { vc } + { 1 pt } { 0 pt } + } + { + \exp_last_unbraced:No + \coffin_display_handles_aux:nnnn + \l_coffin_tmp_tl + } + } + { + \exp_last_unbraced:No \coffin_display_handles_aux:nnnn + \l_coffin_tmp_tl + } + } + } + } +\cs_new_protected_nopar:Npn \coffin_display_handles_aux:nnnn #1#2#3#4 + { + \coffin_display_attach:Nnnnn + \l_coffin_display_coord_coffin {#1} {#2} + { #3 \l_coffin_display_offset_dim } + { #4 \l_coffin_display_offset_dim } + } +\cs_generate_variant:Nn \coffin_display_handles:Nn { c } +% \end{macrocode} +% This is a dedicated version of \cs{coffin_attach:NnnNnnnn} with +% a hard-wired first coffin. As the intersection is already known +% and stored for the display coffin the code simply uses it directly, +% with no calculation. +% \begin{macrocode} +\cs_new_protected_nopar:Npn \coffin_display_attach:Nnnnn #1#2#3#4#5 + { + \coffin_calculate_intersection:Nnn #1 {#2} {#3} + \dim_set:Nn \l_coffin_x_prime_dim { \l_coffin_x_dim } + \dim_set:Nn \l_coffin_y_prime_dim { \l_coffin_y_dim } + \dim_set:Nn \l_coffin_offset_x_dim + { \l_coffin_display_x_dim - \l_coffin_x_prime_dim + #4 } + \dim_set:Nn \l_coffin_offset_y_dim + { \l_coffin_display_y_dim - \l_coffin_y_prime_dim + #5 } + \hbox_set:Nn \l_coffin_aligned_coffin + { + \box_use:N \l_coffin_display_coffin + \tex_kern:D -\box_wd:N \l_coffin_display_coffin + \tex_kern:D \l_coffin_offset_x_dim + \box_move_up:nn { \l_coffin_offset_y_dim } { \box_use:N #1 } + } + \box_set_ht:Nn \l_coffin_aligned_coffin + { \box_ht:N \l_coffin_display_coffin } + \box_set_dp:Nn \l_coffin_aligned_coffin + { \box_dp:N \l_coffin_display_coffin } + \box_set_wd:Nn \l_coffin_aligned_coffin + { \box_wd:N \l_coffin_display_coffin } + \box_set_eq:NN \l_coffin_display_coffin \l_coffin_aligned_coffin + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\coffin_show_structure:N, \coffin_show_structure:c} +% \begin{macro}[aux]{\coffin_show_aux:n} +% \begin{macro}[aux]{\coffin_show_aux:w} +% For showing the various internal structures attached to a coffin in +% a way that keeps things relatively readable. If there is no apparent +% structure then the code complains. +% \begin{macrocode} +\cs_new_protected_nopar:Npn \coffin_show_structure:N #1 + { + \cs_if_exist:cTF { l_coffin_poles_ \int_value:w #1 _prop } + { + \iow_term:x + { + \iow_newline: + Size~of~coffin~\token_to_str:N #1 : \iow_newline: + > ~ ht~=~\dim_use:N \box_ht:N #1 \iow_newline: + > ~ dp~=~\dim_use:N \box_dp:N #1 \iow_newline: + > ~ wd~=~\dim_use:N \box_wd:N #1 \iow_newline: + } + \iow_term:x { Poles~of~coffin~\token_to_str:N #1 : } + \tl_set:Nx \l_coffin_tmp_tl + { + \prop_map_function:cN + { l_coffin_poles_ \int_value:w #1 _prop } + \coffin_show_aux:nn + } + \etex_showtokens:D \exp_after:wN \exp_after:wN \exp_after:wN + { \exp_after:wN \coffin_show_aux:w \l_coffin_tmp_tl } + } + { + \iow_term:x { ---~No~poles~found~--- } + \tl_show:n { Is~this~really~a~coffin? } + } + } +\cs_new:Npn \coffin_show_aux:nn #1#2 + { + \iow_newline: > \c_space_tl \c_space_tl + #1 \c_space_tl \c_space_tl => \c_space_tl \c_space_tl \exp_not:n {#2} + } +\cs_new_nopar:Npn \coffin_show_aux:w #1 > ~ { } +\cs_generate_variant:Nn \coffin_show_structure:N { c } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \subsection{Messages} +% +% \begin{macrocode} +\msg_kernel_new:nnnn { coffin } { no-pole-intersection } + { No~intersection~between~coffin~poles. } + { + \c_msg_coding_error_text_tl + LaTeX~was~asked~to~find~the~intersection~between~two~poles,~ + but~they~do~not~have~a~unique~meeting~point:~ + the~value~(0~pt,~0~pt)~will~be~used. + } +\msg_kernel_new:nnnn { coffin } { unknown-coffin } + { Unknown~coffin~'#1'. } + { The~coffin~'#1'~was~never~defined. } +\msg_kernel_new:nnnn { coffin } { unknown-coffin-pole } + { Pole~'#1'~unknown~for~coffin~'#2'. } + { + \c_msg_coding_error_text_tl + LaTeX~was~asked~to~find~a~typesetting~pole~for~a~coffin,~ + but~either~the~coffin~does~not~exist~or~the~pole~name~is~wrong. + } +% \end{macrocode} +% +% \begin{macrocode} +%</initex|package> +% \end{macrocode} +% +% \end{implementation} +% +% \PrintIndex
\ No newline at end of file diff --git a/Master/texmf-dist/source/latex/l3kernel/l3doc.dtx b/Master/texmf-dist/source/latex/l3kernel/l3doc.dtx index ed8f421b259..7bc2ffb5687 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3doc.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3doc.dtx @@ -78,7 +78,7 @@ Do not distribute a modified version of this file. % \end{macrocode} % %<*driver|class> -\GetIdInfo$Id: l3doc.dtx 2601 2011-08-16 23:20:27Z bruno $ +\GetIdInfo$Id: l3doc.dtx 2674 2011-08-27 19:43:44Z mittelba $ {L3 Experimental documentation class} %</driver|class> % @@ -180,7 +180,11 @@ Do not distribute a modified version of this file. % % \section{Problems \& Todo} % -% Problems at the moment: (1)~not flexible in the types of things that can be documented; (2)~very nonstandard markup (e.g., the odd `"/ (...)"' tags; (3)~no obvious link between the "\begin{function}" environment for documenting things to the "\begin{macro}" function that's used analogously in the implementation. +% Problems at the moment: (1)~not flexible in the types of things that +% can be documented; (2)~very nonstandard markup (e.g., the odd `"/ +% (...)"' tags; (3)~no obvious link between the "\begin{function}" +% environment for documenting things to the "\begin{macro}" function +% that's used analogously in the implementation. % % The "macro" should probably be renamed to "function" when it is used within % an implementation section. But they should have the same syntax before that happens! @@ -480,7 +484,7 @@ Do not distribute a modified version of this file. Frank~Mittelbach,~Denys~Duchier,~Chris~Rowley,~ Rainer~Sch\"opf,~Johannes~Braams,~Michael~Downes,~ David~Carlisle,~Alan~Jeffrey,~Morten~H\o{}gholm,~Thomas~Lotze,~ - Javier~Bezos,~Will~Robertson,~Joseph~Wright}} + Javier~Bezos,~Will~Robertson,~Joseph~Wright,~Bruno~Le~Floch}} % \end{macrocode} % % \subsection{Options and configuration} @@ -628,6 +632,29 @@ Do not distribute a modified version of this file. \setlength \parskip { \medskipamount } % \end{macrocode} % +% +% Customise TOC (as we have so many sections). Different design and/or +% structure is called for ): +% \begin{macrocode} +\cs_set_nopar:Npn \l@section #1#2 { + \ifnum \c@tocdepth >\z@ + \addpenalty\@secpenalty + \addvspace{1.0em \@plus\p@} + \setlength\@tempdima{2.5em} % was 1.5em + \begingroup + \parindent \z@ \rightskip \@pnumwidth + \parfillskip -\@pnumwidth + \leavevmode \bfseries + \advance\leftskip\@tempdima + \hskip -\leftskip + #1\nobreak\hfil \nobreak\hb@xt@\@pnumwidth{\hss #2}\par + \endgroup + \fi} +\cs_set_nopar:Npn\l@subsection{\@dottedtocline{2}{2.5em}{2.3em}} % #2 = 1.5em +% \end{macrocode} +% + +% % \subsection{Text markup} % % Make "|" and |"| be `short verb' characters, but not in diff --git a/Master/texmf-dist/source/latex/l3kernel/l3file.dtx b/Master/texmf-dist/source/latex/l3kernel/l3file.dtx index 7ec9de82c5e..d124905c547 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3file.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3file.dtx @@ -35,7 +35,7 @@ % %<*driver|package> \RequirePackage{l3names} -\GetIdInfo$Id: l3file.dtx 2478 2011-06-19 21:34:23Z joseph $ +\GetIdInfo$Id: l3file.dtx 2665 2011-08-25 22:15:27Z joseph $ {L3 Experimental file operations} %</driver|package> %<*driver> @@ -94,10 +94,7 @@ % \end{syntax} % Searches for \meta{file name} using the current \TeX{} search % path and the additional paths controlled by -% \cs{file_path_include:n}). The branching versions then leave -% either \meta{true code} or \meta{false code} in the input stream, -% as appropriate to the truth of the test and the variant of the -% function chosen. +% \cs{file_path_include:n}). % \begin{texnote} % The \meta{file name} may contain both literal items and expandable % content, which should on full expansion be the desired file name. diff --git a/Master/texmf-dist/source/latex/l3kernel/l3format.ins b/Master/texmf-dist/source/latex/l3kernel/l3format.ins deleted file mode 100644 index 562695271fa..00000000000 --- a/Master/texmf-dist/source/latex/l3kernel/l3format.ins +++ /dev/null @@ -1,72 +0,0 @@ -\iffalse meta-comment - -File l3format.ins Copyright (C) 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 "expl3 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. - -\fi - -\input docstrip.tex -\askforoverwritefalse - -\preamble - -EXPERIMENTAL CODE - -Do not distribute this file without also distributing the -source files specified above. - -Do not distribute a modified version of this file. - -\endpreamble -% stop docstrip adding \endinput -\postamble -\endpostamble - -\keepsilent - -\generate - { - \file{l3format.ltx} - { - \from{l3bootstrap.dtx}{initex} - \from{l3names.dtx} {initex} - \from{l3basics.dtx} {initex} - \from{l3expan.dtx} {initex} - \from{l3tl.dtx} {initex} - \from{l3seq.dtx} {initex} - % ===== FORMAT ONLY ====== - \from{l3alloc.dtx} {initex} - % ======================== - \from{l3int.dtx} {initex} - \from{l3quark.dtx} {initex} - \from{l3prg.dtx} {initex} - \from{l3clist.dtx} {initex} - \from{l3token.dtx} {initex} - \from{l3prop.dtx} {initex} - \from{l3msg.dtx} {initex} - \from{l3io.dtx} {initex} - \from{l3file.dtx} {initex} - \from{l3skip.dtx} {initex} - \from{l3box.dtx} {initex} - \from{l3keyval.dtx} {initex} - \from{l3keys.dtx} {initex} - \from{l3fp.dtx} {initex} - \from{l3luatex.dtx} {initex} - % ===== FORMAT ONLY ====== - \from{l3final.dtx} {initex} - % ======================== - } - } - -\endbatchfile
\ No newline at end of file diff --git a/Master/texmf-dist/source/latex/l3kernel/l3fp.dtx b/Master/texmf-dist/source/latex/l3kernel/l3fp.dtx index 36ac323debd..69646c165a1 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3fp.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3fp.dtx @@ -35,7 +35,7 @@ % %<*driver|package> \RequirePackage{l3names} -\GetIdInfo$Id: l3fp.dtx 2478 2011-06-19 21:34:23Z joseph $ +\GetIdInfo$Id: l3fp.dtx 2665 2011-08-25 22:15:27Z joseph $ {L3 Experimental floating-point operations} %</driver|package> %<*driver> @@ -328,11 +328,7 @@ % ~~\Arg{true code} \Arg{false code} % \end{syntax} % Tests if \meta{floating point} is undefined (\emph{i.e.}~equal to the -% special \cs{c_undefined_fp} variable). The branching versions then -% leave either \meta{true code} or \meta{false code} in the input -% stream, as appropriate to the truth of the test and the variant of -% the function chosen. The logical truth of the test is left in the -% input stream by the predicate version. +% special \cs{c_undefined_fp} variable). % \end{function} % % \begin{function}[EXP]{\fp_if_zero:N} @@ -341,11 +337,7 @@ % \cs{fp_if_zero:NTF} \meta{fixed-point} \Arg{true code} \Arg{false code} % \end{syntax} % Tests if \meta{floating point} is equal to zero (\emph{i.e.}~equal to -% the special \cs{c_zero_fp} variable). The branching versions then -% leave either \meta{true code} or \meta{false code} in the input -% stream, as appropriate to the truth of the test and the variant of -% the function chosen. The logical truth of the test is left in the -% input stream by the predicate version. +% the special \cs{c_zero_fp} variable). % \end{function} % % \begin{function}[TF]{\fp_compare:nNn} @@ -363,9 +355,7 @@ % Less than & |<| \\ % \end{tabular} % \end{center} -% Either \meta{true code} or \meta{false code} is then left in the -% input stream, as appropriate to the truth of the test and the variant -% of the function chosen. The tests treat undefined floating points as +% The tests treat undefined floating points as % zero as the comparison is intended for real numbers only. % \end{function} % @@ -387,9 +377,7 @@ % Not equal & |!=| \\ % \end{tabular} % \end{center} -% Either \meta{true code} or \meta{false code} is then left in the -% input stream, as appropriate to the truth of the test and the variant -% of the function chosen. The tests treat undefined floating points as +% The tests treat undefined floating points as % zero as the comparison is intended for real numbers only. % \end{function} % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3int.dtx b/Master/texmf-dist/source/latex/l3kernel/l3int.dtx index 0719e0e86df..c0b8c5b0179 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3int.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3int.dtx @@ -35,7 +35,7 @@ % %<*driver|package> \RequirePackage{l3names} -\GetIdInfo$Id: l3int.dtx 2600 2011-08-16 22:31:24Z bruno $ +\GetIdInfo$Id: l3int.dtx 2666 2011-08-26 06:10:09Z joseph $ {L3 Experimental integers} %</driver|package> %<*driver> @@ -336,11 +336,6 @@ % Less than & |<| \\ % \end{tabular} % \end{center} -% The branching versions then leave either \meta{true code} or -% \meta{false code} in the input stream, as appropriate to the truth -% of the test and the variant of the function chosen. The logical -% truth of the test is left in the input stream by the predicate -% version. % \end{function} % % \begin{function}[EXP,pTF]{\int_compare:n} @@ -364,11 +359,6 @@ % Not equal & |!=| \\ % \end{tabular} % \end{center} -% The branching versions then leave either \meta{true code} or -% \meta{false code} in the input stream, as appropriate to the truth -% of the test and the variant of the function chosen. The logical -% truth of the test is left in the input stream by the predicate -% version. % \end{function} % % \begin{function}[EXP,pTF]{\int_if_even:n, \int_if_odd:n} @@ -379,11 +369,7 @@ % \end{syntax} % This function first evaluates the \meta{integer expression} % as described for \cs{int_eval:n}. It then evaluates if this -% is odd or even, as appropriate. The branching versions then leave -% either \meta{true code} or \meta{false code} in the input stream, -% as appropriate to the truth of the test and the variant of the -% function chosen. The logical truth of the test is left in the input -% stream by the predicate version. +% is odd or even, as appropriate. % \end{function} % % \section{Integer expression loops} diff --git a/Master/texmf-dist/source/latex/l3kernel/l3io.dtx b/Master/texmf-dist/source/latex/l3kernel/l3io.dtx index 7b6879ba613..f89c10d2562 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3io.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3io.dtx @@ -35,7 +35,7 @@ % %<*driver|package> \RequirePackage{l3names} -\GetIdInfo$Id: l3io.dtx 2595 2011-08-16 00:58:34Z bruno $ +\GetIdInfo$Id: l3io.dtx 2665 2011-08-25 22:15:27Z joseph $ {L3 Experimental input-output operations} %</driver|package> %<*driver> @@ -349,11 +349,7 @@ % Tests if the end of a \meta{stream} has been reached during a reading % operation. The test will also return a \texttt{true} value if % the \meta{stream} is not open or the \meta{file name} associated with -% a \meta{stream} does not exist at all. The branching versions then -% leave either \meta{true code} or \meta{false code} in the input -% stream, as appropriate to the truth of the test and the variant of -% the function chosen. The logical truth of the test is left in the -% input stream by the predicate version. +% a \meta{stream} does not exist at all. %\end{function} % % \section{Internal input--output functions} diff --git a/Master/texmf-dist/source/latex/l3kernel/l3keys.dtx b/Master/texmf-dist/source/latex/l3kernel/l3keys.dtx index df988bea954..0325817636e 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3keys.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3keys.dtx @@ -35,7 +35,7 @@ % %<*driver|package> \RequirePackage{l3names} -\GetIdInfo$Id: l3keys.dtx 2568 2011-08-14 05:03:32Z bruno $ +\GetIdInfo$Id: l3keys.dtx 2677 2011-08-28 06:54:22Z joseph $ {L3 Experimental key-value interfaces} %</driver|package> %<*driver> @@ -189,15 +189,55 @@ % does not exist, it will be created at the point that the key is % set up. The \meta{boolean} will be assigned globally. % \end{function} +% +% \begin{function}{.bool_set_inverse:N} +% \begin{syntax} +% \meta{key} .bool_set_inverse:N = \meta{boolean} +% \end{syntax} +% Defines \meta{key} to set \meta{boolean} to the logical +% inverse of \meta{value} (which must be either \texttt{true} or +% \texttt{false}). +% If the \meta{boolean} does not exist, it will be created at the point +% that the key is set up. The \meta{boolean} will be assigned locally. +% +% \textbf{This property is experimental.} +% \end{function} +% +% \begin{function}{.bool_gset_inverse:N} +% \begin{syntax} +% \meta{key} .bool_gset_inverse:N = \meta{boolean} +% \end{syntax} +% Defines \meta{key} to set \meta{boolean} to the logical +% inverse of \meta{value} (which must be either \texttt{true} or +% \texttt{false}). +% If the \meta{boolean} does not exist, it will be created at the point +% that the key is set up. The \meta{boolean} will be assigned globally. +% +% \textbf{This property is experimental.} +% \end{function} % % \begin{function}{.choice:} % \begin{syntax} % \meta{key} .choice: % \end{syntax} -% Sets \meta{key} to act as a multiple choice key. Each valid choice +% Sets \meta{key} to act as a choice key. Each valid choice % for \meta{key} must then be created, as discussed in % section~\ref{sec:choice}. % \end{function} +% +% \begin{function}{.choices:nn} +% \begin{syntax} +% \meta{key} .choices:nn \meta{choices} \meta{code} +% \end{syntax} +% Sets \meta{key} to act as a choice key, and defines a series \meta{choices} +% which are implemented using the \meta{code}. Inside \meta{code}, +% \cs{l_keys_choice_tl} will be the name of the choice made, and +% \cs{l_keys_choice_int} will be the position of the choice in the list +% of \meta{choices} (indexed from $0$). +% Choices are discussed in detail in section~\ref{sec:choice}. +% +% \textbf{This property is experimental.} +% \end{function} % % \begin{function}{.choice_code:n, .choice_code:x} % \begin{syntax} @@ -325,6 +365,32 @@ % is used, then the value will be passed through to the subsidiary % \meta{keys} for processing (as |#1|). % \end{function} +% +% \begin{function}{.multichoice:} +% \begin{syntax} +% \meta{key} .multichoice: +% \end{syntax} +% Sets \meta{key} to act as a multiple choice key. Each valid choice +% for \meta{key} must then be created, as discussed in +% section~\ref{sec:choice}. +% +% \textbf{This property is experimental.} +% \end{function} +% +% \begin{function}{.multichoice:nn} +% \begin{syntax} +% \meta{key} .multichoice:nn \meta{choices} \meta{code} +% \end{syntax} +% Sets \meta{key} to act as a multiple choice key, and defines a series +% \meta{choices} +% which are implemented using the \meta{code}. Inside \meta{code}, +% \cs{l_keys_choice_tl} will be the name of the choice made, and +% \cs{l_keys_choice_int} will be the position of the choice in the list +% of \meta{choices} (indexed from $0$). +% Choices are discussed in detail in section~\ref{sec:choice}. +% +% \textbf{This property is experimental.} +% \end{function} % % \begin{function}{.skip_set:N, .skip_set:c} % \begin{syntax} @@ -427,10 +493,16 @@ % As will be illustrated in the next section, this subdivision is % particularly relevant to making multiple choices. % -% \section{Multiple choice keys} +% \section{Choice and multiple choice keys} % \label{sec:choice} % -% Multiple choices are created by setting the \texttt{.choice:} +% The \pkg{l3keys} system supports two types of choice key, in which a series +% of pre-defined input values are linked to varying implementations. Choice +% keys are usually created so that the various values are mutually-exclusive: +% only one can apply at any one time. \enquote{Multiple} choice keys are also +% supported: these allow a selection of values to be chosen at the same time. +% +% Mutually-exclusive choices are created by setting the \texttt{.choice:} % property: % \begin{verbatim} % \keys_define:nn { module } @@ -460,13 +532,34 @@ % } % \end{verbatim} % Following common computing practice, \cs{l_keys_choice_int} is -% indexed from $0$ (as an offset), so that the value of +% indexed from $0$ (as an offset), so that the value of % \cs{l_keys_choice_int} for the first choice in a list will be % zero. +% +% The same approach is also implemented by the \emph{experimental} +% property \texttt{.choices:nn}. This combines the functionality of +% \texttt{.choice_code:n} and \texttt{.generate_choices:n} into one +% property: +% \begin{verbatim} +% \keys_define:nn { module } +% { +% key .choices:nn = +% { choice-a, choice-b, choice-c } +% { +% You~gave~choice~'\int_use:N \l_keys_choice_tl',~ +% which~is~in~position~ +% \int_use:N \l_keys_choice_int \c_space_tl +% in~the~list. +% } +% } +% \end{verbatim} +% Note that the \texttt{.choices:nn} property should \emph{not} be mixed with +% use of \texttt{.generate_choices:n}. % % \begin{variable}{\l_keys_choice_int, \l_keys_choice_tl} % Inside the code block for a choice generated using -% \texttt{.generate_choice:}, the variables \cs{l_keys_choice_tl} and +% \texttt{.generate_choice:} or \texttt{.choices:nn}, +% the variables \cs{l_keys_choice_tl} and % \cs{l_keys_choice_int} are available to indicate the name of the % current choice, and its position in the comma list. The position % is indexed from $0$. @@ -479,7 +572,7 @@ % \begin{verbatim} % \keys_define:nn { module } % { -% key .choice:n, +% key .choice:, % key / choice-a .code:n = code-a, % key / choice-b .code:n = code-b, % key / choice-c .code:n = code-c, @@ -491,6 +584,48 @@ % These variables do not have defined behaviour when used outside of % code created using \texttt{.generate_choices:n} % (\emph{i.e.}~anything might happen). +% +% Multiple choices are created in a very similar manner to mutually-exclusive +% choices, using the properties \texttt{.multichoice:} and +% \texttt{.multichoices:nn}. As with mutually exclusive choices, multiple +% choices are define as sub-keys. Thus both +% \begin{verbatim} +% \keys_define:nn { module } +% { +% key .multichoices:nn = +% { choice-a, choice-b, choice-c } +% { +% You~gave~choice~'\int_use:N \l_keys_choice_tl',~ +% which~is~in~position~ +% \int_use:N \l_keys_choice_int \c_space_tl +% in~the~list. +% } +% } +% \end{verbatim} +% and +% \begin{verbatim} +% \keys_define:nn { module } +% { +% key .multichoice:, +% key / choice-a .code:n = code-a, +% key / choice-b .code:n = code-b, +% key / choice-c .code:n = code-c, +% } +%\end{verbatim} +% are valid. The \texttt{.multichoices:nn} property causes +% \cs{l_keys_choice_tl} and \cs{l_keys_choice_int} to be set in exactly +% the same way as described for \texttt{.choices:nn}. +% +% When multiple choice keys are set, the value is treated as a comma-separated +% list: +% \begin{verbatim} +% \keys_set:nn { module } +% { +% key = { a , b , c } % 'key' defined as a multiple choice +% } +%\end{verbatim} +% Each choice will be applied in turn, with the usual handling of unknown +% values. % % \section{Setting keys} % @@ -501,9 +636,7 @@ % Parses the \meta{keyval list}, and sets those keys which are defined % for \meta{module}. The behaviour on finding an unknown key can be set % by defining a special \texttt{unknown} key: this will be illustrated -% later. In contrast to \cs{keys_define:nn}, this function does check -% category codes and ignore spaces, and is therefore suitable for user -% input. +% later. % \end{function} % % If a key is not known, \cs{keys_set:nn} will look for a special @@ -520,8 +653,7 @@ % \begin{variable}{\l_keys_key_tl} % When processing an unknown key, the name of the key is available % as \cs{l_keys_key_tl}. Note that this will have been processed -% using \cs{tl_to_str:n}. The value passed to the key (if any) is -% available as the macro parameter |#1|. +% using \cs{tl_to_str:n}. % \end{variable} % % \begin{variable}{\l_keys_path_tl} @@ -529,22 +661,55 @@ % as \cs{l_keys_path_tl}. Note that this will have been processed % using \cs{tl_to_str:n}. % \end{variable} +% +% \begin{variable}{\l_keys_value_tl} +% When processing an unknown key, the value of the key is available as +% \cs{l_keys_value_tl}. Note that this will be empty if no value was given +% for the key. +% \end{variable} +% +% \section{Setting known keys only} +% +% The functionality described in this section is experimental and may be +% altered or removed, depending on feedback. +% +% \begin{function} +% { +% \keys_set_known:nnN, \keys_set_known:nVN, +% \keys_set_known:nvN, \keys_set_known:noN +% } +% \begin{syntax} +% \cs{keys_set_known:nn} \Arg{module} \Arg{keyval list} \meta{clist} +% \end{syntax} +% Parses the \meta{keyval list}, and sets those keys which are defined +% for \meta{module}. Any keys which are unknown are not processed further +% by the parser. +% The key--value pairs for each \emph{unknown} key name will be +% stored in the \meta{clist}. +% \end{function} % % \section{Utility functions for keys} % % \begin{function}[EXP,pTF]{\keys_if_exist:nn} % \begin{syntax} -% \cs{keys_if_exist:nn} \meta{module} \meta{key} -% \cs{keys_if_exist:nn} \meta{module} \meta{key} +% \cs{keys_if_exist_p:nn} \meta{module} \meta{key} +% \cs{keys_if_exist:nnTF} \meta{module} \meta{key} % ~~\Arg{true code} \Arg{false code} % \end{syntax} % Tests if the \meta{key} exists for \meta{module}, \emph{i.e.}~if any code % has been defined for \meta{key}. -% The branching versions then leave either \meta{true code} or -% \meta{false code} in the input stream, as appropriate to the truth -% of the test and the variant of the function chosen. The logical -% truth of the test is left in the input stream by the predicate -% version. +% \end{function} +% +% \begin{function}[EXP,pTF]{\keys_if_choice_exist:nn} +% \begin{syntax} +% \cs{keys_if_exist_p:nnn} \meta{module} \meta{key} \meta{choice} +% \cs{keys_if_exist:nnnTF} \meta{module} \meta{key} \meta{choice} +% ~~\Arg{true code} \Arg{false code} +% \end{syntax} +% Tests if the \meta{choice} is defined for the \meta{key} within the +% \meta{module},, \emph{i.e.}~if any code has been defined for +% \meta{key}/\meta{choice}. The test is \texttt{false} if the \meta{key} +% itself is not defined. % \end{function} % % \begin{function}{\keys_show:nn} @@ -555,6 +720,78 @@ % \meta{key} for a \meta{module}. % \end{function} % +% \section{Low-level interface for parsing key--val lists} +% +% To re-cap from earlier, a key--value list is input of the form +% \begin{verbatim} +% KeyOne = ValueOne , +% KeyTwo = ValueTwo , +% KeyThree +% \end{verbatim} +% where each key--value pair is separated by a comma from the rest of +% the list, and each key--value pair does not necessarily contain an +% equals sign or a value! Processing this type of input correctly +% requires a number of careful steps, to correctly account for +% braces, spaces and the category codes of separators. +% +% While the functions described earlier are used as a high-level interface +% for processing such input, in especial circumstances you may wish to use +% a lower-level approach. +% The low-level parsing system converts a \meta{key--value list} +% into \meta{keys} and associated \meta{values}. After the parsing phase +% is completed, the resulting keys and values (or keys alone) are +% available for further processing. This processing is not carried out by the +% low-level parser itself, and so the parser requires the names of +% two functions along with the key--value list. One function is +% needed to process key--value pairs (\emph{i.e}~two arguments), +% and a second function if required for keys given without arguments +% (\emph{i.e.}~a single argument). +% +% The parser does not double |#| tokens or expand any input. The tokens +% |=| and |,| are corrected so that the parser does not \enquote{miss} +% any due to category code changes. Spaces are removed from the ends +% of the keys and values. Values which are given in braces will have +% exactly one set removed, thus +% \begin{verbatim} +% key = {value here}, +% \end{verbatim} +% and +% \begin{verbatim} +% key = value here, +% \end{verbatim} +% are treated identically. +% +% \begin{function}{\keyval_parse:NNn} +% \begin{syntax} +% \cs{keyval_parse:NNn} \meta{function1} \meta{function2} +% ~~\Arg{key--value list} +% \end{syntax} +% Parses the \meta{key--value list} into a series of \meta{keys} and +% associated \meta{values}, or keys alone (if no \meta{value} was +% given). \meta{function1} should take one argument, while +% \meta{function2} should absorb two arguments. After +% \cs{keyval_parse:NNn} has parsed the \meta{key--value list}, +% \meta{function1} will be used to process keys given with no value +% and \meta{function2} will be used to process keys given with a +% value. The order of the \meta{keys} in the \meta{key--value list} +% will be preserved. Thus +% \begin{verbatim} +% \keyval_parse:NNn \function:n \function:nn +% { key1 = value1 , key2 = value2, key3 = , key4 } +% \end{verbatim} +% will be converted into an input stream +% \begin{verbatim} +% \function:nn { key1 } { value1 } +% \function:nn { key2 } { value2 } +% \function:nn { key3 } { } +% \function:n { key4 } +% \end{verbatim} +% Note that there is a difference between an empty value (an equals +% sign followed by nothing) and a missing value (no equals sign at +% all). +% \end{function} +% +% % \end{documentation} % % \begin{implementation} @@ -573,6 +810,239 @@ %</package> % \end{macrocode} % +% \subsection{Low-level interface} +% +% For historical reasons this code uses the `keyval' module prefix. +% +% \begin{variable}{\g_keyval_level_int} +% For nesting purposes an integer is needed for the current level. +% \begin{macrocode} +\int_new:N \g_keyval_level_int +% \end{macrocode} +% \end{variable} +% +% \begin{variable}{\l_keyval_key_tl, \l_keyval_value_tl} +% The current key name and value. +% \begin{macrocode} +\tl_new:N \l_keyval_key_tl +\tl_new:N \l_keyval_value_tl +% \end{macrocode} +% \end{variable} +% +% \begin{variable}{\l_keyval_sanitise_tl} +% \begin{variable}{\l_keyval_parse_tl} +% Token list variables for dealing with awkward category codes in the +% input. +% \begin{macrocode} +\tl_new:N \l_keyval_sanitise_tl +\tl_new:N \l_keyval_parse_tl +% \end{macrocode} +%\end{variable} +%\end{variable} +% +% \begin{macro}{\keyval_parse:n} +% The parsing function first deals with the category codes for +% |=| and |,|, so that there are no odd events. The input is then +% handed off to the element by element system. +% \begin{macrocode} +\group_begin: + \char_set_catcode_active:n { `\= } + \char_set_catcode_active:n { `\, } + \char_set_lccode:nn { `\8 } { `\= } + \char_set_lccode:nn { `\9 } { `\, } +\tl_to_lowercase:n + { + \group_end: + \cs_new_protected:Npn \keyval_parse:n #1 + { + \group_begin: + \tl_clear:N \l_keyval_sanitise_tl + \tl_set:Nn \l_keyval_sanitise_tl {#1} + \tl_replace_all:Nnn \l_keyval_sanitise_tl { = } { 8 } + \tl_replace_all:Nnn \l_keyval_sanitise_tl { , } { 9 } + \tl_clear:N \l_keyval_parse_tl + \exp_after:wN \keyval_parse_elt:w \exp_after:wN + \q_no_value \l_keyval_sanitise_tl 9 \q_nil 9 + \exp_after:wN \group_end: + \l_keyval_parse_tl + } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\keyval_parse_elt:w} +% Each item to be parsed will have \cs{q_no_value} added to the front. +% Hence the blank test here can always be used to find a totally +% empty argument. If this is the case, the system loops round. If there +% is something to parse, there is a check for the \cs{q_nil} marker +% and if not a hand-off. +% \begin{macrocode} +\cs_new_protected:Npn \keyval_parse_elt:w #1 , + { + \tl_if_blank:oTF { \use_none:n #1 } + { \keyval_parse_elt:w \q_no_value } + { + \quark_if_nil:oF { \use_ii:nn #1 } + { + \keyval_split_key_value:w #1 = = \q_stop + \keyval_parse_elt:w \q_no_value + } + } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\keyval_split_key_value:w} +% \begin{macro}[aux]{\keyval_split_key_value_aux:wTF} +% The key and value are handled separately. First the key is grabbed and +% saved as \cs{l_keyval_key_tl}. Then a check is need to see if there is +% a value at all: if not then the key name is simply added to the output. +% If there is a value then there is a check to ensure that there was +% only one |=| in the input (remembering some extra ones are around at +% the moment to prevent errors). All being well, there is an +% hand-off to find the value: the \cs{q_nil} is there to prevent loss +% of braces. +% \begin{macrocode} +\cs_new_protected:Npn \keyval_split_key_value:w #1 = #2 \q_stop + { + \keyval_split_key:w #1 \q_stop + \str_if_eq:nnTF {#2} { = } + { + \tl_put_right:Nx \l_keyval_parse_tl + { + \exp_not:c + { keyval_key_no_value_elt_ \int_use:N \g_keyval_level_int :n } + { \exp_not:o \l_keyval_key_tl } + } + } + { + \keyval_split_key_value_aux:wTF #2 \q_no_value \q_stop + { \keyval_split_value:w \q_nil #2 } + { \msg_kernel_error:nn { keyval } { misplaced-equals-sign } } + } + } +\cs_new:Npn \keyval_split_key_value_aux:wTF #1 = #2#3 \q_stop + { \tl_if_head_eq_meaning:nNTF {#3} \q_no_value } +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\keyval_split_key:w} +% \begin{macro}{\keyval_remove_spaces:w} +% \begin{macro}[aux]{\keyval_split_key_aux:w} +% \begin{macro}[aux]{\keyval_remove_spaces_aux:w} +% The aim here is to remove spaces and also exactly one set of braces. +% The spaces are trimmed off from each end using a \enquote{funny} +% |Q|, which will never turn up in normal use. The idea is that +% the \texttt{f}-type expansion will stop if it finds an unexpandable +% token or a space, and will gobble the space. To avoid expanding +% anything else, the \cs{exp_not:N} works by ensuring that the first +% non-space token in the setting will stop the \texttt{f}-type +% expansion. The \cs{use_none:n} is needed to remove the leading +% quark, while the second setting of \cs{l_keyval_key_tl} +% removes exactly one set of braces. +% \begin{macrocode} +\group_begin: + \char_set_catcode_math_toggle:n { `\Q } + \cs_new_protected:Npn \keyval_split_key:w #1 \q_stop + { + \exp_args:NNf \tl_set:Nn \l_keyval_key_tl + { + \exp_after:wN \keyval_remove_spaces:w \exp_after:wN + \exp_not:N \use_none:n #1 Q ~ Q + } + \tl_set:Nx \l_keyval_key_tl + { \exp_after:wN \keyval_split_key_aux:w \l_keyval_key_tl \q_stop } + } + \cs_gset:Npn \keyval_split_key_aux:w #1 \q_stop { \exp_not:n {#1} } + \cs_gset:Npn \keyval_remove_spaces:w #1 ~ Q + { \keyval_remove_spaces_aux:w #1 Q } + \cs_gset:Npn \keyval_remove_spaces_aux:w #1 Q #2 {#1} +\group_end: +% \end{macrocode} +% Fixme: use \cs{tl_trim_spaces} instead of the aux function above? +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\keyval_split_value:w} +% Here the value has to be separated from the equals signs and the +% leading \cs{q_nil} added in to keep the brace levels. Fist the +% processing function can be added to the output list. If there is no +% value, setting \cs{l_keyval_value_tl} with three groups removed will +% leave nothing at all, and so an empty group can be added to the +% parsed list. On the other hand, if the value is entirely contained +% within a set of braces then \cs{l_keyval_value_tl} will contain +% \cs{q_nil} only. In that case, strip off the leading quark using +% \cs{use_ii:nnn}, which also deals with any spaces. +% \begin{macrocode} +\cs_new_protected:Npn \keyval_split_value:w #1 = = + { + \tl_put_right:Nx \l_keyval_parse_tl + { + \exp_not:c + { keyval_key_value_elt_ \int_use:N \g_keyval_level_int :nn } + { \exp_not:o \l_keyval_key_tl } + } + \tl_set:Nx \l_keyval_value_tl + { \exp_not:o { \use_none:nnn #1 \q_nil \q_nil } } + \tl_if_empty:NTF \l_keyval_value_tl + { \tl_put_right:Nn \l_keyval_parse_tl { { } } } + { + \quark_if_nil:NTF \l_keyval_value_tl + { + \tl_put_right:Nx \l_keyval_parse_tl + { { \exp_not:o { \use_ii:nnn #1 \q_nil } } } + } + { \keyval_split_value_aux:w #1 \q_stop } + } + } +% \end{macrocode} +% A similar idea to the key code: remove the spaces from each end and +% deal with one set of braces. +% \begin{macrocode} +\group_begin: + \char_set_catcode_math_toggle:n { `\Q } + \cs_new_protected:Npn \keyval_split_value_aux:w \q_nil #1 \q_stop + { + \exp_args:NNf \tl_set:Nn \l_keyval_value_tl + { \keyval_remove_spaces:w \exp_not:N #1 Q ~ Q } + \tl_put_right:Nx \l_keyval_parse_tl + { { \exp_not:o \l_keyval_value_tl } } + } +\group_end: +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\keyval_parse:NNn} +% The outer parsing routine just sets up the processing functions and +% hands off. +% \begin{macrocode} +\cs_new_protected:Npn \keyval_parse:NNn #1#2#3 + { + \int_gincr:N \g_keyval_level_int + \cs_gset_eq:cN + { keyval_key_no_value_elt_ \int_use:N \g_keyval_level_int :n } #1 + \cs_gset_eq:cN + { keyval_key_value_elt_ \int_use:N \g_keyval_level_int :nn } #2 + \keyval_parse:n {#3} + \int_gdecr:N \g_keyval_level_int + } +% \end{macrocode} +% \end{macro} +% +% One message for the low level parsing system. +% \begin{macrocode} +\msg_kernel_new:nnnn { keyval } { misplaced-equals-sign } + { Misplaced~equals~sign~in~key-value~input~\msg_line_number: } + { + LaTeX~is~attempting~to~parse~some~key-value~input~but~found~ + two~equals~signs~not~separated~by~a~comma. + } +% \end{macrocode} +% +% % \subsection{Constants and variables} % % \begin{variable}{\c_keys_code_root_tl, \c_keys_vars_root_tl} @@ -644,6 +1114,13 @@ \tl_new:N \l_keys_property_tl % \end{macrocode} % \end{variable} +% +% \begin{variable}{\l_keys_unknown_clist} +% Used when setting only known keys to store those left over. +% \begin{macrocode} +\tl_new:N \l_keys_unknown_clist +% \end{macrocode} +% \end{variable} % % \begin{variable}{\l_keys_value_tl} % The value given for a key: may be empty if no value was given. @@ -785,6 +1262,27 @@ } % \end{macrocode} % \end{macro} +% +% \begin{macro}[int]{\keys_bool_set_inverse:NN} +% Inverse boolean setting is much the same. +% \begin{macrocode} +\cs_new_nopar:Npn \keys_bool_set_inverse:NN #1#2 + { + \cs_if_exist:NF #1 { \bool_new:N #1 } + \keys_choice_make: + \keys_cmd_set:nx { \l_keys_path_tl / true } + { \exp_not:c { bool_ #2 set_false:N } \exp_not:N #1 } + \keys_cmd_set:nx { \l_keys_path_tl / false } + { \exp_not:c { bool_ #2 set_true:N } \exp_not:N #1 } + \keys_cmd_set:nn { \l_keys_path_tl / unknown } + { + \msg_kernel_error:nnx { keys } { boolean-values-only } + { \l_keys_key_tl } + } + \keys_default_set:n { true } + } +% \end{macrocode} +% \end{macro} % % \begin{macro}[int]{\keys_choice_make:} % To make a choice from a key, two steps: set the code, and set the @@ -802,6 +1300,29 @@ } % \end{macrocode} % \end{macro} +% +% \begin{macro}[int]{\keys_choices_make:nn} +% Auto-generating choices means setting up the root key as a choice, then +% defining each choice in turn. +% \begin{macrocode} +\cs_new_protected:Npn \keys_choices_make:nn #1#2 + { + \keys_choice_make: + \int_zero:N \l_keys_choice_int + \clist_map_inline:nn {#1} + { + \keys_cmd_set:nx { \l_keys_path_tl / ##1 } + { + \tl_set:Nn \exp_not:N \l_keys_choice_tl {##1} + \int_set:Nn \exp_not:N \l_keys_choice_int + { \int_use:N \l_keys_choice_int } + \exp_not:n {#2} + } + \int_incr:N \l_keys_choice_int + } + } +% \end{macrocode} +% \end{macro} % % \begin{macro}[int]{\keys_choices_generate:n} % \begin{macro}[aux]{\keys_choices_generate_aux:n} @@ -826,8 +1347,8 @@ { \keys_cmd_set:nx { \l_keys_path_tl / #1 } { - \exp_not:n { \tl_set:Nn \l_keys_choice_tl } {#1} - \exp_not:n { \int_set:Nn \l_keys_choice_int } + \tl_set:Nn \exp_not:N \l_keys_choice_tl {#1} + \int_set:Nn \exp_not:N \l_keys_choice_int { \int_use:N \l_keys_choice_int } \exp_not:v { \c_keys_vars_root_tl \l_keys_path_tl .choice~code } @@ -895,7 +1416,7 @@ \cs_new_protected_nopar:Npn \keys_meta_make:n #1 { \exp_args:NNo \keys_cmd_set:nn \l_keys_path_tl - { \exp_after:wN \keys_set:nn \exp_after:wN { \l_keys_module_tl } {#1} } + { \exp_after:wN \keys_set:nn \exp_after:wN { \l_keys_module_tl } {#1} } } \cs_new_protected_nopar:Npn \keys_meta_make:x #1 { @@ -904,6 +1425,47 @@ } % \end{macrocode} % \end{macro} +% +% \begin{macro}[int]{\keys_multichoice_find:n} +% \begin{macro}[int]{\keys_multichoice_make:} +% \begin{macro}[int]{\keys_multichoices_make:nn} +% Choices where several values can be selected are very similar to normal +% exclusive choices. There is just a slight change in implementation to +% map across a comma-separated list. This then requires that the appropriate +% set up takes place elsewhere. +% \begin{macrocode} +\cs_new_nopar:Npn \keys_multichoice_find:n #1 + { \clist_map_function:nN {#1} \keys_choice_find:n } +\cs_new_protected_nopar:Npn \keys_multichoice_make: + { + \keys_cmd_set:nn { \l_keys_path_tl } + { \keys_multichoice_find:n {##1} } + \keys_cmd_set:nn { \l_keys_path_tl / unknown } + { + \msg_kernel_error:nnxx { keys } { choice-unknown } + { \l_keys_path_tl } {##1} + } + } +\cs_new_protected:Npn \keys_multichoices_make:nn #1#2 + { + \keys_multichoice_make: + \int_zero:N \l_keys_choice_int + \clist_map_inline:nn {#1} + { + \keys_cmd_set:nx { \l_keys_path_tl / ##1 } + { + \tl_set:Nn \exp_not:N \l_keys_choice_tl {##1} + \int_set:Nn \exp_not:N \l_keys_choice_int + { \int_use:N \l_keys_choice_int } + \exp_not:n {#2} + } + \int_incr:N \l_keys_choice_int + } + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} % % \begin{macro}[int]{\keys_value_requirement:n} % Values can be required or forbidden by having the appropriate marker @@ -955,15 +1517,37 @@ % \end{macrocode} % \end{macro} % \end{macro} +% +% \begin{macro}{.bool_set_inverse:N} +% \begin{macro}{.bool_gset_inverse:N} +% One function for this. +% \begin{macrocode} +\cs_new_protected_nopar:cpn { \c_keys_props_root_tl .bool_set_inverse:N } #1 + { \keys_bool_set_inverse:NN #1 { } } +\cs_new_protected_nopar:cpn { \c_keys_props_root_tl .bool_gset_inverse:N } #1 + { \keys_bool_set_inverse:NN #1 g } +% \end{macrocode} +% \end{macro} +% \end{macro} % % \begin{macro}{.choice:} % Making a choice is handled internally, as it is also needed by -% \texttt{.generate_choices:n}. +% \texttt{.generate_choices:n}. % \begin{macrocode} \cs_new_protected_nopar:cpn { \c_keys_props_root_tl .choice: } { \keys_choice_make: } % \end{macrocode} % \end{macro} +% +% \begin{macro}{.choices:nn} +% For auto-generation of a series of mutually-exclusive choices. +% Here, |#1| will consist of two separate +% arguments, hence the slightly odd-looking implementation. +% \begin{macrocode} +\cs_new_protected:cpn { \c_keys_props_root_tl .choices:nn } #1 + { \keys_choices_make:nn #1 } +% \end{macrocode} +% \end{macro} % % \begin{macro}{.code:n, .code:x} % Creating code is simply a case of passing through to the underlying @@ -1062,6 +1646,19 @@ { \keys_meta_make:x {#1} } % \end{macrocode} % \end{macro} +% +% \begin{macro}{.multichoice:} +% \begin{macro}{.multichoices:nn} +% The same idea as \texttt{.choice:} and \texttt{.choices:nn}, but +% where more than one choice is allowed. +% \begin{macrocode} +\cs_new_protected_nopar:cpn { \c_keys_props_root_tl .multichoice: } + { \keys_multichoice_make: } +\cs_new_protected:cpn { \c_keys_props_root_tl .multichoices:nn } #1 + { \keys_multichoices_make:nn #1 } +% \end{macrocode} +% \end{macro} +% \end{macro} % % \begin{macro}{.skip_set:N, .skip_set:c} % \begin{macro}{.skip_gset:N, .skip_gset:c} @@ -1139,6 +1736,31 @@ % \end{macrocode} % \end{macro} % \end{macro} +% +% \begin{macro} +% { +% \keys_set_known:nnN, \keys_set_known:nVN, +% \keys_set_known:nvN, \keys_set_known:noN +% } +% \begin{macro}[aux]{\keys_set_known_aux:nnnN, \keys_set_known_aux:onnN} +% \begin{macrocode} +\cs_new_protected:Npn \keys_set_known:nnN + { \keys_set_known_aux:onnN { \l_keys_module_tl } } +\cs_new_protected:Npn \keys_set_known_aux:nnnN #1#2#3#4 + { + \tl_set:Nn \l_keys_module_tl {#2} + \clist_clear:N \l_keys_unknown_clist + \cs_set_eq:NN \keys_execute_unknown: \keys_execute_unknown_alt: + \keyval_parse:NNn \keys_set_elt:n \keys_set_elt:nn {#3} + \cs_set_eq:NN \keys_execute_unknown: \keys_execute_unknown_std: + \tl_set:Nn \l_keys_module_tl {#1} + \clist_set_eq:NN #4 \l_keys_unknown_clist + } +\cs_generate_variant:Nn \keys_set_known:nnN { nV , nv , no } +\cs_generate_variant:Nn \keys_set_known_aux:nnnN { o } +% \end{macrocode} +% \end{macro} +% \end{macro} % % \begin{macro}[int]{\keys_set_elt:n, \keys_set_elt:nn} % \begin{macro}[aux]{\keys_set_elt_aux:nn} @@ -1199,8 +1821,11 @@ { \quark_if_no_value:cF { \c_keys_vars_root_tl \l_keys_path_tl .default } { - \tl_set_eq:Nc \l_keys_value_tl - { \c_keys_vars_root_tl \l_keys_path_tl .default } + \cs_if_exist:cT { \c_keys_vars_root_tl \l_keys_path_tl .default } + { + \tl_set_eq:Nc \l_keys_value_tl + { \c_keys_vars_root_tl \l_keys_path_tl .default } + } } } } @@ -1222,7 +1847,12 @@ % \end{macro} % % \begin{macro}[int]{\keys_execute:} -% \begin{macro}[aux]{\keys_execute_unknown:} +% \begin{macro}[aux] +% { +% \keys_execute_unknown:, +% \keys_execute_unknown_std:, +% \keys_execute_unknown_alt: +% } % \begin{macro}[aux]{\keys_execute:nn} % Actually executing a key is done in two parts. First, look for the % key itself, then look for the \texttt{unknown} key with the same @@ -1238,6 +1868,16 @@ { \l_keys_path_tl } { \l_keys_module_tl } } } +\cs_new_eq:NN \keys_execute_unknown_std: \keys_execute_unknown: +\cs_new_nopar:Npn \keys_execute_unknown_alt: + { + \clist_put_right:Nx \l_keys_unknown_clist + { + \exp_not:o \l_keys_key_tl + \bool_if:NF \l_keys_no_value_bool + { = { \exp_not:o \l_keys_value_tl } } + } + } \cs_new_nopar:Npn \keys_execute:nn #1#2 { \cs_if_exist:cTF { \c_keys_code_root_tl #1 } @@ -1252,7 +1892,7 @@ % \end{macro} % \end{macro} % -% \begin{macro}{\keys_choice_find:n} +% \begin{macro}[int]{\keys_choice_find:n} % Executing a choice has two parts. First, try the choice given, then % if that fails call the unknown key. That will exist, as it is created % when a choice is first made. So there is no need for any escape code. @@ -1267,14 +1907,26 @@ % % \subsection{Utilities} % -% \begin{macro}[pTF]{\keys_if_exist:nn} +% \begin{macro}[EXP,pTF]{\keys_if_exist:nn} % A utility for others to see if a key exists. % \begin{macrocode} \prg_new_conditional:Npnn \keys_if_exist:nn #1#2 { p , T , F , TF } { \cs_if_exist:cTF { \c_keys_code_root_tl #1 / #2 } - { \prg_return_true:} - { \prg_return_false:} + { \prg_return_true: } + { \prg_return_false: } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[EXP,pTF]{\keys_if_choice_exist:nnn} +% Just an alternative view on \cs{keys_if_exist:nn(TF)}. +% \begin{macrocode} +\prg_new_conditional:Npnn \keys_if_choice_exist:nnn #1#2#3 { p , T , F , TF } + { + \cs_if_exist:cTF { \c_keys_code_root_tl #1 / #2 / #3 } + { \prg_return_true: } + { \prg_return_false: } } % \end{macrocode} % \end{macro} @@ -1356,6 +2008,23 @@ } % \end{macrocode} % +% \subsection{Deprecated functions} +% +% Deprecated on 2011-05-27, for removal by 2011-08-31. +% +% \begin{macro}{\KV_process_space_removal_sanitize:NNn} +% \begin{macro}{\KV_process_space_removal_no_sanitize:NNn} +% \begin{macro}{\KV_process_no_space_removal_no_sanitize:NNn} +% There is just one function for this now. +% \begin{macrocode} +\cs_new_eq:NN \KV_process_space_removal_sanitize:NNn \keyval_parse:NNn +\cs_new_eq:NN \KV_process_space_removal_no_sanitize:NNn \keyval_parse:NNn +\cs_new_eq:NN \KV_process_no_space_removal_no_sanitize:NNn \keyval_parse:NNn +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% % \begin{macrocode} %</initex|package> % \end{macrocode} diff --git a/Master/texmf-dist/source/latex/l3kernel/l3keyval.dtx b/Master/texmf-dist/source/latex/l3kernel/l3keyval.dtx deleted file mode 100644 index 01adb3a033a..00000000000 --- a/Master/texmf-dist/source/latex/l3kernel/l3keyval.dtx +++ /dev/null @@ -1,405 +0,0 @@ -% \iffalse meta-comment -% -%% File: l3keyval.dtx Copyright (C) 2006-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 "expl3 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 LaTeX3 Project. -%% -%% ----------------------------------------------------------------------- -% -%<*driver|package> -\RequirePackage{l3names} -\GetIdInfo$Id: l3keyval.dtx 2601 2011-08-16 23:20:27Z bruno $ - {L3 Experimental key-value parsing} -%</driver|package> -%<*driver> -\documentclass[full]{l3doc} -\begin{document} - \DocInput{\jobname.dtx} -\end{document} -%</driver> -% \fi -% -% \title{^^A -% The \pkg{l3keyval} package\\ Key--value parsing^^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} -% -% A key--value list is input of the form -% \begin{verbatim} -% KeyOne = ValueOne , -% KeyTwo = ValueTwo , -% KeyThree -% \end{verbatim} -% where each key--value pair is separated by a comma from the rest of -% the list, and each key--value pair does not necessarily contain an -% equals sign or a value! Processing this type of input correctly -% requires a number of careful steps, to correctly account for -% braces, spaces and the category codes of separators. -% -% This module provides the low-level machinery for processing arbitrary -% key--value lists. The \pkg{l3keys} module provides a higher-level -% interface for managing run-time settings using key--value input, -% while other parts of \LaTeX3 also use key--value input based on -% \pkg{l3keyval} (for example the \pkg{xtemplate} module). -% - %\section{Parsing key--value lists} -% -% The low-level parsing system converts a \meta{key--value list} -% into \meta{keys} and associated \meta{values}. After the parsing phase -% is completed, the resulting keys and values (or keys alone) are -% available for further processing. This is not carried out by the -% low-level parser, and so the parser requires the names of -% two functions along with the key--value list. One function is -% needed to process key--value pairs (\emph{i.e}~two arguments), -% and a second function if required for keys given without arguments -% (\emph{i.e.}~a single argument). -% -% The parser does not double |#| tokens or expand any input. The tokens -% |=| and |,| are corrected so that the parser does not \enquote{miss} -% any due to category code changes. Spaces are removed from the ends -% of the keys and values. Values which are given in braces will have -% exactly one set removed, thus -% \begin{verbatim} -% key = {value here}, -% \end{verbatim} -% and -% \begin{verbatim} -% key = value here, -% \end{verbatim} -% are treated identically. -% - %\begin{function}{\keyval_parse:NNn} -% \begin{syntax} -% \cs{keyval_parse:NNn} \meta{function1} \meta{function2} -% ~~\Arg{key--value list} -% \end{syntax} -% Parses the \meta{key--value list} into a series of \meta{keys} and -% associated \meta{values}, or keys alone (if no \meta{value} was -% given). \meta{function1} should take one argument, while -% \meta{function2} should absorb two arguments. After -% \cs{keyval_parse:NNn} has parsed the \meta{key--value list}, -% \meta{function1} will be used to process keys given with no value -% and \meta{function2} will be used to process keys given with a -% value. The order of the \meta{keys} in the \meta{key--value list} -% will be preserved. Thus -% \begin{verbatim} -% \keyval_parse:NNn \function:n \function:nn -% { key1 = value1 , key2 = value2, key3 = , key4 } -% \end{verbatim} -% will be converted into an input stream -% \begin{verbatim} -% \function:nn { key1 } { value1 } -% \function:nn { key2 } { value2 } -% \function:nn { key3 } { } -% \function:n { key4 } -% \end{verbatim} -% Note that there is a difference between an empty value (an equals -% sign followed by nothing) and a missing value (no equals sign at -% all). -% \end{function} -% -% \end{documentation} -% -% \begin{implementation} -% -% \section{\pkg{l3keyval} implementation} -% -% \begin{macrocode} -%<*initex|package> -% \end{macrocode} -% -% \begin{macrocode} -%<*package> -\ProvidesExplPackage - {\ExplFileName}{\ExplFileDate}{\ExplFileVersion}{\ExplFileDescription} -\package_check_loaded_expl: -%</package> -% \end{macrocode} -% -% \begin{variable}{\g_keyval_level_int} -% For nesting purposes an integer is needed for the current level. -% \begin{macrocode} -\int_new:N \g_keyval_level_int -% \end{macrocode} -% \end{variable} -% -% \begin{variable}{\l_keyval_key_tl, \l_keyval_value_tl} -% The current key name and value. -% \begin{macrocode} -\tl_new:N \l_keyval_key_tl -\tl_new:N \l_keyval_value_tl -% \end{macrocode} -% \end{variable} -% -% \begin{variable}{\l_keyval_sanitise_tl} -% \begin{variable}{\l_keyval_parse_tl} -% Token list variables for dealing with awkward category codes in the -% input. -% \begin{macrocode} -\tl_new:N \l_keyval_sanitise_tl -\tl_new:N \l_keyval_parse_tl -% \end{macrocode} -%\end{variable} -%\end{variable} -% -% \begin{macro}{\keyval_parse:n} -% The parsing function first deals with the category codes for -% |=| and |,|, so that there are no odd events. The input is then -% handed off to the element by element system. -% \begin{macrocode} -\group_begin: - \char_set_catcode_active:n { `\= } - \char_set_catcode_active:n { `\, } - \char_set_lccode:nn { `\8 } { `\= } - \char_set_lccode:nn { `\9 } { `\, } -\tl_to_lowercase:n - { - \group_end: - \cs_new_protected:Npn \keyval_parse:n #1 - { - \group_begin: - \tl_clear:N \l_keyval_sanitise_tl - \tl_set:Nn \l_keyval_sanitise_tl {#1} - \tl_replace_all:Nnn \l_keyval_sanitise_tl { = } { 8 } - \tl_replace_all:Nnn \l_keyval_sanitise_tl { , } { 9 } - \tl_clear:N \l_keyval_parse_tl - \exp_after:wN \keyval_parse_elt:w \exp_after:wN - \q_no_value \l_keyval_sanitise_tl 9 \q_nil 9 - \exp_after:wN \group_end: - \l_keyval_parse_tl - } - } -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\keyval_parse_elt:w} -% Each item to be parsed will have \cs{q_no_value} added to the front. -% Hence the blank test here can always be used to find a totally -% empty argument. If this is the case, the system loops round. If there -% is something to parse, there is a check for the \cs{q_nil} marker -% and if not a hand-off. -% \begin{macrocode} -\cs_new_protected:Npn \keyval_parse_elt:w #1 , - { - \tl_if_blank:oTF { \use_none:n #1 } - { \keyval_parse_elt:w \q_no_value } - { - \quark_if_nil:oF { \use_ii:nn #1 } - { - \keyval_split_key_value:w #1 = = \q_stop - \keyval_parse_elt:w \q_no_value - } - } - } -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\keyval_split_key_value:w} -% \begin{macro}[aux]{\keyval_split_key_value_aux:wTF} -% The key and value are handled separately. First the key is grabbed and -% saved as \cs{l_keyval_key_tl}. Then a check is need to see if there is -% a value at all: if not then the key name is simply added to the output. -% If there is a value then there is a check to ensure that there was -% only one |=| in the input (remembering some extra ones are around at -% the moment to prevent errors). All being well, there is an -% hand-off to find the value: the \cs{q_nil} is there to prevent loss -% of braces. -% \begin{macrocode} -\cs_new_protected:Npn \keyval_split_key_value:w #1 = #2 \q_stop - { - \keyval_split_key:w #1 \q_stop - \str_if_eq:nnTF {#2} { = } - { - \tl_put_right:Nx \l_keyval_parse_tl - { - \exp_not:c { keyval_key_no_value_elt_ \int_use:N \g_keyval_level_int :n } - { \exp_not:o \l_keyval_key_tl } - } - } - { - \keyval_split_key_value_aux:wTF #2 \q_no_value \q_stop - { \keyval_split_value:w \q_nil #2 } - { \msg_kernel_error:nn { keyval } { misplaced-equals-sign } } - } - } -\cs_new:Npn \keyval_split_key_value_aux:wTF #1 = #2#3 \q_stop - { \tl_if_head_eq_meaning:nNTF {#3} \q_no_value } -% \end{macrocode} -% \end{macro} -% \end{macro} -% -% \begin{macro}{\keyval_split_key:w} -% \begin{macro}{\keyval_remove_spaces:w} -% \begin{macro}[aux]{\keyval_split_key_aux:w} -% \begin{macro}[aux]{\keyval_remove_spaces_aux:w} -% The aim here is to remove spaces and also exactly one set of braces. -% The spaces are trimmed off from each end using a \enquote{funny} -% |Q|, which will never turn up in normal use. The idea is that -% the \texttt{f}-type expansion will stop if it finds an unexpandable -% token or a space, and will gobble the space. To avoid expanding -% anything else, the \cs{exp_not:N} works by ensuring that the first -% non-space token in the setting will stop the \texttt{f}-type -% expansion. The \cs{use_none:n} is needed to remove the leading -% quark, while the second setting of \cs{l_keyval_key_tl} -% removes exactly one set of braces. -% \begin{macrocode} -\group_begin: - \char_set_catcode_math_toggle:n { `\Q } - \cs_new_protected:Npn \keyval_split_key:w #1 \q_stop - { - \exp_args:NNf \tl_set:Nn \l_keyval_key_tl - { - \exp_after:wN \keyval_remove_spaces:w \exp_after:wN - \exp_not:N \use_none:n #1 Q ~ Q - } - \tl_set:Nx \l_keyval_key_tl - { \exp_after:wN \keyval_split_key_aux:w \l_keyval_key_tl \q_stop } - } - \cs_gset:Npn \keyval_split_key_aux:w #1 \q_stop { \exp_not:n {#1} } - \cs_gset:Npn \keyval_remove_spaces:w #1 ~ Q { \keyval_remove_spaces_aux:w #1 Q } - \cs_gset:Npn \keyval_remove_spaces_aux:w #1 Q #2 {#1} -\group_end: -% \end{macrocode} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% -% \begin{macro}{\keyval_split_value:w} -% Here the value has to be separated from the equals signs and the -% leading \cs{q_nil} added in to keep the brace levels. Fist the -% processing function can be added to the output list. If there is no -% value, setting \cs{l_keyval_value_tl} with three groups removed will -% leave nothing at all, and so an empty group can be added to the -% parsed list. On the other hand, if the value is entirely contained -% within a set of braces then \cs{l_keyval_value_tl} will contain -% \cs{q_nil} only. In that case, strip off the leading quark using -% \cs{use_ii:nnn}, which also deals with any spaces. -% \begin{macrocode} -\cs_new_protected:Npn \keyval_split_value:w #1 = = - { - \tl_put_right:Nx \l_keyval_parse_tl - { - \exp_not:c { keyval_key_value_elt_ \int_use:N \g_keyval_level_int :nn } - { \exp_not:o \l_keyval_key_tl } - } - \tl_set:Nx \l_keyval_value_tl { \exp_not:o { \use_none:nnn #1 \q_nil \q_nil } } - \tl_if_empty:NTF \l_keyval_value_tl - { \tl_put_right:Nn \l_keyval_parse_tl { { } } } - { - \quark_if_nil:NTF \l_keyval_value_tl - { - \tl_put_right:Nx \l_keyval_parse_tl - { { \exp_not:o { \use_ii:nnn #1 \q_nil } } } - } - { \keyval_split_value_aux:w #1 \q_stop } - } - } -% \end{macrocode} -% A similar idea to the key code: remove the spaces from each end and -% deal with one set of braces. -% \begin{macrocode} -\group_begin: - \char_set_catcode_math_toggle:n { `\Q } - \cs_new_protected:Npn \keyval_split_value_aux:w \q_nil #1 \q_stop - { - \exp_args:NNf \tl_set:Nn \l_keyval_value_tl - { \keyval_remove_spaces:w \exp_not:N #1 Q ~ Q } - \tl_put_right:Nx \l_keyval_parse_tl { { \exp_not:o \l_keyval_value_tl } } - } -\group_end: -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\keyval_parse:NNn} -% The outer parsing routine just sets up the processing functions and -% hands off. -% \begin{macrocode} -\cs_new_protected:Npn \keyval_parse:NNn #1#2#3 - { - \int_gincr:N \g_keyval_level_int - \cs_gset_eq:cN { keyval_key_no_value_elt_ \int_use:N \g_keyval_level_int :n } #1 - \cs_gset_eq:cN { keyval_key_value_elt_ \int_use:N \g_keyval_level_int :nn } #2 - \keyval_parse:n {#3} - \int_gdecr:N \g_keyval_level_int - } -% \end{macrocode} -% \end{macro} -% -% One message for the low level parsing system. -% \begin{macrocode} -\msg_kernel_new:nnnn { keyval } { misplaced-equals-sign } - { Misplaced~equals~sign~in~key-value~input~\msg_line_number: } - { - LaTeX~is~attempting~to~parse~some~key-value~input~but~found~ - two~equals~signs~not~separated~by~a~comma. - } -% \end{macrocode} -% -% \subsection{Deprecated functions} -% -% Deprecated on 2011-05-27, for removal by 2011-08-31. -% -% \begin{macro}{\KV_process_space_removal_sanitize:NNn} -% \begin{macro}{\KV_process_space_removal_no_sanitize:NNn} -% \begin{macro}{\KV_process_no_space_removal_no_sanitize:NNn} -% There is just one function for this now. -% \begin{macrocode} -\cs_new_eq:NN \KV_process_space_removal_sanitize:NNn \keyval_parse:NNn -\cs_new_eq:NN \KV_process_space_removal_no_sanitize:NNn \keyval_parse:NNn -\cs_new_eq:NN \KV_process_no_space_removal_no_sanitize:NNn \keyval_parse:NNn -% \end{macrocode} -% \end{macro} -% \end{macro} -% \end{macro} -% -% \begin{macrocode} -%</initex|package> -% \end{macrocode} -% -% \end{implementation} -% -% \PrintIndex diff --git a/Master/texmf-dist/source/latex/l3kernel/l3luatex.dtx b/Master/texmf-dist/source/latex/l3kernel/l3luatex.dtx index a0e90de31fc..b2f12568bb1 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3luatex.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3luatex.dtx @@ -35,7 +35,7 @@ % %<*driver|package> \RequirePackage{l3names} -\GetIdInfo$Id: l3luatex.dtx 2545 2011-08-11 13:47:19Z bruno $ +\GetIdInfo$Id: l3luatex.dtx 2617 2011-08-18 08:13:44Z joseph $ {L3 Experimental LuaTeX-specific functions} %</driver|package> %<*driver> @@ -229,7 +229,6 @@ {\ExplFileName}{\ExplFileDate}{\ExplFileVersion}{\ExplFileDescription} \package_check_loaded_expl: %</package> -%<*initex|package> % \end{macrocode} % % \begin{macro}{\lua_now:n, \lua_now:x} diff --git a/Master/texmf-dist/source/latex/l3kernel/l3prg.dtx b/Master/texmf-dist/source/latex/l3kernel/l3prg.dtx index b63d2e5721b..66b9837a8be 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3prg.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3prg.dtx @@ -35,7 +35,7 @@ % %<*driver|package> \RequirePackage{l3names} -\GetIdInfo$Id: l3prg.dtx 2601 2011-08-16 23:20:27Z bruno $ +\GetIdInfo$Id: l3prg.dtx 2665 2011-08-25 22:15:27Z joseph $ {L3 Experimental control structures} %</driver|package> %<*driver> @@ -352,11 +352,7 @@ % \cs{bool_if:NTF} \Arg{boolean} \Arg{true code} \Arg{false code} % \end{syntax} % Tests the current truth of \meta{boolean}, and continues expansion -% based on this result. The branching versions then leave either -% \meta{true code} or \meta{false code} in the input stream, as -% appropriate to the truth of the test and the variant of the function -% chosen. The logical truth of the test is left in the input stream by -% the predicate version. +% based on this result. % \end{function} % % \begin{variable}{\l_tmpa_bool} @@ -431,11 +427,7 @@ % |\int_compare_p:nNn { 1 } = { \error }|. The logical Not applies to % the next single predicate or group. As shown above, this means that % any predicates requiring an argument have to be given within -% parentheses. The branching versions then leave either -% \meta{true code} or \meta{false code} in the input stream, as -% appropriate to the truth of the test and the variant of the function -% chosen. The logical truth of the test is left in the input stream by -% the predicate version. +% parentheses. % \end{function} % % \begin{function}[EXP]{\bool_not_p:n} @@ -673,11 +665,7 @@ % \cs{mode_if_horizontal_p:} % \cs{mode_if_horizontal:TF} \Arg{true code} \Arg{false code} % \end{syntax} -% Detects if \TeX{} is currently in horizontal mode. The branching -% versions then leave either \meta{true code} or \meta{false code} -% in the input stream, as appropriate to the truth of the test and -% the variant of the function chosen. The logical truth of the test -% is left in the input stream by the predicate version. +% Detects if \TeX{} is currently in horizontal mode. % \end{function} % % \begin{function}[EXP,pTF]{\mode_if_inner:} @@ -685,21 +673,14 @@ % \cs{mode_if_inner_p:} % \cs{mode_if_inner:TF} \Arg{true code} \Arg{false code} % \end{syntax} -% Detects if \TeX{} is currently in inner mode. The branching -% versions then leave either \meta{true code} or \meta{false code} -% in the input stream, as appropriate to the truth of the test and -% the variant of the function chosen. The logical truth of the test -% is left in the input stream by the predicate version. +% Detects if \TeX{} is currently in inner mode. % \end{function} % % \begin{function}[EXP,TF]{\mode_if_math:} % \begin{syntax} % \cs{mode_if_math:TF} \Arg{true code} \Arg{false code} % \end{syntax} -% Detects if \TeX{} is currently in maths mode. The branching -% versions then leave either \meta{true code} or \meta{false code} -% in the input stream, as appropriate to the truth of the test and -% the variant of the function chosen. +% Detects if \TeX{} is currently in maths mode. % \end{function} % % \begin{function}[EXP,pTF]{\mode_if_vertical:} @@ -707,11 +688,7 @@ % \cs{mode_if_vertical_p:} % \cs{mode_if_vertical:TF} \Arg{true code} \Arg{false code} % \end{syntax} -% Detects if \TeX{} is currently in vertical mode. The branching -% versions then leave either \meta{true code} or \meta{false code} -% in the input stream, as appropriate to the truth of the test and -% the variant of the function chosen. The logical truth of the test -% is left in the input stream by the predicate version. +% Detects if \TeX{} is currently in vertical mode. % \end{function} % % \section{Internal programming functions} @@ -2027,7 +2004,7 @@ % % \subsection{Deprecated functions} % -% These were depreciated on 2011-05-27 and will be removed entirely by +% These were deprecated on 2011-05-27 and will be removed entirely by % 2011-08-31. % % \begin{macro}{\prg_new_map_functions:Nn} diff --git a/Master/texmf-dist/source/latex/l3kernel/l3prop.dtx b/Master/texmf-dist/source/latex/l3kernel/l3prop.dtx index 744cea629fc..0923121015d 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3prop.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3prop.dtx @@ -35,7 +35,7 @@ % %<*driver|package> \RequirePackage{l3names} -\GetIdInfo$Id: l3prop.dtx 2478 2011-06-19 21:34:23Z joseph $ +\GetIdInfo$Id: l3prop.dtx 2665 2011-08-25 22:15:27Z joseph $ {L3 Experimental property lists} %</driver|package> %<*driver> @@ -228,7 +228,8 @@ % variable}. If the \meta{key} is not found in the % \meta{property list} then the \meta{token list variable} will % contain the special marker \cs{q_no_value}. The \meta{token list -% variable} is set within the current \TeX{} group. +% variable} is set within the current \TeX{} group. See also +% \cs{prop_get:NnNTF}. % \end{function} % % \begin{function}{\prop_pop:NnN, \prop_pop:NoN, \prop_pop:cnN, \prop_pop:coN} @@ -258,7 +259,7 @@ % The \meta{property list} is modified globally, while the assignment of % the \meta{token list variable} is local. % \end{function} -% +%% % \section{Modifying property lists} % % \begin{function}{\prop_del:Nn, \prop_del:NV, \prop_del:cn, \prop_del:cV} @@ -292,32 +293,62 @@ % \cs{prop_if_empty:NTF} \meta{property list} % ~~\Arg{true code} \Arg{false code} % \end{syntax} -% Tests if the \meta{property list} is empty (containing no entries). The -% branching versions then leave either \meta{true code} or -% \meta{false code} in the input stream, as appropriate to the truth of -% the test and the variant of the function chosen. The logical truth of -% the test is left in the input stream by the predicate version. +% Tests if the \meta{property list} is empty (containing no entries). % \end{function} % -% \begin{function}[EXP,pTF]{ -% \prop_if_in:Nn, \prop_if_in:NV, \prop_if_in:No, -% \prop_if_in:cn, \prop_if_in:cV, \prop_if_in:co -% } +% \begin{function}[EXP,pTF] +% { +% \prop_if_in:Nn, \prop_if_in:NV, \prop_if_in:No, +% \prop_if_in:cn, \prop_if_in:cV, \prop_if_in:co +% } % \begin{syntax} % \cs{prop_if_in:NnTF} \meta{property list} \Arg{key} % ~~\Arg{true code} \Arg{false code} % \end{syntax} % Tests if the \meta{key} is present in the \meta{property list}, % making the comparison using the method described by \cs{str_if_eq:nnTF}. -% Either the \meta{true code} or \meta{false code} in the input stream, as -% appropriate to the truth of the test and the variant of the function -% chosen. % \begin{texnote} % This function iterates through every key--value pair in the % \meta{property list} and is therefore slower than using the % non-expandable \cs{prop_get:NnNTF}. % \end{texnote} % \end{function} +% +% \section{Recovering values from property lists with branching} +% +% The functions in this section combine tests for the presence of a key +% in a property list with recovery of the associated valued. This makes them +% useful for cases where different cases follow dependent on the presence +% or absence of a key in a property list. They offer increased readability +% and performance over separate testing and recovery phases. +% +% \begin{function}[TF]{\prop_get:NnN, \prop_get:cnN} +% \begin{syntax} +% \cs{prop_get:NnNTF} \meta{property list} \Arg{key} +% ~~\meta{token list variable} \Arg{true code} \Arg{false code} +% \end{syntax} +% If the \meta{key} is not present in the \meta{property list}, leaves +% the \meta{false code} in the input stream and leaves the +% \meta{token list variable} unchanged. If the \meta{key} is present in +% the \meta{property list}, stores the corresponding \meta{value} +% in the \meta{token list variable} without removing it from the +% \meta{property list}. The \meta{token list variable} is assigned locally. +% \end{function} +% +% \begin{function}[TF]{\prop_pop:NnN, \prop_pop:cnN} +% \begin{syntax} +% \cs{prop_pop:NnNTF} \meta{property list} \Arg{key} +% ~~\meta{token list variable} \Arg{true code} \Arg{false code} +% \end{syntax} +% If the \meta{key} is not present in the \meta{property list}, leaves +% the \meta{false code} in the input stream and leaves the +% \meta{token list variable} unchanged. If the \meta{key} is present in +% the \meta{property list}, pops the corresponding \meta{value} +% in the \meta{token list variable}, \emph{i.e.}~removes the item from +% the \meta{property list}. +% Both the \meta{property list} and the \meta{token list variable} +% are assigned locally. +% \end{function} % % \section{Mapping to property lists} % @@ -401,36 +432,7 @@ % This section contains functions which may or may not be retained, depending % on how useful they are found to be. % -% \begin{function}[TF]{\prop_get:NnN} -% \begin{syntax} -% \cs{prop_get:NnNTF} \meta{property list} \Arg{key} -% ~~\meta{token list variable} \Arg{true code} \Arg{false code} -% \end{syntax} -% If the \meta{key} is not present in the \meta{property list}, leaves -% the \meta{false code} in the input stream and leaves the -% \meta{token list variable} unchanged. If the \meta{key} is present in -% the \meta{property list}, stores the corresponding \meta{value} -% in the \meta{token list variable} without removing it from the -% \meta{property list}. The \meta{true code} is then left in the input -% stream. The \meta{token list variable} is assigned locally. -% \end{function} -% -% \begin{function}[TF]{\prop_pop:NnN} -% \begin{syntax} -% \cs{prop_pop:NnNTF} \meta{property list} \Arg{key} -% ~~\meta{token list variable} \Arg{true code} \Arg{false code} -% \end{syntax} -% If the \meta{key} is not present in the \meta{property list}, leaves -% the \meta{false code} in the input stream and leaves the -% \meta{token list variable} unchanged. If the \meta{key} is present in -% the \meta{property list}, pops the corresponding \meta{value} -% in the \meta{token list variable}, \emph{i.e.}~removes the item from -% the \meta{property list}. The \meta{true code} is then left in the input -% stream. Both the \meta{property list} and the \meta{token list variable} -% are assigned locally. -% \end{function} -% -% \begin{function}[TF]{\prop_gpop:NnN} +% \begin{function}[TF]{\prop_gpop:NnN, \prop_gpop:cnN} % \begin{syntax} % \cs{prop_gpop:NnNTF} \meta{property list} \Arg{key} % ~~\meta{token list variable} \Arg{true code} \Arg{false code} @@ -440,12 +442,12 @@ % \meta{token list variable} unchanged. If the \meta{key} is present in % the \meta{property list}, pops the corresponding \meta{value} % in the \meta{token list variable}, \emph{i.e.}~removes the item from -% the \meta{property list}. The \meta{true code} is then left in the input -% stream. The \meta{property list} is modified globally, while the +% the \meta{property list}. +% The \meta{property list} is modified globally, while the % \meta{token list variable} is assigned locally. % \end{function} % -% \begin{function}[EXP]{\prop_map_tokens:Nn} +% \begin{function}[EXP]{\prop_map_tokens:Nn, \prop_map_tokens:cn} % \begin{syntax} % \cs{prop_map_tokens:Nn} \meta{property list} \Arg{code} % \end{syntax} @@ -454,7 +456,7 @@ % property list while keeping track of a given key. % \end{function} % -% \begin{function}[EXP]{\prop_get:Nn} +% \begin{function}[EXP]{\prop_get:Nn, \prop_get:cn} % \begin{syntax} % \cs{prop_get:Nn} \meta{property list} \Arg{key} % \end{syntax} @@ -920,6 +922,32 @@ % \end{macrocode} % \end{macro} % \end{macro} +% +% \subsection{Recovering values from property lists with branching} +% +% \begin{macro}[TF]{\prop_get:NnN, \prop_get:cnN} +% \begin{macro}[aux]{\prop_get_aux_true:Nnnn} +% Getting the value corresponding to a key, keeping track of whether +% the key was present or not, is implemented as a conditional (with +% side effects). If the key was absent, the token list is not altered. +% \begin{macrocode} +\prg_new_protected_conditional:Npnn \prop_get:NnN #1#2#3 { T , F , TF } + { + \prop_split:NnTF #1 {#2} + { \prop_get_aux_true:Nnnn #3 } + { \prg_return_false: } + } +\cs_new_protected:Npn \prop_get_aux_true:Nnnn #1#2#3#4 + { + \tl_set:Nn #1 {#3} + \prg_return_true: + } +\cs_generate_variant:Nn \prop_get:NnNT { c } +\cs_generate_variant:Nn \prop_get:NnNF { c } +\cs_generate_variant:Nn \prop_get:NnNTF { c } +% \end{macrocode} +% \end{macro} +% \end{macro} % % \subsection{Mapping to property lists} % @@ -1043,28 +1071,8 @@ % % \subsection{Experimental functions} % -% \begin{macro}[TF]{\prop_get:NnN} -% \begin{macro}[aux]{\prop_get_aux_true:Nnnn} -% Getting the value corresponding to a key, keeping track of whether -% the key was present or not, is implemented as a conditional (with -% side effects). If the key was absent, the token list is not altered. -% \begin{macrocode} -\prg_new_protected_conditional:Npnn \prop_get:NnN #1#2#3 { T , F , TF } - { - \prop_split:NnTF #1 {#2} - { \prop_get_aux_true:Nnnn #3 } - { \prg_return_false: } - } -\cs_new_protected:Npn \prop_get_aux_true:Nnnn #1#2#3#4 - { - \tl_set:Nn #1 {#3} - \prg_return_true: - } -% \end{macrocode} -% \end{macro} -% \end{macro} -% -% \begin{macro}[TF]{\prop_pop:NnN,\prop_gpop:NnN} +% \begin{macro}[TF] +% {\prop_pop:NnN, \prop_pop:cnN, \prop_gpop:cnN, \prop_gpop:cnN} % \begin{macro}[aux]{\prop_pop_aux_true:NNNnnn} % Popping an item from a property list, keeping track of whether % the key was present or not, is implemented as a conditional. @@ -1072,13 +1080,13 @@ % list are altered. Otherwise, \cs{prg_return_true:} is used after % the assignments. % \begin{macrocode} -\prg_new_protected_conditional:Npnn \prop_pop:NnN #1#2#3 {T,F,TF} +\prg_new_protected_conditional:Npnn \prop_pop:NnN #1#2#3 { T , F , TF } { \prop_split:NnTF #1 {#2} { \prop_pop_aux_true:NNNnnn \tl_set:Nn #1 #3 } { \prg_return_false: } } -\prg_new_protected_conditional:Npnn \prop_gpop:NnN #1#2#3 {T,F,TF} +\prg_new_protected_conditional:Npnn \prop_gpop:NnN #1#2#3 { T , F , TF } { \prop_split:NnTF #1 {#2} { \prop_pop_aux_true:NNNnnn \tl_gset:Nn #1 #3 } @@ -1090,11 +1098,17 @@ #1 #2 { #4 #6 } \prg_return_true: } +\cs_generate_variant:Nn \prop_pop:NnNT { c } +\cs_generate_variant:Nn \prop_pop:NnNF { c } +\cs_generate_variant:Nn \prop_pop:NnNTF { c } +\cs_generate_variant:Nn \prop_gpop:NnNT { c } +\cs_generate_variant:Nn \prop_gpop:NnNF { c } +\cs_generate_variant:Nn \prop_gpop:NnNTF { c } % \end{macrocode} % \end{macro} % \end{macro} % -% \begin{macro}[EXP]{\prop_map_tokens:Nn} +% \begin{macro}[EXP]{\prop_map_tokens:Nn, \prop_map_tokens:cn} % \begin{macro}[aux]{\prop_map_tokens_aux:nwn} % The mapping grabs one key--value pair at a time, and stops when % reaching the marker key |A|, with catcode \enquote{letter}, which @@ -1114,24 +1128,26 @@ \use:n {#1} {#2} {#3} \prop_map_tokens_aux:nwn {#1} } +\cs_generate_variant:Nn \prop_map_tokens:Nn { c } % \end{macrocode} % \end{macro} % \end{macro} % -% \begin{macro}[EXP]{\prop_get:Nn} +% \begin{macro}[EXP]{\prop_get:Nn, \prop_get:Nn} % \begin{macro}[aux]{\prop_get_aux:nnn} -% Getting expandably the value corresponding to a key in a property list -% is a simple instance of mapping some tokens. +% Getting the value corresponding to a key in a property list in an +% expandable fashion is a simple instance of mapping some tokens. % Map the function \cs{prop_get_aux:nnn} which takes as its three % arguments the \meta{key} that we are looking for, the current % \meta{key} and the current \meta{value}. If the \meta{keys} match, % the \meta{value} is returned. If none of the keys match, this expands % to nothing. % \begin{macrocode} -\cs_new:Npn \prop_get:Nn #1 #2 +\cs_new:Npn \prop_get:Nn #1#2 { \prop_map_tokens:Nn #1 { \prop_get_aux:nnn {#2} } } -\cs_new:Npn \prop_get_aux:nnn #1 #2 #3 +\cs_new:Npn \prop_get_aux:nnn #1#2#3 { \str_if_eq:nnT {#1} {#2} { \prop_map_break:n {#3} } } +\cs_generate_variant:Nn \prop_get:Nn { c } % \end{macrocode} % \end{macro} % \end{macro} diff --git a/Master/texmf-dist/source/latex/l3kernel/l3quark.dtx b/Master/texmf-dist/source/latex/l3kernel/l3quark.dtx index 11f4b0805d1..4f8a12c67d4 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3quark.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3quark.dtx @@ -35,7 +35,7 @@ % %<*driver|package> \RequirePackage{l3names} -\GetIdInfo$Id: l3quark.dtx 2549 2011-08-11 21:06:39Z bruno $ +\GetIdInfo$Id: l3quark.dtx 2665 2011-08-25 22:15:27Z joseph $ {L3 Experimental quarks} %</driver|package> %<*driver> @@ -131,11 +131,7 @@ % \cs{quark_if_nil_p:N} \meta{token} % \cs{quark_if_nil:NTF} \meta{token} \Arg{true code} \Arg{false code} % \end{syntax} -% Tests if the \meta{token} is equal to \cs{q_nil}. The branching -% versions then leave either \meta{true code} or \meta{false code} in -% the input stream, as appropriate to the truth of the test and the -% variant of the function chosen. The logical truth of the test is -% left in the input stream by the predicate version. +% Tests if the \meta{token} is equal to \cs{q_nil}. % \end{function} % % \begin{function}[EXP,pTF]{\quark_if_nil:n, \quark_if_nil:o, \quark_if_nil:V} @@ -145,11 +141,7 @@ % \end{syntax} % Tests if the \meta{token list} contains only \cs{q_nil} (distinct % from \meta{token list} being empty or containing \cs{q_nil} plus one -% or more other tokens). The branching versions then leave either -% \meta{true code} or \meta{false code} in the input stream, as -% appropriate to the truth of the test and the variant of the -% function chosen. The logical truth of the test is left in the input -% stream by the predicate version. +% or more other tokens). % \end{function} % % \begin{function}[EXP,pTF]{\quark_if_no_value:N, \quark_if_no_value:c} @@ -158,11 +150,7 @@ % \cs{quark_if_no_value:NTF} \meta{token} \Arg{true code} % ~~\Arg{false code} % \end{syntax} -% Tests if the \meta{token} is equal to \cs{q_no_value}. The branching -% versions then leave either \meta{true code} or \meta{false code} in -% the input stream, as appropriate to the truth of the test and the -% variant of the function chosen. The logical truth of the test is -% left in the input stream by the predicate version. +% Tests if the \meta{token} is equal to \cs{q_no_value}. % \end{function} % % \begin{function}[EXP,pTF]{\quark_if_no_value:n} @@ -173,11 +161,7 @@ % \end{syntax} % Tests if the \meta{token list} contains only \cs{q_no_value} % (distinct from \meta{token list} being empty or containing -% \cs{q_no_value} plus one or more other tokens). The branching -% versions then leave either \meta{true code} or \meta{false code} in -% the input stream, as appropriate to the truth of the test and the -% variant of the function chosen. The logical truth of the test is -% left in the input stream by the predicate version. +% \cs{q_no_value} plus one or more other tokens). % \end{function} % % \section{Recursion} diff --git a/Master/texmf-dist/source/latex/l3kernel/l3seq.dtx b/Master/texmf-dist/source/latex/l3kernel/l3seq.dtx index 10692dcf430..01e719a9ccc 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3seq.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3seq.dtx @@ -35,7 +35,7 @@ % %<*driver|package> \RequirePackage{l3names} -\GetIdInfo$Id: l3seq.dtx 2586 2011-08-15 03:59:12Z bruno $ +\GetIdInfo$Id: l3seq.dtx 2665 2011-08-25 22:15:27Z joseph $ {L3 Experimental sequences and stacks} %</driver|package> %<*driver> @@ -356,11 +356,7 @@ % \cs{seq_if_empty_p:N} \meta{sequence} % \cs{seq_if_empty:NTF} \meta{sequence} \Arg{true code} \Arg{false code} % \end{syntax} -% Tests if the \meta{sequence} is empty (containing no items). The -% branching versions then leave either \meta{true code} or -% \meta{false code} in the input stream, as appropriate to the truth of -% the test and the variant of the function chosen. The logical truth of -% the test is left in the input stream by the predicate version. +% Tests if the \meta{sequence} is empty (containing no items). % \end{function} % % \begin{function}[TF]{ @@ -372,10 +368,6 @@ % ~~\Arg{true code} \Arg{false code} % \end{syntax} % Tests if the \meta{item} is present in the \meta{sequence}. -% Either the \meta{true code} or \meta{false code} is left in the input -% stream, as appropriate to the truth of the test and the variant of the -% function -% chosen. % \end{function} % % \section{Mapping to sequences} @@ -559,9 +551,10 @@ % \end{syntax} % If the \meta{sequence} is empty, leaves the \meta{false code} in the % input stream and leaves the \meta{token list variable} unchanged. If the -% \meta{sequence} is non-empty, stores the left-most item from a \meta{sequence} +% \meta{sequence} is non-empty, stores the left-most item from a +% \meta{sequence} % in the \meta{token list variable} without removing it from a -% \meta{sequence}. The \meta{true code} is then left in the input stream. +% \meta{sequence}. % The \meta{token list variable} is assigned locally. % \end{function} % @@ -572,9 +565,10 @@ % \end{syntax} % If the \meta{sequence} is empty, leaves the \meta{false code} in the % input stream and leaves the \meta{token list variable} unchanged. If the -% \meta{sequence} is non-empty, stores the right-most item from a \meta{sequence} +% \meta{sequence} is non-empty, stores the right-most item from a +% \meta{sequence} % in the \meta{token list variable} without removing it from a -% \meta{sequence}. The \meta{true code} is then left in the input stream. +% \meta{sequence}. % The \meta{token list variable} is assigned locally. % \end{function} % @@ -585,9 +579,10 @@ % \end{syntax} % If the \meta{sequence} is empty, leaves the \meta{false code} in the % input stream and leaves the \meta{token list variable} unchanged. If the -% \meta{sequence} is non-empty, pops the left-most item from a \meta{sequence} +% \meta{sequence} is non-empty, pops the left-most item from a +% \meta{sequence} % in the \meta{token list variable}, \emph{i.e.}~removes the item from a -% \meta{sequence}. The \meta{true code} is then left in the input stream. +% \meta{sequence}. % Both the \meta{sequence} and the \meta{token list variable} are assigned % locally. % \end{function} @@ -601,7 +596,7 @@ % input stream and leaves the \meta{token list variable} unchanged. If the % \meta{sequence} is non-empty, pops the left-most item from a \meta{sequence} % in the \meta{token list variable}, \emph{i.e.}~removes the item from a -% \meta{sequence}. The \meta{true code} is then left in the input stream. +% \meta{sequence}. % The \meta{sequence} is modified globally, while the \meta{token list variable} % is assigned locally. % \end{function} @@ -615,7 +610,7 @@ % input stream and leaves the \meta{token list variable} unchanged. If the % \meta{sequence} is non-empty, pops the right-most item from a \meta{sequence} % in the \meta{token list variable}, \emph{i.e.}~removes the item from a -% \meta{sequence}. The \meta{true code} is then left in the input stream. +% \meta{sequence}. % Both the \meta{sequence} and the \meta{token list variable} are assigned % locally. % \end{function} @@ -629,7 +624,7 @@ % input stream and leaves the \meta{token list variable} unchanged. If the % \meta{sequence} is non-empty, pops the right-most item from a \meta{sequence} % in the \meta{token list variable}, \emph{i.e.}~removes the item from a -% \meta{sequence}. The \meta{true code} is then left in the input stream. +% \meta{sequence}. % The \meta{sequence} is modified globally, while the \meta{token list variable} % is assigned locally. % \end{function} diff --git a/Master/texmf-dist/source/latex/l3kernel/l3skip.dtx b/Master/texmf-dist/source/latex/l3kernel/l3skip.dtx index 9145e7d59cf..8655a41201c 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3skip.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3skip.dtx @@ -35,7 +35,7 @@ % %<*driver|package> \RequirePackage{l3names} -\GetIdInfo$Id: l3skip.dtx 2526 2011-08-09 08:58:42Z joseph $ +\GetIdInfo$Id: l3skip.dtx 2665 2011-08-25 22:15:27Z joseph $ {L3 Experimental dimensions and skips} %</driver|package> %<*driver> @@ -258,11 +258,6 @@ % Less than & |<| \\ % \end{tabular} % \end{center} -% The branching versions then leave either \meta{true code} or -% \meta{false code} in the input stream, as appropriate to the truth -% of the test and the variant of the function chosen. The logical -% truth of the test is left in the input stream by the predicate -% version. % \end{function} % % \begin{function}[EXP,pTF]{\dim_compare:n} @@ -286,11 +281,6 @@ % Not equal & |!=| \\ % \end{tabular} % \end{center} -% The branching versions then leave either \meta{true code} or -% \meta{false code} in the input stream, as appropriate to the truth -% of the test and the variant of the function chosen. The logical -% truth of the test is left in the input stream by the predicate -% version. % \end{function} % % \section{Dimension expression loops} @@ -582,11 +572,7 @@ % \meta{skip expressions} as described for \cs{skip_eval:n}. % The two results are then compared for exact equality, % \emph{i.e.}~both the fixed and rubber components must be the same -% for the test to be true. The branching versions then leave either -% \meta{true code} or \meta{false code} in the input stream, as -% appropriate to the truth of the test and the variant of the function -% chosen. The logical truth of the test is left in the input stream by -% the predicate version. +% for the test to be true. % \end{function} % % \begin{function}[EXP,pTF]{\skip_if_infinite_glue:n} @@ -598,10 +584,6 @@ % Evaluates the \meta{skip expression} as described for \cs{skip_eval:n}, % and then tests if this contains an infinite stretch or shrink % component (or both). -% The branching versions then leave either \meta{true code} or -% \meta{false code} in the input stream, as appropriate to the truth -% of the test and the variant of the function chosen. The logical -% truth of the test is left in the input stream by the predicate % \end{function} % % \section{Using \texttt{skip} expressions and variables} diff --git a/Master/texmf-dist/source/latex/l3kernel/l3tl.dtx b/Master/texmf-dist/source/latex/l3kernel/l3tl.dtx index f596eb1a263..f5a36e95bad 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3tl.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3tl.dtx @@ -35,7 +35,7 @@ % %<*driver|package> \RequirePackage{l3names} -\GetIdInfo$Id: l3tl.dtx 2566 2011-08-13 22:04:42Z bruno $ +\GetIdInfo$Id: l3tl.dtx 2665 2011-08-25 22:15:27Z joseph $ {L3 Experimental token lists} %</driver|package> %<*driver> @@ -445,11 +445,6 @@ % (\emph{i.e.}~contains no item). The test is \texttt{true} if % \meta{token list} is zero or more explicit tokens of character code~$32$ % and category code~$10$, and is \texttt{false} otherwise. -% The branching versions then leave either \meta{true code} -% or \meta{false code} in the input stream, as appropriate to the -% truth of the test and the variant of the function chosen. The logical -% truth of the test is left in the input stream by the predicate -% version. % \end{function} % % \begin{function}[EXP,pTF]{\tl_if_empty:N, \tl_if_empty:c} @@ -458,11 +453,7 @@ % \cs{tl_if_empty:NTF} \meta{tl var} \Arg{true code} \Arg{false code} % \end{syntax} % Tests if the \meta{token list variable} is entirely empty -% (\emph{i.e.}~contains no tokens at all). The branching versions then -% leave either \meta{true code} or \meta{false code} in the input -% stream, as appropriate to the truth of the test and the variant of -% the function chosen. The logical truth of the test is left in the -% input stream by the predicate version. +% (\emph{i.e.}~contains no tokens at all). % \end{function} % % \begin{function}[EXP,pTF]{\tl_if_empty:n, \tl_if_empty:V, \tl_if_empty:o} @@ -471,11 +462,7 @@ % \cs{tl_if_empty:nTF} \Arg{token list} \Arg{true code} \Arg{false code} % \end{syntax} % Tests if the \meta{token list} is entirely empty -% (\emph{i.e.}~contains no tokens at all). The branching versions then -% leave either \meta{true code} or \meta{false code} in the input -% stream, as appropriate to the truth of the test and the variant of -% the function chosen. The logical truth of the test is left in the -% input stream by the predicate version. +% (\emph{i.e.}~contains no tokens at all). % \end{function} % % \begin{function}[EXP,pTF] @@ -494,11 +481,7 @@ % \tl_set:Nx \l_tmpb_tl { \tl_to_str:n { abc } } % \tl_if_eq_p:NN \l_tmpa_tl \l_tmpb_tl % \end{verbatim} -% is logically \texttt{false}. The branching versions then leave either -% \meta{true code} or \meta{false code} in the input stream, as -% appropriate to the truth of the test and the variant of the function -% chosen. The logical truth of the test is left in the input stream by -% the predicate version. +% is logically \texttt{false}. % \end{function} % % \begin{function}[TF]{\tl_if_eq:nn} @@ -507,10 +490,7 @@ % ~~\Arg{false code} % \end{syntax} % Tests if \meta{token list1} and \meta{token list2} are equal, both in -% respect of character codes and category codes. Either the -% \meta{true code} or \meta{false code} in the input stream, as -% appropriate to the truth of the test and the variant of the function -% chosen. +% respect of character codes and category codes. % \end{function} % % \begin{function}[TF]{\tl_if_in:Nn, \tl_if_in:cn} @@ -521,24 +501,18 @@ % Tests if the \meta{token list} is found in the content of the % \meta{token list variable}. The \meta{token list} cannot contain % the tokens |{|, |}| or |#| (assuming the usual \TeX{} category -% codes apply). Either the \meta{true code} or \meta{false code} -% is left in the -% input stream, as appropriate to the truth of the test and the variant -% of the function chosen. +% codes apply). % \end{function} % % \begin{function}[TF] % {\tl_if_in:nn, \tl_if_in:Vn, \tl_if_in:on, \tl_if_in:on} % \begin{syntax} -% \cs{tl_if_in:nnTF} \meta{token list1} \Arg{token list2} \Arg{true code} +% \cs{tl_if_in:nnTF} \Arg{token list1} \Arg{token list2} \Arg{true code} % ~~\Arg{false code} % \end{syntax} -% Tests if the \meta{token list1} is found inside \meta{token list2}. +% Tests if <token list2> is found inside <token list1>. % The \meta{token list} cannot contain the tokens |{|, |}| or |#| -% (assuming the usual \TeX{} category codes apply). Either the -% \meta{true code} or \meta{false code} is left in the input stream, as -% appropriate to the truth of the test and the variant of the function -% chosen. +% (assuming the usual \TeX{} category codes apply). % \end{function} % % \begin{function}[EXP,pTF]{\tl_if_single:N, \tl_if_single:c} @@ -550,11 +524,7 @@ % \emph{i.e.}~is either a single normal token (excluding spaces, % and brace tokens) or a single brace group, surrounded by optional % spaces on both sides. In other words, such a token list has length -% $1$ according to \cs{tl_length:N}. The branching -% versions then leave either \meta{true code} or \meta{false code} -% in the input stream, as appropriate to the truth of the test and the -% variant of the function chosen. The logical truth of the test is left -% in the input stream by the predicate version. +% $1$ according to \cs{tl_length:N}. % \end{function} % % \begin{function}[EXP,pTF]{\tl_if_single:n} @@ -567,10 +537,6 @@ % a single normal token or a single brace group, surrounded by % optional spaces on both sides. In other words, such a token list % has length $1$ according to \cs{tl_length:n}. -% The branching versions leave either \meta{true code} or \meta{false code} -% in the input stream, as appropriate to the truth of the test and -% the variant of the function chosen. The logical truth of the test -% is left in the input stream by the predicate. % \end{function} % % \begin{function}[EXP,pTF]{\tl_if_single_token:n} @@ -582,10 +548,6 @@ % Tests if the token list consists of exactly one token, \emph{i.e.}~is % either a single space character or a single \enquote{normal} token. % Token groups (|{|\ldots|}|) are not single tokens. -% The branching versions leave either \meta{true code} or \meta{false code} -% in the input stream, as appropriate to the truth of the test and -% the variant of the function chosen. The logical truth of the test -% is left in the input stream by the predicate. % \end{function} % % \section{Mapping to token lists} @@ -912,12 +874,6 @@ % category code as the \meta{test token}. In the case where % \meta{token list} is empty, its head is considered to be \cs{q_nil}, % and the test will be true if \meta{test token} is a control sequence. -% The branching versions then -% leave either \meta{true code} or \meta{false code} in the input -% stream, as appropriate to the truth of the test and the variant of -% the function chosen. The logical truth of the test is left in the -% input stream by the predicate -% version. % \end{function} % % \begin{function}[EXP,pTF] @@ -931,12 +887,6 @@ % character code as the \meta{test token}. In the case where % \meta{token list} is empty, its head is considered to be \cs{q_nil}, % and the test will be true if \meta{test token} is a control sequence. -% The branching versions then -% leave either \meta{true code} or \meta{false code} in the input -% stream, as appropriate to the truth of the test and the variant of -% the function chosen. The logical truth of the test is left in the -% input stream by the predicate -% version. % \end{function} % % \begin{function}[EXP,pTF]{\tl_if_head_eq_meaning:nN} @@ -949,12 +899,6 @@ % meaning as the \meta{test token}. In the case where \meta{token list} % is empty, its head is considered to be \cs{q_nil}, and the test will % be true if \meta{test token} has the same meaning as \cs{q_nil}. -% The branching versions then -% leave either \meta{true code} or \meta{false code} in the input -% stream, as appropriate to the truth of the test and the variant of -% the function chosen. The logical truth of the test is left in the -% input stream by the predicate -% version. % \end{function} % % \begin{function}[EXP,pTF,int]{\tl_if_head_group:n} @@ -971,10 +915,6 @@ % \cs{c_group_begin_token}, or if it empty. % This function is useful to implement actions on token lists on % a token by token basis. -% The branching versions leave either \meta{true code} or \meta{false code} -% in the input stream, as appropriate to the truth of the test and -% the variant of the function chosen. The logical truth of the test -% is left in the input stream by the predicate. % \end{function} % % \begin{function}[EXP,pTF,int]{\tl_if_head_N_type:n} @@ -992,10 +932,6 @@ % first token. % This function is useful to implement actions on token lists on % a token by token basis. -% The branching versions leave either \meta{true code} or \meta{false code} -% in the input stream, as appropriate to the truth of the test and -% the variant of the function chosen. The logical truth of the test -% is left in the input stream by the predicate. % \end{function} % % \begin{function}[EXP,pTF,int]{\tl_if_head_space:n} @@ -1013,10 +949,6 @@ % will yield false, as well as if the argument is empty. % This function is useful to implement actions on token lists on % a token by token basis. -% The branching versions leave either \meta{true code} or -% \meta{false code} in the input stream, as appropriate to the truth -% of the test and the variant of the function chosen. The logical -% truth of the test is left in the input stream by the predicate. % \begin{texnote} % When \TeX{} reads a character of category code $10$ for the % first time, it is converted to an explicit space token, with @@ -2371,22 +2303,18 @@ % spaces, whereas \pdfTeX{} and \XeTeX{} do. So there may be a correction to % make in the \LuaTeX{} case. % \begin{macrocode} -%<*package> -\tl_const:Nx \c_job_name_tl { \tex_jobname:D } -%</package> %<*initex> \tex_everyjob:D \exp_after:wN { \tex_the:D \tex_everyjob:D - \luatex_if_engine:TF + \luatex_if_engine:T { - \tl_if_in:onTF { \tex_jobname:D } { ~ } - { \tl_const:Nx \c_job_name_tl { " \tex_jobname:D " } } - { \tl_const:Nx \c_job_name_tl { \tex_jobname:D } } + \lua_now:x + { dofile ( assert ( kpse.find_file ("lualatexquotejobname.lua" ) ) ) } } - { \tl_const:Nx \c_job_name_tl { \tex_jobname:D } } } %</initex> +\tl_const:Nx \c_job_name_tl { \tex_jobname:D } % \end{macrocode} % \end{variable} % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3token.dtx b/Master/texmf-dist/source/latex/l3kernel/l3token.dtx index 3aeca13b29d..c67a876db3d 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3token.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3token.dtx @@ -35,7 +35,7 @@ % %<*driver|package> \RequirePackage{l3names} -\GetIdInfo$Id: l3token.dtx 2579 2011-08-14 16:22:30Z bruno $ +\GetIdInfo$Id: l3token.dtx 2665 2011-08-25 22:15:27Z joseph $ {L3 Experimental token manipulation} %</driver|package> %<*driver> @@ -437,10 +437,7 @@ % \end{syntax} % Tests if \meta{token} has the category code of a begin group token % (|{| when normal \TeX{} category codes are in ^^A } -% force). The branching versions then leave either \meta{true code} or -% \meta{false code} in the input stream, as appropriate to the truth of -% the test and the variant of the function chosen. The logical truth of -% the test is left in the input stream by the predicate version. +% force). % Note that an explicit begin group token cannot be tested in this way, % as it is not a valid \texttt{N}-type argument. % \end{function} @@ -453,11 +450,7 @@ % \end{syntax} % Tests if \meta{token} has the category code of an end group token % (^^A { -% |}| when normal \TeX{} category codes are in force). The branching -% versions then leave either \meta{true code} or \meta{false code} in the -% input stream, as appropriate to the truth of the test and the variant -% of the function chosen. The logical truth of the test is left in the -% input stream by the predicate version. +% |}| when normal \TeX{} category codes are in force). % Note that an explicit end group token cannot be tested in this way, % as it is not a valid \texttt{N}-type argument. % \end{function} @@ -469,11 +462,7 @@ % ~~\Arg{false code} % \end{syntax} % Tests if \meta{token} has the category code of a math shift token -% (|$| when normal \TeX{} category codes are in force). The -% branching versions then leave either \meta{true code} or -% \meta{false code} in the input stream, as appropriate to the truth of -% the test and the variant of the function chosen. The logical truth of -% the test is left in the input stream by the predicate version. +% (|$| when normal \TeX{} category codes are in force). % \end{function} % % \begin{function}[EXP,pTF]{\token_if_alignment:N} @@ -483,11 +472,7 @@ % ~~\Arg{false code} % \end{syntax} % Tests if \meta{token} has the category code of an alignment token -% (|&| when normal \TeX{} category codes are in force). The -% branching versions then leave either \meta{true code} or -% \meta{false code} in the input stream, as appropriate to the truth of -% the test and the variant of the function chosen. The logical truth of -% the test is left in the input stream by the predicate version. +% (|&| when normal \TeX{} category codes are in force). % \end{function} % % \begin{function}[EXP,pTF]{\token_if_parameter:N} @@ -497,11 +482,7 @@ % ~~\Arg{false code} % \end{syntax} % Tests if \meta{token} has the category code of a macro parameter token -% (|#| when normal \TeX{} category codes are in force). The -% branching versions then leave either \meta{true code} or -% \meta{false code} in the input stream, as appropriate to the truth of -% the test and the variant of the function chosen. The logical truth of -% the test is left in the input stream by the predicate version. +% (|#| when normal \TeX{} category codes are in force). % \end{function} % % \begin{function}[EXP,pTF]{\token_if_math_superscript:N} @@ -511,11 +492,7 @@ % ~~\Arg{false code} % \end{syntax} % Tests if \meta{token} has the category code of a superscript token -% (|^| when normal \TeX{} category codes are in force). The -% branching versions then leave either \meta{true code} or -% \meta{false code} in the input stream, as appropriate to the truth of -% the test and the variant of the function chosen. The logical truth of -% the test is left in the input stream by the predicate version. +% (|^| when normal \TeX{} category codes are in force). % \end{function} % % \begin{function}[EXP,pTF]{\token_if_math_subscript:N} @@ -525,11 +502,7 @@ % ~~\Arg{false code} % \end{syntax} % Tests if \meta{token} has the category code of a subscript token -% (|_| when normal \TeX{} category codes are in force). The -% branching versions then leave either \meta{true code} or -% \meta{false code} in the input stream, as appropriate to the truth of -% the test and the variant of the function chosen. The logical truth of -% the test is left in the input stream by the predicate version. +% (|_| when normal \TeX{} category codes are in force). % \end{function} % % \begin{function}[EXP,pTF]{\token_if_space:N} @@ -538,11 +511,7 @@ % \cs{token_if_space:NTF} \meta{token} \Arg{true code} % ~~\Arg{false code} % \end{syntax} -% Tests if \meta{token} has the category code of a space token. The -% branching versions then leave either \meta{true code} or -% \meta{false code} in the input stream, as appropriate to the truth of -% the test and the variant of the function chosen. The logical truth of -% the test is left in the input stream by the predicate version. +% Tests if \meta{token} has the category code of a space token. % Note that an explicit space token with character code $32$ cannot % be tested in this way, as it is not a valid \texttt{N}-type argument. % \end{function} @@ -553,11 +522,7 @@ % \cs{token_if_letter:NTF} \meta{token} \Arg{true code} % ~~\Arg{false code} % \end{syntax} -% Tests if \meta{token} has the category code of a letter token. The -% branching versions then leave either \meta{true code} or -% \meta{false code} in the input stream, as appropriate to the truth of -% the test and the variant of the function chosen. The logical truth of -% the test is left in the input stream by the predicate version. +% Tests if \meta{token} has the category code of a letter token. % \end{function} % % \begin{function}[EXP,pTF]{\token_if_other:N} @@ -567,10 +532,7 @@ % ~~\Arg{false code} % \end{syntax} % Tests if \meta{token} has the category code of an \enquote{other} -% token. The branching versions then leave either \meta{true code} or -% \meta{false code} in the input stream, as appropriate to the truth of -% the test and the variant of the function chosen. The logical truth of -% the test is left in the input stream by the predicate version. +% token. % \end{function} % % \begin{function}[EXP,pTF]{\token_if_active:N} @@ -580,10 +542,6 @@ % ~~\Arg{false code} % \end{syntax} % Tests if \meta{token} has the category code of an active character. -% The branching versions then leave either \meta{true code} or -% \meta{false code} in the input stream, as appropriate to the truth of -% the test and the variant of the function chosen. The logical truth of -% the test is left in the input stream by the predicate version. % \end{function} % % \begin{function}[EXP,pTF]{\token_if_eq_catcode:NN} @@ -592,11 +550,7 @@ % \cs{token_if_eq_catcode:NNTF} \meta{token1} \meta{token2} % ~~\Arg{true code} \Arg{false code} % \end{syntax} -% Tests if the two \meta{tokens} have the same category code. The -% branching versions then leave either \meta{true code} or -% \meta{false code} in the input stream, as appropriate to the truth of -% the test and the variant of the function chosen. The logical truth of -% the test is left in the input stream by the predicate version. +% Tests if the two \meta{tokens} have the same category code. % \end{function} % % \begin{function}[EXP,pTF]{\token_if_eq_charcode:NN} @@ -605,11 +559,7 @@ % \cs{token_if_eq_charcode:NNTF} \meta{token1} \meta{token2} % ~~\Arg{true code} \Arg{false code} % \end{syntax} -% Tests if the two \meta{tokens} have the same character code. The -% branching versions then leave either \meta{true code} or -% \meta{false code} in the input stream, as appropriate to the truth of -% the test and the variant of the function chosen. The logical truth of -% the test is left in the input stream by the predicate version. +% Tests if the two \meta{tokens} have the same character code. % \end{function} % % \begin{function}[EXP,pTF]{\token_if_eq_meaning:NN} @@ -619,10 +569,6 @@ % ~~\Arg{true code} \Arg{false code} % \end{syntax} % Tests if the two \meta{tokens} have the same meaning when expanded. -% The branching versions then leave either \meta{true code} or -% \meta{false code} in the input stream, as appropriate to the truth of -% the test and the variant of the function chosen. The logical truth of -% the test is left in the input stream by the predicate version. % \end{function} % % \begin{function}[EXP,pTF]{\token_if_macro:N} @@ -631,10 +577,6 @@ % \cs{token_if_macro:NTF} \meta{token} \Arg{true code} \Arg{false code} % \end{syntax} % Tests if the \meta{token} is a \TeX{} macro. -% The branching versions then leave either \meta{true code} or -% \meta{false code} in the input stream, as appropriate to the truth of -% the test and the variant of the function chosen. The logical truth of -% the test is left in the input stream by the predicate version. % \end{function} % % \begin{function}[EXP,pTF]{\token_if_cs:N} @@ -643,10 +585,6 @@ % \cs{token_if_cs:NTF} \meta{token} \Arg{true code} \Arg{false code} % \end{syntax} % Tests if the \meta{token} is a control sequence. -% The branching versions then leave either \meta{true code} or -% \meta{false code} in the input stream, as appropriate to the truth of -% the test and the variant of the function chosen. The logical truth of -% the test is left in the input stream by the predicate version. % \end{function} % % \begin{function}[EXP,pTF]{\token_if_expandable:N} @@ -657,10 +595,6 @@ % \end{syntax} % Tests if the \meta{token} is expandable. This test returns \meta{false} % for an undefined token. -% The branching versions then leave either \meta{true code} or -% \meta{false code} in the input stream, as appropriate to the truth of -% the test and the variant of the function chosen. The logical truth of -% the test is left in the input stream by the predicate version. % \end{function} % % \begin{function}[EXP,pTF]{\token_if_long_macro:N} @@ -670,10 +604,6 @@ % ~~\Arg{true code} \Arg{false code} % \end{syntax} % Tests if the \meta{token} is a long macro. -% The branching versions then leave either \meta{true code} or -% \meta{false code} in the input stream, as appropriate to the truth of -% the test and the variant of the function chosen. The logical truth of -% the test is left in the input stream by the predicate version. % \end{function} % % \begin{function}[EXP,pTF]{\token_if_protected_macro:N} @@ -683,11 +613,7 @@ % ~~\Arg{true code} \Arg{false code} % \end{syntax} % Tests if the \meta{token} is a protected macro: a macro which -% is both protected and long will return logical false. -% The branching versions then leave either \meta{true code} or -% \meta{false code} in the input stream, as appropriate to the truth of -% the test and the variant of the function chosen. The logical truth of -% the test is left in the input stream by the predicate version. +% is both protected and long will return logical \texttt{false}. % \end{function} % %% \begin{function}[EXP,pTF]{\token_if_protected_long_macro:N} @@ -697,10 +623,6 @@ % ~~\Arg{true code} \Arg{false code} % \end{syntax} % Tests if the \meta{token} is a protected long macro. -% The branching versions then leave either \meta{true code} or -% \meta{false code} in the input stream, as appropriate to the truth of -% the test and the variant of the function chosen. The logical truth of -% the test is left in the input stream by the predicate version. % \end{function} % % \begin{function}[EXP,pTF]{\token_if_chardef:N} @@ -710,10 +632,6 @@ % ~~\Arg{true code} \Arg{false code} % \end{syntax} % Tests if the \meta{token} is defined to be a chardef. -% The branching versions then leave either \meta{true code} or -% \meta{false code} in the input stream, as appropriate to the truth of -% the test and the variant of the function chosen. The logical truth of -% the test is left in the input stream by the predicate version. % \end{function} % % \begin{function}[EXP,pTF]{\token_if_mathchardef:N} @@ -723,10 +641,6 @@ % ~~\Arg{true code} \Arg{false code} % \end{syntax} % Tests if the \meta{token} is defined to be a mathchardef. -% The branching versions then leave either \meta{true code} or -% \meta{false code} in the input stream, as appropriate to the truth of -% the test and the variant of the function chosen. The logical truth of -% the test is left in the input stream by the predicate version. % \end{function} % % \begin{function}[EXP,pTF]{\token_if_dim_register:N} @@ -736,10 +650,6 @@ % ~~\Arg{true code} \Arg{false code} % \end{syntax} % Tests if the \meta{token} is defined to be a dimension register. -% The branching versions then leave either \meta{true code} or -% \meta{false code} in the input stream, as appropriate to the truth of -% the test and the variant of the function chosen. The logical truth of -% the test is left in the input stream by the predicate version. % \end{function} % % \begin{function}[EXP,pTF]{\token_if_int_register:N} @@ -749,10 +659,6 @@ % ~~\Arg{true code} \Arg{false code} % \end{syntax} % Tests if the \meta{token} is defined to be a integer register. -% The branching versions then leave either \meta{true code} or -% \meta{false code} in the input stream, as appropriate to the truth of -% the test and the variant of the function chosen. The logical truth of -% the test is left in the input stream by the predicate version. % \end{function} % % \begin{function}[EXP,pTF]{\token_if_skip_register:N} @@ -762,10 +668,6 @@ % ~~\Arg{true code} \Arg{false code} % \end{syntax} % Tests if the \meta{token} is defined to be a skip register. -% The branching versions then leave either \meta{true code} or -% \meta{false code} in the input stream, as appropriate to the truth of -% the test and the variant of the function chosen. The logical truth of -% the test is left in the input stream by the predicate version. % \end{function} % % \begin{function}[EXP,pTF]{\token_if_toks_register:N} @@ -776,10 +678,6 @@ % \end{syntax} % Tests if the \meta{token} is defined to be a toks register % (not used by\LaTeX3). -% The branching versions then leave either \meta{true code} or -% \meta{false code} in the input stream, as appropriate to the truth of -% the test and the variant of the function chosen. The logical truth of -% the test is left in the input stream by the predicate version. % \end{function} % % \begin{function}[EXP,pTF]{\token_if_primitive:N} @@ -789,10 +687,6 @@ % ~~\Arg{true code} \Arg{false code} % \end{syntax} % Tests if the \meta{token} is an engine primitive. -% The branching versions then leave either \meta{true code} or -% \meta{false code} in the input stream, as appropriate to the truth of -% the test and the variant of the function chosen. The logical truth of -% the test is left in the input stream by the predicate version. % \end{function} % % \section{Peeking ahead at the next token} diff --git a/Master/texmf-dist/source/latex/l3kernel/l3toks.dtx b/Master/texmf-dist/source/latex/l3kernel/l3toks.dtx index 2b5d5cd0880..c060225ab31 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3toks.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3toks.dtx @@ -35,7 +35,7 @@ % %<*driver|package> \RequirePackage{l3names} -\GetIdInfo$Id: l3toks.dtx 2601 2011-08-16 23:20:27Z bruno $ +\GetIdInfo$Id: l3toks.dtx 2670 2011-08-27 09:58:02Z will $ {L3 Experimental token registers} %</driver|package> %<*driver> @@ -443,7 +443,7 @@ % % \begin{macro}{\toks_put_right:Nf} % We implement |\toks_put_right:Nf| by hand because I think I might -% use it in the \textsf{l3keyval} module in which case it is going to +% use it in the \textsf{l3keys} module in which case it is going to % be used a lot. % \begin{macrocode} %<check>\cs_generate_variant:Nn \toks_put_right:Nn {Nf} diff --git a/Master/texmf-dist/tex/latex/l3kernel/expl3.sty b/Master/texmf-dist/tex/latex/l3kernel/expl3.sty index 117c5ca5b4f..610d2b169ca 100644 --- a/Master/texmf-dist/tex/latex/l3kernel/expl3.sty +++ b/Master/texmf-dist/tex/latex/l3kernel/expl3.sty @@ -48,8 +48,8 @@ \RequirePackage{l3names} \def\ExplFileName{expl3} \def\ExplFileDescription{L3 Experimental code bundle wrapper} -\def\ExplFileDate{2011/08/17} -\def\ExplFileVersion{2607} +\def\ExplFileDate{2011/08/28} +\def\ExplFileVersion{2678} \RequirePackage{etex} \reserveinserts{32} \RequirePackage{calc} @@ -118,10 +118,10 @@ l3file, l3skip, l3box, - l3keyval, l3keys, l3fp, - l3luatex + l3luatex, + l3coffins } \RequirePackage{l3toks} \bool_if:nT { \@l@expl@check@declarations@bool } diff --git a/Master/texmf-dist/tex/latex/l3kernel/l3basics.sty b/Master/texmf-dist/tex/latex/l3kernel/l3basics.sty index edecb52c1c7..4d82350bb19 100644 --- a/Master/texmf-dist/tex/latex/l3kernel/l3basics.sty +++ b/Master/texmf-dist/tex/latex/l3kernel/l3basics.sty @@ -46,7 +46,7 @@ %% %% ----------------------------------------------------------------------- \RequirePackage{l3names} -\GetIdInfo$Id: l3basics.dtx 2493 2011-07-04 09:50:22Z bruno $ +\GetIdInfo$Id: l3basics.dtx 2665 2011-08-25 22:15:27Z joseph $ {L3 Experimental basic definitions} \ProvidesExplPackage diff --git a/Master/texmf-dist/tex/latex/l3kernel/l3box.sty b/Master/texmf-dist/tex/latex/l3kernel/l3box.sty index c6bd2936aae..57415ec278d 100644 --- a/Master/texmf-dist/tex/latex/l3kernel/l3box.sty +++ b/Master/texmf-dist/tex/latex/l3kernel/l3box.sty @@ -46,7 +46,7 @@ %% %% ----------------------------------------------------------------------- \RequirePackage{l3names} -\GetIdInfo$Id: l3box.dtx 2595 2011-08-16 00:58:34Z bruno $ +\GetIdInfo$Id: l3box.dtx 2665 2011-08-25 22:15:27Z joseph $ {L3 Experimental boxes} \ProvidesExplPackage {\ExplFileName}{\ExplFileDate}{\ExplFileVersion}{\ExplFileDescription} diff --git a/Master/texmf-dist/tex/latex/l3kernel/l3clist.sty b/Master/texmf-dist/tex/latex/l3kernel/l3clist.sty index ab92e649563..1f19e3490e0 100644 --- a/Master/texmf-dist/tex/latex/l3kernel/l3clist.sty +++ b/Master/texmf-dist/tex/latex/l3kernel/l3clist.sty @@ -47,7 +47,7 @@ %% %% ----------------------------------------------------------------------- \RequirePackage{l3names} -\GetIdInfo$Id: l3clist.dtx 2498 2011-07-09 17:51:47Z joseph $ +\GetIdInfo$Id: l3clist.dtx 2666 2011-08-26 06:10:09Z joseph $ {L3 Experimental comma separated lists} \ProvidesExplPackage {\ExplFileName}{\ExplFileDate}{\ExplFileVersion}{\ExplFileDescription} diff --git a/Master/texmf-dist/tex/latex/l3kernel/l3coffins.sty b/Master/texmf-dist/tex/latex/l3kernel/l3coffins.sty new file mode 100644 index 00000000000..6e4116ee770 --- /dev/null +++ b/Master/texmf-dist/tex/latex/l3kernel/l3coffins.sty @@ -0,0 +1,988 @@ +%% +%% This is file `l3coffins.sty', +%% generated with the docstrip utility. +%% +%% The original source files were: +%% +%% l3coffins.dtx (with options: `package') +%% +%% EXPERIMENTAL CODE +%% +%% Do not distribute this file without also distributing the +%% source files specified above. +%% +%% Do not distribute a modified version of this file. +%% +%% File: l3coffins.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 "l3kernel 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. +%% +%% ----------------------------------------------------------------------- +%% +\RequirePackage{l3names,graphicx,color} +\GetIdInfo$Id: l3coffins.dtx 2624 2011-08-18 19:02:45Z joseph $ + {L3 Experimental coffin code layer} +\ProvidesExplPackage + {\ExplFileName}{\ExplFileDate}{\ExplFileVersion}{\ExplFileDescription} +\package_check_loaded_expl: +\box_new:N \l_coffin_tmp_box +\dim_new:N \l_coffin_tmp_dim +\fp_new:N \l_coffin_tmp_fp +\tl_new:N \l_coffin_tmp_tl +\prop_new:N \c_coffin_corners_prop +\prop_put:Nnn \c_coffin_corners_prop { tl } { { 0 pt } { 0 pt } } +\prop_put:Nnn \c_coffin_corners_prop { tr } { { 0 pt } { 0 pt } } +\prop_put:Nnn \c_coffin_corners_prop { bl } { { 0 pt } { 0 pt } } +\prop_put:Nnn \c_coffin_corners_prop { br } { { 0 pt } { 0 pt } } +\prop_new:N \c_coffin_poles_prop +\tl_set:Nn \l_coffin_tmp_tl { { 0 pt } { 0 pt } { 0 pt } { 1000 pt } } +\prop_put:Nno \c_coffin_poles_prop { l } { \l_coffin_tmp_tl } +\prop_put:Nno \c_coffin_poles_prop { hc } { \l_coffin_tmp_tl } +\prop_put:Nno \c_coffin_poles_prop { r } { \l_coffin_tmp_tl } +\tl_set:Nn \l_coffin_tmp_tl { { 0 pt } { 0 pt } { 1000 pt } { 0 pt } } +\prop_put:Nno \c_coffin_poles_prop { b } { \l_coffin_tmp_tl } +\prop_put:Nno \c_coffin_poles_prop { vc } { \l_coffin_tmp_tl } +\prop_put:Nno \c_coffin_poles_prop { t } { \l_coffin_tmp_tl } +\prop_put:Nno \c_coffin_poles_prop { B } { \l_coffin_tmp_tl } +\prop_put:Nno \c_coffin_poles_prop { H } { \l_coffin_tmp_tl } +\prop_put:Nno \c_coffin_poles_prop { T } { \l_coffin_tmp_tl } +\fp_new:N \l_coffin_calc_a_fp +\fp_new:N \l_coffin_calc_b_fp +\fp_new:N \l_coffin_calc_c_fp +\fp_new:N \l_coffin_calc_d_fp +\fp_new:N \l_coffin_calc_result_fp +\bool_new:N \l_coffin_error_bool +\dim_new:N \l_coffin_offset_x_dim +\dim_new:N \l_coffin_offset_y_dim +\tl_new:N \l_coffin_pole_a_tl +\tl_new:N \l_coffin_pole_b_tl +\fp_new:N \l_coffin_sin_fp +\fp_new:N \l_coffin_cos_fp +\dim_new:N \l_coffin_x_dim +\dim_new:N \l_coffin_y_dim +\dim_new:N \l_coffin_x_prime_dim +\dim_new:N \l_coffin_y_prime_dim +\fp_new:N \l_coffin_x_fp +\fp_new:N \l_coffin_y_fp +\fp_new:N \l_coffin_x_prime_fp +\fp_new:N \l_coffin_y_prime_fp +\dim_new:N \l_coffin_Depth_dim +\dim_new:N \l_coffin_Height_dim +\dim_new:N \l_coffin_TotalHeight_dim +\dim_new:N \l_coffin_Width_dim +\cs_new_nopar:Npn \coffin_saved_Depth: { } +\cs_new_nopar:Npn \coffin_saved_Height: { } +\cs_new_nopar:Npn \coffin_saved_TotalHeight: { } +\cs_new_nopar:Npn \coffin_saved_Width: { } +\cs_new_protected:Npn \coffin_if_exist:NT #1#2 + { + \cs_if_exist:NTF #1 + { + \cs_if_exist:cTF { l_coffin_poles_ \int_value:w #1 _prop } + { #2 } + { + \msg_kernel_error:nnx { coffin } { unknown-coffin } + { \token_to_str:N #1 } + } + } + { + \msg_kernel_error:nnx { coffin } { unknown-coffin } + { \token_to_str:N #1 } + } + } +\cs_new_protected_nopar:Npn \coffin_clear:N #1 + { + \coffin_if_exist:NT #1 + { + \box_clear:N #1 + \coffin_reset_structure:N #1 + } + } +\cs_generate_variant:Nn \coffin_clear:N { c } +\cs_new_protected_nopar:Npn \coffin_new:N #1 + { + \box_new:N #1 + \prop_clear_new:c { l_coffin_corners_ \int_value:w #1 _prop } + \prop_clear_new:c { l_coffin_poles_ \int_value:w #1 _prop } + \prop_gset_eq:cN { l_coffin_corners_ \int_value:w #1 _prop } + \c_coffin_corners_prop + \prop_gset_eq:cN { l_coffin_poles_ \int_value:w #1 _prop } + \c_coffin_poles_prop + } +\cs_generate_variant:Nn \coffin_new:N { c } +\cs_new_protected:Npn \hcoffin_set:Nn #1#2 + { + \coffin_if_exist:NT #1 + { + \hbox_set:Nn #1 + { + \group_begin: + \set@color + #2 + \group_end: + } + \coffin_reset_structure:N #1 + \coffin_update_poles:N #1 + \coffin_update_corners:N #1 + } + } +\cs_generate_variant:Nn \hcoffin_set:Nn { c } +\cs_new_protected:Npn \vcoffin_set:Nnn #1#2#3 + { + \coffin_if_exist:NT #1 + { + \vbox_set:Nn #1 + { + \dim_set:Nn \tex_hsize:D {#2} + \group_begin: + \set@color + #3 + \group_end: + } + \coffin_reset_structure:N #1 + \coffin_update_poles:N #1 + \coffin_update_corners:N #1 + \vbox_set_top:Nn \l_coffin_tmp_box { \vbox_unpack:N #1 } + \coffin_set_pole:Nnx #1 { T } + { + { 0 pt } + { \dim_eval:n { \box_ht:N #1 - \box_ht:N \l_coffin_tmp_box } } + { 1000 pt } + { 0 pt } + } + \box_clear:N \l_coffin_tmp_box + } + } +\cs_generate_variant:Nn \vcoffin_set:Nnn { c } +\cs_new_protected_nopar:Npn \coffin_set_eq:NN #1#2 + { + \coffin_if_exist:NT #1 + { + \box_set_eq:NN #1 #2 + \coffin_set_eq_structure:NN #1 #2 + } + } +\cs_generate_variant:Nn \coffin_set_eq:NN { c , Nc , cc } +\coffin_new:N \c_empty_coffin +\hbox_set:Nn \c_empty_coffin { } +\coffin_new:N \l_coffin_aligned_coffin +\coffin_new:N \l_coffin_aligned_internal_coffin +\cs_new_protected_nopar:Npn \coffin_get_pole:NnN #1#2#3 + { + \prop_get:cnNF + { l_coffin_poles_ \int_value:w #1 _prop } {#2} #3 + { + \msg_kernel_error:nnxx { coffin } { unknown-coffin-pole } + {#2} { \token_to_str:N #1 } + \tl_set:Nn #3 { { 0 pt } { 0 pt } { 0 pt } { 0 pt } } + } + } +\cs_new_protected_nopar:Npn \coffin_reset_structure:N #1 + { + \prop_set_eq:cN { l_coffin_corners_ \int_value:w #1 _prop } + \c_coffin_corners_prop + \prop_set_eq:cN { l_coffin_poles_ \int_value:w #1 _prop } + \c_coffin_poles_prop + } +\cs_new_protected_nopar:Npn \coffin_set_eq_structure:NN #1#2 + { + \prop_set_eq:cc { l_coffin_corners_ \int_value:w #1 _prop } + { l_coffin_corners_ \int_value:w #2 _prop } + \prop_set_eq:cc { l_coffin_poles_ \int_value:w #1 _prop } + { l_coffin_poles_ \int_value:w #2 _prop } + } +\cs_new_protected_nopar:Npn \coffin_set_user_dimensions:N #1 + { + \cs_set_eq:NN \coffin_saved_Height: \Height + \cs_set_eq:NN \coffin_saved_Depth: \Depth + \cs_set_eq:NN \coffin_saved_TotalHeight: \TotalHeight + \cs_set_eq:NN \coffin_saved_Width: \Width + \cs_set_eq:NN \Height \l_coffin_Height_dim + \cs_set_eq:NN \Depth \l_coffin_Depth_dim + \cs_set_eq:NN \TotalHeight \l_coffin_TotalHeight_dim + \cs_set_eq:NN \Width \l_coffin_Width_dim + \dim_set:Nn \Height { \box_ht:N #1 } + \dim_set:Nn \Depth { \box_dp:N #1 } + \dim_set:Nn \TotalHeight { \box_ht:N #1 - \box_dp:N #1 } + \dim_set:Nn \Width { \box_wd:N #1 } + } +\cs_new_protected_nopar:Npn \coffin_end_user_dimensions: + { + \cs_set_eq:NN \Height \coffin_saved_Height: + \cs_set_eq:NN \Depth \coffin_saved_Depth: + \cs_set_eq:NN \TotalHeight \coffin_saved_TotalHeight: + \cs_set_eq:NN \Width \coffin_saved_Width: + } +\cs_new_protected_nopar:Npn \coffin_set_horizontal_pole:Nnn #1#2#3 + { + \coffin_if_exist:NT #1 + { + \coffin_set_user_dimensions:N #1 + \coffin_set_pole:Nnx #1 {#2} + { + { 0 pt } { \dim_eval:n {#3} } + { 1000 pt } { 0 pt } + } + \coffin_end_user_dimensions: + } + } +\cs_new_protected_nopar:Npn \coffin_set_vertical_pole:Nnn #1#2#3 + { + \coffin_if_exist:NT #1 + { + \coffin_set_user_dimensions:N #1 + \coffin_set_pole:Nnx #1 {#2} + { + { \dim_eval:n {#3} } { 0 pt } + { 0 pt } { 1000 pt } + } + \coffin_end_user_dimensions: + } + } +\cs_new_protected_nopar:Npn \coffin_set_pole:Nnn #1#2#3 + { \prop_put:cnn { l_coffin_poles_ \int_value:w #1 _prop } {#2} {#3} } +\cs_generate_variant:Nn \coffin_set_horizontal_pole:Nnn { c } +\cs_generate_variant:Nn \coffin_set_vertical_pole:Nnn { c } +\cs_generate_variant:Nn \coffin_set_pole:Nnn { Nnx } +\cs_new_protected_nopar:Npn \coffin_update_corners:N #1 + { + \prop_put:cnx { l_coffin_corners_ \int_value:w #1 _prop } { tl } + { { 0 pt } { \dim_use:N \box_ht:N #1 } } + \prop_put:cnx { l_coffin_corners_ \int_value:w #1 _prop } { tr } + { { \dim_use:N \box_wd:N #1 } { \dim_use:N \box_ht:N #1 } } + \prop_put:cnx { l_coffin_corners_ \int_value:w #1 _prop } { bl } + { { 0 pt } { \dim_eval:n { - \box_dp:N #1 } } } + \prop_put:cnx { l_coffin_corners_ \int_value:w #1 _prop } { br } + { { \dim_use:N \box_wd:N #1 } { \dim_eval:n { - \box_dp:N #1 } } } + } +\cs_new_protected_nopar:Npn \coffin_update_poles:N #1 + { + \prop_put:cnx { l_coffin_poles_ \int_value:w #1 _prop } { hc } + { + { \dim_eval:n { 0.5 \box_wd:N #1 } } + { 0 pt } { 0 pt } { 1000 pt } + } + \prop_put:cnx { l_coffin_poles_ \int_value:w #1 _prop } { r } + { + { \dim_use:N \box_wd:N #1 } + { 0 pt } { 0 pt } { 1000 pt } + } + \prop_put:cnx { l_coffin_poles_ \int_value:w #1 _prop } { vc } + { + { 0 pt } + { \dim_eval:n { ( \box_ht:N #1 - \box_dp:N #1 ) / 2 } } + { 1000 pt } + { 0 pt } + } + \prop_put:cnx { l_coffin_poles_ \int_value:w #1 _prop } { t } + { + { 0 pt } + { \dim_use:N \box_ht:N #1 } + { 1000 pt } + { 0 pt } + } + \prop_put:cnx { l_coffin_poles_ \int_value:w #1 _prop } { b } + { + { 0 pt } + { \dim_eval:n { - \box_dp:N #1 } } + { 1000 pt } + { 0 pt } + } + } +\cs_new_protected_nopar:Npn \coffin_calculate_intersection:Nnn #1#2#3 + { + \coffin_get_pole:NnN #1 {#2} \l_coffin_pole_a_tl + \coffin_get_pole:NnN #1 {#3} \l_coffin_pole_b_tl + \bool_set_false:N \l_coffin_error_bool + \exp_last_two_unbraced:Noo + \coffin_calculate_intersection:nnnnnnnn + \l_coffin_pole_a_tl \l_coffin_pole_b_tl + \bool_if:NT \l_coffin_error_bool + { + \msg_kernel_error:nn { coffin } { no-pole-intersection } + \dim_zero:N \l_coffin_x_dim + \dim_zero:N \l_coffin_y_dim + } + } +\cs_new_protected_nopar:Npn \coffin_calculate_intersection:nnnnnnnn + #1#2#3#4#5#6#7#8 + { + \dim_compare:nNnTF {#3} = { \c_zero_dim } + { + \dim_set:Nn \l_coffin_x_dim {#1} + \dim_compare:nNnTF {#7} = \c_zero_dim + { \bool_set_true:N \l_coffin_error_bool } + { + \dim_compare:nNnTF {#8} = \c_zero_dim + { \dim_set:Nn \l_coffin_y_dim {#6} } + { + \coffin_calculate_intersection_aux:nnnnnN + {#1} {#5} {#6} {#7} {#8} \l_coffin_y_dim + } + } + } + { + \dim_compare:nNnTF {#4} = \c_zero_dim + { + \dim_set:Nn \l_coffin_y_dim {#2} + \dim_compare:nNnTF {#8} = { \c_zero_dim } + { \bool_set_true:N \l_coffin_error_bool } + { + \dim_compare:nNnTF {#7} = \c_zero_dim + { \dim_set:Nn \l_coffin_x_dim {#5} } + { + \coffin_calculate_intersection_aux:nnnnnN + {#2} {#6} {#5} {#8} {#7} \l_coffin_x_dim + } + } + } + { + \dim_compare:nNnTF {#7} = \c_zero_dim + { + \dim_set:Nn \l_coffin_x_dim {#5} + \coffin_calculate_intersection_aux:nnnnnN + {#5} {#1} {#2} {#3} {#4} \l_coffin_y_dim + } + { + \dim_compare:nNnTF {#8} = \c_zero_dim + { + \dim_set:Nn \l_coffin_x_dim {#6} + \coffin_calculate_intersection_aux:nnnnnN + {#6} {#2} {#1} {#4} {#3} \l_coffin_x_dim + } + { + \fp_set_from_dim:Nn \l_coffin_calc_a_fp {#3} + \fp_set_from_dim:Nn \l_coffin_calc_b_fp {#4} + \fp_set_from_dim:Nn \l_coffin_calc_c_fp {#7} + \fp_set_from_dim:Nn \l_coffin_calc_d_fp {#8} + \fp_div:Nn \l_coffin_calc_b_fp \l_coffin_calc_a_fp + \fp_div:Nn \l_coffin_calc_d_fp \l_coffin_calc_c_fp + \fp_compare:nNnTF + \l_coffin_calc_b_fp = \l_coffin_calc_d_fp + { \bool_set_true:N \l_coffin_error_bool } + { + \fp_set_from_dim:Nn \l_coffin_calc_result_fp {#6} + \fp_set_from_dim:Nn \l_coffin_calc_a_fp {#2} + \fp_sub:Nn \l_coffin_calc_result_fp + { \l_coffin_calc_a_fp } + \fp_set_from_dim:Nn \l_coffin_calc_a_fp {#1} + \fp_mul:Nn \l_coffin_calc_a_fp + { \l_coffin_calc_b_fp } + \fp_add:Nn \l_coffin_calc_result_fp + { \l_coffin_calc_a_fp } + \fp_set_from_dim:Nn \l_coffin_calc_a_fp {#5} + \fp_mul:Nn \l_coffin_calc_a_fp + { \l_coffin_calc_d_fp } + \fp_sub:Nn \l_coffin_calc_result_fp + { \l_coffin_calc_a_fp } + \fp_sub:Nn \l_coffin_calc_b_fp + { \l_coffin_calc_d_fp } + \fp_div:Nn \l_coffin_calc_result_fp + { \l_coffin_calc_b_fp } + \dim_set:Nn \l_coffin_x_dim + { \fp_to_dim:N \l_coffin_calc_result_fp } + \coffin_calculate_intersection_aux:nnnnnN + { \l_coffin_x_dim } + {#5} {#6} {#8} {#7} \l_coffin_y_dim + } + } + } + } + } + } +\cs_new_protected_nopar:Npn \coffin_calculate_intersection_aux:nnnnnN + #1#2#3#4#5#6 + { + \fp_set_from_dim:Nn \l_coffin_calc_result_fp {#1} + \fp_set_from_dim:Nn \l_coffin_calc_a_fp {#2} + \fp_set_from_dim:Nn \l_coffin_calc_b_fp {#3} + \fp_set_from_dim:Nn \l_coffin_calc_c_fp {#4} + \fp_set_from_dim:Nn \l_coffin_calc_d_fp {#5} + \fp_sub:Nn \l_coffin_calc_result_fp { \l_coffin_calc_a_fp } + \fp_div:Nn \l_coffin_calc_result_fp { \l_coffin_calc_d_fp } + \fp_mul:Nn \l_coffin_calc_result_fp { \l_coffin_calc_c_fp } + \fp_add:Nn \l_coffin_calc_result_fp { \l_coffin_calc_b_fp } + \dim_set:Nn #6 { \fp_to_dim:N \l_coffin_calc_result_fp } + } +\cs_new_protected_nopar:Npn \coffin_join:NnnNnnnn #1#2#3#4#5#6#7#8 + { + \coffin_align:NnnNnnnnN + #1 {#2} {#3} #4 {#5} {#6} {#7} {#8} \l_coffin_aligned_coffin + \hbox_set:Nn \l_coffin_aligned_coffin + { + \dim_compare:nNnT { \l_coffin_offset_x_dim } < \c_zero_dim + { \tex_kern:D -\l_coffin_offset_x_dim } + \hbox_unpack:N \l_coffin_aligned_coffin + \dim_set:Nn \l_coffin_tmp_dim + { \l_coffin_offset_x_dim - \box_wd:N #1 + \box_wd:N #4 } + \dim_compare:nNnT \l_coffin_tmp_dim < \c_zero_dim + { \tex_kern:D -\l_coffin_tmp_dim } + } + \coffin_reset_structure:N \l_coffin_aligned_coffin + \prop_clear:c + { l_coffin_corners_ \int_value:w \l_coffin_aligned_coffin _ prop } + \coffin_update_poles:N \l_coffin_aligned_coffin + \dim_compare:nNnTF \l_coffin_offset_x_dim < \c_zero_dim + { + \coffin_offset_poles:Nnn #1 { -\l_coffin_offset_x_dim } { 0 pt } + \coffin_offset_poles:Nnn #4 { 0 pt } { \l_coffin_offset_y_dim } + \coffin_offset_corners:Nnn #1 { -\l_coffin_offset_x_dim } { 0 pt } + \coffin_offset_corners:Nnn #4 { 0 pt } { \l_coffin_offset_y_dim } + } + { + \coffin_offset_poles:Nnn #1 { 0 pt } { 0 pt } + \coffin_offset_poles:Nnn #4 + { \l_coffin_offset_x_dim } { \l_coffin_offset_y_dim } + \coffin_offset_corners:Nnn #1 { 0 pt } { 0 pt } + \coffin_offset_corners:Nnn #4 + { \l_coffin_offset_x_dim } { \l_coffin_offset_y_dim } + } + \coffin_update_vertical_poles:NNN #1 #4 \l_coffin_aligned_coffin + \coffin_set_eq:NN #1 \l_coffin_aligned_coffin + } +\cs_generate_variant:Nn \coffin_join:NnnNnnnn { c , Nnnc , cnnc } +\cs_new_protected_nopar:Npn \coffin_attach:NnnNnnnn #1#2#3#4#5#6#7#8 + { + \coffin_align:NnnNnnnnN + #1 {#2} {#3} #4 {#5} {#6} {#7} {#8} \l_coffin_aligned_coffin + \box_set_ht:Nn \l_coffin_aligned_coffin { \box_ht:N #1 } + \box_set_dp:Nn \l_coffin_aligned_coffin { \box_dp:N #1 } + \box_set_wd:Nn \l_coffin_aligned_coffin { \box_wd:N #1 } + \coffin_reset_structure:N \l_coffin_aligned_coffin + \prop_set_eq:cc + { l_coffin_corners_ \int_value:w \l_coffin_aligned_coffin _prop } + { l_coffin_corners_ \int_value:w #1 _prop } + \coffin_update_poles:N \l_coffin_aligned_coffin + \coffin_offset_poles:Nnn #1 { 0 pt } { 0 pt } + \coffin_offset_poles:Nnn #4 + { \l_coffin_offset_x_dim } { \l_coffin_offset_y_dim } + \coffin_update_vertical_poles:NNN #1 #4 \l_coffin_aligned_coffin + \coffin_set_eq:NN #1 \l_coffin_aligned_coffin + } +\cs_new_protected_nopar:Npn \coffin_attach_mark:NnnNnnnn #1#2#3#4#5#6#7#8 + { + \coffin_align:NnnNnnnnN + #1 {#2} {#3} #4 {#5} {#6} {#7} {#8} \l_coffin_aligned_coffin + \box_set_ht:Nn \l_coffin_aligned_coffin { \box_ht:N #1 } + \box_set_dp:Nn \l_coffin_aligned_coffin { \box_dp:N #1 } + \box_set_wd:Nn \l_coffin_aligned_coffin { \box_wd:N #1 } + \box_set_eq:NN #1 \l_coffin_aligned_coffin + } +\cs_generate_variant:Nn \coffin_attach:NnnNnnnn { c , Nnnc , cnnc } +\cs_new_protected_nopar:Npn \coffin_align:NnnNnnnnN #1#2#3#4#5#6#7#8#9 + { + \coffin_calculate_intersection:Nnn #4 {#5} {#6} + \dim_set:Nn \l_coffin_x_prime_dim { \l_coffin_x_dim } + \dim_set:Nn \l_coffin_y_prime_dim { \l_coffin_y_dim } + \coffin_calculate_intersection:Nnn #1 {#2} {#3} + \dim_set:Nn \l_coffin_offset_x_dim + { \l_coffin_x_dim - \l_coffin_x_prime_dim + #7 } + \dim_set:Nn \l_coffin_offset_y_dim + { \l_coffin_y_dim - \l_coffin_y_prime_dim + #8 } + \hbox_set:Nn \l_coffin_aligned_internal_coffin + { + \box_use:N #1 + \tex_kern:D -\box_wd:N #1 + \tex_kern:D \l_coffin_offset_x_dim + \box_move_up:nn { \l_coffin_offset_y_dim } { \box_use:N #4 } + } + \coffin_set_eq:NN #9 \l_coffin_aligned_internal_coffin + } +\cs_new_protected_nopar:Npn \coffin_offset_poles:Nnn #1#2#3 + { + \prop_map_inline:cn { l_coffin_poles_ \int_value:w #1 _prop } + { \coffin_offset_pole:Nnnnnnn #1 {##1} ##2 {#2} {#3} } + } +\cs_new_protected_nopar:Npn \coffin_offset_pole:Nnnnnnn #1#2#3#4#5#6#7#8 + { + \dim_set:Nn \l_coffin_x_dim { #3 + #7 } + \dim_set:Nn \l_coffin_y_dim { #4 + #8 } + \tl_if_in:nnTF {#2} { - } + { \tl_set:Nn \l_coffin_tmp_tl { {#2} } } + { \tl_set:Nn \l_coffin_tmp_tl { { #1 - #2 } } } + \exp_last_unbraced:NNo \coffin_set_pole:Nnx \l_coffin_aligned_coffin + { \l_coffin_tmp_tl } + { + { \dim_use:N \l_coffin_x_dim } { \dim_use:N \l_coffin_y_dim } + {#5} {#6} + } + } +\cs_new_protected_nopar:Npn \coffin_offset_corners:Nnn #1#2#3 + { + \prop_map_inline:cn { l_coffin_corners_ \int_value:w #1 _prop } + { \coffin_offset_corner:Nnnnn #1 {##1} ##2 {#2} {#3} } + } +\cs_new_protected_nopar:Npn \coffin_offset_corner:Nnnnn #1#2#3#4#5#6 + { + \prop_put:cnx + { l_coffin_corners_ \int_value:w \l_coffin_aligned_coffin _prop } + { #1 - #2 } + { + { \dim_eval:n { #3 + #5 } } + { \dim_eval:n { #4 + #6 } } + } + } +\cs_new_protected_nopar:Npn \coffin_update_vertical_poles:NNN #1#2#3 + { + \coffin_get_pole:NnN #3 { #1 -T } \l_coffin_pole_a_tl + \coffin_get_pole:NnN #3 { #2 -T } \l_coffin_pole_b_tl + \exp_last_two_unbraced:Noo \coffin_update_T:nnnnnnnnN + \l_coffin_pole_a_tl \l_coffin_pole_b_tl #3 + \coffin_get_pole:NnN #3 { #1 -B } \l_coffin_pole_a_tl + \coffin_get_pole:NnN #3 { #2 -B } \l_coffin_pole_b_tl + \exp_last_two_unbraced:Noo \coffin_update_B:nnnnnnnnN + \l_coffin_pole_a_tl \l_coffin_pole_b_tl #3 + } +\cs_new_protected_nopar:Npn \coffin_update_T:nnnnnnnnN #1#2#3#4#5#6#7#8#9 + { + \dim_compare:nNnTF {#2} < {#6} + { + \coffin_set_pole:Nnx #9 { T } + { { 0 pt } {#6} { 1000 pt } { 0 pt } } + } + { + \coffin_set_pole:Nnx #9 { T } + { { 0 pt } {#2} { 1000 pt } { 0 pt } } + } + } +\cs_new_protected_nopar:Npn \coffin_update_B:nnnnnnnnN #1#2#3#4#5#6#7#8#9 + { + \dim_compare:nNnTF {#2} < {#6} + { + \coffin_set_pole:Nnx #9 { B } + { { 0 pt } {#2} { 1000 pt } { 0 pt } } + } + { + \coffin_set_pole:Nnx #9 { B } + { { 0 pt } {#6} { 1000 pt } { 0 pt } } + } + } +\cs_new_protected_nopar:Npn \coffin_typeset:Nnnnn #1#2#3#4#5 + { + \coffin_align:NnnNnnnnN \c_empty_coffin { H } { l } + #1 {#2} {#3} {#4} {#5} \l_coffin_aligned_coffin + \hbox_set:Nn \l_coffin_aligned_coffin + { + \dim_compare:nNnT { \l_coffin_offset_x_dim } < \c_zero_dim + { \tex_kern:D -\l_coffin_offset_x_dim } + \hbox_unpack:N \l_coffin_aligned_coffin + \dim_set:Nn \l_coffin_tmp_dim + { \l_coffin_offset_x_dim + \box_wd:N #1 } + \dim_compare:nNnT { \l_coffin_tmp_dim } < \c_zero_dim + { \tex_kern:D -\l_coffin_tmp_dim } + } + \hbox_unpack:N \c_empty_box + \box_use:N \l_coffin_aligned_coffin + } +\cs_generate_variant:Nn \coffin_typeset:Nnnnn { c } +\prop_new:N \l_coffin_bounding_prop +\dim_new:N \l_coffin_bounding_shift_dim +\dim_new:N \l_coffin_left_corner_dim +\dim_new:N \l_coffin_right_corner_dim +\dim_new:N \l_coffin_bottom_corner_dim +\dim_new:N \l_coffin_top_corner_dim +\cs_new_protected_nopar:Npn \coffin_rotate:Nn #1#2 + { + \fp_set:Nn \l_coffin_tmp_fp {#2} + \fp_div:Nn \l_coffin_tmp_fp { 180 } + \fp_mul:Nn \l_coffin_tmp_fp { \c_pi_fp } + \fp_sin:Nn \l_coffin_sin_fp { \l_coffin_tmp_fp } + \fp_cos:Nn \l_coffin_cos_fp { \l_coffin_tmp_fp } + \prop_map_inline:cn { l_coffin_corners_ \int_value:w #1 _prop } + { \coffin_rotate_corner:Nnnn #1 {##1} ##2 } + \prop_map_inline:cn { l_coffin_poles_ \int_value:w #1 _prop } + { \coffin_rotate_pole:Nnnnnn #1 {##1} ##2 } + \coffin_set_bounding:N #1 + \prop_map_inline:Nn \l_coffin_bounding_prop + { \coffin_rotate_bounding:nnn {##1} ##2 } + \coffin_find_corner_maxima:N #1 + \coffin_find_bounding_shift: + \hbox_set:Nn #1 { \rotatebox {#2} { \box_use:N #1 } } + \hbox_set:Nn #1 + { + \tex_kern:D \l_coffin_bounding_shift_dim + \tex_kern:D -\l_coffin_left_corner_dim + \box_move_down:nn { \l_coffin_bottom_corner_dim } + { \box_use:N #1 } + } + \box_set_ht:Nn #1 + { \l_coffin_top_corner_dim - \l_coffin_bottom_corner_dim } + \box_set_dp:Nn #1 { 0 pt } + \box_set_wd:Nn #1 + { \l_coffin_right_corner_dim - \l_coffin_left_corner_dim } + \prop_map_inline:cn { l_coffin_corners_ \int_value:w #1 _prop } + { \coffin_shift_corner:Nnnn #1 {##1} ##2 } + \prop_map_inline:cn { l_coffin_poles_ \int_value:w #1 _prop } + { \coffin_shift_pole:Nnnnnn #1 {##1} ##2 } + } +\cs_generate_variant:Nn \coffin_rotate:Nn { c } +\cs_new_protected_nopar:Npn \coffin_set_bounding:N #1 + { + \prop_put:Nnx \l_coffin_bounding_prop { tl } + { { 0 pt } { \dim_use:N \box_ht:N #1 } } + \prop_put:Nnx \l_coffin_bounding_prop { tr } + { { \dim_use:N \box_wd:N #1 } { \dim_use:N \box_ht:N #1 } } + \dim_set:Nn \l_coffin_tmp_dim { - \box_dp:N #1 } + \prop_put:Nnx \l_coffin_bounding_prop { bl } + { { 0 pt } { \dim_use:N \l_coffin_tmp_dim } } + \prop_put:Nnx \l_coffin_bounding_prop { br } + { { \dim_use:N \box_wd:N #1 } { \dim_use:N \l_coffin_tmp_dim } } + } +\cs_new_protected_nopar:Npn \coffin_rotate_bounding:nnn #1#2#3 + { + \coffin_rotate_vector:nnNN {#2} {#3} \l_coffin_x_dim \l_coffin_y_dim + \prop_put:Nnx \l_coffin_bounding_prop {#1} + { { \dim_use:N \l_coffin_x_dim } { \dim_use:N \l_coffin_y_dim } } + } +\cs_new_protected_nopar:Npn \coffin_rotate_corner:Nnnn #1#2#3#4 + { + \coffin_rotate_vector:nnNN {#3} {#4} \l_coffin_x_dim \l_coffin_y_dim + \prop_put:cnx { l_coffin_corners_ \int_value:w #1 _prop } {#2} + { { \dim_use:N \l_coffin_x_dim } { \dim_use:N \l_coffin_y_dim } } + } +\cs_new_protected_nopar:Npn \coffin_rotate_pole:Nnnnnn #1#2#3#4#5#6 + { + \coffin_rotate_vector:nnNN {#3} {#4} \l_coffin_x_dim \l_coffin_y_dim + \coffin_rotate_vector:nnNN {#5} {#6} + \l_coffin_x_prime_dim \l_coffin_y_prime_dim + \coffin_set_pole:Nnx #1 {#2} + { + { \dim_use:N \l_coffin_x_dim } { \dim_use:N \l_coffin_y_dim } + { \dim_use:N \l_coffin_x_prime_dim } + { \dim_use:N \l_coffin_y_prime_dim } + } + } +\cs_new_protected_nopar:Npn \coffin_rotate_vector:nnNN #1#2#3#4 + { + \fp_set_from_dim:Nn \l_coffin_x_fp {#1} + \fp_set_from_dim:Nn \l_coffin_y_fp {#2} + \fp_set_eq:NN \l_coffin_x_prime_fp \l_coffin_x_fp + \fp_set_eq:NN \l_coffin_tmp_fp \l_coffin_y_fp + \fp_mul:Nn \l_coffin_x_prime_fp { \l_coffin_cos_fp } + \fp_mul:Nn \l_coffin_tmp_fp { \l_coffin_sin_fp } + \fp_sub:Nn \l_coffin_x_prime_fp { \l_coffin_tmp_fp } + \fp_set_eq:NN \l_coffin_y_prime_fp \l_coffin_y_fp + \fp_set_eq:NN \l_coffin_tmp_fp \l_coffin_x_fp + \fp_mul:Nn \l_coffin_y_prime_fp { \l_coffin_cos_fp } + \fp_mul:Nn \l_coffin_tmp_fp { \l_coffin_sin_fp } + \fp_add:Nn \l_coffin_y_prime_fp { \l_coffin_tmp_fp } + \dim_set:Nn #3 { \fp_to_dim:N \l_coffin_x_prime_fp } + \dim_set:Nn #4 { \fp_to_dim:N \l_coffin_y_prime_fp } + } +\cs_new_protected_nopar:Npn \coffin_find_corner_maxima:N #1 + { + \dim_set:Nn \l_coffin_top_corner_dim { -\c_max_dim } + \dim_set:Nn \l_coffin_right_corner_dim { -\c_max_dim } + \dim_set:Nn \l_coffin_bottom_corner_dim { \c_max_dim } + \dim_set:Nn \l_coffin_left_corner_dim { \c_max_dim } + \prop_map_inline:cn { l_coffin_corners_ \int_value:w #1 _prop } + { \coffin_find_corner_maxima_aux:nn ##2 } + } +\cs_new_protected_nopar:Npn \coffin_find_corner_maxima_aux:nn #1#2 + { + \dim_set_min:Nn \l_coffin_left_corner_dim {#1} + \dim_set_max:Nn \l_coffin_right_corner_dim {#1} + \dim_set_min:Nn \l_coffin_bottom_corner_dim {#2} + \dim_set_max:Nn \l_coffin_top_corner_dim {#2} + } +\cs_new_protected_nopar:Npn \coffin_find_bounding_shift: + { + \dim_set:Nn \l_coffin_bounding_shift_dim { \c_max_dim } + \prop_map_inline:Nn \l_coffin_bounding_prop + { \coffin_find_bounding_shift_aux:nn ##2 } + } +\cs_new_protected_nopar:Npn \coffin_find_bounding_shift_aux:nn #1#2 + { \dim_set_min:Nn \l_coffin_bounding_shift_dim {#1} } +\cs_new_protected_nopar:Npn \coffin_shift_corner:Nnnn #1#2#3#4 + { + \prop_put:cnx { l_coffin_corners_ \int_value:w #1 _ prop } {#2} + { + { \dim_eval:n { #3 - \l_coffin_left_corner_dim } } + { \dim_eval:n { #4 - \l_coffin_bottom_corner_dim } } + } + } +\cs_new_protected_nopar:Npn \coffin_shift_pole:Nnnnnn #1#2#3#4#5#6 + { + \prop_put:cnx { l_coffin_poles_ \int_value:w #1 _ prop } {#2} + { + { \dim_eval:n { #3 - \l_coffin_left_corner_dim } } + { \dim_eval:n { #4 - \l_coffin_bottom_corner_dim } } + {#5} {#6} + } + } +\coffin_new:N \l_coffin_display_coffin +\coffin_new:N \l_coffin_display_coord_coffin +\coffin_new:N \l_coffin_display_pole_coffin +\prop_new:N \l_coffin_display_handles_prop +\prop_put:Nnn \l_coffin_display_handles_prop { tl } + { { b } { r } { -1 } { 1 } } +\prop_put:Nnn \l_coffin_display_handles_prop { thc } + { { b } { hc } { 0 } { 1 } } +\prop_put:Nnn \l_coffin_display_handles_prop { tr } + { { b } { l } { 1 } { 1 } } +\prop_put:Nnn \l_coffin_display_handles_prop { vcl } + { { vc } { r } { -1 } { 0 } } +\prop_put:Nnn \l_coffin_display_handles_prop { vchc } + { { vc } { hc } { 0 } { 0 } } +\prop_put:Nnn \l_coffin_display_handles_prop { vcr } + { { vc } { l } { 1 } { 0 } } +\prop_put:Nnn \l_coffin_display_handles_prop { bl } + { { t } { r } { -1 } { -1 } } +\prop_put:Nnn \l_coffin_display_handles_prop { bhc } + { { t } { hc } { 0 } { -1 } } +\prop_put:Nnn \l_coffin_display_handles_prop { br } + { { t } { l } { 1 } { -1 } } +\prop_put:Nnn \l_coffin_display_handles_prop { Tl } + { { t } { r } { -1 } { -1 } } +\prop_put:Nnn \l_coffin_display_handles_prop { Thc } + { { t } { hc } { 0 } { -1 } } +\prop_put:Nnn \l_coffin_display_handles_prop { Tr } + { { t } { l } { 1 } { -1 } } +\prop_put:Nnn \l_coffin_display_handles_prop { Hl } + { { vc } { r } { -1 } { 1 } } +\prop_put:Nnn \l_coffin_display_handles_prop { Hhc } + { { vc } { hc } { 0 } { 1 } } +\prop_put:Nnn \l_coffin_display_handles_prop { Hr } + { { vc } { l } { 1 } { 1 } } +\prop_put:Nnn \l_coffin_display_handles_prop { Bl } + { { b } { r } { -1 } { -1 } } +\prop_put:Nnn \l_coffin_display_handles_prop { Bhc } + { { b } { hc } { 0 } { -1 } } +\prop_put:Nnn \l_coffin_display_handles_prop { Br } + { { b } { l } { 1 } { -1 } } +\dim_new:N \l_coffin_display_offset_dim +\dim_set:Nn \l_coffin_display_offset_dim { 2 pt } +\dim_new:N \l_coffin_display_x_dim +\dim_new:N \l_coffin_display_y_dim +\prop_new:N \l_coffin_display_poles_prop +\tl_new:N \l_coffin_display_font_tl +\tl_set:Nn \l_coffin_display_font_tl { \sffamily \tiny } +\prop_new:N \l_coffin_handles_tmp_prop +\cs_new_protected_nopar:Npn \coffin_mark_handle:Nnnn #1#2#3#4 + { + \hcoffin_set:Nn \l_coffin_display_pole_coffin + { + \color {#4} + \rule { 1 pt } { 1 pt } + } + \coffin_attach_mark:NnnNnnnn #1 {#2} {#3} + \l_coffin_display_pole_coffin { hc } { vc } { 0 pt } { 0 pt } + \hcoffin_set:Nn \l_coffin_display_coord_coffin + { + \color {#4} + \l_coffin_display_font_tl + ( \tl_to_str:n { #2 , #3 } ) + } + \prop_get:NnN \l_coffin_display_handles_prop + { #2 #3 } \l_coffin_tmp_tl + \quark_if_no_value:NTF \l_coffin_tmp_tl + { + \prop_get:NnN \l_coffin_display_handles_prop + { #3 #2 } \l_coffin_tmp_tl + \quark_if_no_value:NTF \l_coffin_tmp_tl + { + \coffin_attach_mark:NnnNnnnn #1 {#2} {#3} + \l_coffin_display_coord_coffin { l } { vc } + { 1 pt } { 0 pt } + } + { + \exp_last_unbraced:No \coffin_mark_handle_aux:nnnnNnn + \l_coffin_tmp_tl #1 {#2} {#3} + } + } + { + \exp_last_unbraced:No \coffin_mark_handle_aux:nnnnNnn + \l_coffin_tmp_tl #1 {#2} {#3} + } + } +\cs_new_protected_nopar:Npn \coffin_mark_handle_aux:nnnnNnn #1#2#3#4#5#6#7 + { + \coffin_attach_mark:NnnNnnnn #5 {#6} {#7} + \l_coffin_display_coord_coffin {#1} {#2} + { #3 \l_coffin_display_offset_dim } + { #4 \l_coffin_display_offset_dim } + } +\cs_generate_variant:Nn \coffin_mark_handle:Nnnn { c } +\cs_new_protected_nopar:Npn \coffin_display_handles:Nn #1#2 + { + \hcoffin_set:Nn \l_coffin_display_pole_coffin + { + \color {#2} + \rule { 1 pt } { 1 pt } + } + \prop_set_eq:Nc \l_coffin_display_poles_prop + { l_coffin_poles_ \int_value:w #1 _prop } + \coffin_get_pole:NnN #1 { H } \l_coffin_pole_a_tl + \coffin_get_pole:NnN #1 { T } \l_coffin_pole_b_tl + \tl_if_eq:NNT \l_coffin_pole_a_tl \l_coffin_pole_b_tl + { \prop_del:Nn \l_coffin_display_poles_prop { T } } + \coffin_get_pole:NnN #1 { B } \l_coffin_pole_b_tl + \tl_if_eq:NNT \l_coffin_pole_a_tl \l_coffin_pole_b_tl + { \prop_del:Nn \l_coffin_display_poles_prop { B } } + \coffin_set_eq:NN \l_coffin_display_coffin #1 + \prop_clear:N \l_coffin_handles_tmp_prop + \prop_map_inline:Nn \l_coffin_display_poles_prop + { + \prop_del:Nn \l_coffin_display_poles_prop {##1} + \coffin_display_handles_aux:nnnnnn {##1} ##2 {#2} + } + \box_use:N \l_coffin_display_coffin + } +\cs_new_protected_nopar:Npn \coffin_display_handles_aux:nnnnnn #1#2#3#4#5#6 + { + \prop_map_inline:Nn \l_coffin_display_poles_prop + { + \bool_set_false:N \l_coffin_error_bool + \coffin_calculate_intersection:nnnnnnnn {#2} {#3} {#4} {#5} ##2 + \bool_if:NF \l_coffin_error_bool + { + \dim_set:Nn \l_coffin_display_x_dim { \l_coffin_x_dim } + \dim_set:Nn \l_coffin_display_y_dim { \l_coffin_y_dim } + \coffin_display_attach:Nnnnn + \l_coffin_display_pole_coffin { hc } { vc } + { 0 pt } { 0 pt } + \hcoffin_set:Nn \l_coffin_display_coord_coffin + { + \color {#6} + \l_coffin_display_font_tl + ( \tl_to_str:n { #1 , ##1 } ) + } + \prop_get:NnN \l_coffin_display_handles_prop + { #1 ##1 } \l_coffin_tmp_tl + \quark_if_no_value:NTF \l_coffin_tmp_tl + { + \prop_get:NnN \l_coffin_display_handles_prop + { ##1 #1 } \l_coffin_tmp_tl + \quark_if_no_value:NTF \l_coffin_tmp_tl + { + \coffin_display_attach:Nnnnn + \l_coffin_display_coord_coffin { l } { vc } + { 1 pt } { 0 pt } + } + { + \exp_last_unbraced:No + \coffin_display_handles_aux:nnnn + \l_coffin_tmp_tl + } + } + { + \exp_last_unbraced:No \coffin_display_handles_aux:nnnn + \l_coffin_tmp_tl + } + } + } + } +\cs_new_protected_nopar:Npn \coffin_display_handles_aux:nnnn #1#2#3#4 + { + \coffin_display_attach:Nnnnn + \l_coffin_display_coord_coffin {#1} {#2} + { #3 \l_coffin_display_offset_dim } + { #4 \l_coffin_display_offset_dim } + } +\cs_generate_variant:Nn \coffin_display_handles:Nn { c } +\cs_new_protected_nopar:Npn \coffin_display_attach:Nnnnn #1#2#3#4#5 + { + \coffin_calculate_intersection:Nnn #1 {#2} {#3} + \dim_set:Nn \l_coffin_x_prime_dim { \l_coffin_x_dim } + \dim_set:Nn \l_coffin_y_prime_dim { \l_coffin_y_dim } + \dim_set:Nn \l_coffin_offset_x_dim + { \l_coffin_display_x_dim - \l_coffin_x_prime_dim + #4 } + \dim_set:Nn \l_coffin_offset_y_dim + { \l_coffin_display_y_dim - \l_coffin_y_prime_dim + #5 } + \hbox_set:Nn \l_coffin_aligned_coffin + { + \box_use:N \l_coffin_display_coffin + \tex_kern:D -\box_wd:N \l_coffin_display_coffin + \tex_kern:D \l_coffin_offset_x_dim + \box_move_up:nn { \l_coffin_offset_y_dim } { \box_use:N #1 } + } + \box_set_ht:Nn \l_coffin_aligned_coffin + { \box_ht:N \l_coffin_display_coffin } + \box_set_dp:Nn \l_coffin_aligned_coffin + { \box_dp:N \l_coffin_display_coffin } + \box_set_wd:Nn \l_coffin_aligned_coffin + { \box_wd:N \l_coffin_display_coffin } + \box_set_eq:NN \l_coffin_display_coffin \l_coffin_aligned_coffin + } +\cs_new_protected_nopar:Npn \coffin_show_structure:N #1 + { + \cs_if_exist:cTF { l_coffin_poles_ \int_value:w #1 _prop } + { + \iow_term:x + { + \iow_newline: + Size~of~coffin~\token_to_str:N #1 : \iow_newline: + > ~ ht~=~\dim_use:N \box_ht:N #1 \iow_newline: + > ~ dp~=~\dim_use:N \box_dp:N #1 \iow_newline: + > ~ wd~=~\dim_use:N \box_wd:N #1 \iow_newline: + } + \iow_term:x { Poles~of~coffin~\token_to_str:N #1 : } + \tl_set:Nx \l_coffin_tmp_tl + { + \prop_map_function:cN + { l_coffin_poles_ \int_value:w #1 _prop } + \coffin_show_aux:nn + } + \etex_showtokens:D \exp_after:wN \exp_after:wN \exp_after:wN + { \exp_after:wN \coffin_show_aux:w \l_coffin_tmp_tl } + } + { + \iow_term:x { ---~No~poles~found~--- } + \tl_show:n { Is~this~really~a~coffin? } + } + } +\cs_new:Npn \coffin_show_aux:nn #1#2 + { + \iow_newline: > \c_space_tl \c_space_tl + #1 \c_space_tl \c_space_tl => \c_space_tl \c_space_tl \exp_not:n {#2} + } +\cs_new_nopar:Npn \coffin_show_aux:w #1 > ~ { } +\cs_generate_variant:Nn \coffin_show_structure:N { c } +\msg_kernel_new:nnnn { coffin } { no-pole-intersection } + { No~intersection~between~coffin~poles. } + { + \c_msg_coding_error_text_tl + LaTeX~was~asked~to~find~the~intersection~between~two~poles,~ + but~they~do~not~have~a~unique~meeting~point:~ + the~value~(0~pt,~0~pt)~will~be~used. + } +\msg_kernel_new:nnnn { coffin } { unknown-coffin } + { Unknown~coffin~'#1'. } + { The~coffin~'#1'~was~never~defined. } +\msg_kernel_new:nnnn { coffin } { unknown-coffin-pole } + { Pole~'#1'~unknown~for~coffin~'#2'. } + { + \c_msg_coding_error_text_tl + LaTeX~was~asked~to~find~a~typesetting~pole~for~a~coffin,~ + but~either~the~coffin~does~not~exist~or~the~pole~name~is~wrong. + } +%% +%% +%% End of file `l3coffins.sty'. diff --git a/Master/texmf-dist/tex/latex/l3kernel/l3doc.cls b/Master/texmf-dist/tex/latex/l3kernel/l3doc.cls index 8f91c9a54f6..e7c0b14659e 100644 --- a/Master/texmf-dist/tex/latex/l3kernel/l3doc.cls +++ b/Master/texmf-dist/tex/latex/l3kernel/l3doc.cls @@ -6,6 +6,7 @@ %% %% l3doc.dtx (with options: `class') %% +%% %% EXPERIMENTAL CODE %% %% Do not distribute this file without also distributing the @@ -13,6 +14,7 @@ %% %% Do not distribute a modified version of this file. %% +%% %% File: l3doc.dtx Copyright (C) 1990-2011 The LaTeX3 project %% %% It may be distributed and/or modified under the conditions of the @@ -50,7 +52,7 @@ \let \filedateOld \ExplFileDate \let \fileversionOld \ExplFileVersion \let \filedescriptionOld \ExplFileDescription -\GetIdInfo$Id: l3doc.dtx 2601 2011-08-16 23:20:27Z bruno $ +\GetIdInfo$Id: l3doc.dtx 2674 2011-08-27 19:43:44Z mittelba $ {L3 Experimental documentation class} \ProvidesExplClass {\ExplFileName}{\ExplFileDate}{\ExplFileVersion}{\ExplFileDescription} @@ -64,7 +66,7 @@ Frank~Mittelbach,~Denys~Duchier,~Chris~Rowley,~ Rainer~Sch\"opf,~Johannes~Braams,~Michael~Downes,~ David~Carlisle,~Alan~Jeffrey,~Morten~H\o{}gholm,~Thomas~Lotze,~ - Javier~Bezos,~Will~Robertson,~Joseph~Wright}} + Javier~Bezos,~Will~Robertson,~Joseph~Wright,~Bruno~Le~Floch}} \DeclareOption{a5paper}{\@latexerr{Option not supported}{}} \bool_new:N \g_doc_full_bool \bool_new:N \g_doc_lmodern_bool @@ -136,6 +138,22 @@ \setlength \parindent { 0pt } \setlength \itemindent { 0pt } \setlength \parskip { \medskipamount } +\cs_set_nopar:Npn \l@section #1#2 { + \ifnum \c@tocdepth >\z@ + \addpenalty\@secpenalty + \addvspace{1.0em \@plus\p@} + \setlength\@tempdima{2.5em} % was 1.5em + \begingroup + \parindent \z@ \rightskip \@pnumwidth + \parfillskip -\@pnumwidth + \leavevmode \bfseries + \advance\leftskip\@tempdima + \hskip -\leftskip + #1\nobreak\hfil \nobreak\hb@xt@\@pnumwidth{\hss #2}\par + \endgroup + \fi} +\cs_set_nopar:Npn\l@subsection{\@dottedtocline{2}{2.5em}{2.3em}} % #2 = 1.5em + \AtBeginDocument { \MakeShortVerb \" \MakeShortVerb \| diff --git a/Master/texmf-dist/tex/latex/l3kernel/l3file.sty b/Master/texmf-dist/tex/latex/l3kernel/l3file.sty index e8272cde35f..a0c3041c822 100644 --- a/Master/texmf-dist/tex/latex/l3kernel/l3file.sty +++ b/Master/texmf-dist/tex/latex/l3kernel/l3file.sty @@ -46,7 +46,7 @@ %% %% ----------------------------------------------------------------------- \RequirePackage{l3names} -\GetIdInfo$Id: l3file.dtx 2478 2011-06-19 21:34:23Z joseph $ +\GetIdInfo$Id: l3file.dtx 2665 2011-08-25 22:15:27Z joseph $ {L3 Experimental file operations} \ProvidesExplPackage {\ExplFileName}{\ExplFileDate}{\ExplFileVersion}{\ExplFileDescription} diff --git a/Master/texmf-dist/tex/latex/l3kernel/l3fp.sty b/Master/texmf-dist/tex/latex/l3kernel/l3fp.sty index d3f98d4353a..ae8c42f0e1e 100644 --- a/Master/texmf-dist/tex/latex/l3kernel/l3fp.sty +++ b/Master/texmf-dist/tex/latex/l3kernel/l3fp.sty @@ -46,7 +46,7 @@ %% %% ----------------------------------------------------------------------- \RequirePackage{l3names} -\GetIdInfo$Id: l3fp.dtx 2478 2011-06-19 21:34:23Z joseph $ +\GetIdInfo$Id: l3fp.dtx 2665 2011-08-25 22:15:27Z joseph $ {L3 Experimental floating-point operations} \ProvidesExplPackage {\ExplFileName}{\ExplFileDate}{\ExplFileVersion}{\ExplFileDescription} diff --git a/Master/texmf-dist/tex/latex/l3kernel/l3int.sty b/Master/texmf-dist/tex/latex/l3kernel/l3int.sty index 070c9a3a6e6..26c0e19a66b 100644 --- a/Master/texmf-dist/tex/latex/l3kernel/l3int.sty +++ b/Master/texmf-dist/tex/latex/l3kernel/l3int.sty @@ -46,7 +46,7 @@ %% %% ----------------------------------------------------------------------- \RequirePackage{l3names} -\GetIdInfo$Id: l3int.dtx 2600 2011-08-16 22:31:24Z bruno $ +\GetIdInfo$Id: l3int.dtx 2666 2011-08-26 06:10:09Z joseph $ {L3 Experimental integers} \ProvidesExplPackage {\ExplFileName}{\ExplFileDate}{\ExplFileVersion}{\ExplFileDescription} diff --git a/Master/texmf-dist/tex/latex/l3kernel/l3io.sty b/Master/texmf-dist/tex/latex/l3kernel/l3io.sty index b3ae494e9fb..c46f6d3deee 100644 --- a/Master/texmf-dist/tex/latex/l3kernel/l3io.sty +++ b/Master/texmf-dist/tex/latex/l3kernel/l3io.sty @@ -46,7 +46,7 @@ %% %% ----------------------------------------------------------------------- \RequirePackage{l3names} -\GetIdInfo$Id: l3io.dtx 2595 2011-08-16 00:58:34Z bruno $ +\GetIdInfo$Id: l3io.dtx 2665 2011-08-25 22:15:27Z joseph $ {L3 Experimental input-output operations} \ProvidesExplPackage {\ExplFileName}{\ExplFileDate}{\ExplFileVersion}{\ExplFileDescription} diff --git a/Master/texmf-dist/tex/latex/l3kernel/l3keys.sty b/Master/texmf-dist/tex/latex/l3kernel/l3keys.sty index 749a5791777..434ba050077 100644 --- a/Master/texmf-dist/tex/latex/l3kernel/l3keys.sty +++ b/Master/texmf-dist/tex/latex/l3kernel/l3keys.sty @@ -46,11 +46,134 @@ %% %% ----------------------------------------------------------------------- \RequirePackage{l3names} -\GetIdInfo$Id: l3keys.dtx 2568 2011-08-14 05:03:32Z bruno $ +\GetIdInfo$Id: l3keys.dtx 2677 2011-08-28 06:54:22Z joseph $ {L3 Experimental key-value interfaces} \ProvidesExplPackage {\ExplFileName}{\ExplFileDate}{\ExplFileVersion}{\ExplFileDescription} \package_check_loaded_expl: +\int_new:N \g_keyval_level_int +\tl_new:N \l_keyval_key_tl +\tl_new:N \l_keyval_value_tl +\tl_new:N \l_keyval_sanitise_tl +\tl_new:N \l_keyval_parse_tl +\group_begin: + \char_set_catcode_active:n { `\= } + \char_set_catcode_active:n { `\, } + \char_set_lccode:nn { `\8 } { `\= } + \char_set_lccode:nn { `\9 } { `\, } +\tl_to_lowercase:n + { + \group_end: + \cs_new_protected:Npn \keyval_parse:n #1 + { + \group_begin: + \tl_clear:N \l_keyval_sanitise_tl + \tl_set:Nn \l_keyval_sanitise_tl {#1} + \tl_replace_all:Nnn \l_keyval_sanitise_tl { = } { 8 } + \tl_replace_all:Nnn \l_keyval_sanitise_tl { , } { 9 } + \tl_clear:N \l_keyval_parse_tl + \exp_after:wN \keyval_parse_elt:w \exp_after:wN + \q_no_value \l_keyval_sanitise_tl 9 \q_nil 9 + \exp_after:wN \group_end: + \l_keyval_parse_tl + } + } +\cs_new_protected:Npn \keyval_parse_elt:w #1 , + { + \tl_if_blank:oTF { \use_none:n #1 } + { \keyval_parse_elt:w \q_no_value } + { + \quark_if_nil:oF { \use_ii:nn #1 } + { + \keyval_split_key_value:w #1 = = \q_stop + \keyval_parse_elt:w \q_no_value + } + } + } +\cs_new_protected:Npn \keyval_split_key_value:w #1 = #2 \q_stop + { + \keyval_split_key:w #1 \q_stop + \str_if_eq:nnTF {#2} { = } + { + \tl_put_right:Nx \l_keyval_parse_tl + { + \exp_not:c + { keyval_key_no_value_elt_ \int_use:N \g_keyval_level_int :n } + { \exp_not:o \l_keyval_key_tl } + } + } + { + \keyval_split_key_value_aux:wTF #2 \q_no_value \q_stop + { \keyval_split_value:w \q_nil #2 } + { \msg_kernel_error:nn { keyval } { misplaced-equals-sign } } + } + } +\cs_new:Npn \keyval_split_key_value_aux:wTF #1 = #2#3 \q_stop + { \tl_if_head_eq_meaning:nNTF {#3} \q_no_value } +\group_begin: + \char_set_catcode_math_toggle:n { `\Q } + \cs_new_protected:Npn \keyval_split_key:w #1 \q_stop + { + \exp_args:NNf \tl_set:Nn \l_keyval_key_tl + { + \exp_after:wN \keyval_remove_spaces:w \exp_after:wN + \exp_not:N \use_none:n #1 Q ~ Q + } + \tl_set:Nx \l_keyval_key_tl + { \exp_after:wN \keyval_split_key_aux:w \l_keyval_key_tl \q_stop } + } + \cs_gset:Npn \keyval_split_key_aux:w #1 \q_stop { \exp_not:n {#1} } + \cs_gset:Npn \keyval_remove_spaces:w #1 ~ Q + { \keyval_remove_spaces_aux:w #1 Q } + \cs_gset:Npn \keyval_remove_spaces_aux:w #1 Q #2 {#1} +\group_end: +\cs_new_protected:Npn \keyval_split_value:w #1 = = + { + \tl_put_right:Nx \l_keyval_parse_tl + { + \exp_not:c + { keyval_key_value_elt_ \int_use:N \g_keyval_level_int :nn } + { \exp_not:o \l_keyval_key_tl } + } + \tl_set:Nx \l_keyval_value_tl + { \exp_not:o { \use_none:nnn #1 \q_nil \q_nil } } + \tl_if_empty:NTF \l_keyval_value_tl + { \tl_put_right:Nn \l_keyval_parse_tl { { } } } + { + \quark_if_nil:NTF \l_keyval_value_tl + { + \tl_put_right:Nx \l_keyval_parse_tl + { { \exp_not:o { \use_ii:nnn #1 \q_nil } } } + } + { \keyval_split_value_aux:w #1 \q_stop } + } + } +\group_begin: + \char_set_catcode_math_toggle:n { `\Q } + \cs_new_protected:Npn \keyval_split_value_aux:w \q_nil #1 \q_stop + { + \exp_args:NNf \tl_set:Nn \l_keyval_value_tl + { \keyval_remove_spaces:w \exp_not:N #1 Q ~ Q } + \tl_put_right:Nx \l_keyval_parse_tl + { { \exp_not:o \l_keyval_value_tl } } + } +\group_end: +\cs_new_protected:Npn \keyval_parse:NNn #1#2#3 + { + \int_gincr:N \g_keyval_level_int + \cs_gset_eq:cN + { keyval_key_no_value_elt_ \int_use:N \g_keyval_level_int :n } #1 + \cs_gset_eq:cN + { keyval_key_value_elt_ \int_use:N \g_keyval_level_int :nn } #2 + \keyval_parse:n {#3} + \int_gdecr:N \g_keyval_level_int + } +\msg_kernel_new:nnnn { keyval } { misplaced-equals-sign } + { Misplaced~equals~sign~in~key-value~input~\msg_line_number: } + { + LaTeX~is~attempting~to~parse~some~key-value~input~but~found~ + two~equals~signs~not~separated~by~a~comma. + } \tl_const:Nn \c_keys_code_root_tl { key~code~>~ } \tl_const:Nn \c_keys_vars_root_tl { key~var~>~ } \tl_const:Nn \c_keys_props_root_tl { key~prop~>~ } @@ -63,6 +186,7 @@ \bool_new:N \l_keys_no_value_bool \tl_new:N \l_keys_path_tl \tl_new:N \l_keys_property_tl +\tl_new:N \l_keys_unknown_clist \tl_new:N \l_keys_value_tl \cs_new_protected:Npn \keys_define:nn { \keys_define_aux:onn \l_keys_module_tl } @@ -141,6 +265,21 @@ } \keys_default_set:n { true } } +\cs_new_nopar:Npn \keys_bool_set_inverse:NN #1#2 + { + \cs_if_exist:NF #1 { \bool_new:N #1 } + \keys_choice_make: + \keys_cmd_set:nx { \l_keys_path_tl / true } + { \exp_not:c { bool_ #2 set_false:N } \exp_not:N #1 } + \keys_cmd_set:nx { \l_keys_path_tl / false } + { \exp_not:c { bool_ #2 set_true:N } \exp_not:N #1 } + \keys_cmd_set:nn { \l_keys_path_tl / unknown } + { + \msg_kernel_error:nnx { keys } { boolean-values-only } + { \l_keys_key_tl } + } + \keys_default_set:n { true } + } \cs_new_protected_nopar:Npn \keys_choice_make: { \keys_cmd_set:nn { \l_keys_path_tl } @@ -151,6 +290,22 @@ { \l_keys_path_tl } {##1} } } +\cs_new_protected:Npn \keys_choices_make:nn #1#2 + { + \keys_choice_make: + \int_zero:N \l_keys_choice_int + \clist_map_inline:nn {#1} + { + \keys_cmd_set:nx { \l_keys_path_tl / ##1 } + { + \tl_set:Nn \exp_not:N \l_keys_choice_tl {##1} + \int_set:Nn \exp_not:N \l_keys_choice_int + { \int_use:N \l_keys_choice_int } + \exp_not:n {#2} + } + \int_incr:N \l_keys_choice_int + } + } \cs_new_protected:Npn \keys_choices_generate:n #1 { \cs_if_exist:cTF @@ -169,8 +324,8 @@ { \keys_cmd_set:nx { \l_keys_path_tl / #1 } { - \exp_not:n { \tl_set:Nn \l_keys_choice_tl } {#1} - \exp_not:n { \int_set:Nn \l_keys_choice_int } + \tl_set:Nn \exp_not:N \l_keys_choice_tl {#1} + \int_set:Nn \exp_not:N \l_keys_choice_int { \int_use:N \l_keys_choice_int } \exp_not:v { \c_keys_vars_root_tl \l_keys_path_tl .choice~code } @@ -210,13 +365,41 @@ \cs_new_protected_nopar:Npn \keys_meta_make:n #1 { \exp_args:NNo \keys_cmd_set:nn \l_keys_path_tl - { \exp_after:wN \keys_set:nn \exp_after:wN { \l_keys_module_tl } {#1} } + { \exp_after:wN \keys_set:nn \exp_after:wN { \l_keys_module_tl } {#1} } } \cs_new_protected_nopar:Npn \keys_meta_make:x #1 { \keys_cmd_set:nx { \l_keys_path_tl } { \exp_not:N \keys_set:nn { \l_keys_module_tl } {#1} } } +\cs_new_nopar:Npn \keys_multichoice_find:n #1 + { \clist_map_function:nN {#1} \keys_choice_find:n } +\cs_new_protected_nopar:Npn \keys_multichoice_make: + { + \keys_cmd_set:nn { \l_keys_path_tl } + { \keys_multichoice_find:n {##1} } + \keys_cmd_set:nn { \l_keys_path_tl / unknown } + { + \msg_kernel_error:nnxx { keys } { choice-unknown } + { \l_keys_path_tl } {##1} + } + } +\cs_new_protected:Npn \keys_multichoices_make:nn #1#2 + { + \keys_multichoice_make: + \int_zero:N \l_keys_choice_int + \clist_map_inline:nn {#1} + { + \keys_cmd_set:nx { \l_keys_path_tl / ##1 } + { + \tl_set:Nn \exp_not:N \l_keys_choice_tl {##1} + \int_set:Nn \exp_not:N \l_keys_choice_int + { \int_use:N \l_keys_choice_int } + \exp_not:n {#2} + } + \int_incr:N \l_keys_choice_int + } + } \cs_new_protected_nopar:Npn \keys_value_requirement:n #1 { \tl_set_eq:cc @@ -237,8 +420,14 @@ { \keys_bool_set:NN #1 { } } \cs_new_protected_nopar:cpn { \c_keys_props_root_tl .bool_gset:N } #1 { \keys_bool_set:NN #1 g } +\cs_new_protected_nopar:cpn { \c_keys_props_root_tl .bool_set_inverse:N } #1 + { \keys_bool_set_inverse:NN #1 { } } +\cs_new_protected_nopar:cpn { \c_keys_props_root_tl .bool_gset_inverse:N } #1 + { \keys_bool_set_inverse:NN #1 g } \cs_new_protected_nopar:cpn { \c_keys_props_root_tl .choice: } { \keys_choice_make: } +\cs_new_protected:cpn { \c_keys_props_root_tl .choices:nn } #1 + { \keys_choices_make:nn #1 } \cs_new_protected:cpn { \c_keys_props_root_tl .code:n } #1 { \keys_cmd_set:nn { \l_keys_path_tl } {#1} } \cs_new_protected:cpn { \c_keys_props_root_tl .code:x } #1 @@ -281,6 +470,10 @@ { \keys_meta_make:n {#1} } \cs_new_protected:cpn { \c_keys_props_root_tl .meta:x } #1 { \keys_meta_make:x {#1} } +\cs_new_protected_nopar:cpn { \c_keys_props_root_tl .multichoice: } + { \keys_multichoice_make: } +\cs_new_protected:cpn { \c_keys_props_root_tl .multichoices:nn } #1 + { \keys_multichoices_make:nn #1 } \cs_new_protected_nopar:cpn { \c_keys_props_root_tl .skip_set:N } #1 { \keys_variable_set:NnN #1 { skip } n } \cs_new_protected_nopar:cpn { \c_keys_props_root_tl .skip_set:c } #1 @@ -319,6 +512,20 @@ } \cs_generate_variant:Nn \keys_set:nn { nV , nv , no } \cs_generate_variant:Nn \keys_set_aux:nnn { o } +\cs_new_protected:Npn \keys_set_known:nnN + { \keys_set_known_aux:onnN { \l_keys_module_tl } } +\cs_new_protected:Npn \keys_set_known_aux:nnnN #1#2#3#4 + { + \tl_set:Nn \l_keys_module_tl {#2} + \clist_clear:N \l_keys_unknown_clist + \cs_set_eq:NN \keys_execute_unknown: \keys_execute_unknown_alt: + \keyval_parse:NNn \keys_set_elt:n \keys_set_elt:nn {#3} + \cs_set_eq:NN \keys_execute_unknown: \keys_execute_unknown_std: + \tl_set:Nn \l_keys_module_tl {#1} + \clist_set_eq:NN #4 \l_keys_unknown_clist + } +\cs_generate_variant:Nn \keys_set_known:nnN { nV , nv , no } +\cs_generate_variant:Nn \keys_set_known_aux:nnnN { o } \cs_new_protected_nopar:Npn \keys_set_elt:n #1 { \bool_set_true:N \l_keys_no_value_bool @@ -363,8 +570,11 @@ { \quark_if_no_value:cF { \c_keys_vars_root_tl \l_keys_path_tl .default } { - \tl_set_eq:Nc \l_keys_value_tl - { \c_keys_vars_root_tl \l_keys_path_tl .default } + \cs_if_exist:cT { \c_keys_vars_root_tl \l_keys_path_tl .default } + { + \tl_set_eq:Nc \l_keys_value_tl + { \c_keys_vars_root_tl \l_keys_path_tl .default } + } } } } @@ -385,6 +595,16 @@ { \l_keys_path_tl } { \l_keys_module_tl } } } +\cs_new_eq:NN \keys_execute_unknown_std: \keys_execute_unknown: +\cs_new_nopar:Npn \keys_execute_unknown_alt: + { + \clist_put_right:Nx \l_keys_unknown_clist + { + \exp_not:o \l_keys_key_tl + \bool_if:NF \l_keys_no_value_bool + { = { \exp_not:o \l_keys_value_tl } } + } + } \cs_new_nopar:Npn \keys_execute:nn #1#2 { \cs_if_exist:cTF { \c_keys_code_root_tl #1 } @@ -402,8 +622,14 @@ \prg_new_conditional:Npnn \keys_if_exist:nn #1#2 { p , T , F , TF } { \cs_if_exist:cTF { \c_keys_code_root_tl #1 / #2 } - { \prg_return_true:} - { \prg_return_false:} + { \prg_return_true: } + { \prg_return_false: } + } +\prg_new_conditional:Npnn \keys_if_choice_exist:nnn #1#2#3 { p , T , F , TF } + { + \cs_if_exist:cTF { \c_keys_code_root_tl #1 / #2 / #3 } + { \prg_return_true: } + { \prg_return_false: } } \cs_new_nopar:Npn \keys_show:nn #1#2 { \cs_show:c { \c_keys_code_root_tl #1 / \tl_to_str:n {#2} } } @@ -470,6 +696,9 @@ The~key~'#1'~must~have~a~value.\\ No~value~was~present:~the~key~will~be~ignored. } +\cs_new_eq:NN \KV_process_space_removal_sanitize:NNn \keyval_parse:NNn +\cs_new_eq:NN \KV_process_space_removal_no_sanitize:NNn \keyval_parse:NNn +\cs_new_eq:NN \KV_process_no_space_removal_no_sanitize:NNn \keyval_parse:NNn %% %% %% End of file `l3keys.sty'. diff --git a/Master/texmf-dist/tex/latex/l3kernel/l3keyval.sty b/Master/texmf-dist/tex/latex/l3kernel/l3keyval.sty deleted file mode 100644 index a2b5411e916..00000000000 --- a/Master/texmf-dist/tex/latex/l3kernel/l3keyval.sty +++ /dev/null @@ -1,177 +0,0 @@ -%% -%% This is file `l3keyval.sty', -%% generated with the docstrip utility. -%% -%% The original source files were: -%% -%% l3keyval.dtx (with options: `package') -%% -%% EXPERIMENTAL CODE -%% -%% Do not distribute this file without also distributing the -%% source files specified above. -%% -%% Do not distribute a modified version of this file. -%% -%% File: l3keyval.dtx Copyright (C) 2006-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 "expl3 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 LaTeX3 Project. -%% -%% ----------------------------------------------------------------------- -\RequirePackage{l3names} -\GetIdInfo$Id: l3keyval.dtx 2601 2011-08-16 23:20:27Z bruno $ - {L3 Experimental key-value parsing} - %\section{Parsing key--value lists} - %\begin{function}{\keyval_parse:NNn} -\ProvidesExplPackage - {\ExplFileName}{\ExplFileDate}{\ExplFileVersion}{\ExplFileDescription} -\package_check_loaded_expl: -\int_new:N \g_keyval_level_int -\tl_new:N \l_keyval_key_tl -\tl_new:N \l_keyval_value_tl -\tl_new:N \l_keyval_sanitise_tl -\tl_new:N \l_keyval_parse_tl -\group_begin: - \char_set_catcode_active:n { `\= } - \char_set_catcode_active:n { `\, } - \char_set_lccode:nn { `\8 } { `\= } - \char_set_lccode:nn { `\9 } { `\, } -\tl_to_lowercase:n - { - \group_end: - \cs_new_protected:Npn \keyval_parse:n #1 - { - \group_begin: - \tl_clear:N \l_keyval_sanitise_tl - \tl_set:Nn \l_keyval_sanitise_tl {#1} - \tl_replace_all:Nnn \l_keyval_sanitise_tl { = } { 8 } - \tl_replace_all:Nnn \l_keyval_sanitise_tl { , } { 9 } - \tl_clear:N \l_keyval_parse_tl - \exp_after:wN \keyval_parse_elt:w \exp_after:wN - \q_no_value \l_keyval_sanitise_tl 9 \q_nil 9 - \exp_after:wN \group_end: - \l_keyval_parse_tl - } - } -\cs_new_protected:Npn \keyval_parse_elt:w #1 , - { - \tl_if_blank:oTF { \use_none:n #1 } - { \keyval_parse_elt:w \q_no_value } - { - \quark_if_nil:oF { \use_ii:nn #1 } - { - \keyval_split_key_value:w #1 = = \q_stop - \keyval_parse_elt:w \q_no_value - } - } - } -\cs_new_protected:Npn \keyval_split_key_value:w #1 = #2 \q_stop - { - \keyval_split_key:w #1 \q_stop - \str_if_eq:nnTF {#2} { = } - { - \tl_put_right:Nx \l_keyval_parse_tl - { - \exp_not:c { keyval_key_no_value_elt_ \int_use:N \g_keyval_level_int :n } - { \exp_not:o \l_keyval_key_tl } - } - } - { - \keyval_split_key_value_aux:wTF #2 \q_no_value \q_stop - { \keyval_split_value:w \q_nil #2 } - { \msg_kernel_error:nn { keyval } { misplaced-equals-sign } } - } - } -\cs_new:Npn \keyval_split_key_value_aux:wTF #1 = #2#3 \q_stop - { \tl_if_head_eq_meaning:nNTF {#3} \q_no_value } -\group_begin: - \char_set_catcode_math_toggle:n { `\Q } - \cs_new_protected:Npn \keyval_split_key:w #1 \q_stop - { - \exp_args:NNf \tl_set:Nn \l_keyval_key_tl - { - \exp_after:wN \keyval_remove_spaces:w \exp_after:wN - \exp_not:N \use_none:n #1 Q ~ Q - } - \tl_set:Nx \l_keyval_key_tl - { \exp_after:wN \keyval_split_key_aux:w \l_keyval_key_tl \q_stop } - } - \cs_gset:Npn \keyval_split_key_aux:w #1 \q_stop { \exp_not:n {#1} } - \cs_gset:Npn \keyval_remove_spaces:w #1 ~ Q { \keyval_remove_spaces_aux:w #1 Q } - \cs_gset:Npn \keyval_remove_spaces_aux:w #1 Q #2 {#1} -\group_end: -\cs_new_protected:Npn \keyval_split_value:w #1 = = - { - \tl_put_right:Nx \l_keyval_parse_tl - { - \exp_not:c { keyval_key_value_elt_ \int_use:N \g_keyval_level_int :nn } - { \exp_not:o \l_keyval_key_tl } - } - \tl_set:Nx \l_keyval_value_tl { \exp_not:o { \use_none:nnn #1 \q_nil \q_nil } } - \tl_if_empty:NTF \l_keyval_value_tl - { \tl_put_right:Nn \l_keyval_parse_tl { { } } } - { - \quark_if_nil:NTF \l_keyval_value_tl - { - \tl_put_right:Nx \l_keyval_parse_tl - { { \exp_not:o { \use_ii:nnn #1 \q_nil } } } - } - { \keyval_split_value_aux:w #1 \q_stop } - } - } -\group_begin: - \char_set_catcode_math_toggle:n { `\Q } - \cs_new_protected:Npn \keyval_split_value_aux:w \q_nil #1 \q_stop - { - \exp_args:NNf \tl_set:Nn \l_keyval_value_tl - { \keyval_remove_spaces:w \exp_not:N #1 Q ~ Q } - \tl_put_right:Nx \l_keyval_parse_tl { { \exp_not:o \l_keyval_value_tl } } - } -\group_end: -\cs_new_protected:Npn \keyval_parse:NNn #1#2#3 - { - \int_gincr:N \g_keyval_level_int - \cs_gset_eq:cN { keyval_key_no_value_elt_ \int_use:N \g_keyval_level_int :n } #1 - \cs_gset_eq:cN { keyval_key_value_elt_ \int_use:N \g_keyval_level_int :nn } #2 - \keyval_parse:n {#3} - \int_gdecr:N \g_keyval_level_int - } -\msg_kernel_new:nnnn { keyval } { misplaced-equals-sign } - { Misplaced~equals~sign~in~key-value~input~\msg_line_number: } - { - LaTeX~is~attempting~to~parse~some~key-value~input~but~found~ - two~equals~signs~not~separated~by~a~comma. - } -\cs_new_eq:NN \KV_process_space_removal_sanitize:NNn \keyval_parse:NNn -\cs_new_eq:NN \KV_process_space_removal_no_sanitize:NNn \keyval_parse:NNn -\cs_new_eq:NN \KV_process_no_space_removal_no_sanitize:NNn \keyval_parse:NNn -%% -%% -%% End of file `l3keyval.sty'. diff --git a/Master/texmf-dist/tex/latex/l3kernel/l3luatex.sty b/Master/texmf-dist/tex/latex/l3kernel/l3luatex.sty index 38e13e2b87b..c9db7919b6b 100644 --- a/Master/texmf-dist/tex/latex/l3kernel/l3luatex.sty +++ b/Master/texmf-dist/tex/latex/l3kernel/l3luatex.sty @@ -46,7 +46,7 @@ %% %% ----------------------------------------------------------------------- \RequirePackage{l3names} -\GetIdInfo$Id: l3luatex.dtx 2545 2011-08-11 13:47:19Z bruno $ +\GetIdInfo$Id: l3luatex.dtx 2617 2011-08-18 08:13:44Z joseph $ {L3 Experimental LuaTeX-specific functions} \ProvidesExplPackage {\ExplFileName}{\ExplFileDate}{\ExplFileVersion}{\ExplFileDescription} diff --git a/Master/texmf-dist/tex/latex/l3kernel/l3prg.sty b/Master/texmf-dist/tex/latex/l3kernel/l3prg.sty index a77391e1ec1..2aeb1f516e6 100644 --- a/Master/texmf-dist/tex/latex/l3kernel/l3prg.sty +++ b/Master/texmf-dist/tex/latex/l3kernel/l3prg.sty @@ -46,7 +46,7 @@ %% %% ----------------------------------------------------------------------- \RequirePackage{l3names} -\GetIdInfo$Id: l3prg.dtx 2601 2011-08-16 23:20:27Z bruno $ +\GetIdInfo$Id: l3prg.dtx 2665 2011-08-25 22:15:27Z joseph $ {L3 Experimental control structures} %% \ProvidesExplPackage diff --git a/Master/texmf-dist/tex/latex/l3kernel/l3prop.sty b/Master/texmf-dist/tex/latex/l3kernel/l3prop.sty index 5d2a1ff69d0..222170544df 100644 --- a/Master/texmf-dist/tex/latex/l3kernel/l3prop.sty +++ b/Master/texmf-dist/tex/latex/l3kernel/l3prop.sty @@ -46,8 +46,9 @@ %% %% ----------------------------------------------------------------------- \RequirePackage{l3names} -\GetIdInfo$Id: l3prop.dtx 2478 2011-06-19 21:34:23Z joseph $ +\GetIdInfo$Id: l3prop.dtx 2665 2011-08-25 22:15:27Z joseph $ {L3 Experimental property lists} +%% \ProvidesExplPackage {\ExplFileName}{\ExplFileDate}{\ExplFileVersion}{\ExplFileDescription} \package_check_loaded_expl: @@ -208,6 +209,20 @@ \cs_generate_variant:Nn \prop_if_in:NnF { c , cV , co } \cs_generate_variant:Nn \prop_if_in:NnTF { NV , No } \cs_generate_variant:Nn \prop_if_in:NnTF { c , cV , co } +\prg_new_protected_conditional:Npnn \prop_get:NnN #1#2#3 { T , F , TF } + { + \prop_split:NnTF #1 {#2} + { \prop_get_aux_true:Nnnn #3 } + { \prg_return_false: } + } +\cs_new_protected:Npn \prop_get_aux_true:Nnnn #1#2#3#4 + { + \tl_set:Nn #1 {#3} + \prg_return_true: + } +\cs_generate_variant:Nn \prop_get:NnNT { c } +\cs_generate_variant:Nn \prop_get:NnNF { c } +\cs_generate_variant:Nn \prop_get:NnNTF { c } \cs_new_nopar:Npn \prop_map_function:NN #1#2 { \exp_last_unbraced:NNo \prop_map_function_aux:Nwn #2 @@ -265,24 +280,13 @@ } \cs_new:Npn \prop_show_aux:w #1 > ~ { } \cs_generate_variant:Nn \prop_show:N { c } -\prg_new_protected_conditional:Npnn \prop_get:NnN #1#2#3 { T , F , TF } - { - \prop_split:NnTF #1 {#2} - { \prop_get_aux_true:Nnnn #3 } - { \prg_return_false: } - } -\cs_new_protected:Npn \prop_get_aux_true:Nnnn #1#2#3#4 - { - \tl_set:Nn #1 {#3} - \prg_return_true: - } -\prg_new_protected_conditional:Npnn \prop_pop:NnN #1#2#3 {T,F,TF} +\prg_new_protected_conditional:Npnn \prop_pop:NnN #1#2#3 { T , F , TF } { \prop_split:NnTF #1 {#2} { \prop_pop_aux_true:NNNnnn \tl_set:Nn #1 #3 } { \prg_return_false: } } -\prg_new_protected_conditional:Npnn \prop_gpop:NnN #1#2#3 {T,F,TF} +\prg_new_protected_conditional:Npnn \prop_gpop:NnN #1#2#3 { T , F , TF } { \prop_split:NnTF #1 {#2} { \prop_pop_aux_true:NNNnnn \tl_gset:Nn #1 #3 } @@ -294,6 +298,12 @@ #1 #2 { #4 #6 } \prg_return_true: } +\cs_generate_variant:Nn \prop_pop:NnNT { c } +\cs_generate_variant:Nn \prop_pop:NnNF { c } +\cs_generate_variant:Nn \prop_pop:NnNTF { c } +\cs_generate_variant:Nn \prop_gpop:NnNT { c } +\cs_generate_variant:Nn \prop_gpop:NnNF { c } +\cs_generate_variant:Nn \prop_gpop:NnNTF { c } \cs_new:Npn \prop_map_tokens:Nn #1#2 { \exp_last_unbraced:Nno \prop_map_tokens_aux:nwn {#2} #1 @@ -307,10 +317,12 @@ \use:n {#1} {#2} {#3} \prop_map_tokens_aux:nwn {#1} } -\cs_new:Npn \prop_get:Nn #1 #2 +\cs_generate_variant:Nn \prop_map_tokens:Nn { c } +\cs_new:Npn \prop_get:Nn #1#2 { \prop_map_tokens:Nn #1 { \prop_get_aux:nnn {#2} } } -\cs_new:Npn \prop_get_aux:nnn #1 #2 #3 +\cs_new:Npn \prop_get_aux:nnn #1#2#3 { \str_if_eq:nnT {#1} {#2} { \prop_map_break:n {#3} } } +\cs_generate_variant:Nn \prop_get:Nn { c } \cs_new_eq:NN \prop_display:N \prop_show:N \cs_new_eq:NN \prop_display:c \prop_show:c \cs_new_protected:Npn \prop_gget:NnN #1#2#3 diff --git a/Master/texmf-dist/tex/latex/l3kernel/l3quark.sty b/Master/texmf-dist/tex/latex/l3kernel/l3quark.sty index 236b34b5a0a..d95b117b5f8 100644 --- a/Master/texmf-dist/tex/latex/l3kernel/l3quark.sty +++ b/Master/texmf-dist/tex/latex/l3kernel/l3quark.sty @@ -46,7 +46,7 @@ %% %% ----------------------------------------------------------------------- \RequirePackage{l3names} -\GetIdInfo$Id: l3quark.dtx 2549 2011-08-11 21:06:39Z bruno $ +\GetIdInfo$Id: l3quark.dtx 2665 2011-08-25 22:15:27Z joseph $ {L3 Experimental quarks} \ProvidesExplPackage {\ExplFileName}{\ExplFileDate}{\ExplFileVersion}{\ExplFileDescription} diff --git a/Master/texmf-dist/tex/latex/l3kernel/l3seq.sty b/Master/texmf-dist/tex/latex/l3kernel/l3seq.sty index 0f3aee34e2c..9db270f6006 100644 --- a/Master/texmf-dist/tex/latex/l3kernel/l3seq.sty +++ b/Master/texmf-dist/tex/latex/l3kernel/l3seq.sty @@ -46,7 +46,7 @@ %% %% ----------------------------------------------------------------------- \RequirePackage{l3names} -\GetIdInfo$Id: l3seq.dtx 2586 2011-08-15 03:59:12Z bruno $ +\GetIdInfo$Id: l3seq.dtx 2665 2011-08-25 22:15:27Z joseph $ {L3 Experimental sequences and stacks} \ProvidesExplPackage {\ExplFileName}{\ExplFileDate}{\ExplFileVersion}{\ExplFileDescription} diff --git a/Master/texmf-dist/tex/latex/l3kernel/l3skip.sty b/Master/texmf-dist/tex/latex/l3kernel/l3skip.sty index 787981891fd..2e85a330dae 100644 --- a/Master/texmf-dist/tex/latex/l3kernel/l3skip.sty +++ b/Master/texmf-dist/tex/latex/l3kernel/l3skip.sty @@ -46,7 +46,7 @@ %% %% ----------------------------------------------------------------------- \RequirePackage{l3names} -\GetIdInfo$Id: l3skip.dtx 2526 2011-08-09 08:58:42Z joseph $ +\GetIdInfo$Id: l3skip.dtx 2665 2011-08-25 22:15:27Z joseph $ {L3 Experimental dimensions and skips} \ProvidesExplPackage {\ExplFileName}{\ExplFileDate}{\ExplFileVersion}{\ExplFileDescription} diff --git a/Master/texmf-dist/tex/latex/l3kernel/l3tl.sty b/Master/texmf-dist/tex/latex/l3kernel/l3tl.sty index 463d9f6f6b7..f304c84c084 100644 --- a/Master/texmf-dist/tex/latex/l3kernel/l3tl.sty +++ b/Master/texmf-dist/tex/latex/l3kernel/l3tl.sty @@ -46,7 +46,7 @@ %% %% ----------------------------------------------------------------------- \RequirePackage{l3names} -\GetIdInfo$Id: l3tl.dtx 2566 2011-08-13 22:04:42Z bruno $ +\GetIdInfo$Id: l3tl.dtx 2665 2011-08-25 22:15:27Z joseph $ {L3 Experimental token lists} \ProvidesExplPackage {\ExplFileName}{\ExplFileDate}{\ExplFileVersion}{\ExplFileDescription} diff --git a/Master/texmf-dist/tex/latex/l3kernel/l3token.sty b/Master/texmf-dist/tex/latex/l3kernel/l3token.sty index 018240d7bfa..4ffd05760ff 100644 --- a/Master/texmf-dist/tex/latex/l3kernel/l3token.sty +++ b/Master/texmf-dist/tex/latex/l3kernel/l3token.sty @@ -46,7 +46,7 @@ %% %% ----------------------------------------------------------------------- \RequirePackage{l3names} -\GetIdInfo$Id: l3token.dtx 2579 2011-08-14 16:22:30Z bruno $ +\GetIdInfo$Id: l3token.dtx 2665 2011-08-25 22:15:27Z joseph $ {L3 Experimental token manipulation} %% \begin{function}[EXP,pTF]{\token_if_protected_long_macro:N} \ProvidesExplPackage diff --git a/Master/texmf-dist/tex/latex/l3kernel/l3toks.sty b/Master/texmf-dist/tex/latex/l3kernel/l3toks.sty index 484cdd401e8..5867a1f8e38 100644 --- a/Master/texmf-dist/tex/latex/l3kernel/l3toks.sty +++ b/Master/texmf-dist/tex/latex/l3kernel/l3toks.sty @@ -46,7 +46,7 @@ %% %% ----------------------------------------------------------------------- \RequirePackage{l3names} -\GetIdInfo$Id: l3toks.dtx 2601 2011-08-16 23:20:27Z bruno $ +\GetIdInfo$Id: l3toks.dtx 2670 2011-08-27 09:58:02Z will $ {L3 Experimental token registers} \ProvidesExplPackage {\ExplFileName}{\ExplFileDate}{\ExplFileVersion}{\ExplFileDescription} |