TeX - LaTeX Asked by cdickstein on May 21, 2021
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.
# | 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 |
# | 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. |
# | 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. |
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}
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" |
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}
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.
Answered by Jasper Habicht on May 21, 2021
Get help from others!
Recent Answers
Recent Questions
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP