# Need help with macro-driven tables and expantion

This is a project I have been working on for a while now and I am stuck on implementing this new function, cell coloring.

My function works by taking in an unknown amount of data called 'weapons' and makes a table out of them. It works as a two part process. First I gather all the weapons and store each parameter into an array. Then when all the weapons have been listed another method called makesuperweapon gets used. This method retrieves all the data stored in the arrays and processes them, putting the data into a formatted table.

Now my needs are what makes this tricky, I need to have each row colored dependent on a logic statement. As shown in my bottom picture (my manually done example) you can see why I cannot simply use alternating lines to determine color.

Now onto the code. I did my best to minimize unnecessary code (this was stripped from my main cls file), but there are probably some packages I include that I dont need for this part alone. Starting with the cls fie, I establish some global variables: arrays, counters, and a boolean.

Following is \weapon{}{}{}{}{} which passes in parameters to store into the five arrays: \weaponname, \range, \shots, \damage, and \type. It also keeps track of how many weapons are currently being managed (read "my index").

\makesuperweapon is used to determine whether or not the list was entered with or without names, and calls the appropriate helper function. In this example I have only used named lists and have disabled the selector, manualy calling the helpers to demonstrate my two current methods for trying to solve the problem. Similarly ignore the commented out \unnamedsuperweaponhelper.

Moving onto the real stuff we have my two attempts to solve my issue, neither of them work. Both of them work by trying to compile the lines of the table prior to entering the table environment itself -- I was very unsuccessful trying to put loops inside the table.

The first (typeone) is built using a \renewcommand\mylines which sequentially constructs each line. Type two works by recursively concatenating each line with one another (I think). The problem with both is the order or execution. For the code to work \value{mycount} *must* be evaluated inside the for loop, as the index gets changed each iteration. Similarly the logic code containingrowcolor{mycellcolor}must also be evaluated each loop step. On the other hand,rowcolor{mycellcolor} seems to break if evaluated outside the table environment.

So that is my issue, I need to find a way to stop the evaluation of the rowcolor{mycellcolor} while using method type one, or ensure the evaluation of \value{mycount} and the logic in type two. In my examples you can see that type one will not work with cell coloring, and type two will try evaluate \value{mycount} at the end using the value 8, which is a blank index so it produces an empty line for every line. Does anyone have any ideas on how to solve this? I have been trying to learn about expansion (which I think is the same thing as evaluation) and am still a quite confused.

Onto the class.cls

\NeedsTeXFormat{LaTeX2e}
\ProvidesClass{myclass}[2016/01/15]

\RequirePackage{moresize}
\RequirePackage[english]{babel}

\RequirePackage{geometry}
\geometry{hmargin={0.75in,0.75in},vmargin={0.75in,0.75in},marginparwidth={0.8in},marginparsep={0in}}

\RequirePackage[usenames,dvipsnames,table]{xcolor}

\RequirePackage{fontspec}               % for xelatex

\RequirePackage{amsmath}            %for math
\RequirePackage{amsfonts}           %American math society fonts
\RequirePackage{gensymb}            %Used for symbols such as $\degree$

\RequirePackage{tabularx}           %more tables
\RequirePackage{multirow}           %hell
\RequirePackage{colortbl}           %table cell colors
\definecolor{mycellcolor}{rgb}{0.88,1,1}

\RequirePackage{enumerate}          % enumerate
\RequirePackage{enumitem}           % fixes lists and such (more formatting commands)
\RequirePackage{csvsimple}          % allows csv to table
\RequirePackage{readarray}          % something to parse with

\RequirePackage{arrayjob}           % array data structures
\RequirePackage{forloop}            %allows forloops

\RequirePackage{printlen}           %\uselengthunit{in} and \printlength{\value}

\RequirePackage{xparse}             %not sure what this does
\RequirePackage{etoolbox}           %some programming things, not explored yet

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%******************************************variables*****************************************************%
\newcommand{\@emptymacro}{}% Used to test against an empty macro

