summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/tex/latex/witharrows/witharrows.sty
blob: c3bd9a31d67c4cc662ecd9c1c31bd7881c363d56 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
% 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]


\RequirePackage{l3keys2e}

\ProvidesExplPackage
  {WithArrows}
  {2017/08/09}
  {1.0}
  {Draws arrows for explanations on the right side of a alignment.} 


\RequirePackage{expl3}
\RequirePackage{xparse}

\RequirePackage{tikz}
\usetikzlibrary{calc}
\usetikzlibrary{arrows.meta}
\usetikzlibrary{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,
                           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)
      CommandName .groups:n         = {global,env,secondary},
      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,
      %
      %
      shownodes .groups:n          = {global,env,secondary},
      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
      jot       .value_required:n  = true,
      %
      xoffset  .groups:n          = {global,env,local,secondary},
      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     .value_required:n  = true,
      %
      ll       .groups:n          = {global,env,local,secondary},
      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 },
      %
      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},
      %
      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},
      %
      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},
      %
      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        .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        .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
     \keys_set_groups:nnn {WithArrows} {global} {#1}}



\NewDocumentEnvironment {WithArrows} {O{}}
          {\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
           \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
                   {0 {\vtop}
                    1 {\vcenter}
                    2 {\vbox}}
                   {\msg_error:nn {WithArrows} {Bad~value~for~option~pos}}
           \bgroup
           \openup\jot
           \ialign\bgroup
           \int_gincr:N \g_wa_line_int % will be used for the names of the 2 nodes of the line
           \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) {} ;
           \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) {} ;
           \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.
           \spewnotes
           }



% le following code is necessary because we whill have to expand un argument exactly 3 times
\cs_generate_variant:Nn \keys_set_groups:nnn {nno}
\cs_new: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
     {
      % \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)
           \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
           % 
           \begin{tikzpicture}[remember~picture,
                               overlay,
                               align=left,
                               auto=left,
                               font = {\small\itshape},
                               TipsOfWithArrows,
                               ->,
                               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} ) ; 
           \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
     }


% 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.
   \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
   }



        
% 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
          \int_incr:N \l_tmpa_int
         } % loop on the lines between \l_initial_int et \l_final_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}
             {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~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}          
             {Too~few~lines~for~an~arrow}
             {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}
             {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}
             {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