# Command for Pretty Printing a Poll/Voting as a table (Splitting Parameter Value)

I want to write a command for writing a poll. My Plan is:

\poll[<sumofvotes>]{<Poll title>}{
}


Where the asterisk means that this option had won.

This command should create a table where one column is the part before the : and the other is the part after the colon. If a colon ends with an asterisk, this line will be highlighted (with a background color) and the text "Winning Option" should be appended to the line.

I also want to sum up all votes and print an error if the sum of the votes is unequal the sumofvotes parameter - if such a parameter is present.

however, I am running into two problems:

1. How can I split text on newlines? (Tried \readlist* with \setsepchar{\n} but didnt work - how is a newline in latex referenced?)
2. how can I generate the table? (Using \foreachitem in the body of tabular seems not to work)
• You might split at newlines, but it's awkward and fragile. It's much easier using commas. – egreg Feb 3 at 23:42
• hmm, my experience is, that people tend to forget commas, especially when fast-typing like in the situation you'd be using this class (writing a protocol live during a meeting) – Tobi Feb 3 at 23:46
• TeX transforms endlines into spaces (or \par). Changing this makes the command very fragile. – egreg Feb 4 at 0:17
• I would purposefully provide the input separated with a known separator such as \\  and use that as the \setsepchar. – Steven B. Segletes Feb 4 at 0:31
• whatever separator I am using for 1., I cannot make the second part work (even if I use commas as the first separator) – Tobi Feb 4 at 0:59

It can be cleaned up. I just wanted to show the basic approach one might take.

One key here is that the \foreachitem loop variables of the list must be expanded as it is being stuffed into the tabular array. For this, I found it easier to use a token list.

\documentclass{article}
\usepackage{listofitems,xcolor}
\newcommand\winstyle{\bfseries\color{red}}
\newtoks\tabtoks
\newcommand\poll[3][0]{%
\setsepchar{\\/:/*}%
\tabtoks{}%
\def\votetally{0}%
}%
\centerline{\begin{tabular}{lrc}\the\tabtoks\end{tabular}}%
}
\begin{document}
\poll{Poll Title}{
Option A: 6\\
Option B: 11*\\
Option C: 3
}
\end{document}


You will see I did nothing with optional variable #1, but you could end the macro with and \ifnum test comparing #1 and \votetally, and burp an error message if they fail to agree.

Using endlines as delimiters is quite a problem with TeX, so I suggest the standard line terminator \\.

\documentclass{article}
\usepackage{xparse}
\usepackage[table,dvipsnames]{xcolor}
\usepackage{booktabs}

\colorlet{winning}{SkyBlue}

\ExplSyntaxOn

\NewDocumentCommand{\poll}{o m m}
{
\tobi_poll:nn { #2 } { #3 }
\IfValueT{#1}
{
\tobi_poll_check:n { #1 }
}
}

\tl_new:N \l__tobi_poll_table_tl
\tl_new:N \l__tobi_poll_vote_tl
\seq_new:N \l__tobi_poll_row_seq

\msg_new:nnnn { poll } { not-matching }
{
}
{
}

\cs_generate_variant:Nn \seq_set_split:Nnn { NV }

\cs_new_protected:Nn \tobi_poll:nn
{
\seq_set_split:Nnn \l_tobi_poll_votes_seq { \\ } { #2 }
\tl_clear:N \l__tobi_poll_table_tl
\__tobi_poll_maketable:n { #1 }
}

\cs_new_protected:Nn \__tobi_poll_row:n
{
% the sequence will contain the option as item 1 and the votes as item 2
\seq_set_split:NVn \l__tobi_poll_row_seq \c_colon_str { #1 }
% store the votes, we need to look for *
\tl_set:Nx \l__tobi_poll_vote_tl
{
\seq_item:Nn \l__tobi_poll_row_seq { 2 }
}
\str_if_eq:eeTF { * } { \str_item:Nn \l__tobi_poll_vote_tl { -1 } }
{% remove the trailing asterisk
\tl_set:Nx \l__tobi_poll_vote_tl
{
\tl_range:Nnn \l__tobi_poll_vote_tl { 1 } { -2 }
}
\tl_put_right:Nx \l__tobi_poll_table_tl
{
\exp_not:N \rowcolor{winning} % background color
\seq_item:Nn \l__tobi_poll_row_seq { 1 } &
\l__tobi_poll_vote_tl
& (Winning ~ option) % with the winning option
\exp_not:N \\
}
}
{% no asterisk
\tl_put_right:Nx \l__tobi_poll_table_tl
{
\seq_item:Nn \l__tobi_poll_row_seq { 1 } &
\l__tobi_poll_vote_tl
\exp_not:N \\
}
}
}

\cs_new_protected:Nn \tobi_poll_check:n
{
\int_compare:nF { #1 = \l_tobi_poll_votes_total_int }
{
\msg_error:nnxx { poll } { not-matching }
{ #1 }
{ \int_to_arabic:n { \l_tobi_poll_votes_total_int } }
}
}

\cs_new_protected:Nn \__tobi_poll_maketable:n
{
\begin{tabular}{lrl}
\toprule
\multicolumn{3}{c}
{
\midrule
\l__tobi_poll_table_tl
\bottomrule
\end{tabular}
}

\ExplSyntaxOff

\begin{document}

\poll{Example poll}{
A: 12  \\
B: 15* \\
C: 10  \\
D: 8
}
\poll[45]{Example poll}{
A: 12  \\
B: 15* \\
C: 10  \\
D: 8
}

\bigskip

\poll[120]{Example poll}{
A: 12  \\
B: 15* \\
C: 10  \\
D: 8
}

\end{document}


The last \poll tells the user

! Package poll Error: Votes don't match (45, expected 120)

For immediate help type H <return>.
...

l.128 }

? h

The total number of votes should be 120, you have 45

?