%*******************************************arrays*******************************************************%
\newarray{\weaponname}
\newarray{\range}
\newarray{\shots}
\newarray{\damage}
\newarray{\type}
%*******************************************counters*****************************************************%
\newcount{\weaponcount}\weaponcount 1\relax
\newcounter{mycount}% I dont know why this doesnt work as a \newcount, I think forloop needs a \newcounter
\newcommand{\mylines}{}
%*******************************************booleans*****************************************************%
\newif\iftocolor
\tocolortrue
%********************************************************************************************************%

\newcommand{\weapon}[5]{%calling function used to build up data into my arrays
\weaponname(\weaponcount)={#1}
\range(\weaponcount)={#2}
\shots(\weaponcount)={#3}
\damage(\weaponcount)={#4}
\type(\weaponcount)={#5}
%\identifier(\weaponcount)={#6}
}

\newcommand{\makesuperweapon}{
\checkweaponname(1)
\ifemptydata
%\unnamedsuperweaponhelper       %commented out for this question only
\else
%\namedsuperweaponhelper         %commented out for this example only
\fi
}

%commented out for this example, I am using only named lists to keep consistency to reduce confusion
%\newcommand{\unnamedsuperweaponhelper}{%this formats the table to exclude names
%    \renewcommand{\mylines}{
%       \forloop{mycount}{1}{\value{mycount} < \weaponcount}{
%        %\iftocolor\rowcolor{mycellcolor}\else\fi      my logic on tocolor is not done, but the point remains
%            \themycount \range(\value{mycount})&\shots(\value{mycount})&\damage(\value{mycount})&\type(\value{mycount})\\
%       }
%    }
%
%    %Table settings for un-named entrys, D D D T
%    \newcolumntype{D}{>{\hsize=0.233333\linewidth \centering\arraybackslash}X}%
%    \newcolumntype{T}{>{\hsize=0.3\linewidth \raggedright\arraybackslash}X}%
%
%       \setlength{\tabcolsep}{0pt}
%    \renewcommand{\arraystretch}{1.2}
%    %construct table using only provided entries
%   \begin{tabularx}{0.47\textwidth}{ D D D T }
%       \textbf{Range} & \textbf{Shots} & \textbf{Damage} & \textbf{Type} \\
%        \hline%---------------------------------------------------------------
%       \mylines
%    \end{tabularx}
%   \renewcommand\mylines{}
%}

\newcommand{\namedsuperweaponhelpertypeone}{%this formats the table to include names type 1 (loop construction)
\renewcommand{\mylines}{
\forloop{mycount}{1}{\value{mycount} < \weaponcount}{
%\iftocolor\rowcolor{mycellcolor}\else\fi       my logic on tocolor is not done, but the point remains
\themycount \weaponname(\value{mycount})&\range(\value{mycount})&\shots(\value{mycount})&\damage(\value{mycount})&\type(\value{mycount})\\
}
}

%Table settings for named entrys, N C C C T
\newcolumntype{N}{>{\hsize=0.4\linewidth \raggedright\arraybackslash}X}%
\newcolumntype{C}{>{\hsize=0.15\linewidth \centering\arraybackslash}X}%
\newcolumntype{T}{>{\hsize=0.3\linewidth \raggedright\arraybackslash}X}%

\setlength{\tabcolsep}{0pt}
\renewcommand{\arraystretch}{1.2}
%construct table using only provided entries
\begin{tabularx}{0.47\textwidth}{ N C C C T }
& \textbf{Range} & \textbf{Shots} & \textbf{Dam} & \textbf{Type} \\
\hline%---------------------------------------------------------------
\mylines
\end{tabularx}
\renewcommand\mylines{}
\weaponcount 1\relax
}
\newcommand{\namedsuperweaponhelpertypetwo}{%this formats the table to include names type 2 (loop concatenation)
\forloop{mycount}{1}{\value{mycount} < \weaponcount}{
\def\halfline{\iftocolor\rowcolor{mycellcolor}\else\fi%             %same thing
\themycount \weaponname(\value{mycount})&\range(\value{mycount})&\shots(\value{mycount})&\damage(\value{mycount})&\type(\value{mycount})\\}
\expandafter\renewcommand\expandafter\mylines\expandafter{\mylines\halfline}
}

%Table settings for named entrys, N C C C T
\newcolumntype{N}{>{\hsize=0.4\linewidth \raggedright\arraybackslash}X}%
\newcolumntype{C}{>{\hsize=0.15\linewidth \centering\arraybackslash}X}%
\newcolumntype{T}{>{\hsize=0.3\linewidth \raggedright\arraybackslash}X}%

\setlength{\tabcolsep}{0pt}
\renewcommand{\arraystretch}{1.2}
%construct table using only provided entries
\begin{tabularx}{0.47\textwidth}{ N C C C T }
& \textbf{Range} & \textbf{Shots} & \textbf{Dam} & \textbf{Type} \\
\hline%---------------------------------------------------------------
\mylines
\end{tabularx}
\renewcommand\mylines{}
\weaponcount 1\relax
}

\newcommand{\EXAMPLEnamedsuperweaponhelper}{%this produces the proper output manually

%Table settings for named entrys, N C C C T
\newcolumntype{N}{>{\hsize=0.4\linewidth \raggedright\arraybackslash}X}%
\newcolumntype{C}{>{\hsize=0.15\linewidth \centering\arraybackslash}X}%
\newcolumntype{T}{>{\hsize=0.3\linewidth \raggedright\arraybackslash}X}%

\setlength{\tabcolsep}{0pt}
\renewcommand{\arraystretch}{1.2}
%construct table using only provided entries
\begin{tabularx}{0.47\textwidth}{ N C C C T }
& \textbf{Range} & \textbf{Shots} & \textbf{Dam} & \textbf{Type} \\
\hline%---------------------------------------------------------------
\weaponname(1)&\range(1)&\shots(1)&\damage(1)&\type(1)\\
\rowcolor{mycellcolor}\weaponname(2)&\range(2)&\shots(2)&\damage(2)&\type(2)\\
\weaponname(3)&\range(3)&\shots(3)&\damage(3)&\type(3)\\
\rowcolor{mycellcolor}\weaponname(4)&\range(4)&\shots(4)&\damage(4)&\type(4)\\
\rowcolor{mycellcolor}\weaponname(5)&\range(5)&\shots(5)&\damage(5)&\type(5)\\
\rowcolor{mycellcolor}\weaponname(6)&\range(6)&\shots(6)&\damage(6)&\type(6)\\
\weaponname(7)&\range(7)&\shots(7)&\damage(7)&\type(7)\\

\end{tabularx}
\renewcommand\mylines{}
\weaponcount 1\relax
}

\newcommand{\clearvariables}{%clears used variables
\emptymacro{}
}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\clearvariables{}%LEAVE AT BOTTOM!


And the main.tex file

\documentclass{myclass}

\begin{document}

Here is method one

\weapon{browning}{30}{5}{4}{Machine-gun}
\weapon{colt 1911}{10}{2}{4}{Pistol}
\weapon{M16}{20}{3}{4}{Rifle}
\weapon{Winchester}{}{}{}{}
\weapon{\rule{2em}{0in}solid slug}{16}{2}{5}{Shotgun}
\weapon{\rule{2em}{0in}buck shot}{14}{2}{6}{Shotgun}
\weapon{Desert Eagle}{12}{1}{5}{Pistol}

\makesuperweapon\namedsuperweaponhelpertypeone%normaly this would all be combined, I separated them for this example

Here is method two

\weapon{browning}{30}{5}{4}{Machine-gun}
\weapon{colt 1911}{10}{2}{4}{Pistol}
\weapon{M16}{20}{3}{4}{Rifle}
\weapon{Winchester}{}{}{}{}
\weapon{\rule{2em}{0in}solid slug}{16}{2}{5}{Shotgun}
\weapon{\rule{2em}{0in}buck shot}{14}{2}{6}{Shotgun}
\weapon{Desert Eagle}{12}{1}{5}{Pistol}

\makesuperweapon\namedsuperweaponhelpertypetwo%normaly this would all be combined, I separated them for this example

Here is my manual example

\EXAMPLEnamedsuperweaponhelper

\end{document}


• Can anyone at least recommend some other solution? – Bob Jan 18 '16 at 17:40

Please refer to the MEW instructions to have a consistent one.

This is an expl3 based solution. To switch the rowcolor, the compiler should be informed if the new insertion is (or not) a weapon subtype. In such case, it have to hold on the previous rowcolor. Otherwise, it switches it. The compiler is informed about subtypes via \weapon*.

\documentclass{article}

\usepackage[table]{xcolor}
\usepackage{xparse}

\definecolor{mycellcolor}{rgb}{0.88,1,1}

\ExplSyntaxOn
% a weapon list
\seq_new:N \g_weapon_seq
\int_new:N \g_colorstate_int            % 1 = white, !1 = mycellcolor
\int_set:Nn {\g_colorstate_int} {-1}    % initially white
\tl_new:N \l_temp_tl

\NewDocumentCommand{\weapon}{smmmmm}
{% #1 = star (case of weapon subtype)
% #2 = weaponname, #3 = range, #4 = shots, #5 = damage, #6 = type
\bool_if:NTF #1
{
\int_set:Nn {\g_colorstate_int} {\g_colorstate_int}
}{
\int_set:Nn {\g_colorstate_int} {-1*\g_colorstate_int}
}
\int_compare:nTF {\g_colorstate_int=1}
{
\seq_put_right:Nn  \g_weapon_seq {1#2&#3&#4&#5&#6}
}{
\seq_put_right:Nn  \g_weapon_seq {0#2&#3&#4&#5&#6}
}
}

% build the table
\NewDocumentCommand{\makesuperweapon}{}
{
\make_super_weapon:n {}
}
\cs_new_protected:Nn \make_super_weapon:n
{
\tl_new:N \l_tablebody_tl

% the table preamble
\tl_set:Nn \l_tablebody_tl
{
\begin{tabular}{lcccc}
& \textbf{Range} & \textbf{Shots}& \textbf{Dam}& \textbf{Type}\\
\hline
}

\seq_map_inline:Nn {\g_weapon_seq}
{
\tl_clear_new:N \l_temp_tl
\tl_set:Nn \l_temp_tl {##1}
{
\tl_put_right:Nn \l_tablebody_tl
{
\tl_tail:N ##1 \\ \hline
}
}{
\tl_put_right:Nn \l_tablebody_tl
{
\rowcolor{mycellcolor} \tl_tail:N ##1 \\ \hline
}
}
}

% end of the table
\tl_put_right:Nn \l_tablebody_tl { \end{tabular} }
% print the table
\tl_use:N \l_tablebody_tl
}
\ExplSyntaxOff

\begin{document}
\weapon{browning}{30}{5}{4}{Machine-gun}
\weapon{colt 1911}{10}{2}{4}{Pistol}
\weapon{M16}{20}{3}{4}{Rifle}
\weapon{Winchester}{}{}{}{}
\weapon*{\rule{2em}{0in}solid slug}{16}{2}{5}{Shotgun}
\weapon*{\rule{2em}{0in}buck shot}{14}{2}{6}{Shotgun}
\weapon{Desert Eagle}{12}{1}{5}{Pistol}

\makesuperweapon
\end{document}


The output

• May you fix the names? \t_ is not a valid prefix, for instance, and you're using \g_ for variables you manage locally. – egreg Jan 20 '16 at 0:03
• @egreg Thank you for your comment. It is OK for \t. Should I switch \g_ to \l_ ? – ALOUI Jan 20 '16 at 0:20
• Either use global assignments and keep \g_ or change to \l_. I don't think global assignments are necessary here. – egreg Jan 20 '16 at 7:02
• \g_weapon_seq and \g_colorstate_int are accessed in \weapon and \makesuperweapon`, so they have to be global. – ALOUI Jan 20 '16 at 9:02
• Out of curiosity why is it that all the answers to this and similar questions are done in expl3? Is it way easier or simpler somehow? – Bob Jan 21 '16 at 22:20