TransWikia.com

Table from multiple delimiter list

TeX - LaTeX Asked by cdickstein on May 21, 2021

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{;/,}
readlisttrlist{#5}
foreach n in {1,...,trlistlen}
{
#1trlist[n,1] & trlist[n,2] #2 
hline
}
makeatother
ProcessOptionsrelax


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 Answers

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

Correct answer by egreg on May 21, 2021

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}

newtokstemptabtoks
newcommandaddtabtoks[1]{globaltemptabtoksexpandafter{thetemptabtoks#1}}
newcommandeaddtabtoks[1]{edefetemp{#1}expandafteraddtabtoksexpandafter{etemp}}
newcommand*resettabtoks{globaltemptabtoks{}}
newcommand*printtabtoks{thetemptabtoks}

% #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{;/,}
readlisttrlist{#5}
resettabtoks
addtabtoks{hline}
addtabtoks{textbf{#3} & textbf{#4} }
addtabtoks{hline}
foreach n in {1,...,trlistlen} {
  eaddtabtoks{#1trlist[n,1]}
  addtabtoks{&} 
  eaddtabtoks{trlist[n,2]#2}
  addtabtoks{}
  addtabtoks{hline}
}
begin{tabular}{| l | r |}
printtabtoks
end{tabular}
}

ProcessOptionsrelax

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

Answered by Jasper Habicht on May 21, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP