diff options
author | Karl Berry <karl@freefriends.org> | 2012-02-28 00:40:51 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2012-02-28 00:40:51 +0000 |
commit | 29c459636115f7de4ae9a8681927b52a1e896805 (patch) | |
tree | 5200a1da0c7a7bae64d8c07c48df4a5daf30323e /Master/texmf-dist | |
parent | e20ea4bdd670e0418363a2a38a54b422a4d83231 (diff) |
l3kernel 3471 (26feb12)
git-svn-id: svn://tug.org/texlive/trunk@25525 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist')
45 files changed, 3399 insertions, 2817 deletions
diff --git a/Master/texmf-dist/doc/latex/l3kernel/expl3.pdf b/Master/texmf-dist/doc/latex/l3kernel/expl3.pdf Binary files differindex 3f8746e8f89..c43c9431b77 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 differindex e42c41d7046..e402f3670df 100644 --- a/Master/texmf-dist/doc/latex/l3kernel/interface3.pdf +++ b/Master/texmf-dist/doc/latex/l3kernel/interface3.pdf diff --git a/Master/texmf-dist/doc/latex/l3kernel/l3styleguide.pdf b/Master/texmf-dist/doc/latex/l3kernel/l3styleguide.pdf Binary files differindex b790e90356e..d631f182eb7 100644 --- a/Master/texmf-dist/doc/latex/l3kernel/l3styleguide.pdf +++ 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 index c14d7d8eefd..4f63ed8fc70 100644 --- a/Master/texmf-dist/doc/latex/l3kernel/l3styleguide.tex +++ b/Master/texmf-dist/doc/latex/l3kernel/l3styleguide.tex @@ -1,6 +1,6 @@ \iffalse meta-comment -File l3styleguide.tex Copyright (C) 2011 The LaTeX3 Project +File l3styleguide.tex Copyright (C) 2011,202 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 @@ -155,19 +155,30 @@ look like the example: \section{Code conventions} +All code-level functions should be \enquote{long} if they accept any +arguments, even if it seems \enquote{very unlikely} that a \cs{par} token. +will be passed. Thus \cs{cs_new_nopar:Npn} and so forth should only be used +to create functions which accept no arguments at all. + +The expandability of each function should be well-defined. Functions which +cannot be fully expanded must be \texttt{protected}. This means that expandable +functions must themselves only contain expandable material. Functions which +use any non-expandable material must be defined using \cs{cs_new_protected:Npn} +or similar. + 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 } +\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 + \tl_set:No \l_some_tl \l_some_other_tl \end{verbatim} remains clear and can be used where appropriate. diff --git a/Master/texmf-dist/doc/latex/l3kernel/l3syntax-changes.pdf b/Master/texmf-dist/doc/latex/l3kernel/l3syntax-changes.pdf Binary files differindex b9f9e36d9b1..144bbd62727 100644 --- a/Master/texmf-dist/doc/latex/l3kernel/l3syntax-changes.pdf +++ b/Master/texmf-dist/doc/latex/l3kernel/l3syntax-changes.pdf diff --git a/Master/texmf-dist/doc/latex/l3kernel/source3.pdf b/Master/texmf-dist/doc/latex/l3kernel/source3.pdf Binary files differindex df80fa30686..a48af7e1f7e 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/source3body.tex b/Master/texmf-dist/doc/latex/l3kernel/source3body.tex index 119886c86cb..bd618e6fa23 100644 --- a/Master/texmf-dist/doc/latex/l3kernel/source3body.tex +++ b/Master/texmf-dist/doc/latex/l3kernel/source3body.tex @@ -171,7 +171,7 @@ following argument specifiers: \item[\texttt{x}] The \texttt{x} specifier stands for \emph{exhaustive expansion}: every token in the argument is fully expanded until only unexpandable ones remain. The \TeX{} \tn{edef} primitive carries out - this type of expansion. Functions which feature an \texttt{x}-type + this type of expansion. Functions which feature an \texttt{x}-type argument are in general \emph{not} expandable, unless specifically noted. \item[\texttt{f}] The \texttt{f} specifier stands for \emph{full @@ -411,7 +411,6 @@ logical construct. \DocInput{l3box.dtx} \DocInput{l3coffins.dtx} \DocInput{l3color.dtx} -\DocInput{l3io.dtx} \DocInput{l3msg.dtx} \DocInput{l3keys.dtx} \DocInput{l3file.dtx} diff --git a/Master/texmf-dist/source/latex/l3kernel/expl3.dtx b/Master/texmf-dist/source/latex/l3kernel/expl3.dtx index 1f7d2beed09..5dbfdd60bce 100644 --- a/Master/texmf-dist/source/latex/l3kernel/expl3.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/expl3.dtx @@ -48,8 +48,8 @@ %<package> } \def\ExplFileName{expl3} \def\ExplFileDescription{L3 Experimental code bundle wrapper} -\def\ExplFileDate{2012/02/08} -\def\ExplFileVersion{3343} +\def\ExplFileDate{2012/02/26} +\def\ExplFileVersion{3471} %</driver|package> %<*driver> \documentclass[full]{l3doc} @@ -748,9 +748,6 @@ % \explpkg{l3int}{ % This implements the integer data-type \texttt{int}. % } -% \explpkg{l3io}{ -% A module providing low level input and output functions. -% } % \explpkg{l3keys}{ % For processing lists of the form % \texttt{\{ key1=val1 , key2=val2 \}}, intended to work @@ -843,7 +840,7 @@ % \item If in doubt, ask the team via the LaTeX-L list: someone will % soon get back to you! % \end{itemize} -% +% % \section{Load-time options for \pkg{expl3}} % % To support code authors, the \pkg{expl3} package for \LaTeXe{} includes @@ -851,7 +848,7 @@ % sense, recognising the \texttt{true} and \texttt{false} values. Giving % the option name alone is equivalent to using the option with the % \texttt{true} value. -% +% % \DescribeOption{check-declarations} % All variables used in \LaTeX3 code should be declared. This is enforced % by \TeX{} for variable types based on \TeX{} registers, but not for those @@ -859,14 +856,14 @@ % \texttt{check-declarations} option enables checking for all variable % assignments, issuing an error if any variables are assigned without being % initialised. -% +% % \DescribeOption{log-functions} % The \texttt{log-functions} option is used to enable recording of every new % function name in the \texttt{.log} file. This is useful for debugging % purposes, as it means that there is a complete list of all functions % created by each module loaded (with the exceptions of a very small number % required by he bootstrap code for \LaTeX3). -% +% % \DescribeOption{native-drivers} % The \texttt{native-drivers} option instructs \LaTeX3 not to use the \LaTeXe{} % graphics and colour driver code. Setting this option \texttt{true} uses the @@ -1077,19 +1074,11 @@ \cs_check_exists:N #1 \cs_set_eq:NN #1 } - \cs_undefine:N \bool_set_eq:cN - \cs_undefine:N \bool_set_eq:Nc - \cs_undefine:N \bool_set_eq:cc - \cs_generate_variant:Nn \bool_set_eq:NN { c , Nc , cc } \cs_set_protected:Npn \bool_gset_eq:NN #1 { \cs_check_exists:N #1 - \cs_set_eq:NN #1 + \cs_gset_eq:NN #1 } - \cs_undefine:N \bool_gset_eq:cN - \cs_undefine:N \bool_gset_eq:Nc - \cs_undefine:N \bool_gset_eq:cc - \cs_generate_variant:Nn \bool_gset_eq:NN { c , Nc , cc } \cs_set_protected:Npn \bool_set:Nn #1#2 { \cs_check_exists:N #1 @@ -1109,7 +1098,6 @@ l3token, l3prop, l3msg, - l3io, l3file, l3skip, l3keys, diff --git a/Master/texmf-dist/source/latex/l3kernel/l3alloc.dtx b/Master/texmf-dist/source/latex/l3kernel/l3alloc.dtx index 130cff2671b..d9e59a686a7 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3alloc.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3alloc.dtx @@ -35,7 +35,7 @@ % %<*driver|package> \RequirePackage{l3names} -\GetIdInfo$Id: l3alloc.dtx 3086 2011-12-22 17:55:46Z bruno $ +\GetIdInfo$Id: l3alloc.dtx 3355 2012-02-09 07:18:22Z joseph $ {L3 Experimental register allocation} %</driver|package> %<*driver> @@ -256,7 +256,7 @@ \int_compare:nNnTF { \tl_use:c { g_ #1 _allocation_tl } } > { \tl_use:c { c_ #1 _allocation_max_tl } } - { \msg_kernel_fatal:nnx { alloc } { out-of-registers } {#1} } + { \msg_kernel_fatal:nnx { kernel } { out-of-registers } {#1} } { \seq_if_in:cxT { g_ #1 _allocation_seq } { \tl_use:c { g_ #1 _allocation_tl } } diff --git a/Master/texmf-dist/source/latex/l3kernel/l3basics.dtx b/Master/texmf-dist/source/latex/l3kernel/l3basics.dtx index d16781461b0..bd3b608daf7 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 3317 2012-02-06 12:26:40Z bruno $ +\GetIdInfo$Id: l3basics.dtx 3460 2012-02-26 12:16:41Z will $ {L3 Experimental basic definitions} %</driver|package> %<*driver> @@ -148,7 +148,7 @@ % The name of a function can be checked at the point of definition using % the \cs{cs_new\ldots} functions: this is recommended for all % functions which are defined for the first time. -% +% % There are three ways to define new functions. % All classes define a function to expand to the substitution text. % Within the substitution text the actual parameters are substituted @@ -781,10 +781,10 @@ % % \begin{function}[EXP]{\use:n, \use:nn, \use:nnn, \use:nnnn} % \begin{syntax} -% \cs{use:n} \Arg{group1} -% \cs{use:nn} \Arg{group1} \Arg{group2} -% \cs{use:nnn} \Arg{group1} \Arg{group2} \Arg{group3} -% \cs{use:nnnn} \Arg{group1} \Arg{group2} \Arg{group3} \Arg{group4} +% \cs{use:n} \Arg{group_1} +% \cs{use:nn} \Arg{group_1} \Arg{group_2} +% \cs{use:nnn} \Arg{group_1} \Arg{group_2} \Arg{group_3} +% \cs{use:nnnn} \Arg{group_1} \Arg{group_2} \Arg{group_3} \Arg{group_4} % \end{syntax} % As illustrated, these functions will absorb between one and four % arguments, as indicated by the argument specifier. The braces @@ -805,7 +805,7 @@ % % \begin{function}[EXP]{\use_i:nn, \use_ii:nn} % \begin{syntax} -% \cs{use_i:nn} \Arg{arg1} \Arg{arg2} +% \cs{use_i:nn} \Arg{arg_1} \Arg{arg_2} % \end{syntax} % These functions absorb two arguments from the input stream. The function % \cs{use_i:nn} discards the second argument, and leaves the content @@ -820,7 +820,7 @@ % % \begin{function}[EXP]{\use_i:nnn, \use_ii:nnn, \use_iii:nnn} % \begin{syntax} -% \cs{use_i:nnn} \Arg{arg1} \Arg{arg2} \Arg{arg3} +% \cs{use_i:nnn} \Arg{arg_1} \Arg{arg_2} \Arg{arg_3} % \end{syntax} % These functions absorb three arguments from the input stream. The % function \cs{use_i:nnn} discards the second and third arguments, and @@ -836,7 +836,7 @@ % \begin{function}[EXP] % {\use_i:nnnn, \use_ii:nnnn, \use_iii:nnnn, \use_iv:nnnn} % \begin{syntax} -% \cs{use_i:nnnn} \Arg{arg1} \Arg{arg2} \Arg{arg3} \Arg{arg4} +% \cs{use_i:nnnn} \Arg{arg_1} \Arg{arg_2} \Arg{arg_3} \Arg{arg_4} % \end{syntax} % These functions absorb four arguments from the input stream. The % function \cs{use_i:nnnn} discards the second, third and fourth @@ -852,7 +852,7 @@ % % \begin{function}[EXP]{\use_i_ii:nnn} % \begin{syntax} -% \cs{use_i_ii:nnn} \Arg{arg1} \Arg{arg2} \Arg{arg3} +% \cs{use_i_ii:nnn} \Arg{arg_1} \Arg{arg_2} \Arg{arg_3} % \end{syntax} % This functions will absorb three arguments and leave the content of the % first and second in the input stream. The category code of @@ -883,7 +883,7 @@ % \use_none:nnnnnnnnn % } % \begin{syntax} -% \cs{use_none:n} \Arg{group1} +% \cs{use_none:n} \Arg{group_1} % \end{syntax} % These functions absorb between one and nine groups from the % input stream, leaving nothing on the resulting input stream. @@ -1065,8 +1065,8 @@ % % \begin{function}[EXP,pTF]{\cs_if_eq:NN} % \begin{syntax} -% \cs{cs_if_eq_p:NN} \Arg{cs1} \Arg{cs2} -% \cs{cs_if_eq:NNTF} \Arg{cs1} \Arg{cs2} \Arg{true code} \Arg{false code} +% \cs{cs_if_eq_p:NN} \Arg{cs_1} \Arg{cs_2} +% \cs{cs_if_eq:NNTF} \Arg{cs_1} \Arg{cs_2} \Arg{true code} \Arg{false code} % \end{syntax} % Compares the definition of two \meta{control sequences} and % is logically \texttt{true} the same, \emph{i.e.}~if the have exactly @@ -1103,8 +1103,8 @@ % \str_if_eq:nV, \str_if_eq:VV, \str_if_eq:xx % } % \begin{syntax} -% \cs{str_if_eq_p:nn} \Arg{tl1} \Arg{tl2} -% \cs{str_if_eq:nnTF} \Arg{tl1} \Arg{tl2} \Arg{true code} \Arg{false code} +% \cs{str_if_eq_p:nn} \Arg{tl_1} \Arg{tl_2} +% \cs{str_if_eq:nnTF} \Arg{tl_1} \Arg{tl_2} \Arg{true code} \Arg{false code} % \end{syntax} % Compares the two \meta{token lists} on a character by character % basis, and is \texttt{true} if the two lists contain the same @@ -1173,11 +1173,11 @@ % % \begin{function}[EXP]{\if_meaning:w} % \begin{syntax} -% "\if_meaning:w" <arg1> <arg2> <true code> "\else:" <false code> "\fi:" +% "\if_meaning:w" <arg_1> <arg_2> <true code> "\else:" <false code> "\fi:" % \end{syntax} -% "\if_meaning:w" executes <true code> when <arg1> and <arg2> are the same, +% "\if_meaning:w" executes <true code> when <arg_1> and <arg_2> are the same, % otherwise it executes <false code>. -% <arg1> and <arg2> could be functions, variables, tokens; in all cases the +% <arg_1> and <arg_2> could be functions, variables, tokens; in all cases the % \emph{unexpanded} definitions are compared. % \begin{texnote} % This is \TeX{}'s |\ifx|. @@ -1186,8 +1186,8 @@ % % \begin{function}[EXP]{\if:w, \if_charcode:w,\if_catcode:w} % \begin{syntax} -% "\if:w" <token1> <token2> <true code> "\else:" <false code> "\fi:" \\ -% "\if_catcode:w" <token1> <token2> <true code> "\else:" <false code> "\fi:" +% "\if:w" <token_1> <token_2> <true code> "\else:" <false code> "\fi:" \\ +% "\if_catcode:w" <token_1> <token_2> <true code> "\else:" <false code> "\fi:" % \end{syntax} % These conditionals will expand any following tokens until two % unexpandable tokens are left. If you wish to prevent this expansion, @@ -2359,8 +2359,8 @@ \msg_kernel_error:nnxx { kernel } { command-already-defined } { \token_to_str:N #1 } { \token_to_meaning:N #1 } } - \iow_log:x { Defining~\token_to_str:N #1~ \msg_line_context: } - } + \iow_log:x { Defining~\token_to_str:N #1~ \msg_line_context: } + } \fi: %</package> \cs_set_protected_nopar:Npn \chk_if_free_cs:c diff --git a/Master/texmf-dist/source/latex/l3kernel/l3box.dtx b/Master/texmf-dist/source/latex/l3kernel/l3box.dtx index d00cad8139b..7497971d2d6 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 3158 2012-01-09 00:47:42Z bruno $ +\GetIdInfo$Id: l3box.dtx 3432 2012-02-18 12:16:20Z joseph $ {L3 Experimental boxes} %</driver|package> %<*driver> @@ -290,7 +290,7 @@ % \begin{function}[added = 2011-09-02, updated = 2011-10-22] % {\box_resize_to_wd:Nn, \box_resize_to_wd:cn} % \begin{syntax} -% \cs{box_resize_to_wd:Nnn} \meta{box} \Arg{x-size} +% \cs{box_resize_to_wd:Nn} \meta{box} \Arg{x-size} % \end{syntax} % Resize the \meta{box} to \meta{x-size} horizontally, scaling the vertical % size by the same amount (\meta{x-size} is a dimension expression). @@ -1189,8 +1189,7 @@ % \end{macro} % \end{macro} % -% \begin{macro}{\hbox_overlap_left:n,} -% \begin{macro}{\hbox_overlap_right:n} +% \begin{macro}{\hbox_overlap_left:n, \hbox_overlap_right:n} % Put a zero-sized box with the contents pushed against one side (which % makes it stick out on the other) directly into the input stream. % \begin{macrocode} @@ -1200,7 +1199,6 @@ { \hbox_to_zero:n { #1 \tex_hss:D } } % \end{macrocode} % \end{macro} -% \end{macro} % % \begin{macro}{\hbox_unpack:N, \hbox_unpack:c} % \begin{macro}{\hbox_unpack_clear:N, \hbox_unpack_clear:c} diff --git a/Master/texmf-dist/source/latex/l3kernel/l3clist.dtx b/Master/texmf-dist/source/latex/l3kernel/l3clist.dtx index ade1e0cedc4..8cd9e6d6687 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3clist.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3clist.dtx @@ -37,7 +37,7 @@ % %<*driver|package> \RequirePackage{l3names} -\GetIdInfo$Id: l3clist.dtx 3157 2012-01-09 00:42:07Z bruno $ +\GetIdInfo$Id: l3clist.dtx 3460 2012-02-26 12:16:41Z will $ {L3 Experimental comma separated lists} %</driver|package> %<*driver> @@ -274,8 +274,8 @@ % \begin{function}[EXP,pTF] % {\clist_if_eq:NN, \clist_if_eq:Nc, \clist_if_eq:cN, \clist_if_eq:cc} % \begin{syntax} -% \cs{clist_if_eq_p:NN} \Arg{clist1} \Arg{clist2} -% \cs{clist_if_eq:NNTF} \Arg{clist1} \Arg{clist2} \Arg{true code} \Arg{false code} +% \cs{clist_if_eq_p:NN} \Arg{clist_1} \Arg{clist_2} +% \cs{clist_if_eq:NNTF} \Arg{clist_1} \Arg{clist_2} \Arg{true code} \Arg{false code} % \end{syntax} % Compares the content of two \meta{comma lists} and % is logically \texttt{true} if the two contain the same list of diff --git a/Master/texmf-dist/source/latex/l3kernel/l3coffins.dtx b/Master/texmf-dist/source/latex/l3kernel/l3coffins.dtx index 21aae4e614e..28c9de60e50 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3coffins.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3coffins.dtx @@ -36,7 +36,7 @@ % %<*driver|package> \RequirePackage{l3names} -\GetIdInfo$Id: l3coffins.dtx 3155 2012-01-08 22:53:03Z bruno $ +\GetIdInfo$Id: l3coffins.dtx 3460 2012-02-26 12:16:41Z will $ {L3 Experimental coffin code layer} %</driver|package> %<*driver> @@ -127,8 +127,8 @@ % environment in a coffin. % \end{function} % -% \begin{function}[added = 2011-08-17, updated = 2011-09-03 -% ]{\vcoffin_set:Nnn, \vcoffin_set:cnn} +% \begin{function}[added = 2011-08-17, updated = 2011-09-03] +% {\vcoffin_set:Nnn, \vcoffin_set:cnn} % \begin{syntax} % \cs{vcoffin_set:Nnn} \meta{coffin} \Arg{width} \Arg{material} % \end{syntax} @@ -229,7 +229,7 @@ % ~~\meta{coffin2} \Arg{coffin2-pole1} \Arg{coffin2-pole2} % ~~\Arg{x-offset} \Arg{y-offset} % \end{syntax} -% This function attaches <coffin2> to <coffin1> such that the bounding box +% This function attaches <coffin_2> to <coffin_1> 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 @@ -253,7 +253,7 @@ % ~~\meta{coffin2} \Arg{coffin2-pole1} \Arg{coffin2-pole2} % ~~\Arg{x-offset} \Arg{y-offset} % \end{syntax} -% This function joins <coffin2> to <coffin1> such that the bounding box +% This function joins <coffin_2> to <coffin_1> such that the bounding box % of \meta{coffin1} may expand. The new bounding % box will cover the area containing the bounding boxes of the two % original coffins. The alignment is carried out by first calculating @@ -268,7 +268,7 @@ % % \begin{function}{\coffin_typeset:Nnnnn, \coffin_typeset:cnnnn} % \begin{syntax} -% \cs{coffin_typeset:Nnnnn} \meta{coffin} \Arg{pole1} \Arg{pole2} +% \cs{coffin_typeset:Nnnnn} \meta{coffin} \Arg{pole_1} \Arg{pole_2} % ~~\Arg{x-offset} \Arg{y-offset} % \end{syntax} % Typesetting is carried out by first calculating \meta{handle}, the @@ -326,7 +326,7 @@ % \begin{function}[updated = 2011-09-02] % {\coffin_mark_handle:Nnnn, \coffin_mark_handle:cnnn} % \begin{syntax} -% \cs{coffin_mark_handle:Nnnn} \meta{coffin} \Arg{pole1} \Arg{pole2} \Arg{colour} +% \cs{coffin_mark_handle:Nnnn} \meta{coffin} \Arg{pole_1} \Arg{pole_2} \Arg{colour} % \end{syntax} % This function first calculates the \meta{handle} for the % \meta{coffin} as defined by the intersection of \meta{pole1} and diff --git a/Master/texmf-dist/source/latex/l3kernel/l3doc.dtx b/Master/texmf-dist/source/latex/l3kernel/l3doc.dtx index f6aac3cc544..67d073be832 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 3255 2012-01-28 20:31:12Z joseph $ +\GetIdInfo$Id: l3doc.dtx 3464 2012-02-26 15:30:29Z bruno $ {L3 Experimental documentation class} %</driver|class> % @@ -122,7 +122,7 @@ Do not distribute a modified version of this file. % but not before the good ideas in \pkg{hypdoc}, \cls{xdoc2}, \pkg{docmfp}, and % \cls{gmdoc} are incorporated. % -% \textbf{It is even less stable than the main \pkg{expl3} packages. Use at own risk!} +% \textbf{It is much less stable than the main \pkg{expl3} packages. Use at own risk!} % % It is written as a `self-contained' docstrip file: executing % "latex l3doc.dtx" @@ -200,7 +200,6 @@ Do not distribute a modified version of this file. % their use. % \item Generalise \env{function}/\env{macro} for documenting `other things', % such as environment names, package options, even keyval options. -% \item Use \pkg{xparse}. % \item New function like "\part" but for files (remove awkward `File' as "\partname"). % \item Something better to replace "\StopEventually"; I'm thinking two % environments \env{documentation} and \env{implementation} that can @@ -208,6 +207,7 @@ Do not distribute a modified version of this file. % (This has been implemented but needs further consideration.) % \item Hyperlink documentation and implementation of macros (see % the \textsc{dtx} file of \pkg{svn-multi} v2 as an example). +% This is partially done, now, but should be improved. % \end{itemize} % % \section{Bugs} @@ -277,21 +277,24 @@ Do not distribute a modified version of this file. % \begin{framed} % \vspace{-\baselineskip} % \begin{verbatim} -% \begin{function}{ \function_one: , \function_two: } +% \begin{function}{ \function_one , \function_two: } % \begin{syntax} -% "\foo_bar:" \Arg{meta} <test1> +% "\foo_bar:" \Arg{meta} <test_1> % \end{syntax} % <description> % \end{function} % \end{verbatim} -% \vspace{-2\baselineskip} % \hrulefill +% \par +% \hspace*{0.25\textwidth} +% \begin{minipage}{0.5\textwidth} % \begin{function}{ \function_one: , \function_two: } % \begin{syntax} -% "\foo_bar:" \Arg{meta} <test1> +% "\foo_bar:" \Arg{meta} <test_1> % \end{syntax} % <description> % \end{function} +% \end{minipage} % \end{framed} % % Function environments take an optional argument to indicate whether the function(s) it @@ -308,24 +311,19 @@ Do not distribute a modified version of this file. % <description> % \end{function} % \end{verbatim} -% \vspace{-2\baselineskip} % \hrulefill +% \par +% \hspace*{0.25\textwidth} +% \begin{minipage}{0.5\textwidth} % \begin{function}[pTF]{ \cs_if_exist:N } % \begin{syntax} % "\cs_if_exist_p:N" <cs> % \end{syntax} % <description> % \end{function} +% \end{minipage} % \end{framed} % -% Note that the list of functions used to use "|" as a separator instead, -% and this syntax is \textbf{no longer} supported. -% -% In the old syntax, individual functions could be suffixed by an optional flag or -% two to indicate the same information given in the optional argument. -% This is still supported; use "/" to separate the function name -% from the flag(s) and then add any of "(EXP)", "(rEXP)", "(TF)", or "(pTF)". -% % \DescribeEnv{variable} % If you are documenting a variable instead of a function, use the "variable" environment instead; it behaves identically to the "function" environment above. % @@ -401,18 +399,6 @@ Do not distribute a modified version of this file. % % \end{macro} % \end{verbatim} % -% \bigskip -% \textbf{OPTIONS FOR THE FUTURE}\qquad Any improvements to the markup -% for the \env{function} environment would be good to mirror in \env{macro}. -% -% Perhaps this would be a better syntax for describing arguments? -% \begin{verbatim} -% \begin{macro}{\foo:nn,foo:VV} -% \dArg{Name of froozle to be frazzled} -% \dArg{Name of mumble to be jumbled} -% ... -% \end{verbatim} -% I.e., get rid of the environment and do things like in, say, \pkg{fontspec}. % % \subsection{Keeping things consistent} % @@ -607,7 +593,22 @@ Do not distribute a modified version of this file. % \begin{macrocode} \LoadClass{article} \RequirePackage{doc} -\RequirePackage{array,alphalph,booktabs,color,colortbl,fixltx2e,enumitem,pifont,textcomp,trace,underscore,csquotes,fancyvrb} +\RequirePackage + { + array, + alphalph, + booktabs, + color, + colortbl, + fixltx2e, + enumitem, + pifont, + textcomp, + trace, + underscore, + csquotes, + fancyvrb + } \raggedbottom % \end{macrocode} % @@ -900,8 +901,8 @@ Do not distribute a modified version of this file. % \begin{environment}{function} % \begin{environment}{variabledoc} % Environment for documenting function(s). -% Stick the function names in a box. Use a "|" as delimiter and -% allow |<...>| to be used as markup for |\meta{...}|. +% Stick the function names in a box. +% Allow |<...>| to be used as markup for |\meta{...}|. % Ignore spaces and sanitize with catcodes before reading argument. % \begin{macrocode} \char_set_catcode_active:N \< @@ -914,15 +915,14 @@ Do not distribute a modified version of this file. \coffin_clear:N \l_doc_syntax_coffin \coffin_clear:N \l_doc_names_coffin - \bool_gset_false:N \l_doc_meta_TF_bool - \bool_gset_false:N \l_doc_meta_pTF_bool - \bool_gset_false:N \l_doc_meta_EXP_bool - \bool_gset_false:N \l_doc_meta_rEXP_bool + \bool_set_false:N \l_doc_meta_TF_bool + \bool_set_false:N \l_doc_meta_pTF_bool + \bool_set_false:N \l_doc_meta_EXP_bool + \bool_set_false:N \l_doc_meta_rEXP_bool \keys_set:nn { l3doc/function } {#1} - \char_set_catcode_active:N \< - \cs_set_eq:NN < \doc_open_meta:n + \char_set_active_eq:NN < \doc_open_meta:w \group_begin: \MakePrivateLetters @@ -936,10 +936,6 @@ Do not distribute a modified version of this file. } { \vcoffin_set_end: - \hcoffin_set:Nn \l_doc_names_coffin - { - \exp_args:NV \function_typeset:n \l_doc_function_input_tl - } \bool_if:NTF \l_doc_long_name_bool { \coffin_join:NnnNnnnn @@ -1009,40 +1005,32 @@ Do not distribute a modified version of this file. } \cs_gset_nopar:Npn \function_typeset:n #1 { - - \cs_set_nopar:Npn \nextnewline{\cs_gset_nopar:Npn\nextnewline{\\}} \tl_gclear:N \g_doc_macro_tl - \prop_clear:N \l_doc_functions_block_prop - + % populate "\l_doc_functions_block_prop" with info on the functions present: \clist_map_function:nN {#1} \doc_parse_functions:n \small\ttfamily \begin{tabular}{ @{} l @{} r @{} } \toprule - \prop_map_function:NN \l_doc_functions_block_prop \doc_show_functions:nn - \\ - - \bool_if:nF { \tl_if_empty_p:N \l_doc_date_added_tl && - \tl_if_empty_p:N \l_doc_date_updated_tl } - { \midrule } - - \tl_if_empty:NF \l_doc_date_added_tl - { - \multicolumn{2}{@{}r@{}} - { \scriptsize New:\,\l_doc_date_added_tl } \\ - } - - \tl_if_empty:NF \l_doc_date_updated_tl - { - \multicolumn{2}{@{}r@{}} - { \scriptsize Updated:\,\l_doc_date_updated_tl } \\ - } + \prop_map_function:NN \l_doc_functions_block_prop \doc_typeset_functions:nn + \doc_typeset_dates: \bottomrule \end{tabular} \normalfont\normalsize } - +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\doc_parse_functions:n} +% The idea here is to populate "\l_doc_functions_block_prop" with information +% about the functions being typeset and their variants. +% The property list uses a specific format: the keys contained are the function `names' (stripped of signature) with values specified by a comma-separated list containing two brace groups per item: +% \begin{center} +% "> {my_function} => { {" \meta{Nargs 1} "}{" \meta{sig.\ 1} "} , {" \meta{Nargs 2} "}{" \meta{sig.\ 2} "} , ... }" +% \end{center} +% This somewhat arcane syntax is chosen to distinguish between all variants of control sequence that may be being documented here. (With or without \textsf{expl3} function syntax.) +% \begin{macrocode} \prop_new:N \l_doc_functions_block_prop \cs_generate_variant:Nn \prop_put:Nnn {Nxx} \cs_new:Nn \doc_parse_functions:n @@ -1051,10 +1039,10 @@ Do not distribute a modified version of this file. { \tl_gset_eq:NN \l_doc_function_name_prefix_tl \@backslashchar % for the weird functions named "\::N" and so on: - \exp_args:Nx \tl_if_head_eq_charcode:nNTF { \cs_to_str:N #1 } {:} + \exp_args:Nx \tl_if_head_eq_charcode:nNTF { \cs_to_str:N #1 } { : } { % again, no variants: - \prop_put:Nxx \l_doc_functions_block_prop { \cs_to_str:N #1 } { } + \prop_put:Nxx \l_doc_functions_block_prop { \cs_to_str:N #1 } { {-1} {} } } { % finally, for regular old csnames: @@ -1064,12 +1052,19 @@ Do not distribute a modified version of this file. { \prop_put:Nxx \l_doc_functions_block_prop { \cs_get_function_name:N #1 } - { \l_doc_tmp_tl , \cs_get_function_signature:N #1 } + { + \l_doc_tmp_tl , + {\cs_get_arg_count_from_signature:N #1} + {\cs_get_function_signature:N #1} + } } { \prop_put:Nxx \l_doc_functions_block_prop { \cs_get_function_name:N #1 } - { \cs_get_function_signature:N #1 } + { + {\cs_get_arg_count_from_signature:N #1} + {\cs_get_function_signature:N #1} + } } } } @@ -1077,7 +1072,7 @@ Do not distribute a modified version of this file. { % for now don't bother splitting into variants: \tl_gclear:N \l_doc_function_name_prefix_tl - \prop_put:Nxx \l_doc_functions_block_prop { #1 } { } + \prop_put:Nxx \l_doc_functions_block_prop { #1 } { {-1} {} } } } @@ -1087,124 +1082,134 @@ Do not distribute a modified version of this file. % \end{environment} % % -% \begin{macro}{\doc_showmacro:n} -% This macro is passed one of: -% \begin{quote} -% "\abc:cnx / (EXP) / \q_stop" \\ -% "\abc:cnx / \q_stop" \\ -% \end{quote} -% We also have some code here to print out every documented macro at the end -% of the document. +% \begin{macro}{\doc_typeset_functions:nn} % \begin{arguments} -% \item Function/macro/variable name \item Metadata tags (if any) +% \item Function/macro/variable name (stripped of signature in the first case, if any) +% \item Comma-list containing information about the signature variants being documented (if any) % \end{arguments} % \begin{macrocode} -\cs_new:Nn \doc_show_functions:nn +\cs_new:Nn \doc_typeset_functions:nn { \clist_gset:Nn \l_doc_variants_clist {#2} \clist_gpop:NN \l_doc_variants_clist \l_doc_tmp_tl - \exp_args:Nx \doc_showmacro:n - { \exp_not:c {#1 \tl_if_empty:NF \l_doc_tmp_tl { : \l_doc_tmp_tl } } } + \exp_args:Nc \doc_typeset_functions_aux:N + { + #1 + \int_compare:nT { \exp_after:wN \use_i:nn \l_doc_tmp_tl > -1 } {:} + \int_compare:nT { \exp_after:wN \use_i:nn \l_doc_tmp_tl > 0 } + { \exp_after:wN \use_ii:nn \l_doc_tmp_tl } + } + \\ } -\cs_new_nopar:Nn \doc_showmacro:n { +\cs_new_nopar:Nn \doc_typeset_functions_aux:N +{ \bool_if:NT \l_doc_meta_pTF_bool { \tl_set:Nx \l_doc_pTF_name_tl { \doc_predicate_from_base:N #1 } - \doc_special_main_index:o { \token_to_str:N \l_doc_pTF_name_tl } - \seq_gput_right:Nx \g_doc_functions_seq { \tl_to_str:N \l_doc_pTF_name_tl } + \doc_special_main_index:o { \tl_to_str:N \l_doc_pTF_name_tl } + \seq_gput_right:Nx \g_doc_functions_seq { \l_doc_function_name_prefix_tl \l_doc_pTF_name_tl } } \bool_if:NTF \l_doc_meta_TF_bool { \doc_special_main_index:o { \token_to_str:N #1 TF } - \seq_gput_right:Nx \g_doc_functions_seq { \tl_to_str:n { #1 TF } } - \seq_gput_right:Nx \g_doc_functions_seq { \tl_to_str:n { #1 T } } - \seq_gput_right:Nx \g_doc_functions_seq { \tl_to_str:n { #1 F } } + \seq_gput_right:Nx \g_doc_functions_seq { \token_to_str:N #1 TF } }{ \doc_special_main_index:o { \token_to_str:N #1 } - \seq_gput_right:Nx \g_doc_functions_seq { \tl_to_str:n { #1 } } + \seq_gput_right:Nx \g_doc_functions_seq { \tl_to_str:n {#1} } } \bool_if:NTF \l_doc_meta_pTF_bool { + \bool_gset_false:N \l_doc_meta_TF_bool - \exp_args:Nc \doc_showmacro_aux_ii:N \l_doc_pTF_name_tl + \exp_args:Nc \doc_typeset_function_block:N { \l_doc_pTF_name_tl } \bool_gset_true:N \l_doc_meta_TF_bool - \exp_args:Nc \doc_showmacro_aux_ii:N { \cs_to_str:N #1 } + + \\ + \doc_typeset_function_block:N #1 + }{ \exp_args:Nx \tl_if_head_eq_charcode:nNTF { \exp_after:wN \use_none:n \token_to_str:N #1 } {:} - { \doc_showmacro_aux_iii:N #1 } - { \doc_showmacro_aux_ii:N #1 } + { \doc_show_macro_unusual:N #1 } + { \doc_typeset_function_block:N #1 } } } % \end{macrocode} % \end{macro} % -% \begin{macro}[aux]{\doc_showmacro_aux_ii:N} +% \begin{macro}[internal]{\doc_typeset_function_block:N} % \begin{macrocode} -\cs_set_nopar:Nn \doc_showmacro_aux_ii:N { - \nextnewline +\cs_set_nopar:Nn \doc_typeset_function_block:N { \tl_gset:Nx \l_doc_function_name_tl { \cs_get_function_name:N #1 } \tl_gset:Nx \l_doc_function_sig_tl { \cs_get_function_signature:N #1 } \tl_gset:Nx \g_doc_macro_tl { \l_doc_function_name_prefix_tl \l_doc_function_name_tl } - \g_doc_macro_tl - \int_compare:nT { \cs_get_arg_count_from_signature:N #1 >= 0 } - { : \l_doc_function_sig_tl } - + \doc_typeset_function_basename:N #1 \bool_if:NT \l_doc_meta_TF_bool { \doc_typeset_TF: } + \doc_typeset_expandability: + \clist_if_empty:NF \l_doc_variants_clist { \doc_typeset_variants: } + \bool_if:NT \g_doc_full_bool { \doc_label_function: } - & - \bool_if:NT \l_doc_meta_EXP_bool { - \hspace{\tabcolsep} - \hyperlink{expstar} {$\star$} - } - \bool_if:NT \l_doc_meta_rEXP_bool { - \hspace{\tabcolsep} - \hyperlink{rexpstar} {\ding{73}} % hollow star - } - - \clist_if_empty:NF \l_doc_variants_clist - { - \\ - \doc_typeset_aux:n \g_doc_macro_tl : - \int_compare:nTF { \clist_length:N \l_doc_variants_clist == 1 } - { \l_doc_variants_clist } - { - \textrm( - \clist_pop:NN \l_doc_variants_clist \l_doc_tmp_tl - \l_doc_tmp_tl - \clist_map_inline:Nn \l_doc_variants_clist {\textrm|##1} - \textrm) - } - \bool_if:NT \l_doc_meta_TF_bool { \doc_typeset_TF: } - & - \bool_if:NT \l_doc_meta_EXP_bool { - \hspace{\tabcolsep} - \hyperlink{expstar} {$\star$} +} +\cs_set:Nn \doc_typeset_function_basename:N + { + \g_doc_macro_tl + \int_compare:nT { \cs_get_arg_count_from_signature:N #1 > -1 } { : } + \int_compare:nT { \cs_get_arg_count_from_signature:N #1 > 0 } + { \l_doc_function_sig_tl } } - \bool_if:NT \l_doc_meta_rEXP_bool { - \hspace{\tabcolsep} - \hyperlink{rexpstar} {\ding{73}} % hollow star +\cs_set:Nn \doc_typeset_expandability: + { + & + \bool_if:NT \l_doc_meta_EXP_bool { + \hspace{\tabcolsep} + \hyperlink{expstar} {$\star$} + } + \bool_if:NT \l_doc_meta_rEXP_bool { + \hspace{\tabcolsep} + \hyperlink{rexpstar} {\ding{73}} % hollow star + } } +\cs_set:Nn \doc_typeset_variants: + { + \\ + \doc_typeset_aux:n \g_doc_macro_tl : + \int_compare:nTF { \clist_length:N \l_doc_variants_clist == 1 } + { \exp_after:wN \use_ii:nn \l_doc_variants_clist } + { + \textrm( + \clist_pop:NN \l_doc_variants_clist \l_doc_tmp_tl + \exp_after:wN \use_ii:nn \l_doc_tmp_tl + \clist_map_inline:Nn \l_doc_variants_clist {\textrm| \use_ii:nn ##1} + \textrm) + } + \bool_if:NT \l_doc_meta_TF_bool { \doc_typeset_TF: } + & + \bool_if:NT \l_doc_meta_EXP_bool { + \hspace{\tabcolsep} + \hyperlink{expstar} {$\star$} } - - \exp_args:NNf \tl_replace_all:Nnn \g_doc_macro_tl {\token_to_str:N _} {/} - \exp_args:NNf \tl_replace_all:Nnn \g_doc_macro_tl {\@backslashchar} {} - \bool_if:NT \g_doc_full_bool { + \bool_if:NT \l_doc_meta_rEXP_bool { + \hspace{\tabcolsep} + \hyperlink{rexpstar} {\ding{73}} % hollow star + } + } +\cs_set:Nn \doc_label_function: + { + \exp_args:NNf \tl_replace_all:Nnn \g_doc_macro_tl {\token_to_str:N _} {/} + \exp_args:NNf \tl_replace_all:Nnn \g_doc_macro_tl {\@backslashchar} {} \exp_args:Nx \label { doc/function//\g_doc_macro_tl \tl_if_empty:NF \l_doc_function_sig_tl { : \l_doc_function_sig_tl } } } -} % \end{macrocode} % \end{macro} % -% \begin{macro}[aux]{\doc_showmacro_aux_iii:N} +% \begin{macro}[aux]{\doc_show_macro_unusual:N} % This is for the case when the function is one of the weird ones like \cs{::N}. % \begin{macrocode} -\cs_set_nopar:Nn \doc_showmacro_aux_iii:N { - \nextnewline +\cs_set_nopar:Nn \doc_show_macro_unusual:N { \tl_gset:Nx \g_doc_macro_tl { \token_to_str:N #1} \token_to_str:N #1 & @@ -1217,6 +1222,30 @@ Do not distribute a modified version of this file. % \end{macrocode} % \end{macro} % +% \begin{macro}[internal]{\doc_typeset_dates:} +% To display metadata for when functions are added/modified. +% \begin{macrocode} +\cs_set:Nn \doc_typeset_dates: + { + \bool_if:nF { \tl_if_empty_p:N \l_doc_date_added_tl && + \tl_if_empty_p:N \l_doc_date_updated_tl } + { \midrule } + + \tl_if_empty:NF \l_doc_date_added_tl + { + \multicolumn{2}{@{}r@{}} + { \scriptsize New:\,\l_doc_date_added_tl } \\ + } + + \tl_if_empty:NF \l_doc_date_updated_tl + { + \multicolumn{2}{@{}r@{}} + { \scriptsize Updated:\,\l_doc_date_updated_tl } \\ + } + } +% \end{macrocode} +% \end{macro} +% % \begin{environment}{syntax} % Syntax block placed next to the list of functions to illustrate their use. % \begin{macrocode} @@ -1251,55 +1280,68 @@ Do not distribute a modified version of this file. % \end{macrocode} % \end{environment} % -% Perhaps these belong in \file{l3token}? +% \begin{macro}{\doc_ensuremath_sb:n} % \begin{macrocode} -\tl_map_inline:nn {0123456789} { \cs_gset_eq:cN {char_other_#1} #1 } +\cs_new:Npn \doc_ensuremath_sb:n #1 + { + \ensuremath{\sb{#1}} + } % \end{macrocode} +% \end{macro} % -% \begin{macro}{\doc_open_meta:n,\doc_close_meta:n} -% This code turns all numbers within "<...>" markup to be set as subscripts. -% You can use escaped numbers to get the real thing (e.g., "\1" = `1'). +% \begin{macro}{\doc_open_meta:w,\doc_close_meta:n} % \begin{macrocode} -\group_begin: - \tl_map_inline:nn {0123456789} { \char_set_catcode_active:N #1 } - \cs_new:Npn \doc_open_meta:n { +\cs_set_eq:NN \doc_meta:n \meta +\cs_set:Npn \meta + { \group_begin: - \tl_map_function:nN {0123456789} \doc_assign_num:n + \char_set_active_eq:NN _ \doc_ensuremath_sb:n + \doc_close_meta:n + } +\cs_new:Npn \doc_open_meta:w + { + \group_begin: + \char_set_active_eq:NN _ \doc_ensuremath_sb:n \doc_close_meta:w } - \cs_new:Npn \Arg { +\cs_new:Npn \Arg + { \texttt{ \char`\{ } \group_begin: - \tl_map_function:nN {0123456789} \doc_assign_num:n + \char_set_active_eq:NN _ \doc_ensuremath_sb:n \doc_close_Arg:n } -\group_end: -\cs_new_nopar:Npn \doc_close_meta:w #1> { \meta {#1} \group_end: } +\cs_new_nopar:Npn \doc_close_meta:n #1 { \doc_meta:n {#1} \group_end: } +\cs_new_nopar:Npn \doc_close_meta:w #1> { \doc_meta:n {#1} \group_end: } \cs_new_nopar:Npn \doc_close_Arg:n #1 { - \meta {#1} + \doc_meta:n {#1} \group_end: \texttt{ \char`\} } } % \end{macrocode} % \end{macro} % -% \begin{macro}{\doc_assign_num:n} -% This function takes a numeral (`0'), defines its escaped self to be equal -% to itself ("\0" $\to$ `0'), makes it active, and turns itself into a subscript -% instead (`0' $\to$ `${}_0$'). +% \begin{environment}{macro} +% We want to extend the old definition to allow comma-separated lists of +% macros, rather than one at a time. +% +% Keyval: % \begin{macrocode} -\cs_new_nopar:Npn \doc_assign_num:n #1 { - \cs_set_eq:cc { \string #1 } { char_other_\string #1 } - \char_set_catcode_active:N #1 - \cs_set_nopar:Npn #1 { \unskip \, $ {} \sb { \use:c { char_other_\string #1 } } $ } -} +\keys_define:nn { l3doc/macro } + { + aux .code:n = + { \bool_set_true:N \l_doc_macro_aux_bool } , + internal .code:n = + { \bool_set_true:N \l_doc_macro_internal_bool } , + var .code:n = + { \bool_set_true:N \l_doc_macro_var_bool } , + TF .code:n = + { \bool_set_true:N \l_doc_macro_TF_bool } , + pTF .code:n = + { \bool_set_true:N \l_doc_macro_pTF_bool } , + } % \end{macrocode} -% \end{macro} % -% \begin{environment}{macro} -% We want to extend the old definition to allow comma-separated lists of -% macros, rather than one at a time. keyval processing is very rudimentary; -% awaiting a more robust solution. % \begin{macrocode} \renewcommand \macro [1][] { @@ -1307,12 +1349,12 @@ Do not distribute a modified version of this file. { \int_gzero:N \g_doc_nested_macro_int } { \int_incr:N \g_doc_nested_macro_int } - \bool_set_false:N \l_doc_macro_aux_bool - \bool_set_false:N \l_doc_macro_internal_bool - \bool_set_false:N \l_doc_macro_TF_bool - \bool_set_false:N \l_doc_macro_pTF_bool - \bool_set_false:N \l_doc_macro_var_bool - \bool_set_false:N \l_doc_tested_bool + \bool_gset_false:N \l_doc_macro_aux_bool + \bool_gset_false:N \l_doc_macro_internal_bool + \bool_gset_false:N \l_doc_macro_TF_bool + \bool_gset_false:N \l_doc_macro_pTF_bool + \bool_gset_false:N \l_doc_macro_var_bool + \bool_gset_false:N \l_doc_tested_bool \cs_set_eq:NN \doc_macroname_prefix:n \use:n \cs_set_eq:NN \doc_macroname_suffix: \c_empty_tl @@ -1355,23 +1397,16 @@ Do not distribute a modified version of this file. { \clist_map_inline:Nn \l_doc_macro_input_clist { - \exp_args:Nf \doc_macro_single { \doc_predicate_from_base:w ##1 } + \exp_args:Nx \doc_macro_single:n { \doc_predicate_from_base:w ##1 \q_nil } } \bool_set_true:N \l_doc_macro_TF_bool - \clist_map_function:NN \l_doc_macro_input_clist \doc_macro_single + \clist_map_function:NN \l_doc_macro_input_clist \doc_macro_single:n \bool_set_false:N \l_doc_macro_TF_bool } - { \clist_map_function:NN \l_doc_macro_input_clist \doc_macro_single } + { \clist_map_function:NN \l_doc_macro_input_clist \doc_macro_single:n } } % \end{macrocode} % -% \begin{macrocode} -\cs_set_nopar:Npn \doc_macro_opt_aux: { \bool_set_true:N \l_doc_macro_aux_bool } -\cs_set_nopar:Npn \doc_macro_opt_internal: { \bool_set_true:N \l_doc_macro_internal_bool } -\cs_set_nopar:Npn \doc_macro_opt_TF: { \bool_set_true:N \l_doc_macro_TF_bool } -\cs_set_nopar:Npn \doc_macro_opt_pTF: { \bool_set_true:N \l_doc_macro_pTF_bool } -\cs_set_nopar:Npn \doc_macro_opt_var: { \bool_set_true:N \l_doc_macro_var_bool } -% \end{macrocode} % \end{environment} % % \begin{macrocode} @@ -1379,6 +1414,10 @@ Do not distribute a modified version of this file. { \cs_get_function_name:N #1 _p: \cs_get_function_signature:N #1 } +\cs_set:Npn \doc_predicate_from_base:w #1 : #2 \q_nil + { + #1 _p: #2 + } % \end{macrocode} % % \begin{environment}{doc_macro_single} @@ -1389,7 +1428,7 @@ Do not distribute a modified version of this file. % \item Macro/function/whatever name; input has already been sanitised. % \end{arguments} % \begin{macrocode} -\cs_set_nopar:Npn \doc_macro_single #1 { +\cs_set_nopar:Npn \doc_macro_single:n #1 { \int_incr:N \l_doc_macro_int \tl_set:Nx \saved@macroname { \token_to_str:N #1 } \topsep\MacroTopsep @@ -1562,34 +1601,38 @@ Do not distribute a modified version of this file. % % \begin{macro}{\endmacro} % \begin{macrocode} +\cs_set:Nn \doc_macro_wrap:n + { + #1 \bool_if:NT \l_doc_macro_TF_bool {TF} + } \cs_set:Nn \doc_texttt_comma:n {\,,~\texttt{#1}} \cs_set:Npn \endmacro { \int_compare:nT {\g_doc_nested_macro_int<1} { - \par\nobreak{\footnotesize(\emph{ + \par\nobreak\noindent{\footnotesize(\emph{ End~ definition~ for~ \prg_case_int:nnn { \clist_length:N \l_doc_macro_input_clist } { - {1} { \texttt{ \clist_use:N \l_doc_macro_input_clist }. } + {1} { \texttt{ \doc_macro_wrap:n { \clist_use:N \l_doc_macro_input_clist } }. } {2} { \tl_set:Nx \l_clist_first_tl { \clist_item:Nn \l_doc_macro_input_clist {0} } \tl_set:Nx \l_clist_last_tl { \clist_item:Nn \l_doc_macro_input_clist {1} } - \texttt{\l_clist_first_tl}\,~ and~ \texttt{\l_clist_last_tl}\,. + \texttt{\doc_macro_wrap:n\l_clist_first_tl}\,~ and~ \texttt{\doc_macro_wrap:n\l_clist_last_tl}\,. } {3} { \tl_set:Nx \l_clist_first_tl { \clist_item:Nn \l_doc_macro_input_clist {0} } \tl_set:Nx \l_clist_mid_tl { \clist_item:Nn \l_doc_macro_input_clist {1} } \tl_set:Nx \l_clist_last_tl { \clist_item:Nn \l_doc_macro_input_clist {2} } - \texttt{\l_clist_first_tl}\,,~ - \texttt{\l_clist_mid_tl}\,,~ - and~ \texttt{\l_clist_last_tl}\,. + \texttt{\doc_macro_wrap:n\l_clist_first_tl}\,,~ + \texttt{\doc_macro_wrap:n\l_clist_mid_tl}\,,~ + and~ \texttt{\doc_macro_wrap:n\l_clist_last_tl}\,. } } { \tl_set:Nx \l_clist_first_tl { \clist_item:Nn \l_doc_macro_input_clist {0} } - \texttt{\l_clist_first_tl}\,~and~others. + \texttt{\doc_macro_wrap:n\l_clist_first_tl}\,~and~others. } \bool_if:nT { !\l_doc_macro_aux_bool && @@ -2207,16 +2250,18 @@ page_precedence "rnaA" % \end{macrocode} % % \section{Testing} -%\ExplSyntaxOn -%\cs_set_eq:NN\g_saved_doc_functions_seq\g_doc_functions_seq -%\cs_set_eq:NN\g_saved_doc_macros_seq\g_doc_macros_seq -%\ExplSyntaxOff +% +% \begin{function}{foo} +% \begin{syntax} +% "\foo" <something_n> \Arg{something_1} +% \end{syntax} +% Does <something_1> with <something_n> +% \end{function} % % \begin{function}{.bool_set:N} % blah % \end{function} % -% \lipsum[2] % \ExplSyntaxOn \cs_set_eq:NN \c_alignment_token @ \ExplSyntaxOff % \begin{variabledoc} % { @@ -2227,17 +2272,17 @@ page_precedence "rnaA" % % \begin{function}[added=2011-09-06]{\example_foo:N,\example_foo:c} % \begin{syntax} -% "\example_foo:N" <arg1> -% "\example_foo:c" \Arg{arg1} +% "\example_foo:N" <arg_1> +% "\example_foo:c" \Arg{arg_1} % \end{syntax} -% <0123456789> <\0\1\2\3\4\5\6\7\8\9> \Arg{arg1} ":(" +% <0123456789> % \end{function} % -% \begin{function}[added=2011-09-06]{ \foo , \foo: , \foo:x , \barrz: } +% \begin{function}[added=2011-09-06]{ \foo , \fooo: , \foooo:n , \foooo:x , \fooooo:n , \fooooo:c , \fooooo:x } % \begin{syntax} -% "\example_foo:N" <arg1> +% "\example_foo:N" <arg_1> % \end{syntax} -% <0123456789> <\0\1\2\3\4\5\6\7\8\9> +% <0123456789> % \end{function} % % \begin{function}[TF]{\foo:N , \foo_if:c } @@ -2295,17 +2340,22 @@ page_precedence "rnaA" % \bigskip\bigskip % % \begin{macro}[aux]{ \foo_aux: } -% Testing. +% Testing `aux' option. % \end{macro} % -% \bigskip\bigskip -% % \begin{macro}[TF]{ \foo_if:c } -% Testing. +% Testing `TF' option. +% \end{macro} +% \begin{macro}[TF]{ \foo_if:c, \fooo_if:n } +% Testing `TF' option. +% \end{macro} +% +% \begin{macro}[pTF]{ \foo_if:d } +% Testing `pTF' option. % \end{macro} % -% \begin{macro}[internal]{ \foo_if:d } -% Testing. +% \begin{macro}[internal]{ \test_internal: } +% Testing `internal' option. % \end{macro} % % \bigskip\bigskip @@ -2364,10 +2414,6 @@ page_precedence "rnaA" % \end{macro} % % -%\ExplSyntaxOn -%\cs_set_eq:NN\g_doc_functions_seq\g_saved_doc_functions_seq -%\cs_set_eq:NN\g_doc_macros_seq\g_saved_doc_macros_seq -%\ExplSyntaxOff % % % \subsection{Macros} diff --git a/Master/texmf-dist/source/latex/l3kernel/l3expan.dtx b/Master/texmf-dist/source/latex/l3kernel/l3expan.dtx index 863413fa019..01024ff6593 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3expan.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3expan.dtx @@ -35,7 +35,7 @@ % %<*driver|package> \RequirePackage{l3names} -\GetIdInfo$Id: l3expan.dtx 3196 2012-01-15 09:44:05Z joseph $ +\GetIdInfo$Id: l3expan.dtx 3460 2012-02-26 12:16:41Z will $ {L3 Experimental argument expansion} %</driver|package> %<*driver> @@ -336,7 +336,7 @@ % \exp_args:Nnc % } % \begin{syntax} -% \cs{exp_args:Noo} \meta{token} \Arg{tokens1} \Arg{tokens2} +% \cs{exp_args:Noo} \meta{token} \Arg{tokens_1} \Arg{tokens_2} % \end{syntax} % These functions absorb three arguments and expand the second and % third as detailed by their argument specifier. The first argument @@ -413,7 +413,7 @@ % \exp_args:Nccx % } % \begin{syntax} -% \cs{exp_args:NNnx} \meta{token1} \meta{token2} \Arg{tokens1} \Arg{tokens2} +% \cs{exp_args:NNnx} \meta{token1} \meta{token2} \Arg{tokens_1} \Arg{tokens_2} % \end{syntax} % These functions absorb four arguments and expand the second, third % and fourth as detailed by their argument specifier. The first @@ -423,7 +423,7 @@ % % \section{Unbraced expansion} % -% \begin{function}[EXP] +% \begin{function}[EXP, updated = 2012-02-12] % { % \exp_last_unbraced:Nf, % \exp_last_unbraced:NV, @@ -437,7 +437,8 @@ % \exp_last_unbraced:Noo, % \exp_last_unbraced:Nfo, % \exp_last_unbraced:NNNV, -% \exp_last_unbraced:NNNo +% \exp_last_unbraced:NNNo, +% \exp_last_unbraced:NnNo % } % \begin{syntax} % \cs{exp_last_unbraced:Nno} \meta{token} \meta{tokens1} \meta{tokens2} @@ -468,7 +469,7 @@ % % \begin{function}[EXP]{\exp_last_two_unbraced:Noo} % \begin{syntax} -% \cs{exp_last_two_unbraced:Noo} \meta{token} \meta{tokens1} \Arg{tokens2} +% \cs{exp_last_two_unbraced:Noo} \meta{token} \meta{tokens1} \Arg{tokens_2} % \end{syntax} % This function absorbs three arguments and expand the second and third % once. The first argument of the function is then the next item on the @@ -481,14 +482,15 @@ % \begin{syntax} % \cs{exp_after:wN} \meta{token1} \meta{token2} % \end{syntax} -% Carries out a single expansion of \meta{token2} prior to expansion +% Carries out a single expansion of \meta{token2} (which may consume +% arguments) prior to the expansion % of \meta{token1}. If \meta{token2} is a \TeX{} primitive, it will % be executed rather than expanded, while if \meta{token2} has not % expansion (for example, if it is a character) then it will be left % unchanged. It is important to notice that \meta{token1} may be % \emph{any} single token, including group-opening and -closing % tokens (|{| or |}| assuming normal \TeX{} category codes). Unless -% specifically required, expansion should be carried out using an +% specifically required, expansion should be carried out using an % appropriate argument specifier variant or the appropriate % \cs{exp_arg:N} function. % \begin{texnote} @@ -1165,6 +1167,7 @@ % \begin{macro}[EXP]{\exp_last_unbraced:Nno} % \begin{macro}[EXP]{\exp_last_unbraced:Noo} % \begin{macro}[EXP]{\exp_last_unbraced:Nfo} +% \begin{macro}[EXP]{\exp_last_unbraced:NnNo} % \begin{macro}{\exp_last_unbraced:Nx} % Now the business end: most of these are hand-tuned for speed, but the % general system is in place. @@ -1204,6 +1207,7 @@ \cs_new_nopar:Npn \exp_last_unbraced:Nno { \::n \::o_unbraced \::: } \cs_new_nopar:Npn \exp_last_unbraced:Noo { \::o \::o_unbraced \::: } \cs_new_nopar:Npn \exp_last_unbraced:Nfo { \::f \::o_unbraced \::: } +\cs_new_nopar:Npn \exp_last_unbraced:NnNo { \::n \::N \::o_unbraced \::: } \cs_new_protected_nopar:Npn \exp_last_unbraced:Nx { \::x_unbraced \::: } % \end{macrocode} % \end{macro} @@ -1220,6 +1224,7 @@ % \end{macro} % \end{macro} % \end{macro} +% \end{macro} % % \begin{macro}[EXP]{\exp_last_two_unbraced:Noo} % If |#2| is a single token then this can be implemented as diff --git a/Master/texmf-dist/source/latex/l3kernel/l3file.dtx b/Master/texmf-dist/source/latex/l3kernel/l3file.dtx index 12ce5b17b17..28f53230235 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3file.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3file.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -%% File: l3file.dtx Copyright (C) 2009-2012 The LaTeX3 Project +%% File: l3file.dtx Copyright (C) 1990-2012 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 @@ -35,8 +35,8 @@ % %<*driver|package> \RequirePackage{l3names} -\GetIdInfo$Id: l3file.dtx 3287 2012-01-31 22:08:14Z joseph $ - {L3 Experimental file operations} +\GetIdInfo$Id: l3file.dtx 3464 2012-02-26 15:30:29Z bruno $ + {L3 Experimental file and I/O operations} %</driver|package> %<*driver> \documentclass[full]{l3doc} @@ -47,7 +47,7 @@ % \fi % % \title{^^A -% The \pkg{l3file} package\\ File operations^^A +% The \pkg{l3file} package\\ File and I/O operations^^A % \thanks{This file describes v\ExplFileVersion, % last revised \ExplFileDate.}^^A % } @@ -67,16 +67,16 @@ % % \begin{documentation} % -% In contrast to the \pkg{l3io} module, which deals with the lowest -% level of file management, the \pkg{l3file} module provides a higher -% level interface for handling file contents. This involves providing -% convenient wrappers around many of the functions in \pkg{l3io} -% to make them more generally accessible. +% This module provides functions for working with external files. Some of these +% functions apply to an entire file, and have prefix \cs{file_\ldots}, while +% others are used to work with files on a line by line basis and have prefix +% \cs{ior_\ldots} (reading) or \cs{iow_\ldots} (writing). % -% It is important to remember that \TeX{} will attempt to locate files using -% both the operating system path and entries in the \TeX{} file database (most -% \TeX{} systems use such a database). Thus the \enquote{current path} for -% \TeX{} is somewhat broader than that for other programs. +% It is important to remember that when reading external files \TeX{} will +% attempt to locate them both the operating system path and entries in the +% \TeX{} file database (most \TeX{} systems use such a database). Thus the +% \enquote{current path} for \TeX{} is somewhat broader than that for other +% programs. % % \section{File operation functions} % @@ -88,7 +88,7 @@ % \cs{file_input:n}. % \end{variable} % -% \begin{function}[TF, updated = 2012-01-25]{\file_if_exist:n} +% \begin{function}[TF, updated = 2012-02-10]{\file_if_exist:n} % \begin{syntax} % \cs{file_if_exist:nTF} \Arg{file name} \Arg{true code} \Arg{false code} % \end{syntax} @@ -102,14 +102,15 @@ % \end{texnote} % \end{function} % -% \begin{function}[updated = 2012-01-25]{\file_add_path:nN} +% \begin{function}[updated = 2012-02-10]{\file_add_path:nN} % \begin{syntax} % \cs{file_add_path:nN} \Arg{file name} \meta{tl var} % \end{syntax} % Searches for \meta{file name} in the path as detailed for % \cs{file_if_exist:nTF}, and if found sets the \meta{tl var} the % fully-qualified name of the file, \emph{i.e}.~the path and file name. -% If the file is not found then the \meta{tl var} will be empty. +% If the file is not found then the \meta{tl var} will contain the +% marker \cs{q_no_value}. % \begin{texnote} % The \meta{file name} may contain both literal items and expandable % content, which should on full expansion be the desired file name. @@ -119,7 +120,7 @@ % \end{texnote} % \end{function} % -% \begin{function}[updated = 2012-01-25]{\file_input:n} +% \begin{function}[updated = 2012-02-17]{\file_input:n} % \begin{syntax} % \cs{file_input:n} \Arg{file name} % \end{syntax} @@ -127,7 +128,7 @@ % \cs{file_if_exist:nTF}, and if found reads in the file as % additional \LaTeX{} source. All files read are recorded % for information and the file name stack is updated by this -% function. +% function. An error will be raised if the file is not found % \begin{texnote} % The \meta{file name} may contain both literal items and expandable % content, which should on full expansion be the desired file name. @@ -137,24 +138,63 @@ % \end{texnote} % \end{function} % -% \begin{function}[added = 2012-01-25]{\file_split_path_name_ext:nNNN} +% \begin{function}{\file_path_include:n} % \begin{syntax} -% \cs{file_split_path_name_ext:nNNN} \Arg{name} \meta{path} \meta{filename} \meta{ext} +% \cs{file_path_include:n} \Arg{path} % \end{syntax} -% Splits the file \meta{name} into any \meta{path} (up to the last |/|), -% any \meta{ext} (from the last |.| to the end of the \meta{name}), -% and the the \meta{filename} (the rest of the \meta{name}). Thus for -% example -% \begin{verbatim} -% \file_split_path_name_ext:nNNN { figures / example.foo.eps } -% \end{verbatim} -% will result in \meta{path} \texttt{figures/}, \meta{filename} -% \texttt{example.foo} and \meta{ext} \texttt{eps}. -% The three parts of the \meta{name} will be stored in the -% token list variables given as the \meta{name}, \meta{path} and -% \meta{filename} arguments. +% Adds \meta{path} to the list of those used to search when reading +% files. The assignment is local. +% \end{function} +% +% \begin{function}{\file_path_remove:n} +% \begin{syntax} +% \cs{file_path_remove:n} \Arg{path} +% \end{syntax} +% Removes \meta{path} from the list of those used to search when reading +% files. The assignment is local. +% \end{function} +% +% \begin{function}{\file_list:} +% \begin{syntax} +% \cs{file_list:} +% \end{syntax} +% This function will list all files loaded using \cs{file_input:n} +% in the log file. +% \end{function} +% +% \subsection{Input--output stream management} +% +% As \TeX{} is limited to $16$ input streams and $16$ output streams, direct +% use of the streams by the programmer is not supported in \LaTeX3. Instead, an +% internal pool of streams is maintained, and these are allocated and +% deallocated as needed by other modules. As a result, the programmer should +% close streams when they are no longer needed, to release them for other +% processes. +% +% \begin{function}[added = 2011-09-26, updated = 2011-12-27] +% {\ior_new:N, \ior_new:c, \iow_new:N, \iow_new:c} +% \begin{syntax} +% \cs{ior_new:Nn} \meta{stream} +% \end{syntax} +% Globally reserves the name of the \meta{stream}, either for reading +% or for writing as appropriate. The \meta{stream} is not opened until the +% appropriate \cs{\ldots_open:Nn} function is used. Attempting to use +% a \meta{stream} which has not been opened will result in a \TeX{} +% error. +% \end{function} +% +% \begin{function}[updated = 2012-02-10]{\ior_open:Nn, \ior_open:cn} +% \begin{syntax} +% \cs{ior_open:Nn} \meta{stream} \Arg{file name} +% \end{syntax} +% Opens \meta{file name} for reading using \meta{stream} as the +% control sequence for file access. If the \meta{stream} was already +% open it is closed before the new operation begins. The +% \meta{stream} is available for access immediately and will remain +% allocated to \meta{file name} until a \cs{ior_close:N} instruction +% is given or the file ends. % \begin{texnote} -% The \meta{name} may contain both literal items and expandable +% The \meta{file name} may contain both literal items and expandable % content, which should on full expansion be the desired file name. % Any active characters (as declared in \cs{l_char_active_seq}) will % \emph{not} be expanded, allowing the direct use of these in @@ -162,30 +202,278 @@ % \end{texnote} % \end{function} % -% \begin{function}{\file_path_include:n} +% \begin{function}[updated = 2012-02-09]{\iow_open:Nn, \iow_open:cn} % \begin{syntax} -% \cs{file_path_include:n} \Arg{path} +% \cs{iow_open:Nn} \meta{stream} \Arg{file name} +% \end{syntax} +% Opens \meta{file name} for writing using \meta{stream} as the +% control sequence for file access. If the \meta{stream} was already +% open it is closed before the new operation begins. The +% \meta{stream} is available for access immediately and will remain +% allocated to \meta{file name} until a \cs{iow_close:N} instruction +% is given or the file ends. Opening a file for writing will clear +% any existing content in the file (\emph{i.e.}~writing is \emph{not} +% additive). +% \begin{texnote} +% The \meta{file name} may contain both literal items and expandable +% content, which should on full expansion be the desired file name. +% Any active characters (as declared in \cs{l_char_active_seq}) will +% \emph{not} be expanded, allowing the direct use of these in +% file names. +% \end{texnote} +% \end{function} +% +% \begin{function}[updated = 2011-12-27]{\ior_close:N, \ior_close:c} +% \begin{syntax} +% \cs{ior_close:N} \meta{stream} % \end{syntax} -% Adds \meta{path} to the list of those used to search for files -% by the \cs{file_input:n} and \cs{file_if_exist:n} function. The -% assignment is local. +% Closes the \meta{stream}. Streams should always be closed when +% they are finished with as this ensures that they remain available +% to other programmer. % \end{function} % -% \begin{function}{\file_path_remove:n} +% \begin{function}[updated = 2011-12-27]{\iow_close:N, \iow_close:c} % \begin{syntax} -% \cs{file_path_remove:n} \Arg{path} +% \cs{iow_close:N} \meta{stream} % \end{syntax} -% Removes \meta{path} from the list of those used to search for files -% by the \cs{file_input:n} and \cs{file_if_exist:n} function. The -% assignment is local. +% Closes the \meta{stream}. Streams should always be closed when +% they are finished with as this ensures that they remain available +% to other programmer. % \end{function} % -% \begin{function}{\file_list:} +% \begin{function}{\ior_list_streams:, \iow_list_streams:} % \begin{syntax} -% \cs{file_list:} +% \cs{ior_list_streams:} +% \cs{iow_list_streams:} % \end{syntax} -% This function will list all files loaded using \cs{file_input:n} -% in the log file. +% Displays a list of the file names associated with each open +% stream: intended for tracking down problems. +% \end{function} +% +% \section{Reading from files} +% +% \begin{function}{\ior_to:NN,\ior_gto:NN} +% \begin{syntax} +% \cs{ior_to:NN} \meta{stream} \meta{token list variable} +% \end{syntax} +% Functions that reads one or more lines (until an equal number of left +% and right braces are found) from the input \meta{stream} and stores +% the result in the \meta{token list} variable, locally or globally. If the +% \meta{stream} is not open, input is requested from the terminal. +% The material read from the \meta{stream} will be tokenized by +% \TeX{} according to the category codes in force when the function +% is used. +% \begin{texnote} +% This protected macro expands to the \TeX{} primitives \tn{read} +% or \tn{global}\tn{read} along with the |to| keyword. +% \end{texnote} +% \end{function} +% +% \begin{function}{\ior_str_to:NN,\ior_str_gto:NN} +% \begin{syntax} +% \cs{ior_str_to:NN} \meta{stream} \meta{token list variable} +% \end{syntax} +% Functions that reads one line from the input \meta{stream} and stores +% the result in the \meta{token list} variable, locally or globally. If the +% \meta{stream} is not open, input is requested from the terminal. +% The material read from the \meta{stream} as a series of tokens with +% category code $12$ (other), with the exception of space +% characters which are given category code $10$ (space). +% \begin{texnote} +% This protected macro expands to the \eTeX{} primitives \tn{readline} +% or \tn{global}\tn{readline} along with the |to| keyword. +% \end{texnote} +% \end{function} +% +%\begin{function}[updated = 2012-02-10, EXP, pTF]{\ior_if_eof:N} +% \begin{syntax} +% \cs{ior_if_eof_p:N} \meta{stream} \\ +% \cs{ior_if_eof:NTF} \meta{stream} \Arg{true code} \Arg{false code} +% \end{syntax} +% 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. +%\end{function} +% +% \section{Writing to files} +% +% \begin{function}{\iow_now:Nn, \iow_now:Nx} +% \begin{syntax} +% \cs{iow_now:Nn} \meta{stream} \Arg{tokens} +% \end{syntax} +% This functions writes \meta{tokens} to the specified +% \meta{stream} immediately (\emph{i.e.}~the write operation is called +% on expansion of \cs{iow_now:Nn}). +% \begin{texnote} +% \cs{iow_now:Nx} is a protected macro which expands to +% the two \TeX{} primitives \tn{immediate}\tn{write}. +% \end{texnote} +% \end{function} +% +% \begin{function}{\iow_log:n, \iow_log:x} +% \begin{syntax} +% \cs{iow_log:n} \Arg{tokens} +% \end{syntax} +% This function writes the given \meta{tokens} to the log (transcript) +% file immediately: it is a dedicated version of \cs{iow_now:Nn}. +% \end{function} +% +% \begin{function}{\iow_term:n, \iow_term:x} +% \begin{syntax} +% \cs{iow_term:n} \Arg{tokens} +% \end{syntax} +% This function writes the given \meta{tokens} to the terminal +% file immediately: it is a dedicated version of \cs{iow_now:Nn}. +% \end{function} +% +% \begin{function}{\iow_shipout:Nn, \iow_shipout:Nx} +% \begin{syntax} +% \cs{iow_shipout:Nn} \meta{stream} \Arg{tokens} +% \end{syntax} +% This functions writes \meta{tokens} to the specified +% \meta{stream} when the current page is finalised (\emph{i.e.}~at +% shipout). The \texttt{x}-type variants expand the \meta{tokens} +% at the point where the function is used but \emph{not} when the +% resulting tokens are written to the \meta{stream} +% (\emph{cf.}~\cs{iow_shipout_x:Nn}). +% \end{function} +% +% \begin{function}{\iow_shipout_x:Nn, \iow_shipout_x:Nx} +% \begin{syntax} +% \cs{iow_shipout_x:Nn} \meta{stream} \Arg{tokens} +% \end{syntax} +% This functions writes \meta{tokens} to the specified +% \meta{stream} when the current page is finalised (\emph{i.e.}~at +% shipout). The \meta{tokens} are expanded at the time of writing +% in addition to any expansion when the function is used. This makes +% these functions suitable for including material finalised during +% the page building process (such as the page number integer). +% \begin{texnote} +% \cs{iow_shipout_x:Nn} is the \TeX{} primitive \tn{write} renamed. +% \end{texnote} +% \end{function} +% +% \begin{function}[EXP]{\iow_char:N} +% \begin{syntax} +% \cs{iow_char:N} \meta{token} +% \end{syntax} +% Inserts \meta{token} into the output stream. Useful when trying to +% write difficult characters such as |%|, |{|, |}|, +% \emph{etc.}~in messages, for example: +% \begin{verbatim} +% \iow_now:Nx \g_my_iow { \iow_char:N \{ text \iow_char:N \} } +% \end{verbatim} +% The function has no effect if writing is taking place without +% expansion (\emph{e.g.}~in the second argument of \cs{iow_now:Nn}). +% \end{function} +% +% \begin{function}[EXP]{\iow_newline:} +% \begin{syntax} +% \cs{iow_newline:} +% \end{syntax} +% Function to add a new line within the \meta{tokens} written to a +% file. The function has no effect if writing is taking place without +% expansion (\emph{e.g.}~in the second argument of \cs{iow_now:Nn}). +% \end{function} +% +% \section{Wrapping lines in output} +% +% \begin{function}[updated = 2011-09-21]{\iow_wrap:xnnnN} +% \begin{syntax} +% \cs{iow_wrap:xnnnN} \Arg{text} \Arg{run-on text} \Arg{run-on length} \Arg{set up} \meta{function} +% \end{syntax} +% This function will wrap the \meta{text} to a fixed number of +% characters per line. At the start of each line which is wrapped, +% the \meta{run-on text} will be inserted. The line length targeted +% will be the value of \cs{l_iow_line_length_int} minus the +% \meta{run-on length}. The later value should be the number of +% characters in the \meta{run-on text}. Additional functions may be +% added to the wrapping by using the \meta{set up}, which is executed +% before the wrapping takes place. The result of the wrapping operation +% is passed as a braced argument to the \meta{function}, which will +% typically be a wrapper around a writing operation. Within the +% \meta{text}, +% \begin{itemize} +% \item |\\| may be used to force a new line, +% \item \verb|\ | may be used to represent a forced space +% (for example after a control sequence), +% \item |\#|, |\%|, |\{|, |\}|, |\~| may be used to represent +% the corresponding character, +% \item \cs{iow_indent:n} may be used to indent a part of the +% message. +% \end{itemize} +% Both the wrapping process and the subsequent write operation +% will perform \texttt{x}-type expansion. For this reason, material which +% is to be written \enquote{as is} should be given as the argument to +% \cs{token_to_str:N} or \cs{tl_to_str:n} (as appropriate) within +% the \meta{text}. The output of \cs{iow_wrap:xnnnN} (\emph{i.e.}~the +% argument passed to the \meta{function}) will consist of characters of +% category code $12$ (other) and $10$ (space) only. This means that the +% output will \emph{not} expand further when written to a file. +% \end{function} +% +% \begin{function}[added = 2011-09-21]{\iow_indent:n} +% \begin{syntax} +% \cs{iow_indent:n} \Arg{text} +% \end{syntax} +% In the context of \cs{iow_wrap:xnnnN} (for instance in messages), +% indents \meta{text} by four spaces. This function will not cause +% a line break, and only affects lines which start within the scope +% of the \meta{text}. In case the indented \meta{text} should appear +% on separate lines from the surrounding text, use |\\| to force +% line breaks. +% \end{function} +% +% \begin{variable}{\l_iow_line_length_int} +% The maximum length of a line to be written by the \cs{iow_wrap:xxnnN} +% function. This value depends on the \TeX{} system in use: the standard +% value is $78$, which is typically correct for unmodified \TeX{}live +% and MiK\TeX{} systems. +% \end{variable} +% +% \begin{variable}[added = 2011-09-05]{\c_catcode_other_space_tl} +% Token list containing one character with category code $12$, +% (\enquote{other}), and character code $32$ (space). +% \end{variable} +% +% \section{Constant input--output streams} +% +% \begin{variable}{\c_term_ior} +% Constant input stream for reading from the terminal. Reading from this +% stream using \cs{ior_to:NN} or similar will result in a prompt from +% \TeX{} of the form +% \begin{verbatim} +% <tl>= +% \end{verbatim} +% \end{variable} +% +% \begin{variable}{\c_log_iow, \c_term_iow} +% Constant output streams for writing to the log and to the terminal +% (plus the log), respectively. +% \end{variable} +% +% \section{Experimental functions} +% +% \begin{function}[added = 2012-02-11]{\ior_map_inline:Nn} +% \begin{syntax} +% \cs{ior_map_inline:Nn} \meta{stream} \Arg{inline function} +% \end{syntax} +% Applies the \meta{inline function} to \meta{items} obtained by +% reading one or more lines (until an equal number of left and right +% braces are found) from the \meta{stream}. The \meta{inline function} +% should consist of code which will receive the \meta{line} as |#1|. +% \end{function} +% +% \begin{function}[added = 2012-02-11]{\ior_str_map_inline:nn} +% \begin{syntax} +% \cs{ior_str_map_inline:Nn} \Arg{stream} \Arg{inline function} +% \end{syntax} +% Applies the \meta{inline function} to every \meta{line} +% in the \meta{file}. The material is read from the \meta{stream} +% as a series of tokens with category code $12$ (other), with the +% exception of space characters which are given category code $10$ +% (space). The \meta{inline function} should consist of code which +% will receive the \meta{line} as |#1|. % \end{function} % % \section{Internal file functions} @@ -220,6 +508,67 @@ % the comma lists \tn{input@path} and \tn{@filelist} to sequences. % \end{variable} % +% \section{Internal input--output functions} +% +% \begin{function}[added = 2012-02-09]{\file_name_sanitize:nn} +% \begin{syntax} +% \cs{file_name_sanitize:nn} \Arg{name} \Arg{tokens} +% \end{syntax} +% Exhaustively-expands the \meta{name} with the exception of any +% category \meta{active} (catcode~$12$) tokens, which are not expanded. +% The list of \meta{active} tokens is taken from \cs{l_char_active_seq}. +% The \meta{sanitized name} is then inserted (in braces) after the +% \meta{tokens}, which should further process the file name. If any +% spaces are found in the name after expansion, an error is raised. +% \end{function} +% +% \begin{function}[EXP]{\if_eof:w} +% \begin{syntax} +% \cs{if_eof:w} \meta{stream} +% ~~\meta{true code} +% \cs{else:} +% ~~\meta{false code} +% \cs{fi:} +% \end{syntax} +% Tests if the \meta{stream} returns \enquote{end of file}, which is true +% for non-existent files. The \cs{else:} branch is optional. +% \begin{texnote} +% This is the \TeX{} primitive \tn{ifeof}. +% \end{texnote} +% \end{function} +% +% \begin{function}[added = 2012-01-23] +% {\ior_open_unsafe:Nn, \ior_open_unsafe:No, \iow_open_unsafe:Nn} +% \begin{syntax} +% \cs{ior_open_unsafe:Nn} \meta{stream} \Arg{file name} +% \end{syntax} +% These functions have identical syntax to the generally-available +% versions without the |_unsafe| suffix. However, these functions do not +% take precautions against active characters in the \meta{file name}: they +% are therefore intended to be used by higher-level functions which +% have already fully expanded the \meta{file name} and which need to +% perform multiple open or close operations. See for example the +% implementation of \cs{file_add_path:Nn}, +% \end{function} +% +% \begin{function}{\ior_raw_new:N, \ior_raw_new:c} +% \begin{syntax} +% \cs{ior_raw_new:N} \meta{stream} +% \end{syntax} +% Directly allocates a new stream for reading, bypassing the stack +% system. This is to be used only when a new stream is required at a +% \TeX{} level, when a new stream is requested by the stack itself. +% \end{function} +% +% \begin{function}{\iow_raw_new:N, \iow_raw_new:c} +% \begin{syntax} +% \cs{iow_raw_new:N} \meta{stream} +% \end{syntax} +% Directly allocates a new stream for writing, bypassing the stack +% system. This is to be used only when a new stream is required at a +% \TeX{} level, when a new stream is requested by the stack itself. +% \end{function} +% % \end{documentation} % % \begin{implementation} @@ -240,6 +589,8 @@ %</package> % \end{macrocode} % +% \subsection{File operations} +% % \begin{variable}{\g_file_current_name_tl} % The name of the current file should be available at all times. % \begin{macrocode} @@ -318,8 +669,33 @@ % \end{macrocode} % \end{variable} % +% \begin{macro}[int]{\file_name_sanitize:nn} +% For converting a token list to a string where active characters are treated +% as strings from the start. +% \begin{macrocode} +\cs_new_protected:Npn \file_name_sanitize:nn #1#2 + { + \group_begin: + \seq_map_inline:Nn \l_char_active_seq + { \cs_set_nopar:Npx ##1 { \token_to_str:N ##1 } } + \tl_set:Nx \l_file_internal_name_tl {#1} + \tl_set:Nx \l_file_internal_name_tl + { \tl_to_str:N \l_file_internal_name_tl } + \tl_if_in:NnTF \l_file_internal_name_tl { ~ } + { + \msg_kernel_error:nnx { file } { space-in-file-name } + { \l_file_internal_name_tl } + } + \use:x + { + \group_end: + \exp_not:n {#2} { \l_file_internal_name_tl } + } + } +% \end{macrocode} +% \end{macro} +% % \begin{macro}{\file_add_path:nN} -% \begin{variable}{\g_file_internal_ior} % \begin{macro}[aux]{\file_add_path_aux:nN, \file_add_path_search:nN} % The way to test if a file exists is to try to open it: if it does not % exist then \TeX{} will report end-of-file. For files which are in the @@ -328,19 +704,8 @@ % location is of course treated as the correct one. If nothing is found, % |#2| is returned empty. % \begin{macrocode} -\ior_new:N \g_file_internal_ior \cs_new_protected:Npn \file_add_path:nN #1 - { - \group_begin: - \tl_to_str_active_safe:Nx \l_file_internal_name_tl {#1} - \tl_if_in:NnT \l_file_internal_name_tl { ~ } - { - \msg_kernel_error:nnx { io } { space-in-file-name } - { \l_file_internal_name_tl } - } - \exp_args:NNo \group_end: - \file_add_path_aux:nN \l_file_internal_name_tl - } + { \file_name_sanitize:nn {#1} { \file_add_path_aux:nN } } \cs_new_protected:Npn \file_add_path_aux:nN #1#2 { \ior_open_unsafe:Nn \g_file_internal_ior {#1} @@ -353,7 +718,7 @@ } \cs_new_protected:Npn \file_add_path_search:nN #1#2 { - \tl_clear:N #2 + \tl_set:Nn #2 { \q_no_value } %<*package> \cs_if_exist:NT \input@path { @@ -380,7 +745,6 @@ } % \end{macrocode} % \end{macro} -% \end{variable} % \end{macro} % % \begin{macro}[TF]{\file_if_exist:n} @@ -389,10 +753,10 @@ % something, whereas if the file was not located then the return value % will be empty. % \begin{macrocode} -\prg_new_protected_conditional:Nnn \file_if_exist:n { T , F , TF } +\prg_new_protected_conditional:Npnn \file_if_exist:n #1 { T , F , TF } { \file_add_path:nN {#1} \l_file_internal_name_tl - \tl_if_empty:NTF \l_file_internal_name_tl + \quark_if_no_value:NTF \l_file_internal_name_tl { \prg_return_false: } { \prg_return_true: } } @@ -400,126 +764,1053 @@ % \end{macro} % % \begin{macro}{\file_input:n} +% \begin{macro}[aux]{\file_input_aux:n \file_input_aux:V, \file_input_error:n} % Loading a file is done in a safe way, checking first that the file % exists and loading only if it does. % \begin{macrocode} \cs_new_protected:Npn \file_input:n #1 { \file_add_path:nN {#1} \l_file_internal_name_tl - \tl_if_empty:NF \l_file_internal_name_tl - { + \quark_if_no_value:NTF \l_file_internal_name_tl + { \file_name_sanitize:nn {#1} { \file_input_error:n } } + { \file_input_aux:V \l_file_internal_name_tl } + } +\cs_new_protected:Npn \file_input_aux:n #1 + { %<*initex> - \seq_gput_right:Nx \g_file_record_seq {#1} + \seq_gput_right:Nn \g_file_record_seq {#1} %</initex> %<*package> - \@addtofilelist {#1} + \@addtofilelist {#1} %</package> - \seq_gpush:NV \g_file_stack_seq \g_file_current_name_tl - \tl_gset:Nn \g_file_current_name_tl {#1} - \exp_after:wN \tex_input:D \l_file_internal_name_tl \c_space_tl - \seq_gpop:NN \g_file_stack_seq \g_file_current_name_tl - } + \seq_gpush:Nn \g_file_stack_seq \g_file_current_name_tl + \tl_gset:Nn \g_file_current_name_tl {#1} + \tex_input:D #1 \c_space_tl + \seq_gpop:NN \g_file_stack_seq \g_file_current_name_tl } +\cs_generate_variant:Nn \file_input_aux:n { V } +\cs_new_protected:Npn \file_input_error:n #1 + { \msg_kernel_error:nnx { file } { file-not-found } {#1} } % \end{macrocode} % \end{macro} +% \end{macro} % -% \begin{macro}{\file_split_path_name_ext:nNNN} -% \begin{macro}[aux]{\file_split_path_name_ext_aux:nNNN} -% \begin{macro}[aux]{\file_split_path:wNNN, \file_split_name_ext:wNN} -% Splits a file name into any path part, the file name and the extension, -% which is considered as the part after the last |.|. +% \begin{macro}{\file_path_include:n} +% \begin{macro}{\file_path_remove:n} +% Wrapper functions to manage the search path. % \begin{macrocode} -\cs_new_protected:Npn \file_split_path_name_ext:nNNN #1 +\cs_new_protected:Npn \file_path_include:n #1 { - \group_begin: - \tl_to_str_active_safe:Nx \l_file_internal_name_tl {#1} - \tl_if_in:NnT \l_file_internal_name_tl { ~ } - { - \msg_kernel_error:nnx { io } { space-in-file-name } - { \l_file_internal_name_tl } - } - \exp_args:NNo \group_end: - \file_split_path_name_ext_aux:nNNN \l_file_internal_name_tl + \seq_if_in:NnF \l_file_search_path_seq {#1} + { \seq_put_right:Nn \l_file_search_path_seq {#1} } } -\cs_new_protected:Npn \file_split_path_name_ext_aux:nNNN #1#2#3#4 +\cs_new_protected:Npn \file_path_remove:n #1 + { \seq_remove_all:Nn \l_file_search_path_seq {#1} } +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\file_list:} +% A function to list all files used to the log. +% \begin{macrocode} +\cs_new_protected_nopar:Npn \file_list: { - \tl_clear:N #2 - \tl_clear:N #3 - \file_split_path:wNNN #1 / \q_nil / \q_stop #2#3#4 + \seq_remove_duplicates:N \g_file_record_seq + \iow_log:n { *~File~List~* } + \seq_map_inline:Nn \g_file_record_seq { \iow_log:n {##1} } + \iow_log:n { ************* } } -\cs_new_protected:Npn \file_split_path:wNNN #1 / #2 / #3 \q_stop #4 +% \end{macrocode} +% \end{macro} +% +% When used as a package, there is a need to hold onto the standard +% file list as well as the new one here. +% \begin{macrocode} +%<*package> +\AtBeginDocument + { + \seq_set_from_clist:NN \l_file_internal_seq \@filelist + \seq_gconcat:NNN \g_file_record_seq \g_file_record_seq \l_file_internal_seq + } +%</package> +% \end{macrocode} +% +% \subsection{Input--output variables constants} +% +% \begin{variable}{\c_term_ior} +% Reading from the terminal (with a prompt) is done using a positive +% but non-existent stream number. Unlike writing, there is no concept +% of reading from the log. +% \begin{macrocode} +\cs_new_eq:NN \c_term_ior \c_sixteen +% \end{macrocode} +% \end{variable} +% +% \begin{variable}{\c_log_iow, \c_term_iow} +% Here we allocate two output streams for writing to the transcript +% file only (\cs{c_log_iow}) and to both the terminal and +% transcript file (\cs{c_term_iow}). +% \begin{macrocode} +\cs_new_eq:NN \c_log_iow \c_minus_one +\cs_new_eq:NN \c_term_iow \c_sixteen +% \end{macrocode} +% \end{variable} +% +% \begin{variable}{\c_iow_streams_tl, \c_ior_streams_tl} +% The list of streams available, by number. +% \begin{macrocode} +\tl_const:Nn \c_iow_streams_tl { - \quark_if_nil:nTF {#2} - { \file_split_name_ext:wNN #1 . \q_nil . \q_stop } + \c_zero + \c_one + \c_two + \c_three + \c_four + \c_five + \c_six + \c_seven + \c_eight + \c_nine + \c_ten + \c_eleven + \c_twelve + \c_thirteen + \c_fourteen + \c_fifteen + } +\cs_new_eq:NN \c_ior_streams_tl \c_iow_streams_tl +% \end{macrocode} +% \end{variable} +% +% \begin{variable}{\g_iow_streams_prop, \g_ior_streams_prop} +% The allocations for streams are stored in property lists, which +% are set up to have a \enquote{full} set of allocations from the start. +% In package mode, a few slots are always taken, so these are +% blocked off from use. +% \begin{macrocode} +\prop_new:N \g_iow_streams_prop +\prop_new:N \g_ior_streams_prop +%<*package> +\prop_put:Nnn \g_iow_streams_prop { 0 } { LaTeX2e~reserved } +\prop_put:Nnn \g_iow_streams_prop { 1 } { LaTeX2e~reserved } +\prop_put:Nnn \g_iow_streams_prop { 2 } { LaTeX2e~reserved } +\prop_put:Nnn \g_ior_streams_prop { 0 } { LaTeX2e~reserved } +%</package> +% \end{macrocode} +% \end{variable} +% +% \begin{variable}{\l_iow_stream_int, \l_ior_stream_int} +% Used to track the number allocated to the stream being created: +% this is taken from the property list but does alter. +% \begin{macrocode} +\int_new:N \l_iow_stream_int +\cs_new_eq:NN \l_ior_stream_int \l_iow_stream_int +% \end{macrocode} +% \end{variable} +% +% \subsection{Stream management} +% +% \begin{macro}[int]{\ior_raw_new:N, \ior_raw_new:c} +% \begin{macro}[int]{\iow_raw_new:N, \iow_raw_new:c} +% The lowest level for stream management is actually creating raw \TeX{} +% streams. As these are very limited (even with \eTeX{}), this should not +% be addressed directly. +% \begin{macrocode} +%<*initex> +\alloc_setup_type:nnn { ior } \c_zero \c_sixteen +\cs_new_protected:Npn \ior_raw_new:N #1 + { \alloc_reg:nNN { ior } \tex_chardef:D #1 } +\alloc_setup_type:nnn { iow } \c_zero \c_sixteen +\cs_new_protected:Npn \iow_raw_new:N #1 + { \alloc_reg:nNN { iow } \tex_chardef:D #1 } +%</initex> +%<*package> +\cs_set_eq:NN \iow_raw_new:N \newwrite +\cs_set_eq:NN \ior_raw_new:N \newread +%</package> +\cs_generate_variant:Nn \ior_raw_new:N { c } +\cs_generate_variant:Nn \iow_raw_new:N { c } +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\ior_new:N, \ior_new:c, \iow_new:N, \iow_new:c} +% Reserving a new stream is done by defining the name as equal to using the +% terminal. +% \begin{macrocode} +\cs_new_protected:Npn \ior_new:N #1 { \cs_new_eq:NN #1 \c_term_ior } +\cs_generate_variant:Nn \ior_new:N { c } +\cs_new_protected:Npn \iow_new:N #1 { \cs_new_eq:NN #1 \c_term_iow } +\cs_generate_variant:Nn \iow_new:N { c } +% \end{macrocode} +% \end{macro} +% +% \begin{variable}{\g_file_internal_ior} +% Delayed from above so that the mechanisms are in place. +% \begin{macrocode} +\ior_new:N \g_file_internal_ior +% \end{macrocode} +% \end{variable} +% +% \begin{macro}{\ior_open:Nn, \ior_open:cn, \iow_open:Nn, \iow_open:cn} +% \begin{macro}[int]{\ior_open_aux:Nn} +% \begin{macro}[TF]{\ior_open:Nn} +% \begin{macro}[aux]{\ior_open_aux:NnTF} +% \begin{macro}[int] +% {\ior_open_unsafe:Nn, \ior_open_unsafe:No, \iow_open_unsafe:Nn} +% In both cases, opening a stream starts with a call to the closing +% function: this is safest. There is then a loop through the +% allocation number list to find the first free stream number. +% When one is found the allocation can take place, the information +% can be stored and finally the file can actually be opened. Before +% any actual file operations there is a precaution against special +% characters in file names. For reading files, there is an intermediate +% auxiliary to allow path addition, keeping the internal function fast +% and avoiding an infinite loop. +% \begin{macrocode} +\cs_new_protected:Npn \ior_open:Nn #1#2 + { \file_name_sanitize:nn {#2} { \ior_open_aux:Nn #1 } } +\cs_generate_variant:Nn \ior_open:Nn { c } +\cs_new_protected:Npn \iow_open:Nn #1#2 + { \file_name_sanitize:nn {#2} { \iow_open_unsafe:Nn #1 } } +\cs_generate_variant:Nn \iow_open:Nn { c } +\cs_new_protected:Npn \ior_open_aux:Nn #1#2 + { + \file_add_path:nN {#2} \l_file_name_internal_tl + \quark_if_no_value:NTF \l_file_internal_name_tl + { \file_input_error:n {#2} } + { \ior_open_unsafe:No #1 \l_file_name_internal_tl } + } +\prg_new_protected_conditional:Npnn \ior_open:Nn #1#2 { T , F , TF } + { \file_name_sanitize:nn {#2} { \ior_open_aux:NnTF #1 } } +\cs_new_protected:Npn \ior_open_aux:NnTF #1#2 + { + \file_add_path:nN {#2} \l_file_name_internal_tl + \quark_if_no_value:NTF \l_file_internal_name_tl + { \prg_return_false: } + { + \ior_open_unsafe:No #1 \l_file_name_internal_tl + \prg_return_true: + } + } +\cs_generate_variant:Nn \ior_open:NnT { c } +\cs_generate_variant:Nn \ior_open:NnF { c } +\cs_generate_variant:Nn \ior_open:NnTF { c } +\cs_new_protected:Npn \ior_open_unsafe:Nn #1#2 + { + \ior_close:N #1 + \int_set:Nn \l_ior_stream_int \c_sixteen + \tl_map_function:NN \c_ior_streams_tl \ior_alloc_read:n + \int_compare:nNnTF \l_ior_stream_int = \c_sixteen + { \msg_kernel_fatal:nn { ior } { streams-exhausted } } { - \tl_put_right:Nn #4 { #1 / } - \file_split_path:wNNN #2 / #3 \q_stop #4 + \ior_stream_alloc:N #1 + \prop_gput:NVn \g_ior_streams_prop \l_ior_stream_int {#2} + \tex_openin:D #1#2 \scan_stop: } } -\cs_new_protected:Npn \file_split_name_ext:wNN #1 . #2 . #3 \q_stop #4#5 +\cs_generate_variant:Nn \ior_open_unsafe:Nn { No } +\cs_new_protected:Npn \iow_open_unsafe:Nn #1#2 { - \quark_if_nil:nTF {#2} + \iow_close:N #1 + \int_set:Nn \l_iow_stream_int \c_sixteen + \tl_map_function:NN \c_iow_streams_tl \iow_alloc_write:n + \int_compare:nNnTF \l_iow_stream_int = \c_sixteen + { \msg_kernel_fatal:nn { iow } { streams-exhausted } } { - \tl_if_empty:NTF #4 + \iow_stream_alloc:N #1 + \prop_gput:NVn \g_iow_streams_prop \l_iow_stream_int {#2} + \tex_immediate:D \tex_openout:D #1#2 \scan_stop: + } + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}[aux]{\ior_alloc_read:n} +% \begin{macro}[aux]{\iow_alloc_write:n} +% These functions are used to see if a particular stream is available. +% The property list contains file names for streams in use, so +% any unused ones are for the taking. +% \begin{macrocode} +\cs_new_protected:Npn \iow_alloc_write:n #1 + { + \prop_if_in:NnF \g_iow_streams_prop {#1} + { + \int_set:Nn \l_iow_stream_int {#1} + \tl_map_break: + } + } +\cs_new_protected:Npn \ior_alloc_read:n #1 + { + \prop_if_in:NnF \g_iow_streams_prop {#1} + { + \int_set:Nn \l_ior_stream_int {#1} + \tl_map_break: + } + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}[aux]{\iow_stream_alloc:N, \ior_stream_alloc:N} +% \begin{macro}[aux]{\iow_stream_alloc_aux:, \ior_stream_alloc_aux:} +% \begin{variable}{\g_iow_internal_iow, \g_ior_internal_ior} +% Allocating a raw stream is much easier in \IniTeX{} mode than for +% the package. For the format, all streams will be allocated by +% \pkg{l3file} and so there is a simple check to see if a raw +% stream is actually available. On the other hand, for the +% package there will be non-managed streams. So if the managed +% one is not open, a check is made to see if some other managed +% stream is available before deciding to open a new one. If a new +% one is needed, we get the number allocated by \LaTeXe{} to get +% \enquote{back on track} with allocation. +% \begin{macrocode} +\iow_new:N \g_iow_internal_iow +\ior_new:N \g_ior_internal_ior +\cs_new_protected:Npn \iow_stream_alloc:N #1 + { + \cs_if_exist:cTF { g_iow_ \int_use:N \l_iow_stream_int _iow } + { \cs_gset_eq:Nc #1 { g_iow_ \int_use:N \l_iow_stream_int _iow } } + { +%<*package> + \iow_stream_alloc_aux: + \int_compare:nNnT \l_iow_stream_int = \c_sixteen { - \tl_set:Nn #4 {#1} - \tl_clear:N #5 + \iow_raw_new:N \g_iow_internal_iow + \int_set:Nn \l_iow_stream_int { \g_iow_internal_iow } + \cs_gset_eq:cN + { g_iow_ \int_use:N \l_iow_stream_int _iow } \g_iow_internal_iow } - { \tl_set:Nn #5 {#1} } +%</package> +%<*initex> + \iow_raw_new:c { g_iow_ \int_use:N \l_iow_stream_int _iow } +%</initex> + \cs_gset_eq:Nc #1 { g_iow_ \int_use:N \l_iow_stream_int _iow } } + } +%<*package> +\cs_new_protected_nopar:Npn \iow_stream_alloc_aux: + { + \int_incr:N \l_iow_stream_int + \int_compare:nNnT \l_iow_stream_int < \c_sixteen { - \tl_put_right:Nx #4 + \cs_if_exist:cTF { g_iow_ \int_use:N \l_iow_stream_int _iow } + { + \prop_if_in:NVT \g_iow_streams_prop \l_iow_stream_int + { \iow_stream_alloc_aux: } + } + { \iow_stream_alloc_aux: } + } + } +%</package> +\cs_new_protected:Npn \ior_stream_alloc:N #1 + { + \cs_if_exist:cTF { g_ior_ \int_use:N \l_ior_stream_int _ior } + { \cs_gset_eq:Nc #1 { g_ior_ \int_use:N \l_ior_stream_int _ior } } + { +%<*package> + \ior_stream_alloc_aux: + \int_compare:nNnT \l_ior_stream_int = \c_sixteen { - \tl_if_empty:NF #4 { . } - #1 + \ior_raw_new:N \g_ior_internal_ior + \int_set:Nn \l_ior_stream_int { \g_ior_internal_ior } + \cs_gset_eq:cN + { g_ior_ \int_use:N \l_iow_stream_int _ior } \g_ior_internal_ior } - \file_split_name_ext:wNN #2 . #3 \q_stop #4#5 +%</package> +%<*initex> + \ior_raw_new:c { g_ior_ \int_use:N \l_ior_stream_int _ior } +%</initex> + \cs_gset_eq:Nc #1 { g_ior_ \int_use:N \l_ior_stream_int _ior } + } + } +%<*package> +\cs_new_protected_nopar:Npn \ior_stream_alloc_aux: + { + \int_incr:N \l_ior_stream_int + \int_compare:nNnT \l_ior_stream_int < \c_sixteen + { + \cs_if_exist:cTF { g_ior_ \int_use:N \l_ior_stream_int _ior } + { + \prop_if_in:NVT \g_ior_streams_prop \l_ior_stream_int + { \ior_stream_alloc_aux: } + } + { \ior_stream_alloc_aux: } } } +%</package> % \end{macrocode} +% \end{variable} % \end{macro} % \end{macro} +% +% \begin{macro}{\ior_close:N, \ior_close:c, \iow_close:N, \iow_close:c} +% Closing a stream is not quite the reverse of opening one. First, +% the close operation is easier than the open one, and second as the +% stream is actually a number we can use it directly to show that the +% slot has been freed up. +% \begin{macrocode} +\cs_new_protected:Npn \ior_close:N #1 + { + \cs_if_exist:NT #1 + { + \int_compare:nNnF #1 = \c_minus_one + { + \int_compare:nNnF #1 = \c_sixteen + { \tex_closein:D #1 } + \prop_gdel:NV \g_ior_streams_prop #1 + \cs_gset_eq:NN #1 \c_term_ior + } + } + } +\cs_new_protected:Npn \iow_close:N #1 + { + \cs_if_exist:NT #1 + { + \int_compare:nNnF #1 = \c_minus_one + { + \int_compare:nNnF #1 = \c_sixteen + { \tex_closein:D #1 } + \prop_gdel:NV \g_iow_streams_prop #1 + \cs_gset_eq:NN #1 \c_term_iow + } + } + } +\cs_generate_variant:Nn \ior_close:N { c } +\cs_generate_variant:Nn \iow_close:N { c } +% \end{macrocode} % \end{macro} % -% \begin{macro}{\file_path_include:n} -% \begin{macro}{\file_path_remove:n} -% Wrapper functions to manage the search path. +% \begin{macro}{\ior_list_streams:} +% Show the property lists, but with some \enquote{pretty printing}. +% See the \pkg{l3msg} module. If there are no open read streams, +% issue the message \texttt{show-no-stream}, and show an empty +% token list. If there are open read streams, format them with +% \cs{msg_aux_show_unbraced:nn}, and with the message +% \texttt{show-open-streams}. % \begin{macrocode} -\cs_new_protected:Npn \file_path_include:n #1 +\cs_new_protected_nopar:Npn \ior_list_streams: + { \ior_list_streams_aux:Nn \g_ior_streams_prop { ior } } +\cs_new_protected_nopar:Npn \iow_list_streams: + { \ior_list_streams_aux:Nn \g_iow_streams_prop { iow } } +\cs_new_protected:Npn \ior_list_streams_aux:Nn #1#2 { - \seq_if_in:NnF \l_file_search_path_seq {#1} - { \seq_put_right:Nn \l_file_search_path_seq {#1} } + \msg_aux_use:nn { LaTeX / #2 } + { \prop_if_empty:NTF #1 { show-no-stream } { show-open-streams } } + \msg_aux_show:x + { \prop_map_function:NN #1 \msg_aux_show_unbraced:nn } } -\cs_new_protected:Npn \file_path_remove:n #1 - { \seq_remove_all:Nn \l_file_search_path_seq {#1} } % \end{macrocode} % \end{macro} +% +% Text for the error messages. +% \begin{macrocode} +\msg_kernel_new:nnnn { iow } { streams-exhausted } + { Output~streams~exhausted } + { + TeX~can~only~open~up~to~16~output~streams~at~one~time.\\ + All~16 are currently~in~use,~and~something~wanted~to~open + another~one. + } +\msg_kernel_new:nnnn { ior } { streams-exhausted } + { Input~streams~exhausted } + { + TeX~can~only~open~up~to~16~input~streams~at~one~time.\\ + All~16 are currently~in~use,~and~something~wanted~to~open + another~one. + } +% \end{macrocode} +% +% \subsection{Deferred writing} +% +% \begin{macro}{\iow_shipout_x:Nn, \iow_shipout_x:Nx} +% First the easy part, this is the primitive. +% \begin{macrocode} +\cs_new_eq:NN \iow_shipout_x:Nn \tex_write:D +\cs_generate_variant:Nn \iow_shipout_x:Nn { Nx } +% \end{macrocode} % \end{macro} % -% \begin{macro}{\file_list:} -% A function to list all files used to the log. +% \begin{macro}{\iow_shipout:Nn, \iow_shipout:Nx} +% With \eTeX{} available deferred writing is easy. % \begin{macrocode} -\cs_new_protected_nopar:Npn \file_list: +\cs_new_protected:Npn \iow_shipout:Nn #1#2 + { \iow_shipout_x:Nn #1 { \exp_not:n {#2} } } +\cs_generate_variant:Nn \iow_shipout:Nn { Nx } +% \end{macrocode} +% \end{macro} +% +% \subsection{Immediate writing} +% +% \begin{macro}{\iow_now:Nx} +% An abbreviation for an often used operation, which immediately +% writes its second argument expanded to the output stream. +% \begin{macrocode} +\cs_new_protected_nopar:Npn \iow_now:Nx { \tex_immediate:D \iow_shipout_x:Nn } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\iow_now:Nn} +% This routine writes the second argument onto the output stream without +% expansion. If this stream isn't open, the output goes to the terminal +% instead. If the first argument is no output stream at all, we get an +% internal error. +% \begin{macrocode} +\cs_new_protected:Npn \iow_now:Nn #1#2 + { \iow_now:Nx #1 { \exp_not:n {#2} } } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\iow_log:n, \iow_log:x} +% \begin{macro}{\iow_term:n, \iow_term:x} +% Writing to the log and the terminal directly are relatively easy. +% \begin{macrocode} +\cs_set_protected_nopar:Npn \iow_log:x { \iow_now:Nx \c_log_iow } +\cs_new_protected_nopar:Npn \iow_log:n { \iow_now:Nn \c_log_iow } +\cs_set_protected_nopar:Npn \iow_term:x { \iow_now:Nx \c_term_iow } +\cs_new_protected_nopar:Npn \iow_term:n { \iow_now:Nn \c_term_iow } +% \end{macrocode} +%\end{macro} +%\end{macro} +% +% \subsection{Special characters for writing} +% +% \begin{macro}{\iow_newline:} +% Global variable holding the character that forces a new line when +% something is written to an output stream +% \begin{macrocode} +\cs_new_nopar:Npn \iow_newline: { ^^J } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\iow_char:N} +% Function to write any escaped char to an output stream. +% \begin{macrocode} +\cs_new_eq:NN \iow_char:N \cs_to_str:N +% \end{macrocode} +% \end{macro} +% +% \subsection{Hard-wrapping lines based on length} +% +% The code here implements a generic hard-wrapping function. This is +% used by the messaging system, but is designed such that it is +% available for other uses. +% +% \begin{macro}{\l_iow_line_length_int} +% This is the \enquote{raw} length of a line which can be written to a +% file. The standard value is the line length typically used by +% \TeX{}Live and Mik\TeX{}. +% \begin{macrocode} +\int_new:N \l_iow_line_length_int +\int_set:Nn \l_iow_line_length_int { 78 } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[aux]{\l_iow_target_length_int} +% This stores the target line length: the full length minus any +% part for a leader at the start of each line. +% \begin{macrocode} +\int_new:N \l_iow_target_length_int +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[aux] +% { +% \l_iow_current_line_int, +% \l_iow_current_word_int, +% \l_iow_current_indentation_int +% } +% These store the number of characters in the line and word currently +% being constructed, and the current indentation, respectively. +% \begin{macrocode} +\int_new:N \l_iow_current_line_int +\int_new:N \l_iow_current_word_int +\int_new:N \l_iow_current_indentation_int +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[aux] +% { +% \l_iow_current_line_tl, +% \l_iow_current_word_tl, +% \l_iow_current_indentation_tl +% } +% These hold the current line of text and current word, +% and a number of spaces for indentation, respectively. +% \begin{macrocode} +\tl_new:N \l_iow_current_line_tl +\tl_new:N \l_iow_current_word_tl +\tl_new:N \l_iow_current_indentation_tl +% \end{macrocode} +%\end{macro} +% +% \begin{macro}[aux]{\l_iow_wrap_tl} +% Used for the expansion step before detokenizing. +% \begin{macrocode} +\tl_new:N \l_iow_wrap_tl +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[aux]{\l_iow_wrapped_tl} +% The output from wrapping text: fully expanded and with lines +% which are not overly long. +% \begin{macrocode} +\tl_new:N \l_iow_wrapped_tl +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[aux]{\l_iow_line_start_bool} +% Boolean to avoid adding a space at the beginning of forced newlines. +% \begin{macrocode} +\bool_new:N \l_iow_line_start_bool +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[aux]{\c_catcode_other_space_tl} +% Lowercase a character with category code $12$ to produce an +% \enquote{other} space. We can do everything within the group, +% because \cs{tl_const:Nn} defines its argument globally. +% \begin{macrocode} +\group_begin: + \char_set_catcode_other:N \* + \char_set_lccode:nn {`\*} {`\ } + \tl_to_lowercase:n { \tl_const:Nn \c_catcode_other_space_tl { * } } +\group_end: +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[aux]{\c_iow_wrap_marker_tl} +% \begin{macro}[aux]{ +% \c_iow_wrap_end_marker_tl, +% \c_iow_wrap_newline_marker_tl, +% \c_iow_wrap_indent_marker_tl, +% \c_iow_wrap_unindent_marker_tl} +% \begin{macro}[aux]{\iow_wrap_new_marker:n} +% Every special action of the wrapping code is preceeded by +% the same recognizable string, \cs{c_iow_wrap_marker_tl}. +% Upon seeing that \enquote{word}, the wrapping code reads +% one space-delimited argument to know what operation to +% perform. The setting of \tn{escapechar} here is not +% very important, but makes \cs{c_iow_wrap_marker_tl} look +% nicer. Note that \cs{iow_wrap_new_marker:n} does not +% survive the group, but all constants are defined globally. +% \begin{macrocode} +\group_begin: + \int_set_eq:NN \tex_escapechar:D \c_minus_one + \tl_const:Nx \c_iow_wrap_marker_tl + { \tl_to_str:n { \^^I \^^O \^^W \^^_ \^^W \^^R \^^A \^^P } } + \cs_set:Npn \iow_wrap_new_marker:n #1 + { + \tl_const:cx { c_iow_wrap_ #1 _marker_tl } + { + \c_catcode_other_space_tl + \c_iow_wrap_marker_tl + \c_catcode_other_space_tl + #1 + \c_catcode_other_space_tl + } + } + \iow_wrap_new_marker:n { end } + \iow_wrap_new_marker:n { newline } + \iow_wrap_new_marker:n { indent } + \iow_wrap_new_marker:n { unindent } +\group_end: +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\iow_indent:n} +% \begin{macro}[aux]{\iow_indent_expandable:n} +% We give a dummy (protected) definition to \cs{iow_indent:n} +% when outside messages. Within wrapped message, it places +% the instruction for increasing the indentation before its +% argument, and the instruction for unindenting afterwards. +% Note that there will be no forced line-break, so the indentation +% only changes when the next line is started. +% \begin{macrocode} +\cs_new_protected:Npn \iow_indent:n #1 { } +\cs_new:Npx \iow_indent_expandable:n #1 { - \seq_remove_duplicates:N \g_file_record_seq - \iow_log:n { *~File~List~* } - \seq_map_inline:Nn \g_file_record_seq { \iow_log:n {##1} } - \iow_log:n { ************* } + \c_iow_wrap_indent_marker_tl + #1 + \c_iow_wrap_unindent_marker_tl } % \end{macrocode} % \end{macro} +% \end{macro} % -% When used as a package, there is a need to hold onto the standard -% file list as well as the new one here. +% \begin{macro}{\iow_wrap:xnnnN} +% The main wrapping function works as follows. The target number of +% characters in a line is calculated, before fully-expanding the input +% such that |\\| and \verb*|\ | are converted into the appropriate +% values. There is then a loop over each word in the input, which +% will do the actual wrapping. After the loop, the resulting text is +% passed on to the function which has been given as a post-processor. +% The argument |#4| is available for additional set up steps for +% the output. The definition of |\\| and \verb*|\ | use an +% \enquote{other} space rather than a normal space, because the latter +% might be absorbed by \TeX{} to end a number or other \texttt{f}-type +% expansions. The \cs{tl_to_str:N} step converts the \enquote{other} +% space back to a normal space. % \begin{macrocode} +\cs_new_protected:Npn \iow_wrap:xnnnN #1#2#3#4#5 + { + \group_begin: + \int_set:Nn \l_iow_target_length_int { \l_iow_line_length_int - ( #3 ) } + \int_zero:N \l_iow_current_indentation_int + \tl_clear:N \l_iow_current_indentation_tl + \int_zero:N \l_iow_current_line_int + \tl_clear:N \l_iow_current_line_tl + \tl_clear:N \l_iow_wrap_tl + \bool_set_true:N \l_iow_line_start_bool + \int_set_eq:NN \tex_escapechar:D \c_minus_one + \cs_set_nopar:Npx \{ { \token_to_str:N \{ } + \cs_set_nopar:Npx \# { \token_to_str:N \# } + \cs_set_nopar:Npx \} { \token_to_str:N \} } + \cs_set_nopar:Npx \% { \token_to_str:N \% } + \cs_set_nopar:Npx \~ { \token_to_str:N \~ } + \int_set:Nn \tex_escapechar:D { 92 } + \cs_set_eq:NN \\ \c_iow_wrap_newline_marker_tl + \cs_set_eq:NN \ \c_catcode_other_space_tl + \cs_set_eq:NN \iow_indent:n \iow_indent_expandable:n + #4 +%<*initex> + \tl_set:Nx \l_iow_wrap_tl {#1} +%</initex> %<*package> -\AtBeginDocument + \protected@edef \l_iow_wrap_tl {#1} +%</package> + \cs_set:Npn \\ { \iow_newline: #2 } + \use:x + { + \iow_wrap_loop:w + \tl_to_str:N \l_iow_wrap_tl + \tl_to_str:N \c_iow_wrap_end_marker_tl + \c_space_tl \c_space_tl + \exp_not:N \q_stop + } + \exp_args:NNo \group_end: + #5 \l_iow_wrapped_tl + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[aux]{\iow_wrap_loop:w} +% The loop grabs one word in the input, and checks whether it is +% the special marker, or a normal word. +% \begin{macrocode} +\cs_new_protected:Npn \iow_wrap_loop:w #1 ~ % { - \seq_set_from_clist:NN \l_file_internal_seq \@filelist - \seq_gconcat:NNN \g_file_record_seq \g_file_record_seq \l_file_internal_seq + \tl_set:Nn \l_iow_current_word_tl {#1} + \tl_if_eq:NNTF \l_iow_current_word_tl \c_iow_wrap_marker_tl + { \iow_wrap_special:w } + { \iow_wrap_word: } } -%</package> % \end{macrocode} +% \end{macro} +% +% \begin{macro}[aux]{\iow_wrap_word:} +% \begin{macro}[aux]{\iow_wrap_word_fits:} +% \begin{macro}[aux]{\iow_wrap_word_newline:} +% For a normal word, update the line length, then test if the current +% word would fit in the current line, and call the appropriate function. +% If the word fits in the current line, add it to the line, preceded by +% a space unless it is the first word of the line. +% Otherwise, the current line is added to the result, with the run-on text. +% The current word (and its length) are then put in the new line. +% \begin{macrocode} +\cs_new_protected_nopar:Npn \iow_wrap_word: + { + \int_set:Nn \l_iow_current_word_int + { \str_length_skip_spaces:N \l_iow_current_word_tl } + \int_add:Nn \l_iow_current_line_int { \l_iow_current_word_int } + \int_compare:nNnTF \l_iow_current_line_int < \l_iow_target_length_int + { \iow_wrap_word_fits: } + { \iow_wrap_word_newline: } + \iow_wrap_loop:w + } +\cs_new_protected_nopar:Npn \iow_wrap_word_fits: + { + \bool_if:NTF \l_iow_line_start_bool + { + \bool_set_false:N \l_iow_line_start_bool + \tl_put_right:Nx \l_iow_current_line_tl + { \l_iow_current_indentation_tl \l_iow_current_word_tl } + \int_add:Nn \l_iow_current_line_int + { \l_iow_current_indentation_int } + } + { + \tl_put_right:Nx \l_iow_current_line_tl + { ~ \l_iow_current_word_tl } + \int_incr:N \l_iow_current_line_int + } + } +\cs_new_protected_nopar:Npn \iow_wrap_word_newline: + { + \tl_put_right:Nx \l_iow_wrapped_tl + { \l_iow_current_line_tl \\ } + \int_set:Nn \l_iow_current_line_int + { + \l_iow_current_word_int + + \l_iow_current_indentation_int + } + \tl_set:Nx \l_iow_current_line_tl + { \l_iow_current_indentation_tl \l_iow_current_word_tl } + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}[aux]{\iow_wrap_special:w} +% \begin{macro}[aux]{\iow_wrap_newline:w} +% \begin{macro}[aux]{\iow_wrap_indent:w} +% \begin{macro}[aux]{\iow_wrap_unindent:w} +% \begin{macro}[aux]{\iow_wrap_end:w} +% When the \enquote{special} marker is encountered, +% read what operation to perform, as a space-delimited +% argument, perform it, and remember to loop. +% In fact, to avoid spurious spaces when two special +% actions follow each other, we look ahead for another +% copy of the marker. +% Forced newlines are almost identical to those caused by overflow, +% except that here the word is empty. +% To indent more, add four spaces to the start of the indentation +% token list. To reduce indentation, rebuild the indentation token +% list using \cs{prg_replicate:nn}. +% At the end, we simply save the last line (without the run-on text), +% and prevent the loop. +% \begin{macrocode} +\cs_new_protected:Npn \iow_wrap_special:w #1 ~ #2 ~ #3 ~ % + { + \use:c { iow_wrap_#1: } + \str_if_eq:xxTF { #2~#3 } { ~ \c_iow_wrap_marker_tl } + { \iow_wrap_special:w } + { \iow_wrap_loop:w #2 ~ #3 ~ } + } +\cs_new_protected_nopar:Npn \iow_wrap_newline: + { + \tl_put_right:Nx \l_iow_wrapped_tl + { \l_iow_current_line_tl \\ } + \int_zero:N \l_iow_current_line_int + \tl_clear:N \l_iow_current_line_tl + \bool_set_true:N \l_iow_line_start_bool + } +\cs_new_protected_nopar:Npx \iow_wrap_indent: + { + \int_add:Nn \l_iow_current_indentation_int \c_four + \tl_put_right:Nx \exp_not:N \l_iow_current_indentation_tl + { \c_space_tl \c_space_tl \c_space_tl \c_space_tl } + } +\cs_new_protected_nopar:Npn \iow_wrap_unindent: + { + \int_sub:Nn \l_iow_current_indentation_int \c_four + \tl_set:Nx \l_iow_current_indentation_tl + { \prg_replicate:nn \l_iow_current_indentation_int { ~ } } + } +\cs_new_protected_nopar:Npn \iow_wrap_end: + { + \tl_put_right:Nx \l_iow_wrapped_tl + { \l_iow_current_line_tl } + \use_none_delimit_by_q_stop:w + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}[aux]{\str_length_skip_spaces:N} +% \begin{macro}[aux]{\str_length_skip_spaces:n} +% \begin{macro}[aux]{\str_length_loop:NNNNNNNNN} +% The wrapping code requires to measure the number of character +% in each word. This could be done with \cs{tl_length:n}, but +% it is ten times faster (literally) to use the code below. +% \begin{macrocode} +\cs_new_nopar:Npn \str_length_skip_spaces:N + { \exp_args:No \str_length_skip_spaces:n } +\cs_new:Npn \str_length_skip_spaces:n #1 + { + \int_value:w \int_eval:w + \exp_after:wN \str_length_loop:NNNNNNNNN \tl_to_str:n {#1} + { X8 } { X7 } { X6 } { X5 } { X4 } { X3 } { X2 } { X1 } { X0 } \q_stop + \int_eval_end: + } +\cs_new:Npn \str_length_loop:NNNNNNNNN #1#2#3#4#5#6#7#8#9 + { + \if_catcode:w X #9 + \exp_after:wN \use_none_delimit_by_q_stop:w + \else: + 9 + + \exp_after:wN \str_length_loop:NNNNNNNNN + \fi: + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \subsection{Reading input} +% +% \begin{macro}[int]{\if_eof:w} +% The primitive conditional +% \begin{macrocode} +\cs_new_eq:NN \if_eof:w \tex_ifeof:D +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[pTF]{\ior_if_eof:N} +% To test if some particular input stream is exhausted the following +% conditional is provided. +% \begin{macrocode} +\prg_new_conditional:Nnn \ior_if_eof:N { p , T , F , TF } + { + \cs_if_exist:NTF #1 + { + \if_int_compare:w #1 = \c_sixteen + \prg_return_true: + \else: + \if_eof:w #1 + \prg_return_true: + \else: + \prg_return_false: + \fi: + \fi: + } + { \prg_return_true: } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\ior_to:NN, \ior_gto:NN} +% And here we read from files. +% \begin{macrocode} +\cs_new_protected:Npn \ior_to:NN #1#2 + { \tex_read:D #1 to #2 } +\cs_new_protected:Npn \ior_gto:NN #1#2 + { \tex_global:D \tex_read:D #1 to #2 } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\ior_str_to:NN, \ior_str_gto:NN} +% Reading as strings is also a primitive wrapper. +% \begin{macrocode} +\cs_new_protected:Npn \ior_str_to:NN #1#2 + { \etex_readline:D #1 to #2 } +\cs_new_protected:Npn \ior_str_gto:NN #1#2 + { \tex_global:D \etex_readline:D #1 to #2 } +% \end{macrocode} +% \end{macro} +% +% \subsection{Experimental functions} +% +% \begin{macro}{\ior_map_inline:Nn, \ior_str_map_inline:Nn} +% \begin{macro}[aux]{\ior_str_map_inline_aux:NNn} +% \begin{macro}[aux]{\ior_str_map_inline_aux:NNNn} +% \begin{macro}[aux]{\ior_str_map_inline_loop:NNN} +% \begin{variable}{\l_ior_internal_tl} +% Mapping to an input stream can be done on either a token or a string +% basis, hence the set up. Within that, there is a check to avoid reading +% past the end of a file, hence the two applications of \cs{ior_if_eof:N}. +% This mapping cannot be nested as the stream has only one \enquote{current +% line}. +% \begin{macrocode} +\cs_new_protected_nopar:Npn \ior_map_inline:Nn + { \ior_map_inline_aux:NNn \ior_to:NN } +\cs_new_protected_nopar:Npn \ior_str_map_inline:Nn + { \ior_map_inline_aux:NNn \ior_str_to:NN } +\cs_new_protected_nopar:Npn \ior_map_inline_aux:NNn + { + \exp_args:Nc \ior_map_inline_aux:NNNn + { ior_map_ \int_use:N \g_prg_map_int :n } + } +\cs_new_protected:Npn \ior_map_inline_aux:NNNn #1#2#3#4 + { + \cs_set:Npn #1 ##1 {#4} + \int_gincr:N \g_prg_map_int + \ior_if_eof:NF #3 { \ior_map_inline_loop:NNN #1#2#3 } + \prg_break_point:n { \int_gdecr:N \g_prg_map_int } + } +\cs_new_protected:Npn \ior_map_inline_loop:NNN #1#2#3 + { + #2 #3 \l_ior_internal_tl + \ior_if_eof:NF #3 + { + \exp_args:No #1 \l_ior_internal_tl + \ior_map_inline_loop:NNN #1#2#3 + } + } +\tl_new:N \l_ior_internal_tl +% \end{macrocode} +% \end{variable} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \subsection{Messages} +% +% \begin{macrocode} +\msg_kernel_new:nnnn { file } { file-not-found } + { Space~in~file~name~'#1'. } + { + Spaces~are~not~permitted~in~files~loaded~by~LaTeX: \\ + Further~errors~may~follow! + } +\msg_kernel_new:nnnn { file } { space-in-file-name } + { Space~in~file~name~'#1'. } + { + Spaces~are~not~permitted~in~files~loaded~by~LaTeX: \\ + Further~errors~may~follow! + } +% \end{macrocode} +% +% \subsection{Deprecated functions} +% +% Deprecated on 2012-02-10, for removal by 2012-05-31. +% +% \begin{macro}{\iow_now_when_avail:Nn, \iow_now_when_avail:Nx} +% For writing only if the stream requested is open at all. +% \begin{macrocode} +\cs_new_protected:Npn \iow_now_when_avail:Nn #1 + { \cs_if_free:NTF #1 { \use_none:n } { \iow_now:Nn #1 } } +\cs_new_protected:Npn \iow_now_when_avail:Nx #1 + { \cs_if_free:NTF #1 { \use_none:n } { \iow_now:Nx #1 } } +% \end{macrocode} +% \end{macro} +% +% Deprecated on 2011-05-27, for removal by 2011-08-31. +% +% \begin{macro}{\iow_now_buffer_safe:Nn, \iow_now_buffer_safe:Nx} +% This is much more easily done using the wrapping system: there is +% an expansion there, so a bit of a hack is needed. +% \begin{macrocode} +%<*deprecated> +\cs_new_protected:Npn \iow_now_buffer_safe:Nn #1#2 + { \iow_wrap:xnnnN { \exp_not:n {#2} } { } \c_zero { } \iow_now:Nn #1 } +\cs_new_protected:Npn \iow_now_buffer_safe:Nx #1#2 + { \iow_wrap:xnnnN {#2} { } \c_zero { } \iow_now:Nn #1 } +%</deprecated> +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\ior_open_streams:} +% \begin{macro}{\iow_open_streams:} +% Slightly misleading names. +% \begin{macrocode} +%<*deprecated> +\cs_new_eq:NN \ior_open_streams: \ior_list_streams: +\cs_new_eq:NN \iow_open_streams: \iow_list_streams: +%</deprecated> +% \end{macrocode} +% \end{macro} +% \end{macro} % % \begin{macrocode} %</initex|package> diff --git a/Master/texmf-dist/source/latex/l3kernel/l3int.dtx b/Master/texmf-dist/source/latex/l3kernel/l3int.dtx index f977f49c9f8..fa633515f99 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 3315 2012-02-06 11:17:04Z bruno $ +\GetIdInfo$Id: l3int.dtx 3460 2012-02-26 12:16:41Z will $ {L3 Experimental integers} %</driver|package> %<*driver> @@ -117,7 +117,7 @@ % % \begin{function}[EXP]{\int_div_round:nn} % \begin{syntax} -% \cs{int_div_round:nn} \Arg{intexpr1} \Arg{intexpr2} +% \cs{int_div_round:nn} \Arg{intexpr_1} \Arg{intexpr_2} % \end{syntax} % Evaluates the two \meta{integer expressions} as described earlier, % then calculates the result of dividing the first value by the @@ -127,9 +127,9 @@ % the input stream as a \meta{integer denotation} after two expansions. % \end{function} % -% \begin{function}[EXP]{\int_div_truncate:nn} +% \begin{function}[EXP, updated = 2012-02-09]{\int_div_truncate:nn} % \begin{syntax} -% \cs{int_div_truncate:nn} \Arg{intexpr1} \Arg{intexpr2} +% \cs{int_div_truncate:nn} \Arg{intexpr_1} \Arg{intexpr_2} % \end{syntax} % Evaluates the two \meta{integer expressions} as described earlier, % then calculates the result of dividing the first value by the @@ -140,8 +140,8 @@ % % \begin{function}[EXP]{\int_max:nn, \int_min:nn} % \begin{syntax} -% \cs{int_max:nn} \Arg{intexpr1} \Arg{intexpr2} -% \cs{int_min:nn} \Arg{intexpr1} \Arg{intexpr2} +% \cs{int_max:nn} \Arg{intexpr_1} \Arg{intexpr_2} +% \cs{int_min:nn} \Arg{intexpr_1} \Arg{intexpr_2} % \end{syntax} % Evaluates the \meta{integer expressions} as described for % \cs{int_eval:n} and leaves either the larger or smaller value @@ -151,7 +151,7 @@ % % \begin{function}[EXP]{\int_mod:nn} % \begin{syntax} -% \cs{int_mod:nn} \Arg{intexpr1} \Arg{intexpr2} +% \cs{int_mod:nn} \Arg{intexpr_1} \Arg{intexpr_2} % \end{syntax} % Evaluates the two \meta{integer expressions} as described earlier, % then calculates the integer remainder of dividing the first @@ -273,9 +273,9 @@ % % \begin{function}[EXP,pTF]{\int_compare:nNn} % \begin{syntax} -% \cs{int_compare_p:nNn} \Arg{intexpr1} \meta{relation} \Arg{intexpr2} \\ +% \cs{int_compare_p:nNn} \Arg{intexpr_1} \meta{relation} \Arg{intexpr_2} \\ % \cs{int_compare:nNnTF} -% ~~\Arg{intexpr1} \meta{relation} \Arg{intexpr2} +% ~~\Arg{intexpr_1} \meta{relation} \Arg{intexpr_2} % ~~\Arg{true code} \Arg{false code} % \end{syntax} % This function first evaluates each of the \meta{integer expressions} @@ -328,7 +328,7 @@ % \begin{function}[rEXP]{\int_do_while:nNnn} % \begin{syntax} % \cs{int_do_while:nNnn} -% ~~\Arg{intexpr1} \meta{relation} \Arg{intexpr2} \Arg{code} +% ~~\Arg{intexpr_1} \meta{relation} \Arg{intexpr_2} \Arg{code} % \end{syntax} % Evaluates the relationship between the two \meta{integer expressions} % as described for \cs{int_compare:nNnTF}, and then places the @@ -341,7 +341,7 @@ % \begin{function}[rEXP]{\int_do_until:nNnn} % \begin{syntax} % \cs{int_do_until:nNnn} -% ~~\Arg{intexpr1} \meta{relation} \Arg{intexpr2} \Arg{code} +% ~~\Arg{intexpr_1} \meta{relation} \Arg{intexpr_2} \Arg{code} % \end{syntax} % Evaluates the relationship between the two \meta{integer expressions} % as described for \cs{int_compare:nNnTF}, and then places the @@ -354,7 +354,7 @@ % \begin{function}[rEXP]{\int_until_do:nNnn} % \begin{syntax} % \cs{int_until_do:nNnn} -% ~~\Arg{intexpr1} \meta{relation} \Arg{intexpr2} \Arg{code} +% ~~\Arg{intexpr_1} \meta{relation} \Arg{intexpr_2} \Arg{code} % \end{syntax} % Places the \meta{code} in the input stream for \TeX{} to process, and % then evaluates the relationship between the two @@ -367,7 +367,7 @@ % \begin{function}[rEXP]{\int_while_do:nNnn} % \begin{syntax} % \cs{int_while_do:nNnn} \ -% ~~\Arg{intexpr1} \meta{relation} \Arg{intexpr2} \Arg{code} +% ~~\Arg{intexpr_1} \meta{relation} \Arg{intexpr_2} \Arg{code} % \end{syntax} % Places the \meta{code} in the input stream for \TeX{} to process, and % then evaluates the relationship between the two @@ -916,41 +916,47 @@ % \end{macro} % \end{macro} % -% \begin{macro}{\int_div_truncate:nn} +% \begin{macro}[EXP]{\int_div_truncate:nn} % \UnitTested -% \begin{macro}{\int_div_round:nn} +% \begin{macro}[EXP]{\int_div_round:nn} % \UnitTested -% \begin{macro}{\int_mod:nn} +% \begin{macro}[EXP]{\int_mod:nn} % \UnitTested -% As \cs{int_eval:w} rounds the result of a division we also -% provide a version that truncates the result. This version is thanks -% to Heiko Oberdiek: getting things right in all cases is not so easy. +% \begin{macro}[aux, EXP]{\int_div_truncate_aux:NwNw} +% As \cs{int_eval:w} rounds the result of a division we also provide a +% version that truncates the result. We use an auxiliary to make sure +% numerator and denominator are only evaluated once: this comes in +% handy when those are more expressions are expensive to evaluate +% (\emph{e.g.}, \cs{tl_length:n}). If the numerator |#1#2| is $0$, +% then we divide $0$ by the denominator (this ensures that $0/0$ is +% correctly reported as an error). Otherwise, shift the numerator +% |#1#2| towards $0$ by $(\left\vert\texttt{\#3\#4}\right\vert-1)/2$, which we +% round away from zero. It turns out that this quantity exactly +% compensates the difference between \eTeX{}'s rounding and the +% truncating behaviour that we want. The details are thanks to Heiko +% Oberdiek: getting things right in all cases is not so easy. % \begin{macrocode} \cs_new:Npn \int_div_truncate:nn #1#2 { - \int_value:w \int_eval:w - \if_int_compare:w \int_eval:w #1 = \c_zero - 0 - \else: - ( #1 % ) - \if_int_compare:w \int_eval:w #1 < \c_zero - \if_int_compare:w \int_eval:w #2 < \c_zero - - ( #2 + % ) - \else: - + ( #2 - % ) - \fi: - \else: - \if_int_compare:w \int_eval:w #2 < \c_zero - + ( #2 + % ) - \else: - - ( #2 - % ) - \fi: - \fi: % ( ( - 1 ) / 2 ) - \fi: - / ( #2 ) + \int_use:N \int_eval:w + \exp_after:wN \int_div_truncate_aux:NwNw + \int_use:N \int_eval:w #1 \exp_after:wN ; + \int_use:N \int_eval:w #2 ; \int_eval_end: } +\cs_new:Npn \int_div_truncate_aux:NwNw #1#2; #3#4; + { + \if_meaning:w 0 #1 + \c_zero + \else: + ( + #1#2 + \if_meaning:w - #1 + \else: - \fi: + ( \if_meaning:w - #3 - \fi: #3#4 - \c_one ) / \c_two + ) + \fi: + / #3#4 + } % \end{macrocode} % For the sake of completeness: % \begin{macrocode} @@ -968,6 +974,7 @@ % \end{macro} % \end{macro} % \end{macro} +% \end{macro} % % \subsection{Creating and initialising integers} % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3io.dtx b/Master/texmf-dist/source/latex/l3kernel/l3io.dtx deleted file mode 100644 index 206d2daed09..00000000000 --- a/Master/texmf-dist/source/latex/l3kernel/l3io.dtx +++ /dev/null @@ -1,1467 +0,0 @@ -% \iffalse meta-comment -% -%% File: l3io.dtx Copyright (C) 1990-2012 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 LaTeX3 Project. -%% -%% ----------------------------------------------------------------------- -% -%<*driver|package> -\RequirePackage{l3names} -\GetIdInfo$Id: l3io.dtx 3245 2012-01-28 02:58:37Z bruno $ - {L3 Experimental input-output operations} -%</driver|package> -%<*driver> -\documentclass[full]{l3doc} -\begin{document} - \DocInput{\jobname.dtx} -\end{document} -%</driver> -% \fi -% -% \title{^^A -% The \pkg{l3io} package\\ Input--output operations^^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} -% -% Reading and writing from file streams is handled in \LaTeX3 using -% functions with prefixes \cs{iow_\ldots} (file reading) and -% \cs{ior_\ldots} (file writing). Many of the basic functions are -% very similar, with reading and writing using the same syntax and -% function concepts. As a result, the reading and writing functions -% are documented together where this makes sense. -% -% As \TeX{} is limited to $16$ input streams and $16$ output -% streams, direct use of the streams by the programmer is not -% supported in \LaTeX3. Instead, an internal pool of streams is -% maintained, and these are allocated and deallocated as needed -% by other modules. As a result, the programmer should close streams -% when they are no longer needed, to release them for other processes. -% -% Reading from or writing to a file requires a \meta{stream} to -% be used. This is a csname which refers to the file being processed, -% and is independent of the name of the file (except of course that -% the file name is needed when the file is opened). -% -% \section{Managing streams} -% -% \begin{function}[added = 2011-09-26, updated = 2011-12-27] -% {\ior_new:N, \ior_new:c, \iow_new:N, \io_new:c} -% \begin{syntax} -% \cs{ior_new:Nn} \meta{stream} -% \end{syntax} -% Globally reserves the name of the \meta{stream}, either for reading -% or for writing as appropriate. The \meta{stream} is not opened until the -% appropriate \cs{\ldots_open:Nn} function is used. Attempting to use -% a \meta{stream} which has not been opened will result in a \TeX{} -% error. -% \end{function} -% -% \begin{function}[updated = 2012-01-25]{\ior_open:Nn, \ior_open:cn} -% \begin{syntax} -% \cs{ior_open:Nn} \meta{stream} \Arg{file name} -% \end{syntax} -% Opens \meta{file name} for reading using \meta{stream} as the -% control sequence for file access. If the \meta{stream} was already -% open it is closed before the new operation begins. The -% \meta{stream} is available for access immediately and will remain -% allocated to \meta{file name} until a \cs{ior_close:N} instruction -% is given or the file ends. -% \begin{texnote} -% The \meta{file name} may contain both literal items and expandable -% content, which should on full expansion be the desired file name. -% Any active characters (as declared in \cs{l_char_active_seq}) will -% \emph{not} be expanded, allowing the direct use of these in -% file names. -% \end{texnote} -% \end{function} -% -% \begin{function}[updated = 2012-01-25]{\iow_open:Nn, \iow_open:cn} -% \begin{syntax} -% \cs{iow_open:Nn} \meta{stream} \Arg{file name} -% \end{syntax} -% Opens \meta{file name} for writing using \meta{stream} as the -% control sequence for file access. If the \meta{stream} was already -% open it is closed before the new operation begins. The -% \meta{stream} is available for access immediately and will remain -% allocated to \meta{file name} until a \cs{iow_close:N} instruction -% is given or the file ends. Opening a file for writing will clear -% any existing content in the file (\emph{i.e.}~writing is \emph{not} -% additive). -% \begin{texnote} -% The \meta{file name} may contain both literal items and expandable -% content, which should on full expansion be the desired file name. -% Any active characters (as declared in \cs{l_char_active_seq}) will -% \emph{not} be expanded, allowing the direct use of these in -% file names. -% \end{texnote} -% \end{function} -% -% \begin{function}[updated = 2011-12-27]{\ior_close:N, \ior_close:c} -% \begin{syntax} -% \cs{ior_close:N} \meta{stream} -% \end{syntax} -% Closes the \meta{stream}. Streams should always be closed when -% they are finished with as this ensures that they remain available -% to other programmer. -% \end{function} -% -% \begin{function}[updated = 2011-12-27]{\iow_close:N, \iow_close:c} -% \begin{syntax} -% \cs{iow_close:N} \meta{stream} -% \end{syntax} -% Closes the \meta{stream}. Streams should always be closed when -% they are finished with as this ensures that they remain available -% to other programmer. -% \end{function} -% -% \begin{function}{\ior_list_streams:, \iow_list_streams:} -% \begin{syntax} -% \cs{ior_list_streams:} \\ -% \cs{iow_list_streams:} -% \end{syntax} -% Displays a list of the file names associated with each open -% stream: intended for tracking down problems. -% \end{function} -% -% \section{Writing to files} -% -% \begin{function}{\iow_now:Nn, \iow_now:Nx} -% \begin{syntax} -% \cs{iow_now:Nn} \meta{stream} \Arg{tokens} -% \end{syntax} -% This functions writes \meta{tokens} to the specified -% \meta{stream} immediately (\emph{i.e.}~the write operation is called -% on expansion of \cs{iow_now:Nn}). -% \begin{texnote} -% \cs{iow_now:Nx} is a protected macro which expands to -% the two \TeX{} primitives \tn{immediate}\tn{write}. -% \end{texnote} -% \end{function} -% -% \begin{function}{\iow_log:n, \iow_log:x} -% \begin{syntax} -% \cs{iow_log:n} \Arg{tokens} -% \end{syntax} -% This function writes the given \meta{tokens} to the log (transcript) -% file immediately: it is a dedicated version of \cs{iow_now:Nn}. -% \end{function} -% -% \begin{function}{\iow_term:n, \iow_term:x} -% \begin{syntax} -% \cs{iow_term:n} \Arg{tokens} -% \end{syntax} -% This function writes the given \meta{tokens} to the terminal -% file immediately: it is a dedicated version of \cs{iow_now:Nn}. -% \end{function} -% -% \begin{function}{\iow_now_when_avail:Nn, \iow_now_when_avail:Nx} -% \begin{syntax} -% \cs{iow_now_when_avail:Nn} \meta{stream} \Arg{tokens} -% \end{syntax} -% If \meta{stream} is open, writes the \meta{tokens} to the \meta{stream} -% in the same manner as \cs{iow_now:Nn}. If the \meta{stream} is not open, -% the \meta{tokens}are simply thrown away. -% \end{function} -% -% \begin{function}{\iow_shipout:Nn, \iow_shipout:Nx} -% \begin{syntax} -% \cs{iow_shipout:Nn} \meta{stream} \Arg{tokens} -% \end{syntax} -% This functions writes \meta{tokens} to the specified -% \meta{stream} when the current page is finalised (\emph{i.e.}~at -% shipout). The \texttt{x}-type variants expand the \meta{tokens} -% at the point where the function is used but \emph{not} when the -% resulting tokens are written to the \meta{stream} -% (\emph{cf.}~\cs{iow_shipout_x:Nn}). -% \end{function} -% -% \begin{function}{\iow_shipout_x:Nn, \iow_shipout_x:Nx} -% \begin{syntax} -% \cs{iow_shipout_x:Nn} \meta{stream} \Arg{tokens} -% \end{syntax} -% This functions writes \meta{tokens} to the specified -% \meta{stream} when the current page is finalised (\emph{i.e}.~at -% shipout). The \meta{tokens} are expanded at the time of writing -% in addition to any expansion when the function is used. This makes -% these functions suitable for including material finalised during -% the page building process (such as the page number integer). -% \begin{texnote} -% \cs{iow_shipout_x:Nn} is the \TeX{} primitive \tn{write} renamed. -% \end{texnote} -% \end{function} -% -% \begin{function}[EXP]{\iow_char:N} -% \begin{syntax} -% \cs{iow_char:N} \meta{token} -% \end{syntax} -% Inserts \meta{token} into the output stream. Useful when trying to -% write difficult characters such as "%", "{", "}", -% \emph{etc}.~in messages, for example: -% \begin{verbatim} -% \iow_now:Nx \g_my_iow { \iow_char:N \{ text \iow_char:N \} } -% \end{verbatim} -% The function has no effect if writing is taking place without -% expansion (\emph{e.g.}~in the second argument of \cs{iow_now:Nn}). -% \end{function} -% -% \begin{function}[EXP]{\iow_newline:} -% \begin{syntax} -% \cs{iow_newline:} -% \end{syntax} -% Function to add a new line within the \meta{tokens} written to a -% file. The function has no effect if writing is taking place without -% expansion (\emph{e.g.}~in the second argument of \cs{iow_now:Nn}). -% \end{function} -% -% \section{Wrapping lines in output} -% -% \begin{function}[updated = 2011-09-21]{\iow_wrap:xnnnN} -% \begin{syntax} -% \cs{iow_wrap:xnnnN} \Arg{text} \Arg{run-on text} \Arg{run-on length} \Arg{set up} \meta{function} -% \end{syntax} -% This function will wrap the \meta{text} to a fixed number of -% characters per line. At the start of each line which is wrapped, -% the \meta{run-on text} will be inserted. The line length targeted -% will be the value of \cs{l_iow_line_length_int} minus the -% \meta{run-on length}. The later value should be the number of -% characters in the \meta{run-on text}. Additional functions may be -% added to the wrapping by using the \meta{set up}, which is executed -% before the wrapping takes place. The result of the wrapping operation -% is passed as a braced argument to the \meta{function}, which will -% typically be a wrapper around a writing operation. Within the -% \meta{text}, -% \begin{itemize} -% \item |\\| may be used to force a new line, -% \item \verb|\ | may be used to represent a forced space -% (for example after a control sequence), -% \item |\#|, |\%|, |\{|, |\}|, |\~| may be used to represent -% the corresponding character, -% \item \cs{iow_indent:n} may be used to indent a part of the -% message. -% \end{itemize} -% Both the wrapping process and the subsequent write operation -% will perform \texttt{x}-type expansion. For this reason, material which -% is to be written \enquote{as is} should be given as the argument to -% \cs{token_to_str:N} or \cs{tl_to_str:n} (as appropriate) within -% the \meta{text}. The output of \cs{iow_wrap:xnnnN} (\emph{i.e.}~the -% argument passed to the \meta{function}) will consist of characters of -% category code $12$ (other) and $10$ (space) only. This means that the -% output will \emph{not} expand further when written to a file. -% \end{function} -% -% \begin{function}[added = 2011-09-21]{\iow_indent:n} -% \begin{syntax} -% \cs{iow_indent:n} \Arg{text} -% \end{syntax} -% In the context of \cs{iow_wrap:xnnnN} (for instance in messages), -% indents \meta{text} by four spaces. This function will not cause -% a line break, and only affects lines which start within the scope -% of the \meta{text}. In case the indented \meta{text} should appear -% on separate lines from the surrounding text, use |\\| to force -% line breaks. -% \end{function} -% -% \begin{variable}{\l_iow_line_length_int} -% The maximum length of a line to be written by the \cs{iow_wrap:xxnnN} -% function. This value depends on the \TeX{} system in use: the standard -% value is $78$, which is typically correct for unmodified \TeX{}live -% and MiK\TeX{} systems. -% \end{variable} -% -% \begin{variable}[added = 2011-09-05]{\c_catcode_other_space_tl} -% Token list containing one character with category code $12$, -% (\enquote{other}), and character code $32$ (space). -% \end{variable} -% -% \section{Reading from files} -% -% \begin{function}{\ior_to:NN,\ior_gto:NN} -% \begin{syntax} -% \cs{ior_to:NN} \meta{stream} \meta{token list variable} -% \end{syntax} -% Functions that reads one or more lines (until an equal number of left -% and right braces are found) from the input \meta{stream} and stores -% the result in the \meta{token list} variable, locally or globally. If the -% \meta{stream} is not open, input is requested from the terminal. -% The material read from the \meta{stream} will be tokenized by -% \TeX{} according to the category codes in force when the function -% is used. -% \begin{texnote} -% This protected macro expands to the \TeX{} primitives \tn{read} -% or \tn{global}\tn{read} along with the |to| keyword. -% \end{texnote} -% \end{function} -% -% \begin{function}{\ior_str_to:NN,\ior_str_gto:NN} -% \begin{syntax} -% \cs{ior_str_to:NN} \meta{stream} \meta{token list variable} -% \end{syntax} -% Functions that reads one line from the input \meta{stream} and stores -% the result in the \meta{token list} variable, locally or globally. If the -% \meta{stream} is not open, input is requested from the terminal. -% The material read from the \meta{stream} as a series of tokens with -% category code $12$ (other), with the exception of space -% characters which are given category code $10$ (space). -% \begin{texnote} -% This protected macro expands to the \eTeX{} primitives \tn{readline} -% or \tn{global}\tn{readline} along with the |to| keyword. -% \end{texnote} -% \end{function} -% -%\begin{function}[updated = 2011-09-26, EXP,pTF]{\ior_if_eof:N} -% \begin{syntax} -% \cs{ior_if_eof_p:N} \meta{stream} \\ -% \cs{ior_if_eof:NTF} \meta{stream} \Arg{true code} \Arg{false code} -% \end{syntax} -% 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. -%\end{function} -% -% \section{Constants} -% -% \begin{variable}{\c_term_ior} -% Constant input stream for reading from the terminal. Reading from this -% stream using \cs{ior_to:NN} or similar will result in a prompt from -% \TeX{} of the form -% \begin{verbatim} -% <tl>= -% \end{verbatim} -% \end{variable} -% -% \begin{variable}{\c_log_iow, \c_term_iow} -% Constant output streams for writing to the log and to the terminal -% (plus the log), respectively. -% \end{variable} -% -% \section{Experimental functions} -% -% \begin{function}{\ior_map_inline:nn} -% \begin{syntax} -% \cs{ior_map_inline:nn} \Arg{file name} \Arg{inline function} -% \end{syntax} -% Applies the \meta{inline function} to \meta{items} obtained by -% reading one or more lines (until an equal number of left and right -% braces are found) from the \meta{file}. The \meta{inline function} -% should consist of code which will receive the \meta{line} as |#1|. -% One in line mapping can be nested inside another. -% If the file is not found, the \meta{inline function} is never called. -% \end{function} -% -% \begin{function}{\ior_str_map_inline:nn} -% \begin{syntax} -% \cs{ior_str_map_inline:nn} \Arg{file name} \Arg{inline function} -% \end{syntax} -% Applies the \meta{inline function} to every \meta{line} -% in the \meta{file}. The material is read from the \meta{file} -% as a series of tokens with category code $12$ (other), with the -% exception of space characters which are given category code $10$ -% (space). The \meta{inline function} should consist of code which -% will receive the \meta{line} as |#1|. -% One in line mapping can be nested inside another. -% If the file is not found, the \meta{inline function} is never called. -% \end{function} -% -% \section{Internal input--output functions} -% -% \begin{function}[EXP]{\if_eof:w} -% \begin{syntax} -% \cs{if_eof:w} \meta{stream} -% ~~\meta{true code} -% \cs{else:} -% ~~\meta{false code} -% \cs{fi:} -% \end{syntax} -% Tests if the \meta{stream} returns \enquote{end of file}, which is true -% for non-existent files. The \cs{else:} branch is optional. -% \begin{texnote} -% This is the \TeX{} primitive \tn{ifeof}. -% \end{texnote} -% \end{function} -% -% \begin{function}[added = 2012-01-23] -% {\ior_open_unsafe:Nn, \iow_open_unsafe:Nn} -% \begin{syntax} -% \cs{ior_open_unsafe:Nn} \meta{stream} \Arg{file name} -% \end{syntax} -% These functions have identical syntax to the generally-available -% versions without the |_unsafe| suffix. However, these functions do not -% take precautions against active characters in the \meta{file name}: they -% are therefore intended to be used by higher-level functions which -% have already fully expanded the \meta{file name} and which need to -% perform multiple open or close operations. See for example the -% implementation of \cs{file_add_path:Nn}, -% \end{function} -% -% \begin{function}{\ior_raw_new:N, \ior_raw_new:c} -% \begin{syntax} -% \cs{ior_raw_new:N} \meta{stream} -% \end{syntax} -% Directly allocates a new stream for reading, bypassing the stack -% system. This is to be used only when a new stream is required at a -% \TeX{} level, when a new stream is requested by the stack itself. -% \end{function} -% -% \begin{function}{\iow_raw_new:N, \iow_raw_new:c} -% \begin{syntax} -% \cs{iow_raw_new:N} \meta{stream} -% \end{syntax} -% Directly allocates a new stream for writing, bypassing the stack -% system. This is to be used only when a new stream is required at a -% \TeX{} level, when a new stream is requested by the stack itself. -% \end{function} -% -% \end{documentation} -% -% \begin{implementation} -% -% \section{\pkg{l3io} implementation} -% -% \begin{macrocode} -%<*initex|package> -% \end{macrocode} -% -% \begin{macrocode} -%<*package> -\ProvidesExplPackage - {\ExplFileName}{\ExplFileDate}{\ExplFileVersion}{\ExplFileDescription} -\package_check_loaded_expl: -%</package> -% \end{macrocode} -% -% \subsection{Primitives} -% -% \begin{macro}{\if_eof:w} -% The primitive conditional -% \begin{macrocode} -\cs_new_eq:NN \if_eof:w \tex_ifeof:D -% \end{macrocode} -% \end{macro} -% -% \subsection{Variables and constants} -% -% \begin{variable}{\c_term_ior} -% Reading from the terminal (with a prompt) is done using a positive -% but non-existent stream number. Unlike writing, there is no concept -% of reading from the log. -% \begin{macrocode} -\cs_new_eq:NN \c_term_ior \c_sixteen -% \end{macrocode} -% \end{variable} -% -% \begin{variable}{\c_log_iow, \c_term_iow} -% Here we allocate two output streams for writing to the transcript -% file only (\cs{c_log_iow}) and to both the terminal and -% transcript file (\cs{c_term_iow}). -% \begin{macrocode} -\cs_new_eq:NN \c_log_iow \c_minus_one -\cs_new_eq:NN \c_term_iow \c_sixteen -% \end{macrocode} -% \end{variable} -% -% \begin{variable}{\c_iow_streams_tl, \c_ior_streams_tl} -% The list of streams available, by number. -% \begin{macrocode} -\tl_const:Nn \c_iow_streams_tl - { - \c_zero - \c_one - \c_two - \c_three - \c_four - \c_five - \c_six - \c_seven - \c_eight - \c_nine - \c_ten - \c_eleven - \c_twelve - \c_thirteen - \c_fourteen - \c_fifteen - } -\cs_new_eq:NN \c_ior_streams_tl \c_iow_streams_tl -% \end{macrocode} -% \end{variable} -% -% \begin{variable}{\g_iow_streams_prop, \g_ior_streams_prop} -% The allocations for streams are stored in property lists, which -% are set up to have a \enquote{full} set of allocations from the start. -% In package mode, a few slots are always taken, so these are -% blocked off from use. -% \begin{macrocode} -\prop_new:N \g_iow_streams_prop -\prop_new:N \g_ior_streams_prop -%<*package> -\prop_put:Nnn \g_iow_streams_prop { 0 } { LaTeX2e~reserved } -\prop_put:Nnn \g_iow_streams_prop { 1 } { LaTeX2e~reserved } -\prop_put:Nnn \g_iow_streams_prop { 2 } { LaTeX2e~reserved } -\prop_put:Nnn \g_ior_streams_prop { 0 } { LaTeX2e~reserved } -%</package> -% \end{macrocode} -% \end{variable} -% -% \begin{variable}{\l_ior_internal_tl, \l_iow_internal_tl} -% For expanding file names. -% \begin{macrocode} -\tl_new:N \l_ior_internal_tl -\tl_new:N \l_iow_internal_tl -% \end{macrocode} -% \end{variable} -% -% \begin{variable}{\l_iow_stream_int, \l_ior_stream_int} -% Used to track the number allocated to the stream being created: -% this is taken from the property list but does alter. -% \begin{macrocode} -\int_new:N \l_iow_stream_int -\cs_new_eq:NN \l_ior_stream_int \l_iow_stream_int -% \end{macrocode} -% \end{variable} -% -% \subsection{Stream management} -% -% \begin{macro}[int]{\ior_raw_new:N, \ior_raw_new:c} -% \begin{macro}[int]{\iow_raw_new:N, \iow_raw_new:c} -% The lowest level for stream management is actually creating raw \TeX{} -% streams. As these are very limited (even with \eTeX{}), this should not -% be addressed directly. -% \begin{macrocode} -%<*initex> -\alloc_setup_type:nnn { ior } \c_zero \c_sixteen -\cs_new_protected:Npn \ior_raw_new:N #1 - { \alloc_reg:nNN { ior } \tex_chardef:D #1 } -\alloc_setup_type:nnn { iow } \c_zero \c_sixteen -\cs_new_protected:Npn \iow_raw_new:N #1 - { \alloc_reg:nNN { iow } \tex_chardef:D #1 } -%</initex> -%<*package> -\cs_set_eq:NN \iow_raw_new:N \newwrite -\cs_set_eq:NN \ior_raw_new:N \newread -%</package> -\cs_generate_variant:Nn \ior_raw_new:N { c } -\cs_generate_variant:Nn \iow_raw_new:N { c } -% \end{macrocode} -% \end{macro} -% \end{macro} -% -% \begin{macro}{\ior_new:N, \ior_new:c, \iow_new:N, \iow_new:c} -% Reserving a new stream is done by defining the name as equal to using the -% terminal. -% \begin{macrocode} -\cs_new_protected:Npn \ior_new:N #1 { \cs_new_eq:NN #1 \c_term_ior } -\cs_generate_variant:Nn \ior_new:N { c } -\cs_new_protected:Npn \iow_new:N #1 { \cs_new_eq:NN #1 \c_term_iow } -\cs_generate_variant:Nn \iow_new:N { c } -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\ior_open:Nn, \ior_open:cn, \iow_open:Nn, \iow_open:cn} -% \begin{macro}[int]{\ior_open_unsafe:Nn, \iow_open_unsafe:Nn} -% In both cases, opening a stream starts with a call to the closing -% function: this is safest. There is then a loop through the -% allocation number list to find the first free stream number. -% When one is found the allocation can take place, the information -% can be stored and finally the file can actually be opened. Before -% any actual file operations there is a precaution against special -% characters in file names. -% \begin{macrocode} -\cs_new_protected:Npn \ior_open:Nn #1#2 - { - \group_begin: - \tl_to_str_active_safe:Nx \l_ior_internal_tl {#2} - \tl_if_in:NnT \l_ior_internal_tl { ~ } - { - \msg_kernel_error:nnx { io } { space-in-file-name } - { \l_ior_internal_tl } - } - \exp_args:NNNo \group_end: - \ior_open_unsafe:Nn #1 \l_ior_internal_tl - } -\cs_generate_variant:Nn \ior_open:Nn { c } -\cs_new_protected:Npn \iow_open:Nn #1#2 - { - \group_begin: - \tl_to_str_active_safe:Nx \l_iow_internal_tl {#2} - \tl_if_in:NnT \l_iow_internal_tl { ~ } - { - \msg_kernel_error:nnx { io } { space-in-file-name } - { \l_iow_internal_tl } - } - \exp_args:NNNo \group_end: - \iow_open_unsafe:Nn #1 \l_iow_internal_tl - } -\cs_generate_variant:Nn \iow_open:Nn { c } -\cs_new_protected:Npn \ior_open_unsafe:Nn #1#2 - { - \ior_close:N #1 - \int_set:Nn \l_ior_stream_int \c_sixteen - \tl_map_function:NN \c_ior_streams_tl \ior_alloc_read:n - \int_compare:nNnTF \l_ior_stream_int = \c_sixteen - { \msg_kernel_fatal:nn { ior } { streams-exhausted } } - { - \ior_stream_alloc:N #1 - \prop_gput:NVn \g_ior_streams_prop \l_ior_stream_int {#2} - \tex_openin:D #1#2 \scan_stop: - } - } -\cs_new_protected:Npn \iow_open_unsafe:Nn #1#2 - { - \iow_close:N #1 - \int_set:Nn \l_iow_stream_int \c_sixteen - \tl_map_function:NN \c_iow_streams_tl \iow_alloc_write:n - \int_compare:nNnTF \l_iow_stream_int = \c_sixteen - { \msg_kernel_fatal:nn { iow } { streams-exhausted } } - { - \iow_stream_alloc:N #1 - \prop_gput:NVn \g_iow_streams_prop \l_iow_stream_int {#2} - \tex_immediate:D \tex_openout:D #1#2 \scan_stop: - } - } -% \end{macrocode} -% \end{macro} -% \end{macro} -% -% \begin{macro}[aux]{\ior_alloc_read:n} -% \begin{macro}[aux]{\iow_alloc_write:n} -% These functions are used to see if a particular stream is available. -% The property list contains file names for streams in use, so -% any unused ones are for the taking. -% \begin{macrocode} -\cs_new_protected:Npn \iow_alloc_write:n #1 - { - \prop_if_in:NnF \g_iow_streams_prop {#1} - { - \int_set:Nn \l_iow_stream_int {#1} - \tl_map_break: - } - } -\cs_new_protected:Npn \ior_alloc_read:n #1 - { - \prop_if_in:NnF \g_iow_streams_prop {#1} - { - \int_set:Nn \l_ior_stream_int {#1} - \tl_map_break: - } - } -% \end{macrocode} -% \end{macro} -% \end{macro} -% -% \begin{macro}[aux]{\iow_stream_alloc:N} -% \begin{macro}[aux]{\ior_stream_alloc:N} -% \begin{macro}[aux]{\iow_stream_alloc_aux:} -% \begin{macro}[aux]{\ior_stream_alloc_aux:} -% \begin{variable}{\g_iow_internal_iow} -% \begin{variable}{\g_ior_internal_ior} -% Allocating a raw stream is much easier in \IniTeX{} mode than for -% the package. For the format, all streams will be allocated by -% \pkg{l3io} and so there is a simple check to see if a raw -% stream is actually available. On the other hand, for the -% package there will be non-managed streams. So if the managed -% one is not open, a check is made to see if some other managed -% stream is available before deciding to open a new one. If a new -% one is needed, we get the number allocated by \LaTeXe{} to get -% \enquote{back on track} with allocation. -% \begin{macrocode} -\iow_new:N \g_iow_internal_iow -\ior_new:N \g_ior_internal_ior -\cs_new_protected:Npn \iow_stream_alloc:N #1 - { - \cs_if_exist:cTF { g_iow_ \int_use:N \l_iow_stream_int _iow } - { \cs_gset_eq:Nc #1 { g_iow_ \int_use:N \l_iow_stream_int _iow } } - { -%<*package> - \iow_stream_alloc_aux: - \int_compare:nNnT \l_iow_stream_int = \c_sixteen - { - \iow_raw_new:N \g_iow_internal_iow - \int_set:Nn \l_iow_stream_int { \g_iow_internal_iow } - \cs_gset_eq:cN - { g_iow_ \int_use:N \l_iow_stream_int _iow } \g_iow_internal_iow - } -%</package> -%<*initex> - \iow_raw_new:c { g_iow_ \int_use:N \l_iow_stream_int _iow } -%</initex> - \cs_gset_eq:Nc #1 { g_iow_ \int_use:N \l_iow_stream_int _iow } - } - } -%<*package> -\cs_new_protected_nopar:Npn \iow_stream_alloc_aux: - { - \int_incr:N \l_iow_stream_int - \int_compare:nNnT \l_iow_stream_int < \c_sixteen - { - \cs_if_exist:cTF { g_iow_ \int_use:N \l_iow_stream_int _iow } - { - \prop_if_in:NVT \g_iow_streams_prop \l_iow_stream_int - { \iow_stream_alloc_aux: } - } - { \iow_stream_alloc_aux: } - } - } -%</package> -\cs_new_protected:Npn \ior_stream_alloc:N #1 - { - \cs_if_exist:cTF { g_ior_ \int_use:N \l_ior_stream_int _ior } - { \cs_gset_eq:Nc #1 { g_ior_ \int_use:N \l_ior_stream_int _ior } } - { -%<*package> - \ior_stream_alloc_aux: - \int_compare:nNnT \l_ior_stream_int = \c_sixteen - { - \ior_raw_new:N \g_ior_internal_ior - \int_set:Nn \l_ior_stream_int { \g_ior_internal_ior } - \cs_gset_eq:cN - { g_ior_ \int_use:N \l_iow_stream_int _ior } \g_ior_internal_ior - } -%</package> -%<*initex> - \ior_raw_new:c { g_ior_ \int_use:N \l_ior_stream_int _ior } -%</initex> - \cs_gset_eq:Nc #1 { g_ior_ \int_use:N \l_ior_stream_int _ior } - } - } -%<*package> -\cs_new_protected_nopar:Npn \ior_stream_alloc_aux: - { - \int_incr:N \l_ior_stream_int - \int_compare:nNnT \l_ior_stream_int < \c_sixteen - { - \cs_if_exist:cTF { g_ior_ \int_use:N \l_ior_stream_int _ior } - { - \prop_if_in:NVT \g_ior_streams_prop \l_ior_stream_int - { \ior_stream_alloc_aux: } - } - { \ior_stream_alloc_aux: } - } - } -%</package> -% \end{macrocode} -% \end{variable} -% \end{variable} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% -% \begin{macro}{\iow_close:N, \iow_close:c} -% \begin{macro}{\iow_close:N, \iow_close:c} -% Closing a stream is not quite the reverse of opening one. First, -% the close operation is easier than the open one, and second as the -% stream is actually a number we can use it directly to show that the -% slot has been freed up. -% \begin{macrocode} -\cs_new_protected:Npn \ior_close:N #1 - { - \cs_if_exist:NT #1 - { - \int_compare:nNnF #1 = \c_minus_one - { - \int_compare:nNnF #1 = \c_sixteen - { \tex_closein:D #1 } - \prop_gdel:NV \g_ior_streams_prop #1 - \cs_gset_eq:NN #1 \c_term_ior - } - } - } -\cs_new_protected:Npn \iow_close:N #1 - { - \cs_if_exist:NT #1 - { - \int_compare:nNnF #1 = \c_minus_one - { - \int_compare:nNnF #1 = \c_sixteen - { \tex_closein:D #1 } - \prop_gdel:NV \g_iow_streams_prop #1 - \cs_gset_eq:NN #1 \c_term_iow - } - } - } -\cs_generate_variant:Nn \ior_close:N { c } -\cs_generate_variant:Nn \iow_close:N { c } -% \end{macrocode} -% \end{macro} -% \end{macro} -% -% \begin{macro}{\ior_list_streams:} -% Show the property lists, but with some \enquote{pretty printing}. -% See the \pkg{l3msg} module. If there are no open read streams, -% issue the message \texttt{show-no-stream}, and show an empty -% token list. If there are open read streams, format them with -% \cs{msg_aux_show_unbraced:nn}, and with the message -% \texttt{show-open-streams}. -% \begin{macrocode} -\cs_new_protected_nopar:Npn \ior_list_streams: - { \ior_list_streams_aux:Nn \g_ior_streams_prop { ior } } -\cs_new_protected_nopar:Npn \iow_list_streams: - { \ior_list_streams_aux:Nn \g_iow_streams_prop { iow } } -\cs_new_protected:Npn \ior_list_streams_aux:Nn #1#2 - { - \msg_aux_use:nn { LaTeX / #2 } - { \prop_if_empty:NTF #1 { show-no-stream } { show-open-streams } } - \msg_aux_show:x - { \prop_map_function:NN #1 \msg_aux_show_unbraced:nn } - } -% \end{macrocode} -% \end{macro} -% -% Text for the error messages. -% \begin{macrocode} -\msg_kernel_new:nnnn { iow } { streams-exhausted } - { Output~streams~exhausted } - { - TeX~can~only~open~up~to~16~output~streams~at~one~time.\\ - All~16 are currently~in~use,~and~something~wanted~to~open - another~one. - } -\msg_kernel_new:nnnn { ior } { streams-exhausted } - { Input~streams~exhausted } - { - TeX~can~only~open~up~to~16~input~streams~at~one~time.\\ - All~16 are currently~in~use,~and~something~wanted~to~open - another~one. - } -% \end{macrocode} -% -% \subsection{Deferred writing} -% -% \begin{macro}{\iow_shipout_x:Nn, \iow_shipout_x:Nx} -% First the easy part, this is the primitive. -% \begin{macrocode} -\cs_new_eq:NN \iow_shipout_x:Nn \tex_write:D -\cs_generate_variant:Nn \iow_shipout_x:Nn { Nx } -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\iow_shipout:Nn, \iow_shipout:Nx} -% With \eTeX{} available deferred writing is easy. -% \begin{macrocode} -\cs_new_protected:Npn \iow_shipout:Nn #1#2 - { \iow_shipout_x:Nn #1 { \exp_not:n {#2} } } -\cs_generate_variant:Nn \iow_shipout:Nn { Nx } -% \end{macrocode} -% \end{macro} -% -% \subsection{Immediate writing} -% -% \begin{macro}{\iow_now:Nx} -% An abbreviation for an often used operation, which immediately -% writes its second argument expanded to the output stream. -% \begin{macrocode} -\cs_new_protected_nopar:Npn \iow_now:Nx { \tex_immediate:D \iow_shipout_x:Nn } -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\iow_now:Nn} -% This routine writes the second argument onto the output stream without -% expansion. If this stream isn't open, the output goes to the terminal -% instead. If the first argument is no output stream at all, we get an -% internal error. -% \begin{macrocode} -\cs_new_protected:Npn \iow_now:Nn #1#2 - { \iow_now:Nx #1 { \exp_not:n {#2} } } -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\iow_log:n, \iow_log:x} -% \begin{macro}{\iow_term:n, \iow_term:x} -% Writing to the log and the terminal directly are relatively easy. -% \begin{macrocode} -\cs_set_protected_nopar:Npn \iow_log:x { \iow_now:Nx \c_log_iow } -\cs_new_protected_nopar:Npn \iow_log:n { \iow_now:Nn \c_log_iow } -\cs_set_protected_nopar:Npn \iow_term:x { \iow_now:Nx \c_term_iow } -\cs_new_protected_nopar:Npn \iow_term:n { \iow_now:Nn \c_term_iow } -% \end{macrocode} -%\end{macro} -%\end{macro} -% -% \begin{macro}{\iow_now_when_avail:Nn, \iow_now_when_avail:Nx} -% For writing only if the stream requested is open at all. -% \begin{macrocode} -\cs_new_protected:Npn \iow_now_when_avail:Nn #1 - { \cs_if_free:NTF #1 { \use_none:n } { \iow_now:Nn #1 } } -\cs_new_protected:Npn \iow_now_when_avail:Nx #1 - { \cs_if_free:NTF #1 { \use_none:n } { \iow_now:Nx #1 } } -% \end{macrocode} -% \end{macro} -% -% \subsection{Special characters for writing} -% -% \begin{macro}{\iow_newline:} -% Global variable holding the character that forces a new line when -% something is written to an output stream -% \begin{macrocode} -\cs_new_nopar:Npn \iow_newline: { ^^J } -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\iow_char:N} -% Function to write any escaped char to an output stream. -% \begin{macrocode} -\cs_new_eq:NN \iow_char:N \cs_to_str:N -% \end{macrocode} -% \end{macro} -% -% \subsection{Hard-wrapping lines based on length} -% -% The code here implements a generic hard-wrapping function. This is -% used by the messaging system, but is designed such that it is -% available for other uses. -% -% \begin{macro}{\l_iow_line_length_int} -% This is the \enquote{raw} length of a line which can be written to a -% file. The standard value is the line length typically used by -% \TeX{}Live and Mik\TeX{}. -% \begin{macrocode} -\int_new:N \l_iow_line_length_int -\int_set:Nn \l_iow_line_length_int { 78 } -% \end{macrocode} -% \end{macro} -% -% \begin{macro}[aux]{\l_iow_target_length_int} -% This stores the target line length: the full length minus any -% part for a leader at the start of each line. -% \begin{macrocode} -\int_new:N \l_iow_target_length_int -% \end{macrocode} -% \end{macro} -% -% \begin{macro}[aux]{ -% \l_iow_current_line_int, -% \l_iow_current_word_int, -% \l_iow_current_indentation_int} -% These store the number of characters in the line and word currently -% being constructed, and the current indentation, respectively. -% \begin{macrocode} -\int_new:N \l_iow_current_line_int -\int_new:N \l_iow_current_word_int -\int_new:N \l_iow_current_indentation_int -% \end{macrocode} -% \end{macro} -% -% \begin{macro}[aux]{ -% \l_iow_current_line_tl, -% \l_iow_current_word_tl, -% \l_iow_current_indentation_tl} -% These hold the current line of text and current word, -% and a number of spaces for indentation, respectively. -% \begin{macrocode} -\tl_new:N \l_iow_current_line_tl -\tl_new:N \l_iow_current_word_tl -\tl_new:N \l_iow_current_indentation_tl -% \end{macrocode} -%\end{macro} -% -% \begin{macro}[aux]{\l_iow_wrap_tl} -% Used for the expansion step before detokenizing. -% \begin{macrocode} -\tl_new:N \l_iow_wrap_tl -% \end{macrocode} -% \end{macro} -% -% \begin{macro}[aux]{\l_iow_wrapped_tl} -% The output from wrapping text: fully expanded and with lines -% which are not overly long. -% \begin{macrocode} -\tl_new:N \l_iow_wrapped_tl -% \end{macrocode} -% \end{macro} -% -% \begin{macro}[aux]{\l_iow_line_start_bool} -% Boolean to avoid adding a space at the beginning of forced newlines. -% \begin{macrocode} -\bool_new:N \l_iow_line_start_bool -% \end{macrocode} -% \end{macro} -% -% \begin{macro}[aux]{\c_catcode_other_space_tl} -% Lowercase a character with category code $12$ to produce an -% \enquote{other} space. We can do everything within the group, -% because \cs{tl_const:Nn} defines its argument globally. -% \begin{macrocode} -\group_begin: - \char_set_catcode_other:N \* - \char_set_lccode:nn {`\*} {`\ } - \tl_to_lowercase:n { \tl_const:Nn \c_catcode_other_space_tl { * } } -\group_end: -% \end{macrocode} -% \end{macro} -% -% \begin{macro}[aux]{\c_iow_wrap_marker_tl} -% \begin{macro}[aux]{ -% \c_iow_wrap_end_marker_tl, -% \c_iow_wrap_newline_marker_tl, -% \c_iow_wrap_indent_marker_tl, -% \c_iow_wrap_unindent_marker_tl} -% \begin{macro}[aux]{\iow_wrap_new_marker:n} -% Every special action of the wrapping code is preceeded by -% the same recognizable string, \cs{c_iow_wrap_marker_tl}. -% Upon seeing that \enquote{word}, the wrapping code reads -% one space-delimited argument to know what operation to -% perform. The setting of \tn{escapechar} here is not -% very important, but makes \cs{c_iow_wrap_marker_tl} look -% nicer. Note that \cs{iow_wrap_new_marker:n} does not -% survive the group, but all constants are defined globally. -% \begin{macrocode} -\group_begin: - \int_set_eq:NN \tex_escapechar:D \c_minus_one - \tl_const:Nx \c_iow_wrap_marker_tl - { \tl_to_str:n { \^^I \^^O \^^W \^^_ \^^W \^^R \^^A \^^P } } - \cs_set:Npn \iow_wrap_new_marker:n #1 - { - \tl_const:cx { c_iow_wrap_ #1 _marker_tl } - { - \c_catcode_other_space_tl - \c_iow_wrap_marker_tl - \c_catcode_other_space_tl - #1 - \c_catcode_other_space_tl - } - } - \iow_wrap_new_marker:n { end } - \iow_wrap_new_marker:n { newline } - \iow_wrap_new_marker:n { indent } - \iow_wrap_new_marker:n { unindent } -\group_end: -% \end{macrocode} -% \end{macro} -% \end{macro} -% \end{macro} -% -% \begin{macro}{\iow_indent:n} -% \begin{macro}[aux]{\iow_indent_expandable:n} -% We give a dummy (protected) definition to \cs{iow_indent:n} -% when outside messages. Within wrapped message, it places -% the instruction for increasing the indentation before its -% argument, and the instruction for unindenting afterwards. -% Note that there will be no forced line-break, so the indentation -% only changes when the next line is started. -% \begin{macrocode} -\cs_new_protected:Npn \iow_indent:n #1 { } -\cs_new:Npx \iow_indent_expandable:n #1 - { - \c_iow_wrap_indent_marker_tl - #1 - \c_iow_wrap_unindent_marker_tl - } -% \end{macrocode} -% \end{macro} -% \end{macro} -% -% \begin{macro}{\iow_wrap:xnnnN} -% The main wrapping function works as follows. The target number of -% characters in a line is calculated, before fully-expanding the input -% such that |\\| and \verb*|\ | are converted into the appropriate -% values. There is then a loop over each word in the input, which -% will do the actual wrapping. After the loop, the resulting text is -% passed on to the function which has been given as a post-processor. -% The argument |#4| is available for additional set up steps for -% the output. The definition of |\\| and \verb*|\ | use an -% \enquote{other} space rather than a normal space, because the latter -% might be absorbed by \TeX{} to end a number or other \texttt{f}-type -% expansions. The \cs{tl_to_str:N} step converts the \enquote{other} -% space back to a normal space. -% \begin{macrocode} -\cs_new_protected:Npn \iow_wrap:xnnnN #1#2#3#4#5 - { - \group_begin: - \int_set:Nn \l_iow_target_length_int { \l_iow_line_length_int - ( #3 ) } - \int_zero:N \l_iow_current_indentation_int - \tl_clear:N \l_iow_current_indentation_tl - \int_zero:N \l_iow_current_line_int - \tl_clear:N \l_iow_current_line_tl - \tl_clear:N \l_iow_wrap_tl - \bool_set_true:N \l_iow_line_start_bool - \int_set_eq:NN \tex_escapechar:D \c_minus_one - \cs_set_nopar:Npx \{ { \token_to_str:N \{ } - \cs_set_nopar:Npx \# { \token_to_str:N \# } - \cs_set_nopar:Npx \} { \token_to_str:N \} } - \cs_set_nopar:Npx \% { \token_to_str:N \% } - \cs_set_nopar:Npx \~ { \token_to_str:N \~ } - \int_set:Nn \tex_escapechar:D { 92 } - \cs_set_eq:NN \\ \c_iow_wrap_newline_marker_tl - \cs_set_eq:NN \ \c_catcode_other_space_tl - \cs_set_eq:NN \iow_indent:n \iow_indent_expandable:n - #4 -%<*initex> - \tl_set:Nx \l_iow_wrap_tl {#1} -%</initex> -%<*package> - \protected@edef \l_iow_wrap_tl {#1} -%</package> - \cs_set:Npn \\ { \iow_newline: #2 } - \use:x - { - \iow_wrap_loop:w - \tl_to_str:N \l_iow_wrap_tl - \tl_to_str:N \c_iow_wrap_end_marker_tl - \c_space_tl \c_space_tl - \exp_not:N \q_stop - } - \exp_args:NNo \group_end: - #5 \l_iow_wrapped_tl - } -% \end{macrocode} -% \end{macro} -% -% \begin{macro}[aux]{\iow_wrap_loop:w} -% The loop grabs one word in the input, and checks whether it is -% the special marker, or a normal word. -% \begin{macrocode} -\cs_new_protected:Npn \iow_wrap_loop:w #1 ~ % - { - \tl_set:Nn \l_iow_current_word_tl {#1} - \tl_if_eq:NNTF \l_iow_current_word_tl \c_iow_wrap_marker_tl - { \iow_wrap_special:w } - { \iow_wrap_word: } - } -% \end{macrocode} -% \end{macro} -% -% \begin{macro}[aux]{\iow_wrap_word:} -% \begin{macro}[aux]{\iow_wrap_word_fits:} -% \begin{macro}[aux]{\iow_wrap_word_newline:} -% For a normal word, update the line length, then test if the current -% word would fit in the current line, and call the appropriate function. -% If the word fits in the current line, add it to the line, preceded by -% a space unless it is the first word of the line. -% Otherwise, the current line is added to the result, with the run-on text. -% The current word (and its length) are then put in the new line. -% \begin{macrocode} -\cs_new_protected_nopar:Npn \iow_wrap_word: - { - \int_set:Nn \l_iow_current_word_int - { \str_length_skip_spaces:N \l_iow_current_word_tl } - \int_add:Nn \l_iow_current_line_int { \l_iow_current_word_int } - \int_compare:nNnTF \l_iow_current_line_int < \l_iow_target_length_int - { \iow_wrap_word_fits: } - { \iow_wrap_word_newline: } - \iow_wrap_loop:w - } -\cs_new_protected_nopar:Npn \iow_wrap_word_fits: - { - \bool_if:NTF \l_iow_line_start_bool - { - \bool_set_false:N \l_iow_line_start_bool - \tl_put_right:Nx \l_iow_current_line_tl - { \l_iow_current_indentation_tl \l_iow_current_word_tl } - \int_add:Nn \l_iow_current_line_int - { \l_iow_current_indentation_int } - } - { - \tl_put_right:Nx \l_iow_current_line_tl - { ~ \l_iow_current_word_tl } - \int_incr:N \l_iow_current_line_int - } - } -\cs_new_protected_nopar:Npn \iow_wrap_word_newline: - { - \tl_put_right:Nx \l_iow_wrapped_tl - { \l_iow_current_line_tl \\ } - \int_set:Nn \l_iow_current_line_int - { - \l_iow_current_word_int - + \l_iow_current_indentation_int - } - \tl_set:Nx \l_iow_current_line_tl - { \l_iow_current_indentation_tl \l_iow_current_word_tl } - } -% \end{macrocode} -% \end{macro} -% \end{macro} -% \end{macro} -% -% \begin{macro}[aux]{\iow_wrap_special:w} -% \begin{macro}[aux]{\iow_wrap_newline:w} -% \begin{macro}[aux]{\iow_wrap_indent:w} -% \begin{macro}[aux]{\iow_wrap_unindent:w} -% \begin{macro}[aux]{\iow_wrap_end:w} -% When the \enquote{special} marker is encountered, -% read what operation to perform, as a space-delimited -% argument, perform it, and remember to loop. -% In fact, to avoid spurious spaces when two special -% actions follow each other, we look ahead for another -% copy of the marker. -% Forced newlines are almost identical to those caused by overflow, -% except that here the word is empty. -% To indent more, add four spaces to the start of the indentation -% token list. To reduce indentation, rebuild the indentation token -% list using \cs{prg_replicate:nn}. -% At the end, we simply save the last line (without the run-on text), -% and prevent the loop. -% \begin{macrocode} -\cs_new_protected:Npn \iow_wrap_special:w #1 ~ #2 ~ #3 ~ % - { - \use:c { iow_wrap_#1: } - \str_if_eq:xxTF { #2~#3 } { ~ \c_iow_wrap_marker_tl } - { \iow_wrap_special:w } - { \iow_wrap_loop:w #2 ~ #3 ~ } - } -\cs_new_protected_nopar:Npn \iow_wrap_newline: - { - \tl_put_right:Nx \l_iow_wrapped_tl - { \l_iow_current_line_tl \\ } - \int_zero:N \l_iow_current_line_int - \tl_clear:N \l_iow_current_line_tl - \bool_set_true:N \l_iow_line_start_bool - } -\cs_new_protected_nopar:Npx \iow_wrap_indent: - { - \int_add:Nn \l_iow_current_indentation_int \c_four - \tl_put_right:Nx \exp_not:N \l_iow_current_indentation_tl - { \c_space_tl \c_space_tl \c_space_tl \c_space_tl } - } -\cs_new_protected_nopar:Npn \iow_wrap_unindent: - { - \int_sub:Nn \l_iow_current_indentation_int \c_four - \tl_set:Nx \l_iow_current_indentation_tl - { \prg_replicate:nn \l_iow_current_indentation_int { ~ } } - } -\cs_new_protected_nopar:Npn \iow_wrap_end: - { - \tl_put_right:Nx \l_iow_wrapped_tl - { \l_iow_current_line_tl } - \use_none_delimit_by_q_stop:w - } -% \end{macrocode} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% -% \begin{macro}[aux]{\str_length_skip_spaces:N} -% \begin{macro}[aux]{\str_length_skip_spaces:n} -% \begin{macro}[aux]{\str_length_loop:NNNNNNNNN} -% The wrapping code requires to measure the number of character -% in each word. This could be done with \cs{tl_length:n}, but -% it is ten times faster (literally) to use the code below. -% \begin{macrocode} -\cs_new_nopar:Npn \str_length_skip_spaces:N - { \exp_args:No \str_length_skip_spaces:n } -\cs_new:Npn \str_length_skip_spaces:n #1 - { - \int_value:w \int_eval:w - \exp_after:wN \str_length_loop:NNNNNNNNN \tl_to_str:n {#1} - {X8}{X7}{X6}{X5}{X4}{X3}{X2}{X1}{X0} \q_stop - \int_eval_end: - } -\cs_new:Npn \str_length_loop:NNNNNNNNN #1#2#3#4#5#6#7#8#9 - { - \if_catcode:w X #9 - \exp_after:wN \use_none_delimit_by_q_stop:w - \else: - 9 + - \exp_after:wN \str_length_loop:NNNNNNNNN - \fi: - } -% \end{macrocode} -% \end{macro} -% \end{macro} -% \end{macro} -% -% \subsection{Reading input} -% -% \begin{macro}[pTF]{\ior_if_eof_p:N} -% To test if some particular input stream is exhausted the following -% conditional is provided. As the pool model means that closed -% streams are undefined control sequences, the test has two parts. -% \begin{macrocode} -\prg_new_conditional:Nnn \ior_if_eof:N { p , T , F , TF } - { - \cs_if_exist:NTF #1 - { - \if_int_compare:w #1 = \c_sixteen - \prg_return_true: - \else: - \if_eof:w #1 - \prg_return_true: - \else: - \prg_return_false: - \fi: - \fi: - } - { \prg_return_true: } - } -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\ior_to:NN} -% \begin{macro}{\ior_gto:NN} -% And here we read from files. -% \begin{macrocode} -\cs_new_protected:Npn \ior_to:NN #1#2 - { \tex_read:D #1 to #2 } -\cs_new_protected:Npn \ior_gto:NN #1#2 - { \tex_global:D \tex_read:D #1 to #2 } -% \end{macrocode} -% \end{macro} -% \end{macro} -% -% \begin{macro}{\ior_str_to:NN} -% \begin{macro}{\ior_str_gto:NN} -% Reading as strings is also a primitive wrapper. -% \begin{macrocode} -\cs_new_protected:Npn \ior_str_to:NN #1#2 - { \etex_readline:D #1 to #2 } -\cs_new_protected:Npn \ior_str_gto:NN #1#2 - { \tex_global:D \etex_readline:D #1 to #2 } -% \end{macrocode} -% \end{macro} -% \end{macro} -% -% \subsection{Experimental functions} -% -% \begin{macro}{\ior_map_inline:nn} -% \begin{macro}{\ior_str_map_inline:nn} -% \begin{macro}[aux]{\ior_str_map_inline_aux:Nnn} -% \begin{macro}[aux]{\ior_str_map_inline_aux:NNNnn} -% \begin{macro}[aux]{\ior_str_map_inline_loop:NNN} -% \begin{variable}{\l_ior_internal_tl} -% The five arguments of \cs{ior_str_map_inline_aux:NNNnn} are: -% the read stream used at this level of map nesting; -% the control sequence which will hold the function to map; -% either \cs{ior_to:NN} or \cs{ior_str_to:NN}; the file name; -% and finally the inline function. We make sure to decrease -% \cs{g_prg_map_int} and close the file after the mapping, -% even if the mapping exits prematurely because of a -% \cs{prg_map_break:} instruction. The \cs{ior_if_eof:nF} -% tests are a little bit tricky to get right: if the file -% does not exist, we should do nothing, hence the preliminary -% test. Then the end-of-file test must be done after reading -% each line. -% \begin{macrocode} -\cs_new_protected_nopar:Npn \ior_map_inline:nn - { \ior_map_inline_aux:Nnn \ior_to:NN } -\cs_new_protected_nopar:Npn \ior_str_map_inline:nn - { \ior_map_inline_aux:Nnn \ior_str_to:NN } -\cs_new_protected_nopar:Npn \ior_map_inline_aux:Nnn - { - \exp_args:Ncc \ior_map_inline_aux:NNNnn - { g_ior_map_ \int_use:N \g_prg_map_int _ior } - { ior_map_ \int_use:N \g_prg_map_int :n } - } -\cs_new_protected:Npn \ior_map_inline_aux:NNNnn #1#2#3#4#5 - { - \cs_if_exist:NF #1 { \ior_new:N #1 } - \cs_set:Npn #2 ##1 {#5} - \ior_open:Nn #1 {#4} - \int_gincr:N \g_prg_map_int - \ior_if_eof:NF #1 { \ior_map_inline_loop:NNN #1#2#3 } - \prg_break_point:n - { - \int_gdecr:N \g_prg_map_int - \ior_close:N #1 - } - } -\cs_new_protected:Npn \ior_map_inline_loop:NNN #1#2#3 - { - #3 #1 \l_ior_internal_tl - \ior_if_eof:NF #1 - { - \exp_args:No #2 \l_ior_internal_tl - \ior_map_inline_loop:NNN #1#2#3 - } - } -% \end{macrocode} -% \end{variable} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% -% \subsection{Messages} -% -% \begin{macrocode} -\msg_kernel_new:nnnn { io } { space-in-file-name } - { Space~in~file~name~'#1'. } - { - Spaces~are~not~permitted~in~files~loaded~by~LaTeX: \\ - Further~errors~may~follow! - } -% \end{macrocode} -% -% \subsection{Deprecated functions} -% -% Deprecated on 2011-05-27, for removal by 2011-08-31. -% -% \begin{macro}{\iow_now_buffer_safe:Nn, \iow_now_buffer_safe:Nx} -% This is much more easily done using the wrapping system: there is -% an expansion there, so a bit of a hack is needed. -% \begin{macrocode} -%<*deprecated> -\cs_new_protected:Npn \iow_now_buffer_safe:Nn #1#2 - { \iow_wrap:xnnnN { \exp_not:n {#2} } { } \c_zero { } \iow_now:Nn #1 } -\cs_new_protected:Npn \iow_now_buffer_safe:Nx #1#2 - { \iow_wrap:xnnnN {#2} { } \c_zero { } \iow_now:Nn #1 } -%</deprecated> -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\ior_open_streams:} -% \begin{macro}{\iow_open_streams:} -% Slightly misleading names. -% \begin{macrocode} -%<*deprecated> -\cs_new_eq:NN \ior_open_streams: \ior_list_streams: -\cs_new_eq:NN \iow_open_streams: \iow_list_streams: -%</deprecated> -% \end{macrocode} -% \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 15e6c362d75..212c953b2aa 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 3158 2012-01-09 00:47:42Z bruno $ +\GetIdInfo$Id: l3luatex.dtx 3355 2012-02-09 07:18:22Z joseph $ {L3 Experimental LuaTeX-specific functions} %</driver|package> %<*driver> @@ -314,7 +314,7 @@ \tex_global:D \tex_chardef:D #1 \g_cctab_allocate_int \luatex_initcatcodetable:D #1 } - { \msg_kernel_fatal:nnx { alloc } { out-of-registers } { cctab } } + { \msg_kernel_fatal:nnx { kernel } { out-of-registers } { cctab } } } \luatex_if_engine:F { diff --git a/Master/texmf-dist/source/latex/l3kernel/l3msg.dtx b/Master/texmf-dist/source/latex/l3kernel/l3msg.dtx index e0cb6029a79..472196ac62a 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3msg.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3msg.dtx @@ -35,7 +35,7 @@ % %<*driver|package> \RequirePackage{l3names} -\GetIdInfo$Id: l3msg.dtx 3316 2012-02-06 12:24:43Z bruno $ +\GetIdInfo$Id: l3msg.dtx 3470 2012-02-26 19:10:24Z bruno $ {L3 Experimental messages} %</driver|package> %<*driver> @@ -431,9 +431,9 @@ % from sources other than \meta{module} are not affected by this % redirection. This function can be used to make some messages % \enquote{silent} by default. For example, all of the -% \texttt{trace} messages of \meta{module} could be turned off with: +% \texttt{warning} messages of \meta{module} could be turned off with: % \begin{verbatim} -% \msg_redirect_module:nnn { module } { trace } { none } +% \msg_redirect_module:nnn { module } { warning } { none } % \end{verbatim} % \end{function} % @@ -677,7 +677,7 @@ % % \begin{function}{\msg_aux_use:nn, \msg_aux_use:nnxxxx} % \begin{syntax} -% \cs{msg_aux_use:nnxx} \Arg{module} \Arg{message} +% \cs{msg_aux_use:nnxxxx} \Arg{module} \Arg{message} % ~~\Arg{arg one} \Arg{arg two} \Arg{arg three} \Arg{arg four} % \end{syntax} % Prints the \meta{message} from \meta{module} in the terminal, @@ -688,9 +688,10 @@ % \begin{syntax} % \cs{msg_aux_show:x} \Arg{formatted string} % \end{syntax} -% Shows the \meta{formatted string} on the terminal. -% The \meta{formatted string} must start with |^^J>|, -% failure to do so causes low-level \TeX{} errors. +% Shows the \meta{formatted string} on the terminal. After expansion, +% unless it is empty, the \meta{formatted string} must contain |>|, +% and the part of \meta{formatted string} before the first |>| is +% removed. Failure to do so causes low-level \TeX{} errors. % \end{function} % % \begin{function}{\msg_aux_show:Nnx} @@ -740,6 +741,37 @@ % \end{macrocode} % \end{variable} % +% \begin{macro}[aux]{\chk_if_free_msg:nn} +% This auxiliary is similar to \cs{chk_if_free_cs:N}, and is used when +% defining messages with \cs{msg_new:nnnn}. It could be inlined in +% \cs{msg_new:nnnn}, but the experimental \pkg{l3trace} module needs +% to disable this check when reloading a package with the extra +% tracing information. +% \begin{macrocode} +\cs_new_protected:Npn \chk_if_free_msg:nn #1#2 + { + \cs_if_free:cF { \c_msg_text_prefix_tl #1 / #2 } + { + \msg_kernel_error:nnxx { msg } { message-already-defined } + {#1} {#2} + } + } +%<*package> +\tex_ifodd:D \l@expl@log@functions@bool + \cs_gset_protected:Npn \chk_if_free_msg:nn #1#2 + { + \cs_if_free:cF { \c_msg_text_prefix_tl #1 / #2 } + { + \msg_kernel_error:nnxx { msg } { message-already-defined } + {#1} {#2} + } + \iow_log:x { Defining~message~#1/#2~ \msg_line_context: } + } +\fi: +%</package> +% \end{macrocode} +% \end{macro} +% % \begin{macro}{\msg_new:nnnn, \msg_new:nnn} % \begin{macro}{\msg_gset:nnnn,\msg_gset:nnn} % \begin{macro}{\msg_set:nnnn, \msg_set:nnn} @@ -748,11 +780,7 @@ % \begin{macrocode} \cs_new_protected:Npn \msg_new:nnnn #1#2 { - \cs_if_exist:cT { \c_msg_text_prefix_tl #1 / #2 } - { - \msg_kernel_error:nnxx { msg } { message-already-defined } - {#1} {#2} - } + \chk_if_free_msg:nn {#1} {#2} \msg_gset:nnnn {#1} {#2} } \cs_new_protected:Npn \msg_new:nnn #1#2#3 @@ -1614,6 +1642,13 @@ LaTeX~has~been~asked~to~use~a~command~#1,~but~this~has~not~ been~defined~yet. } +\msg_kernel_new:nnnn { kernel } { out-of-registers } + { No~room~for~a~new~#1. } + { + TeX~only~supports~\int_use:N \c_max_register_int \ + of~each~type.~All~the~#1~registers~have~been~used.~ + This~run~will~be~aborted~now. + } \msg_kernel_new:nnnn { kernel } { variable-not-defined } { Variable~#1~undefined. } { diff --git a/Master/texmf-dist/source/latex/l3kernel/l3prg.dtx b/Master/texmf-dist/source/latex/l3kernel/l3prg.dtx index 194181b4c87..9b3ad6dae1c 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 3338 2012-02-08 08:21:42Z joseph $ +\GetIdInfo$Id: l3prg.dtx 3464 2012-02-26 15:30:29Z bruno $ {L3 Experimental control structures} %</driver|package> %<*driver> @@ -289,6 +289,21 @@ % based on this result. % \end{function} % +% \begin{function}[added = 2012-02-09]{\bool_show:N, \bool_show:c} +% \begin{syntax} +% \cs{bool_show:N} \meta{boolean} +% \end{syntax} +% Displays the logical truth of the \meta{boolean} on the terminal. +% \end{function} +% +% \begin{function}[added = 2012-02-09]{\bool_show:n} +% \begin{syntax} +% \cs{bool_show:n} \Arg{boolean expression} +% \end{syntax} +% Displays the logical truth of the \meta{boolean expression} on the +% terminal. +% \end{function} +% % \begin{variable}{\l_tmpa_bool} % A scratch boolean for local assignment. It is never used by % the kernel code, and so is safe for use with any \LaTeX3-defined @@ -373,7 +388,7 @@ % % \begin{function}[EXP]{\bool_xor_p:nn} % \begin{syntax} -% \cs{bool_xor_p:nn} \Arg{boolexpr1} \Arg{boolexpr1} +% \cs{bool_xor_p:nn} \Arg{boolexpr_1} \Arg{boolexpr_1} % \end{syntax} % Implements an \enquote{exclusive or} operation between two boolean % expressions. There is no infix operation for this logical @@ -442,7 +457,7 @@ % ~~~~\Arg{intexpr case1} \Arg{code case1} \\ % ~~~~\Arg{intexpr case2} \Arg{code case2} \\ % ~~~~\ldots \\ -% ~~~~\Arg{intexpr case$_n$} \Arg{code case$_n$} \\ +% ~~~~\Arg{intexpr case$\sb{n}$} \Arg{code case$\sb{n}$} \\ % ~~|}| \\ % ~~\Arg{else case} % \end{syntax} @@ -474,7 +489,7 @@ % ~~~~\Arg{dimexpr case1} \Arg{code case1} \\ % ~~~~\Arg{dimexpr case2} \Arg{code case2} \\ % ~~~~\ldots \\ -% ~~~~\Arg{dimexpr case$_n$} \Arg{code case$_n$} \\ +% ~~~~\Arg{dimexpr case$\sb{n}$} \Arg{code case$\sb{n}$} \\ % ~~|}| \\ % ~~\Arg{else case} % \end{syntax} @@ -494,7 +509,7 @@ % ~~~~\Arg{string case1} \Arg{code case1} \\ % ~~~~\Arg{string case2} \Arg{code case2} \\ % ~~~~\ldots \\ -% ~~~~\Arg{string case$_n$} \Arg{code case$_n$} \\ +% ~~~~\Arg{string case$\sb{n}$} \Arg{code case$\sb{n}$} \\ % ~~|}| \\ % ~~\Arg{else case} % \end{syntax} @@ -520,7 +535,7 @@ % ~~~~\meta{token list variable case1} \Arg{code case1} \\ % ~~~~\meta{token list variable case2} \Arg{code case2} \\ % ~~~~\ldots \\ -% ~~~~\meta{token list variable case$_n$} \Arg{code case$_n$} \\ +% ~~~~\meta{token list variable case$\sb{n}$} \Arg{code case$\sb{n}$} \\ % ~~"}" \\ % ~~\Arg{else case} % \end{syntax} @@ -881,6 +896,30 @@ % \end{macro} % \end{macro} % +% \begin{macro}{\bool_show:N, \bool_show:c, \bool_show:n} +% Show the truth value of the boolean, as \texttt{true} or +% \texttt{false}. We use \cs{msg_aux_show:x} to get a better output; +% this function requires its argument to start with |>|. +% \begin{macrocode} +\cs_new_protected:Npn \bool_show:N #1 + { + \cs_if_exist:NTF #1 + { \bool_show:n {#1} } + { + \msg_kernel_error:nnx { kernel } { variable-not-defined } + { \token_to_str:N #1 } + } + } +\cs_new_protected:Npn \bool_show:n #1 + { + \bool_if:nTF {#1} + { \msg_aux_show:x { > true } } + { \msg_aux_show:x { > false } } + } +\cs_generate_variant:Nn \bool_show:N { c } +% \end{macrocode} +% \end{macro} +% % \begin{variable}{\l_tmpa_bool, \g_tmpa_bool} % A few booleans just if you need them. % \begin{macrocode} @@ -1845,7 +1884,7 @@ % \end{macro} % % \subsection{Deprecated functions} -% +% % These were deprecated on 2012-02-08, and will be removed entirely by % 2012-05-31. % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3prop.dtx b/Master/texmf-dist/source/latex/l3kernel/l3prop.dtx index ac7dc25183d..177d467a0b7 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 3158 2012-01-09 00:47:42Z bruno $ +\GetIdInfo$Id: l3prop.dtx 3460 2012-02-26 12:16:41Z will $ {L3 Experimental property lists} %</driver|package> %<*driver> @@ -593,7 +593,7 @@ % is simply \cs{q_prop}, and \cs{prop_split_aux:nnnn} will gobble this % and the false branch (|#4|), leaving the correct code on the input % stream. More precisely, it leaves the user code (true branch), followed -% by three groups, \Arg{extract1} \Arg{value} \Arg{extract2}. +% by three groups, \Arg{extract_1} \Arg{value} \Arg{extract_2}. % In order for \meta{extract1}\meta{extract2} to be a well-formed % property list, \meta{extract1} has a leading and trailing \cs{q_prop}, % retaining exactly the structure of a property list, while \meta{extract2} @@ -625,8 +625,8 @@ % \begin{macro}[int]{\prop_split:Nnn} % The goal here is to provide a common interface for both true and false % branches of \cs{prop_split:NnTF}. In both cases, the code given by the -% user will be placed in front of three brace groups, \Arg{extract1} -% \Arg{value} \Arg{extract2}. +% user will be placed in front of three brace groups, \Arg{extract_1} +% \Arg{value} \Arg{extract_2}. % If the key was missing from the property list, then \meta{extract1} % is the full property list, \meta{value} is \cs{q_no_value}, and % \meta{extract2} is empty. diff --git a/Master/texmf-dist/source/latex/l3kernel/l3quark.dtx b/Master/texmf-dist/source/latex/l3kernel/l3quark.dtx index a87d1065c61..3cb65a59b33 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 3148 2012-01-08 15:42:18Z bruno $ +\GetIdInfo$Id: l3quark.dtx 3384 2012-02-12 13:13:11Z will $ {L3 Experimental quarks} %</driver|package> %<*driver> @@ -67,29 +67,62 @@ % % \begin{documentation} % +% \section{Introduction to quarks and scan marks} +% % Two special types of constants in \LaTeX3 are \enquote{quarks} and % \enquote{scan marks}. By convention all constants of type quark % start out with |\q_|, and scan marks start with |\s_|. -% % \emph{Scan marks are an experimental feature.} % +% \subsection{Quarks} +% % Quarks are control sequences that expand to themselves and should % therefore \emph{never} be executed directly in the code. % This would result in an endless loop! % -% They are meant to be used as delimiter in weird functions (for -% example as the stop token (\emph{i.e.}~\cs{q_stop}). They also permit the -% following ingenious trick: when you pick up a token in a temporary, +% They are meant to be used as delimiter in weird functions, with the most +% command use case as the `stop token' (\emph{i.e.}~\cs{q_stop}). +% For example, when writing a macro to parse a user-defined date +% \begin{verbatim} +% \date_parse:n {19/June/1981} +% \end{verbatim} +% one might write a command such as +% \begin{verbatim} +% \cs_new:Npn \date_parse:n #1 { \date_parse_aux:w #1 \q_stop } +% \cs_new:Npn \date_parse_aux:w #1 / #2 / #3 \q_stop +% { <do something with the date> } +% \end{verbatim} +% +% Quarks are sometimes also used as error return values for functions +% that receive erroneous input. +% For example, in the function \cs{prop_get:NnN} to retrieve a value stored +% in some key of a property list, if the key does not exist then the return value +% is the quark \cs{q_no_value}. +% As mentioned above, such quarks are extremely fragile and it is imperative +% when using such functions that code is carefully written to check for +% pathological cases to avoid leakage of a quark into an uncontrolled +% environment. +% +% Quarks also permit the +% following ingenious trick when parsing tokens: +% when you pick up a token in a temporary variable % and you want to know whether you have picked up a particular quark, -% all you have to do is compare the temporary to the quark using -% \cs{if_meaning:w}. A set of special quark testing functions is set up +% all you have to do is compare the temporary variable to the quark using +% \cs{tl_if_eq:NNTF}. A set of special quark testing functions is set up % below. All the quark testing functions are expandable although the % ones testing only single tokens are much faster. +% An example of the quark testing functions and their use in recursion +% can be seen in the implementation of \cs{clist_map_function:NN}. +% +% +% \subsection{Scan marks} % % Scan marks are control sequences set equal to \cs{scan_stop:}, -% hence will never expand. +% hence will never expand in an expansion context and will be (largely) +% invisible if they are encountered in a typesetting context. % -% Like quarks, they can be used as delimiters in weird functions. +% Like quarks, they can be used as delimiters in weird functions +% and are often safer to use for this purpose. % Since they are harmless when executed by \TeX{} in non-expandable % contexts, they can be used to mark the end of a set of instructions. % This allows to skip to that point if the end of the instructions @@ -182,10 +215,12 @@ % terminating loops as when one is doing tail recursion. The building % blocks follow below. % -% \begin{variable}{\q_recursion_tail} +% \begin{variable}{/q_recursion_tail} % This quark is appended to the data structure in question and % appears as a real element there. This means it gets any list % separators around it. +% Can you guess why the documentation for this quark requires us +% to write the control sequence with the wrong slash before it? % \end{variable} % % \begin{variable}{\q_recursion_stop} @@ -274,9 +309,9 @@ % \end{variable} % % \begin{function}{\use_none_delimit_by_s_stop:w} -% \begin{variable} +% \begin{syntax} % \cs{use_none_delimit_by_s_stop:w} \meta{tokens} \cs{s_stop} -% \end{variable} +% \end{syntax} % Removes the \meta{tokens} and \cs{s_stop} from the input stream. % This leads to a low-level \TeX{} error if \cs{s_stop} is absent. % \end{function} diff --git a/Master/texmf-dist/source/latex/l3kernel/l3skip.dtx b/Master/texmf-dist/source/latex/l3kernel/l3skip.dtx index 02cc54e90d3..1110130bc13 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3skip.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3skip.dtx @@ -36,7 +36,7 @@ % %<*driver|package> \RequirePackage{l3names} -\GetIdInfo$Id: l3skip.dtx 3313 2012-02-06 11:15:21Z bruno $ +\GetIdInfo$Id: l3skip.dtx 3460 2012-02-26 12:16:41Z will $ {L3 Experimental dimensions and skips} %</driver|package> %<*driver> @@ -179,7 +179,7 @@ % % \begin{function}[updated = 2011-10-22, EXP]{\dim_ratio:nn} % \begin{syntax} -% \cs{dim_ratio:nn} \Arg{dimexpr1} \Arg{dimexpr2} +% \cs{dim_ratio:nn} \Arg{dimexpr_1} \Arg{dimexpr_2} % \end{syntax} % Parses the two \meta{dimension expressions} and converts the ratio of % the two to a form suitable for use inside a \meta{dimension expression}. @@ -202,9 +202,9 @@ % % \begin{function}[EXP,pTF]{\dim_compare:nNn} % \begin{syntax} -% \cs{dim_compare_p:nNn} \Arg{dimexpr1} \meta{relation} \Arg{dimexpr2} \\ +% \cs{dim_compare_p:nNn} \Arg{dimexpr_1} \meta{relation} \Arg{dimexpr_2} \\ % \cs{dim_compare:nNnTF} -% ~~\Arg{dimexpr1} \meta{relation} \Arg{dimexpr2} +% ~~\Arg{dimexpr_1} \meta{relation} \Arg{dimexpr_2} % ~~\Arg{true code} \Arg{false code} % \end{syntax} % This function first evaluates each of the \meta{dimension expressions} @@ -245,7 +245,7 @@ % % \begin{function}[rEXP]{\dim_do_while:nNnn} % \begin{syntax} -% \cs{dim_do_while:nNnn} \Arg{dimexpr1} \meta{relation} \Arg{dimexpr2} \Arg{code} +% \cs{dim_do_while:nNnn} \Arg{dimexpr_1} \meta{relation} \Arg{dimexpr_2} \Arg{code} % \end{syntax} % Evaluates the relationship between the two \meta{dimension expressions} % as described for \cs{dim_compare:nNnTF}, and then places the @@ -257,7 +257,7 @@ % % \begin{function}[rEXP]{\dim_do_until:nNnn} % \begin{syntax} -% \cs{dim_do_until:nNnn} \Arg{dimexpr1} \meta{relation} \Arg{dimexpr2} \Arg{code} +% \cs{dim_do_until:nNnn} \Arg{dimexpr_1} \meta{relation} \Arg{dimexpr_2} \Arg{code} % \end{syntax} % Evaluates the relationship between the two \meta{dimension expressions} % as described for \cs{dim_compare:nNnTF}, and then places the @@ -269,7 +269,7 @@ % % \begin{function}[rEXP]{\dim_until_do:nNnn} % \begin{syntax} -% \cs{dim_until_do:nNnn} \Arg{dimexpr1} \meta{relation} \Arg{dimexpr2} \Arg{code} +% \cs{dim_until_do:nNnn} \Arg{dimexpr_1} \meta{relation} \Arg{dimexpr_2} \Arg{code} % \end{syntax} % Places the \meta{code} in the input stream for \TeX{} to process, and % then evaluates the relationship between the two @@ -281,7 +281,7 @@ % % \begin{function}[rEXP]{\dim_while_do:nNnn} % \begin{syntax} -% \cs{dim_while_do:nNnn} \Arg{dimexpr1} \meta{relation} \Arg{dimexpr2} \Arg{code} +% \cs{dim_while_do:nNnn} \Arg{dimexpr_1} \meta{relation} \Arg{dimexpr_2} \Arg{code} % \end{syntax} % Places the \meta{code} in the input stream for \TeX{} to process, and % then evaluates the relationship between the two @@ -488,7 +488,7 @@ % % \begin{function}[EXP,pTF]{\skip_if_eq:nn} % \begin{syntax} -% \cs{skip_if_eq_p:nn} \Arg{skipexpr1} \Arg{skipexpr2} +% \cs{skip_if_eq_p:nn} \Arg{skipexpr_1} \Arg{skipexpr_2} % \cs{dim_compare:nTF} % ~~\Arg{skip expr1} \Arg{skip expr2} % ~~\Arg{true code} \Arg{false code} diff --git a/Master/texmf-dist/source/latex/l3kernel/l3tl.dtx b/Master/texmf-dist/source/latex/l3kernel/l3tl.dtx index f0279ff6bfc..9fa0a297d51 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 3316 2012-02-06 12:24:43Z bruno $ +\GetIdInfo$Id: l3tl.dtx 3460 2012-02-26 12:16:41Z will $ {L3 Experimental token lists} %</driver|package> %<*driver> @@ -637,8 +637,8 @@ % \cs{tl_reverse_items:n} \Arg{token list} % \end{syntax} % Reverses the order of the \meta{items} stored in \meta{tl~var}, -% so that \Arg{item1}\Arg{item2}\Arg{item3} \ldots \Arg{item$_n$} -% becomes \Arg{item$_n$} \ldots{} \Arg{item3}\Arg{item2}\Arg{item1}. +% so that \Arg{item_1}\Arg{item_2}\Arg{item_3} \ldots \Arg{item$_n$} +% becomes \Arg{item$_n$} \ldots{} \Arg{item_3}\Arg{item_2}\Arg{item_1}. % This process will remove any unprotected space within the % \meta{token list}. Braced token groups are copied without % reversing the order of tokens, and keep the outer set of braces. @@ -686,8 +686,8 @@ % Functions which deal with either only the very first token of a % token list or everything except the first token. % -% \begin{function}[updated = 2012-01-08, EXP] -% {\tl_head:n, \tl_head:V, \tl_head:v, \tl_head:f} +% \begin{function}[updated = 2012-02-08, EXP] +% {\tl_head:N, \tl_head:n, \tl_head:V, \tl_head:v, \tl_head:f} % \begin{syntax} % \cs{tl_head:n} \Arg{tokens} % \end{syntax} @@ -727,8 +727,8 @@ % is not critical. % \end{function} % -% \begin{function}[updated = 2012-01-08, EXP] -% {\tl_tail:n, \tl_tail:V, \tl_tail:v, \tl_tail:f} +% \begin{function}[updated = 2012-02-08, EXP] +% {\tl_tail:N, \tl_tail:n, \tl_tail:V, \tl_tail:v, \tl_tail:f} % \begin{syntax} % \cs{tl_tail:n} \Arg{tokens} % \end{syntax} @@ -1016,17 +1016,6 @@ % \cs{tl_act_...} functions. % \end{variable} % -% \begin{function}[added = 2012-01-25]{\tl_to_str_active_safe:Nx} -% \begin{syntax} -% \cs{tl_to_str_active_safe:Nx} \meta{tl var} \Arg{tokens} -% \end{syntax} -% Exhaustively-expands the \meta{tokens} with the exception of any -% category \meta{active} (catcode~$12$) tokens, which are not expanded. The -% resulting \meta{expanded tokens} are then converted to a string as -% described for \cs{tl_to_str:n}. The list of \meta{active} tokens is taken -% from \cs{l_char_active_seq}. -% \end{function} -% % \end{documentation} % % \begin{implementation} @@ -1943,9 +1932,9 @@ % % \subsection{The first token from a token list} % -% \begin{macro}{\tl_head:n, \tl_head:V, \tl_head:v, \tl_head:f} +% \begin{macro}{\tl_head:N, \tl_head:n, \tl_head:V, \tl_head:v, \tl_head:f} % \begin{macro}{\tl_head:w} -% \begin{macro}{\tl_tail:n, \tl_tail:V, \tl_tail:v, \tl_tail:f} +% \begin{macro}{\tl_tail:N, \tl_tail:n, \tl_tail:V, \tl_tail:v, \tl_tail:f} % \begin{macro}{\tl_tail:w} % These functions pick up either the head or the tail of a list. The % empty brace groups in \cs{tl_head:n} and \cs{tl_tail:n} ensure that @@ -1959,7 +1948,9 @@ \cs_new:Npn \tl_tail:n #1 { \etex_unexpanded:D \tl_tail_aux:w #1 \q_mark { } \q_mark \q_stop } \cs_new:Npn \tl_tail_aux:w #1 #2 \q_mark #3 \q_stop { {#2} } +\cs_new_nopar:Npn \tl_head:N { \exp_args:No \tl_head:n } \cs_generate_variant:Nn \tl_head:n { V , v , f } +\cs_new_nopar:Npn \tl_tail:N { \exp_args:No \tl_tail:n } \cs_generate_variant:Nn \tl_tail:n { V , v , f } % \end{macrocode} % \end{macro} @@ -2193,27 +2184,6 @@ % \end{macro} % \end{macro} % -% \subsection{Specialist functions for kernel use} -% -% \begin{macro}[int]{\tl_to_str_active_safe:Nx} -% For converting a token list to a string where active characters are treated -% as strings from the start. This is needed by the file-loading modules. -% \begin{macrocode} -\cs_new_protected:Npn \tl_to_str_active_safe:Nx #1#2 - { - \group_begin: - \seq_map_inline:Nn \l_char_active_seq - { \cs_set_nopar:Npx ##1 { \token_to_str:N ##1 } } - \use:x - { - \group_end: - \tl_set:Nn \exp_not:N #1 {#2} - } - \tl_set:Nx #1 { \tl_to_str:N #1 } - } -% \end{macrocode} -%\end{macro} -% % \subsection{Viewing token lists} % % \begin{macro}{\tl_show:N, \tl_show:c} diff --git a/Master/texmf-dist/source/latex/l3kernel/l3token.dtx b/Master/texmf-dist/source/latex/l3kernel/l3token.dtx index 3c5ba351913..151901bd2dd 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 3316 2012-02-06 12:24:43Z bruno $ +\GetIdInfo$Id: l3token.dtx 3460 2012-02-26 12:16:41Z will $ {L3 Experimental token manipulation} %</driver|package> %<*driver> @@ -172,7 +172,7 @@ % % \begin{function}{\char_set_catcode:nn} % \begin{syntax} -% \cs{char_set_catcode:nn} \Arg{intexpr1} \Arg{intexpr2} +% \cs{char_set_catcode:nn} \Arg{intexpr_1} \Arg{intexpr_2} % \end{syntax} % These functions set the category code of the \meta{character} which % has character code as given by the \meta{integer expression}. @@ -203,7 +203,7 @@ % % \begin{function}{\char_set_lccode:nn} % \begin{syntax} -% \cs{char_set_lcode:nn} \Arg{intexpr1} \Arg{intexpr2} +% \cs{char_set_lcode:nn} \Arg{intexpr_1} \Arg{intexpr_2} % \end{syntax} % This function set up the behaviour of \meta{character} when % found inside \cs{tl_to_lowercase:n}, such that \meta{character1} @@ -240,7 +240,7 @@ % % \begin{function}{\char_set_uccode:nn} % \begin{syntax} -% \cs{char_set_uccode:nn} \Arg{intexpr1} \Arg{intexpr2} +% \cs{char_set_uccode:nn} \Arg{intexpr_1} \Arg{intexpr_2} % \end{syntax} % This function set up the behaviour of \meta{character} when % found inside \cs{tl_to_uppercase:n}, such that \meta{character1} @@ -277,7 +277,7 @@ % % \begin{function}{\char_set_mathcode:nn} % \begin{syntax} -% \cs{char_set_mathcode:nn} \Arg{intexpr1} \Arg{intexpr2} +% \cs{char_set_mathcode:nn} \Arg{intexpr_1} \Arg{intexpr_2} % \end{syntax} % This function sets up the math code of \meta{character}. % The \meta{character} is specified as @@ -306,7 +306,7 @@ % % \begin{function}{\char_set_sfcode:nn} % \begin{syntax} -% \cs{char_set_sfcode:nn} \Arg{intexpr1} \Arg{intexpr2} +% \cs{char_set_sfcode:nn} \Arg{intexpr_1} \Arg{intexpr_2} % \end{syntax} % This function sets up the space factor for the \meta{character}. % The \meta{character} is specified as @@ -332,14 +332,14 @@ % character code given by the \meta{integer expression} on the % terminal. % \end{function} -% +% % \begin{variable}[added = 2012-01-23]{\l_char_active_seq} % Used to track which tokens will require special handling at the document % level as they are of category \meta{active} (catcode~$13$). Each entry in % the sequence consists of a single active character. Active tokens should be % added to the sequence when they are defined for general document use. % \end{variable} -% +% % \begin{variable}[added = 2012-01-23]{\l_char_special_seq} % Used to track which tokens will require special handling when working with % verbatim-like material at the document level as they are not of categories @@ -354,7 +354,7 @@ % % \begin{function}{\token_new:Nn} % \begin{syntax} -% \cs{token_new:Nn} \meta{token1} \Arg{token2} +% \cs{token_new:Nn} \meta{token1} \Arg{token_2} % \end{syntax} % Defines \meta{token1} to globally be a snapshot of \meta{token2}. % This will be an implicit representation of \meta{token2}. @@ -652,6 +652,14 @@ % \end{texnote} % \end{function} % +% \begin{function}[EXP,pTF, added=2012-02-15]{\token_if_muskip_register:N} +% \begin{syntax} +% \cs{token_if_muskip_register_p:N} \meta{token} \\ +% \cs{token_if_muskip_register:NTF} \meta{token} \Arg{true code} \Arg{false code} +% \end{syntax} +% Tests if the \meta{token} is defined to be a muskip register. +% \end{function} +% % \begin{function}[EXP,pTF, updated=2012-01-20]{\token_if_skip_register:N} % \begin{syntax} % \cs{token_if_skip_register_p:N} \meta{token} \\ @@ -947,7 +955,7 @@ % made active within the current \TeX{} group level, and the definition % is also local. % \end{function} -% +% % \begin{function}[added = 2011-12-27] % {\char_gset_active:Npn, \char_gset_active:Npx} % \begin{syntax} @@ -973,7 +981,7 @@ % is made active within the current \TeX{} group level, and the definition % is also local. % \end{function} -% +% % \begin{function}[added = 2011-12-27] % {\char_gset_active_eq:NN} % \begin{syntax} @@ -1256,7 +1264,7 @@ \group_end: % \end{macrocode} % \end{variable} -% +% % \begin{variable}{\l_char_active_seq, \l_char_special_seq} % Two sequences for dealing with special characters. The first is characters % which may be active, and contains the active characters themselves to @@ -1264,8 +1272,8 @@ % characters more generally, and these are escaped so that for example % bulk code assignments can be carried out. In both cases, the order is % by \textsc{ascii} character code (as is done in for example -% \cs{ExplSyntaxOn}). The only complication is dealing with |_|, which has to -% be done using \cs{tl_to_lowercase:n} +% \cs{ExplSyntaxOn}). The only complication is dealing with |_|, which +% requires the use of \cs{use:n} \emph{and} \cs{use:nn}. % \begin{macrocode} \seq_new:N \l_char_active_seq \use:n @@ -1283,7 +1291,7 @@ \seq_set_from_clist:Nn \l_char_active_seq } } - { { " , $ , & , ^ , _ , ~ } } + { { " , $ , & , ^ , _ , ~ } } %$ \seq_new:N \l_char_special_seq \seq_set_from_clist:Nn \l_char_special_seq { \ , \" , \# , \$ , \% , \& , \\ , \^ , \_ , \{ , \} , \~ } @@ -1324,7 +1332,7 @@ { \if_catcode:w \exp_not:N #1 \c_math_toggle_token \prg_return_true: \else: \prg_return_false: \fi: - } + } % \end{macrocode} % \end{macro} % @@ -1555,6 +1563,7 @@ % { % \token_if_chardef:N, \token_if_mathchardef:N, % \token_if_dim_register:N, \token_if_int_register:N, +% \token_if_muskip_register:N, % \token_if_skip_register:N, \token_if_toks_register:N, % \token_if_long_macro:N, % \token_if_protected_macro:N, \token_if_protected_long_macro:N, @@ -1564,6 +1573,7 @@ % \token_if_chardef_aux:w, % \token_if_dim_register_aux:w, % \token_if_int_register_aux:w, +% \token_if_muskip_register_aux:w, % \token_if_skip_register_aux:w, % \token_if_toks_register_aux:w, % \token_if_protected_macro_aux:w, @@ -1674,7 +1684,28 @@ } \cs_new:Npn \token_if_int_register_aux:w #1 COUXY #2 \q_stop { #1 ~ } % \end{macrocode} -% Skip registers are done the same way as the dimension registers. +% Muskip registers are done the same way as the dimension registers. +% \begin{macrocode} + \prg_new_conditional:Npnn \token_if_muskip_register:N #1 { p , T , F , TF } + { + \if_meaning:w \tex_muskip:D #1 + \prg_return_false: + \else: + \if_meaning:w \tex_muskipdef:D #1 + \prg_return_false: + \else: + \str_if_eq_return:xx + { + \exp_after:wN \token_if_muskip_register_aux:w + \token_to_meaning:N #1 MUSKIP \q_stop + } + { \token_to_str:N \ } + \fi: + \fi: + } + \cs_new:Npn \token_if_muskip_register_aux:w #1 MUSKIP #2 \q_stop { #1 ~ } +% \end{macrocode} +% Skip registers. % \begin{macrocode} \prg_new_conditional:Npnn \token_if_skip_register:N #1 { p , T , F , TF } { diff --git a/Master/texmf-dist/source/latex/l3kernel/l3tree.dtx b/Master/texmf-dist/source/latex/l3kernel/l3tree.dtx new file mode 100644 index 00000000000..27e5b7e5d44 --- /dev/null +++ b/Master/texmf-dist/source/latex/l3kernel/l3tree.dtx @@ -0,0 +1,595 @@ +% \iffalse +% +%% File l3tree.dtx (C) Copyright 2012 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 "l3trial 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{expl3} +\GetIdInfo$Id: l3tree.dtx 3177 2012-01-11 02:11:43Z bruno $ + {L3 Experimental tree manipulations} +%</driver|package> +%<*driver> +\documentclass[full]{l3doc} +\usepackage{amsmath} +\begin{document} + \DocInput{\jobname.dtx} +\end{document} +%</driver> +% \fi +% +% \title{^^A +% The \pkg{l3tree} package\\ Trees^^A +% \thanks{This file describes v\ExplFileVersion, +% last revised \ExplFileDate.}^^A +% } +% +% \author{^^A +% The \LaTeX3 Project\thanks +% {^^A +% E-mail: +% \href{mailto:latex-team@latex-project.org} +% {latex-team@latex-project.org}^^A +% }^^A +% } +% +% \date{Released \ExplFileDate} +% +% \maketitle +% +% \begin{documentation} +% +% \section{\pkg{l3tree} documentation} +% +% \LaTeX3 comes with a tree data-type, whose keys are integers. +% ^^A Currently, we only support binary trees, but that will probably +% ^^A be extended as the need arises. +% +% A tree is a box containing +% +% \begin{function}{\tree_new:N, \tree_new:c} +% \begin{syntax} +% \cs{tree_new:N} \meta{tree} +% \end{syntax} +% Creates a new tree, with no node. +% \end{function} +% +% \begin{function}{\tree_put:Nn, \tree_put:cn, \tree_gput:Nn, \tree_gput:cn} +% \begin{syntax} +% \cs{tree_put:Nn} \meta{tree} \Arg{integer expression} +% \end{syntax} +% Evaluates the \meta{integer expression}, and puts the +% \end{function} +% +% \end{documentation} +% +% \begin{implementation} +% +% \section{\pkg{l3tree} implementation} +% +% \begin{macrocode} +%<*initex|package> +% \end{macrocode} +% +% \begin{macrocode} +%<*package> +\ProvidesExplPackage + {\ExplFileName}{\ExplFileDate}{\ExplFileVersion}{\ExplFileDescription} +\package_check_loaded_expl: +%</package> +% \end{macrocode} +% +% \subsection{Variables} +% +% \begin{variable}{\l_tree_index_int} +% +% \begin{macrocode} +\int_new:N \l_tree_index_int +% \end{macrocode} +% \end{variable} +% +% \begin{variable}{\l_tree_item_box} +% +% \begin{macrocode} +\box_new:N \l_tree_item_box +% \end{macrocode} +% \end{variable} +% +% \begin{variable}{\l_tree_left_box,\l_tree_right_box} +% During the splaying step, these two boxes hold the left and right +% children of the node which we splay. +% \begin{macrocode} +\box_new:N \l_tree_left_box +\box_new:N \l_tree_right_box +% \end{macrocode} +% \end{variable} +% +% \begin{variable}{\l_tree_first_box, \l_tree_second_box} +% Temporary variables holding subtrees of the full tree +% in various circumstances. +% \begin{macrocode} +\box_new:N \l_tree_first_box +\box_new:N \l_tree_second_box +% \end{macrocode} +% \end{variable} +% +% \begin{variable}{\l_tree_parent_box, \l_tree_grandpa_box} +% +% \begin{macrocode} +\box_new:N \l_tree_parent_box +\box_new:N \l_tree_grandpa_box +% \end{macrocode} +% \end{variable} +% +% \begin{variable}{\c_one_sp_dim} +% Smallest dimension that \TeX{} recognizes. When implicitly +% converting from integers to dimensions, this is the conversion +% factor. +% \begin{macrocode} +\dim_new:N \c_one_sp_dim +\dim_set:Nn \c_one_sp_dim { 1 sp } +% \end{macrocode} +% \end{variable} +% +% \begin{variable}{\l_tree_parent_dim,\l_tree_grandpa_dim} +% +% \begin{macrocode} +\dim_new:N \l_tree_parent_dim +\dim_new:N \l_tree_grandpa_dim +% \end{macrocode} +% \end{variable} +% +% \begin{variable}{\g_tree_result_seq} +% When extracting keys from a tree, the result is temporarily stored +% globally in \cs{g_tree_result_seq} to exit a group. +% \begin{macrocode} +\seq_new:N \g_tree_result_seq +% \end{macrocode} +% \end{variable} +% +% \begin{variable}{\l_tree_internal_box} +% Scratch box register for temporary use. +% \begin{macrocode} +\box_new:N \l_tree_internal_box +% \end{macrocode} +% \end{variable} +% +% \subsection{Generic helpers} +% +% \begin{macro}{\tree_end:} +% Used to end box assignments started by \cs{tree_edit:Nw}, +% \cs{tree_gedit:Nw}, or \cs{tree_cat:Nw}. +% \begin{macrocode} +\cs_new_eq:NN \tree_end: \c_group_end_token +% \end{macrocode} +% \end{macro} +% +%^^A explain that we need protection against a potential \tn{everyhbox}. +% +% \begin{macro}{\tree_edit:Nw, \tree_gedit:Nw} +% Accessing the contents of a tree requires unpacking its contents, +% to access them using the \tn{lastbox} primitive. We may not do +% that in the current list. Instead, this is done within a box +% assignment to the tree itself: this choice allows us to modify +% (\enquote{edit}) the tree and not only access the nodes. +% This editing should be ended by \cs{tree_end:}. +% \begin{macrocode} +\cs_new_protected:Npn \tree_edit:Nw #1 + { + \tex_afterassignment:D \use_none_delimit_by_q_stop:w + \tex_setbox:D #1 \tex_hbox:D \c_group_begin_token + \q_stop + \tex_everyhbox:D { } + \hbox_unpack_clear:N #1 + } +\cs_new_protected:Npn \tree_gedit:Nw #1 + { + \tex_afterassignment:D \use_none_delimit_by_q_stop:w + \tex_global:D \tex_setbox:D #1 \tex_hbox:D \c_group_begin_token + \q_stop + \tex_everyhbox:D { } + \hbox_unpack_clear:N #1 + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\tree_cat:Nw} +% Similar to \cs{tree_edit:Nw}, but without altering the tree contents. +% \begin{macrocode} +\cs_new_protected:Npn \tree_cat:Nw #1 + { + \tex_afterassignment:D \use_none_delimit_by_q_stop:w + \tex_setbox:D \l_tree_internal_box \tex_hbox:D \c_group_begin_token + \q_stop + \tex_everyhbox:D { } + \hbox_unpack:N #1 + } +% \end{macrocode} +% \end{macro} +% +% \subsection{Empty trees} +% +% \begin{macro}{\tree_new:N, \tree_new:c} +% \begin{macro}{\tree_clear:N, \tree_clear:c} +% \begin{macro}{\tree_gclear:N, \tree_gclear:c} +% Trees are simply boxes, so we copy the box functions. +% \begin{macrocode} +\cs_new_eq:NN \tree_new:N \box_new:N +\cs_new_eq:NN \tree_new:c \box_new:c +\cs_new_eq:NN \tree_clear:N \box_clear:N +\cs_new_eq:NN \tree_clear:c \box_clear:c +\cs_new_eq:NN \tree_gclear:N \box_gclear:N +\cs_new_eq:NN \tree_gclear:c \box_gclear:c +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}[pTF, EXP]{\tree_if_empty:N} +% Test whether a tree is empty, \emph{i.e.}, contains no node at all. +% \begin{macrocode} +\prg_new_eq_conditional:NNn \tree_if_empty:N + \box_if_empty:N { p , T , F , TF } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[EXP]{\if_tree_empty:N} +% The primitive conditional is used in the code because it expands +% in only one step. +% \begin{macrocode} +\cs_new_eq:NN \if_tree_empty:N \if_box_empty:N +% \end{macrocode} +% \end{macro} +% +% \subsection{Extracting the keys} +% +% \begin{macro}{\seq_set_from_tree:NN, \seq_gset_from_tree:NN} +% \begin{macro}[aux]{\tree_extract_aux:NNN} +% The local and global versions only differ by how the sequence +% is assigned once it has been built in \cs{g_tree_result_seq}. +% We open the tree with \cs{tree_cat:Nw}, then extract the keys +% non-expandably into \tn{dimen} registers (used as integers) +% using \cs{tree_extract_loop:}, and store the values of those +% \tn{dimen} registers expandably as the sequence +% \cs{g_tree_result_seq}. After closing the tree, store the +% result sequence into the user's variable, and clear the +% internal sequence (a small cost operation to avoid memory leaks). +% \begin{macrocode} +\cs_new_protected_nopar:Npn \seq_set_from_tree:NN + { \tree_extract_aux:NNN \seq_set_eq:NN } +\cs_new_protected_nopar:Npn \seq_gset_from_tree:NN + { \tree_extract_aux:NNN \seq_gset_eq:NN } +\cs_new_protected:Npn \tree_extract_aux:NNN #1#2#3 + { + \int_zero:N \l_tree_index_int + \tree_cat:Nw #3 + \tree_extract_loop: + \tl_gset:Nx \g_tree_result_seq + { + \exp_after:wN \tree_extract_loop:w + \int_use:N \l_tree_index_int ; + \prg_break_point:n { } + } + \tree_end: + #1 #2 \g_tree_result_seq + \tl_gclear:N \g_tree_result_seq + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}[aux]{\tree_extract_loop:} +% +% \begin{macrocode} +\cs_new_protected:Npn \tree_extract_loop: + { + \tex_setbox:D \l_tree_first_box \tex_lastbox:D + \if_hbox:N \l_tree_first_box + \hbox_unpack_clear:N \l_tree_first_box + \else: + \if_num:w \tex_ht:D \l_tree_first_box = \c_zero + \exp_after:wN \exp_after:wN \exp_after:wN \use_none:n + \else: + \tex_advance:D \l_tree_index_int \c_one + \tex_dimen:D \l_tree_index_int \tex_ht:D \l_tree_first_box + \fi: + \fi: + \tree_extract_loop: + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[aux, EXP]{\tree_extract_loop:w} +% +% \begin{macrocode} +\cs_new:Npn \tree_extract_loop:w #1 ; + { + \if_num:w #1 = \c_zero + \exp_after:wN \prg_map_break: + \fi: + \exp_not:N \seq_item:n { \int_value:w \tex_dimen:D #1 } + \exp_after:wN \tree_extract_loop:w + \int_use:N \int_eval:w #1 - \c_one ; + } +% \end{macrocode} +% \end{macro} +% +% \subsection{Comparison} +% +% \begin{macro}{\tree_compare:NN} +% +% \begin{macrocode} +\cs_new_protected:Npn \tree_compare:NN #1 #2 + { + \if_num:w \tex_ht:D #1 > \tex_ht:D #2 \exp_stop_f: + \tree_reversed: + \else: + \tree_ordered: + \fi: + } +% \end{macrocode} +% \end{macro} +% +% \subsection{Adding nodes to a tree} +% +% \begin{macro}{\tree_put:Nnn, \tree_gput:Nnn} +% \begin{macro}[aux]{\tree_put_aux:NNnn} +% +% \begin{macrocode} +\cs_new_protected:Npn \tree_put:Nnn + { \tree_put_aux:NNnn \tree_edit:Nw } +\cs_new_protected:Npn \tree_gput:Nnn + { \tree_put_aux:NNnn \tree_gedit:Nw } +\cs_new_protected:Npn \tree_put_aux:NNnn #1#2#3#4 + { + \tex_setbox:D \l_tree_left_box \tex_box:D \c_empty_box + \tex_setbox:D \l_tree_right_box \tex_box:D \c_empty_box + \tex_setbox:D \l_tree_item_box + \tex_vbox:D to \int_eval:w #3 \int_eval_end: \c_one_sp_dim {#4} + \exp_after:wN #1 \exp_after:wN #2 + \if_tree_empty:N #2 + \else: + \tree_put_loop: + \tree_splay_loop: + \fi: + \box_use_clear:N \l_tree_left_box + \box_use_clear:N \l_tree_item_box + \box_use_clear:N \l_tree_right_box + \tree_end: + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}[aux]{\tree_put_loop:} +% +% \begin{macrocode} +\cs_new_protected:Npn \tree_put_loop: + { + \tex_setbox:D \l_tree_first_box \tex_lastbox:D + \tex_setbox:D \l_tree_parent_box + \if_vbox:N \l_tree_first_box + \tex_box:D \l_tree_first_box + \else: + \tex_lastbox:D + \fi: + \tree_compare:NN \l_tree_parent_box \l_tree_item_box + \if_box_empty:N \l_tree_first_box + \exp_after:wN \use_none:n + \else: + \hbox_unpack_clear:N \l_tree_first_box + \fi: + \tree_put_loop: + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\tree_ordered:, \tree_reversed:} +% +% \begin{macrocode} +\cs_new_protected:Npn \tree_ordered: + { + \box_use_clear:N \l_tree_parent_box + \tex_kern:D \c_one_sp_dim + } +\cs_new_protected:Npn \tree_reversed: + { + \tex_setbox:D \l_tree_second_box \tex_lastbox:D + \box_use_clear:N \l_tree_first_box + \tex_setbox:D \l_tree_first_box \tex_box:D \l_tree_second_box + \box_use_clear:N \l_tree_parent_box + \tex_kern:D - \c_one_sp_dim + } +% \end{macrocode} +% \end{macro} +% +% \subsection{Splaying} +% +% \begin{macro}[int]{\tree_splay_loop:} +% +% \begin{macrocode} +\cs_new_protected:Npn \tree_splay_loop: + { + \l_tree_parent_dim \tex_lastkern:D + \tex_unkern:D + \tex_setbox:D \l_tree_parent_box \tex_lastbox:D + \tex_setbox:D \l_tree_first_box \tex_lastbox:D + \l_tree_grandpa_dim \tex_lastkern:D + \tex_unkern:D + \tex_setbox:D \l_tree_grandpa_box \tex_lastbox:D + \tex_setbox:D \l_tree_second_box \tex_lastbox:D + \cs:w + tree_splay + _\int_value:w \l_tree_parent_dim + _\int_value:w \l_tree_grandpa_dim + : + \cs_end: + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[aux]{\tree_splay_0_0:} +% +% \begin{macrocode} +\cs_new_protected:cpn { tree_splay_0_0: } { } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[aux]{\tree_splay_1_0:} +% +% \begin{macrocode} +\cs_new_protected:cpn { tree_splay_1_0: } + { + \tex_setbox:D \l_tree_left_box \tex_hbox:D + { + \box_use_clear:N \l_tree_first_box + \box_use_clear:N \l_tree_parent_box + \box_use_clear:N \l_tree_left_box + } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[aux]{\tree_splay_-1_0:} +% +% \begin{macrocode} +\cs_new_protected:cpn { tree_splay_-1_0: } + { + \tex_setbox:D \l_tree_right_box \tex_hbox:D + { + \box_use_clear:N \l_tree_right_box + \box_use_clear:N \l_tree_parent_box + \box_use_clear:N \l_tree_first_box + } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[aux]{\tree_splay_1_1:} +% +% \begin{macrocode} +\cs_new_protected:cpn { tree_splay_1_1: } + { + \tex_setbox:D \l_tree_left_box \tex_hbox:D + { + \tex_hbox:D + { + \box_use_clear:N \l_tree_second_box + \box_use_clear:N \l_tree_grandpa_box + \box_use_clear:N \l_tree_first_box + } + \box_use_clear:N \l_tree_parent_box + \box_use_clear:N \l_tree_left_box + } + \tree_splay_loop: + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[aux]{\tree_splay_1_-1:} +% +% \begin{macrocode} +\cs_new_protected:cpn { tree_splay_1_-1: } + { + \tex_setbox:D \l_tree_right_box \tex_hbox:D + { + \box_use_clear:N \l_tree_right_box + \box_use_clear:N \l_tree_grandpa_box + \box_use_clear:N \l_tree_second_box + } + \tex_setbox:D \l_tree_left_box \tex_hbox:D + { + \box_use_clear:N \l_tree_first_box + \box_use_clear:N \l_tree_parent_box + \box_use_clear:N \l_tree_left_box + } + \tree_splay_loop: + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[aux]{\tree_splay_-1_1:} +% +% \begin{macrocode} +\cs_new_protected:cpn { tree_splay_-1_1: } + { + \tex_setbox:D \l_tree_right_box \tex_hbox:D + { + \box_use_clear:N \l_tree_right_box + \box_use_clear:N \l_tree_parent_box + \box_use_clear:N \l_tree_first_box + } + \tex_setbox:D \l_tree_left_box \tex_hbox:D + { + \box_use_clear:N \l_tree_second_box + \box_use_clear:N \l_tree_grandpa_box + \box_use_clear:N \l_tree_left_box + } + \tree_splay_loop: + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[aux]{\tree_splay_-1_-1:} +% +% \begin{macrocode} +\cs_new_protected:cpn { tree_splay_-1_-1: } + { + \tex_setbox:D \l_tree_right_box \tex_hbox:D + { + \box_use_clear:N \l_tree_right_box + \box_use_clear:N \l_tree_parent_box + \tex_hbox:D + { + \box_use_clear:N \l_tree_first_box + \box_use_clear:N \l_tree_grandpa_box + \box_use_clear:N \l_tree_second_box + } + } + \tree_splay_loop: + } +% \end{macrocode} +% \end{macro} +% +% \subsection{Sorting} +% +% \begin{macrocode} +% \end{macrocode} +% +% \begin{macrocode} +%</initex|package> +% \end{macrocode} +% +% \end{implementation} +% +% \PrintIndex
\ No newline at end of file diff --git a/Master/texmf-dist/tex/latex/l3kernel/expl3.sty b/Master/texmf-dist/tex/latex/l3kernel/expl3.sty index 31d7c78ee60..28dfab3ab00 100644 --- a/Master/texmf-dist/tex/latex/l3kernel/expl3.sty +++ b/Master/texmf-dist/tex/latex/l3kernel/expl3.sty @@ -59,8 +59,8 @@ } \def\ExplFileName{expl3} \def\ExplFileDescription{L3 Experimental code bundle wrapper} -\def\ExplFileDate{2012/02/08} -\def\ExplFileVersion{3343} +\def\ExplFileDate{2012/02/26} +\def\ExplFileVersion{3471} \RequirePackage{etex} \reserveinserts{32} \ProvidesExplPackage @@ -155,19 +155,11 @@ \cs_check_exists:N #1 \cs_set_eq:NN #1 } - \cs_undefine:N \bool_set_eq:cN - \cs_undefine:N \bool_set_eq:Nc - \cs_undefine:N \bool_set_eq:cc - \cs_generate_variant:Nn \bool_set_eq:NN { c , Nc , cc } \cs_set_protected:Npn \bool_gset_eq:NN #1 { \cs_check_exists:N #1 - \cs_set_eq:NN #1 + \cs_gset_eq:NN #1 } - \cs_undefine:N \bool_gset_eq:cN - \cs_undefine:N \bool_gset_eq:Nc - \cs_undefine:N \bool_gset_eq:cc - \cs_generate_variant:Nn \bool_gset_eq:NN { c , Nc , cc } \cs_set_protected:Npn \bool_set:Nn #1#2 { \cs_check_exists:N #1 @@ -184,7 +176,6 @@ l3token, l3prop, l3msg, - l3io, l3file, l3skip, l3keys, diff --git a/Master/texmf-dist/tex/latex/l3kernel/l3basics.sty b/Master/texmf-dist/tex/latex/l3kernel/l3basics.sty index 4ea5a1ce780..2193b30348f 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 3317 2012-02-06 12:26:40Z bruno $ +\GetIdInfo$Id: l3basics.dtx 3460 2012-02-26 12:16:41Z will $ {L3 Experimental basic definitions} \ProvidesExplPackage {\ExplFileName}{\ExplFileDate}{\ExplFileVersion}{\ExplFileDescription} @@ -451,8 +451,8 @@ \msg_kernel_error:nnxx { kernel } { command-already-defined } { \token_to_str:N #1 } { \token_to_meaning:N #1 } } - \iow_log:x { Defining~\token_to_str:N #1~ \msg_line_context: } - } + \iow_log:x { Defining~\token_to_str:N #1~ \msg_line_context: } + } \fi: \cs_set_protected_nopar:Npn \chk_if_free_cs:c { \exp_args:Nc \chk_if_free_cs:N } diff --git a/Master/texmf-dist/tex/latex/l3kernel/l3box.sty b/Master/texmf-dist/tex/latex/l3kernel/l3box.sty index 9176a912928..1fe36dc7ca3 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 3158 2012-01-09 00:47:42Z bruno $ +\GetIdInfo$Id: l3box.dtx 3432 2012-02-18 12:16:20Z 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 bf523e186e1..7fc71a96c04 100644 --- a/Master/texmf-dist/tex/latex/l3kernel/l3clist.sty +++ b/Master/texmf-dist/tex/latex/l3kernel/l3clist.sty @@ -48,7 +48,7 @@ %% %% ----------------------------------------------------------------------- \RequirePackage{l3names} -\GetIdInfo$Id: l3clist.dtx 3157 2012-01-09 00:42:07Z bruno $ +\GetIdInfo$Id: l3clist.dtx 3460 2012-02-26 12:16:41Z will $ {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 index c13164ef700..5c5ea863483 100644 --- a/Master/texmf-dist/tex/latex/l3kernel/l3coffins.sty +++ b/Master/texmf-dist/tex/latex/l3kernel/l3coffins.sty @@ -47,7 +47,7 @@ %% ----------------------------------------------------------------------- %% \RequirePackage{l3names} -\GetIdInfo$Id: l3coffins.dtx 3155 2012-01-08 22:53:03Z bruno $ +\GetIdInfo$Id: l3coffins.dtx 3460 2012-02-26 12:16:41Z will $ {L3 Experimental coffin code layer} \ProvidesExplPackage {\ExplFileName}{\ExplFileDate}{\ExplFileVersion}{\ExplFileDescription} diff --git a/Master/texmf-dist/tex/latex/l3kernel/l3doc.cls b/Master/texmf-dist/tex/latex/l3kernel/l3doc.cls index 33821fa37f4..e01b5752fd5 100644 --- a/Master/texmf-dist/tex/latex/l3kernel/l3doc.cls +++ b/Master/texmf-dist/tex/latex/l3kernel/l3doc.cls @@ -52,7 +52,7 @@ \let \filedateOld \ExplFileDate \let \fileversionOld \ExplFileVersion \let \filedescriptionOld \ExplFileDescription -\GetIdInfo$Id: l3doc.dtx 3255 2012-01-28 20:31:12Z joseph $ +\GetIdInfo$Id: l3doc.dtx 3464 2012-02-26 15:30:29Z bruno $ {L3 Experimental documentation class} \ProvidesExplClass {\ExplFileName}{\ExplFileDate}{\ExplFileVersion}{\ExplFileDescription} @@ -125,7 +125,22 @@ \ProcessOptions \LoadClass{article} \RequirePackage{doc} -\RequirePackage{array,alphalph,booktabs,color,colortbl,fixltx2e,enumitem,pifont,textcomp,trace,underscore,csquotes,fancyvrb} +\RequirePackage + { + array, + alphalph, + booktabs, + color, + colortbl, + fixltx2e, + enumitem, + pifont, + textcomp, + trace, + underscore, + csquotes, + fancyvrb + } \raggedbottom \fvset{gobble=2} \cs_set_eq:NN \verbatim \Verbatim @@ -302,15 +317,14 @@ \coffin_clear:N \l_doc_syntax_coffin \coffin_clear:N \l_doc_names_coffin - \bool_gset_false:N \l_doc_meta_TF_bool - \bool_gset_false:N \l_doc_meta_pTF_bool - \bool_gset_false:N \l_doc_meta_EXP_bool - \bool_gset_false:N \l_doc_meta_rEXP_bool + \bool_set_false:N \l_doc_meta_TF_bool + \bool_set_false:N \l_doc_meta_pTF_bool + \bool_set_false:N \l_doc_meta_EXP_bool + \bool_set_false:N \l_doc_meta_rEXP_bool \keys_set:nn { l3doc/function } {#1} - \char_set_catcode_active:N \< - \cs_set_eq:NN < \doc_open_meta:n + \char_set_active_eq:NN < \doc_open_meta:w \group_begin: \MakePrivateLetters @@ -324,10 +338,6 @@ } { \vcoffin_set_end: - \hcoffin_set:Nn \l_doc_names_coffin - { - \exp_args:NV \function_typeset:n \l_doc_function_input_tl - } \bool_if:NTF \l_doc_long_name_bool { \coffin_join:NnnNnnnn @@ -387,40 +397,20 @@ } \cs_gset_nopar:Npn \function_typeset:n #1 { - - \cs_set_nopar:Npn \nextnewline{\cs_gset_nopar:Npn\nextnewline{\\}} \tl_gclear:N \g_doc_macro_tl - \prop_clear:N \l_doc_functions_block_prop - + % populate "\l_doc_functions_block_prop" with info on the functions present: \clist_map_function:nN {#1} \doc_parse_functions:n \small\ttfamily \begin{tabular}{ @{} l @{} r @{} } \toprule - \prop_map_function:NN \l_doc_functions_block_prop \doc_show_functions:nn - \\ - - \bool_if:nF { \tl_if_empty_p:N \l_doc_date_added_tl && - \tl_if_empty_p:N \l_doc_date_updated_tl } - { \midrule } - - \tl_if_empty:NF \l_doc_date_added_tl - { - \multicolumn{2}{@{}r@{}} - { \scriptsize New:\,\l_doc_date_added_tl } \\ - } - - \tl_if_empty:NF \l_doc_date_updated_tl - { - \multicolumn{2}{@{}r@{}} - { \scriptsize Updated:\,\l_doc_date_updated_tl } \\ - } + \prop_map_function:NN \l_doc_functions_block_prop \doc_typeset_functions:nn + \doc_typeset_dates: \bottomrule \end{tabular} \normalfont\normalsize } - \prop_new:N \l_doc_functions_block_prop \cs_generate_variant:Nn \prop_put:Nnn {Nxx} \cs_new:Nn \doc_parse_functions:n @@ -429,10 +419,10 @@ { \tl_gset_eq:NN \l_doc_function_name_prefix_tl \@backslashchar % for the weird functions named "\::N" and so on: -\exp_args:Nx \tl_if_head_eq_charcode:nNTF { \cs_to_str:N #1 } {:} +\exp_args:Nx \tl_if_head_eq_charcode:nNTF { \cs_to_str:N #1 } { : } { % again, no variants: -\prop_put:Nxx \l_doc_functions_block_prop { \cs_to_str:N #1 } { } +\prop_put:Nxx \l_doc_functions_block_prop { \cs_to_str:N #1 } { {-1} {} } } { % finally, for regular old csnames: @@ -442,12 +432,19 @@ { \prop_put:Nxx \l_doc_functions_block_prop { \cs_get_function_name:N #1 } -{ \l_doc_tmp_tl , \cs_get_function_signature:N #1 } +{ + \l_doc_tmp_tl , + {\cs_get_arg_count_from_signature:N #1} + {\cs_get_function_signature:N #1} +} } { \prop_put:Nxx \l_doc_functions_block_prop { \cs_get_function_name:N #1 } -{ \cs_get_function_signature:N #1 } +{ + {\cs_get_arg_count_from_signature:N #1} + {\cs_get_function_signature:N #1} +} } } } @@ -455,105 +452,121 @@ { % for now don't bother splitting into variants: \tl_gclear:N \l_doc_function_name_prefix_tl -\prop_put:Nxx \l_doc_functions_block_prop { #1 } { } +\prop_put:Nxx \l_doc_functions_block_prop { #1 } { {-1} {} } } } -\cs_new:Nn \doc_show_functions:nn +\cs_new:Nn \doc_typeset_functions:nn { \clist_gset:Nn \l_doc_variants_clist {#2} \clist_gpop:NN \l_doc_variants_clist \l_doc_tmp_tl - \exp_args:Nx \doc_showmacro:n - { \exp_not:c {#1 \tl_if_empty:NF \l_doc_tmp_tl { : \l_doc_tmp_tl } } } + \exp_args:Nc \doc_typeset_functions_aux:N + { + #1 + \int_compare:nT { \exp_after:wN \use_i:nn \l_doc_tmp_tl > -1 } {:} + \int_compare:nT { \exp_after:wN \use_i:nn \l_doc_tmp_tl > 0 } + { \exp_after:wN \use_ii:nn \l_doc_tmp_tl } + } + \\ } -\cs_new_nopar:Nn \doc_showmacro:n { +\cs_new_nopar:Nn \doc_typeset_functions_aux:N +{ \bool_if:NT \l_doc_meta_pTF_bool { \tl_set:Nx \l_doc_pTF_name_tl { \doc_predicate_from_base:N #1 } - \doc_special_main_index:o { \token_to_str:N \l_doc_pTF_name_tl } - \seq_gput_right:Nx \g_doc_functions_seq { \tl_to_str:N \l_doc_pTF_name_tl } + \doc_special_main_index:o { \tl_to_str:N \l_doc_pTF_name_tl } + \seq_gput_right:Nx \g_doc_functions_seq { \l_doc_function_name_prefix_tl \l_doc_pTF_name_tl } } \bool_if:NTF \l_doc_meta_TF_bool { \doc_special_main_index:o { \token_to_str:N #1 TF } - \seq_gput_right:Nx \g_doc_functions_seq { \tl_to_str:n { #1 TF } } - \seq_gput_right:Nx \g_doc_functions_seq { \tl_to_str:n { #1 T } } - \seq_gput_right:Nx \g_doc_functions_seq { \tl_to_str:n { #1 F } } + \seq_gput_right:Nx \g_doc_functions_seq { \token_to_str:N #1 TF } }{ \doc_special_main_index:o { \token_to_str:N #1 } - \seq_gput_right:Nx \g_doc_functions_seq { \tl_to_str:n { #1 } } + \seq_gput_right:Nx \g_doc_functions_seq { \tl_to_str:n {#1} } } \bool_if:NTF \l_doc_meta_pTF_bool { + \bool_gset_false:N \l_doc_meta_TF_bool - \exp_args:Nc \doc_showmacro_aux_ii:N \l_doc_pTF_name_tl + \exp_args:Nc \doc_typeset_function_block:N { \l_doc_pTF_name_tl } \bool_gset_true:N \l_doc_meta_TF_bool - \exp_args:Nc \doc_showmacro_aux_ii:N { \cs_to_str:N #1 } + + \\ + \doc_typeset_function_block:N #1 + }{ \exp_args:Nx \tl_if_head_eq_charcode:nNTF { \exp_after:wN \use_none:n \token_to_str:N #1 } {:} - { \doc_showmacro_aux_iii:N #1 } - { \doc_showmacro_aux_ii:N #1 } + { \doc_show_macro_unusual:N #1 } + { \doc_typeset_function_block:N #1 } } } -\cs_set_nopar:Nn \doc_showmacro_aux_ii:N { - \nextnewline +\cs_set_nopar:Nn \doc_typeset_function_block:N { \tl_gset:Nx \l_doc_function_name_tl { \cs_get_function_name:N #1 } \tl_gset:Nx \l_doc_function_sig_tl { \cs_get_function_signature:N #1 } \tl_gset:Nx \g_doc_macro_tl { \l_doc_function_name_prefix_tl \l_doc_function_name_tl } - \g_doc_macro_tl - \int_compare:nT { \cs_get_arg_count_from_signature:N #1 >= 0 } - { : \l_doc_function_sig_tl } - + \doc_typeset_function_basename:N #1 \bool_if:NT \l_doc_meta_TF_bool { \doc_typeset_TF: } + \doc_typeset_expandability: + \clist_if_empty:NF \l_doc_variants_clist { \doc_typeset_variants: } + \bool_if:NT \g_doc_full_bool { \doc_label_function: } - & - \bool_if:NT \l_doc_meta_EXP_bool { - \hspace{\tabcolsep} - \hyperlink{expstar} {$\star$} - } - \bool_if:NT \l_doc_meta_rEXP_bool { - \hspace{\tabcolsep} - \hyperlink{rexpstar} {\ding{73}} % hollow star - } - - \clist_if_empty:NF \l_doc_variants_clist - { - \\ - \doc_typeset_aux:n \g_doc_macro_tl : - \int_compare:nTF { \clist_length:N \l_doc_variants_clist == 1 } - { \l_doc_variants_clist } - { - \textrm( - \clist_pop:NN \l_doc_variants_clist \l_doc_tmp_tl - \l_doc_tmp_tl - \clist_map_inline:Nn \l_doc_variants_clist {\textrm|##1} - \textrm) - } - \bool_if:NT \l_doc_meta_TF_bool { \doc_typeset_TF: } - & - \bool_if:NT \l_doc_meta_EXP_bool { - \hspace{\tabcolsep} - \hyperlink{expstar} {$\star$} +} +\cs_set:Nn \doc_typeset_function_basename:N + { + \g_doc_macro_tl + \int_compare:nT { \cs_get_arg_count_from_signature:N #1 > -1 } { : } + \int_compare:nT { \cs_get_arg_count_from_signature:N #1 > 0 } + { \l_doc_function_sig_tl } } - \bool_if:NT \l_doc_meta_rEXP_bool { - \hspace{\tabcolsep} - \hyperlink{rexpstar} {\ding{73}} % hollow star +\cs_set:Nn \doc_typeset_expandability: + { + & + \bool_if:NT \l_doc_meta_EXP_bool { + \hspace{\tabcolsep} + \hyperlink{expstar} {$\star$} + } + \bool_if:NT \l_doc_meta_rEXP_bool { + \hspace{\tabcolsep} + \hyperlink{rexpstar} {\ding{73}} % hollow star + } } +\cs_set:Nn \doc_typeset_variants: + { + \\ + \doc_typeset_aux:n \g_doc_macro_tl : + \int_compare:nTF { \clist_length:N \l_doc_variants_clist == 1 } + { \exp_after:wN \use_ii:nn \l_doc_variants_clist } + { + \textrm( + \clist_pop:NN \l_doc_variants_clist \l_doc_tmp_tl + \exp_after:wN \use_ii:nn \l_doc_tmp_tl + \clist_map_inline:Nn \l_doc_variants_clist {\textrm| \use_ii:nn ##1} + \textrm) + } + \bool_if:NT \l_doc_meta_TF_bool { \doc_typeset_TF: } + & + \bool_if:NT \l_doc_meta_EXP_bool { + \hspace{\tabcolsep} + \hyperlink{expstar} {$\star$} } - - \exp_args:NNf \tl_replace_all:Nnn \g_doc_macro_tl {\token_to_str:N _} {/} - \exp_args:NNf \tl_replace_all:Nnn \g_doc_macro_tl {\@backslashchar} {} - \bool_if:NT \g_doc_full_bool { + \bool_if:NT \l_doc_meta_rEXP_bool { + \hspace{\tabcolsep} + \hyperlink{rexpstar} {\ding{73}} % hollow star + } + } +\cs_set:Nn \doc_label_function: + { + \exp_args:NNf \tl_replace_all:Nnn \g_doc_macro_tl {\token_to_str:N _} {/} + \exp_args:NNf \tl_replace_all:Nnn \g_doc_macro_tl {\@backslashchar} {} \exp_args:Nx \label { doc/function//\g_doc_macro_tl \tl_if_empty:NF \l_doc_function_sig_tl { : \l_doc_function_sig_tl } } } -} -\cs_set_nopar:Nn \doc_showmacro_aux_iii:N { - \nextnewline +\cs_set_nopar:Nn \doc_show_macro_unusual:N { \tl_gset:Nx \g_doc_macro_tl { \token_to_str:N #1} \token_to_str:N #1 & @@ -563,6 +576,24 @@ \exp_args:Nx \label { doc/function//\g_doc_macro_tl } } } +\cs_set:Nn \doc_typeset_dates: + { + \bool_if:nF { \tl_if_empty_p:N \l_doc_date_added_tl && + \tl_if_empty_p:N \l_doc_date_updated_tl } + { \midrule } + + \tl_if_empty:NF \l_doc_date_added_tl + { + \multicolumn{2}{@{}r@{}} + { \scriptsize New:\,\l_doc_date_added_tl } \\ + } + + \tl_if_empty:NF \l_doc_date_updated_tl + { + \multicolumn{2}{@{}r@{}} + { \scriptsize Updated:\,\l_doc_date_updated_tl } \\ + } + } \newenvironment{syntax}{ \small\ttfamily \bool_if:NTF \l_doc_long_name_bool @@ -591,44 +622,62 @@ \coffin_gset_eq:NN \l_doc_syntax_coffin \l_doc_syntax_coffin \ignorespacesafterend } -\tl_map_inline:nn {0123456789} { \cs_gset_eq:cN {char_other_#1} #1 } -\group_begin: - \tl_map_inline:nn {0123456789} { \char_set_catcode_active:N #1 } - \cs_new:Npn \doc_open_meta:n { +\cs_new:Npn \doc_ensuremath_sb:n #1 + { + \ensuremath{\sb{#1}} + } +\cs_set_eq:NN \doc_meta:n \meta +\cs_set:Npn \meta + { \group_begin: - \tl_map_function:nN {0123456789} \doc_assign_num:n + \char_set_active_eq:NN _ \doc_ensuremath_sb:n + \doc_close_meta:n + } +\cs_new:Npn \doc_open_meta:w + { + \group_begin: + \char_set_active_eq:NN _ \doc_ensuremath_sb:n \doc_close_meta:w } - \cs_new:Npn \Arg { +\cs_new:Npn \Arg + { \texttt{ \char`\{ } \group_begin: - \tl_map_function:nN {0123456789} \doc_assign_num:n + \char_set_active_eq:NN _ \doc_ensuremath_sb:n \doc_close_Arg:n } -\group_end: -\cs_new_nopar:Npn \doc_close_meta:w #1> { \meta {#1} \group_end: } +\cs_new_nopar:Npn \doc_close_meta:n #1 { \doc_meta:n {#1} \group_end: } +\cs_new_nopar:Npn \doc_close_meta:w #1> { \doc_meta:n {#1} \group_end: } \cs_new_nopar:Npn \doc_close_Arg:n #1 { - \meta {#1} + \doc_meta:n {#1} \group_end: \texttt{ \char`\} } } -\cs_new_nopar:Npn \doc_assign_num:n #1 { - \cs_set_eq:cc { \string #1 } { char_other_\string #1 } - \char_set_catcode_active:N #1 - \cs_set_nopar:Npn #1 { \unskip \, $ {} \sb { \use:c { char_other_\string #1 } } $ } -} +\keys_define:nn { l3doc/macro } + { + aux .code:n = + { \bool_set_true:N \l_doc_macro_aux_bool } , + internal .code:n = + { \bool_set_true:N \l_doc_macro_internal_bool } , + var .code:n = + { \bool_set_true:N \l_doc_macro_var_bool } , + TF .code:n = + { \bool_set_true:N \l_doc_macro_TF_bool } , + pTF .code:n = + { \bool_set_true:N \l_doc_macro_pTF_bool } , + } \renewcommand \macro [1][] { \int_compare:nNnTF \currentgrouplevel=2 { \int_gzero:N \g_doc_nested_macro_int } { \int_incr:N \g_doc_nested_macro_int } - \bool_set_false:N \l_doc_macro_aux_bool - \bool_set_false:N \l_doc_macro_internal_bool - \bool_set_false:N \l_doc_macro_TF_bool - \bool_set_false:N \l_doc_macro_pTF_bool - \bool_set_false:N \l_doc_macro_var_bool - \bool_set_false:N \l_doc_tested_bool + \bool_gset_false:N \l_doc_macro_aux_bool + \bool_gset_false:N \l_doc_macro_internal_bool + \bool_gset_false:N \l_doc_macro_TF_bool + \bool_gset_false:N \l_doc_macro_pTF_bool + \bool_gset_false:N \l_doc_macro_var_bool + \bool_gset_false:N \l_doc_tested_bool \cs_set_eq:NN \doc_macroname_prefix:n \use:n \cs_set_eq:NN \doc_macroname_suffix: \c_empty_tl @@ -668,24 +717,23 @@ { \clist_map_inline:Nn \l_doc_macro_input_clist { - \exp_args:Nf \doc_macro_single { \doc_predicate_from_base:w ##1 } + \exp_args:Nx \doc_macro_single:n { \doc_predicate_from_base:w ##1 \q_nil } } \bool_set_true:N \l_doc_macro_TF_bool - \clist_map_function:NN \l_doc_macro_input_clist \doc_macro_single + \clist_map_function:NN \l_doc_macro_input_clist \doc_macro_single:n \bool_set_false:N \l_doc_macro_TF_bool } - { \clist_map_function:NN \l_doc_macro_input_clist \doc_macro_single } + { \clist_map_function:NN \l_doc_macro_input_clist \doc_macro_single:n } } -\cs_set_nopar:Npn \doc_macro_opt_aux: { \bool_set_true:N \l_doc_macro_aux_bool } -\cs_set_nopar:Npn \doc_macro_opt_internal: { \bool_set_true:N \l_doc_macro_internal_bool } -\cs_set_nopar:Npn \doc_macro_opt_TF: { \bool_set_true:N \l_doc_macro_TF_bool } -\cs_set_nopar:Npn \doc_macro_opt_pTF: { \bool_set_true:N \l_doc_macro_pTF_bool } -\cs_set_nopar:Npn \doc_macro_opt_var: { \bool_set_true:N \l_doc_macro_var_bool } \cs_set:Nn \doc_predicate_from_base:N { \cs_get_function_name:N #1 _p: \cs_get_function_signature:N #1 } -\cs_set_nopar:Npn \doc_macro_single #1 { +\cs_set:Npn \doc_predicate_from_base:w #1 : #2 \q_nil + { + #1 _p: #2 + } +\cs_set_nopar:Npn \doc_macro_single:n #1 { \int_incr:N \l_doc_macro_int \tl_set:Nx \saved@macroname { \token_to_str:N #1 } \topsep\MacroTopsep @@ -815,34 +863,38 @@ } { \prop_gput:NVn \g_doc_missing_tests_prop \l_doc_macro_input_clist {#1} } } +\cs_set:Nn \doc_macro_wrap:n + { + #1 \bool_if:NT \l_doc_macro_TF_bool {TF} + } \cs_set:Nn \doc_texttt_comma:n {\,,~\texttt{#1}} \cs_set:Npn \endmacro { \int_compare:nT {\g_doc_nested_macro_int<1} { - \par\nobreak{\footnotesize(\emph{ + \par\nobreak\noindent{\footnotesize(\emph{ End~ definition~ for~ \prg_case_int:nnn { \clist_length:N \l_doc_macro_input_clist } { - {1} { \texttt{ \clist_use:N \l_doc_macro_input_clist }. } + {1} { \texttt{ \doc_macro_wrap:n { \clist_use:N \l_doc_macro_input_clist } }. } {2} { \tl_set:Nx \l_clist_first_tl { \clist_item:Nn \l_doc_macro_input_clist {0} } \tl_set:Nx \l_clist_last_tl { \clist_item:Nn \l_doc_macro_input_clist {1} } - \texttt{\l_clist_first_tl}\,~ and~ \texttt{\l_clist_last_tl}\,. + \texttt{\doc_macro_wrap:n\l_clist_first_tl}\,~ and~ \texttt{\doc_macro_wrap:n\l_clist_last_tl}\,. } {3} { \tl_set:Nx \l_clist_first_tl { \clist_item:Nn \l_doc_macro_input_clist {0} } \tl_set:Nx \l_clist_mid_tl { \clist_item:Nn \l_doc_macro_input_clist {1} } \tl_set:Nx \l_clist_last_tl { \clist_item:Nn \l_doc_macro_input_clist {2} } - \texttt{\l_clist_first_tl}\,,~ - \texttt{\l_clist_mid_tl}\,,~ - and~ \texttt{\l_clist_last_tl}\,. + \texttt{\doc_macro_wrap:n\l_clist_first_tl}\,,~ + \texttt{\doc_macro_wrap:n\l_clist_mid_tl}\,,~ + and~ \texttt{\doc_macro_wrap:n\l_clist_last_tl}\,. } } { \tl_set:Nx \l_clist_first_tl { \clist_item:Nn \l_doc_macro_input_clist {0} } - \texttt{\l_clist_first_tl}\,~and~others. + \texttt{\doc_macro_wrap:n\l_clist_first_tl}\,~and~others. } \bool_if:nT { !\l_doc_macro_aux_bool && diff --git a/Master/texmf-dist/tex/latex/l3kernel/l3expan.sty b/Master/texmf-dist/tex/latex/l3kernel/l3expan.sty index f3bf00e9997..d6463b70fac 100644 --- a/Master/texmf-dist/tex/latex/l3kernel/l3expan.sty +++ b/Master/texmf-dist/tex/latex/l3kernel/l3expan.sty @@ -46,7 +46,7 @@ %% %% ----------------------------------------------------------------------- \RequirePackage{l3names} -\GetIdInfo$Id: l3expan.dtx 3196 2012-01-15 09:44:05Z joseph $ +\GetIdInfo$Id: l3expan.dtx 3460 2012-02-26 12:16:41Z will $ {L3 Experimental argument expansion} \ProvidesExplPackage {\ExplFileName}{\ExplFileDate}{\ExplFileVersion}{\ExplFileDescription} @@ -286,6 +286,7 @@ \cs_new_nopar:Npn \exp_last_unbraced:Nno { \::n \::o_unbraced \::: } \cs_new_nopar:Npn \exp_last_unbraced:Noo { \::o \::o_unbraced \::: } \cs_new_nopar:Npn \exp_last_unbraced:Nfo { \::f \::o_unbraced \::: } +\cs_new_nopar:Npn \exp_last_unbraced:NnNo { \::n \::N \::o_unbraced \::: } \cs_new_protected_nopar:Npn \exp_last_unbraced:Nx { \::x_unbraced \::: } \cs_new:Npn \exp_last_two_unbraced:Noo #1#2#3 { \exp_after:wN \exp_last_two_unbraced_aux:noN \exp_after:wN {#3} {#2} #1 } diff --git a/Master/texmf-dist/tex/latex/l3kernel/l3file.sty b/Master/texmf-dist/tex/latex/l3kernel/l3file.sty index f79666e640a..25eda0dc609 100644 --- a/Master/texmf-dist/tex/latex/l3kernel/l3file.sty +++ b/Master/texmf-dist/tex/latex/l3kernel/l3file.sty @@ -13,7 +13,7 @@ %% %% Do not distribute a modified version of this file. %% -%% File: l3file.dtx Copyright (C) 2009-2012 The LaTeX3 Project +%% File: l3file.dtx Copyright (C) 1990-2012 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 @@ -46,8 +46,8 @@ %% %% ----------------------------------------------------------------------- \RequirePackage{l3names} -\GetIdInfo$Id: l3file.dtx 3287 2012-01-31 22:08:14Z joseph $ - {L3 Experimental file operations} +\GetIdInfo$Id: l3file.dtx 3464 2012-02-26 15:30:29Z bruno $ + {L3 Experimental file and I/O operations} \ProvidesExplPackage {\ExplFileName}{\ExplFileDate}{\ExplFileVersion}{\ExplFileDescription} \package_check_loaded_expl: @@ -59,19 +59,27 @@ \seq_new:N \l_file_search_path_seq \seq_new:N \l_file_internal_saved_path_seq \seq_new:N \l_file_internal_seq -\ior_new:N \g_file_internal_ior -\cs_new_protected:Npn \file_add_path:nN #1 +\cs_new_protected:Npn \file_name_sanitize:nn #1#2 { \group_begin: - \tl_to_str_active_safe:Nx \l_file_internal_name_tl {#1} - \tl_if_in:NnT \l_file_internal_name_tl { ~ } + \seq_map_inline:Nn \l_char_active_seq + { \cs_set_nopar:Npx ##1 { \token_to_str:N ##1 } } + \tl_set:Nx \l_file_internal_name_tl {#1} + \tl_set:Nx \l_file_internal_name_tl + { \tl_to_str:N \l_file_internal_name_tl } + \tl_if_in:NnTF \l_file_internal_name_tl { ~ } { - \msg_kernel_error:nnx { io } { space-in-file-name } + \msg_kernel_error:nnx { file } { space-in-file-name } { \l_file_internal_name_tl } } - \exp_args:NNo \group_end: - \file_add_path_aux:nN \l_file_internal_name_tl + \use:x + { + \group_end: + \exp_not:n {#2} { \l_file_internal_name_tl } + } } +\cs_new_protected:Npn \file_add_path:nN #1 + { \file_name_sanitize:nn {#1} { \file_add_path_aux:nN } } \cs_new_protected:Npn \file_add_path_aux:nN #1#2 { \ior_open_unsafe:Nn \g_file_internal_ior {#1} @@ -84,7 +92,7 @@ } \cs_new_protected:Npn \file_add_path_search:nN #1#2 { - \tl_clear:N #2 + \tl_set:Nn #2 { \q_no_value } \cs_if_exist:NT \input@path { \seq_set_eq:NN \l_file_internal_saved_path_seq \l_file_search_path_seq @@ -105,91 +113,529 @@ { \seq_set_eq:NN \l_file_search_path_seq \l_file_internal_saved_path_seq } \ior_close:N \g_file_internal_ior } -\prg_new_protected_conditional:Nnn \file_if_exist:n { T , F , TF } +\prg_new_protected_conditional:Npnn \file_if_exist:n #1 { T , F , TF } { \file_add_path:nN {#1} \l_file_internal_name_tl - \tl_if_empty:NTF \l_file_internal_name_tl + \quark_if_no_value:NTF \l_file_internal_name_tl { \prg_return_false: } { \prg_return_true: } } \cs_new_protected:Npn \file_input:n #1 { \file_add_path:nN {#1} \l_file_internal_name_tl - \tl_if_empty:NF \l_file_internal_name_tl + \quark_if_no_value:NTF \l_file_internal_name_tl + { \file_name_sanitize:nn {#1} { \file_input_error:n } } + { \file_input_aux:V \l_file_internal_name_tl } + } +\cs_new_protected:Npn \file_input_aux:n #1 + { + \@addtofilelist {#1} + \seq_gpush:Nn \g_file_stack_seq \g_file_current_name_tl + \tl_gset:Nn \g_file_current_name_tl {#1} + \tex_input:D #1 \c_space_tl + \seq_gpop:NN \g_file_stack_seq \g_file_current_name_tl + } +\cs_generate_variant:Nn \file_input_aux:n { V } +\cs_new_protected:Npn \file_input_error:n #1 + { \msg_kernel_error:nnx { file } { file-not-found } {#1} } +\cs_new_protected:Npn \file_path_include:n #1 + { + \seq_if_in:NnF \l_file_search_path_seq {#1} + { \seq_put_right:Nn \l_file_search_path_seq {#1} } + } +\cs_new_protected:Npn \file_path_remove:n #1 + { \seq_remove_all:Nn \l_file_search_path_seq {#1} } +\cs_new_protected_nopar:Npn \file_list: + { + \seq_remove_duplicates:N \g_file_record_seq + \iow_log:n { *~File~List~* } + \seq_map_inline:Nn \g_file_record_seq { \iow_log:n {##1} } + \iow_log:n { ************* } + } +\AtBeginDocument + { + \seq_set_from_clist:NN \l_file_internal_seq \@filelist + \seq_gconcat:NNN \g_file_record_seq \g_file_record_seq \l_file_internal_seq + } +\cs_new_eq:NN \c_term_ior \c_sixteen +\cs_new_eq:NN \c_log_iow \c_minus_one +\cs_new_eq:NN \c_term_iow \c_sixteen +\tl_const:Nn \c_iow_streams_tl + { + \c_zero + \c_one + \c_two + \c_three + \c_four + \c_five + \c_six + \c_seven + \c_eight + \c_nine + \c_ten + \c_eleven + \c_twelve + \c_thirteen + \c_fourteen + \c_fifteen + } +\cs_new_eq:NN \c_ior_streams_tl \c_iow_streams_tl +\prop_new:N \g_iow_streams_prop +\prop_new:N \g_ior_streams_prop +\prop_put:Nnn \g_iow_streams_prop { 0 } { LaTeX2e~reserved } +\prop_put:Nnn \g_iow_streams_prop { 1 } { LaTeX2e~reserved } +\prop_put:Nnn \g_iow_streams_prop { 2 } { LaTeX2e~reserved } +\prop_put:Nnn \g_ior_streams_prop { 0 } { LaTeX2e~reserved } +\int_new:N \l_iow_stream_int +\cs_new_eq:NN \l_ior_stream_int \l_iow_stream_int +\cs_set_eq:NN \iow_raw_new:N \newwrite +\cs_set_eq:NN \ior_raw_new:N \newread +\cs_generate_variant:Nn \ior_raw_new:N { c } +\cs_generate_variant:Nn \iow_raw_new:N { c } +\cs_new_protected:Npn \ior_new:N #1 { \cs_new_eq:NN #1 \c_term_ior } +\cs_generate_variant:Nn \ior_new:N { c } +\cs_new_protected:Npn \iow_new:N #1 { \cs_new_eq:NN #1 \c_term_iow } +\cs_generate_variant:Nn \iow_new:N { c } +\ior_new:N \g_file_internal_ior +\cs_new_protected:Npn \ior_open:Nn #1#2 + { \file_name_sanitize:nn {#2} { \ior_open_aux:Nn #1 } } +\cs_generate_variant:Nn \ior_open:Nn { c } +\cs_new_protected:Npn \iow_open:Nn #1#2 + { \file_name_sanitize:nn {#2} { \iow_open_unsafe:Nn #1 } } +\cs_generate_variant:Nn \iow_open:Nn { c } +\cs_new_protected:Npn \ior_open_aux:Nn #1#2 + { + \file_add_path:nN {#2} \l_file_name_internal_tl + \quark_if_no_value:NTF \l_file_internal_name_tl + { \file_input_error:n {#2} } + { \ior_open_unsafe:No #1 \l_file_name_internal_tl } + } +\prg_new_protected_conditional:Npnn \ior_open:Nn #1#2 { T , F , TF } + { \file_name_sanitize:nn {#2} { \ior_open_aux:NnTF #1 } } +\cs_new_protected:Npn \ior_open_aux:NnTF #1#2 + { + \file_add_path:nN {#2} \l_file_name_internal_tl + \quark_if_no_value:NTF \l_file_internal_name_tl + { \prg_return_false: } { - \@addtofilelist {#1} - \seq_gpush:NV \g_file_stack_seq \g_file_current_name_tl - \tl_gset:Nn \g_file_current_name_tl {#1} - \exp_after:wN \tex_input:D \l_file_internal_name_tl \c_space_tl - \seq_gpop:NN \g_file_stack_seq \g_file_current_name_tl + \ior_open_unsafe:No #1 \l_file_name_internal_tl + \prg_return_true: } } -\cs_new_protected:Npn \file_split_path_name_ext:nNNN #1 +\cs_generate_variant:Nn \ior_open:NnT { c } +\cs_generate_variant:Nn \ior_open:NnF { c } +\cs_generate_variant:Nn \ior_open:NnTF { c } +\cs_new_protected:Npn \ior_open_unsafe:Nn #1#2 { - \group_begin: - \tl_to_str_active_safe:Nx \l_file_internal_name_tl {#1} - \tl_if_in:NnT \l_file_internal_name_tl { ~ } - { - \msg_kernel_error:nnx { io } { space-in-file-name } - { \l_file_internal_name_tl } - } - \exp_args:NNo \group_end: - \file_split_path_name_ext_aux:nNNN \l_file_internal_name_tl + \ior_close:N #1 + \int_set:Nn \l_ior_stream_int \c_sixteen + \tl_map_function:NN \c_ior_streams_tl \ior_alloc_read:n + \int_compare:nNnTF \l_ior_stream_int = \c_sixteen + { \msg_kernel_fatal:nn { ior } { streams-exhausted } } + { + \ior_stream_alloc:N #1 + \prop_gput:NVn \g_ior_streams_prop \l_ior_stream_int {#2} + \tex_openin:D #1#2 \scan_stop: + } } -\cs_new_protected:Npn \file_split_path_name_ext_aux:nNNN #1#2#3#4 +\cs_generate_variant:Nn \ior_open_unsafe:Nn { No } +\cs_new_protected:Npn \iow_open_unsafe:Nn #1#2 { - \tl_clear:N #2 - \tl_clear:N #3 - \file_split_path:wNNN #1 / \q_nil / \q_stop #2#3#4 + \iow_close:N #1 + \int_set:Nn \l_iow_stream_int \c_sixteen + \tl_map_function:NN \c_iow_streams_tl \iow_alloc_write:n + \int_compare:nNnTF \l_iow_stream_int = \c_sixteen + { \msg_kernel_fatal:nn { iow } { streams-exhausted } } + { + \iow_stream_alloc:N #1 + \prop_gput:NVn \g_iow_streams_prop \l_iow_stream_int {#2} + \tex_immediate:D \tex_openout:D #1#2 \scan_stop: + } } -\cs_new_protected:Npn \file_split_path:wNNN #1 / #2 / #3 \q_stop #4 +\cs_new_protected:Npn \iow_alloc_write:n #1 { - \quark_if_nil:nTF {#2} - { \file_split_name_ext:wNN #1 . \q_nil . \q_stop } + \prop_if_in:NnF \g_iow_streams_prop {#1} { - \tl_put_right:Nn #4 { #1 / } - \file_split_path:wNNN #2 / #3 \q_stop #4 + \int_set:Nn \l_iow_stream_int {#1} + \tl_map_break: } } -\cs_new_protected:Npn \file_split_name_ext:wNN #1 . #2 . #3 \q_stop #4#5 +\cs_new_protected:Npn \ior_alloc_read:n #1 { - \quark_if_nil:nTF {#2} + \prop_if_in:NnF \g_iow_streams_prop {#1} { - \tl_if_empty:NTF #4 + \int_set:Nn \l_ior_stream_int {#1} + \tl_map_break: + } + } +\iow_new:N \g_iow_internal_iow +\ior_new:N \g_ior_internal_ior +\cs_new_protected:Npn \iow_stream_alloc:N #1 + { + \cs_if_exist:cTF { g_iow_ \int_use:N \l_iow_stream_int _iow } + { \cs_gset_eq:Nc #1 { g_iow_ \int_use:N \l_iow_stream_int _iow } } + { + \iow_stream_alloc_aux: + \int_compare:nNnT \l_iow_stream_int = \c_sixteen { - \tl_set:Nn #4 {#1} - \tl_clear:N #5 + \iow_raw_new:N \g_iow_internal_iow + \int_set:Nn \l_iow_stream_int { \g_iow_internal_iow } + \cs_gset_eq:cN + { g_iow_ \int_use:N \l_iow_stream_int _iow } \g_iow_internal_iow } - { \tl_set:Nn #5 {#1} } + \cs_gset_eq:Nc #1 { g_iow_ \int_use:N \l_iow_stream_int _iow } + } + } +\cs_new_protected_nopar:Npn \iow_stream_alloc_aux: + { + \int_incr:N \l_iow_stream_int + \int_compare:nNnT \l_iow_stream_int < \c_sixteen + { + \cs_if_exist:cTF { g_iow_ \int_use:N \l_iow_stream_int _iow } + { + \prop_if_in:NVT \g_iow_streams_prop \l_iow_stream_int + { \iow_stream_alloc_aux: } + } + { \iow_stream_alloc_aux: } } + } +\cs_new_protected:Npn \ior_stream_alloc:N #1 + { + \cs_if_exist:cTF { g_ior_ \int_use:N \l_ior_stream_int _ior } + { \cs_gset_eq:Nc #1 { g_ior_ \int_use:N \l_ior_stream_int _ior } } { - \tl_put_right:Nx #4 + \ior_stream_alloc_aux: + \int_compare:nNnT \l_ior_stream_int = \c_sixteen { - \tl_if_empty:NF #4 { . } - #1 + \ior_raw_new:N \g_ior_internal_ior + \int_set:Nn \l_ior_stream_int { \g_ior_internal_ior } + \cs_gset_eq:cN + { g_ior_ \int_use:N \l_iow_stream_int _ior } \g_ior_internal_ior } - \file_split_name_ext:wNN #2 . #3 \q_stop #4#5 + \cs_gset_eq:Nc #1 { g_ior_ \int_use:N \l_ior_stream_int _ior } } } -\cs_new_protected:Npn \file_path_include:n #1 +\cs_new_protected_nopar:Npn \ior_stream_alloc_aux: { - \seq_if_in:NnF \l_file_search_path_seq {#1} - { \seq_put_right:Nn \l_file_search_path_seq {#1} } + \int_incr:N \l_ior_stream_int + \int_compare:nNnT \l_ior_stream_int < \c_sixteen + { + \cs_if_exist:cTF { g_ior_ \int_use:N \l_ior_stream_int _ior } + { + \prop_if_in:NVT \g_ior_streams_prop \l_ior_stream_int + { \ior_stream_alloc_aux: } + } + { \ior_stream_alloc_aux: } + } } -\cs_new_protected:Npn \file_path_remove:n #1 - { \seq_remove_all:Nn \l_file_search_path_seq {#1} } -\cs_new_protected_nopar:Npn \file_list: +\cs_new_protected:Npn \ior_close:N #1 { - \seq_remove_duplicates:N \g_file_record_seq - \iow_log:n { *~File~List~* } - \seq_map_inline:Nn \g_file_record_seq { \iow_log:n {##1} } - \iow_log:n { ************* } + \cs_if_exist:NT #1 + { + \int_compare:nNnF #1 = \c_minus_one + { + \int_compare:nNnF #1 = \c_sixteen + { \tex_closein:D #1 } + \prop_gdel:NV \g_ior_streams_prop #1 + \cs_gset_eq:NN #1 \c_term_ior + } + } } -\AtBeginDocument +\cs_new_protected:Npn \iow_close:N #1 { - \seq_set_from_clist:NN \l_file_internal_seq \@filelist - \seq_gconcat:NNN \g_file_record_seq \g_file_record_seq \l_file_internal_seq + \cs_if_exist:NT #1 + { + \int_compare:nNnF #1 = \c_minus_one + { + \int_compare:nNnF #1 = \c_sixteen + { \tex_closein:D #1 } + \prop_gdel:NV \g_iow_streams_prop #1 + \cs_gset_eq:NN #1 \c_term_iow + } + } + } +\cs_generate_variant:Nn \ior_close:N { c } +\cs_generate_variant:Nn \iow_close:N { c } +\cs_new_protected_nopar:Npn \ior_list_streams: + { \ior_list_streams_aux:Nn \g_ior_streams_prop { ior } } +\cs_new_protected_nopar:Npn \iow_list_streams: + { \ior_list_streams_aux:Nn \g_iow_streams_prop { iow } } +\cs_new_protected:Npn \ior_list_streams_aux:Nn #1#2 + { + \msg_aux_use:nn { LaTeX / #2 } + { \prop_if_empty:NTF #1 { show-no-stream } { show-open-streams } } + \msg_aux_show:x + { \prop_map_function:NN #1 \msg_aux_show_unbraced:nn } + } +\msg_kernel_new:nnnn { iow } { streams-exhausted } + { Output~streams~exhausted } + { + TeX~can~only~open~up~to~16~output~streams~at~one~time.\\ + All~16 are currently~in~use,~and~something~wanted~to~open + another~one. + } +\msg_kernel_new:nnnn { ior } { streams-exhausted } + { Input~streams~exhausted } + { + TeX~can~only~open~up~to~16~input~streams~at~one~time.\\ + All~16 are currently~in~use,~and~something~wanted~to~open + another~one. + } +\cs_new_eq:NN \iow_shipout_x:Nn \tex_write:D +\cs_generate_variant:Nn \iow_shipout_x:Nn { Nx } +\cs_new_protected:Npn \iow_shipout:Nn #1#2 + { \iow_shipout_x:Nn #1 { \exp_not:n {#2} } } +\cs_generate_variant:Nn \iow_shipout:Nn { Nx } +\cs_new_protected_nopar:Npn \iow_now:Nx { \tex_immediate:D \iow_shipout_x:Nn } +\cs_new_protected:Npn \iow_now:Nn #1#2 + { \iow_now:Nx #1 { \exp_not:n {#2} } } +\cs_set_protected_nopar:Npn \iow_log:x { \iow_now:Nx \c_log_iow } +\cs_new_protected_nopar:Npn \iow_log:n { \iow_now:Nn \c_log_iow } +\cs_set_protected_nopar:Npn \iow_term:x { \iow_now:Nx \c_term_iow } +\cs_new_protected_nopar:Npn \iow_term:n { \iow_now:Nn \c_term_iow } +\cs_new_nopar:Npn \iow_newline: { ^^J } +\cs_new_eq:NN \iow_char:N \cs_to_str:N +\int_new:N \l_iow_line_length_int +\int_set:Nn \l_iow_line_length_int { 78 } +\int_new:N \l_iow_target_length_int +\int_new:N \l_iow_current_line_int +\int_new:N \l_iow_current_word_int +\int_new:N \l_iow_current_indentation_int +\tl_new:N \l_iow_current_line_tl +\tl_new:N \l_iow_current_word_tl +\tl_new:N \l_iow_current_indentation_tl +\tl_new:N \l_iow_wrap_tl +\tl_new:N \l_iow_wrapped_tl +\bool_new:N \l_iow_line_start_bool +\group_begin: + \char_set_catcode_other:N \* + \char_set_lccode:nn {`\*} {`\ } + \tl_to_lowercase:n { \tl_const:Nn \c_catcode_other_space_tl { * } } +\group_end: +\group_begin: + \int_set_eq:NN \tex_escapechar:D \c_minus_one + \tl_const:Nx \c_iow_wrap_marker_tl + { \tl_to_str:n { \^^I \^^O \^^W \^^_ \^^W \^^R \^^A \^^P } } + \cs_set:Npn \iow_wrap_new_marker:n #1 + { + \tl_const:cx { c_iow_wrap_ #1 _marker_tl } + { + \c_catcode_other_space_tl + \c_iow_wrap_marker_tl + \c_catcode_other_space_tl + #1 + \c_catcode_other_space_tl + } + } + \iow_wrap_new_marker:n { end } + \iow_wrap_new_marker:n { newline } + \iow_wrap_new_marker:n { indent } + \iow_wrap_new_marker:n { unindent } +\group_end: +\cs_new_protected:Npn \iow_indent:n #1 { } +\cs_new:Npx \iow_indent_expandable:n #1 + { + \c_iow_wrap_indent_marker_tl + #1 + \c_iow_wrap_unindent_marker_tl + } +\cs_new_protected:Npn \iow_wrap:xnnnN #1#2#3#4#5 + { + \group_begin: + \int_set:Nn \l_iow_target_length_int { \l_iow_line_length_int - ( #3 ) } + \int_zero:N \l_iow_current_indentation_int + \tl_clear:N \l_iow_current_indentation_tl + \int_zero:N \l_iow_current_line_int + \tl_clear:N \l_iow_current_line_tl + \tl_clear:N \l_iow_wrap_tl + \bool_set_true:N \l_iow_line_start_bool + \int_set_eq:NN \tex_escapechar:D \c_minus_one + \cs_set_nopar:Npx \{ { \token_to_str:N \{ } + \cs_set_nopar:Npx \# { \token_to_str:N \# } + \cs_set_nopar:Npx \} { \token_to_str:N \} } + \cs_set_nopar:Npx \% { \token_to_str:N \% } + \cs_set_nopar:Npx \~ { \token_to_str:N \~ } + \int_set:Nn \tex_escapechar:D { 92 } + \cs_set_eq:NN \\ \c_iow_wrap_newline_marker_tl + \cs_set_eq:NN \ \c_catcode_other_space_tl + \cs_set_eq:NN \iow_indent:n \iow_indent_expandable:n + #4 + \protected@edef \l_iow_wrap_tl {#1} + \cs_set:Npn \\ { \iow_newline: #2 } + \use:x + { + \iow_wrap_loop:w + \tl_to_str:N \l_iow_wrap_tl + \tl_to_str:N \c_iow_wrap_end_marker_tl + \c_space_tl \c_space_tl + \exp_not:N \q_stop + } + \exp_args:NNo \group_end: + #5 \l_iow_wrapped_tl + } +\cs_new_protected:Npn \iow_wrap_loop:w #1 ~ % + { + \tl_set:Nn \l_iow_current_word_tl {#1} + \tl_if_eq:NNTF \l_iow_current_word_tl \c_iow_wrap_marker_tl + { \iow_wrap_special:w } + { \iow_wrap_word: } + } +\cs_new_protected_nopar:Npn \iow_wrap_word: + { + \int_set:Nn \l_iow_current_word_int + { \str_length_skip_spaces:N \l_iow_current_word_tl } + \int_add:Nn \l_iow_current_line_int { \l_iow_current_word_int } + \int_compare:nNnTF \l_iow_current_line_int < \l_iow_target_length_int + { \iow_wrap_word_fits: } + { \iow_wrap_word_newline: } + \iow_wrap_loop:w + } +\cs_new_protected_nopar:Npn \iow_wrap_word_fits: + { + \bool_if:NTF \l_iow_line_start_bool + { + \bool_set_false:N \l_iow_line_start_bool + \tl_put_right:Nx \l_iow_current_line_tl + { \l_iow_current_indentation_tl \l_iow_current_word_tl } + \int_add:Nn \l_iow_current_line_int + { \l_iow_current_indentation_int } + } + { + \tl_put_right:Nx \l_iow_current_line_tl + { ~ \l_iow_current_word_tl } + \int_incr:N \l_iow_current_line_int + } + } +\cs_new_protected_nopar:Npn \iow_wrap_word_newline: + { + \tl_put_right:Nx \l_iow_wrapped_tl + { \l_iow_current_line_tl \\ } + \int_set:Nn \l_iow_current_line_int + { + \l_iow_current_word_int + + \l_iow_current_indentation_int + } + \tl_set:Nx \l_iow_current_line_tl + { \l_iow_current_indentation_tl \l_iow_current_word_tl } + } +\cs_new_protected:Npn \iow_wrap_special:w #1 ~ #2 ~ #3 ~ % + { + \use:c { iow_wrap_#1: } + \str_if_eq:xxTF { #2~#3 } { ~ \c_iow_wrap_marker_tl } + { \iow_wrap_special:w } + { \iow_wrap_loop:w #2 ~ #3 ~ } + } +\cs_new_protected_nopar:Npn \iow_wrap_newline: + { + \tl_put_right:Nx \l_iow_wrapped_tl + { \l_iow_current_line_tl \\ } + \int_zero:N \l_iow_current_line_int + \tl_clear:N \l_iow_current_line_tl + \bool_set_true:N \l_iow_line_start_bool + } +\cs_new_protected_nopar:Npx \iow_wrap_indent: + { + \int_add:Nn \l_iow_current_indentation_int \c_four + \tl_put_right:Nx \exp_not:N \l_iow_current_indentation_tl + { \c_space_tl \c_space_tl \c_space_tl \c_space_tl } + } +\cs_new_protected_nopar:Npn \iow_wrap_unindent: + { + \int_sub:Nn \l_iow_current_indentation_int \c_four + \tl_set:Nx \l_iow_current_indentation_tl + { \prg_replicate:nn \l_iow_current_indentation_int { ~ } } + } +\cs_new_protected_nopar:Npn \iow_wrap_end: + { + \tl_put_right:Nx \l_iow_wrapped_tl + { \l_iow_current_line_tl } + \use_none_delimit_by_q_stop:w + } +\cs_new_nopar:Npn \str_length_skip_spaces:N + { \exp_args:No \str_length_skip_spaces:n } +\cs_new:Npn \str_length_skip_spaces:n #1 + { + \int_value:w \int_eval:w + \exp_after:wN \str_length_loop:NNNNNNNNN \tl_to_str:n {#1} + { X8 } { X7 } { X6 } { X5 } { X4 } { X3 } { X2 } { X1 } { X0 } \q_stop + \int_eval_end: + } +\cs_new:Npn \str_length_loop:NNNNNNNNN #1#2#3#4#5#6#7#8#9 + { + \if_catcode:w X #9 + \exp_after:wN \use_none_delimit_by_q_stop:w + \else: + 9 + + \exp_after:wN \str_length_loop:NNNNNNNNN + \fi: + } +\cs_new_eq:NN \if_eof:w \tex_ifeof:D +\prg_new_conditional:Nnn \ior_if_eof:N { p , T , F , TF } + { + \cs_if_exist:NTF #1 + { + \if_int_compare:w #1 = \c_sixteen + \prg_return_true: + \else: + \if_eof:w #1 + \prg_return_true: + \else: + \prg_return_false: + \fi: + \fi: + } + { \prg_return_true: } + } +\cs_new_protected:Npn \ior_to:NN #1#2 + { \tex_read:D #1 to #2 } +\cs_new_protected:Npn \ior_gto:NN #1#2 + { \tex_global:D \tex_read:D #1 to #2 } +\cs_new_protected:Npn \ior_str_to:NN #1#2 + { \etex_readline:D #1 to #2 } +\cs_new_protected:Npn \ior_str_gto:NN #1#2 + { \tex_global:D \etex_readline:D #1 to #2 } +\cs_new_protected_nopar:Npn \ior_map_inline:Nn + { \ior_map_inline_aux:NNn \ior_to:NN } +\cs_new_protected_nopar:Npn \ior_str_map_inline:Nn + { \ior_map_inline_aux:NNn \ior_str_to:NN } +\cs_new_protected_nopar:Npn \ior_map_inline_aux:NNn + { + \exp_args:Nc \ior_map_inline_aux:NNNn + { ior_map_ \int_use:N \g_prg_map_int :n } + } +\cs_new_protected:Npn \ior_map_inline_aux:NNNn #1#2#3#4 + { + \cs_set:Npn #1 ##1 {#4} + \int_gincr:N \g_prg_map_int + \ior_if_eof:NF #3 { \ior_map_inline_loop:NNN #1#2#3 } + \prg_break_point:n { \int_gdecr:N \g_prg_map_int } + } +\cs_new_protected:Npn \ior_map_inline_loop:NNN #1#2#3 + { + #2 #3 \l_ior_internal_tl + \ior_if_eof:NF #3 + { + \exp_args:No #1 \l_ior_internal_tl + \ior_map_inline_loop:NNN #1#2#3 + } + } +\tl_new:N \l_ior_internal_tl +\msg_kernel_new:nnnn { file } { file-not-found } + { Space~in~file~name~'#1'. } + { + Spaces~are~not~permitted~in~files~loaded~by~LaTeX: \\ + Further~errors~may~follow! + } +\msg_kernel_new:nnnn { file } { space-in-file-name } + { Space~in~file~name~'#1'. } + { + Spaces~are~not~permitted~in~files~loaded~by~LaTeX: \\ + Further~errors~may~follow! } +\cs_new_protected:Npn \iow_now_when_avail:Nn #1 + { \cs_if_free:NTF #1 { \use_none:n } { \iow_now:Nn #1 } } +\cs_new_protected:Npn \iow_now_when_avail:Nx #1 + { \cs_if_free:NTF #1 { \use_none:n } { \iow_now:Nx #1 } } %% %% %% End of file `l3file.sty'. diff --git a/Master/texmf-dist/tex/latex/l3kernel/l3int.sty b/Master/texmf-dist/tex/latex/l3kernel/l3int.sty index 2747a0afeeb..f12cda36783 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 3315 2012-02-06 11:17:04Z bruno $ +\GetIdInfo$Id: l3int.dtx 3460 2012-02-26 12:16:41Z will $ {L3 Experimental integers} \ProvidesExplPackage {\ExplFileName}{\ExplFileDate}{\ExplFileVersion}{\ExplFileDescription} @@ -90,29 +90,25 @@ } \cs_new:Npn \int_div_truncate:nn #1#2 { - \int_value:w \int_eval:w - \if_int_compare:w \int_eval:w #1 = \c_zero - 0 - \else: - ( #1 % ) - \if_int_compare:w \int_eval:w #1 < \c_zero - \if_int_compare:w \int_eval:w #2 < \c_zero - - ( #2 + % ) - \else: - + ( #2 - % ) - \fi: - \else: - \if_int_compare:w \int_eval:w #2 < \c_zero - + ( #2 + % ) - \else: - - ( #2 - % ) - \fi: - \fi: % ( ( - 1 ) / 2 ) - \fi: - / ( #2 ) + \int_use:N \int_eval:w + \exp_after:wN \int_div_truncate_aux:NwNw + \int_use:N \int_eval:w #1 \exp_after:wN ; + \int_use:N \int_eval:w #2 ; \int_eval_end: } +\cs_new:Npn \int_div_truncate_aux:NwNw #1#2; #3#4; + { + \if_meaning:w 0 #1 + \c_zero + \else: + ( + #1#2 + \if_meaning:w - #1 + \else: - \fi: + ( \if_meaning:w - #3 - \fi: #3#4 - \c_one ) / \c_two + ) + \fi: + / #3#4 + } \cs_new:Npn \int_div_round:nn #1#2 { \int_eval:n { ( #1 ) / ( #2 ) } } \cs_new:Npn \int_mod:nn #1#2 { diff --git a/Master/texmf-dist/tex/latex/l3kernel/l3io.sty b/Master/texmf-dist/tex/latex/l3kernel/l3io.sty deleted file mode 100644 index 47f29f44e8a..00000000000 --- a/Master/texmf-dist/tex/latex/l3kernel/l3io.sty +++ /dev/null @@ -1,533 +0,0 @@ -%% -%% This is file `l3io.sty', -%% generated with the docstrip utility. -%% -%% The original source files were: -%% -%% l3io.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: l3io.dtx Copyright (C) 1990-2012 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 LaTeX3 Project. -%% -%% ----------------------------------------------------------------------- -\RequirePackage{l3names} -\GetIdInfo$Id: l3io.dtx 3245 2012-01-28 02:58:37Z bruno $ - {L3 Experimental input-output operations} -\ProvidesExplPackage - {\ExplFileName}{\ExplFileDate}{\ExplFileVersion}{\ExplFileDescription} -\package_check_loaded_expl: -\cs_new_eq:NN \if_eof:w \tex_ifeof:D -\cs_new_eq:NN \c_term_ior \c_sixteen -\cs_new_eq:NN \c_log_iow \c_minus_one -\cs_new_eq:NN \c_term_iow \c_sixteen -\tl_const:Nn \c_iow_streams_tl - { - \c_zero - \c_one - \c_two - \c_three - \c_four - \c_five - \c_six - \c_seven - \c_eight - \c_nine - \c_ten - \c_eleven - \c_twelve - \c_thirteen - \c_fourteen - \c_fifteen - } -\cs_new_eq:NN \c_ior_streams_tl \c_iow_streams_tl -\prop_new:N \g_iow_streams_prop -\prop_new:N \g_ior_streams_prop -\prop_put:Nnn \g_iow_streams_prop { 0 } { LaTeX2e~reserved } -\prop_put:Nnn \g_iow_streams_prop { 1 } { LaTeX2e~reserved } -\prop_put:Nnn \g_iow_streams_prop { 2 } { LaTeX2e~reserved } -\prop_put:Nnn \g_ior_streams_prop { 0 } { LaTeX2e~reserved } -\tl_new:N \l_ior_internal_tl -\tl_new:N \l_iow_internal_tl -\int_new:N \l_iow_stream_int -\cs_new_eq:NN \l_ior_stream_int \l_iow_stream_int -\cs_set_eq:NN \iow_raw_new:N \newwrite -\cs_set_eq:NN \ior_raw_new:N \newread -\cs_generate_variant:Nn \ior_raw_new:N { c } -\cs_generate_variant:Nn \iow_raw_new:N { c } -\cs_new_protected:Npn \ior_new:N #1 { \cs_new_eq:NN #1 \c_term_ior } -\cs_generate_variant:Nn \ior_new:N { c } -\cs_new_protected:Npn \iow_new:N #1 { \cs_new_eq:NN #1 \c_term_iow } -\cs_generate_variant:Nn \iow_new:N { c } -\cs_new_protected:Npn \ior_open:Nn #1#2 - { - \group_begin: - \tl_to_str_active_safe:Nx \l_ior_internal_tl {#2} - \tl_if_in:NnT \l_ior_internal_tl { ~ } - { - \msg_kernel_error:nnx { io } { space-in-file-name } - { \l_ior_internal_tl } - } - \exp_args:NNNo \group_end: - \ior_open_unsafe:Nn #1 \l_ior_internal_tl - } -\cs_generate_variant:Nn \ior_open:Nn { c } -\cs_new_protected:Npn \iow_open:Nn #1#2 - { - \group_begin: - \tl_to_str_active_safe:Nx \l_iow_internal_tl {#2} - \tl_if_in:NnT \l_iow_internal_tl { ~ } - { - \msg_kernel_error:nnx { io } { space-in-file-name } - { \l_iow_internal_tl } - } - \exp_args:NNNo \group_end: - \iow_open_unsafe:Nn #1 \l_iow_internal_tl - } -\cs_generate_variant:Nn \iow_open:Nn { c } -\cs_new_protected:Npn \ior_open_unsafe:Nn #1#2 - { - \ior_close:N #1 - \int_set:Nn \l_ior_stream_int \c_sixteen - \tl_map_function:NN \c_ior_streams_tl \ior_alloc_read:n - \int_compare:nNnTF \l_ior_stream_int = \c_sixteen - { \msg_kernel_fatal:nn { ior } { streams-exhausted } } - { - \ior_stream_alloc:N #1 - \prop_gput:NVn \g_ior_streams_prop \l_ior_stream_int {#2} - \tex_openin:D #1#2 \scan_stop: - } - } -\cs_new_protected:Npn \iow_open_unsafe:Nn #1#2 - { - \iow_close:N #1 - \int_set:Nn \l_iow_stream_int \c_sixteen - \tl_map_function:NN \c_iow_streams_tl \iow_alloc_write:n - \int_compare:nNnTF \l_iow_stream_int = \c_sixteen - { \msg_kernel_fatal:nn { iow } { streams-exhausted } } - { - \iow_stream_alloc:N #1 - \prop_gput:NVn \g_iow_streams_prop \l_iow_stream_int {#2} - \tex_immediate:D \tex_openout:D #1#2 \scan_stop: - } - } -\cs_new_protected:Npn \iow_alloc_write:n #1 - { - \prop_if_in:NnF \g_iow_streams_prop {#1} - { - \int_set:Nn \l_iow_stream_int {#1} - \tl_map_break: - } - } -\cs_new_protected:Npn \ior_alloc_read:n #1 - { - \prop_if_in:NnF \g_iow_streams_prop {#1} - { - \int_set:Nn \l_ior_stream_int {#1} - \tl_map_break: - } - } -\iow_new:N \g_iow_internal_iow -\ior_new:N \g_ior_internal_ior -\cs_new_protected:Npn \iow_stream_alloc:N #1 - { - \cs_if_exist:cTF { g_iow_ \int_use:N \l_iow_stream_int _iow } - { \cs_gset_eq:Nc #1 { g_iow_ \int_use:N \l_iow_stream_int _iow } } - { - \iow_stream_alloc_aux: - \int_compare:nNnT \l_iow_stream_int = \c_sixteen - { - \iow_raw_new:N \g_iow_internal_iow - \int_set:Nn \l_iow_stream_int { \g_iow_internal_iow } - \cs_gset_eq:cN - { g_iow_ \int_use:N \l_iow_stream_int _iow } \g_iow_internal_iow - } - \cs_gset_eq:Nc #1 { g_iow_ \int_use:N \l_iow_stream_int _iow } - } - } -\cs_new_protected_nopar:Npn \iow_stream_alloc_aux: - { - \int_incr:N \l_iow_stream_int - \int_compare:nNnT \l_iow_stream_int < \c_sixteen - { - \cs_if_exist:cTF { g_iow_ \int_use:N \l_iow_stream_int _iow } - { - \prop_if_in:NVT \g_iow_streams_prop \l_iow_stream_int - { \iow_stream_alloc_aux: } - } - { \iow_stream_alloc_aux: } - } - } -\cs_new_protected:Npn \ior_stream_alloc:N #1 - { - \cs_if_exist:cTF { g_ior_ \int_use:N \l_ior_stream_int _ior } - { \cs_gset_eq:Nc #1 { g_ior_ \int_use:N \l_ior_stream_int _ior } } - { - \ior_stream_alloc_aux: - \int_compare:nNnT \l_ior_stream_int = \c_sixteen - { - \ior_raw_new:N \g_ior_internal_ior - \int_set:Nn \l_ior_stream_int { \g_ior_internal_ior } - \cs_gset_eq:cN - { g_ior_ \int_use:N \l_iow_stream_int _ior } \g_ior_internal_ior - } - \cs_gset_eq:Nc #1 { g_ior_ \int_use:N \l_ior_stream_int _ior } - } - } -\cs_new_protected_nopar:Npn \ior_stream_alloc_aux: - { - \int_incr:N \l_ior_stream_int - \int_compare:nNnT \l_ior_stream_int < \c_sixteen - { - \cs_if_exist:cTF { g_ior_ \int_use:N \l_ior_stream_int _ior } - { - \prop_if_in:NVT \g_ior_streams_prop \l_ior_stream_int - { \ior_stream_alloc_aux: } - } - { \ior_stream_alloc_aux: } - } - } -\cs_new_protected:Npn \ior_close:N #1 - { - \cs_if_exist:NT #1 - { - \int_compare:nNnF #1 = \c_minus_one - { - \int_compare:nNnF #1 = \c_sixteen - { \tex_closein:D #1 } - \prop_gdel:NV \g_ior_streams_prop #1 - \cs_gset_eq:NN #1 \c_term_ior - } - } - } -\cs_new_protected:Npn \iow_close:N #1 - { - \cs_if_exist:NT #1 - { - \int_compare:nNnF #1 = \c_minus_one - { - \int_compare:nNnF #1 = \c_sixteen - { \tex_closein:D #1 } - \prop_gdel:NV \g_iow_streams_prop #1 - \cs_gset_eq:NN #1 \c_term_iow - } - } - } -\cs_generate_variant:Nn \ior_close:N { c } -\cs_generate_variant:Nn \iow_close:N { c } -\cs_new_protected_nopar:Npn \ior_list_streams: - { \ior_list_streams_aux:Nn \g_ior_streams_prop { ior } } -\cs_new_protected_nopar:Npn \iow_list_streams: - { \ior_list_streams_aux:Nn \g_iow_streams_prop { iow } } -\cs_new_protected:Npn \ior_list_streams_aux:Nn #1#2 - { - \msg_aux_use:nn { LaTeX / #2 } - { \prop_if_empty:NTF #1 { show-no-stream } { show-open-streams } } - \msg_aux_show:x - { \prop_map_function:NN #1 \msg_aux_show_unbraced:nn } - } -\msg_kernel_new:nnnn { iow } { streams-exhausted } - { Output~streams~exhausted } - { - TeX~can~only~open~up~to~16~output~streams~at~one~time.\\ - All~16 are currently~in~use,~and~something~wanted~to~open - another~one. - } -\msg_kernel_new:nnnn { ior } { streams-exhausted } - { Input~streams~exhausted } - { - TeX~can~only~open~up~to~16~input~streams~at~one~time.\\ - All~16 are currently~in~use,~and~something~wanted~to~open - another~one. - } -\cs_new_eq:NN \iow_shipout_x:Nn \tex_write:D -\cs_generate_variant:Nn \iow_shipout_x:Nn { Nx } -\cs_new_protected:Npn \iow_shipout:Nn #1#2 - { \iow_shipout_x:Nn #1 { \exp_not:n {#2} } } -\cs_generate_variant:Nn \iow_shipout:Nn { Nx } -\cs_new_protected_nopar:Npn \iow_now:Nx { \tex_immediate:D \iow_shipout_x:Nn } -\cs_new_protected:Npn \iow_now:Nn #1#2 - { \iow_now:Nx #1 { \exp_not:n {#2} } } -\cs_set_protected_nopar:Npn \iow_log:x { \iow_now:Nx \c_log_iow } -\cs_new_protected_nopar:Npn \iow_log:n { \iow_now:Nn \c_log_iow } -\cs_set_protected_nopar:Npn \iow_term:x { \iow_now:Nx \c_term_iow } -\cs_new_protected_nopar:Npn \iow_term:n { \iow_now:Nn \c_term_iow } -\cs_new_protected:Npn \iow_now_when_avail:Nn #1 - { \cs_if_free:NTF #1 { \use_none:n } { \iow_now:Nn #1 } } -\cs_new_protected:Npn \iow_now_when_avail:Nx #1 - { \cs_if_free:NTF #1 { \use_none:n } { \iow_now:Nx #1 } } -\cs_new_nopar:Npn \iow_newline: { ^^J } -\cs_new_eq:NN \iow_char:N \cs_to_str:N -\int_new:N \l_iow_line_length_int -\int_set:Nn \l_iow_line_length_int { 78 } -\int_new:N \l_iow_target_length_int -\int_new:N \l_iow_current_line_int -\int_new:N \l_iow_current_word_int -\int_new:N \l_iow_current_indentation_int -\tl_new:N \l_iow_current_line_tl -\tl_new:N \l_iow_current_word_tl -\tl_new:N \l_iow_current_indentation_tl -\tl_new:N \l_iow_wrap_tl -\tl_new:N \l_iow_wrapped_tl -\bool_new:N \l_iow_line_start_bool -\group_begin: - \char_set_catcode_other:N \* - \char_set_lccode:nn {`\*} {`\ } - \tl_to_lowercase:n { \tl_const:Nn \c_catcode_other_space_tl { * } } -\group_end: -\group_begin: - \int_set_eq:NN \tex_escapechar:D \c_minus_one - \tl_const:Nx \c_iow_wrap_marker_tl - { \tl_to_str:n { \^^I \^^O \^^W \^^_ \^^W \^^R \^^A \^^P } } - \cs_set:Npn \iow_wrap_new_marker:n #1 - { - \tl_const:cx { c_iow_wrap_ #1 _marker_tl } - { - \c_catcode_other_space_tl - \c_iow_wrap_marker_tl - \c_catcode_other_space_tl - #1 - \c_catcode_other_space_tl - } - } - \iow_wrap_new_marker:n { end } - \iow_wrap_new_marker:n { newline } - \iow_wrap_new_marker:n { indent } - \iow_wrap_new_marker:n { unindent } -\group_end: -\cs_new_protected:Npn \iow_indent:n #1 { } -\cs_new:Npx \iow_indent_expandable:n #1 - { - \c_iow_wrap_indent_marker_tl - #1 - \c_iow_wrap_unindent_marker_tl - } -\cs_new_protected:Npn \iow_wrap:xnnnN #1#2#3#4#5 - { - \group_begin: - \int_set:Nn \l_iow_target_length_int { \l_iow_line_length_int - ( #3 ) } - \int_zero:N \l_iow_current_indentation_int - \tl_clear:N \l_iow_current_indentation_tl - \int_zero:N \l_iow_current_line_int - \tl_clear:N \l_iow_current_line_tl - \tl_clear:N \l_iow_wrap_tl - \bool_set_true:N \l_iow_line_start_bool - \int_set_eq:NN \tex_escapechar:D \c_minus_one - \cs_set_nopar:Npx \{ { \token_to_str:N \{ } - \cs_set_nopar:Npx \# { \token_to_str:N \# } - \cs_set_nopar:Npx \} { \token_to_str:N \} } - \cs_set_nopar:Npx \% { \token_to_str:N \% } - \cs_set_nopar:Npx \~ { \token_to_str:N \~ } - \int_set:Nn \tex_escapechar:D { 92 } - \cs_set_eq:NN \\ \c_iow_wrap_newline_marker_tl - \cs_set_eq:NN \ \c_catcode_other_space_tl - \cs_set_eq:NN \iow_indent:n \iow_indent_expandable:n - #4 - \protected@edef \l_iow_wrap_tl {#1} - \cs_set:Npn \\ { \iow_newline: #2 } - \use:x - { - \iow_wrap_loop:w - \tl_to_str:N \l_iow_wrap_tl - \tl_to_str:N \c_iow_wrap_end_marker_tl - \c_space_tl \c_space_tl - \exp_not:N \q_stop - } - \exp_args:NNo \group_end: - #5 \l_iow_wrapped_tl - } -\cs_new_protected:Npn \iow_wrap_loop:w #1 ~ % - { - \tl_set:Nn \l_iow_current_word_tl {#1} - \tl_if_eq:NNTF \l_iow_current_word_tl \c_iow_wrap_marker_tl - { \iow_wrap_special:w } - { \iow_wrap_word: } - } -\cs_new_protected_nopar:Npn \iow_wrap_word: - { - \int_set:Nn \l_iow_current_word_int - { \str_length_skip_spaces:N \l_iow_current_word_tl } - \int_add:Nn \l_iow_current_line_int { \l_iow_current_word_int } - \int_compare:nNnTF \l_iow_current_line_int < \l_iow_target_length_int - { \iow_wrap_word_fits: } - { \iow_wrap_word_newline: } - \iow_wrap_loop:w - } -\cs_new_protected_nopar:Npn \iow_wrap_word_fits: - { - \bool_if:NTF \l_iow_line_start_bool - { - \bool_set_false:N \l_iow_line_start_bool - \tl_put_right:Nx \l_iow_current_line_tl - { \l_iow_current_indentation_tl \l_iow_current_word_tl } - \int_add:Nn \l_iow_current_line_int - { \l_iow_current_indentation_int } - } - { - \tl_put_right:Nx \l_iow_current_line_tl - { ~ \l_iow_current_word_tl } - \int_incr:N \l_iow_current_line_int - } - } -\cs_new_protected_nopar:Npn \iow_wrap_word_newline: - { - \tl_put_right:Nx \l_iow_wrapped_tl - { \l_iow_current_line_tl \\ } - \int_set:Nn \l_iow_current_line_int - { - \l_iow_current_word_int - + \l_iow_current_indentation_int - } - \tl_set:Nx \l_iow_current_line_tl - { \l_iow_current_indentation_tl \l_iow_current_word_tl } - } -\cs_new_protected:Npn \iow_wrap_special:w #1 ~ #2 ~ #3 ~ % - { - \use:c { iow_wrap_#1: } - \str_if_eq:xxTF { #2~#3 } { ~ \c_iow_wrap_marker_tl } - { \iow_wrap_special:w } - { \iow_wrap_loop:w #2 ~ #3 ~ } - } -\cs_new_protected_nopar:Npn \iow_wrap_newline: - { - \tl_put_right:Nx \l_iow_wrapped_tl - { \l_iow_current_line_tl \\ } - \int_zero:N \l_iow_current_line_int - \tl_clear:N \l_iow_current_line_tl - \bool_set_true:N \l_iow_line_start_bool - } -\cs_new_protected_nopar:Npx \iow_wrap_indent: - { - \int_add:Nn \l_iow_current_indentation_int \c_four - \tl_put_right:Nx \exp_not:N \l_iow_current_indentation_tl - { \c_space_tl \c_space_tl \c_space_tl \c_space_tl } - } -\cs_new_protected_nopar:Npn \iow_wrap_unindent: - { - \int_sub:Nn \l_iow_current_indentation_int \c_four - \tl_set:Nx \l_iow_current_indentation_tl - { \prg_replicate:nn \l_iow_current_indentation_int { ~ } } - } -\cs_new_protected_nopar:Npn \iow_wrap_end: - { - \tl_put_right:Nx \l_iow_wrapped_tl - { \l_iow_current_line_tl } - \use_none_delimit_by_q_stop:w - } -\cs_new_nopar:Npn \str_length_skip_spaces:N - { \exp_args:No \str_length_skip_spaces:n } -\cs_new:Npn \str_length_skip_spaces:n #1 - { - \int_value:w \int_eval:w - \exp_after:wN \str_length_loop:NNNNNNNNN \tl_to_str:n {#1} - {X8}{X7}{X6}{X5}{X4}{X3}{X2}{X1}{X0} \q_stop - \int_eval_end: - } -\cs_new:Npn \str_length_loop:NNNNNNNNN #1#2#3#4#5#6#7#8#9 - { - \if_catcode:w X #9 - \exp_after:wN \use_none_delimit_by_q_stop:w - \else: - 9 + - \exp_after:wN \str_length_loop:NNNNNNNNN - \fi: - } -\prg_new_conditional:Nnn \ior_if_eof:N { p , T , F , TF } - { - \cs_if_exist:NTF #1 - { - \if_int_compare:w #1 = \c_sixteen - \prg_return_true: - \else: - \if_eof:w #1 - \prg_return_true: - \else: - \prg_return_false: - \fi: - \fi: - } - { \prg_return_true: } - } -\cs_new_protected:Npn \ior_to:NN #1#2 - { \tex_read:D #1 to #2 } -\cs_new_protected:Npn \ior_gto:NN #1#2 - { \tex_global:D \tex_read:D #1 to #2 } -\cs_new_protected:Npn \ior_str_to:NN #1#2 - { \etex_readline:D #1 to #2 } -\cs_new_protected:Npn \ior_str_gto:NN #1#2 - { \tex_global:D \etex_readline:D #1 to #2 } -\cs_new_protected_nopar:Npn \ior_map_inline:nn - { \ior_map_inline_aux:Nnn \ior_to:NN } -\cs_new_protected_nopar:Npn \ior_str_map_inline:nn - { \ior_map_inline_aux:Nnn \ior_str_to:NN } -\cs_new_protected_nopar:Npn \ior_map_inline_aux:Nnn - { - \exp_args:Ncc \ior_map_inline_aux:NNNnn - { g_ior_map_ \int_use:N \g_prg_map_int _ior } - { ior_map_ \int_use:N \g_prg_map_int :n } - } -\cs_new_protected:Npn \ior_map_inline_aux:NNNnn #1#2#3#4#5 - { - \cs_if_exist:NF #1 { \ior_new:N #1 } - \cs_set:Npn #2 ##1 {#5} - \ior_open:Nn #1 {#4} - \int_gincr:N \g_prg_map_int - \ior_if_eof:NF #1 { \ior_map_inline_loop:NNN #1#2#3 } - \prg_break_point:n - { - \int_gdecr:N \g_prg_map_int - \ior_close:N #1 - } - } -\cs_new_protected:Npn \ior_map_inline_loop:NNN #1#2#3 - { - #3 #1 \l_ior_internal_tl - \ior_if_eof:NF #1 - { - \exp_args:No #2 \l_ior_internal_tl - \ior_map_inline_loop:NNN #1#2#3 - } - } -\msg_kernel_new:nnnn { io } { space-in-file-name } - { Space~in~file~name~'#1'. } - { - Spaces~are~not~permitted~in~files~loaded~by~LaTeX: \\ - Further~errors~may~follow! - } -%% -%% -%% End of file `l3io.sty'. diff --git a/Master/texmf-dist/tex/latex/l3kernel/l3luatex.sty b/Master/texmf-dist/tex/latex/l3kernel/l3luatex.sty index 9643cba784c..7655ba4ae08 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 3158 2012-01-09 00:47:42Z bruno $ +\GetIdInfo$Id: l3luatex.dtx 3355 2012-02-09 07:18:22Z joseph $ {L3 Experimental LuaTeX-specific functions} \ProvidesExplPackage {\ExplFileName}{\ExplFileDate}{\ExplFileVersion}{\ExplFileDescription} @@ -94,7 +94,7 @@ \tex_global:D \tex_chardef:D #1 \g_cctab_allocate_int \luatex_initcatcodetable:D #1 } - { \msg_kernel_fatal:nnx { alloc } { out-of-registers } { cctab } } + { \msg_kernel_fatal:nnx { kernel } { out-of-registers } { cctab } } } \luatex_if_engine:F { diff --git a/Master/texmf-dist/tex/latex/l3kernel/l3msg.sty b/Master/texmf-dist/tex/latex/l3kernel/l3msg.sty index 1531c7a39b1..af40a84ac92 100644 --- a/Master/texmf-dist/tex/latex/l3kernel/l3msg.sty +++ b/Master/texmf-dist/tex/latex/l3kernel/l3msg.sty @@ -46,7 +46,7 @@ %% %% ----------------------------------------------------------------------- \RequirePackage{l3names} -\GetIdInfo$Id: l3msg.dtx 3316 2012-02-06 12:24:43Z bruno $ +\GetIdInfo$Id: l3msg.dtx 3470 2012-02-26 19:10:24Z bruno $ {L3 Experimental messages} \ProvidesExplPackage {\ExplFileName}{\ExplFileDate}{\ExplFileVersion}{\ExplFileDescription} @@ -54,13 +54,28 @@ \tl_new:N \l_msg_internal_tl \tl_const:Nn \c_msg_text_prefix_tl { msg~text~>~ } \tl_const:Nn \c_msg_more_text_prefix_tl { msg~extra~text~>~ } -\cs_new_protected:Npn \msg_new:nnnn #1#2 +\cs_new_protected:Npn \chk_if_free_msg:nn #1#2 { - \cs_if_exist:cT { \c_msg_text_prefix_tl #1 / #2 } + \cs_if_free:cF { \c_msg_text_prefix_tl #1 / #2 } { \msg_kernel_error:nnxx { msg } { message-already-defined } {#1} {#2} } + } +\tex_ifodd:D \l@expl@log@functions@bool + \cs_gset_protected:Npn \chk_if_free_msg:nn #1#2 + { + \cs_if_free:cF { \c_msg_text_prefix_tl #1 / #2 } + { + \msg_kernel_error:nnxx { msg } { message-already-defined } + {#1} {#2} + } + \iow_log:x { Defining~message~#1/#2~ \msg_line_context: } + } +\fi: +\cs_new_protected:Npn \msg_new:nnnn #1#2 + { + \chk_if_free_msg:nn {#1} {#2} \msg_gset:nnnn {#1} {#2} } \cs_new_protected:Npn \msg_new:nnn #1#2#3 @@ -534,6 +549,13 @@ LaTeX~has~been~asked~to~use~a~command~#1,~but~this~has~not~ been~defined~yet. } +\msg_kernel_new:nnnn { kernel } { out-of-registers } + { No~room~for~a~new~#1. } + { + TeX~only~supports~\int_use:N \c_max_register_int \ + of~each~type.~All~the~#1~registers~have~been~used.~ + This~run~will~be~aborted~now. + } \msg_kernel_new:nnnn { kernel } { variable-not-defined } { Variable~#1~undefined. } { diff --git a/Master/texmf-dist/tex/latex/l3kernel/l3prg.sty b/Master/texmf-dist/tex/latex/l3kernel/l3prg.sty index 8c3e0e70b3f..4fc7acdcdbb 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 3338 2012-02-08 08:21:42Z joseph $ +\GetIdInfo$Id: l3prg.dtx 3464 2012-02-26 15:30:29Z bruno $ {L3 Experimental control structures} %% \ProvidesExplPackage @@ -94,6 +94,22 @@ \cs_generate_variant:Nn \bool_if:NT { c } \cs_generate_variant:Nn \bool_if:NF { c } \cs_generate_variant:Nn \bool_if:NTF { c } +\cs_new_protected:Npn \bool_show:N #1 + { + \cs_if_exist:NTF #1 + { \bool_show:n {#1} } + { + \msg_kernel_error:nnx { kernel } { variable-not-defined } + { \token_to_str:N #1 } + } + } +\cs_new_protected:Npn \bool_show:n #1 + { + \bool_if:nTF {#1} + { \msg_aux_show:x { > true } } + { \msg_aux_show:x { > false } } + } +\cs_generate_variant:Nn \bool_show:N { c } \bool_new:N \l_tmpa_bool \bool_new:N \g_tmpa_bool \prg_new_conditional:Npnn \bool_if:n #1 { T , F , TF } diff --git a/Master/texmf-dist/tex/latex/l3kernel/l3prop.sty b/Master/texmf-dist/tex/latex/l3kernel/l3prop.sty index c58cff46737..169d5ffe5d6 100644 --- a/Master/texmf-dist/tex/latex/l3kernel/l3prop.sty +++ b/Master/texmf-dist/tex/latex/l3kernel/l3prop.sty @@ -46,7 +46,7 @@ %% %% ----------------------------------------------------------------------- \RequirePackage{l3names} -\GetIdInfo$Id: l3prop.dtx 3158 2012-01-09 00:47:42Z bruno $ +\GetIdInfo$Id: l3prop.dtx 3460 2012-02-26 12:16:41Z will $ {L3 Experimental property lists} %% \ProvidesExplPackage diff --git a/Master/texmf-dist/tex/latex/l3kernel/l3quark.sty b/Master/texmf-dist/tex/latex/l3kernel/l3quark.sty index 344873f2405..e22e215617a 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 3148 2012-01-08 15:42:18Z bruno $ +\GetIdInfo$Id: l3quark.dtx 3384 2012-02-12 13:13:11Z will $ {L3 Experimental quarks} \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 8fdb538a031..5ba6dec68d7 100644 --- a/Master/texmf-dist/tex/latex/l3kernel/l3skip.sty +++ b/Master/texmf-dist/tex/latex/l3kernel/l3skip.sty @@ -47,7 +47,7 @@ %% %% ----------------------------------------------------------------------- \RequirePackage{l3names} -\GetIdInfo$Id: l3skip.dtx 3313 2012-02-06 11:15:21Z bruno $ +\GetIdInfo$Id: l3skip.dtx 3460 2012-02-26 12:16:41Z will $ {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 95b2d84cd8a..59e810e8aa5 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 3316 2012-02-06 12:24:43Z bruno $ +\GetIdInfo$Id: l3tl.dtx 3460 2012-02-26 12:16:41Z will $ {L3 Experimental token lists} \ProvidesExplPackage {\ExplFileName}{\ExplFileDate}{\ExplFileVersion}{\ExplFileDescription} @@ -486,7 +486,9 @@ \cs_new:Npn \tl_tail:n #1 { \etex_unexpanded:D \tl_tail_aux:w #1 \q_mark { } \q_mark \q_stop } \cs_new:Npn \tl_tail_aux:w #1 #2 \q_mark #3 \q_stop { {#2} } +\cs_new_nopar:Npn \tl_head:N { \exp_args:No \tl_head:n } \cs_generate_variant:Nn \tl_head:n { V , v , f } +\cs_new_nopar:Npn \tl_tail:N { \exp_args:No \tl_tail:n } \cs_generate_variant:Nn \tl_tail:n { V , v , f } \cs_new:Npn \str_head:n #1 { @@ -602,18 +604,6 @@ { \exp_after:wN \c_zero \exp_after:wN \prg_return_false: } \exp_after:wN \use_none:n \exp_after:wN { \if_false: } \fi: } -\cs_new_protected:Npn \tl_to_str_active_safe:Nx #1#2 - { - \group_begin: - \seq_map_inline:Nn \l_char_active_seq - { \cs_set_nopar:Npx ##1 { \token_to_str:N ##1 } } - \use:x - { - \group_end: - \tl_set:Nn \exp_not:N #1 {#2} - } - \tl_set:Nx #1 { \tl_to_str:N #1 } - } \cs_new_protected:Npn \tl_show:N #1 { \cs_show:N #1 } \cs_generate_variant:Nn \tl_show:N { c } \cs_new_eq:NN \tl_show:n \etex_showtokens:D diff --git a/Master/texmf-dist/tex/latex/l3kernel/l3token.sty b/Master/texmf-dist/tex/latex/l3kernel/l3token.sty index 3bab1bd32dd..04531db0274 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 3316 2012-02-06 12:24:43Z bruno $ +\GetIdInfo$Id: l3token.dtx 3460 2012-02-26 12:16:41Z will $ {L3 Experimental token manipulation} \ProvidesExplPackage {\ExplFileName}{\ExplFileDate}{\ExplFileVersion}{\ExplFileDescription} @@ -181,7 +181,7 @@ \seq_set_from_clist:Nn \l_char_active_seq } } - { { " , $ , & , ^ , _ , ~ } } + { { " , $ , & , ^ , _ , ~ } } %$ \seq_new:N \l_char_special_seq \seq_set_from_clist:Nn \l_char_special_seq { \ , \" , \# , \$ , \% , \& , \\ , \^ , \_ , \{ , \} , \~ } @@ -367,6 +367,24 @@ % } } \cs_new:Npn \token_if_int_register_aux:w #1 COUXY #2 \q_stop { #1 ~ } + \prg_new_conditional:Npnn \token_if_muskip_register:N #1 { p , T , F , TF } + { + \if_meaning:w \tex_muskip:D #1 + \prg_return_false: + \else: + \if_meaning:w \tex_muskipdef:D #1 + \prg_return_false: + \else: + \str_if_eq_return:xx + { + \exp_after:wN \token_if_muskip_register_aux:w + \token_to_meaning:N #1 MUSKIP \q_stop + } + { \token_to_str:N \ } + \fi: + \fi: + } + \cs_new:Npn \token_if_muskip_register_aux:w #1 MUSKIP #2 \q_stop { #1 ~ } \prg_new_conditional:Npnn \token_if_skip_register:N #1 { p , T , F , TF } { \if_meaning:w \tex_skip:D #1 |