% This is file `numerica-tables.sty'.
%
% This work may be distributed and/or modified under the conditions
% of the LaTeX Project Public License, either version 1.3c of this 
% license or any later version; see
% http://www.latex-project.org/lppl.txt
%
% Andrew Parsloe (ajparsloe@gmail.com)
%
\RequirePackage{booktabs}
\ProvidesExplFile
  {numerica-tables.sty}
  {2024/11/19}
  {3.2.0}
  {Create mathematical tables of function values}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\msg_new:nnn {numerica-tables} {version}
  {
    Package~too~old!~This~version~of~numerica-tables~requires~
    numerica~version~3.0~(or~later).
  }
\msg_new:nnn {numerica-tables} {load-order}
  {
    Please~load~version~3.0~(or~later)~of~the~numerica~
    package~before~numerica-tables~version~3.2. 
  }
\cs_if_exist:NTF \c_nmc_version_tl  
  { 
    \int_compare:nNnT { \c_nmc_version_tl } < { 30 }
      { \msg_fatal:nn {numerica-tables} {version} }
  }
  { \msg_fatal:nn {numerica-tables} {load-order} }
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\AtBeginDocument
  {
    \cs_if_exist:NF \sfrac
      { \NewDocumentCommand \sfrac { m m } { \scriptstyle #1 / #2 } }
  }
% debugging break point
\cs_new_protected:Npn \here { \tl_show:e {here} }
% to replace numerica.sty routine
\cs_set_protected:Npn \__nmc_fpify_fact:
  { 
    \__nmc_error_where:n { factorial }
    \tl_clear:N \l_tmpa_tl
    \tl_if_head_eq_meaning:VNTF \l__nmc_fact_arg_tl \s__fp
      { \tl_set_eq:NN \l_tmpa_tl \l__nmc_fact_arg_tl }
      { \__nmc_fpify:VN \l__nmc_fact_arg_tl \l_tmpa_tl }
    \bool_if:NF \g__nmc_error_bool
      {
        \tl_set:Ne \l_tmpa_tl { \fp_to_int:n \l_tmpa_tl }
        \tl_if_eq:VnTF \l__nmcC_tl { ! }
          { \__nmc_fpify_fact_repeated: }
          { 
            \int_compare:nNnTF { \l_tmpa_tl } < { 0 }
              { \__nmc_error_what:n { Integer~$\ge 0$~required~in } }
              {
                \seq_gpop:NN \g__nmc_error_where_seq \l__nmc_toss_tl
                \__nmc_accum_fn_parenth:NVn \l__nmc_accum_tl
                    \l_tmpa_tl { fact }
              }
          }
      }
    \bool_set_true:N \l__nmc_insert_aster_bool 
  }
\cs_generate_variant:Nn \tl_if_eq:nnTF { v }
\cs_generate_variant:Nn \tl_if_head_eq_charcode:nNTF { V, v }
\cs_generate_variant:Nn \seq_set_from_clist:Nn { No }
\cs_generate_variant:Nn \int_compare:nNnTF { v }
\cs_generate_variant:Nn \int_compare:nNnT { v }
\cs_generate_variant:Nn \int_case:nnTF { v }
\cs_generate_variant:Nn \clist_pop:NN { Nc, cc }
\cs_generate_variant:Nn \fp_add:Nn { cv }

\tl_new:N \l__nmc_swap_tl
\seq_new:N \l_tmpd_seq
\clist_const:Nn \c__nmc_table_fontsize_clist 
  { \tiny,\scriptsize,\footnotesize,\small,\normalsize,
    \large,\Large,\LARGE,\huge,\Huge }
%
\cs_new_protected:Npn \__nmc_table_new:n #1
  { \clist_map_inline:nn { #1 } { \__nmc_table_new_aux:wN ##1\q_stop } }
\cs_new_protected:Npn \__nmc_table_new_aux:wN #1_#2\q_stop
  { \use:c { #2_new:c } { l__nmc_table_#1_#2 } }
\__nmc_table_new:n 
  { 
    rvar_tl, rvari_tl, rvari_bool, rspec_clist, rspec_bool, rdelim_tl, 
    rpos_int, rvirreg_seq, rvirreg_bool, rfunc_tl, rverb_bool, rround_int, 
    rstart_fp, rstep_tl, rstep_fp, rstop_tl, rstop_fp, rnum_int, rfrac_int, 
    rhnudge_clist, rhnudge_tl, rheadi_tl, rhnudgei_tl, ralign_tl, rhsize_tl, 
    rhead_tl, rhead_bool, rhauto_bool, rhiauto_bool, rfont_tl, rmath_tl, 

    cvar_tl, cstop_tl, cstop_fp, cstart_fp, cstep_tl, cstep_fp, cnum_int, 
    cspec_clist, cspec_bool, chverb_bool, chround_int, calign_tl, chfont_tl, 
    chstyle_int, chnudge_clist, chnudge_tl, chmath_clist,chmath_tl, 
    chsize_clist, chsize_tl, chead_tl, chead_seq, header_tl, footer_tl, 
    ctitle_tl, ctitle_int, csubt_tl, rules_tl, rules_int, headless_bool, 

    rbloc_tl, rblock_tl, rbloc_int, rbloc_clist, rblocsep_tl, 
    signs_int, tsigns_int, signs_bool, diffs_bool, diffs_tl, diffs_int, 
    Q_tl, A_tl, QA_bool, query_tl, QAmax_bool, QAmin_bool, 
    
    multifn_seq, multifn_bool, transpose_bool, totalcols_tl, 
    rvcol_seq, rvcoli_seq, fvcols_seq, thiscol_seq, rows_seq, 
    r_fp, c_fp, max_fp, min_fp, a_int, b_int, c_int, 
    store_int, numonly_tl, numonly_bool, round_bool, valign_tl
  }
%------------------------------------------------
\nmc_define:NnN \nmcTabulate { table } \tabulate
%
\keys_define:nn { numerica-tables/package }
  { 
    rules  .tl_set:N = \l__nmc_table_rules_tl,
    rules .initial:n = ThB,
    norules  .code:n = \tl_clear:N \l__nmc_table_rules_tl,
    Q?*    .tl_set:N = \l__nmc_table_Q_tl,
    Q?*   .initial:n = {@=MAX}
  }
\ProcessKeyOptions [ numerica-tables/package ]

% \nmcTabulate / \__nmc_initialize:n
\cs_gset_protected:Npn \__nmc_table_initialize:
  {
    \bool_set_false:N \l__nmc_allow_TF_out_bool 
    \int_set:Nn \l__nmc_table_rnum_int { -1 }
    \int_set:Nn \l__nmc_table_cnum_int { -1 }
    \bool_if:NF \l__nmc_num_only_bool
      { \tl_clear:N \l__nmc_table_Q_tl }
  }
% \nmcTabulate / \__nmc_settings:nn
\keys_define:nn { numerica/table }
  {
    rvar       .tl_set:N = \l__nmc_table_rvar_tl,
    rstop      .tl_set:N = \l__nmc_table_rstop_tl,
    rstep      .tl_set:N = \l__nmc_table_rstep_tl,
    rows         .code:n = \__nmc_table_kv_rcnum:nn { #1 } { r },
    rspec   .clist_set:N = \l__nmc_table_rspec_clist,
    rfunc      .tl_set:N = \l__nmc_table_rfunc_tl,
    rdelim     .tl_set:N = \l__nmc_rdelim_tl,
    rdelim    .initial:V = \c__nmc_vv_delim_tl,
    rdata        .code:n = \__nmc_table_kv_rdata:n { #1 },
    rfile        .code:n = \__nmc_table_kv_rfile:n { #1 },
    rverb        .code:n = \__nmc_table_kv_rverb:n { #1 },
    rround    .int_set:N = \l__nmc_table_rround_int,
    rround    .initial:n = 1,
    rfont        .code:n = \tl_set:Nn \l__nmc_table_rfont_tl 
                               { \use:c { math#1 } },
    ralign     .tl_set:N = \l__nmc_table_ralign_tl,
    ralign    .initial:n = r, 
    rhead      .tl_set:N = \l__nmc_table_rhead_tl,
    rhead     .initial:n = `,
    rhnudge      .code:n = \tl_set:Nn \l__nmc_table_rhnudge_tl 
                              { \mkern #1 mu },
    rhnudge   .initial:n = { 0 },
    rhsize       .code:n = \tl_set:Ne \l__nmc_table_rhsize_tl
            { \clist_item:Nn \c__nmc_table_fontsize_clist { 5 + #1 } },
    rmath       .code:n  = \tl_set:Ne \l__nmc_table_rmath_tl
                             { \__nmc_table_kv_mathstyle:n { #1 } },
    rpos      .int_set:N = \l__nmc_table_rpos_int,
    rpos      .initial:n = 1,
    rvar'        .code:n = \__nmc_table_kv_rvari:n { #1 },
    rhead'     .tl_set:N = \l__nmc_table_rheadi_tl,
    rhead'    .initial:n = `,
    rhnudge'     .code:n = \tl_set:Nn \l__nmc_table_rhnudgei_tl
                                { \mkern #1 mu },
%
    cvar       .tl_set:N = \l__nmc_table_cvar_tl,
    cstop      .tl_set:N = \l__nmc_table_cstop_tl,
    cstep      .tl_set:N = \l__nmc_table_cstep_tl,
    cols         .code:n = \__nmc_table_kv_rcnum:nn { #1 } { c },
    cspec   .clist_set:N = \l__nmc_table_cspec_clist,
    chround  .int_set:N = \l__nmc_table_chround_int,
    calign     .tl_set:N = \l__nmc_table_calign_tl,
    calign    .initial:n = r,
    chstyle   .int_set:N = \l__nmc_table_chstyle_int,
    chfont       .code:n = \tl_set:Nn \l__nmc_table_chfont_tl 
                               { \use:c { math#1 } },
    chnudge .clist_set:N = \l__nmc_table_chnudge_clist,
    chnudge   .initial:n = { 0 },
    chmath  .clist_set:N = \l__nmc_table_chmath_clist,
    chmath    .initial:n = t,
    chsize      .code:n  = \tl_set:Nn \l__nmc_table_chsize_tl { \normalsize }
                           \clist_set:Nn \l__nmc_table_chsize_clist { #1 }, 
    chead      .tl_set:N = \l__nmc_table_chead_tl,
%
    ctitle     .tl_set:N = \l__nmc_table_ctitle_tl,
    cmidrow    .tl_set:N = \l__nmc_table_csubt_tl,
    csubttl    .tl_set:N = \l__nmc_table_csubt_tl,
    foot       .tl_set:N = \l__nmc_table_footer_tl,
    norules      .code:n = \tl_clear:N \l__nmc_table_rules_tl,
    rules      .tl_set:N =  \l__nmc_table_rules_tl,
    rbloc   .clist_set:N = \l__nmc_table_rbloc_clist,
    rblocsep   .tl_set:N = \l__nmc_table_rblocsep_tl,
    rblocsep  .initial:n = 1ex,
    signs     .int_set:N = \l__nmc_table_signs_int,
    (pad)     .int_set:N = \l__nmc_table_tsigns_int,
    diffs     .int_set:N = \l__nmc_table_diffs_int,
    diffs     .initial:n = 0,
%
    headless     .code:n = \__nmc_int_to_bool:Nn 
                                \l__nmc_table_headless_bool { #1 },
    headless  .default:n = 1,
    headless  .initial:n = 0,
    round        .code:n = \__nmc_table_kv_rounding:n { #1 },
    Q?         .tl_set:N = \l__nmc_table_Q_tl,
    A!         .tl_set:N = \l__nmc_table_A_tl,
    valign       .code:n = \tl_set:Nn \l__nmc_table_valign_tl { [#1] },
    valign    .initial:n = m,
    view         .code:n = \__nmc_dbg_int:nn { 1 } { 11 },
    transpose    .code:n = \__nmc_int_to_bool:Nn 
                                \l__nmc_table_transpose_bool { #1 },
    transpose .default:n = 1,
    transpose .initial:n = 0,
  }
% \nmcTabulate / \__nmc_settings:nn
\cs_gset_protected:Npn \__nmc_table_settings:
  {
    \__nmc_table_settings_rpos:
    \__nmc_table_settings_rv_vals: % for r \l__nmc_table_rspec_clist
    \__nmc_table_settings_spec:NN c \l__nmc_table_cspec_clist
    \__nmc_table_settings_rhead:
    \__nmc_table_settings_rhnudge:
    \__nmc_table_settings_chnudge:
    \__nmc_table_settings_chmath:
    \__nmc_table_settings_chsize:
    \__nmc_table_settings_ctitle:
    \__nmc_table_settings_QA:
    \__nmc_table_settings_rbloc:
    \__nmc_table_settings_rules:
    \__nmc_table_settings_diffs:
    \__nmc_table_settings_chead:
    \int_compare:nNnF \l__nmc_dbg_int = { 11 }
      { \int_zero:N \l__nmc_dbg_int }
  } 
% \nmcTabulate / \__nmc_formula:nn
\cs_set_protected:Npn \__nmc_table_formula:
  {
    \tl_set:Ne \l_tmpa_tl { \tl_head:N \l__nmc_formula_tl }
    \tl_if_in:nVT { $ \( \[ } \l_tmpa_tl
      {
        \tl_set:Ne \l__nmc_formula_tl 
          { \tl_range:Nnn \l__nmc_formula_tl {2}{-2} } 
      }
    \tl_set_eq:NN \l__nmc_formula_dup_tl \l__nmc_formula_tl 
    \int_compare:nNnT { \l__nmc_table_ctitle_int } > { 1 }
      { \tl_set_eq:NN \l__nmc_table_ctitle_tl \l__nmc_formula_tl }
  }
% \nmcTabulate / \__nmc_trailing_args:nnn #1 seq
\cs_gset_protected:Npn \__nmc_table_vv_digest:N #1
  { 
    \bool_if:NT \l__nmc_table_rvirreg_bool
      { 
        \seq_get_left:NN \l__nmc_table_rvirreg_seq \l_tmpa_tl
        \seq_push:Ne #1 
            { \exp_not:o \l__nmc_table_rvar_tl = \exp_not:o \l_tmpa_tl }
      }
    \bool_if:NT \l__nmc_multitok_bool
      { \__nmc_table_multitok:nn { cr } { \exp_args:NNc \clist_push:NV } }
    \__nmc_vv_digest:N #1
    \bool_if:NT \l__nmc_multitok_bool
      { \__nmc_table_multitok:nn { rc } { \clist_pop:Nc } }
    \seq_gpop:NN \g__nmc_error_where_seq \l__nmc_toss_tl
    \__nmc_table_get_ini_vals:
    \bool_if:NF \g__nmc_error_bool
      { \__nmc_table_add_vv_to_ctitle: }
  }
% \nmcTabulate /
\cs_gset_protected:Npn \__nmc_table_process:
  { 
    \__nmc_error_where:n { formula }
    \__nmc_table_calculate:
    \bool_if:NF \g__nmc_error_bool
      { 
        \bool_if:NT \l__nmc_table_transpose_bool
          { \__nmc_table_transpose: }
      }
    \bool_if:NF \g__nmc_error_bool
      { 
        \tl_set:Ne \l__nmc_table_totalcols_tl { \__nmc_table_totalcols: }
        \__nmc_table_format_items:
      }
    \bool_if:NF \g__nmc_error_bool
      { 
        \__nmc_table_assemble_body:
        \tl_set_eq:NN \l__nmc_fp_expr_tl \l__nmc_fp_exprn_tl
      }
    \bool_if:NF \g__nmc_error_bool
      {
        \bool_if:NT \l__nmc_num_only_bool
          { \__nmc_table_num_only: }
        \int_compare:nNnT \l__nmc_dbg_int = { 11 }
          { 
            \__nmc_table_display:
            \tl_set:NV \l__nmc_show_tl \l__nmc_result_tl
          }
      }
  }
% \nmcTabulate / 
\cs_gset_protected:Npn \__nmc_table_display:
  { 
    \bool_if:NF \l__nmc_num_only_bool
      {
        \tl_set:Ne \l__nmc_result_tl
          {
            \__nmc_table_upper:
            \bool_if:NF \l__nmc_table_headless_bool
              { 
                \exp_not:o \l__nmc_table_header_tl \\~
                \__nmc_if_mod_zero:nnTF { \l__nmc_table_rules_int } { 11 }
                  { \exp_not:N \midrule }
                  {
                    \__nmc_if_mod_zero:nnT { \l__nmc_table_rules_int } { 7 }
                      { \exp_not:N \cmidrule(lr) 
                          { 1-\l__nmc_table_totalcols_tl } }
                  }
              }
            \exp_not:o \l__nmc_result_tl
            \__nmc_table_lower:
          }
        \bool_gset_false:N \g__nmc_reuse_bool
        \tl_gset:Ne \g__nmc_reuse_tl { \exp_not:o \l__nmc_result_tl } 
      }
    \int_if_zero:nT \l__nmc_dbg_int
      { \l__nmc_result_tl }
  }
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% keys_define:nn
\cs_new_protected:Npn \__nmc_table_kv_rcnum:nn #1#2
  {
    \__nmc_fpify_set:Nn \l_tmpb_fp { #1 }
    \int_set:cn { l__nmc_table_#2 num_int } { \fp_to_int:N \l_tmpb_fp }
  }
\cs_generate_variant:Nn \__nmc_table_kv_rcnum:nn { V }

\cs_new_protected:Npn \__nmc_table_kv_rdata:n #1
  {
    \tl_if_single:nT { #1 } { \exp_args:NNNV } 
    \seq_set_split:NVn \l__nmc_table_rvirreg_seq \l__nmc_rdelim_tl { #1 }
    \seq_remove_all:Nn \l__nmc_table_rvirreg_seq {}
  }
\cs_new_protected:Npn \__nmc_table_kv_rfile:n #1
  {
    \file_get:nnNTF { #1 } {} \l_tmpa_tl
      { \__nmc_table_kv_rdata:n \l_tmpa_tl }
      { \__nmc_error_what:n { File~#1~not~found~in } }
  }
\cs_new_protected:Npn \__nmc_table_kv_rvari:n #1
  {
    \bool_lazy_or:nnTF { \tl_if_empty_p:n { #1 } } 
                       { \tl_if_head_eq_charcode_p:nN { #1 } * }
      { \bool_set_false:N \l__nmc_table_rvari_bool }
      { 
        \tl_set:Nn \l__nmc_table_rvari_tl { #1 }
        \bool_set_true:N \l__nmc_table_rvari_bool
      }
  }
\cs_new_protected:Npn \__nmc_table_kv_rverb:n #1
  {
    \int_set:Nn \l__nmc_table_rfrac_int { \fp_to_int:n { 10 * { #1 } } }
    \bool_set:Nn \l__nmc_table_rverb_bool 
        { \int_compare_p:nNn {\l__nmc_table_rfrac_int } = { 10 } }
  }
\cs_new:Npn \__nmc_table_kv_mathstyle:n #1
  {
    \str_case:nnF { #1 }
      { 
        { t } { \textstyle }
        { d } { \displaystyle }
        { s } { \scriptstyle }
      } { \textstyle }
  }
\cs_generate_variant:Nn \__nmc_table_kv_mathstyle:n { V }

\cs_new_protected:Npn \__nmc_table_kv_rounding:n #1
  {
    \bool_set:Nn \l__nmc_table_round_bool { !\tl_if_blank_p:n { #1 } } 
    \tl_set:Nn \l__nmc_round_xpr_tl { #1 }
  }
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% settings:
\cs_new_protected:Npn \__nmc_table_settings_rpos:
  {
    \int_compare:nTF { 0 <= \l__nmc_table_rpos_int <= 4 }
      { 
        \int_compare:nNnT { \l__nmc_table_rpos_int } = { 4 }
          { \int_incr:N \l__nmc_table_rpos_int }
      }
      { \int_set:Nn \l__nmc_table_rpos_int { 1 } }
  }
\cs_new_protected:Npn \__nmc_table_settings_rv_vals: 
  {
    \seq_if_empty:NTF \l__nmc_table_rvirreg_seq
      { \__nmc_table_settings_spec:NN r \l__nmc_table_rspec_clist }
      { 
        \bool_set_true:N \l__nmc_table_rvirreg_bool 
        \int_set:Nn \l__nmc_table_rnum_int 
            { \seq_count:N \l__nmc_table_rvirreg_seq }
        \bool_if:NT \l__nmc_table_rverb_bool
          { \int_set_eq:NN \l__nmc_table_rround_int \c_max_int }
      }

    \bool_if:nT { !\l__nmc_table_rvari_bool &&
          \int_compare_p:nNn { \l__nmc_table_rpos_int } < { 5 } }
      { \tl_set_eq:NN \l__nmc_table_rvari_tl \l__nmc_table_rvar_tl }
  }
\cs_new_protected:Npn \__nmc_table_settings_spec:NN #1 #2 
  { 
    \clist_if_empty:NF #2
      {
        \bool_set_true:c { l__nmc_table_#1 spec_bool }
        \clist_pop:cc { l__nmc_table_#1 spec_clist } 
            { l__nmc_table_#1 var_tl }
        \clist_pop:cc { l__nmc_table_#1 spec_clist } 
            { l__nmc_table_#1 step_tl }
        \clist_pop:cN { l__nmc_table_#1 spec_clist } \l_tmpb_tl
        \__nmc_table_kv_rcnum:Vn \l_tmpb_tl { #1 }
        \clist_if_empty:NF #2
          { 
            \clist_pop:cN { l__nmc_table_#1 spec_clist } \l_tmpa_tl 
            \tl_if_eq:NNTF #1 r
              { \int_set:Nn \l__nmc_table_rround_int \l_tmpa_tl }
              { \int_set:Nn \l__nmc_table_chround_int \l_tmpa_tl }
          }
      }
  }
\cs_new_protected:Npn \__nmc_table_settings_rhead:
  {
    \tl_if_eq:VnTF \l__nmc_table_rhead_tl { ` }
      { 
        \tl_if_empty:NT \l__nmc_table_chead_tl
          {
            \bool_set_true:N \l__nmc_table_rhead_bool
            \__nmc_table_rhead:NNNn r \backslash c {}
          }
          { \tl_set_eq:NN \l__nmc_table_rhead_tl \l__nmc_table_rvar_tl }
        \tl_if_eq:VnT \l__nmc_table_rheadi_tl { ` }
          { 
            \int_compare:nNnTF { \l__nmc_table_rpos_int } = { 5 }
              { 
                \int_if_zero:nTF { \l__nmc_table_chstyle_int }
                  { \tl_clear:N \l__nmc_table_rheadi_tl }
                  { \tl_set_eq:NN \l__nmc_table_rheadi_tl \l__nmc_table_rvari_tl }
              }
              { \__nmc_table_rhead:NNNn c / r { i } }
          }
      }
      {
        \tl_if_eq:VnT \l__nmc_table_rheadi_tl { ` }
          { \tl_set_eq:NN \l__nmc_table_rheadi_tl \l__nmc_table_rhead_tl }
      }
  }
% #4 blank or i
\cs_new:Npn \__nmc_table_rhead:NNNn #1#2#3#4
  { 
    \tl_if_empty:NTF \l__nmc_table_cvar_tl
      {
        \tl_set_eq:cc { l__nmc_table_rhead #4_tl }
            { l__nmc_table_rvar #4_tl } 
      }
      { 
        \bool_if:nF { \l__nmc_table_transpose_bool 
                        && \l__nmc_table_multifn_bool }
          { 
            \tl_set:ce { l__nmc_table_rhead #4_tl } 
              {
                \int_if_zero:nTF { \l__nmc_table_chstyle_int }
                  { \__nmc_table_rhead:NNN #1 #2 #3 }
                  { \use:c { l__nmc_table_rvar_tl } }
              }
            \bool_set_true:c { l__nmc_table_rh #4 auto_bool }
          }
      }
  }
\cs_new:Npn \__nmc_table_rhead:NNN #1#2#3
  { 
    \use:c { l__nmc_table_#1 var_tl } 
    \exp_not:n { \:\! #2 \:\! }
    \use:c { l__nmc_table_#3 var_tl } 
  }
\cs_new_protected:Npn \__nmc_table_settings_rhnudge:
  {
    \tl_if_empty:NT \l__nmc_table_rhnudgei_tl
        { \tl_set_eq:NN \l__nmc_table_rhnudgei_tl \l__nmc_table_rhnudge_tl }
  }
\cs_new_protected:Npn \__nmc_table_settings_chnudge:
  {
    \clist_if_empty:NF \l__nmc_table_chnudge_clist
      { 
        \clist_pop:NN \l__nmc_table_chnudge_clist \l__nmc_table_chnudge_tl
        \tl_set:Ne \l__nmc_table_chnudge_tl 
            { \mkern \l__nmc_table_chnudge_tl mu } 
      }
  }
\cs_new_protected:Npn \__nmc_table_settings_chmath:
  {
    \clist_if_empty:NF \l__nmc_table_chmath_clist
      { 
        \clist_pop:NN \l__nmc_table_chmath_clist \l_tmpa_tl
        \tl_set:Ne \l__nmc_table_chmath_tl 
            { \__nmc_table_kv_mathstyle:V \l_tmpa_tl }
      }
  }
\cs_new_protected:Npn \__nmc_table_settings_chsize:
  {
    \clist_if_empty:NF \l__nmc_table_chsize_clist
      {
        \clist_pop:NN \l__nmc_table_chsize_clist \l_tmpa_tl
        \tl_set:Ne \l__nmc_table_chsize_tl 
          { \clist_item:Nn \c__nmc_table_fontsize_clist { 5+\l_tmpa_tl } }
      }
  }
\cs_new_protected:Npn \__nmc_table_settings_ctitle:
  {
    \tl_if_empty:NF \l__nmc_table_ctitle_tl
      { 
        \int_incr:N \l__nmc_table_ctitle_int % 1
        \tl_if_eq:VnT \l__nmc_table_ctitle_tl { * }
          { \int_incr:N \l__nmc_table_ctitle_int } % 2
        \tl_if_eq:VnT \l__nmc_table_ctitle_tl { ** }
          { \int_set:Nn \l__nmc_table_ctitle_int { 3 } } % 3
      }
  }
\cs_new_protected:Npn \__nmc_table_settings_QA:
  {
    \tl_if_empty:NTF \l__nmc_table_Q_tl
      { \tl_set:Nn \l__nmc_table_query_tl { Missing~ } }
      { 
        \tl_set:Nn \l__nmc_table_query_tl { No~table~value~satisfies~ }
        \bool_set_true:N \l__nmc_table_QA_bool
        \regex_replace_all:nnN { (\@) } { \c{l_tmpb_fp} } 
            \l__nmc_table_Q_tl
        \tl_set_rescan:Nno \l__nmc_table_Q_tl { \ExplSyntaxOn } 
            \l__nmc_table_Q_tl
        \regex_replace_all:nnN { (\cC.) } { \c{exp_not:N}\1 } 
            \l__nmc_table_A_tl
        \regex_replace_all:nnN { (\@) } { \c{l_tmpb_tl} } 
            \l__nmc_table_A_tl
        \tl_if_in:NnT \l__nmc_table_Q_tl { MAX }
          { 
            \bool_set_true:N \l__nmc_table_QAmax_bool 
            \regex_replace_all:nnN { MAX } { \c{l__nmc_table_max_fp} }
                \l__nmc_table_Q_tl
            \fp_set:Nn \l__nmc_table_max_fp { -inf }    
          }
        \tl_if_in:NnT \l__nmc_table_Q_tl { MIN }
          { 
            \bool_set_true:N \l__nmc_table_QAmin_bool 
            \regex_replace_all:nnN { MIN } { \c{l__nmc_table_min_fp} }
                \l__nmc_table_Q_tl
            \fp_set:Nn \l__nmc_table_min_fp { inf }
          }
      }
  }
\cs_new_protected:Npn \__nmc_table_settings_rbloc:
  {
    \clist_if_empty:NTF \l__nmc_table_rbloc_clist
      { \tl_set:Nn \l__nmc_table_rbloc_tl { 10000 } }
      { \clist_pop:NN \l__nmc_table_rbloc_clist \l__nmc_table_rbloc_tl }
    \tl_set_eq:NN \l__nmc_table_rblock_tl \l__nmc_table_rbloc_tl
    \int_set:Nn \l__nmc_table_rbloc_int { \l__nmc_table_rbloc_tl }
  }
\cs_new_protected:Npn \__nmc_table_settings_rules:
  {
    \clist_map_inline:nn { {T{*2}},{t{*3}},{m{*5}},{s{*5}},{{h'}{*7}},
        {h{*11}},{{f'}{*13}},{f{*17}},{B{*19}} }
      { \tl_replace_once:Nnn \l__nmc_table_rules_tl ##1 }
    \int_set:Nn \l__nmc_table_rules_int { 1 \l__nmc_table_rules_tl }
  }
\cs_new_protected:Npn \__nmc_table_settings_diffs:
  {
    \int_if_zero:nTF \l__nmc_table_diffs_int
      { \bool_set_false:N \l__nmc_table_diffs_bool } 
      { \bool_set_true:N \l__nmc_table_diffs_bool  }
  }
\cs_new_protected:Npn \__nmc_table_settings_chead:
  {
    \tl_if_empty:NF \l__nmc_table_chead_tl
      { \bool_set_true:N \l__nmc_table_chverb_bool }
  }
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% vv_digest:N (x2)
\cs_new_protected:Npn \__nmc_table_multitok:nn #1#2
  { 
    \tl_map_inline:nn { #1 }
      { 
        \tl_if_empty:cF { l__nmc_table_##1 var_tl }
          { #2 \l__nmc_formula_tl { l__nmc_table_##1 var_tl } }
      }
  }
% vv_digest:N 
\cs_new_protected:Npn \__nmc_table_get_ini_vals:
  { 
    \__nmc_error_where:n { settings }
    \__nmc_table_get_ini_vals_aux:N r
    \bool_if:nF { \g__nmc_error_bool || \l__nmc_table_multifn_bool }
      {
        \tl_if_empty:NTF \l__nmc_table_cvar_tl
          { 
            \int_set:Nn \l__nmc_table_cnum_int
              { \int_min:nn { 1 } 
                          { \int_abs:n { \l__nmc_table_cnum_int } } }
          }
          { \__nmc_table_get_ini_vals_aux:N c }
      }
    \bool_if:NT \l__nmc_table_round_bool
      { 
        \__nmc_error_where:n { rounding~function } 
        \__nmc_fpify:VN \l__nmc_round_xpr_tl \l__nmc_toss_tl 
        \bool_if:NF \g__nmc_error_bool
          { \seq_gpop:NN \g__nmc_error_where_seq \l__nmc_toss_tl }
      }
    \bool_if:NF \g__nmc_error_bool
      { \seq_gpop:NN \g__nmc_error_where_seq \l__nmc_toss_tl }
  }
% vv_digest:N
\cs_new_protected:Npn \__nmc_table_add_vv_to_ctitle:
  {  
    \bool_if:nTF
        { 
          \int_if_zero_p:n { \l__nmc_table_rpos_int } &&
          \int_if_zero_p:n { \l__nmc_table_cnum_int }
        }
      { \__nmc_error_what:n { Null~table~specified~in } }
      { 
        \int_compare:nNnT { \l__nmc_table_ctitle_int } = { 3 }
          { 
            \tl_put_right:Ne \l__nmc_table_ctitle_tl 
              { 
                \c__nmc_vv_delim_tl \mskip18muminus15mu(
                \seq_use:Nn \l__nmc_vv_visible_seq { \c__nmc_vv_delim_tl } )
              }
          }
      }
  }
% get_ini_vals:
\cs_new_protected:Npn \__nmc_table_get_ini_vals_aux:N #1
  { 
    \prop_get:NvNTF \l__nmc_subst_var_prop 
        { l__nmc_table_#1 var_tl } \l_tmpa_tl
      { 
        \fp_set:cn { l__nmc_table_#1 start_fp } { \l_tmpa_tl }
        \bool_if:cTF { l__nmc_table_#1 spec_bool }
          { 
            \__nmc_fpify_set:cv { l__nmc_table_#1 step_fp }
                { l__nmc_table_#1 step_tl }
            \int_compare:vNnT { l__nmc_table_#1 num_int } = { -1 }
              {
                \__nmc_fpify_set:cv { l__nmc_table_#1 stop_fp }
                    { l__nmc_table_#1 stop_tl }
                \__nmc_table_calc_rcnum:cnnn { l__nmc_table_#1 num_int } 
                    { l__nmc_table_#1 stop_fp } { l__nmc_table_#1 start_fp } 
                    { l__nmc_table_#1 step_fp }
              }
          }
          { \__nmc_table_get_ini_vidual_vals:N #1 }
        }
        {
          \tl_if_empty:cTF { l__nmc_table_#1 var_tl }
            {
              \__nmc_error_what:n { No~ \__nmc_table_rc:N #1 
                    \ variable~specified~in } 
            }
            {
              \__nmc_error_where:n { variable=value~list }
              \__nmc_error_what:n { No~initial~value~for~\__nmc_table_rc:N #1\ variable~in }
            }
        }
  }
% get_ini_vals_aux:N
\cs_new_protected:Npn  \__nmc_table_get_ini_vidual_vals:N #1
  { 
    \int_case:vnTF { l__nmc_table_#1 num_int } 
      {
        { -1 }
          { 
            \__nmc_fpify_set:cv { l__nmc_table_#1 step_fp }
                { l__nmc_table_#1 step_tl } 
            \bool_if:NF \g__nmc_error_bool
              { \__nmc_fpify_set:cv { l__nmc_table_#1 stop_fp } }
                  { l__nmc_table_#1 stop_tl } 
            \bool_if:NF \g__nmc_error_bool
              {        
                \__nmc_table_calc_rcnum:cnnn { l__nmc_table_#1 num_int } 
                    { l__nmc_table_#1 stop_fp } { l__nmc_table_#1 start_fp }
                    { l__nmc_table_#1 step_fp }
              }
          }
        { 0 }
          { 
            \fp_set:cn { l__nmc_table_#1 stop_fp } 
                { \exp_not:v { l__nmc_table_#1 start_fp } - 1 }
            \fp_set:cn { l__nmc_table_#1 step_fp } { 1 }
          }
        { 1 }
          {
            \fp_set_eq:cc { l__nmc_table_#1 stop_fp } 
                { l__nmc_table_#1 start_fp }
            \fp_set:cn { l__nmc_table_#1 step_fp } { 1 }
          }
      }
      { 
        \bool_if:NT \g__nmc_error_bool
          { \__nmc_error_what:n {  Missing~ 
              \__nmc_table_rc:N #1-related~variable~in } }
      }
      { 
        \int_compare:vNnTF { l__nmc_table_#1 num_int } > { 1 }
          { 
            \bool_if:nF { \l__nmc_table_rvirreg_bool }
              { 
                \__nmc_fpify_set:cv { l__nmc_table_#1 step_fp }
                    { l__nmc_table_#1 step_tl } 
              }
          }
          { \__nmc_error_what:n { Check~number~of~
              \__nmc_table_rc:N #1s~specified~in } }
      }
  }
% get_ini_vals_aux:N , get_ini_vidual_vals:N
\cs_new_protected:Npn \__nmc_table_calc_rcnum:Nnnn #1#2#3#4
  { 
    \int_set:Nn #1 { \fp_to_int:n { ( \exp_not:v { #2 } - \exp_not:v { #3 } )
        / \exp_not:v { #4 } } + 1 } 
  }
\cs_generate_variant:Nn \__nmc_table_calc_rcnum:Nnnn { c }
% get_ini_vals_aux:N (x2), get_ini_vidual_vals:N (x2)
\cs_new:Npn \__nmc_table_rc:N #1
  { \str_if_eq:nnTF { #1 } { r } { row } { column } }
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% process: /
\cs_new_protected:Npn \__nmc_table_calculate:
  {
    \__nmc_table_rvcol_calc:N \l__nmc_table_rvcol_seq
    \bool_if:NF \g__nmc_error_bool
      { 
        \__nmc_table_multifn:NN \l__nmc_table_chead_seq \l__nmc_table_cnum_int
        \bool_if:nT 
            { 
              \l__nmc_table_multifn_bool ||
              \int_compare_p:nNn \l__nmc_table_cnum_int = { 1 }
            }
          { \bool_set_true:N \l__nmc_table_chverb_bool }
      }
    \bool_if:NF \g__nmc_error_bool
      { 
        \__nmc_table_fvcols_calc:NN 
            \l__nmc_table_fvcols_seq \l__nmc_table_chead_seq 
        \bool_if:NT \l__nmc_table_rverb_bool 
          { \seq_set_eq:NN \l__nmc_table_rvcol_seq \l__nmc_table_rvirreg_seq }
      }
  }
% calulate: / #1 = rvcol_seq
\cs_new_protected:Npn \__nmc_table_rvcol_calc:N #1
  { 
    \bool_if:NTF \l__nmc_table_rvirreg_bool
      { \__nmc_table_rdata:N #1 }
      { 
        \tl_if_empty:NTF \l__nmc_table_rfunc_tl
          { \__nmc_table_runiform:N #1 }
          { \__nmc_table_rfunc:N #1 }
      }
  }
% calculate: / #1 chead_seq; #2 cnum_int
\cs_new_protected:Npn \__nmc_table_multifn:NN #1#2
  { 
    \tl_if_in:NVT \l__nmc_formula_tl \l__nmc_multi_delim_tl
      { 
        \bool_set_true:N \l__nmc_table_multifn_bool
        \seq_set_split:NVV \l__nmc_table_multifn_seq
            \l__nmc_multi_delim_tl \l__nmc_formula_tl
        \seq_remove_all:Nn \l__nmc_table_multifn_seq {}
        \seq_set_eq:NN #1 \l__nmc_table_multifn_seq
        \int_set:Nn #2 { \seq_count:N \l__nmc_table_multifn_seq }
      }
    \tl_if_empty:NT \l__nmc_table_cvar_tl
      { 
        \fp_set:Nn \l__nmc_table_cstep_fp { 0 }
        \fp_set:Nn \l__nmc_table_cstart_fp { 0 }
        \tl_set:Nn \l__nmc_table_cvar_tl { \c_empty_tl }
        \prop_put:Nnn \l__nmc_subst_var_prop { \c_empty_tl } { 0 }
      }
  }
% calculate: / #1 = fvcols_seq, #2 = chead_seq
\cs_new_protected:Npn \__nmc_table_fvcols_calc:NN #1#2
  { 
    \fp_set_eq:NN \l__nmc_table_c_fp \l__nmc_table_cstart_fp
    \int_step_inline:nn { \l__nmc_table_cnum_int }
      {  
        \bool_if:NF \g__nmc_error_bool
          { \__nmc_table_thiscol_calc:NN \l__nmc_table_thiscol_seq #2 }
        \bool_if:NF \g__nmc_error_bool
          { 
            \__nmc_table_fvcols_append_col:NN #1 \l__nmc_table_thiscol_seq
            \__nmc_calc_fn_val:VNnN \l__nmc_table_cvar_tl \l__nmc_formula_tl
                 { \l__nmc_table_c_fp } \l_tmpc_fp
          }
      }
  }
%%%%%%%%%%
% rvcol_calc: / #1 = rvcol_seq
\cs_new_protected:Npn \__nmc_table_rdata:N #1
  {
    \seq_map_inline:Nn \l__nmc_table_rvirreg_seq
      {
        \tl_clear:N \l_tmpb_tl
        \__nmc_fpify:nN { ##1 } \l_tmpb_tl
        \fp_set:Nn \l__nmc_table_r_fp
          { 
            \int_if_zero:nTF \l__nmc_table_rfrac_int
              { round( \l_tmpb_tl, \l__nmc_table_rround_int ) }
              { \l_tmpb_tl }
          }
        \__nmc_error_fpflag:
        \bool_if:NT \g__nmc_error_bool
          { \seq_map_break: }
        \seq_put_right:NV #1 \l__nmc_table_r_fp
     }
  }
% rvcol_calc:N / #1 = rvcol_seq
\cs_new_protected:Npn \__nmc_table_runiform:N #1
  { 
    \fp_set_eq:NN \l__nmc_table_r_fp \l__nmc_table_rstart_fp
    \int_step_inline:nn { \l__nmc_table_rnum_int }
      { 
        \int_if_zero:nT \l__nmc_table_rfrac_int
          {
            \fp_set:Nn \l__nmc_table_r_fp 
                { round( \l__nmc_table_r_fp, \l__nmc_table_rround_int ) }
          } 
        \seq_put_right:NV #1 \l__nmc_table_r_fp
        \fp_add:Nn \l__nmc_table_r_fp { \l__nmc_table_rstep_fp }
      }
  }
% rvcol_calc:N / 
\cs_new_protected:Npn \__nmc_table_rfunc:N #1
  { 
    \__nmc_error_where:n { row-variable~function }
    \fp_set_eq:NN \l__nmc_table_r_fp \l__nmc_table_rstart_fp
    \bool_if:NF \g__nmc_error_bool
      {
        \seq_clear:N \l__nmc_table_rvirreg_seq 
        \int_step_function:nN { \l__nmc_table_rnum_int }
            \__nmc_table_rfunc_step_fn:n
        \seq_gpop:NN \g__nmc_error_where_seq \l__nmc_toss_tl
      }
    \bool_if:NF \g__nmc_error_bool
      {
        \prop_get:NVN \l__nmc_subst_var_prop 
            \l__nmc_table_rvar_tl \l_tmpa_tl
        \fp_set:Nn \l__nmc_table_rstart_fp { \l_tmpa_tl }
        \seq_set_eq:NN #1 \l__nmc_table_rvirreg_seq
        \bool_set_true:N \l__nmc_table_rvirreg_bool
      }
  } 
% rfunc: / 
\cs_new_protected:Npn \__nmc_table_rfunc_step_fn:n #1
  {
    \bool_if:NF \g__nmc_error_bool
      { 
        \__nmc_calc_fn_val:VNnN \l__nmc_table_rvar_tl
            \l__nmc_table_rfunc_tl { \l__nmc_table_r_fp } \l_tmpa_fp
        \int_if_zero:nTF \l__nmc_table_rfrac_int
          {
            \__nmc_num_format:nNnN { \l_tmpa_fp } \l_tmpb_tl 
                { \l__nmc_table_rround_int } \c_false_bool
             \tl_set:Ne \l_tmpb_tl 
                 { \exp_not:o \l__nmc_table_rfont_tl { \l_tmpb_tl } }
          }
          { \tl_set:Ne \l_tmpb_tl { \fp_use:N \l_tmpa_fp } }
        \seq_put_right:NV \l__nmc_table_rvirreg_seq \l_tmpb_tl
        \fp_add:Nn \l__nmc_table_r_fp { \l__nmc_table_rstep_fp }
      }
  }
% fvcols_calc:NN / #1 = thiscol_seq, #2 = chead_seq
\cs_new_protected:Npn \__nmc_table_thiscol_calc:NN #1#2
  {
    \bool_if:NTF \l__nmc_table_multifn_bool
      { \seq_pop:NN \l__nmc_table_multifn_seq \l__nmc_formula_tl }
      { 
        \int_compare:nNnTF { \l__nmc_table_cnum_int } = { 1 }
          {  \seq_put_right:NV #2 \l__nmc_formula_tl }
          { \__nmc_table_chead:Nn #2 { \l__nmc_table_c_fp } }
      }
    \seq_clear:N #1
    \seq_map_inline:Nn \l__nmc_table_rvcol_seq
      { 
        \__nmc_calc_fn_val:VNnN \l__nmc_table_rvar_tl
            \l__nmc_formula_tl { ##1 } \l_tmpa_fp
        \bool_if:NT \g__nmc_error_bool
          { \seq_map_break: }
        \seq_put_right:NV #1 \l_tmpa_fp
        \bool_if:NT \l__nmc_table_QA_bool
          { \__nmc_table_maxmin_do:n { \l_tmpa_fp } }
      }
  }
% fvcols_calc:NN / append seq #2 to seq of seqs #1
\cs_new_protected:Npn \__nmc_table_fvcols_append_col:NN #1 #2
  {
    \seq_put_right:NV #1 #2
    \fp_add:Nn \l__nmc_table_c_fp \l__nmc_table_cstep_fp
    \int_if_zero:nTF { \l__nmc_mode_tl }
      { \prop_put:NVV \l__nmc_subst_var_prop } 
      { \prop_put:NVV \l__nmc_vv_change_prop }
          \l__nmc_table_rvar_tl \l__nmc_table_rstart_fp
  }
% thiscol_calc:NN / #1 = chead_seq, #2 = cvar_fp
\cs_new_protected:Npn \__nmc_table_chead:Nn #1#2
  { 
    \bool_if:nTF { \int_compare_p:nNn { \l__nmc_table_cnum_int } = { 1 } &&
                    !\int_compare_p:nNn { \l__nmc_table_rnum_int } = { 1 } }
      { \seq_put_right:Ne #1 { \exp_not:o\l__nmc_formula_dup_tl } }
      { \seq_put_right:No #1 { #2 } }
  }
%%%%%%%%%%
% process: /
\cs_new_protected:Npn \__nmc_table_transpose:
  {
      \__nmc_table_transpose_body:N \l__nmc_table_fvcols_seq
    \__nmc_table_transpose_hrow_rvcol_vals:
  }
% transpose: / #1 seq of seqs
\cs_new_protected:Npn \__nmc_table_transpose_body:N #1
  { 
    \seq_clear:N \l_tmpd_seq 
    \int_step_inline:nn { \l__nmc_table_rnum_int }
      {
        \seq_clear:N \l_tmpb_seq
        \seq_clear:N \l_tmpc_seq
        \seq_map_variable:NNn #1 \l_tmpa_seq
          { 
            \seq_pop:NN \l_tmpa_seq \l_tmpa_tl
            \seq_put_right:Ne \l_tmpb_seq \l_tmpa_tl
            \seq_put_right:NV \l_tmpc_seq \l_tmpa_seq
          }
        \seq_put_right:NV \l_tmpd_seq \l_tmpb_seq
        \seq_set_eq:NN #1 \l_tmpc_seq        
      }
    \seq_set_eq:NN #1 \l_tmpd_seq
  }
\cs_new_protected:Npn \__nmc_table_transpose_hrow_rvcol_vals:
  {
    \__nmc_table_swap:nNN {int} \l__nmc_table_rnum_int \l__nmc_table_cnum_int
    \__nmc_table_swap:nNN {int} 
        \l__nmc_table_rround_int \l__nmc_table_chround_int
    \bool_if:NT \l__nmc_table_rverb_bool
      { \seq_set_eq:NN \l__nmc_table_rvcol_seq \l__nmc_table_rvirreg_seq }
    \__nmc_table_swap:nNN {seq}
        \l__nmc_table_rvcol_seq \l__nmc_table_chead_seq
    \__nmc_table_swap:nNN {fp} 
        \l__nmc_table_rstep_fp \l__nmc_table_cstep_fp
    \__nmc_table_swap:nNN {fp} 
        \l__nmc_table_rstart_fp \l__nmc_table_cstart_fp
    \__nmc_table_swap:nNN {tl} 
        \l__nmc_table_rvar_tl \l__nmc_table_cvar_tl
    \bool_xor:nnT { \l__nmc_table_rverb_bool } { \l__nmc_table_chverb_bool }
      { 
        \bool_set_inverse:N \l__nmc_table_rverb_bool
        \bool_set_inverse:N \l__nmc_table_chverb_bool
      }
    \int_set:Nn \l__nmc_table_rpos_int 
            { \int_min:nn { \l__nmc_table_rpos_int } { 3 } }
    \bool_if:NT \l__nmc_table_rhead_bool 
      { 
        \int_compare:nNnT \l__nmc_table_rnum_int > { 1 }
          { 
            \bool_if:NF \l__nmc_table_multifn_bool
              { 
                \tl_set:Nn \l__nmc_table_rhead_tl { ` } 
                \tl_set:Nn \l__nmc_table_rheadi_tl { ` }
              }
          }
        \__nmc_table_settings_rhead:
      }
  }
% not applicable to boolean variables
\cs_new_protected:Npn \__nmc_table_swap:nNN #1#2#3
  {
    \tl_set:NV \l__nmc_swap_tl #2
    \use:c {#1_set_eq:NN} #2 #3
    \use:c {#1_set_eq:NN} #3 \l__nmc_swap_tl
  }
%%%%%%%%%%
% process: / 
\cs_new:Npn \__nmc_table_totalcols:
  {
    \int_eval:n { \int_sign:n { \l__nmc_table_rpos_int }
       + \l__nmc_table_cnum_int
          + \int_div_truncate:nn { \l__nmc_table_rpos_int } { 3 } }
  }
%%%%%%%%%%
% process:
\cs_new_protected:Npn \__nmc_table_format_items:
  {
    \__nmc_table_rvcol_format:NN 
        \l__nmc_table_rvcol_seq \l__nmc_table_rvcoli_seq
    \__nmc_table_chead_format:NN 
        \l__nmc_table_chead_seq \l__nmc_table_chead_tl
    \tl_set:Ne \l__nmc_table_header_tl { \__nmc_table_header: }
    \__nmc_table_footer:NN 
        \l__nmc_table_footer_tl \l__nmc_table_header_tl
    \__nmc_table_fvcols_format:N \l__nmc_table_fvcols_seq
  }
% format_items: / #1 rvcol_seq #2 rvcoli_seq
\cs_new_protected:Npn \__nmc_table_rvcol_format:NN #1#2
  {
    \seq_set_eq:NN #2 #1
    \bool_lazy_all:nTF 
      { 
        { \l__nmc_table_rvirreg_bool }
        { \int_compare_p:nNn \l__nmc_table_rfrac_int = { 5 } }
        { !\l__nmc_table_rverb_bool }
      }
      {
        \__nmc_table_rdatafrac:NN 
            \l__nmc_table_rvcol_seq \l__nmc_table_rvirreg_seq 
      }
      {
        \int_zero:N \l__nmc_table_rfrac_int
        \seq_clear:N \l_tmpa_seq
        \bool_if:NTF \l__nmc_table_rverb_bool
          {
            \seq_map_inline:Nn #1 { \__nmc_table_rvcol_format_aux:nN 
                      { \exp_not:n { ##1 } } \l_tmpa_seq }
          }
          {
            \__nmc_table_swap:nNN {int} 
                \l__nmc_frac_out_int \l__nmc_table_rfrac_int
            \seq_map_inline:Nn #1
              {
                \__nmc_num_format:nNnN { ##1 } \l_tmpb_tl 
                    { \l__nmc_table_rround_int } \c_false_bool
                \__nmc_table_rvcol_format_aux:nN \l_tmpb_tl \l_tmpa_seq
              }
            \__nmc_table_swap:nNN {int} \l__nmc_frac_out_int \l__nmc_table_rfrac_int
          }
        \seq_set_eq:NN #1 \l_tmpa_seq
      }
    \int_compare:nNnTF { \l__nmc_table_rpos_int } < { 4 }    
      { \seq_set_eq:NN #2 \l_tmpa_seq }
      { 
        \bool_if:NF \l__nmc_table_transpose_bool
          {
            \bool_if:NTF \l__nmc_table_rvari_bool
              { \__nmc_table_rvcoli:N #2 }
              {
                \seq_reverse:N \l_tmpa_seq
                \seq_set_eq:NN #2 \l_tmpa_seq
              }
          }
      }
  }
% rvcol_format:N #1 rvcoli_seq
\cs_new_protected:Npn \__nmc_table_rvcoli:N #1
  { 
    \__nmc_error_where:n { settings }
    \__nmc_table_swap:nNN {int} 
        \l__nmc_frac_out_int \l__nmc_table_rfrac_int 
    \seq_clear:N \l_tmpb_seq
    \seq_map_inline:Nn #1 
      { 
        \__nmc_calc_fn_val:VNnN \l__nmc_table_rvar_tl 
              \l__nmc_table_rvari_tl { ##1 } \l_tmpa_fp
        \__nmc_num_format:nNnN { \l_tmpa_fp } \l_tmpb_tl 
            { \l__nmc_table_rround_int } \c_false_bool
        \__nmc_table_rvcol_format_aux:VN \l_tmpb_tl \l_tmpb_seq
      }
    \__nmc_table_swap:nNN {int} \l__nmc_frac_out_int \l__nmc_table_rfrac_int
    \seq_set_eq:NN #1 \l_tmpb_seq
    \seq_gpop:NN \g__nmc_error_where_seq \l__nmc_toss_tl
  }
\cs_new_protected:Npn \__nmc_table_rvcol_format_aux:nN #1#2
  { 
    \seq_put_right:Ne #2 { $ \l__nmc_table_rmath_tl 
        \exp_not:o \l__nmc_table_rfont_tl { \exp_not:o { #1 } } $ }
  }
\cs_generate_variant:Nn \__nmc_table_rvcol_format_aux:nN { V }

% rvcol_format:N #1 rvcol_seq (out), #2 rvirreg_seq (in)
\cs_new_protected:Npn \__nmc_table_rdatafrac:NN #1#2
  { 
    \seq_clear:N \l_tmpa_seq
    \seq_map_inline:Nn #2
      {
        \__nmc_table_rvcol_format_aux:nN  
          { \__nmc_table_rdatafrac_split:wN ##1/\q_stop }
          \l_tmpa_seq
      }
    \seq_set_eq:NN #1 \l_tmpa_seq
  }
\cs_new:Npn \__nmc_table_rdatafrac_split:wN #1#2/#3\q_stop
  {
    \tl_if_empty:nTF { #3 } 
      { #1#2 }
      {
        \tl_if_head_eq_charcode:nNTF { #1 } -
          { #1 \__nmc_table_frac_out_aux:nn { #2 } }
          { \__nmc_table_frac_out_aux:nn { #1#2 } }
              { \__nmc_table_rdatafrac_slash:wN #3\q_stop } 
      }
  }
\cs_new:Npn \__nmc_table_rdatafrac_slash:wN #1/\q_stop { #1 }
\cs_new:Npn \__nmc_table_frac_out_aux:nn #1#2
  { 
    \fp_compare:nNnT { #1 } < { 0 } { - }
    \sfrac { #1 } { #2 }
  }
% format_items: / #1 chead_seq #2 chead_tl 
\cs_new_protected:Npn \__nmc_table_chead_format:NN #1#2
  { 
    \int_compare:nNnTF { \l__nmc_table_cnum_int } = { 1 }
      {
        \int_compare:nNnTF { \l__nmc_table_rnum_int } = { 1 }
          { \__nmc_table_chead_n:NN #1 #2 }
          { \__nmc_table_chead_i:N #2 }
      }
      { \__nmc_table_chead_n:NN #1 #2 }
  }
% chead_format:NN / #1 chead_seq, but cvar val if transpose=rnum=cnum=1
\cs_new:Npn \__nmc_table_chead_i:N #1
  {
    \tl_if_empty:NT #1
      {
        \tl_set:Ne #1 
          {
            \__nmc_table_chead_nudge:Nnn c  
              {
                \l__nmc_table_chmath_tl
                \int_if_zero:nTF { \l__nmc_table_ctitle_int }
                  { \exp_not:o \l__nmc_formula_dup_tl }
                  { \exp_not:o \l__nmc_table_ctitle_tl }
              } 
              \l__nmc_table_chnudge_tl
          }
      }
  }
% chead_format:NN / #1 chead_seq #2 chead_tl
\cs_new:Npn \__nmc_table_chead_n:NN #1#2
  { 
    \int_set_eq:NN \l__nmc_table_store_int \l__nmc_frac_out_int
    \int_zero:N \l__nmc_frac_out_int
    \tl_if_empty:NT #2
      {
        \seq_clear:N \l_tmpa_seq
        \bool_set_true:N \l__nmc_table_coli_only_bool
        \bool_if:NTF \l__nmc_table_chverb_bool
          {
            \seq_map_variable:NNn #1 \l_tmpb_tl
              { \__nmc_table_chstyler:NN \l_tmpa_seq \l_tmpb_tl }
          }
          {
            \seq_map_inline:Nn #1
              { 
                \__nmc_num_format:nNnN { ##1 } \l_tmpb_tl 
                    { \l__nmc_table_chround_int } \l__nmc_sci_num_out_bool
                \int_if_zero:nF { \l__nmc_table_chstyle_int - 3 }
                  {
                    \tl_set:Ne \l_tmpb_tl 
                      { \exp_not:o \l__nmc_table_chfont_tl { \l_tmpb_tl } }
                  }
                \__nmc_table_chstyler:NN \l_tmpa_seq \l_tmpb_tl
              }
          }
        \tl_set:Ne #2 { \seq_use:Nn \l_tmpa_seq { & }  }
      }
    \int_set_eq:NN \l__nmc_frac_out_int \l__nmc_table_store_int
  }
% headern:NN / #1 tmpa_seq #2 tmpb_tl
\cs_new_protected:Npn \__nmc_table_chstyler:NN #1#2
  {
    \bool_if:NTF \l__nmc_table_transpose_bool
      { 
        \int_compare:nNnT { \l__nmc_table_chstyle_int } > { 2 }
          { \int_zero:N \l__nmc_table_chstyle_int }
      }
      {
        \bool_if:NT \l__nmc_table_multifn_bool
          { \int_zero:N \l__nmc_table_chstyle_int }
      }
    \int_case:nnTF { \l__nmc_table_chstyle_int }
      {
        { 0 } { \__nmc_table_chead_auxi:NV #1 #2 }
        { 1 } 
          {
            \bool_if:NTF \l__nmc_table_coli_only_bool
              { 
                \__nmc_table_chead_auxi:Ne #1 
                    { \l__nmc_table_cvar_tl = \exp_not:o #2 } 
                \bool_set_false:N \l__nmc_table_coli_only_bool
              }
              { \__nmc_table_chead_auxi:Ne #1 { \exp_not:o #2 } }
          }
        { 2 } { \__nmc_table_chead_auxi:Ne #1 
                    { \l__nmc_table_cvar_tl = \exp_not:o #2 } }
        { 3 } { \__nmc_table_chead_auxii:NV #1 #2 }
        { 4 } {  \__nmc_table_chead_auxiii:NV #1 #2 }
      }
      { 
        \int_if_zero:nF { \l__nmc_table_chstyle_int }
          { \tl_set_eq:NN \l__nmc_table_rhead_tl \l__nmc_table_rvar_tl }
      }
      { 
        \bool_if:NTF \l__nmc_table_chverb_bool
          { \seq_set_split:NnV #1 { & } \l__nmc_table_chead_tl }
          { \__nmc_table_chead_auxi:NV #1 #2 }
      }
    \__nmc_table_settings_chnudge:
    \__nmc_table_settings_chmath: 
    \__nmc_table_settings_chsize:
  }
\cs_new_protected:Npn \__nmc_table_chead_auxi:Nn #1#2
  {
    \seq_put_right:Ne #1 { \exp_not:o \l__nmc_table_chsize_tl 
        \__nmc_table_chead_nudge:Nnn c
            { \l__nmc_table_chmath_tl \  \exp_not:n { #2 } } 
                \l__nmc_table_chnudge_tl }
  }
\cs_generate_variant:Nn \__nmc_table_chead_auxi:Nn { NV,Ne }

\cs_new_protected:Npn \__nmc_table_chead_auxii:Nn #1#2
  {
    \tl_set_eq:NN \l_tmpa_tl \l__nmc_formula_dup_tl
    \regex_replace_all:nnNT { \u{l__nmc_table_cvar_tl} } { #2 } \l_tmpa_tl
      { \__nmc_table_chead_auxi:NV #1 \l_tmpa_tl }
  }
\cs_generate_variant:Nn \__nmc_table_chead_auxii:Nn { NV }

\cs_new_protected:Npn \__nmc_table_chead_auxiii:Nn #1#2
  {
    \tl_set_eq:NN \l_tmpa_tl \l__nmc_formula_dup_tl
    \fp_compare:nNnTF { #2 } = { 1 }
      { \regex_replace_all:nnNT { \u{l__nmc_table_cvar_tl} } { } \l_tmpa_tl }
      { \regex_replace_all:nnNT 
            { \u{l__nmc_table_cvar_tl} } { #2 } \l_tmpa_tl }
      { \__nmc_table_chead_auxi:NV #1 \l_tmpa_tl }

  }
\cs_generate_variant:Nn \__nmc_table_chead_auxiii:Nn { NV }
% #1=r(ow)/c(ol), #2=var, #3=nudge
\cs_new:Npn \__nmc_table_chead_nudge:Nnn #1#2#3
  {
    \tl_if_head_eq_charcode:vNTF { l__nmc_table_#1 align_tl } r
      { $ #2 #3 $ } { $ #3 #2 $ }
  }
\cs_generate_variant:Nn \__nmc_table_chead_nudge:Nnn { NnV }
% format_items: /
\cs_new:Npn \__nmc_table_header:
  {
    \int_if_zero:nTF { \l__nmc_table_cnum_int }
      { \exp_not:o \l__nmc_table_rhsize_tl
        \__nmc_table_chead_nudge:Nnn r
          { \exp_not:o \l__nmc_table_rhead_tl }
            \l__nmc_table_rhnudge_tl 
      }
      {
        \int_if_odd:nT { \l__nmc_table_rpos_int } 
          { 
            \exp_not:o \l__nmc_table_rhsize_tl
            \__nmc_table_chead_nudge:Nnn r 
              { \exp_not:o \l__nmc_table_rhead_tl }
                \l__nmc_table_rhnudge_tl &
          }
        \exp_not:o \l__nmc_table_chead_tl
        \int_compare:nNnT { \l__nmc_table_rpos_int } > { 1 }
          {
            & \exp_not:o \l__nmc_table_rhsize_tl
            \__nmc_table_chead_nudge:Nnn r 
              { \exp_not:o \l__nmc_table_rheadi_tl }
                \l__nmc_table_rhnudgei_tl 
           }
      }
  }
% format_items: / #1 footer_tl, #2 header_tl
\cs_new_protected:Npn \__nmc_table_footer:NN #1#2
  { 
    \bool_if:nTF 
        { 
          \l__nmc_table_transpose_bool &&
          \int_compare_p:nNn { \l__nmc_table_rpos_int } = { 5 } 
        }
      { \tl_set:Ne #1 { \seq_use:Nn \l__nmc_table_rvcoli_seq { & } } }
      {
        \tl_if_empty:NF #1
          {
            \seq_set_split:NnV \l_tmpa_seq { & } #2
            \str_if_eq:VnTF #1 {''}
              { \__nmc_table_footer_ditto:NN #1#2 }
              {
                \str_if_eq:VnTF #1 { * }
                  { \__nmc_table_footer_reverse:N #1 }
                  { \tl_set_eq:NN #1 #2 }
              }
          }
      }
  }
\cs_new_protected:Npn \__nmc_table_footer_ditto:NN #1#2
  { 
    \bool_if:NTF \l__nmc_table_rhauto_bool
      {
        \int_if_odd:nT { \l__nmc_table_rpos_int }
          {
            \seq_pop_left:NN \l_tmpa_seq \l_tmpa_tl
            \tl_replace_once:Nnn \l_tmpa_tl { \backslash } { / }
            \seq_put_left:NV \l_tmpa_seq \l_tmpa_tl
          }
        \int_compare:nNnT { \l__nmc_table_rpos_int } > { 1 }
          {
            \seq_pop_right:NN \l_tmpa_seq \l_tmpa_tl
            \tl_replace_once:Nnn \l_tmpa_tl { / } { \backslash }
            \seq_put_right:NV \l_tmpa_seq \l_tmpa_tl
          }
        \tl_set:Ne #1 { \seq_use:Nn \l_tmpa_seq { & } }
      }
      { \tl_set_eq:NN #1 #2 }
  }
\cs_new_protected:Npn \__nmc_table_footer_reverse:N #1
  { 
    \int_if_zero:nTF \l__nmc_table_cnum_int
      { 
        \seq_pop_left:NNT \l_tmpa_seq \l_tmpa_tl
          { \tl_set:NV #1 \l_tmpa_tl }
      }
      {
        \seq_reverse:N \l_tmpa_seq 
        \tl_set:Ne #1 { \seq_use:Nn \l_tmpa_seq { & } }
      }
  }
%%%%%%%%%%
% process: /
\cs_new_protected:Npn \__nmc_table_assemble_body:
  {
    \__nmc_table_attach_rvcol:N \l__nmc_table_fvcols_seq
    \__nmc_table_rows_from_cols:N \l__nmc_table_rows_seq
    \__nmc_table_space_rows:N \l__nmc_result_tl
  }
% assemble_body: / #1 fvcols_seq
\cs_new_protected:Npn \__nmc_table_fvcols_format:N #1
  {
    \int_zero:N \l__nmc_table_rbloc_int
    \bool_if:NT \l__nmc_table_round_bool
      { \__nmc_table_reset_rounding:Nn c { 0 } }
    \seq_clear:N \l_tmpd_seq
    \seq_map_variable:NNn #1 \l_tmpa_seq 
      { 
        \bool_if:NT \l__nmc_table_round_bool
          { \__nmc_table_reset_rounding:Nn r { 0 } }
        \seq_clear:N \l_tmpb_seq
        \__nmc_table_bodycols_format:NN \l_tmpb_seq \l_tmpa_seq 
        \seq_put_right:NV \l_tmpd_seq \l_tmpb_seq
      }
    \seq_set_eq:NN #1 \l_tmpd_seq
  }
% process: #1 fvcols_seq
\cs_new_protected:Npn \__nmc_table_attach_rvcol:N #1
  {
    \int_if_zero:nF { \l__nmc_table_rpos_int }
      {
        \int_compare:nNnF { \l__nmc_table_rpos_int } = { 2 }
          { \seq_put_left:NV #1 \l__nmc_table_rvcol_seq }
        \int_compare:nNnT { \l__nmc_table_rpos_int } > { 1 }
          { \seq_put_right:NV #1 \l__nmc_table_rvcoli_seq }
      }
  }
\cs_new_protected:Npn  \__nmc_table_attach_rvcol_aux:nn #1#2
  {
    \seq_put_left:Nn #2 { #1 } 
    \seq_put_right:Nn \l_tmpa_seq { #2 }
  }
% process: #1 rows_seq
\cs_new_protected:Npn \__nmc_table_rows_from_cols:N #1
  { 
    \int_step_inline:nn { \l__nmc_table_rnum_int }
      {
        \seq_clear:N \l_tmpb_seq
        \seq_clear:N \l_tmpc_seq
        \seq_map_variable:NNn \l__nmc_table_fvcols_seq \l_tmpa_seq
          {  
            \seq_pop:NN \l_tmpa_seq \l_tmpa_tl
            \seq_put_right:Ne \l_tmpb_seq { \exp_not:o\l_tmpa_tl }
            \seq_put_right:NV \l_tmpc_seq \l_tmpa_seq
          }
        \seq_put_right:NV #1 \l_tmpb_seq
        \seq_set_eq:NN \l__nmc_table_fvcols_seq \l_tmpc_seq        
      }
  }
% process: #1 \l__nmc_result_tl
\cs_new_protected:Npn \__nmc_table_space_rows:N #1
  {
    \tl_clear:N \l__nmc_result_tl
    \seq_map_variable:NNn \l__nmc_table_rows_seq \l_tmpa_seq
      { 
        \__nmc_table_rbloc_spc:NN \l__nmc_table_rbloc_int \l_tmpa_bool
        \tl_put_right:Ne #1
          { 
            \seq_use:Nn \l_tmpa_seq { & } \\~
            \bool_if:NT \l_tmpa_bool
              { \exp_not:o \addlinespace[\l__nmc_table_rblocsep_tl] }
          }
      }
  }

\cs_new_protected:Npn \__nmc_table_rbloc_spc:NN #1#2
  { 
    \int_incr:N #1 
    \bool_set_false:N #2
    \int_compare:nNnT { #1 } = { \l__nmc_table_rblock_tl }
      { 
        \int_compare:nNnF { #1 } = { \l__nmc_table_rnum_int }
          { \bool_set_true:N #2 }
        \clist_if_empty:NF \l__nmc_table_rbloc_clist
          { \clist_pop:NN \l__nmc_table_rbloc_clist \l__nmc_table_rbloc_tl }
        \tl_set:Ne \l__nmc_table_rblock_tl 
            { \int_eval:n { \l__nmc_table_rblock_tl + \l__nmc_table_rbloc_tl } }
      }
  } 
% #1 formatted col seq out #2 raw col seq in
\cs_new_protected:Npn \__nmc_table_bodycols_format:NN #1#2
  { 
    \int_case:nnF {  \l__nmc_table_rnum_int }
      {
        { 0 } { \prg_do_nothing: }
        { 1 } { \__nmc_table_form_cols_ri:NN #1 #2 }
        { 2 } { \__nmc_table_form_cols_rii:NN #1 #2 }
      }
      { \__nmc_table_form_cols_riii:NN #1 #2 }
    \bool_if:NT \l__nmc_table_round_bool
      { \__nmc_table_reset_rounding:Nn c { 1 } }
  }
\cs_new_protected:Npn \__nmc_table_form_cols_ri:NN #1#2
  { 
    \seq_pop:NN #2 \l_tmpb_fp
    \__nmc_num_format:nNnN \l_tmpb_fp \l_tmpb_tl 
        { \l__nmc_round_int } \l__nmc_sci_num_table_bool
    \bool_if:NT \l__nmc_table_QA_bool
      { \__nmc_table_QA:N \l_tmpb_tl }
    \seq_put_right:Ne #1 { $ \exp_not:o \l_tmpb_tl $ }
  }
\cs_new_protected:Npn \__nmc_table_form_cols_rii:NN #1#2
  {
    \__nmc_table_form_cols_rii_aux:NN #1#2
    \__nmc_table_signs:
    \__nmc_num_format:nNnN \l_tmpb_fp \l_tmpb_tl 
        { \l__nmc_round_int } \l__nmc_sci_num_out_bool
    \__nmc_table_num_format:N \l_tmpb_tl
    \seq_put_right:Ne #1 
        { $ \exp_not:o \l_tmpb_tl \exp_not:o \l__nmc_table_diffs_tl $ }
  }
\cs_new_protected:Npn \__nmc_table_form_cols_rii_aux:NN #1#2
  { 
    \seq_pop:NN #2 \l_tmpb_fp
    \int_if_zero:nF \l__nmc_table_diffs_int
      { \__nmc_table_form_diffs_null:n { \l__nmc_table_diffs_int } }
    \seq_pop:NN #2 \l_tmpa_fp
    \int_set:Nn \l__nmc_table_c_int { 1 }    
    \int_set:Nn \l__nmc_table_b_int { \fp_sign:n { \l_tmpb_fp } }
    \int_set:Nn \l__nmc_table_a_int { \fp_sign:n { \l_tmpa_fp } }
    \__nmc_table_signs:
    \__nmc_num_format:nNnN \l_tmpb_fp \l_tmpb_tl 
        { \l__nmc_round_int } \l__nmc_sci_num_out_bool
    \__nmc_table_num_format:N \l_tmpb_tl
    \seq_put_right:Ne #1 
        { $ \exp_not:o \l_tmpb_tl \exp_not:o \l__nmc_table_diffs_tl $ }
    \int_if_zero:nF \l__nmc_table_diffs_int
      { \__nmc_table_calc_diffs:nn { \l_tmpb_fp } { \l_tmpa_fp } }
    \fp_set_eq:NN \l_tmpb_fp \l_tmpa_fp 
  }
\cs_new_protected:Npn \__nmc_table_form_cols_riii:NN #1#2
  { 
    \__nmc_table_form_cols_rii_aux:NN #1#2
    \bool_if:NT \l__nmc_table_round_bool
      { \__nmc_table_reset_rounding:Nn r { 1 } }
    \int_set_eq:NN \l__nmc_table_c_int \l__nmc_table_b_int
    \int_set_eq:NN \l__nmc_table_b_int \l__nmc_table_a_int
    \seq_map_variable:NNn #2 \l_tmpa_fp
      { 
        \int_set:Nn \l__nmc_table_a_int { \fp_sign:n { \l_tmpa_fp } } 
        \__nmc_table_signs:
        \__nmc_num_format:nNnN \l_tmpb_fp \l_tmpb_tl 
            { \l__nmc_round_int } \l__nmc_sci_num_out_bool
        \__nmc_table_num_format:N \l_tmpb_tl
        \seq_put_right:Ne #1 
            { $ \exp_not:o \l_tmpb_tl \exp_not:o \l__nmc_table_diffs_tl $ }
        \int_if_zero:nF \l__nmc_table_diffs_int
          { \__nmc_table_calc_diffs:nn { \l_tmpb_fp } { \l_tmpa_fp } }
        \fp_set_eq:NN \l_tmpb_fp \l_tmpa_fp
        \int_set_eq:NN \l__nmc_table_c_int \l__nmc_table_b_int
        \int_set_eq:NN \l__nmc_table_b_int \l__nmc_table_a_int 
        \bool_if:NT \l__nmc_table_round_bool
          { \__nmc_table_reset_rounding:Nn r { 1 } }
      }
    \int_set:Nn \l__nmc_table_a_int { 1 } 
    \__nmc_table_signs:
    \__nmc_num_format:nNnN \l_tmpb_fp \l_tmpb_tl 
        { \l__nmc_round_int } \l__nmc_sci_num_out_bool
    \__nmc_table_num_format:N \l_tmpb_tl
    \seq_put_right:Ne #1 
        { $ \exp_not:o \l_tmpb_tl \exp_not:o \l__nmc_table_diffs_tl $ }
  }
\cs_new_protected:Npn \__nmc_table_num_format:N #1
  { 
    \bool_if:NTF \l__nmc_sci_num_table_bool
      { 
        \tl_if_head_eq_charcode:VNTF #1 ( 
          { % for nums in [1,10)
            \exp_last_unbraced:NV 
                \__nmc_table_t_format:wN #1\q_stop \l_tmpa_tl
            \tl_set_eq:NN #1 \l_tmpa_tl
          }
          { \tl_set:Ne #1 { \__nmc_sci_num_table_signs:n { #1 } } 
            
          }
      }
      { \tl_set:Ne #1 { \__nmc_sci_num_table_signs:n { #1 } } }
    \bool_if:NT \l__nmc_table_QA_bool
      { \__nmc_table_QA:N #1 }
  }
\cs_new_protected:Npn \__nmc_table_QA:N #1
  {
    \fp_compare:nNnT { \l__nmc_table_Q_tl } = { 1 }
      { 
        \bool_lazy_and:nnT 
            { \l__nmc_num_only_bool } { !\l__nmc_table_numonly_bool }
          { 
            \tl_set_eq:NN \l__nmc_table_numonly_tl #1 
            \bool_set_true:N \l__nmc_table_numonly_bool
          }
        \tl_set:Ne #1 { \l__nmc_table_A_tl }
      }
  }
\cs_new_protected:Npn \__nmc_table_t_format:wN (#1)#2#3\q_stop #4
  { 
    \tl_set:Nn \l__nmc_toss_tl { #1 }
   \__nmc_table_prepad:Nnn \l__nmc_toss_tl
     { \l__nmc_table_tsigns_int } { \exp_not:o \hphantom{-} }
    \tl_set:Ne #4 { \__nmc_sci_num_table_plus:nn 
        { #3 } { \exp_not:o\l__nmc_toss_tl } }
  }
\cs_new_protected:Npn \__nmc_table_calc_diffs:nn #1#2
  { 
    \__nmc_num_format:nNnN 
      { \fp_abs:n {round( #1,\l__nmc_round_int ) 
          - round( #2, \l__nmc_round_int) } } \l_tmpb_tl
        { \l__nmc_round_int } \c_false_bool    
    \tl_set:Ne \l_tmpb_tl { \fp_eval:n { round( 10^{ \l__nmc_round_int }
        * \l_tmpb_tl, \l__nmc_round_int + 1) } }
    \__nmc_table_prepad:Nnn \l_tmpb_tl { \l__nmc_table_diffs_int } { 0 }
    \tl_set:Ne \l__nmc_table_diffs_tl { ^{\,^{ \l_tmpb_tl } } }
  }
\cs_new_protected:Npn \__nmc_table_form_diffs_null:n #1
  {
    \tl_set:Nn \l_tmpb_tl { 0 }
    \__nmc_table_prepad:Nnn \l_tmpb_tl { #1 } { 0 }
    \tl_set:Ne \l__nmc_table_diffs_tl 
        { ^{\,^{ \exp_not:o \hphantom{ \l_tmpb_tl } } } }
  }  
\cs_new_protected:Npn \__nmc_table_signs:
  { % A prev, B current, C next
    \int_compare:nNnTF \l__nmc_table_b_int > { -1 } 
      {
        \bool_lazy_or:nnTF
            { \int_compare_p:nNn \l__nmc_table_a_int = { -1 } }
            { \int_compare_p:nNn \l__nmc_table_c_int = { -1 } }
          { \bool_set_true:N \l__nmc_table_signs_bool }
          { \bool_set_false:N \l__nmc_table_signs_bool }
      }
      { \bool_set_false:N \l__nmc_table_signs_bool }
  }
\cs_new:Npn \__nmc_sci_num_table_signs:n #1
  { 
    \int_compare:nNnF { \l__nmc_num_sgn_int } < { 0 }
      { 
        \int_case:nn { \l__nmc_table_signs_int }
          {
            {-2 } { \exp_not:N \hphantom{+} }
            {-1 } { \bool_if:NTF \l__nmc_table_signs_bool 
                        { + }{ \exp_not:N \hphantom{+} } }
            { 1 } { \bool_if:NT \l__nmc_table_signs_bool { + } }
            { 2 } { + }
          }
      } 
    \exp_not:o { #1 }
  }
\cs_new_protected:Npn \__nmc_table_prepad:Nnn #1#2#3
  { 
    \tl_put_left:Ne #1 { \prg_replicate:nn 
        { \int_max:nn { #2 - \tl_count:N #1 } { 0 } } { #3 } }
  }
\cs_new:Npn \__nmc_sci_num_table_plus:nn #1#2
  { % #1 significand, #2 exponent
    \fp_compare:nTF { #1 >= 0 }
      { ( #2 )\,{ \__nmc_sci_num_table_signs:n { #1 } } }
      { ( #2 )\,{ #1 } }
  }
% \__nmc_table_format_cols:NN, #1 r/c; #2 0 (pre)/1 (post)
\cs_new_protected:Npn \__nmc_table_reset_rounding:Nn #1#2
  { 
    \int_if_zero:nTF { #2 }
      { \fp_set_eq:cc { l__nmc_table_#1_fp } { l__nmc_table_#1 start_fp } }
      { \fp_add:cv { l__nmc_table_#1_fp } { l__nmc_table_#1step_fp  } }
    \prop_put:Nve  \l__nmc_subst_var_prop { l__nmc_table_#1 var_tl }
        { \fp_use:c { l__nmc_table_#1_fp } }
    \tl_clear:N \l_tmpc_tl
    \__nmc_fpify:VN \l__nmc_round_xpr_tl \l_tmpc_tl
    \int_set:Nn \l__nmc_round_int { \fp_to_int:n \l_tmpc_tl }
  }
% thiscol_calc:NN #1 tmpa_fp (fn val. from calc_fn_val:VNnN)
\cs_new_protected:Npn \__nmc_table_maxmin_do:n #1
  {
    \bool_if:NT \l__nmc_table_QAmax_bool
      { \fp_set:Nn \l__nmc_table_max_fp 
            { \fp_max:nn { \l__nmc_table_max_fp } { #1} } }
    \bool_if:NT \l__nmc_table_QAmin_bool
      { \fp_set:Nn \l__nmc_table_min_fp 
            { \fp_min:nn { \l__nmc_table_min_fp } { #1 } } }
  }
%%%%%%%%%%
% process: /
\cs_new_protected:Npn \__nmc_table_num_only:
  {
    \bool_if:NTF \l__nmc_table_numonly_bool
      { 
        \tl_set_eq:NN \l__nmc_result_tl \l__nmc_table_numonly_tl
        \tl_gset_eq:NN \g__nmc_reuse_tl \l__nmc_table_numonly_tl
        \bool_gset_true:N \g__nmc_reuse_bool
      }
      { 
        \__nmc_error_where:n { settings }
        \__nmc_error_what:n  
            { \l__nmc_table_query_tl~query~\__nmc_verb:n {Q?}~in }
        \tl_clear:N \l__nmc_result_tl
      }
  }
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% display:
\cs_new:Npn \__nmc_table_upper:
  { 
    \exp_not:n { \begin{tabular} }
    \l__nmc_table_valign_tl 
    {
      \int_if_odd:nT { \l__nmc_table_rpos_int }
        { \l__nmc_table_ralign_tl } 
      \prg_replicate:nn 
        { \l__nmc_table_cnum_int } \l__nmc_table_calign_tl
      \int_compare:nNnT { \l__nmc_table_rpos_int } > { 1 }
        { \l__nmc_table_ralign_tl }
    }
    \__nmc_if_mod_zero:nnT { \l__nmc_table_rules_int } { 2 }
      { \exp_not:N  \toprule }
    \int_if_zero:nF { \l__nmc_table_ctitle_int }
      { \__nmc_table_ctitle_form: } 
  }
% upper: 
\cs_new:Npn \__nmc_table_ctitle_form: 
  {
    \int_compare:nNnTF { \l__nmc_table_rpos_int } = { 0 }
      { 
        \int_compare:nNnF { \l__nmc_table_cnum_int } = { 1 }
          {
            \__nmc_table_ctitle_form:nenn { 1 }
                { \int_use:N \l__nmc_table_cnum_int } {} {} 
          }
      }
      { 
        \int_compare:nNnT { \l__nmc_table_cnum_int } > { 1 }
          { 
            \int_case:nnF { \l__nmc_table_rpos_int }
              { 
                { 1 } { \__nmc_table_ctitle_form:nenn { 2 }
                          { \l__nmc_table_totalcols_tl } { & } {} }
                { 2 } { \__nmc_table_ctitle_form:nenn { 1 }
                          { \int_use:N \l__nmc_table_cnum_int } {} { & } }
              } 
              { % 3,4/5
                 \__nmc_table_ctitle_form:nenn { 2 }
                      { \int_eval:n { \l__nmc_table_cnum_int + 1 } }
                          { & } { & }
              }
          }
      }
  }
% ctitle_form: #1 midrule start, #2 midrule end, #3 left &, #4 right &
\cs_new:Npn \__nmc_table_ctitle_form:nnnn #1#2#3#4
  { 
    #3 \exp_not:N \multicolumn
    { \int_eval:n { \l__nmc_table_cnum_int } } { c }
    { $ \exp_not:o \l__nmc_table_ctitle_tl $  }
    #4 \\~
    \__nmc_if_mod_zero:nnT { \l__nmc_table_rules_int } { 3 }
      { \exp_not:N \cmidrule(lr) { #1-\int_eval:n { #2 } } }
    \tl_if_empty:NF \l__nmc_table_csubt_tl
      { 
        \__nmc_table_csubtitle: 
        \__nmc_if_mod_zero:nnT { \l__nmc_table_rules_int } { 5 }
          { \__nmc_table_csubtitle_rule:nn { #1 } { #2 } }
      }
  }
\cs_generate_variant:Nn \__nmc_table_ctitle_form:nnnn { ne }
% ctitle_form:nnnn
\cs_new:Npn \__nmc_table_csubtitle:
  {
    \int_if_zero:nF { \l__nmc_table_cnum_int }
      { 
        \int_case:nnF { \l__nmc_table_rpos_int }
          {
            { 1 } { & \exp_not:o \l__nmc_table_csubt_tl }
            { 2 } { \exp_not:o \l__nmc_table_csubt_tl & }
            { 0 } { \exp_not:o \l__nmc_table_csubt_tl }
          }
          { & \exp_not:o \l__nmc_table_csubt_tl & }
      }
    \\~
  }
% ctitle_form:nnnn 
\cs_new:Npn \__nmc_table_csubtitle_rule:nn #1#2
  { 
    \int_compare:nNnTF { \l__nmc_table_rpos_int } > { 2 }
      { \exp_not:N \cmidrule(lr) { 1-\l__nmc_table_totalcols_tl } }
      { \exp_not:N \cmidrule(lr) { { #1 }-\int_eval:n { #2 } } } 
  }
% display: 
\cs_new:Npn \__nmc_table_lower:
  {
    \tl_if_empty:NF \l__nmc_table_footer_tl
      { 
        \__nmc_if_mod_zero:nnTF { \l__nmc_table_rules_int } { 17 }
          { \exp_not:N \midrule }
          {
            \__nmc_if_mod_zero:nnT { \l__nmc_table_rules_int } { 13 }
              { \exp_not:N \cmidrule(lr) { 1-\l__nmc_table_totalcols_tl } }
          }
        \exp_not:o \l__nmc_table_footer_tl
        \\~
      }
    \__nmc_if_mod_zero:nnT { \l__nmc_table_rules_int } { 19 }
      { \exp_not:N \bottomrule }
    \exp_not:n { \end{tabular} }
  } 
% end of `numerica-tables.sty'