summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/tex/latex/nicematrix/nicematrix.sty
blob: d0c2e771cc6625ce62c07cb5d7c504ef4e099d80 (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
%%
%% This is file `nicematrix.sty',
%% generated with the docstrip utility.
%%
%% The original source files were:
%%
%% nicematrix.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.0}
\def\myfiledate{2018/02/13}
\RequirePackage{tikz}
\usetikzlibrary{calc,math}
\RequirePackage{l3keys2e}
\ProvidesExplPackage
  {nicematrix}
  {\myfiledate}
  {\myfileversion}
  {Draws nice dotted lines in matrix environments}
\RequirePackage{array}
\RequirePackage{mathtools}
\RequirePackage{xparse}
\ProvideDocumentCommand \iddots {}
      {\mathinner{\mkern 1mu
                  \raise 1pt \hbox{.}
                  \mkern 2mu
                  \raise 4pt\hbox{.}
                  \mkern 2mu
                  \raise7pt \vbox{\kern 7pt
                                  \hbox{.}}
                  \mkern1mu}}
\cs_new_protected:Nn \__nm_multicolumn:nn
       {\msg_error:nn {nicematrix} {multicolumn~forbidden}}
\int_new:N \g__nm_env_int
\bool_new:N \l__nm_parallelize_diags_bool
\bool_set_true:N \l__nm_parallelize_diags_bool
\bool_new:N \l__nm_nullify_dots_bool
\bool_new:N \l__nm_renew_matrix_bool
\keys_define:nn {NiceMatrix}
     {ParallelizeDiagonals .bool_set:N = \l__nm_parallelize_diags_bool,
      ParallelizeDiagonals .default:n  = true,
      RenewDots            .bool_set:N = \l__nm_renew_dots_bool,
      RenewDots            .default:n  = true,
      RenewMatrix          .code:n     = {\cs_set_eq:NN \env@matrix \NiceMatrix
                                          \bool_set_true:N \l__nm_renew_matrix_bool},
      RenewMatrix          .default:n  = true,
      Transparent          .meta:n     = {RenewDots,RenewMatrix},
      Transparent          .value_forbidden:n = true,
      NullifyDots          .bool_set:N = \l__nm_nullify_dots_bool ,
      NullifyDots          .default:n  = true}
\NewDocumentCommand \NiceMatrixOptions {m}
    {\keys_set:nn {NiceMatrix} {#1}}
\cs_new_protected:Nn \__nm_Cell:
   {
    \int_gincr:N \g__nm_column_int
    \int_gset:Nn \g__nm_nb_column_int {\int_max:nn \g__nm_nb_column_int \g__nm_column_int}
    \tikz[remember~picture, inner~sep = 0pt, minimum~width = 0pt, baseline]
       \node [anchor=base] (nm-\int_use:N \g__nm_env_int-
                               \int_use:N \g__nm_line_int-
                               \int_use:N \g__nm_column_int)
       \bgroup $} % $
\cs_new_protected:Nn \__nm_end_Cell:
   {$\egroup ;} % $
\cs_new_protected:Nn \__nm_Cell_First_Column:
   {\int_gincr:N \g__nm_line_int
    \int_gset:Nn \g__nm_column_int 0
    \__nm_Cell:}
\NewDocumentEnvironment {NiceMatrix} {}
   {
    \aftergroup \__nm_draw_lines:
    \cs_set_eq:NN \Ldots \__nm_Ldots
    \cs_set_eq:NN \Cdots \__nm_Cdots
    \cs_set_eq:NN \Vdots \__nm_Vdots
    \cs_set_eq:NN \Ddots \__nm_Ddots
    \cs_set_eq:NN \Iddots \__nm_Iddots
    \cs_set_eq:NN \Hspace \__nm_Hspace:
    \cs_set_eq:NN \NiceMatrixEndPoint \__nm_NiceMatrixEndPoint:
    \bool_if:NF \l__nm_renew_matrix_bool
        {\cs_set_eq:NN \multicolumn \__nm_multicolumn:nn}
    \bool_if:NT \l__nm_renew_dots_bool
       {\cs_set_eq:NN \ldots \__nm_Ldots
        \cs_set_eq:NN \cdots \__nm_Cdots
        \cs_set_eq:NN \vdots \__nm_Vdots
        \cs_set_eq:NN \ddots \__nm_Ddots
        \cs_set_eq:NN \iddots \__nm_Iddots
        \cs_set_eq:NN \dots  \__nm_Ldots}
    \int_gincr:N \g__nm_env_int
    \seq_gclear_new:N  \g__nm_empty_cells_seq
    \int_gzero_new:N \g__nm_instruction_int
    \int_gzero_new:N \g__nm_line_int
    \int_gzero_new:N \g__nm_column_int
    \int_gzero_new:N \g__nm_nb_column_int
    \hskip -\arraycolsep
    \cs_set_eq:NN \@ifnextchar \new@ifnextchar
    \int_set:Nn \l_tmpa_int {\c@MaxMatrixCols - 1}
    \array{>{\__nm_Cell_First_Column:}c<{\__nm_end_Cell:}
                  *\l_tmpa_int{>{\__nm_Cell:}c<{\__nm_end_Cell:}}}}
   {\endarray
    \hskip -\arraycolsep}
\NewDocumentEnvironment {pNiceMatrix} {}
   {\left(\begin{NiceMatrix}}
   {\end{NiceMatrix}\right)}
\NewDocumentEnvironment {bNiceMatrix} {}
   {\left[\begin{NiceMatrix}}
   {\end{NiceMatrix}\right]}
\NewDocumentEnvironment {BNiceMatrix} {}
   {\left\{\begin{NiceMatrix}}
   {\end{BNiceMatrix}\right\}}
\NewDocumentEnvironment {vNiceMatrix} {}
   {\left\lvert\begin{NiceMatrix}}
   {\end{BNiceMatrix}\right\rvert}
\NewDocumentEnvironment {VNiceMatrix} {}
   {\left\lVert\begin{NiceMatrix}}
   {\end{BNiceMatrix}\right\rVert}
\prg_set_conditional:Npnn \__nm_if_not_empty_cell:nn #1#2 {T}
       {\cs_if_exist:cTF {pgf@sh@ns@nm-
                                    \int_use:N \g__nm_env_int-
                                    \int_use:N #1-
                                    \int_use:N #2}
          {\seq_if_in:NxTF \g__nm_empty_cells_seq
                           {\int_use:N #1-\int_use:N #2}
             {\prg_return_false:}
             {\tikz[remember~picture]
                \path let \p1 = (nm-
                                 \int_use:N \g__nm_env_int-
                                 \int_use:N #1-
                                 \int_use:N #2.east),
                          \p2 = (nm-
                                 \int_use:N \g__nm_env_int-
                                 \int_use:N #1-
                                 \int_use:N #2.west)
                      in \pgfextra {\dim_gset:Nn \g_tmpa_dim {\x1}
                                    \dim_gset:Nn \g_tmpb_dim {\x2}} ;
              \dim_gsub:Nn \g_tmpa_dim \g_tmpb_dim
              \dim_compare:nNnTF {\dim_abs:n \g_tmpa_dim} < {0.5 pt}
                    {\prg_return_false:}
                    {\prg_return_true:}}}
          {\prg_return_false:}
       }
\cs_new_protected:Nn \__nm_instruction_of_type:n
     {\int_gincr:N \g__nm_instruction_int
      \prop_put:Nnn \l_tmpa_prop {type} {#1}
      \prop_put:NnV \l_tmpa_prop {line} \g__nm_line_int
      \prop_put:NnV \l_tmpa_prop {column} \g__nm_column_int
      \prop_gclear_new:c
         {g__nm_instruction_\int_use:N\g__nm_instruction_int _prop}
      \prop_gset_eq:cN
         {g__nm_instruction_\int_use:N\g__nm_instruction_int _prop}
         \l_tmpa_prop
      }

\cs_new_protected:Nn \__nm_draw_lines:
    {
     \seq_clear_new:N \l__nm_yet_drawn_seq
     \int_zero_new:N \l__nm_type_int
     \int_zero_new:N \l__nm_line_int
     \int_zero_new:N \l__nm_column_int
     \int_zero_new:N \l__nm_di_int
     \int_zero_new:N \l__nm_dj_int
     \bool_if:NT \l__nm_parallelize_diags_bool
          {\int_zero_new:N \l__nm_ddots_int
           \int_zero_new:N \l__nm_iddots_int
           \dim_zero_new:N \l__nm_delta_x_one_dim
           \dim_zero_new:N \l__nm_delta_y_one_dim
           \dim_zero_new:N \l__nm_delta_x_two_dim
           \dim_zero_new:N \l__nm_delta_y_two_dim}
     \int_zero_new:N \l__nm_instruction_int
     \int_incr:N \l__nm_instruction_int
     \int_until_do:nNnn \l__nm_instruction_int > \g__nm_instruction_int
        {
         \prop_get:cnN {g__nm_instruction_\int_use:N \l__nm_instruction_int _prop}
                        {type} \l_tmpa_tl
         \int_set:Nn \l__nm_type_int {\l_tmpa_tl}
         \prop_get:cnN {g__nm_instruction_\int_use:N \l__nm_instruction_int _prop}
                        {line} \l_tmpa_tl
         \int_set:Nn \l__nm_line_int {\l_tmpa_tl}
         \prop_get:cnN {g__nm_instruction_\int_use:N \l__nm_instruction_int _prop}
                        {column} \l_tmpa_tl
         \int_set:Nn \l__nm_column_int {\l_tmpa_tl}
           \int_case:nn \l__nm_type_int
             { 0 {\int_set:Nn \l__nm_di_int 0
                  \int_set:Nn \l__nm_dj_int 1}
               1 {\int_set:Nn \l__nm_di_int 0
                  \int_set:Nn \l__nm_dj_int 1}
               2 {\int_set:Nn \l__nm_di_int 1
                  \int_set:Nn \l__nm_dj_int 0}
               3 {\int_set:Nn \l__nm_di_int 1
                  \int_set:Nn \l__nm_dj_int 1}
               4 {\int_set:Nn \l__nm_di_int 1
                  \int_set:Nn \l__nm_dj_int {-1}}}
           \bool_if_exist:NTF \l__nm_impossible_instruction_bool
               {\bool_set_false:N \l__nm_impossible_instruction_bool}
               {\bool_new:N \l__nm_impossible_instruction_bool}
           \int_zero_new:N  \l__nm_final_i_int
           \int_zero_new:N  \l__nm_final_j_int
           \int_set:Nn \l__nm_final_i_int \l__nm_line_int
           \int_set:Nn \l__nm_final_j_int \l__nm_column_int
           \bool_if_exist:NTF \l__nm_stop_loop_bool
                  {\bool_set_false:N \l__nm_stop_loop_bool}
                  {\bool_new:N \l__nm_stop_loop_bool}
           \bool_do_until:Nn \l__nm_stop_loop_bool
              {\int_add:Nn \l__nm_final_i_int \l__nm_di_int
               \int_add:Nn \l__nm_final_j_int \l__nm_dj_int
               \bool_if:nTF { \int_compare_p:nNn \l__nm_final_i_int < 1
                           || \int_compare_p:nNn \l__nm_final_i_int > \g__nm_line_int
                           || \int_compare_p:nNn \l__nm_final_j_int < 1
                           || \int_compare_p:nNn \l__nm_final_j_int > \g__nm_nb_column_int}
                       {\bool_set_true:N \l__nm_impossible_instruction_bool
                        \bool_set_true:N \l__nm_stop_loop_bool}
                       {\__nm_if_not_empty_cell:nnT \l__nm_final_i_int \l__nm_final_j_int
                              {\bool_set_true:N \l__nm_stop_loop_bool}}
               }
           \int_zero_new:N  \l__nm_initial_i_int
           \int_zero_new:N  \l__nm_initial_j_int
           \int_set:Nn \l__nm_initial_i_int \l__nm_line_int
           \int_set:Nn \l__nm_initial_j_int \l__nm_column_int
           \bool_set_eq:NN \l__nm_stop_loop_bool \l__nm_impossible_instruction_bool
           \bool_do_until:Nn \l__nm_stop_loop_bool
              {\int_sub:Nn \l__nm_initial_i_int \l__nm_di_int
               \int_sub:Nn \l__nm_initial_j_int \l__nm_dj_int
               \bool_if:nTF
                       {   \int_compare_p:nNn \l__nm_initial_i_int < 1
                        || \int_compare_p:nNn \l__nm_initial_i_int > \g__nm_line_int
                        || \int_compare_p:nNn \l__nm_initial_j_int < 1
                        || \int_compare_p:nNn \l__nm_initial_j_int > \g__nm_nb_column_int}
                       {\bool_set_true:N \l__nm_impossible_instruction_bool
                        \bool_set_true:N \l__nm_stop_loop_bool}
                       {\__nm_if_not_empty_cell:nnT \l__nm_initial_i_int \l__nm_initial_j_int
                              {\bool_set_true:N \l__nm_stop_loop_bool}}
               }
          \bool_if:NTF \l__nm_impossible_instruction_bool
            {\msg_error:nn {nicematrix} {Impossible~instruction}}
            {\tl_set:Nx \l_tmpa_tl {\int_use:N \l__nm_initial_i_int-
                                    \int_use:N \l__nm_initial_j_int-
                                    \int_use:N \l__nm_final_i_int-
                                    \int_use:N \l__nm_final_j_int}
             \seq_if_in:NVF \l__nm_yet_drawn_seq \l_tmpa_tl
              {\seq_put_left:NV \l__nm_yet_drawn_seq \l_tmpa_tl
               \dim_zero_new:N \g__nm_x_initial_dim
               \dim_zero_new:N \g__nm_y_initial_dim
               \dim_zero_new:N \g__nm_x_final_dim
               \dim_zero_new:N \g__nm_y_final_dim
               \int_case:nn \l__nm_type_int
                {0  \__nm_draw_ldots_line:
                 1  \__nm_draw_cdots_line:
                 2  \__nm_draw_vdots_line:
                 3  \__nm_draw_ddots_line:
                 4  \__nm_draw_iddots_line:}}}
            \int_incr:N \l__nm_instruction_int
         }
}
\cs_new_protected:Nn \__nm_retrieve_coords:nn
     {\tikz[remember~picture]
       \path let \p1 = (nm-\int_use:N \g__nm_env_int-
                           \int_use:N \l__nm_initial_i_int-
                           \int_use:N \l__nm_initial_j_int #1),
                 \p2 = (nm-\int_use:N \g__nm_env_int-
                           \int_use:N \l__nm_final_i_int-
                           \int_use:N \l__nm_final_j_int #2)
             in \pgfextra {\dim_gset:Nn \g__nm_x_initial_dim {\x1}
                           \dim_gset:Nn \g__nm_y_initial_dim {\y1}
                           \dim_gset:Nn \g__nm_x_final_dim {\x2}
                           \dim_gset:Nn \g__nm_y_final_dim {\y2}} ; }
\cs_new_protected:Nn \__nm_draw_ldots_line:
      {\__nm_retrieve_coords:nn {.south~east} {.south~west}
       \__nm_draw_tikz_line:}
\cs_new_protected:Nn \__nm_draw_cdots_line:
      {\__nm_retrieve_coords:nn {.mid~east} {.mid~west}
       \__nm_draw_tikz_line:}
\cs_new_protected:Nn \__nm_draw_vdots_line:
      {\__nm_retrieve_coords:nn {.south} {.north}
       \__nm_draw_tikz_line:}
\cs_new_protected:Nn \__nm_draw_ddots_line:
   {\__nm_retrieve_coords:nn {.south~east} {.north~west}
    \bool_if:NT \l__nm_parallelize_diags_bool
       {\int_incr:N \l__nm_ddots_int
        \int_compare:nNnTF \l__nm_ddots_int = 1
          {\dim_set:Nn \l__nm_delta_x_one_dim {\g__nm_x_final_dim - \g__nm_x_initial_dim }
           \dim_set:Nn \l__nm_delta_y_one_dim {\g__nm_y_final_dim - \g__nm_y_initial_dim }}
          {\dim_gset:Nn \g__nm_y_final_dim
                  {\g__nm_y_initial_dim +
                      (\g__nm_x_final_dim - \g__nm_x_initial_dim)
                      * \dim_ratio:nn \l__nm_delta_y_one_dim \l__nm_delta_x_one_dim }}}
    \__nm_draw_tikz_line:}
\cs_new_protected:Nn \__nm_draw_iddots_line:
   {\__nm_retrieve_coords:nn {.south~west} {.north~east}
    \bool_if:NT \l__nm_parallelize_diags_bool
       {\int_incr:N \l__nm_iddots_int
        \int_compare:nNnTF \l__nm_iddots_int = 1
          {\dim_set:Nn \l__nm_delta_x_two_dim {\g__nm_x_final_dim - \g__nm_x_initial_dim }
           \dim_set:Nn \l__nm_delta_y_two_dim {\g__nm_y_final_dim - \g__nm_y_initial_dim }}
          {\dim_gset:Nn \g__nm_y_final_dim
                  {\g__nm_y_initial_dim +
                      (\g__nm_x_final_dim - \g__nm_x_initial_dim)
                      * \dim_ratio:nn \l__nm_delta_y_two_dim \l__nm_delta_x_two_dim }}}
    \__nm_draw_tikz_line:}

\cs_new_protected:Nn \__nm_draw_tikz_line:
                     {\begin{tikzpicture}[overlay]
                        \tikzmath{
                           coordinate~\a , \b ;
                           real~\l, \x, \d ;
                           integer~\n ;
                           \a = (\g__nm_x_initial_dim, \g__nm_y_initial_dim) ;
                           \b = (\g__nm_x_final_dim,  \g__nm_y_final_dim) ;
                           \l = veclen(\bx-\ax,\by-\ay) ;
                           \n = (\l - 0.54em)/(0.45em) ;
                           \x = (\l - \n*0.45em)/(2*\l) ;
                           \d = 0.45em / \l ;
                           if~\n>0
                           then~{ for~\k in~{0,...,\n}
                                  { {\node at ($(\a)!\x+\k*\d!(\b)$) {.} ; } ; } ;
                            }  ;
                           }
                      \end{tikzpicture}}
\cs_set_eq:NN \__nm_ldots \ldots
\cs_set_eq:NN \__nm_cdots \cdots
\cs_set_eq:NN \__nm_vdots \vdots
\cs_set_eq:NN \__nm_ddots \ddots
\cs_set_eq:NN \__nm_iddots \iddots
\cs_new_protected:Nn \__nm_add_to_empty_cells:
    {\seq_gput_right:Nx \g__nm_empty_cells_seq
          {\int_use:N \g__nm_line_int-
           \int_use:N \g__nm_column_int}}
\NewDocumentCommand \__nm_Ldots {s}
    {\IfBooleanF {#1} {\__nm_instruction_of_type:n 0}
     \bool_if:NF \l__nm_nullify_dots_bool {\phantom \__nm_ldots}
     \__nm_add_to_empty_cells:}
\NewDocumentCommand \__nm_Cdots {s}
    {\IfBooleanF {#1} {\__nm_instruction_of_type:n 1}
     \bool_if:NF \l__nm_nullify_dots_bool {\phantom \__nm_cdots}
     \__nm_add_to_empty_cells:}
\NewDocumentCommand \__nm_Vdots {s}
    {\IfBooleanF {#1} {\__nm_instruction_of_type:n 2}
     \bool_if:NF \l__nm_nullify_dots_bool {\phantom \__nm_vdots}
     \__nm_add_to_empty_cells:}
\NewDocumentCommand \__nm_Ddots {s}
    {\IfBooleanF {#1} {\__nm_instruction_of_type:n 3}
     \bool_if:NF \l__nm_nullify_dots_bool {\phantom \__nm_ddots}
     \__nm_add_to_empty_cells:}
\NewDocumentCommand \__nm_Iddots {s}
    {\IfBooleanF {#1} {\__nm_instruction_of_type:n 4}
     \bool_if:NF \l__nm_nullify_dots_bool {\phantom \__nm_iddots}
     \__nm_add_to_empty_cells:}
\cs_new_protected:Nn \__nm_Hspace:
  {\__nm_add_to_empty_cells:
   \hspace}
\cs_new_protected:Nn \__nm_NiceMatrixEndPoint:
     {\kern 0.5pt}
\ProcessKeysOptions {NiceMatrix}
\msg_new:nnnn {nicematrix}
              {Impossible~instruction}
              {It's~not~possible~to~execute~the~instruction~
               \int_case:nn \l__nm_type_int
                 {0 {\token_to_str:N \Ldots}
                  1 {\token_to_str:N \Cdots}
                  2 {\token_to_str:N \Vdots}
                  3 {\token_to_str:N \Ddots}}~in~the~line~\int_use:N\l__nm_line_int\
               ~and~the~column~\int_use:N\l__nm_column_int\space of~the~matrix~
               because~it's~impossible~to~find~one~of~its~extremities~
               (both~extremities~must~be~non~empty~cells~of~the~matrix).~
               If~you~go~on,~the~instruction~will~be~ignored.}
              {You~can~specify~a~end~of~line~on~a~empty~cell~
               with~\token_to_str:N \NiceMatrixEndPoint.}
\msg_new:nnn {nicematrix}
             {multicolumn~forbidden}
             {The~command~\token_to_str:N \multicolumn\
              is~forbidden~in~the~environment~\{NiceMatrix\}~
              and~its~variants.~The~command~\token_to_str:N \hdotsfor\
              of~amsmath~is~also~forbidden~since~it~uses~
              \token_to_str:N \multicolumn.~You~can~go~on~but~your~line~will~
              probably~be~wrong.}
\endinput
%%
%% End of file `nicematrix.sty'.