6

Question

I am trying to get a table based on a multiple delimiter string. My current idea is to use \setsepchar{} and \readlist.

I put my requirements and details into a table because I would have a harder time putting the information into sentences in a way that makes sense.

Criteria

Answer Requirement

# Requirement Reason
1 Optional add prefix to left column Same left column prefix across all rows
2 Optional add suffix to right column Same right column suffix across all rows
3 Function callable from tabular environment
4 Usable within a node The table is placed in a node in a tikzpicture environment

Options

# Option Reason
1 Multiple Delimiters So long as the prefix and suffix condition is met multiple delimiters is not a necessity.
2 Environment Instead Of A Function So long as the prefix and suffix condition is met using a function is not a necessity.

Misc Details

# Detail
1 I prefer using xparse \NewDocumentCommand and \NewDocumentEnvironment due to ease with optional parameters
2 There will only ever be 2 columns, but the number of rows could be 20 or it could be 10.
3 I will be using this many times so having a function would be much easier than doing this by hand every single time.
4 Eventually this will be put into an ".sty" file.

Code

\usepackage{xparse}
\usepackage{pgffor}
\usepackage{listofitems}

\makeatletter
% #1 = Prefix for left column 
% #2 = Suffix for right column
% #3 = Left column header
% #4 = Right column header
% #5 = Input List
\NewDocumentCommand{\ptr}{O{} O{"} O{Parameter} O{Value} m}
{
#3 & #4 \\
\setsepchar{;/,}
\readlist\trlist{#5}
\foreach \n in {1,...,\trlistlen}
{
#1\trlist[\n,1] & \trlist[\n,2] #2 \\
\hline
}
\makeatother
\ProcessOptions\relax


\begin{document}
% As Examples
Data 1
\begin{tabular}{| l | r |}
\ptr[groupa00]["]{test1,1;test2,2;test3,3}
\end{tabular}

Data 2
\begin{tabular}{| l | r |}
\ptr[groupb00]["]{test1,1;test2,2;test3,3}
\end{tabular}
\end{document}

Output

The output should be the look like below:

Data 1

Parameter Value
groupa00Test1 1"
groupa00Test2 2"
groupa00Test3 3"

Data 2

Parameter Value
groupb00Test1 1"
groupb00Test2 2"
groupb00Test3 3"
2
  • I am aware that My post is long, however, I wanted to make sure that I provided enough information, and the requirements I have. Also, I apologize if my wording is somewhat awkward as grammar and syntax have never been my strong suit.
    – cdickstein
    Mar 29, 2021 at 13:01
  • the \ptr macro is just a temporary name.
    – cdickstein
    Mar 30, 2021 at 12:52

2 Answers 2

5

I wouldn't use many optional arguments, because if you just want one you have to use all the preceding ones.

A key-value syntax seems better.

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn

\keys_define:nn { dickstein/tables }
 {
  lh   .tl_set:N  = \l_dickstein_tables_lh_tl, % left header
  lh   .initial:n = Parameter,
  rh   .tl_set:N  = \l_dickstein_tables_rh_tl, % right header
  rh   .initial:n = Value,
  pre  .tl_set:N  = \l_dickstein_tables_pre_tl, % prefix
  post .tl_set:N  = \l_dickstein_tables_post_tl, % suffix
 }
\seq_new:N \l_dickstein_tables_allrows_seq
\seq_new:N \l_dickstein_tables_onerow_seq

\NewDocumentCommand{\ptr}{O{}m}
 {
  % #1 = options
  % #2 = Input List
  \group_begin: % localize the setting of keys
  \keys_set:nn { dickstein/tables } { #1 }
  % split the input into rows
  \seq_set_split:Nnn \l_dickstein_tables_allrows_seq { ; } { #2 }
  \begin{tabular}{| l | r |}
  \hline
  \bfseries \l_dickstein_tables_lh_tl & \bfseries \l_dickstein_tables_rh_tl \\
  \hline
  % make all rows
  \seq_map_function:NN \l_dickstein_tables_allrows_seq \dickstein_tables_row:n
  \hline
  \end{tabular}
  \group_end:
}

\cs_new_protected:Nn \dickstein_tables_row:n
 {
  % split the input at the comma
  \seq_set_from_clist:Nn \l_dickstein_tables_onerow_seq { #1 }
  % the prefix
  \l_dickstein_tables_pre_tl
  % the entries
  \seq_use:Nn \l_dickstein_tables_onerow_seq { & }
  % the suffix
  \l_dickstein_tables_post_tl
  \\
 }

\ExplSyntaxOff


\begin{document}

Data 1

\ptr[pre=groupa00]{test1,1;test2,2;test3,3}

\medskip

Data 2

\ptr[
  pre=groupb00,
  post=XYZ,
  lh=P,
  rh=V
]{test1,1;test2,2;test3,3}

\end{document}

enter image description here

2
  • I definitely need to learn LaTeX3 syntax! This example seems to be quite nice teaching material. Mar 29, 2021 at 21:57
  • Perfect answer, exactly what I was looking for, and in addition, it allows me to change the column headers as well.It met my required criteriasand I appreciate using xparse \NewDocumentCommand.
    – cdickstein
    Mar 30, 2021 at 12:50
2

Similar things have already been asked here and there for example. Based on the answers to these questions, the following can be done (which, although not shown here, would also work if the resulting macro is used inside a TikZ node):

\documentclass{article}
\usepackage{xparse}
\usepackage{pgffor}
\usepackage{listofitems}

\newtoks\temptabtoks
\newcommand\addtabtoks[1]{\global\temptabtoks\expandafter{\the\temptabtoks#1}}
\newcommand\eaddtabtoks[1]{\edef\etemp{#1}\expandafter\addtabtoks\expandafter{\etemp}}
\newcommand*\resettabtoks{\global\temptabtoks{}}
\newcommand*\printtabtoks{\the\temptabtoks}

% #1 = Prefix for left column 
% #2 = Suffix for right column
% #3 = Left column header
% #4 = Right column header
% #5 = Input List
\NewDocumentCommand{\ptr}{O{} O{"} O{Parameter} O{Value} m}{%
\setsepchar{;/,}
\readlist\trlist{#5}
\resettabtoks
\addtabtoks{\hline}
\addtabtoks{\textbf{#3} & \textbf{#4} \\}
\addtabtoks{\hline}
\foreach \n in {1,...,\trlistlen} {
  \eaddtabtoks{#1\trlist[\n,1]}
  \addtabtoks{&} 
  \eaddtabtoks{\trlist[\n,2]#2}
  \addtabtoks{\\}
  \addtabtoks{\hline}
}
\begin{tabular}{| l | r |}
\printtabtoks
\end{tabular}
}

\ProcessOptions\relax

\begin{document}
Data 1

\ptr[groupa00]["]{test1,1;test2,2;test3,3}

\bigskip

Data 2

\ptr[groupb00]["]{test1,1;test2,2;test3,3}

\end{document}

As you can see, I included the tabular environment inside the \ptr macro, which is maybe not what you want (as per Requirement 3), but would spare you some typing. Also, you should probably rename the internal macros to something "safer", especially if you want to place this inside a .sty files.

enter image description here

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.