1

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] 

\LoadClass[letterpaper, 8pt]{extbook}
\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{array}              %for advanced table commands

\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
\newcommand{\emptymacro}[1]{\renewcommand\@emptymacro{#1}}

%*******************************************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}
    \advance\weaponcount 1\relax
}

\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}

enter image description here

1
  • Can anyone at least recommend some other solution?
    – Bob
    Jan 18, 2016 at 17:40

1 Answer 1

1

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

% add a new weapon
\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
   }

   % add rows
  \seq_map_inline:Nn {\g_weapon_seq}
  {
   \tl_clear_new:N \l_temp_tl
   \tl_set:Nn \l_temp_tl {##1}
   \int_compare:nNnTF{\tl_head:N \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

enter image description here

5
  • 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, 2016 at 0:03
  • @egreg Thank you for your comment. It is OK for \t. Should I switch \g_ to \l_ ?
    – ALOUI
    Jan 20, 2016 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, 2016 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, 2016 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, 2016 at 22:20

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .