From 9b3715d6ade58a41883a912d6c01e1e502645323 Mon Sep 17 00:00:00 2001 From: Karl Berry Date: Mon, 6 Nov 2017 21:58:05 +0000 Subject: witharrows (6nov17) git-svn-id: svn://tug.org/texlive/trunk@45707 c570f23f-e606-0410-a88d-b1316a301751 --- .../texmf-dist/tex/latex/witharrows/witharrows.sty | 792 ++++++++++----------- 1 file changed, 362 insertions(+), 430 deletions(-) (limited to 'Master/texmf-dist/tex/latex') diff --git a/Master/texmf-dist/tex/latex/witharrows/witharrows.sty b/Master/texmf-dist/tex/latex/witharrows/witharrows.sty index c3bd9a31d67..5f9619ed32c 100644 --- a/Master/texmf-dist/tex/latex/witharrows/witharrows.sty +++ b/Master/texmf-dist/tex/latex/witharrows/witharrows.sty @@ -1,341 +1,328 @@ -% This work may be distributed and modified under the -% conditions of the LaTeX Project Public License, either version 1.3 -% of this license or (at your option) any later version. -% The latest version of this license is in -% http://mirrors.ctan.org/help/Catalogue/licenses.lppl.html -% and version 1.3 or later is part of all distributions of LaTeX -% version 2005/12/01 or later. - - -% The author of this work is F. Pantigny (fpantigny at wanadoo point fr) - -\NeedsTeXFormat{LaTeX2e}[1994/06/01] - - +%% +%% This is file `witharrows.sty', +%% generated with the docstrip utility. +%% +%% The original source files were: +%% +%% witharrows.dtx (with options: `package') +%% +%% Copyright (C) 2017 by F. Pantigny +%% +%% This file may be distributed and/or modified under the +%% conditions of the LaTeX Project Public License, either +%% version 1.3 of this license or (at your option) any later +%% version. The latest version of this license is in: +%% +%% http://www.latex-project.org/lppl.txt +%% +%% and version 1.3 or later is part of all distributions of +%% LaTeX version 2005/12/01 or later. +%% +\def\myfileversion{1.1} +\def\myfiledate{2017/11/06} \RequirePackage{l3keys2e} - \ProvidesExplPackage - {WithArrows} - {2017/08/09} - {1.0} - {Draws arrows for explanations on the right side of a alignment.} - - + {witharrows} + {\myfiledate} + {\myfileversion} + {Draws arrows for explanations on the right} \RequirePackage{expl3} \RequirePackage{xparse} - \RequirePackage{tikz} -\usetikzlibrary{calc} -\usetikzlibrary{arrows.meta} -\usetikzlibrary{bending} - - - +\usetikzlibrary{calc,arrows.meta,bending} \RequirePackage{footnote} - - - -% There is a style for the tips of arrow because someone will use this style -% if he wants draw an arrow directly with a Tikz command in his document (probably using the Tikz nodes created by -% {WithArrows} in the \halign. -\tikzset{TipsOfWithArrows/.style= { > = {Straight~Barb[scale=1.2,bend]}} } - - -% The following variables are for the options ; these options can be set at 3 levels : see the groups of keys defined in -% the \keys_define:nn comand below. - -% if the beginning of the arrow use a "r" option (if not, it's a "l" option) -\bool_new:N \l_wa_initial_r_bool -\bool_set_true:N \l_wa_initial_r_bool - -% if the end of the arrow use a "r" option (if not, it's à "l" option) -\bool_new:N \l_wa_final_r_bool -\bool_set_true:N \l_wa_final_r_bool - -% if the arrow use a "i" option (in this case the options "l" and "r" for the ends are meaningless) -\bool_new:N \l_wa_i_bool -\bool_set_false:N \l_wa_i_bool - -% to translate the whole arrow to the right -\dim_new:N \l_wa_xoffset_dim -\dim_set:Nn \l_wa_xoffset_dim {3mm} - -% to indicate if the nodes will be drawn (in red) ; useful only for debugging -\bool_new:N \l_wa_shownodes_bool -\bool_set_false:N \l_wa_shownodes_bool - -% to indiate if the elements of the \halign will be composed with \displaystyle -\bool_new:N \l_wa_displaystyle_bool -\bool_set_false:N \l_wa_displaystyle_bool - -% will contains the Tikz options used to draw the arrow -\tl_clear_new:N \l_wa_options_tikz_tl -% At each possible level for the options ("global", "env" or "local : see below), the new values will be appended -% on the right of the token list \l_wa_options_tikz_tl - -% will be raised when a key controling position of the arrow has been set in the same list of key -% useful in order to raise an error if 2 incompatibles keys are specified at the same level -\bool_new:N \l_wa_position_key_already_set_bool -\bool_set_false:N \l_wa_position_key_already_set_bool - -% This Tikz style is for the nodes created automatically in the \halign. -\tikzstyle{wa_node_style}=[rectangle, +\tikzstyle{__wa_node_style}=[rectangle, inner~sep = 0 pt, minimum~height = 3 pt, minimum~width = 0pt, - red, % red... but will be drawn only if shownodes=true - \bool_if:NT \l_wa_shownodes_bool {draw}] - - - -% There are 3 levels where keys can be set : -% with \WithArrowsOptions{...} : this level will be called "global" level ; -% with \begin{WithArrows}[...] : this level will be called "env" level ; -% with \Arrow[...] : this level will be called "local" level. - -% That's why there is 3 groups of keys named "global", "env" and "local". - -% Before each \keys_set_groups:nnn, we execute a \keys_set_filter:nnn with group "secondary" -% Thus, an unknown key will raise an error. Furthermore, the "primary" keys (those which are not in the -% group "secondary") will be set first : it's useful to raise an error if, for example, keys "i" and "group" -% are set at the same level (which is incoherent). - -% There is also the group named "jump" (with only one key : "jump") for technical reasons. -\keys_define:nn {WithArrows} - { % the key named "jump" will be extracted in the \Arrow command - jump .groups:n = {jump,secondary}, - jump .code:n = {\int_set:Nn \l_jump_int {#1} - \int_compare:nNnF \l_jump_int > 0 - {\msg_error:nn {WithArrows} {The~option~"jump"~must~be~non~negative}}}, - jump .value_required:n = true, - % - % 0 = t = \vtop , 1 = c = \vcenter, 2 = b = \vbox - pos .groups:n = {global,env,secondary}, - pos .int_set:N = \l_wa_pos_int, - pos .initial:n = 0, - pos .value_required:n = true, - % - t .groups:n = {global,env,kown}, - t .meta:n = {pos=0}, - c .groups:n = {global,env,kown}, - c .meta:n = {pos=1}, - b .groups:n = {global,env,kown}, - b .meta:n = {pos=2}, - % - % if the user wants to give a new name to the \Arrow command (and the name \Arrow remains free) + red, + \bool_if:NT \l__wa_shownodes_bool {draw}] +\tikzset{TipsOfWithArrows/.style= { > = {Straight~Barb[scale=1.2,bend]}} } +\cs_if_free:NT \spread@equation + {\cs_set:Npn \spread@equation{\openup\jot + \cs_set_eq:NN \spread@equation \prg_do_nothing}} +\seq_new:N \g__wa_position_in_the_tree_seq +\seq_gput_right:Nn \g__wa_position_in_the_tree_seq 1 +\int_new:N \g__wa_last_env_int +\skip_new:N \l__wa_interline_skip +\bool_new:N \l__wa_MoreColumns_bool +\int_new:N \l__wa_pos_int +\bool_new:N \l__wa_initial_r_bool +\bool_set_true:N \l__wa_initial_r_bool +\bool_new:N \l__wa_final_r_bool +\bool_set_true:N \l__wa_final_r_bool +\bool_new:N \l__wa_i_bool +\dim_new:N \l__wa_xoffset_dim +\dim_set:Nn \l__wa_xoffset_dim {3mm} +\bool_new:N \l__wa_shownodes_bool +\bool_new:N \l__wa_shownodenames_bool +\bool_new:N \l__wa_displaystyle_bool +\tl_clear_new:N \l__wa_options_tikz_tl +\bool_new:N \l__wa_position_key_already_set_bool +\seq_new:N \g__wa_stack_counter_arrows_seq +\int_new:N \g__wa_arrow_int +\seq_new:N \g__wa_stack_counter_lines_seq +\int_new:N \g__wa_line_int +\seq_new:N \g__wa_stack_counter_lines_bis_seq +\int_new:N \g__wa_line_bis_int + +\keys_define:nn {WithArrows} + { jump .groups:n = {jump,secondary}, + jump .code:n = {\int_set:Nn \l__wa_jump_int {#1} + \int_compare:nNnF \l__wa_jump_int > 0 + {\msg_error:nn {witharrows} + {The~option~"jump"~must~be~non~negative}}}, + jump .value_required:n = true, + t .groups:n = {global,env,secondary}, + t .code:n = {\int_set:Nn \l__wa_pos_int 0}, + t .value_forbidden:n = true, + c .groups:n = {global,env,secondary}, + c .code:n = {\int_set:Nn \l__wa_pos_int 1}, + c .value_forbidden:n = true, + b .groups:n = {global,env,secondary}, + b .code:n = {\int_set:Nn \l__wa_pos_int 2}, + b .value_forbidden:n = true, + MoreColumns .groups:n = {global,env,secondary}, + MoreColumns .bool_set:N = \l__wa_MoreColumns_bool, + MoreColumns .default:n = true, + MoreColumns .value_forbidden:n = true, CommandName .groups:n = {global,env,secondary}, - CommandName .tl_set:N = \l_wa_CommandName_tl, + CommandName .tl_set:N = \l__wa_CommandName_tl, CommandName .initial:n = {Arrow}, CommandName .value_required:n = true, - % displaystyle .groups:n = {global,env,secondary}, - displaystyle .bool_set:N = \l_wa_displaystyle_bool, - displaystyle .value_forbidden:n = true, - % + displaystyle .bool_set:N = \l__wa_displaystyle_bool, % shownodes .groups:n = {global,env,secondary}, - shownodes .bool_set:N = \l_wa_shownodes_bool, + shownodes .bool_set:N = \l__wa_shownodes_bool, shownodes .default:n = true, - shownodes .value_forbidden:n = true, - % - jot .groups:n = {env,secondary}, % don't put "global" - jot .dim_set:N = \jot, % \jot is a LaTeX parameter for the distance between 2 lines in displaymath + shownodenames .groups:n = {global,env,secondary}, + shownodenames .bool_set:N = \l__wa_shownodenames_bool, + shownodenames .default:n = true, + jot .groups:n = {env,secondary}, + jot .dim_set:N = \jot, jot .value_required:n = true, - % + interline .groups:n = {env,secondary}, + interline .skip_set:N = \l__wa_interline_skip, + interline .initial:n = \c_zero_skip, + interline .value_required:n = true, xoffset .groups:n = {global,env,local,secondary}, - xoffset .dim_set:N = \l_wa_xoffset_dim, - xoffset .value_required:n = true, - % + xoffset .dim_set:N = \l__wa_xoffset_dim, + xoffset .value_required:n = true, tikz .groups:n = {global,env,local,secondary}, - tikz .code:n = {\tl_put_right:Nn \l_wa_options_tikz_tl {,#1}}, + tikz .code:n = {\tl_put_right:Nn \l__wa_options_tikz_tl {,#1}}, tikz .value_required:n = true, - % ll .groups:n = {global,env,local,secondary}, - ll .value_forbidden:n = true, + ll .value_forbidden:n = true, ll .default:n = true, - ll .code:n = {\bool_if:NT \l_wa_position_key_already_set_bool - {\msg_error:nn {WithArrows} {Two~options~are~incompatible}} - \bool_if:NT \l_wa_group_bool - {\msg_error:nn {WithArrows} {Option~incompatible~with~group}} - \bool_set_true:N \l_wa_position_key_already_set_bool - \bool_set_false:N \l_wa_initial_r_bool - \bool_set_false:N \l_wa_final_r_bool - \bool_set_false:N \l_wa_i_bool }, - % + ll .code:n = {\bool_if:NT \l__wa_position_key_already_set_bool + {\msg_error:nn {witharrows} + {Two~options~are~incompatible}} + \bool_if:NT \l__wa_group_bool + {\msg_error:nn {witharrows} + {Option~incompatible~with~group}} + \bool_set_true:N \l__wa_position_key_already_set_bool + \bool_set_false:N \l__wa_initial_r_bool + \bool_set_false:N \l__wa_final_r_bool + \bool_set_false:N \l__wa_i_bool }, lr .groups:n = {global,env,local,secondary}, lr .value_forbidden:n = true, - lr .default:n = true, - lr .code:n = {\bool_if:NT \l_wa_position_key_already_set_bool - {\msg_error:nn {WithArrows} {Two~options~are~incompatible}} - \bool_if:NT \l_wa_group_bool - {\msg_error:nn {WithArrows} {Option~incompatible~with~group}} - \bool_set_true:N \l_wa_position_key_already_set_bool - \bool_set_false:N \l_wa_initial_r_bool - \bool_set_true:N \l_wa_final_r_bool - \bool_set_false:N \l_wa_i_bool}, - % + lr .default:n = true, + lr .code:n = {\bool_if:NT \l__wa_position_key_already_set_bool + {\msg_error:nn {witharrows} + {Two~options~are~incompatible}} + \bool_if:NT \l__wa_group_bool + {\msg_error:nn {witharrows} + {Option~incompatible~with~group}} + \bool_set_true:N \l__wa_position_key_already_set_bool + \bool_set_false:N \l__wa_initial_r_bool + \bool_set_true:N \l__wa_final_r_bool + \bool_set_false:N \l__wa_i_bool}, rl .groups:n = {global,env,local,secondary}, rl .value_forbidden:n = true, - rl .default:n = true, - rl .code:n = {\bool_if:NT \l_wa_position_key_already_set_bool - {\msg_error:nn {WithArrows} {Two~options~are~incompatible}} - \bool_if:NT \l_wa_group_bool - {\msg_error:nn {WithArrows} {Option~incompatible~with~group}} - \bool_set_true:N \l_wa_position_key_already_set_bool - \bool_set_true:N \l_wa_initial_r_bool - \bool_set_false:N \l_wa_final_r_bool - \bool_set_false:N \l_wa_i_bool}, - % + rl .default:n = true, + rl .code:n = {\bool_if:NT \l__wa_position_key_already_set_bool + {\msg_error:nn {witharrows} + {Two~options~are~incompatible}} + \bool_if:NT \l__wa_group_bool + {\msg_error:nn {witharrows} + {Option~incompatible~with~group}} + \bool_set_true:N \l__wa_position_key_already_set_bool + \bool_set_true:N \l__wa_initial_r_bool + \bool_set_false:N \l__wa_final_r_bool + \bool_set_false:N \l__wa_i_bool}, rr .groups:n = {global,env,local,secondary}, rr .value_forbidden:n = true, - rr .default:n = true, - rr .code:n = {\bool_if:NT \l_wa_position_key_already_set_bool - {\msg_error:nn {WithArrows} {Two~options~are~incompatible}} - \bool_if:NT \l_wa_group_bool - {\msg_error:nn {WithArrows} {Option~incompatible~with~group}} - \bool_set_true:N \l_wa_position_key_already_set_bool - \bool_set_true:N \l_wa_initial_r_bool - \bool_set_true:N \l_wa_final_r_bool - \bool_set_false:N \l_wa_i_bool}, - % + rr .default:n = true, + rr .code:n = {\bool_if:NT \l__wa_position_key_already_set_bool + {\msg_error:nn {witharrows} + {Two~options~are~incompatible}} + \bool_if:NT \l__wa_group_bool + {\msg_error:nn {witharrows} + {Option~incompatible~with~group}} + \bool_set_true:N \l__wa_position_key_already_set_bool + \bool_set_true:N \l__wa_initial_r_bool + \bool_set_true:N \l__wa_final_r_bool + \bool_set_false:N \l__wa_i_bool}, i .groups:n = {global,env,local,secondary}, - i .code:n = {\bool_if:NT \l_wa_position_key_already_set_bool - {\msg_error:nn {WithArrows} {Two~options~are~incompatible}} - \bool_if:NT \l_wa_group_bool - {\msg_error:nn {WithArrows} {Option~incompatible~with~group}} - \bool_set_true:N \l_wa_position_key_already_set_bool - \bool_set_true:N \l_wa_i_bool}, + i .code:n = {\bool_if:NT \l__wa_position_key_already_set_bool + {\msg_error:nn {witharrows} + {Two~options~are~incompatible}} + \bool_if:NT \l__wa_group_bool + {\msg_error:nn {witharrows} + {Option~incompatible~with~group}} + \bool_set_true:N \l__wa_position_key_already_set_bool + \bool_set_true:N \l__wa_i_bool}, i .value_forbidden:n = true, i .default:n = true, - % - % indicate if all the arrows of an environment are grouped - % volontary not in "secondary" group : thus, if will be set first during the \keys_set_filter:nnn - group .groups:n = {global,env}, - group .bool_set:N = \l_wa_group_bool, + group .groups:n = {global,env}, + group .bool_set:N = \l__wa_group_bool, group .value_forbidden:n = true } - - - - - \ProcessKeysOptions {WithArrows} - - -% \WithArrowsOptions is the command of the WithArrows package to fix options at the document level \NewDocumentCommand \WithArrowsOptions {m} - {\bool_set_false:N \l_wa_position_key_already_set_bool - \keys_set_filter:nnn {WithArrows} {secondary} {#1} % in order to raise an error if a key is unknown + {\bool_set_false:N \l__wa_position_key_already_set_bool + \keys_set_filter:nnn {WithArrows} {secondary} {#1} \keys_set_groups:nnn {WithArrows} {global} {#1}} - - - +\NewDocumentCommand \__wa_Arrow {O{} m O{}} + {\tl_if_eq:noF {WithArrows} {\@currenvir} + {\msg_error:nn {witharrows} {Arrow~used~outside~{WithArrows}~environment}} + \int_gincr:N \g__wa_arrow_int + \int_zero_new:N \l__wa_jump_int + \int_set:Nn \l__wa_jump_int 1 + \keys_set_groups:nnn {WithArrows} {jump} {#1,#3} + \prop_put:NnV \l_tmpa_prop {initial} \g__wa_line_int + \int_set:Nn \l_tmpa_int {\g__wa_line_int + \l__wa_jump_int} + \prop_put:NnV \l_tmpa_prop {final} \l_tmpa_int + \prop_put:Nnn \l_tmpa_prop {options} {#1,#3} + \prop_put:Nnn \l_tmpa_prop {label} {#2} + \prop_gclear_new:c + {g__wa_arrow_\l__wa_prefix_tl _\int_use:N\g__wa_arrow_int _prop} + \prop_gset_eq:cN + {g__wa_arrow_\l__wa_prefix_tl _\int_use:N\g__wa_arrow_int _prop} + \l_tmpa_prop + } \NewDocumentEnvironment {WithArrows} {O{}} - {\reverse_if:N \if_mode_math: - \msg_error:nn {WithArrows} {WithArrows~used~outside~math~mode} + { \seq_gput_right:NV \g__wa_stack_counter_arrows_seq \g__wa_arrow_int + \int_gzero:N \g__wa_arrow_int + \seq_gput_right:NV \g__wa_stack_counter_lines_seq \g__wa_line_int + \int_gzero:N \g__wa_line_int + \seq_gput_right:NV \g__wa_stack_counter_lines_bis_seq \g__wa_line_bis_int + \int_gzero:N \g__wa_line_bis_int + \seq_gput_right:Nn \g__wa_position_in_the_tree_seq 1 + \seq_set_eq:NN \l_tmpa_seq \g__wa_position_in_the_tree_seq + \seq_pop_right:NN \l_tmpa_seq \l_tmpa_tl + \tl_clear_new:N \l__wa_prefix_tl + \tl_set:Nx \l__wa_prefix_tl {\seq_use:Nnnn \l_tmpa_seq {-} {-} {-}} + + \reverse_if:N \if_mode_math: + \msg_error:nn {witharrows} {{WithArrows}~used~outside~math~mode} \fi - \savenotes % to extract the footnotes of the environment {WithArrows} - \m@th - \def\\{\cr} - % - \int_gzero_new:N \g_wa_line_int % to count the lines in the \halign - % - % to count the arrows created in the environment - \int_gzero_new:N \g_wa_arrow_int - % - % these 3 counters will be used later as variables - \int_zero_new:N \l_initial_int - \int_zero_new:N \l_final_int - \int_zero_new:N \l_arrow_int - % - \bool_set_false:N \l_wa_position_key_already_set_bool - \keys_set_filter:nnn {WithArrows} {secondary} {#1} % in order to raise an error if a key is unknown + \savenotes + \cs_set_eq:NN \\ \__wa_cr: + \mathsurround = \c_zero_dim + \int_zero_new:N \l__wa_initial_int + \int_zero_new:N \l__wa_final_int + \int_zero_new:N \l__wa_arrow_int + \bool_set_false:N \l__wa_position_key_already_set_bool + \skip_zero:N \l__wa_interline_skip + \keys_set_filter:nnn {WithArrows} {secondary} {#1} \keys_set_groups:nnn {WithArrows} {env} {#1} - % - \cs_set:cpn \l_wa_CommandName_tl {\wa_Arrow} % new name for \Arrow command in {WithArrows} environments - % - \int_case:nnF \l_wa_pos_int % is fixed via the options t, c or b + \cs_set_eq:cN \l__wa_CommandName_tl \__wa_Arrow + \int_case:nn \l__wa_pos_int {0 {\vtop} 1 {\vcenter} 2 {\vbox}} - {\msg_error:nn {WithArrows} {Bad~value~for~option~pos}} \bgroup - \openup\jot + \spread@equation \ialign\bgroup - \int_gincr:N \g_wa_line_int % will be used for the names of the 2 nodes of the line + \int_gincr:N \g__wa_line_int \strut\hfil - $\bool_if:NT \l_wa_displaystyle_bool \displaystyle {##}$ - & - $\bool_if:NT \l_wa_displaystyle_bool \displaystyle {{}##}$ - % - % we create a first node (the "left node" of the line) - \tikz[remember~picture] - \node [wa_node_style] (wa-\int_use:N\g_wa_line_int-l) {} ; + $\bool_if:NT \l__wa_displaystyle_bool \displaystyle {##}$ + & + \int_gincr:N \g__wa_line_bis_int + $\bool_if:NT \l__wa_displaystyle_bool \displaystyle {{}##}$ + \tikz[remember~picture] + \node [__wa_node_style] + (wa-\tl_use:N\l__wa_prefix_tl-\int_use:N\g__wa_line_int-l) {} ; \hfil - % we create a second node (the "right node" of the line) - \tikz[remember~picture] - \node [wa_node_style] (wa-\int_use:N\g_wa_line_int-r) {} ; + \tikz[remember~picture,label~position=right] + \node [__wa_node_style] + (wa-\tl_use:N\l__wa_prefix_tl-\int_use:N\g__wa_line_int-r) {} ; + \bool_if:NT \l__wa_shownodenames_bool + {\hbox_overlap_right:n {\small wa-\tl_use:N\l__wa_prefix_tl + -\int_use:N\g__wa_line_int}} + && \bool_if:NF \l__wa_MoreColumns_bool + {\msg_error:nn {witharrows} {Third~column~in~a~{WithArrows}~environment}} + $\bool_if:NT \l__wa_displaystyle_bool \displaystyle {##}$ \cr } - {\crcr % - \egroup% end of halign - \egroup% end of vtop (or \vcenter or \vbox) - % - \int_compare:nNnT \g_wa_arrow_int > 0 % If there is really arrows... - \wa_draw_arrows: % ...we draw these arrows. + {\crcr + \egroup + \egroup + \int_compare:nNnT \g__wa_line_bis_int < \g__wa_line_int + {\msg_error:nn {witharrows} {All~lines~must~have~an~ampersand}} + \int_compare:nNnT \g__wa_arrow_int > 0 + \__wa_draw_arrows: \spewnotes + \seq_gpop_right:NN \g__wa_position_in_the_tree_seq \l_tmpa_tl + \seq_gpop_right:NN \g__wa_position_in_the_tree_seq \l_tmpa_tl + \seq_gput_right:Nx \g__wa_position_in_the_tree_seq {\int_eval:n {\l_tmpa_tl + 1}} + \int_compare:nNnT {\seq_count:N \g__wa_position_in_the_tree_seq} = 1 + {\int_gincr:N \g__wa_last_env_int} + \seq_gpop_right:NN \g__wa_stack_counter_arrows_seq {\l_tmpa_tl} + \int_gset:Nn \g__wa_arrow_int {\l_tmpa_tl} + \seq_gpop_right:NN \g__wa_stack_counter_lines_seq \l_tmpa_tl + \int_gset:Nn \g__wa_line_int {\l_tmpa_tl} + \seq_gpop_right:NN \g__wa_stack_counter_lines_bis_seq \l_tmpa_tl + \int_gset:Nn \g__wa_line_bis_int {\l_tmpa_tl} } - - - -% le following code is necessary because we whill have to expand un argument exactly 3 times +\cs_set_protected:Nn \__wa_cr: + {\scan_stop: + \group_align_safe_begin: + \peek_meaning_remove:NTF * \__wa_cr_i: \__wa_cr_i:} +\cs_set_protected:Nn \__wa_cr_i: + {\peek_meaning:NTF [ {\__wa_cr_ii:} {\__wa_cr_ii:[\c_zero_dim]} } +\cs_new_protected:Npn \__wa_cr_ii:[#1] + {\group_align_safe_end: + \cr\noalign{\skip_vertical:n {#1 + \l__wa_interline_skip} + \scan_stop:}} \cs_generate_variant:Nn \keys_set_groups:nnn {nno} -\cs_new:Nn \keys_set_groups_WithArrows_local: {\keys_set_groups:nno {WithArrows} {local}} - +\cs_new_protected:Nn \keys_set_groups_WithArrows_local: + {\keys_set_groups:nno {WithArrows} {local}} \cs_generate_variant:Nn \keys_set_filter:nnn {nno} -\cs_new:Nn \keys_set_filter_WithArrows_secondary: {\keys_set_filter:nno {WithArrows} {secondary}} - -\cs_new:Nn \wa_draw_arrows: - {% - % if the option "group" is used in the current environment - \bool_if:NT \l_wa_group_bool - \wa_x_computation_for_option_group: % will compute \g_wa_x_dim which is the abscissa of all the arrows - % - % loop over the arrows created in the environment : the arrows will be drawn - \int_set:Nn \l_arrow_int 1 - \int_until_do:nNnn \l_arrow_int > \g_wa_arrow_int % g_wa_arrow_int is the total number of arrows +\cs_new_protected:Nn \keys_set_filter_WithArrows_secondary: + {\keys_set_filter:nno {WithArrows} {secondary}} +\cs_new_protected:Nn \__wa_draw_arrows: + { + \bool_if:NT \l__wa_group_bool + \__wa_x_computation_for_option_group: + \int_set:Nn \l__wa_arrow_int 1 + \int_until_do:nNnn \l__wa_arrow_int > \g__wa_arrow_int { - % \l_initial_int is the line number from which the arrow starts - \int_set:Nn \l_initial_int {\int_use:c {wa_initial\int_use:N\l_arrow_int}} - % - % \l_final_int is the line number to which the arrow ends - \int_set:Nn \l_final_int {\int_use:c {wa_final\int_use:N\l_arrow_int}} - % - \int_compare:nNnT \l_final_int > \g_wa_line_int - {\msg_error:nn {WithArrows} {Too~few~lines~for~an~arrow}} - % - \group_begin: % for the options given in \Arrow[...] ("local level" of the options) + \prop_get:cnN {g__wa_arrow_\l__wa_prefix_tl _\int_use:N\l__wa_arrow_int _prop} + {initial} \l_tmpa_tl + \int_set:Nn \l__wa_initial_int {\l_tmpa_tl} + \prop_get:cnN {g__wa_arrow_\l__wa_prefix_tl _\int_use:N\l__wa_arrow_int _prop} + {final} \l_tmpa_tl + \int_set:Nn \l__wa_final_int {\l_tmpa_tl} + \int_compare:nNnT \l__wa_final_int > \g__wa_line_int + {\msg_error:nn {witharrows} {Too~few~lines~for~an~arrow}} + \group_begin: \keys_define:nn {WithArrows} {group .undefine:} - \bool_set_false:N \l_wa_position_key_already_set_bool - % the third argument de \keys_set_groups:nnn must be expanded exactly three times - % a x-expansion is not possible because there can be tokens like \bfseries in the option "font" - \exp_args:NNo \exp_args:No \keys_set_filter_WithArrows_secondary: {\use:c {wa_options\int_use:N\l_arrow_int}} - \exp_args:NNo \exp_args:No \keys_set_groups_WithArrows_local: {\use:c {wa_options\int_use:N\l_arrow_int}} - % - % In case of option "i", we have to compute the abscissa of the arrow (which is vertical). - \bool_if:NT \l_wa_i_bool - \wa_x_computation_for_option_i: % the abscissa is computed in \g_wa_x_dim - % - % \l_initial_tl contains the name of the Tikz node from which the arrow starts (in normal cases... - % because with option "group" or option "i", the point will perhaps have an other x-value --- but always the - % same y-value). - \tl_set:Nx \l_initial_tl {wa-\int_use:N\l_initial_int-\bool_if:NTF\l_wa_initial_r_bool rl} - % - % \l_final_tl contains the name of the Tikz node to which the arrow ends (in normal cases : with option - % "group" or option "i", the point will perhaps have an other x-value but always the same y-value) - \tl_set:Nx \l_final_tl {wa-\int_use:N\l_final_int-\bool_if:NTF\l_wa_final_r_bool rl . north} - % ". north" because we want a small gap between two consecutive arrows - % + \bool_set_false:N \l__wa_position_key_already_set_bool + \prop_get:cnN {g__wa_arrow_\l__wa_prefix_tl + _\int_use:N\l__wa_arrow_int _prop} {options} \l_tmpa_tl + \exp_args:NNo \exp_args:No \keys_set_filter_WithArrows_secondary: {\l_tmpa_tl} + \exp_args:NNo \exp_args:No \keys_set_groups_WithArrows_local: {\l_tmpa_tl} + \bool_if:NT \l__wa_i_bool + \__wa_x_computation_for_option_i: + \tl_set:Nx \l__wa_initial_tl + {wa-\tl_use:N\l__wa_prefix_tl-\int_use:N\l__wa_initial_int- + \bool_if:NTF\l__wa_initial_r_bool rl} + \tl_set:Nx \l__wa_final_tl + {wa-\tl_use:N\l__wa_prefix_tl-\int_use:N\l__wa_final_int- + \bool_if:NTF\l__wa_final_r_bool rl . north} \begin{tikzpicture}[remember~picture, overlay, align=left, @@ -345,161 +332,106 @@ ->, looseness=1, bend~left=45] - \draw \exp_after:wN [\l_wa_options_tikz_tl] - % \p1 and \p2 are the two ends of the arrow (in fact, not exactly in case of options "group" or "i") - let \p1 = (\tl_use:N \l_initial_tl), - \p2 = (\tl_use:N \l_final_tl) in - (\bool_if:nTF {\l_wa_group_bool || \l_wa_i_bool} - {\dim_use:N \g_wa_x_dim + \dim_use:N \l_wa_xoffset_dim, \y1} - {\x1 + \dim_use:N \l_wa_xoffset_dim, \y1} ) - to node (wa-a-\int_use:N\l_arrow_int) % in fact, this name will not be used by WithArrows - {\tl_use:c {wa_label\int_use:N\l_arrow_int}} - (\bool_if:nTF {\l_wa_group_bool || \l_wa_i_bool} - {\dim_use:N \g_wa_x_dim + \dim_use:N \l_wa_xoffset_dim, \y2} - {\x2 + \dim_use:N \l_wa_xoffset_dim, \y2} ) ; + \prop_get:cnN {g__wa_arrow_\l__wa_prefix_tl _\int_use:N\l__wa_arrow_int _prop} + {label} \l_tmpa_tl + \draw \exp_after:wN [\l__wa_options_tikz_tl] + let \p1 = (\tl_use:N \l__wa_initial_tl), + \p2 = (\tl_use:N \l__wa_final_tl) in + (\bool_if:nTF {\l__wa_group_bool || \l__wa_i_bool} + {\dim_use:N \g__wa_x_dim + \dim_use:N \l__wa_xoffset_dim, \y1} + {\x1 + \dim_use:N \l__wa_xoffset_dim, \y1} ) + to node [node~contents = {\tl_use:N \l_tmpa_tl}] {} + (\bool_if:nTF {\l__wa_group_bool || \l__wa_i_bool} + {\dim_use:N \g__wa_x_dim + \dim_use:N \l__wa_xoffset_dim, \y2} + {\x2 + \dim_use:N \l__wa_xoffset_dim, \y2} ) ; \end{tikzpicture} - \group_end: % for the options given to \Arrow[...] ("local level" of the options) - \int_incr:N \l_arrow_int - } % end of the loop over the arrows : all arrows are drawn + \group_end: + \int_incr:N \l__wa_arrow_int + } } - - -% We want to compute the x-value for the current environment which has option "group" (and therefore all arrows are -% vertical at the same abscissa). This value will be computed in \g_wa_x_dim (which is global for technical reasons : -% we have to do assignments in a \tikz command). -\cs_new:Nn \wa_x_computation_for_option_group: - {\dim_gzero_new:N \g_wa_x_dim - % - % first, we calculate the initial value for \g_wa_x_dim - % in this \tikz command, nothing is drawn : we only want to read the abscissa of a Tikz node - \tikz[remember~picture] - \path let \p1 = (wa-\int_use:c{wa_initial1}-l) % "let" is given by the Tikz library "calc" - in \pgfextra {\dim_gset:Nn \g_wa_x_dim {\x1}} ; % a global assignment is necessary because of \tikz - % - % Then, we loop to determine the maximal length of all the lines concerned by the arrows of the environment. - \int_set:Nn \l_arrow_int 1 - \int_until_do:nNnn \l_arrow_int > \g_wa_arrow_int % g_wa_arrow_int is the total number of arrows - { % \l_initial_int is the line number from which the arrow starts - \int_set:Nn \l_initial_int {\int_use:c {wa_initial\int_use:N\l_arrow_int}} - % - % \l_final_int is the line number to which the arrow ends - \int_set:Nn \l_final_int {\int_use:c {wa_final\int_use:N\l_arrow_int}} - % - \wa_x_computation_analyze_lines_between: %... between lines \l_initial_int and \l_final_int - % - \int_incr:N \l_arrow_int - } % end of the loop over the arrows of the environment - } - - -% We want to compute the x-value for the current arrow which has option "i" (and therefore is vertical). -% This value will be computed in \g_wa_x_dim (which is global for technical reasons : we have to do assignments in -% a \tikz command). -\cs_new:Nn \wa_x_computation_for_option_i: - {\dim_gzero_new:N \g_wa_x_dim - % First, we calculate the initial value for \g_wa_x_dim. - % In the next \tikz command, nothing is drawn : we only want to read a abscissa of a Tikz node. +\cs_new_protected:Nn \__wa_x_computation_for_option_i: + {\dim_gzero_new:N \g__wa_x_dim \tikz[remember~picture] - \path let \p1 = (wa-\int_use:N\l_initial_int-l) % "let" is given by the Tikz library "calc" - in \pgfextra {\dim_gset:Nn \g_wa_x_dim {\x1}} ; % a global assignment is necessary because of \tikz - % - \wa_x_computation_analyze_lines_between: %... between lines \l_initial_int and \l_final_int + \path let \p1 = (wa-\tl_use:N\l__wa_prefix_tl-\int_use:N\l__wa_initial_int-l) + in \pgfextra {\dim_gset:Nn \g__wa_x_dim {\x1}} ; + \__wa_x_computation_analyze_lines_between: } - - - - -% We analyse lines between \l_initial_int and \l_final_int in order to modify \g_wa_x_dim in consequence. -% More precisely, we will increase \g_wa_x_dim if we find a line longer than the current value of \g_wa_x_dim. -\cs_new:Nn \wa_x_computation_analyze_lines_between: - {\int_compare:nNnT \l_final_int > \g_wa_line_int - {\msg_error:nn {WithArrows} {Too~few~lines~for~an~arrow}} - % - % \l_tmpa_int will be the index of the loop - \int_set:Nn \l_tmpa_int \l_initial_int - \int_until_do:nNnn \l_tmpa_int > \l_final_int - {% in the next \tikz command, nothing is drawn : we only want to read the abscissa of a Tikz node - \tikz[remember~picture] - \path let \p1 = (wa-\int_use:N\l_tmpa_int-l) - in \pgfextra {\dim_gset:Nn \g_wa_x_dim {\dim_max:nn \g_wa_x_dim {\x1}}} ; % \gset because of \tikz +\cs_new_protected:Nn \__wa_x_computation_analyze_lines_between: + {\int_compare:nNnT \l__wa_final_int > \g__wa_line_int + {\msg_error:nn {witharrows} {Too~few~lines~for~an~arrow}} + \int_set:Nn \l_tmpa_int \l__wa_initial_int + \int_until_do:nNnn \l_tmpa_int > \l__wa_final_int + {\tikz[remember~picture] + \path let \p1 = (wa-\tl_use:N\l__wa_prefix_tl-\int_use:N\l_tmpa_int-l) + in \pgfextra {\dim_gset:Nn \g__wa_x_dim {\dim_max:nn \g__wa_x_dim {\x1}}} ; \int_incr:N \l_tmpa_int - } % loop on the lines between \l_initial_int et \l_final_int - } - - - + } + } +\cs_new_protected:Nn \__wa_x_computation_for_option_group: + {\dim_gzero_new:N \g__wa_x_dim + \prop_get:cnN {g__wa_arrow_\l__wa_prefix_tl _1_prop} {initial} \l_tmpa_tl + \tikz[remember~picture] + \path let \p1 = (wa-\tl_use:N\l__wa_prefix_tl-\tl_use:N\l_tmpa_tl-l) + in \pgfextra {\dim_gset:Nn \g__wa_x_dim {\x1}} ; + \int_set:Nn \l__wa_arrow_int 1 + \int_until_do:nNnn \l__wa_arrow_int > \g__wa_arrow_int + { + \prop_get:cnN {g__wa_arrow_\l__wa_prefix_tl _\int_use:N\l__wa_arrow_int _prop} + {initial} \l_tmpa_tl + \int_set:Nn \l__wa_initial_int {\l_tmpa_tl} + \prop_get:cnN {g__wa_arrow_\l__wa_prefix_tl _\int_use:N\l__wa_arrow_int _prop} + {final} \l_tmpa_tl + \int_set:Nn \l__wa_final_int {\l_tmpa_tl} + \__wa_x_computation_analyze_lines_between: + \int_incr:N \l__wa_arrow_int + } + } \cs_generate_variant:Nn \int_compare:nNnT {cNnT} - -\cs_generate_variant:Nn \tl_if_eq:nnF {onF} - - -% The next command has a strange name, but, in fact, usually, we will have \let\Arrow\wa_Arrow ; -% The user can use the CommandName option if he wants an other name for the command called \Arrow by default. -% It's useful if the user already has a command named "\Arrow" he still wants to use. -\NewDocumentCommand \wa_Arrow {O{} m O{}} - {\tl_if_eq:onF {\@currenvir} {WithArrows} - {\msg_fatal:nn {WithArrows} {Arrow~used~outside~{WithArrows}~environment}} - % - % \g_wa_arrow_int counts the arrows in the environment - \int_gincr:N \g_wa_arrow_int - % - % we decide to extract immediatly the key "jump" in ordre to compute the end line ; - \int_zero_new:N \l_jump_int - \int_set:Nn \l_jump_int 1 - \keys_set_groups:nnn {WithArrows} {jump} {#1,#3} % "jump" is the only key of the group "jump" - % - % to stock the informations of the considered arrow (in four variables) ; - % these informations will be used when the arrow will be really drawn - \int_gzero_new:c {wa_initial\int_use:N\g_wa_arrow_int} - \int_gset_eq:cN {wa_initial\int_use:N\g_wa_arrow_int} \g_wa_line_int - % - \int_gzero_new:c {wa_final\int_use:N\g_wa_arrow_int} - \int_gset:cn {wa_final\int_use:N\g_wa_arrow_int} {\g_wa_line_int + \l_jump_int} - % - \tl_gclear_new:c {wa_options\int_use:N\g_wa_arrow_int} - \tl_gset:cn {wa_options\int_use:N\g_wa_arrow_int} {#1,#3} - % - \tl_gclear_new:c {wa_label\int_use:N\g_wa_arrow_int} - \tl_gset:cn {wa_label\int_use:N\g_wa_arrow_int} {#2} - % - } - - - -\msg_new:nnn {WithArrows} +\cs_generate_variant:Nn \tl_if_eq:nnF {noF} +\bigskip +\NewDocumentCommand \WithArrowsLastEnv {} + {\int_use:N \g__wa_last_env_int} +\msg_new:nnn {witharrows} + {Third~column~in~a~{WithArrows}~environment} + {By~default,~a~\{WithArrows\}~environment~can~only~have~two~columns.~ + Maybe~you~have~forgotten~a~newline~symbol.~If~you~really~want~ + more~than~two~columns,~you~should~use~the~option~"MoreColumns"~at~ + a~global~level~or~for~an~environment.~However,~you~can~go~one~for~this~time.} +\msg_new:nnn {witharrows} {Arrow~used~outside~{WithArrows}~environment} - {Arrow~command~should~be~used~only~directly~in~\{WithArrows\}~environment\\ - and~not~in~a~subenvironment.} - -\msg_new:nnn {WithArrows} + {The~command~\string\Arrow\space~should~be~used~only~directly~ + in~\{WithArrows\}~environment~and~not~in~a~subenvironment.~However,~you~ + can~go~on.} +\msg_new:nnn {witharrows} {The~option~"jump"~must~be~non~negative} - {You~can't~use~a~stricly~negative~value~for~the~option~"jump"~of~command~Arrow\\ - You~can~create~an~arrow~going~backwards~with~the~option~"<-"~of~Tikz.} - -\msg_new:nnn {WithArrows} + {You~can't~use~a~strictly~negative~value~for~the~option~"jump"~of~command~ + \string\Arrow.~ You~can~create~an~arrow~going~backwards~with~ + the~option~"<-"~of~Tikz.} +\msg_new:nnn {witharrows} {Too~few~lines~for~an~arrow} - {There~is~at~least~an~arrow~that~can't~be~drawn~because~it~arrives~after~the\\ + {There~is~at~least~an~arrow~that~can't~be~drawn~because~it~arrives~after~the~ last~line~of~the~environment.} - -\msg_new:nnn {WithArrows} - {Bad~value~for~option~pos} - {The~option~"pos"~of~the~environment~\{WithArrows\}~must~be~equal~to\\ - 0,~1,~or~2.} - -\msg_new:nnn {WithArrows} - {WithArrows~used~outside~math~mode} - {The~environment~WithArrows~must~be~used~only~in~math~mode.} - -\msg_new:nnn {WithArrows} +\msg_new:nnn {witharrows} + {{WithArrows}~used~outside~math~mode} + {The~environment~\{WithArrows\}~should~be~used~only~in~math~mode.~ + Nevertheless,~you~can~go~on.} +\msg_new:nnn {witharrows} {Option~incompatible~with~group} - {You~try~to~use~the~option~"\tl_use:N\l_keys_key_tl"~while~you~are~using~the~option~"group".\\ - It's~incompatible.~You~can~go~on~ignoring~this~option~"\tl_use:N\l_keys_key_tl"~and~"group"~will~be~used.} - - -\msg_new:nnn {WithArrows} + {You~try~to~use~the~option~"\tl_use:N\l_keys_key_tl"~while~ + you~are~using~the~option~"group".~It's~incompatible.~You~can~go~on~ignoring~ + this~option~"\tl_use:N\l_keys_key_tl"~and~"group"~will~be~used.} +\msg_new:nnn {witharrows} {Two~options~are~incompatible} - {You~try~to~use~the~option~"\tl_use:N\l_keys_key_tl"~but~this~option~is~incompatible\\ - with~an~option~previously~set.~If~you~go~on,~it~will~overwrite~the~previous~option.} - - -\endinput \ No newline at end of file + {You~try~to~use~the~option~"\tl_use:N\l_keys_key_tl"~but~ + this~option~is~incompatible~with~an~option~previously~set.~ + If~you~go~on,~I~will~overwrite~the~previous~option.} +\msg_new:nnnn {witharrows} + {All~lines~must~have~an~ampersand} + {All~lines~of~an~environment~\{WithArrows\}~must~have~an~second~column~ + (because~the~nodes~are~created~in~the~second~column).~You~can~go~on~but~maybe~ + you~will~have~an~pgf~error~for~an~undefined~shape.} + {The~ampersand~can~be~implicit~ + (e.g.~if~you~use~\string\MoveEqLeft\space~of~mathtools).} +\endinput +%% +%% End of file `witharrows.sty'. -- cgit v1.2.3