diff options
author | Karl Berry <karl@freefriends.org> | 2012-02-07 22:41:58 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2012-02-07 22:41:58 +0000 |
commit | 7dd80542eb368ed18c1298c24250b409350a2059 (patch) | |
tree | b2e1a4782f380070ebda613cbdbd81bf6da4bd7e /Master/texmf-dist/source/latex/l3experimental | |
parent | 31c0645d94c7626cab0b433b855f6c2a6893f133 (diff) |
l3experimental 3331 (7feb12)
git-svn-id: svn://tug.org/texlive/trunk@25328 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/source/latex/l3experimental')
8 files changed, 1733 insertions, 36 deletions
diff --git a/Master/texmf-dist/source/latex/l3experimental/l3sort/l3sort.dtx b/Master/texmf-dist/source/latex/l3experimental/l3sort/l3sort.dtx new file mode 100644 index 00000000000..65a95dbee29 --- /dev/null +++ b/Master/texmf-dist/source/latex/l3experimental/l3sort/l3sort.dtx @@ -0,0 +1,572 @@ +% \iffalse +% +%% File l3sort.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 "l3experimental bundle" (The Work in LPPL) +%% and all files in that bundle must be distributed together. +%% +%% The released version of this bundle is available from CTAN. +%% +%% ----------------------------------------------------------------------- +%% +%% The development version of the bundle can be found at +%% +%% http://www.latex-project.org/svnroot/experimental/trunk/ +%% +%% for those people who are interested. +%% +%%%%%%%%%%% +%% NOTE: %% +%%%%%%%%%%% +%% +%% Snapshots taken from the repository represent work in progress and may +%% not work or may contain conflicting material! We therefore ask +%% people _not_ to put them into distributions, archives, etc. without +%% prior consultation with the LaTeX Project Team. +%% +%% ----------------------------------------------------------------------- +%% +% +%<*driver|package> +\RequirePackage{expl3} +\GetIdInfo$Id: l3sort.dtx 3295 2012-02-02 09:30:14Z joseph $ + {L3 Experimental sorting functions} +%</driver|package> +%<*driver> +\documentclass[full]{l3doc} +\usepackage{amsmath} +\begin{document} + \DocInput{\jobname.dtx} +\end{document} +%</driver> +% \fi +% +% \title{^^A +% The \pkg{l3sort} package\\ Sorting lists^^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{l3sort} documentation} +% +% \LaTeX3 comes with a function to sort list variables (sequences, +% token lists, or comma-lists) according to some user-defined +% comparison. For instance, +% \begin{verbatim} +% \clist_set:Nn \l_foo_clist { 3 , 01 , -2 , 5 , +1 } +% \clist_sort:Nn \l_foo_clist +% { +% \int_compare:nNnTF { #1 } > { #2 } +% { \sort_reversed: } +% { \sort_ordered: } +% } +% \end{verbatim} +% will result in \cs{l_foo_clist} holding the values +% |{ -2 , 01 , +1 , 3 , 5 }| sorted in non-decreasing order. +% +% The code defining the comparison should perform +% \cs{sort_reversed:} if the two items given as |#1| +% and |#2| are not in the correct order, and otherwise it +% should call \cs{sort_ordered:} to indicate that +% the order of this pair of items should not be changed. +% +% For instance, a \meta{comparison code} consisting only +% of \cs{sort_ordered:} with no test will yield a trivial +% sort: the final order is identical to the original order. +% Conversely, using a \meta{comparison code} consisting only +% of \cs{sort_reversed:} will reverse the list (in a fairly +% inefficient way). +% +% \begin{texnote} +% Internally, the code from \pkg{l3sort} stores items in \tn{toks}. +% Thus, the \meta{comparison code} should not alter the +% contents of any \tn{toks}, nor assume that they hold a +% given value. +% \end{texnote} +% +% \begin{function}{\seq_sort:Nn, \seq_gsort:Nn} +% \begin{syntax} +% \cs{seq_sort:Nn} \meta{sequence} \Arg{comparison code} +% \end{syntax} +% Sorts the items in the \meta{sequence} according to the +% \meta{comparison code}, and assigns the result to +% \meta{sequence}. +% \end{function} +% +% \begin{function}{\tl_sort:Nn, \tl_gsort:Nn} +% \begin{syntax} +% \cs{tl_sort:Nn} \meta{tl var} \Arg{comparison code} +% \end{syntax} +% Sorts the items in the \meta{tl var} according to the +% \meta{comparison code}, and assigns the result to +% \meta{tl var}. +% \end{function} +% +% \begin{function}{\clist_sort:Nn, \clist_gsort:Nn} +% \begin{syntax} +% \cs{clist_sort:Nn} \meta{clist var} \Arg{comparison code} +% \end{syntax} +% Sorts the items in the \meta{clist var} according to the +% \meta{comparison code}, and assigns the result to +% \meta{clist var}. +% \end{function} +% +% \end{documentation} +% +% \begin{implementation} +% +% \section{\pkg{l3sort} 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}{\c_sort_max_length_int} +% The maximum length of a sequence which will not overflow +% the available registers depends on which engine is in use. +% For $2^{N}$ registers, it is $3\cdot 2^{N-2}$: for that number +% of items, at the last step the block size will be $2^{N-1}$, +% and the two blocks to merge will be of sizes $2^{N-1}$ and +% $2^{N-2}$ respectively. When merging, one of the blocks must +% be copied to temporary registers; here, the smallest block, +% of size $2^{N-2}$, will fill up exactly the $2^{N-2}$ free +% registers, totalling $2^{N-1}+2^{N-2}+2^{N-2}=2^{N}$ registers. +% \begin{macrocode} +\int_const:Nn \c_sort_max_length_int + { \luatex_if_engine:TF { 49152 } { 24576 } } +% \end{macrocode} +% \end{variable} +% +% \begin{variable}{\l_sort_length_int} +% Length of the sequence which is being sorted. +% \begin{macrocode} +\int_new:N \l_sort_length_int +% \end{macrocode} +% \end{variable} +% +% \begin{variable}{\l_sort_block_int} +% Merge sort is done in several passes. In each pass, blocks of size +% \cs{l_sort_block_int} are merged in pairs. The block size starts +% at $1$, and, for a length in the range $[2^k+1,2^{k+1}]$, reaches +% $2^{k}$ in the last pass. +% \begin{macrocode} +\int_new:N \l_sort_block_int +% \end{macrocode} +% \end{variable} +% +% \begin{variable}{\l_sort_begin_int} +% \begin{variable}{\l_sort_end_int} +% When merging two blocks, \cs{l_sort_begin_int} marks the lowest +% index in the two blocks, and \cs{l_sort_end_int} marks the +% highest index, plus $1$. +% \begin{macrocode} +\int_new:N \l_sort_begin_int +\int_new:N \l_sort_end_int +% \end{macrocode} +% \end{variable} +% \end{variable} +% +% \begin{variable}{\l_sort_A_int} +% \begin{variable}{\l_sort_B_int} +% \begin{variable}{\l_sort_C_int} +% When merging two blocks (whose end-points are \texttt{beg} +% and \texttt{end}), $A$ starts from the high end of the low +% block, and decreases until reaching \texttt{beg}. The index +% $B$ starts from the top of the range and marks the register +% in which a sorted item should be put. Finally, $C$ points +% to the copy of the high block in the interval of registers +% starting at \cs{l_sort_length_int}, upwards. $C$ starts +% from the upper limit of that range. +% \begin{macrocode} +\int_new:N \l_sort_A_int +\int_new:N \l_sort_B_int +\int_new:N \l_sort_C_int +% \end{macrocode} +% \end{variable} +% \end{variable} +% \end{variable} +% +% \subsection{User commands} +% +% \begin{macro}[int]{\sort_aux:NNnNn} +% Sorting happens in three steps. First store items +% in \tn{toks} registers ranging from $0$ to the length +% of the list, while checking that the list is not too +% long. If we reach the maximum length, all further +% items are entirely ignored after raising an error. +% Secondly, sort the array of \tn{toks} registers, +% using the user-defined sorting function, |#5|. +% Finally, unpack the \tn{toks} registers (now sorted) +% into a variable of the right type, by \texttt{x}-expanding +% the code in |#3|, specific to each type of list. +% \begin{macrocode} +\cs_new_protected:Npn \sort_aux:NNnNn #1#2#3#4#5 + { + \group_begin: + \l_sort_length_int \c_zero + #2 #4 + { + \if_num:w \l_sort_length_int = \c_sort_max_length_int + \sort_too_long_error:Nw #4 + \fi: + \tex_toks:D \l_sort_length_int {##1} + \tex_advance:D \l_sort_length_int \c_one + } + \cs_set:Npn \sort_compare:nn ##1 ##2 { #5 } + \l_sort_block_int \c_one + \sort_level: + \use:x + { + \group_end: + #1 \exp_not:N #4 {#3} + } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\seq_sort:Nn, \seq_gsort:Nn} +% The first argument to \cs{sort_aux:NNnNn} is the final +% assignment function used, either \cs{tl_set:Nn} or +% \cs{tl_gset:Nn} to control local versus global results. +% The second argument is what mapping function is used +% when storing items to \tn{toks} registers. The third +% is used to build back the correct kind of list from the +% contents of the \tn{toks} registers. Fourth and fifth +% arguments are the variable to sort, and the sorting method +% as inline code. +% \begin{macrocode} +\cs_new_protected_nopar:Npn \seq_sort:Nn + { + \sort_aux:NNnNn \tl_set:Nn + \seq_map_inline:Nn + { \sort_toks:NNw \exp_not:N \seq_item:n 0 ; } + } +\cs_new_protected_nopar:Npn \seq_gsort:Nn + { + \sort_aux:NNnNn \tl_gset:Nn + \seq_map_inline:Nn + { \sort_toks:NNw \exp_not:N \seq_item:n 0 ; } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\tl_sort:Nn, \tl_gsort:Nn} +% Again, use \cs{tl_set:Nn} or \cs{tl_gset:Nn} to control +% the scope of the assignment. Mapping through the token +% list is done with \cs{tl_map_inline:Nn}, and producing +% the token list is very similar to sequences, removing +% \cs{seq_item:Nn}. +% \begin{macrocode} +\cs_new_protected_nopar:Npn \tl_sort:Nn + { + \sort_aux:NNnNn \tl_set:Nn + \tl_map_inline:Nn + { \sort_toks:NNw \prg_do_nothing: \prg_do_nothing: 0 ; } + } +\cs_new_protected_nopar:Npn \tl_gsort:Nn + { + \sort_aux:NNnNn \tl_gset:Nn + \tl_map_inline:Nn + { \sort_toks:NNw \prg_do_nothing: \prg_do_nothing: 0 ; } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\clist_sort:Nn, \clist_gsort:Nn} +% \begin{macro}[aux]{\clist_sort_aux:NNn} +% The case of empty comma-lists is a little bit special as usual, +% and filtered out: there is nothing to sort in that case. +% Otherwise, the input is done with \cs{clist_map_inline:Nn}, +% and the output requires some more elaborate processing than +% for sequences and token lists. The first comma must be removed. +% An item must be wrapped in an extra set of braces if it contains +% either the space or the comma characters. This is taken care of +% by \cs{clist_wrap_item:n}, but \cs{sort_toks:NNw} would simply +% feed \cs{tex_the:D} \cs{tex_toks:D} \meta{number} as an +% argument to that function; hence we need to expand this argument +% once to unpack the register. +% \begin{macrocode} +\cs_new_protected_nopar:Npn \clist_sort:Nn + { \clist_sort_aux:NNn \tl_set:Nn } +\cs_new_protected_nopar:Npn \clist_gsort:Nn + { \clist_sort_aux:NNn \tl_gset:Nn } +\cs_new_protected:Npn \clist_sort_aux:NNn #1#2#3 + { + \clist_if_empty:NF #2 + { + \sort_aux:NNnNn #1 + \clist_map_inline:Nn + { + \exp_last_unbraced:Nf \use_none:n + { \sort_toks:NNw \exp_args:No \clist_wrap_item:n 0 ; } + } + #2 {#3} + } + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\sort_toks:NNw} +% Unpack the various \tn{toks} registers, from $0$ to the length +% of the list. The functions |#1| and |#2| allow us to treat the +% three data structures in a unified way: +% \begin{itemize} +% \item for sequences, they are \cs{exp_not:N} \cs{seq_item:n}, +% expanding to the \cs{seq_item:n} separator, as expected; +% \item for token lists, they expand to nothing; +% \item for comma lists, they expand to \cs{exp_args:No} +% \cs{clist_wrap_item:n}, taking care of unpacking the register +% before letting the undocumented internal \pkg{clist} function +% \cs{clist_wrap_item:n} do the work of putting a comma and possibly +% braces. +% \end{itemize} +% \begin{macrocode} +\cs_new:Npn \sort_toks:NNw #1#2#3 ; + { + \if_num:w #3 < \l_sort_length_int + #1 #2 { \tex_the:D \tex_toks:D #3 } + \exp_after:wN \sort_toks:NNw \exp_after:wN #1 \exp_after:wN #2 + \int_use:N \int_eval:w #3 + \c_one \exp_after:wN ; + \fi: + } +% \end{macrocode} +% \end{macro} +% +% \subsection{Sorting itself} +% +% \begin{macro}[int]{\sort_level:} +% This function is called once blocks of size \cs{l_sort_block_int} +% (initially $1$) are each sorted. If the whole list fits in one +% block, then we are done (this also takes care of the case of an +% empty list or a list with one item). Otherwise, go through pairs +% of blocks starting from $0$, then double the block size, and repeat. +% \begin{macrocode} +\cs_new_protected_nopar:Npn \sort_level: + { + \if_num:w \l_sort_block_int < \l_sort_length_int + \l_sort_end_int \c_zero + \sort_merge_blocks: + \tex_multiply:D \l_sort_block_int \c_two + \exp_after:wN \sort_level: + \fi: + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[int]{\sort_merge_blocks:} +% This function is called to merge a pair of blocks, starting at +% the last value of \cs{l_sort_end_int} (end-point of the previous +% pair of blocks). If shifting by one block to the right we reach +% the end of the list, then this pass has ended: this end of the +% list is sorted already. Store the result of that shift in $A$, +% which will index the first block starting from the top end. +% Then locate the end-point (maximum) of the upper block: shift +% \texttt{end} upwards by one more block, checking that we don't +% go beyond the length of the list. Copy this upper block of \tn{toks} +% registers in registers above \texttt{length}, indexed by $C$: +% this is covered by \cs{sort_copy_block:}. Once this is done we +% are ready to do the actual merger using \cs{sort_merge_blocks_aux:}, +% after shifting $A$, $B$ and $C$ so that they point to the largest +% index in their respective ranges rather than pointing just beyond +% those ranges. Of course, once that pair of blocks is merged, +% move on to the next pair. +% \begin{macrocode} +\cs_new_protected_nopar:Npn \sort_merge_blocks: + { + \l_sort_begin_int \l_sort_end_int + \tex_advance:D \l_sort_end_int \l_sort_block_int + \if_num:w \int_eval:w \l_sort_end_int < \l_sort_length_int + \l_sort_A_int \l_sort_end_int + \tex_advance:D \l_sort_end_int \l_sort_block_int + \if_num:w \l_sort_end_int > \l_sort_length_int + \l_sort_end_int \l_sort_length_int + \fi: + \l_sort_B_int \l_sort_A_int + \l_sort_C_int \l_sort_length_int + \sort_copy_block: + \tex_advance:D \l_sort_A_int \c_minus_one + \tex_advance:D \l_sort_B_int \c_minus_one + \tex_advance:D \l_sort_C_int \c_minus_one + \sort_merge_blocks_aux: + \exp_after:wN \sort_merge_blocks: + \fi: + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[int]{\sort_copy_block:} +% We wish to store a copy of the \enquote{upper} block of +% \tn{toks} registers, ranging between the initial value of +% \cs{l_sort_B_int} (included) and \cs{l_sort_end_int} +% (excluded) into a new range starting at the initial value +% of \cs{l_sort_C_int}, namely \cs{l_sort_length_int}. +% \begin{macrocode} +\cs_new_protected_nopar:Npn \sort_copy_block: + { + \tex_toks:D \l_sort_C_int \tex_toks:D \l_sort_B_int + \tex_advance:D \l_sort_C_int \c_one + \tex_advance:D \l_sort_B_int \c_one + \if_num:w \l_sort_B_int = \l_sort_end_int + \use_i:nn + \fi: + \sort_copy_block: + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[aux]{\sort_merge_blocks_aux:} +% At this stage, the first block starts at \cs{l_sort_begin_int}, +% and ends at \cs{l_sort_A_int}, and the second block starts at +% \cs{l_sort_length_int} and ends at \cs{l_sort_C_int}. The result +% of the merger is stored at positions indexed by \cs{l_sort_B_int}, +% which starts at $\cs{l_sort_end_int}-1$ and decreases down to +% \cs{l_sort_begin_int}, covering the full range of the two blocks. +% In other words, we are building the merger starting with the +% largest values. +% The comparison function is defined to return either +% \texttt{reversed} or \texttt{ordered}. Of course, this +% means the arguments need to be given in the order they +% appear originally in the list. +% \begin{macrocode} +\cs_new_protected_nopar:Npn \sort_merge_blocks_aux: + { + \exp_after:wN \sort_compare:nn \exp_after:wN + { \tex_the:D \tex_toks:D \exp_after:wN \l_sort_A_int \exp_after:wN } + \exp_after:wN { \tex_the:D \tex_toks:D \l_sort_C_int } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[aux]{\sort_ordered:} +% If the comparison function returns \texttt{ordered}, +% then the second argument fed to \cs{sort_compare:nn} +% should remain to the right of the other one. Since +% we build the merger starting from the right, we copy +% that \tn{toks} register into the allotted range, then +% shift the pointers $B$ and $C$, and go on to do one +% more step in the merger, unless the second block has +% been exhausted: then the remainder of the first block +% is already in the correct register and we are done +% with merging those two blocks. +% \begin{macrocode} +\cs_new_protected_nopar:Npn \sort_ordered: + { + \tex_toks:D \l_sort_B_int \tex_toks:D \l_sort_C_int + \tex_advance:D \l_sort_B_int \c_minus_one + \tex_advance:D \l_sort_C_int \c_minus_one + \if_num:w \l_sort_C_int < \l_sort_length_int + \use_i:nn + \fi: + \sort_merge_blocks_aux: + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[aux]{\sort_reversed:} +% If the comparison function returns \texttt{reversed}, +% then the next item to add to the merger is the first +% argument, contents of the \tn{toks} register $A$. +% Then shift the pointers $A$ and $B$ to the left, and +% go for one more step fo the merger, unless the left +% block was exhausted ($A$ goes below the threshold). +% In that case, all remaining \tn{toks} registers in +% the second block, indexed by $C$, should be copied +% to the merger (see \cs{sort_merge_blocks_end:}). +% \begin{macrocode} +\cs_new_protected_nopar:Npn \sort_reversed: + { + \tex_toks:D \l_sort_B_int \tex_toks:D \l_sort_A_int + \tex_advance:D \l_sort_B_int \c_minus_one + \tex_advance:D \l_sort_A_int \c_minus_one + \if_num:w \l_sort_A_int < \l_sort_begin_int + \sort_merge_blocks_end: \use_i:nn + \fi: + \sort_merge_blocks_aux: + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[aux]{\sort_merge_blocks_end:} +% This function's task is to copy the \tn{toks} registers +% in the block indexed by $C$ to the merger indexed by $B$. +% The end can equally be detected by checking when $B$ reaches +% the threshold \texttt{begin}, or when $C$ reaches +% \texttt{length}. +% \begin{macrocode} +\cs_new_protected_nopar:Npn \sort_merge_blocks_end: + { + \tex_toks:D \l_sort_B_int \tex_toks:D \l_sort_C_int + \tex_advance:D \l_sort_B_int \c_minus_one + \tex_advance:D \l_sort_C_int \c_minus_one + \if_num:w \l_sort_B_int < \l_sort_begin_int + \use_i:nn + \fi: + \sort_merge_blocks_end: + } +% \end{macrocode} +% \end{macro} +% +% \subsection{Messages} +% +% \begin{macro}{\sort_too_long_error:Nw} +% When there are too many items in a sequence, this is an error, +% and we clean up properly the mapping over items in the list. +% This relies on the fact that the breaking code for all mappings +% is unified. +% \begin{macrocode} +\cs_new_protected:Npn \sort_too_long_error:Nw #1 \fi: + { + \fi: + \msg_kernel_error:nnx { sort } { too-large } { \token_to_str:N #1 } + \prg_map_break: + } +\msg_kernel_new:nnnn { sort } { too-large } + { The~list~#1~is~too~long~to~be~sorted~by~TeX. } + { + TeX~has~\int_use:N \c_max_register_int \ registers~available:~ + this~only~allows~to~sorts~with~up~to~\int_use:N \c_sort_max_length_int + \ items.~All~extra~items~will~be~ignored. + } +% \end{macrocode} +% \end{macro} +% +% \begin{macrocode} +%</initex|package> +% \end{macrocode} +% +% \end{implementation} +% +% \PrintIndex
\ No newline at end of file diff --git a/Master/texmf-dist/source/latex/l3experimental/l3sort/l3sort.ins b/Master/texmf-dist/source/latex/l3experimental/l3sort/l3sort.ins new file mode 100644 index 00000000000..0cc04d132fe --- /dev/null +++ b/Master/texmf-dist/source/latex/l3experimental/l3sort/l3sort.ins @@ -0,0 +1,40 @@ +\iffalse meta-comment + +File l3sort.ins Copyright (C) 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 "l3experimental bundle" (The Work in LPPL) +and all files in that bundle must be distributed together. + +The released version of this bundle is available from CTAN. + +\fi + +\input docstrip.tex +\askforoverwritefalse + +\preamble + +EXPERIMENTAL CODE + +Do not distribute this file without also distributing the +source files specified above. + +Do not distribute a modified version of this file. + +\endpreamble +% stop docstrip adding \endinput +\postamble +\endpostamble + +\keepsilent + +\generate{\file{l3sort.sty}{\from{l3sort.dtx}{package}}} + +\endbatchfile diff --git a/Master/texmf-dist/source/latex/l3experimental/l3str/l3regex.dtx b/Master/texmf-dist/source/latex/l3experimental/l3str/l3regex.dtx index 9c2b82c248d..d2968338f46 100644 --- a/Master/texmf-dist/source/latex/l3experimental/l3str/l3regex.dtx +++ b/Master/texmf-dist/source/latex/l3experimental/l3str/l3regex.dtx @@ -35,7 +35,7 @@ % %<*driver|package> \RequirePackage{expl3} -\GetIdInfo$Id: l3regex.dtx 3259 2012-01-29 20:50:48Z bruno $ +\GetIdInfo$Id: l3regex.dtx 3326 2012-02-07 00:39:44Z bruno $ {L3 Experimental Regular Expressions} %</driver|package> %<*driver> @@ -643,27 +643,31 @@ % which accepts precisely those token lists matching that regular % expression. Then loop through the query token list one token (one % \enquote{index}) at a time, exploring in parallel every possible path -% through the NFA. We keep track of an array of the states currently -% \enquote{active}, which are to be considered in order when the next -% token is read. +% through the NFA. When performing this matching, we keep track of an +% array of the states currently \enquote{active}, which are to be +% considered in order when the next token is read. % % We use the following vocabulary in the code comments (and in variable % names). % \begin{itemize} -% \item \emph{Query}: the token list to which we apply the regular -% expression. +% \item \emph{Group}: index of the capturing group, $-1$ for +% non-capturing groups. % \item \emph{Index}: each token in the query is labelled by an integer % \meta{index}, with $\cs{l_regex_min_index_int} - 1 \leq \meta{index} % \leq \cs{l_regex_max_index_int}$. The lowest and highest indexes % correspond to imaginary begin and end markers (with inacessible % category code and character code). -% \item \emph{Step}:^^A todo: fill +% \item \emph{Query}: the token list to which we apply the regular +% expression. % \item \emph{State}: each state of the NFA is labelled by an integer % \meta{state} with $0 \leq \meta{state} < % \cs{l_regex_max_state_int}$. % \item \emph{Active state}: state of the NFA that is reached when % reading the query string for the matching. Those states are % ordered according to the greediness of quantifiers. +% \item \emph{Step}: used when matching, starts at $0$, incremented +% every time a character is read, and is not reset when searching +% for repeated matches. % \end{itemize} % % To acheive a good performance, we abuse \TeX{}'s registers in two @@ -672,33 +676,38 @@ % functions. And we store integers in \tn{dimen} registers in scaled % points (\texttt{sp}), using \TeX{}'s implicit conversion from % dimensions to integers in some contexts. Specifically, the registers -% are used as follows. +% are used as follows. When building, +% \begin{itemize} +% \item \tn{toks}\meta{state} has two parts separated by \cs{s_stop}: +% a property list which holds the submatch information, followed by +% the tests and actions to perform in the \meta{state} of the NFA. +% \item \tn{skip}$i$ has the form \meta{group} \texttt{plus} +% \meta{left state} \texttt{minus} \meta{right state}. +% ^^A todo: not done yet. +% \end{itemize} +% When matching, % \begin{itemize} -% \item \tn{toks}\meta{state} has two parts: a property list which -% holds the submatch information, followed by the tests and actions -% to perform in the \meta{state} of the NFA. -% \item \tn{dimen}\meta{state} is equal to the last step in which -% the \meta{state} was active. +% \item \tn{dimen}\meta{state} is equal to the last \meta{step} in +% which the \meta{state} was active. % \item \tn{skip}$i$ holds the \meta{state} number corresponding to -% the $i$-th active \meta{state} (in order of precedence: smaller is -% more important) and has no shrink or stretch components. +% the $i$-th active \meta{state} (smaller $i$ is higher precendence) +% and has no shrink or stretch components. % \item \tn{toks}\meta{index} holds \meta{tokens} which \texttt{o}- % and \texttt{x}-expand to the \meta{index}-th token in the query. % \end{itemize} % \tn{count} registers are not abused, which means that we can safely -% use named integers. +% use named integers in this module. % % The code is structured as follows. Variables, constants and various % helper functions are introduced first, to limit the clutter in later % parts. Then functions pertaining to parsing the regular expression are % defined: that part is rather long because of the many bells and % whistles of the regex notation. The next subsection takes care of -% running the NFA. Finally, user functions. +% running the NFA. Thereafter, we give tools for the replacements. +% Finally, user functions. % % \subsection{Constants and variables} % -% \subsubsection{Generic} -% % \begin{macro}{\regex_tmp:w} % \begin{variable} % {\l_regex_internal_a_int, \l_regex_internal_b_int, \l_regex_internal_c_int} @@ -719,6 +728,8 @@ % \end{variable} % \end{macro} % +% \subsubsection{Character properties} +% % \begin{variable} % { % \c_regex_d_tl, \c_regex_D_tl, \c_regex_h_tl, \c_regex_H_tl, @@ -802,12 +813,12 @@ % % \begin{variable}{\l_regex_max_state_int} % \begin{variable}{\l_regex_left_state_int, \l_regex_right_state_int} -% The end-point states of the last group (which any quantifier -% would repeat) are stored as \cs{l_regex_left/right_state_int}. -% For simple strings of characters, the left and right pointers -% only differ by one. % The last state that was allocated is $\cs{l_regex_max_state_int}-1$, % so that \cs{l_regex_max_state_int} always points to a free state. +% The starting state and end state of the last group (which any +% quantifier would act on) are stored as +% \cs{l_regex_left/right_state_int}. In almost all cases, the left +% and right pointers only differ by~$1$. % \begin{macrocode} \int_new:N \l_regex_max_state_int \int_new:N \l_regex_left_state_int @@ -2071,6 +2082,7 @@ \int_set_eq:NN \l_regex_catcodes_default_int \c_regex_catcodes_all_int \int_set_eq:NN \l_regex_catcodes_int \l_regex_catcodes_default_int \int_set_eq:NN \l_regex_capturing_group_int \c_zero + \seq_clear:N \l_regex_capturing_group_seq \tl_clear:N \l_regex_tests_tl \bool_set_true:N \l_regex_tests_bool \int_zero:N \l_regex_max_state_int @@ -3962,7 +3974,7 @@ \int_set_eq:NN \l_regex_step_int \c_minus_one \prg_stepwise_inline:nnnn \c_zero \c_one { \l_regex_max_state_int - \c_one } - { \tex_dimen:D ##1 \l_regex_step_int sp \scan_stop: } + { \tex_dimen:D ##1 \l_regex_step_int sp } \int_set:Nn \l_regex_start_index_int { \l_regex_min_index_int - \c_one } \int_set_eq:NN \l_regex_current_index_int \l_regex_min_index_int @@ -4949,9 +4961,6 @@ \group_end: \fi: } -\cs_new_protected:Npn \regex_replace_once_aux:w #1; - { - } % \end{macrocode} % \end{macro} % diff --git a/Master/texmf-dist/source/latex/l3experimental/xcoffins/xcoffins-test.tex b/Master/texmf-dist/source/latex/l3experimental/xcoffins/xcoffins-test.tex new file mode 100644 index 00000000000..1ede1770c08 --- /dev/null +++ b/Master/texmf-dist/source/latex/l3experimental/xcoffins/xcoffins-test.tex @@ -0,0 +1,380 @@ + +\documentclass{article} + +\usepackage[T1]{fontenc} +\usepackage{times,multicol} +\usepackage{xcoffins} + +\usepackage{color} +\newcommand\cbox[2][.8]{{\setlength\fboxsep{0pt}\colorbox[gray]{#1}{#2}}} + +\newcommand\hrulebox [2]{\setbox#1\hbox to#2{{\scriptsize\itshape + \color{blue}\hrulefill #2\hrulefill}}} +\newcommand\vrulebox [2]{\setbox#1\vbox to#2{{\hsize 1pt\centering\scriptsize + \itshape\color{blue}\leaders\vrule\vfill + \hbox to0pt{\hss #2\hss}\leaders\vrule\vfill\par}}} + + +\addtolength\textwidth{10pt} + +\showboxdepth 9999 +\showboxbreadth 9999 +\tracingonline 1 + + +\scrollmode + +\newbox\zzz + + +\begin{document} + + +\title{Test file for coffins} +\author{FMi} +\maketitle + +First we add a few test coffins: +\begin{verbatim} + \newcoffin \aaa + \newcoffin \bbb + \newcoffin \ccc + \newcoffin \ddd +\end{verbatim} + \newcoffin \aaa + \newcoffin \bbb + \newcoffin \ccc + \newcoffin \ddd +and some boxes not set up as ordinary boxes (without extra poles): +\begin{verbatim} + \newbox \xxx + \newbox \yyy +\end{verbatim} + \newbox \xxx + \newbox \yyy + + +If a coffin receives data a set of ``natural'' default poles are automatically added. +\begin{verbatim} +\sbox\aaa{\fbox{\begin{tabular}[b]{l}123\\4\\5\end{tabular}}} +\showcoffindata \aaa +\end{verbatim} +\sbox\aaa{\fbox{\begin{tabular}[b]{l}123\\4\\5\end{tabular}}} +\showcoffindata \aaa + + +In contrast, boxes not declared as coffins have no poles defined. However, if +used as coffins at least the natural default poles can be used without +further problems, i.e.,they are changed to coffins automatically on use. +\begin{verbatim} +\sbox\xxx{\fbox{Some very looooonggg Caption Text}} +\showpoles \xxx +\end{verbatim} +\sbox\xxx{\fbox{Some very looooonggg Caption Text}} +\showcoffindata \xxx + + +Using \verb|\setvcoffin| instead of \verb|\sbox| gives us the codes with +\texttt{T} and \texttt{B}. Similar to \verb|\parbox| this command requires to +specify a target width of the box: +\begin{verbatim} +\setvcoffin \aaa {1.5cm} {\centering + \fbox{\begin{tabular}[b]{l}123\\4\\5\end{tabular}}} +\showcoffindata \aaa +\end{verbatim} +\setvcoffin \aaa {1.5cm} {\centering + \fbox{\begin{tabular}[b]{l}123\\4\\5\end{tabular}}} +\showcoffindata \aaa + +There are a dozen natural poles per box (some with multiple names); you can +move each of the poles to someplace else (either to an absolute position in +``box space'' or relative to its previous position). The coordinates can +refer to box dimensions (using \verb|\height|, \verb|\depth|, + and \verb|width|). First we move some pole and add one +additional one: +\begin{verbatim} +\setcoffinpole \aaa [h]{t}(\height -3pt) +\setcoffinpole \aaa [v]{l}(0pt) +\setcoffinpole \aaa [h]{mybottom}(\depth +2pt) +\showcoffindata \aaa +\end{verbatim} +\setcoffinpole \aaa [h]{t}(\height -3pt) +\setcoffinpole \aaa [v]{l}(0pt) +\setcoffinpole \aaa [h]{mybottom}(\depth +2pt) +\showcoffindata \aaa + + +More interesting in many cases is the relative move of poles. For this the +poles better exist or one gets an error and \texttt{0pt,0pt} is used: +\begin{verbatim} +\adjustcoffinpole \aaa [h]{H}(1pt) +\adjustcoffinpole \aaa [v]{l}(1pt) +\adjustcoffinpole \aaa [h]{undefined}(1pt) +\showcoffindata \aaa +\end{verbatim} +\adjustcoffinpole \aaa [h]{H}(1pt) +\adjustcoffinpole \aaa [v]{l}(1pt) +\adjustcoffinpole \aaa [h]{undefined}(1pt) +\showcoffindata \aaa + + + +\sbox \aaa {\fontsize{14.4}{5.5pc minus .5pc}\sffamily C\,H\,A\,P\,T\,E\,R + \fontsize{36}{40pt}\selectfont 2} + +\setvcoffin \bbb {11cm} + {\raggedleft\normalfont\fontsize{36}{38pt}\bfseries + The Structure of a \LaTeX{} Document} + +\setvcoffin \ccc {13cm} + {Some sample blind text to produce paragraph data after a heading. + Some sample blind text to produce paragraph data after a heading. + Some sample blind text to produce paragraph data after a heading. + Some sample blind text to produce paragraph data after a heading. + \endgraf + Some more sample blind text to produce paragraph data after a heading. + Some more sample blind text to produce paragraph data after a heading. +} + + +Suppose you have the following blocks of text: + +\bigskip + +\noindent\cbox{\usebox\aaa} + +\begin{multicols}{2} +\ttfamily\tiny +\ExplSyntaxOn + \noindent \coffin_print_pole_values:Nn \aaa \\ +\ExplSyntaxOff +\end{multicols} + +\medskip + +\noindent\cbox{\usebox\bbb} + +\medskip + +\noindent\cbox{\usebox\ccc} + +\bigskip + +produced by: +\begin{verbatim} +\sbox \aaa {\fontsize{14.4}{5.5pc minus .5pc}\sffamily + C\,H\,A\,P\,T\,E\,R + \fontsize{36}{40pt}\selectfont 2} +\setvcoffin \bbb {11cm} + {\raggedleft\normalfont\fontsize{36}{38pt}\bfseries + The Structure of a \LaTeX{} Document} +\setvcoffin \ccc {13cm} + {Some sample blind text to produce paragraph + data after a heading. ... } +\end{verbatim} + +How do you turn this into a heading of TLC2? + + +\newbox\RBi +\newbox\RBii +\newbox\RBiii + +\hrulebox\RBi{62pt} +\vrulebox\RBii{90pt} +\vrulebox\RBiii{60pt} + +\aligncoffins \bbb [T,r] \aaa [H,r](-62pt,60pt) +\aligncoffins \ccc[T,r] \bbb[B,r](62pt,90pt) + + \aligncoffins * \ccc[\bbb-T,\bbb-hc] \RBiii[b,hc](28pt,0pt) + \aligncoffins * \ccc[\bbb-b,\bbb-r] \RBi[H,r](0pt,-5pt) + \aligncoffins * \ccc[\bbb-B,\bbb-hc] \RBii[t,r](14pt,0pt) + +\newpage + +How do you best define/describe the following design? + +\medskip + +\noindent\cbox{\usebox\ccc} + + + + + + +\newpage \pagestyle{empty} + +\newcoffin \eee +\newcoffin \fff +\newcoffin \ggg + +\sbox \aaa {\small\scshape les vases communicants} +\sbox \bbb {\scshape comunicating} +\sbox \ccc {\fontsize{70pt}{60pt} \bfseries Ve\S els} +\sbox \ddd {\scshape andr\'e breton} +\setvcoffin \eee {4.7cm}{\noindent Translated by Mary Ann Caws \&\break + Geoffrey T.\,Harris, with notes \&\break + introduction by Mary Ann Caws\parfillskip=0pt\relax + } +\sbox \fff {University of Nebraska Press: Lincoln \& London} + +\setvcoffin \ggg {100mm}{\noindent\fbox{\parbox{97mm}{\leavevmode\vspace*{228mm}}}} + + +\aligncoffins \ccc [H,r] \ddd [H,r](0pt,-12pt) +\aligncoffins \ccc [t,l] \bbb (0pt,6pt) +\aligncoffins \ccc [H,r] \aaa [H,r](0pt,138pt) +\aligncoffins \eee [T,l] \ccc (0pt,22pc) +\aligncoffins \fff \eee [B,l](0pt,4pc) +\aligncoffins \ggg [b,l] \fff [B,l](54pt,11pc) + + +\vspace*{-2cm} +\noindent\cbox{\usebox\ggg} + + +\newpage + +\section{Rotation} + +\sbox \aaa {\tabcolsep0pt\begin{tabular}[c]{|c|}\hline a\\b\\cccccccccccccc\\d + \\e\\e\\e\\e\\\hline\end{tabular}} +\sbox \bbb {\fbox{A sample Text}} + +% just for the sake of it: +\adjustcoffinpole \aaa {T}(24pt) +\displaycoffinpoles \aaa {black} +x\cbox{\usebox \aaa }x +% +\rotatecoffin \aaa {45} +\displaycoffinhandle \aaa {b}{hc} {blue} +\displaycoffinhandle \aaa {b}{l} {blue} +\displaycoffinhandle \aaa {t}{r} {blue} +\displaycoffinhandle \aaa {vc}{r} {blue} +\displaycoffinhandle \aaa {vc}{l} {blue} +\quad +x\cbox{\usebox \aaa }x +\rotatecoffin \aaa {45} +\displaycoffinhandle \aaa {b}{r} {red} +\displaycoffinhandle \aaa {vc}{l} {red} +\quad +x\cbox{\usebox \aaa }x + +\vspace{1cm} + +\rotatecoffin \aaa {45} +\displaycoffinhandle \aaa {b}{l} {yellow} +% +x\cbox{\usebox \aaa }x +% + +\vspace{1cm} + +x\cbox{\usebox \bbb }x +% +\rotatecoffin \bbb {45} +\displaycoffinhandle \bbb {B}{hc} {yellow} +\quad +x\cbox{\usebox \bbb }x + + +\section{Rotation + alignment} + +\aligncoffins \aaa [b,l] \bbb[B,hc](30pt,0pt) +x\cbox{\usebox \aaa }x + + +After we have aligned a roated box with some other box we need to decide about +the bounding box of the new box. Right now this become the enclosing box and +we do not maintain information about the inner boxes. So when we rotate that +new box there seems to be unnecessary space in the enclosing bounding box, +even though that is correct if you think of the aligned box being unrotated. + +There is at least the possibility to refer to the handles of the inner boxes +as one can see by two of the green handles + +\medskip + +\rotatecoffin \aaa {45} +\displaycoffinhandle \aaa {vc}{hc} {green} +\displaycoffinhandle \aaa {H}{l} {green} +\displaycoffinhandle \aaa {\aaa-T}{\aaa-r} {green} +\displaycoffinhandle \aaa {\bbb-H}{\bbb-r} {green} +%\quad +x\cbox{\usebox \aaa }x + +We could do better, if we want to, by actually checking for max and +min of all inner bounding box corners and construct the result BB box from +that---but is it worth it? + +Perhaps it is! After all, the current implementation shows different results +depending on when you align boxes and when you rotate, e.g., aligning first +gives totally different bounding box results. + +\newpage + +Aligning first and then 135 + 45 rotation gives this: + +\sbox \aaa {\tabcolsep0pt\begin{tabular}[c]{|c|}\hline a\\b\\cccccccccccccc\\d + \\e\\e\\e\\e\\\hline\end{tabular}} +\sbox \bbb {\fbox{A sample Text}} +\rotatecoffin \bbb {90} + +\aligncoffins \aaa [b,l] \bbb[B,hc](-30pt,0pt) +x\cbox{\usebox \aaa }x +\qquad +\rotatecoffin \aaa {135} +x\cbox{\usebox \aaa }x +\qquad +\rotatecoffin \aaa {45} +x\cbox{\usebox \aaa }x + + + + +\newpage + +\section{Rotation by small amounts} + +\sbox \aaa {\tabcolsep0pt\begin{tabular}[c]{|c|}\hline a\\b\\ccccccccc\\d + \\e\\e\\e\\\hline\end{tabular}} + +\subsection{30 + 30 +30 } +\rotatecoffin \aaa {30} +x\cbox{\usebox \aaa }x +\rotatecoffin \aaa {30} +x\cbox{\usebox \aaa }x +\rotatecoffin \aaa {30} +x\cbox{\usebox \aaa }x + +\subsection{6 * 10 + 45 + 45 + 30} + +\rotatecoffin \aaa {10} +x\cbox{\usebox \aaa }x +\rotatecoffin \aaa {10} +x\cbox{\usebox \aaa }x +\rotatecoffin \aaa {10} +x\cbox{\usebox \aaa }x + +\vspace{1cm} +\rotatecoffin \aaa {10} +x\cbox{\usebox \aaa }x +\rotatecoffin \aaa {10} +x\cbox{\usebox \aaa }x +\rotatecoffin \aaa {10} +x\cbox{\usebox \aaa }x + +\vspace{1cm} +\rotatecoffin \aaa {45} +x\cbox{\usebox \aaa }x +\rotatecoffin \aaa {45} +x\cbox{\usebox \aaa }x +\rotatecoffin \aaa {30} +x\cbox{\usebox \aaa }x + + +\end{document} + + diff --git a/Master/texmf-dist/source/latex/l3experimental/xcoffins/xcoffins-tschichold-example-keyval.tex b/Master/texmf-dist/source/latex/l3experimental/xcoffins/xcoffins-tschichold-example-keyval.tex new file mode 100644 index 00000000000..e83c0b490b6 --- /dev/null +++ b/Master/texmf-dist/source/latex/l3experimental/xcoffins/xcoffins-tschichold-example-keyval.tex @@ -0,0 +1,281 @@ + +\documentclass{article} + +\usepackage[a4paper,margin=5pt]{geometry} + +\usepackage[T1]{fontenc} +\usepackage{times,multicol,graphicx} +\usepackage{xcoffins} + +\usepackage{times,color} +\newcommand\cbox[2][.8]{{\setlength\fboxsep{0pt}\colorbox[gray]{#1}{#2}}} + +\ExplSyntaxOn + +\ExplSyntaxOff + + + +%\scrollmode + +\pagestyle{empty} + +\begin{document} + + \NewCoffin \result + \NewCoffin \aaa + \NewCoffin \bbb + \NewCoffin \ccc + \NewCoffin \ddd + \NewCoffin \eee + \NewCoffin \fff + \NewCoffin \rulei + \NewCoffin \ruleii + \NewCoffin \ruleiii + +\SetHorizontalCoffin \result {} +\SetHorizontalCoffin \aaa {\fontsize{52}{50}\sffamily\bfseries mitteilungen} +\SetHorizontalCoffin \bbb {\fontsize{52}{50}\sffamily\bfseries typographische} +\SetHorizontalCoffin \ccc {\fontsize{12}{10}\sffamily + \quad zeitschrift des bildungsverbandes der + deutschen buchdrucker leipzig + \textbullet{} oktoberheft 1925} +\SetHorizontalCoffin \ddd {\fontsize{28}{20}\sffamily sonderheft} +\SetVerticalCoffin \eee {180pt} + {\raggedleft\fontsize{31}{36}\sffamily\bfseries + elementare\\ + typographie} +\SetVerticalCoffin \fff {140pt} + {\raggedright \fontsize{13}{14}\sffamily\bfseries + natan altman \\ + otto baumberger \\ + herbert mayer \\ + max burchartz \\ + el lissitzky \\ + ladislaus moholy-nagy \\ + moln\'ar f.~farkas \\ + johannes molzahn \\ + kurt schwitters \\ + mart stam \\ + ivan tschichold} + +\RotateCoffin \bbb {90} +\RotateCoffin \ccc {270} + +\SetHorizontalCoffin \rulei {\color{red}\rule{6.5in}{1pc}} +\SetHorizontalCoffin \ruleii {\color{red}\rule{1pc}{23.5cm}} +\SetHorizontalCoffin \ruleiii{\color{black}\rule{10pt}{152pt}} + + +\JoinCoffins \result \aaa +\JoinCoffins [ + coffin1-hpole = \aaa-t , + coffin1-vpole = \aaa-r , + coffin2-hpole = b , + coffin2-vpole = r , + voffset = 2 mm , +] \result \rulei +\JoinCoffins [ + coffin1-hpole = \aaa-b , + coffin1-vpole = \aaa-l , + coffin2-hpole = B , + coffin2-vpole = r , + hoffset = 2 pt , +] \result \bbb +\JoinCoffins [ + coffin1-hpole = \bbb-t , + coffin1-vpole = \bbb-r , + coffin2-hpole = t , + coffin2-vpole = r , + hoffset = -2 mm , +] \result \ruleii +\JoinCoffins [ + coffin1-hpole = \aaa-B , + coffin1-vpole = \aaa-r , + coffin2-hpole = B , + coffin2-vpole = l , + hoffset = 66 pt , + voffset = 14 pc , +] \result \ccc +\JoinCoffins [ + coffin1-hpole = \bbb-l , + coffin1-vpole = \ccc-B , + coffin2-hpole = t , + coffin2-vpole = r , + hoffset = -2 mm , +] \result \fff +\JoinCoffins [ + coffin1-hpole = \fff-b , + coffin1-vpole = \fff-r , + coffin2-hpole = b , + coffin2-vpole = l , + hoffset = 2 mm , +] \result \ruleiii +\JoinCoffins [ + coffin1-hpole = \ccc-r , + coffin1-vpole = \fff-l , + coffin2-hpole = B , + coffin2-vpole = r , +] \result \eee +\JoinCoffins [ + coffin1-hpole = \eee-T , + coffin1-vpole = \eee-r , + coffin2-hpole = B , + coffin2-vpole = r , + voffset = 4 pc , +] \result \ddd + + +\vspace*{3cm} +\begin{center} + {\Large Title page of ``elementare typographie'' by Ivan Tschichold\par} + +\large +\vspace*{1cm} + + 1. first the scanned original from 1925 + +\vspace*{6mm} + + 2. then the recreated \TeX{} version from 2010 using coffins---not + attempting\\ to match the fonts and size but the structure + +\vspace*{6mm} + + 3. and finally the source code used. + + This document uses the new + implementation by Joseph in \texttt{l3coffins-new}. + +\end{center} + +\newpage + + +\begin{center} + \null + \fbox{\includegraphics[scale=.95]{elementare-typographie-title.jpg}} +\end{center} + +\newpage + +\TypesetCoffin \result + +\newpage + +\vspace*{3cm} +\begin{center} + {\Large Code used: \par} +\vspace*{1cm} + + +\begin{minipage}{14cm} +\begin{verbatim} +\SetHorizontalCoffin\result{} +\SetHorizontalCoffin \aaa {\fontsize{52}{50}\sffamily\bfseries mitteilungen} +\SetHorizontalCoffin \bbb {\fontsize{52}{50}\sffamily\bfseries typographische} +\SetHorizontalCoffin \ccc {\fontsize{12}{10}\sffamily + \quad zeitschrift des bildungsverbandes der + deutschen buchdrucker leipzig + \textbullet{} oktoberheft 1925} +\SetHorizontalCoffin \ddd {\fontsize{28}{20}\sffamily sonderheft} +\SetVerticalCoffin \eee {180pt} + {\raggedleft\fontsize{31}{36}\sffamily\bfseries + elementare\\ + typographie} +\SetVerticalCoffin \fff {140pt} + {\raggedright \fontsize{13}{14}\sffamily\bfseries + natan altman \\ + otto baumberger \\ + herbert mayer \\ + max burchartz \\ + el lissitzky \\ + ladislaus moholy-nagy \\ + moln\'ar f.~farkas \\ + jahannes molzahn \\ + kurt schwitters \\ + mart stam \\ + ivan tschichold} + +\RotateCoffin \bbb {90} +\RotateCoffin \ccc {270} + +\SetHorizontalCoffin \rulei {\color{red}\rule{6.5in}{1pc}} +\SetHorizontalCoffin \ruleii {\color{red}\rule{1pc}{23.5cm}} +\SetHorizontalCoffin \ruleiii{\color{black}\rule{10pt}{152pt}} + +\JoinCoffins \result \aaa +\JoinCoffins [ + coffin1-hpole = \aaa-t , + coffin1-vpole = \aaa-r , + coffin2-hpole = b , + coffin2-vpole = r , + voffset = 2 mm , +] \result \rulei +\JoinCoffins [ + coffin1-hpole = \aaa-b , + coffin1-vpole = \aaa-l , + coffin2-hpole = B , + coffin2-vpole = r , + hoffset = 2 pt , +] \result \bbb +\JoinCoffins [ + coffin1-hpole = \bbb-t , + coffin1-vpole = \bbb-r , + coffin2-hpole = t , + coffin2-vpole = r , + hoffset = -2 mm , +] \result \ruleii +\JoinCoffins [ + coffin1-hpole = \aaa-B , + coffin1-vpole = \aaa-r , + coffin2-hpole = B , + coffin2-vpole = l , + hoffset = 66 pt , + voffset = 14 pc , +] \result \ccc +\JoinCoffins [ + coffin1-hpole = \bbb-l , + coffin1-vpole = \ccc-B , + coffin2-hpole = t , + coffin2-vpole = r , + hoffset = -2 mm , +] \result \fff +\JoinCoffins [ + coffin1-hpole = \fff-b , + coffin1-vpole = \fff-r , + coffin2-hpole = b , + coffin2-vpole = l , + hoffset = 2 mm , +] \result \ruleiii +\JoinCoffins [ + coffin1-hpole = \ccc-r , + coffin1-vpole = \fff-l , + coffin2-hpole = B , + coffin2-vpole = r , +] \result \eee +\JoinCoffins [ + coffin1-hpole = \eee-T , + coffin1-vpole = \eee-r , + coffin2-hpole = B , + coffin2-vpole = r , + voffset = 4 pc , +] \result \ddd +\SetHorizontalCoffin\result{} +\SetHorizontalCoffin \aaa {\fontsize{52}{50}\sffamily\bfseries + mitteilungen} +\SetHorizontalCoffin \bbb {\fontsize{52}{50}\rotatebox{90}{\sffamily\bfseries + typographische}} + +\TypesetCoffin \result +\end{verbatim} + +This is not necessarily the final syntax but for now it does its job. For +example, flexible support for adding ornaments (lines, \ldots) is still +missing, so above the rules got added as predefined individual coffins. + +\end{minipage} +\end{center} + +\end{document} + diff --git a/Master/texmf-dist/source/latex/l3experimental/xcoffins/xcoffins-tschichold-example.tex b/Master/texmf-dist/source/latex/l3experimental/xcoffins/xcoffins-tschichold-example.tex new file mode 100644 index 00000000000..343c9d7e29f --- /dev/null +++ b/Master/texmf-dist/source/latex/l3experimental/xcoffins/xcoffins-tschichold-example.tex @@ -0,0 +1,185 @@ + +\documentclass{article} + +\usepackage[a4paper,margin=5pt]{geometry} + +\usepackage[T1]{fontenc} +\usepackage{times,multicol,graphicx} +\usepackage{xcoffins} + +\usepackage{times,color} +\newcommand\cbox[2][.8]{{\setlength\fboxsep{0pt}\colorbox[gray]{#1}{#2}}} + +\ExplSyntaxOn + +\ExplSyntaxOff + + + +%\scrollmode + +\pagestyle{empty} + +\begin{document} + + \NewCoffin \result + \NewCoffin \aaa + \NewCoffin \bbb + \NewCoffin \ccc + \NewCoffin \ddd + \NewCoffin \eee + \NewCoffin \fff + \NewCoffin \rulei + \NewCoffin \ruleii + \NewCoffin \ruleiii + +\SetHorizontalCoffin \result {} +\SetHorizontalCoffin \aaa {\fontsize{52}{50}\sffamily\bfseries mitteilungen} +\SetHorizontalCoffin \bbb {\fontsize{52}{50}\sffamily\bfseries typographische} +\SetHorizontalCoffin \ccc {\fontsize{12}{10}\sffamily + \quad zeitschrift des bildungsverbandes der + deutschen buchdrucker leipzig + \textbullet{} oktoberheft 1925} +\SetHorizontalCoffin \ddd {\fontsize{28}{20}\sffamily sonderheft} +\SetVerticalCoffin \eee {180pt} + {\raggedleft\fontsize{31}{36}\sffamily\bfseries + elementare\\ + typographie} +\SetVerticalCoffin \fff {140pt} + {\raggedright \fontsize{13}{14}\sffamily\bfseries + natan altman \\ + otto baumberger \\ + herbert mayer \\ + max burchartz \\ + el lissitzky \\ + ladislaus moholy-nagy \\ + moln\'ar f.~farkas \\ + johannes molzahn \\ + kurt schwitters \\ + mart stam \\ + ivan tschichold} + +\RotateCoffin \bbb {90} +\RotateCoffin \ccc {270} + +\SetHorizontalCoffin \rulei {\color{red}\rule{6.5in}{1pc}} +\SetHorizontalCoffin \ruleii {\color{red}\rule{1pc}{23.5cm}} +\SetHorizontalCoffin \ruleiii{\color{black}\rule{10pt}{152pt}} + + +\JoinCoffins \result \aaa +\JoinCoffins \result[\aaa-t,\aaa-r] \rulei [b,r](0pt,2mm) +\JoinCoffins \result[\aaa-b,\aaa-l] \bbb [B,r](2pt,0pt) +\JoinCoffins \result[\bbb-t,\bbb-r] \ruleii [t,r](-2mm,0pt) +\JoinCoffins \result[\aaa-B,\aaa-r] \ccc [B,l](66pt,14pc) +\JoinCoffins \result[\bbb-l,\ccc-B] \fff [t,r](-2mm,0pt) +\JoinCoffins \result[\fff-b,\fff-r] \ruleiii [b,l](2mm,0pt) +\JoinCoffins \result[\ccc-r,\fff-l] \eee [B,r] +\JoinCoffins \result[\eee-T,\eee-r] \ddd [B,r](0pt,4pc) + + +\vspace*{3cm} +\begin{center} + {\Large Title page of ``elementare typographie'' by Ivan Tschichold\par} + +\large +\vspace*{1cm} + + 1. first the scanned original from 1925 + +\vspace*{6mm} + + 2. then the recreated \TeX{} version from 2010 using coffins---not + attempting\\ to match the fonts and size but the structure + +\vspace*{6mm} + + 3. and finally the source code used. + + This document uses the new + implementation by Joseph in \texttt{l3coffins-new}. + +\end{center} + +\newpage + + +\begin{center} + \null + \fbox{\includegraphics[scale=.95]{elementare-typographie-title.jpg}} +\end{center} + +\newpage + +\TypesetCoffin \result + +\newpage + +\vspace*{3cm} +\begin{center} + {\Large Code used: \par} +\vspace*{1cm} + + +\begin{minipage}{14cm} +\begin{verbatim} +\SetHorizontalCoffin\result{} +\SetHorizontalCoffin \aaa {\fontsize{52}{50}\sffamily\bfseries mitteilungen} +\SetHorizontalCoffin \bbb {\fontsize{52}{50}\sffamily\bfseries typographische} +\SetHorizontalCoffin \ccc {\fontsize{12}{10}\sffamily + \quad zeitschrift des bildungsverbandes der + deutschen buchdrucker leipzig + \textbullet{} oktoberheft 1925} +\SetHorizontalCoffin \ddd {\fontsize{28}{20}\sffamily sonderheft} +\SetVerticalCoffin \eee {180pt} + {\raggedleft\fontsize{31}{36}\sffamily\bfseries + elementare\\ + typographie} +\SetVerticalCoffin \fff {140pt} + {\raggedright \fontsize{13}{14}\sffamily\bfseries + natan altman \\ + otto baumberger \\ + herbert mayer \\ + max burchartz \\ + el lissitzky \\ + ladislaus moholy-nagy \\ + moln\'ar f.~farkas \\ + jahannes molzahn \\ + kurt schwitters \\ + mart stam \\ + ivan tschichold} + +\RotateCoffin \bbb {90} +\RotateCoffin \ccc {270} + +\SetHorizontalCoffin \rulei {\color{red}\rule{6.5in}{1pc}} +\SetHorizontalCoffin \ruleii {\color{red}\rule{1pc}{23.5cm}} +\SetHorizontalCoffin \ruleiii{\color{black}\rule{10pt}{152pt}} + +\JoinCoffins \result \aaa +\JoinCoffins \result[\aaa-t,\aaa-r] \rulei [b,r](0pt,2mm) +\JoinCoffins \result[\aaa-b,\aaa-l] \bbb [B,r](2pt,0pt) +\JoinCoffins \result[\bbb-t,\bbb-r] \ruleii [t,r](-2mm,0pt) +\JoinCoffins \result[\aaa-B,\aaa-r] \ccc [B,l](66pt,14pc) +\JoinCoffins \result[\bbb-l,\ccc-B] \fff [t,r](-2mm,0pt) +\JoinCoffins \result[\fff-b,\fff-r] \ruleiii [b,l](2mm,0pt) +\JoinCoffins \result[\ccc-r,\fff-l] \eee [B,r] +\JoinCoffins \result[\eee-T,\eee-r] \ddd [B,r](0pt,4pc) +\SetHorizontalCoffin\result{} +\SetHorizontalCoffin \aaa {\fontsize{52}{50}\sffamily\bfseries + mitteilungen} +\SetHorizontalCoffin \bbb {\fontsize{52}{50}\rotatebox{90}{\sffamily\bfseries + typographische}} + +\TypesetCoffin \result +\end{verbatim} + +This is not necessarily the final syntax but for now it does its job. For +example, flexible support for adding ornaments (lines, \ldots) is still +missing, so above the rules got added as predefined individual coffins. + +\end{minipage} +\end{center} + +\end{document} + diff --git a/Master/texmf-dist/source/latex/l3experimental/xgalley/l3galley.dtx b/Master/texmf-dist/source/latex/l3experimental/xgalley/l3galley.dtx index cb34e8a92aa..bb07281e01b 100644 --- a/Master/texmf-dist/source/latex/l3experimental/xgalley/l3galley.dtx +++ b/Master/texmf-dist/source/latex/l3experimental/xgalley/l3galley.dtx @@ -37,7 +37,7 @@ % %<*driver|package> \RequirePackage{xparse} -\GetIdInfo$Id: l3galley.dtx 3253 2012-01-28 14:59:55Z joseph $ +\GetIdInfo$Id: l3galley.dtx 3325 2012-02-06 22:07:00Z joseph $ {L3 Experimental galley code} %</driver|package> %<*driver> @@ -942,8 +942,6 @@ \cs_new_protected_nopar:Npn \galley_initialise_settings: { \dim_set_eq:NN \l_galley_text_width_dim \l_galley_width_dim - \dim_zero:N \l_galley_left_margin_dim - \dim_zero:N \l_galley_right_margin_dim \dim_zero:N \l_galley_total_left_margin_dim \dim_zero:N \l_galley_total_right_margin_dim } @@ -2187,6 +2185,30 @@ %<*package> % \end{macrocode} % +% \begin{macro}{\clearpage} +% The \tn{clearpage} macro needs to place material into the correct +% structures rather than directly onto the main vertical list. Other +% than that it is the same as the \LaTeXe{} version. +% \begin{macrocode} +\RenewDocumentCommand \clearpage { } + { + \mode_if_vertical:T + { + \int_compare:nNnT \@dbltopnum = \c_minus_one + { + \dim_compare:nNnT \tex_pagetotal:D < \topskip + { \tex_hbox:D { } } + } + } + \newpage + \tl_gput_right:Nn \g_galley_whatsit_next_tl + { \iow_shipout:Nx \c_minus_one { } } + \tex_vbox:D { } + \galley_set_user_penalty:n { -\@Mi } + } +% \end{macrocode} +% \end{macro} +% % \begin{macro}{\nobreak} % \begin{macro}{\noindent} % \begin{macro}{\vspace} @@ -2207,11 +2229,11 @@ \tex_noindent:D \bool_gset_false:N \g_galley_omit_next_indent_bool } -\RenewDocumentCommand \vspace { m } +\RenewDocumentCommand \vspace { s m } { - \@ifstar - { \galley_set_user_vspace:n {#1} } - { \galley_set_user_vspace:n {#1} } + \IfBooleanTF #1 + { \galley_set_user_vspace:n {#2} } + { \galley_set_user_vspace:n {#2} } } % \end{macrocode} % \end{macro} @@ -2228,8 +2250,8 @@ \RenewDocumentCommand \newline { } { \galley_break_line:Nn \c_true_bool { 0 pt } } % \end{macrocode} -%\end{macro} -%\end{macro} +% \end{macro} +% \end{macro} % % \subsection{\LaTeXe{} fixes} % diff --git a/Master/texmf-dist/source/latex/l3experimental/xgalley/xgalley-demo.tex b/Master/texmf-dist/source/latex/l3experimental/xgalley/xgalley-demo.tex new file mode 100644 index 00000000000..a2ede159b96 --- /dev/null +++ b/Master/texmf-dist/source/latex/l3experimental/xgalley/xgalley-demo.tex @@ -0,0 +1,208 @@ +\documentclass{article} + +\setlength{\parindent}{12 pt} + +\usepackage{xgalley} + +% Customised templates, etc.: would be in the class for a real document +\ExplSyntaxOn +\DeclareTemplateInterface { parshape } { cutout } { 0 } + { + on-left-side : boolean = true , + no-page-break : boolean = false , + normal-lines : integer = 1 , + parshape-list : commalist + } +\DeclareTemplateCode { parshape } { cutout } { 0 } + { + on-left-side = \l_galley_parshape_on_left_bool , + no-page-break = \l_galley_parshape_no_break_bool , + normal-lines = \l_galley_parshape_lines_int , + parshape-list = \l_galley_parshape_clist + } + { + \AssignTemplateKeys + \bool_if:NT \l_galley_parshape_no_break_bool + { \bool_gset_true:N \g_galley_nobreak_next_bool } + \clist_clear:N \l_tmpa_clist + \clist_map_inline:Nn \l_galley_parshape_clist + { \clist_put_right:Nn \l_tmpa_clist { 0 pt } } + \bool_if:NTF \l_galley_parshape_on_left_bool + { + \galley_parshape_single_par:nVVN + \l_galley_parshape_lines_int + \l_galley_parshape_clist + \l_tmpa_clist + \c_true_bool + } + { + \galley_parshape_single_par:nVVN + \l_galley_parshape_lines_int + \l_tmpa_clist + \l_galley_parshape_clist + \c_true_bool + } + } +\DeclareInstance { parshape } { staggered } { cutout } + { + no-page-break = true , + parshape-list = { 20 pt, 40 pt, 60 pt } + } + +\DeclareInstance { justification } { adjust } { std } + { + end-skip = \fill , + left-skip = 0 pt , + right-skip = 0 pt , + start-skip = 0 pt + } +\DeclareInstance { justification } { centerfirst } { single } + { + end-skip = 0 pt , + indent-width = 0 pt , + left-skip = -\fill , + right-skip = \fill , + start-skip = 0 pt plus 2fill + } +\DeclareInstance { justification } { centerfirst-adjust } { compound } + { + first-paragraph = centerfirst , + other-paragraphs = adjust + } +\ExplSyntaxOff + +\begin{document} + +Some starting text. Some starting text. Some starting text. Some starting text. +Some starting text. Some starting text. Some starting text. Some starting text. + +Some starting text. Some starting text. Some starting text. Some starting text. +Some starting text. Some starting text. Some starting text. Some starting text. + +\UseInstance{parshape}{staggered} +\section{This should\\ be\\a really staggered\\heading (but isn't)} + +In fact we should not be surprised since the standard \LaTeX{} heading +code is essentially using its own parshape and thus overwriting the +outer parshape declaration. + +\UseInstance{parshape}{staggered} +\UseInstance{justification}{ragged-right} + +This is a paragraph for testing various justification\\ settings. We have some +text and after the word `word' \\ we just had a forced line break. We +do some more line break testing, e.g., this\\[7pt] one was supposed to +add $7$\,pt of extra space. + +And here a paragraph for comparison with some text some text some text +also-containing-a-longer-word some text some text some text some text +some text some text some text. + +\section{Linebreaks} + +A line break with linebreak\linebreak +and now \ldots + +\section{Justified} + +some text% +\marginpar + {% + \UseInstance{justification}{ragged-right}% + \fussy + \fontfamily{pop}\fontsize{7}{9}\selectfont + ZZZ Some text in Optima. Some text in Optima. Some text in Optima. + Some text in Optima. Some text in Optima.% + } +some text some text some text some text some text some text some text +some text some text some text some text some text some text +some text some text some text some text some text some text some text +some text some text some text some text some text some text +some text some text some text some text some text some text some text +some text some text some text some text some text some text. + +\section{Ragged-right} + +\UseInstance{justification}{ragged-right} +This is a paragraph for testing various justification settings. We have some +text and after the word `word' \\ we just had a forced line break. We +do some more line break testing, e.g., this\\[7pt] one was supposed to +add $7$\,pt of extra space. + +And here a paragraph for comparison with some text some text some text +also-containing-a-longer-word some text some text some text some text +some text some text some text. + +\section{Ragged-left} + +\UseInstance{justification}{ragged-left} +\UseTemplate{hyphenation}{std}{enable = false} +\sloppy +This is a paragraph for testing various justification settings. We have some +text and after the word `word' \\ we just had a forced line break. We +do some more line break testing, e.g., this\\[7pt] one was supposed to +add $7$\,pt of extra space. + +And here a paragraph for comparison with some text some text some text +also-containing-a-longer-word some text some text some text some text +some text some text some text. + +\section{Adjust} + +\UseInstance{justification}{adjust} +\UseTemplate{hyphenation}{std}{enable = true} +\fussy +This is a paragraph for testing various justification settings. We have some +text and after the word `word' \\ we just had a forced line break. We +do some more line break testing, e.g., this\\[7pt] one was supposed to +add $7$\,pt of extra space. + +And here a paragraph for comparison with some text some text some text +also-containing-a-longer-word some text some text some text some text +some text some text some text. + +\section{Centered} + +\UseInstance{justification}{centered} +This is a paragraph for testing various justification settings. We have some +text and after the word `word' \\ we just had a forced line break. We +do some more line break testing, e.g., this\\[7pt] one was supposed to +add $7$\,pt of extra space. + +And here a paragraph for comparison with some text some text some text +also-containing-a-longer-word some text some text some text some text +some text some text some text. + +\section{Center first} + +\UseInstance{justification}{centerfirst-adjust} +This is a paragraph for testing various justification settings. We have some +This is a paragraph for testing various justification settings. We have some +This is a paragraph for testing various justification settings. We have some +This is a paragraph for testing various justification settings. We have some +text and after the word `word' \\ we just had a forced line break. We +do some more line break testing, e.g., this\\[7pt] one was supposed to +add $7$\,pt of extra space. +This is a paragraph for testing various justification settings. We have some +This is a paragraph for testing various justification settings. We have some +This is a paragraph for testing various justification settings. We have some +This is a paragraph for testing various justification settings. We have some + +And here a paragraph for comparison with some text some text some text +also-containing-a-longer-word some text some text some text some text +some text some text some text. + +\section{Centering} + +\UseInstance{justification}{centering} +This is a paragraph for testing various justification settings. We have some +text and after the word `word' \\ we just had a forced line break. We +do some more line break testing, e.g., this\\[7pt] one was supposed to +add $7$\,pt of extra space. + +And here a paragraph for comparison with some text some text some text +also-containing-a-longer-word some text some text some text some text +some text some text some text. + + +\end{document} |