TransWikia.com

Creating a bold header for a table with the csvsimple, siunitx, and tokcycle packages

TeX - LaTeX Asked on June 14, 2021

I found this post, illustrating how to typeset the header of a table in bold face. Combining it with csvreader from the csvsimple package worked fine, as long as I don’t format the numbers using siunitx package. Below sisetup fixes two decimal points as in this answer.

documentclass{article}
usepackage{csvsimple, siunitx, booktabs, array}

begin{filecontents*}{sample.csv}
Player, Merlin, Mordred
Andrew, 0.6, 0.55
Ben, 0.54, 0.62
end{filecontents*}

newcolumntype{+}{>{globalletcurrentrowstylerelax}}
newcolumntype{-}{>{currentrowstyle}}
newcommand{rowstyle}[1]{gdefcurrentrowstyle{#1}#1ignorespaces}

csvstyle{boldhead}{
    no head,
    table head=toprulerowstyle{bfseries},
    late after first line= midrule, 
    table foot=bottomrule
}
sisetup{round-mode=places, round-precision=2, round-integer-to-decimal}

begin{document}

csvreader[tabular=+l-c-c, boldhead]{sample.csv}{}{csvcoli & csvcolii & csvcoliii}

end{document}

I think there are three problems with this solution:

  1. The option head to column names cannot be used because the no head option is loaded. Is there a better way to display the header using csvreader that preserves the possibility of using head to column names?
  2. If I replace tabular=+l-c-c with tabular=+l-S-S, then the table no longer typesets because the siunitx package does not recognize the header and throws the error invalid numerical input 'e'.
  3. Personally, I’d prefer typing lcc instead of +l-c-c.

Since the number formatting of the siunitx package can be escaped with a group, my idea for point 2 was to include a bgroup egroup pair into the rowstyle as follows:

newcolumntype{+}{>{globalletcurrentrowstylerelaxgloballetcurrentrowstylepostrelax}}
newcolumntype{-}{>{currentrowstyle}}
newcolumntype{^}{<{currentrowstylepost}}
newcommand{rowstyle}[1]{%
    gdefcurrentrowstylepost{egroup}%
    gdefcurrentrowstyle{#1bgroup}%
    #1bgroupignorespaces%
}

While the above code works for option tabular=+l^-c^-c^, it still does not work for tabular=+l^-S^-S^. What am I missing?

Regarding point 3, one would imagine that this can be fixed with the tokcycle package. This was my attempt.

settcEscapechar{:}
newififfirstchar
Characterdirective{%
    ifx#1|%
        #1%
    else%
        iffirstchar%
            globalfirstcharfalse%
            +#1%
        else%
            -#1%
        fi%
    fi%
}

newcommand{csvboldreader}[4]{%
    globalfirstchartrue%
    csvreader[tabular=tokencyclexpress #1endtokencyclexpress, boldhead]{#2}{#3}{#4}
}

begin{document}
csvboldreader{lcc}{sample.csv}{}{csvcoli & csvcolii & csvcoliii}
end{document}

Unfortunately, it throws an error illegal token 'c' used. If I call

tokencyclexpress lccendtokencyclexpress

in isolation, the string is transformed correctly. What am I missing?

I have to admit I am not too familiar with the siunitx package and figured I’d tag on two more questions about it:

  1. What is the cleanest sisetup to align numbers centered with the header, but among each other aligned according to the decimal point? Is there a better way than setting {S[table-format=1.2]} etc. manually for each column?
  2. What is the @{} used for that appears in the siunitx manual? My first guess was that one doesn’t have to use braces for each column, but that appears to be incorrect since tabular=@{} l S S[table-format=2.2] @{} doesn’t work.

One Answer

See SUPPLEMENT for alternative.

As to the tokcycle portion of the question (item No. 3), there were two problems with the approach posted:

  1. Running the token cycle inside of csvreader optional argument does not work.

  2. Even passing a macro with the proper tokens, as in tabular=mypreamble, does not work. It must be passed the actual tokens of the tabular preamble.

Thus, several things were needed. The token cycle had to be performed in advance of the csvreader invocation and the result had to be saved in the cytoks token list. This required the Characterdirective to be changed from the direct output of <tokens> to the equivalent addcytoks{<tokens>} format. By using tokcyclexpress (macro) rather than tokencyclexpress (pseudo-environment), the automatic typsetting of thecytoks output is suppressed, even as the result is stored in cytoks.

So far, so good. But even here, tabular=thecytoks as an option in csvreader does not work. So, the invocation had to be broken into two parts: deftmp{csvreader[tabular=} followed by expandaftertmpthecytoks, boldhead]{#2}{#3}{#4}. In this way, thecytoks expanded into the actual desired tokens prior to the invocation of csvreader.

documentclass{article}
usepackage{csvsimple, siunitx, booktabs, array,tokcycle}

begin{filecontents*}[overwrite]{sample.csv}
Player, Merlin, Mordred
Andrew, 0.6, 0.55
Ben, 0.54, 0.62
end{filecontents*}

newcolumntype{+}{>{globalletcurrentrowstylerelax}}
newcolumntype{-}{>{currentrowstyle}}
newcommand{rowstyle}[1]{gdefcurrentrowstyle{#1}#1ignorespaces}

csvstyle{boldhead}{
    no head,
    table head=toprulerowstyle{bfseries},
    late after first line= midrule, 
    table foot=bottomrule
}
sisetup{round-mode=places, round-precision=2, round-integer-to-decimal}

settcEscapechar{:}
newififfirstchar
Characterdirective{%
    ifx#1|%
        addcytoks{#1}%
    else%
        iffirstchar%
            globalfirstcharfalse%
            addcytoks{+#1}%
        else%
            addcytoks{-#1}%
        fi%
    fi%
}

newcommand{csvboldreader}[4]{%
    globalfirstchartrue%
    tokcyclexpress{#1}%
    deftmp{csvreader[tabular=}%
    expandaftertmpthecytoks, boldhead]{#2}{#3}{#4}
}

begin{document}
csvboldreader{lcc}{sample.csv}{}{csvcoli & csvcolii & csvcoliii}
end{document}

enter image description here

SUPPLEMENT

Here is an alternative approach that supports the siunitx column types as well as a bolded (or other) first line:

documentclass{article}
usepackage{siunitx, booktabs, array, tokcycle, readarray}
begin{filecontents*}[overwrite]{sample.csv}
Player, Merlin, Mordred
Andrew, 0.6, 0.55
Ben, 0.54, 0.62
end{filecontents*}
sisetup{round-mode=places, round-precision=2, round-integer-to-decimal}
newififfirstrow
Characterdirective{%
  iffirstrow
    tctestifx{,#1}{addcytoks{&xxcmd}}{addcytoks{#1}}
  else
    tctestifx{,#1}{addcytoks{&}}{addcytoks{#1}}
  fi
}
Macrodirective{%
  iffirstrow
    tctestifx{#1}{firstrowfalseaddcytoks{#1midrule}}{addcytoks{#1}}
  else
    addcytoks{#1}
  fi
}
newcommandcsvxreader[3][bfseries]{%
  readarraysepchar{}%
  readdef{#3}mytab
  firstrowtrue
  defxxcmd{#1}%
  expandaftertokcyclexpressexpandafter{mytab}%
  begin{tabular}{#2}%
  toprule
  #1%
  thecytoks
  bottomrule
  end{tabular}%
}
begin{document}
csvxreader[scshape]{lcc}{sample.csv}

bigskip
csvxreader{lSS}{sample.csv}
end{document}

enter image description here

Correct answer by Steven B. Segletes on June 14, 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