I want to store several pieces of data, each of the following type, so that I can manipulate them both for formatting and for calculations. The number of lines analysed in the user's code is not fixed in advance.
I have already made the parser that extracts this values.
LINE: 1
CTXT: xvals
LABEL: t
VAL: 1, 20, 300, 4000
LINE: 2
CTXT: imgs
LABEL: f(t)
VAL: a , b, bb, ccc, dddd
LINE: 3
CTXT: imgs
LABEL: g(t)
VAL: U, V, VV, WWW, XXXX
I will produce in this simple situation the following output, see the nicematrix table, but this is only the 1st functionality. I would like for example to compute the maximum of f later in the document. To do that, I need to recover the context imgs such as to find the label f(t) and its associated values.
\documentclass[11pt, a4paper]{article}
\usepackage{nicematrix}
\begin{document}
\section{What the user types}
\begin{verbatim}
\begin{functable}
xvals = t : 1 , 20 , 300 , 4000 ;
imgs = f(t) : a , bb , ccc , dddd ;
g(t) : U , VV , WWW , XXXX
\end{functable}
\end{verbatim}
\section{What the user sees}
$\begin{NiceArray}[cell-space-limits = 3pt]{c*{4}{|c}}
t & 1 & 20 & 300 & 4000
\ \hline
f(t) & a & bb & ccc & dddd
\ \hline
g(t) & U & VV & VVV & WWW
\end{NiceArray}$
\section{What can be do after}
The user can ask for example to rebuild the 1st table
with something like this.
\begin{verbatim}
\begin{functable}[rebuild=1]
\end{functable}
\end{verbatim}
The user can also ask to calculate the maximum value
of $f(t)$ via something like \verb+\calcfunctable{max=f(t)}+.
\end{document}
I see two possibilities.
Either use the
starraypackage, but I fear that this project will be not maintained in the long term.Or I can try to implement a homemade solution which looks like a list of property lists.
JSON like structure expected [2024-03-09.v1]
The idea is to have a variable associated with each table, a variable that can be iterated dictionary by dictionary, and for each dictionary thus obtained, we will have access to the different types of values.
[
{
'CTX' : 'xvals',
'VAL' : ['1', '20', '300', '4000'],
'LABEL': 't',
'LINE' : '1'
},
{
'CTX' : 'imgs',
'VAL' : ['a' , 'b', 'bb', 'ccc', 'dddd'],
'LABEL': 'f(t)',
'LINE' : '2'
},
{
'CTX' : 'imgs',
'VAL' : ['U', 'V', 'VV', 'WWW', 'XXXX'],
'LABEL': 'g(t)',
'LINE' : '3'
}
]
Some additional information [2024-01-17.v1]
The parser gives
l3-token lists.The value of
VALkeys can be used as comma separated lists, or as sequences byL3functions. The second choice should be better.The values will be used in different situations, sometimes to print a table, sometimes to perform calculations. This should be similar to what it is done in this answer.
Proof of Concept simplified [2024-03-09.v1]
\documentclass[12pt]{article}
\ExplSyntaxOn
% -- FUNCTABLE ENV. -- %
\NewDocumentEnvironment{ functable }{ b }{%
\tns_functab_functable:n { #1 }
}{}
\cs_new:Npn \tns_functab_functable:n #1 {
\tns_core_DSL_ctxt_parser:nn { functable } { #1 }
\bigskip\par
NEW ~ DATA ~ \int_use:N \g_tns_functab_id_int
\par
TODO
}
% -- DSL - L3 -- %
\tl_new:N \g_tns_functab_semicolon_tl
\tl_gset:Nn \g_tns_functab_semicolon_tl { ; }
\tl_new:N \g_tns_functab_colon_tl
\tl_gset:Nn \g_tns_functab_colon_tl { : }
\cs_generate_variant:Nn \seq_set_split:Nnn { NV }
\AtBeginDocument {
\tl_gset_rescan:NnV \g_tns_functab_semicolon_tl
{}
\g_tns_functab_semicolon_tl
\tl_gset_rescan:NnV \g_tns_functab_colon_tl
{}
\g_tns_functab_colon_tl
}
% :: AGNOSTIC PARSERS :: %
\int_new:N \g_tns_functab_id_int
\int_gset:Nn \g_tns_functab_id_int { 0 }
\int_new:N \l_tns_core_ctxt_nb_line_int
\seq_new:N \l_tns_core_ctxts_seq
\tl_new:N \l_tns_core_current_ctxt_tl
\cs_new:Npn \tns_core_DSL_ctxt_parser:nn #1#2 {
% The ID nb. of the env.
\int_gincr:N \g_tns_functab_id_int
% Line by line parsing.
%
% Lines are semi-colon separated.
\seq_set_split:NVn \l_tns_core_ctxts_seq
\g_tns_functab_semicolon_tl
{ #2 }
\int_zero:N \l_tns_core_ctxt_nb_line_int
\seq_map_inline:Nn \l_tns_core_ctxts_seq {
\bigskip\par
\int_incr:N \l_tns_core_ctxt_nb_line_int
Line ~ \int_use:N \l_tns_core_ctxt_nb_line_int
\par
% Get the context and its content.
\seq_set_split:Nnn \l_tmpa_seq { = } { ##1 }
\int_set:Nn \l_tmpa_int {\seq_count:N \l_tmpa_seq}
\quad
\int_case:nnF { \int_use:N \l_tmpa_int } {
{ 1 } {
LAST - CTXT: ~
(\tl_use:N \l_tns_core_current_ctxt_tl)
}
{ 2 } {
\seq_pop_left:NN \l_tmpa_seq \l_tns_core_current_ctxt_tl
NEW - CTXT: ~
(\tl_use:N \l_tns_core_current_ctxt_tl)
}
}{
ILLEGAL!
}
% Get the optional label and its content.
\seq_pop_left:NN \l_tmpa_seq \l_tmpa_tl
\seq_set_split:NVV \l_tmpa_seq
\g_tns_functab_colon_tl
\l_tmpa_tl
\int_set:Nn \l_tmpa_int {\seq_count:N \l_tmpa_seq}
\par\quad
\int_case:nnF { \int_use:N \l_tmpa_int } {
{ 1 } {
NO LABEL
}
{ 2 } {
\seq_pop_left:NN \l_tmpa_seq \l_tmpa_tl
LABEL: ~
$(\tl_use:N \l_tmpa_tl)$
}
}{
ILLEGAL!
}
\par\quad
\seq_pop_left:NN \l_tmpa_seq \l_tmpa_tl
VAL: ~
$(\tl_use:N \l_tmpa_tl)$
}
}
\ExplSyntaxOff
\begin{document}
\begin{functable}
xvals = t : 1 , 20 , 300 , 4000 ;
imgs = f(t) : a , bb , ccc , dddd ;
g(t) : U , VV , WWW , XXXX
\end{functable}
\end{document}


,,:, and;.) – Alan Munn Jan 15 '24 at 22:36\def\linei{{xvals}{t}{(1, 20, 300, 4000)}}\def\liniii{{imgs}{f(t)}{(a ; b, bb, ccc, dddd)}}then for example\def\listval#1{\expandafter\expandafter\expandafter\@thirdofthree\csname list\romanumeral#1\endcsname}so\listval{2}expands to(a ; b, bb, ccc, dddd)– David Carlisle Jan 15 '24 at 22:44\int_set:Nn \g_tns_functab_id_int { 0 }is wrong. If it is global, usegset. If it isn't, use\l_tns_functab_id_int. On topic: but what is it supposed to build? It's not clear what you want the result to be. I know you want something, but I really have no idea what. – cfr Mar 09 '24 at 20:03