[Tex/LaTex] Create table with automatic row numbering

luatexpgfplotstabletables

I am trying to create a table with subheading and automatic row numbers. The original table looks like this:
Table image
The latex to generate the table is as follows:

\documentclass{article}
\usepackage{amssymb}

\usepackage{unicode-math}
\setmainfont[Mapping=tex-text, Numbers=OldStyle]{TeX Gyre Pagella}
\setmathfont[math-style=ISO]{TeX Gyre Pagella Math}

\usepackage{siunitx}
\usepackage{xcolor}
\usepackage{booktabs,colortbl, array}
\usepackage{pgfplotstable}
\pgfplotsset{compat=1.8}

\definecolor{rulecolor}{RGB}{0,71,171}
\definecolor{tableheadcolor}{gray}{0.92}
% Following is taken from Werner: http://tex.stackexchange.com/a/33761/3061
% and modified for my needs
%
% Command \topline consists of a (slightly modified)
% \toprule followed by a \heavyrule rule of colour tableheadcolor
% (hence, 2 separate rules)
\newcommand{\topline}{ %
        \arrayrulecolor{rulecolor}\specialrule{0.1em}{\abovetopsep}{0pt}%
        \arrayrulecolor{tableheadcolor}\specialrule{\belowrulesep}{0pt}{0pt}%
        \arrayrulecolor{rulecolor}}
% Command \midline consists of 3 rules (top colour tableheadcolor, middle colour black, bottom colour white)
\newcommand{\midtopline}{ %
        \arrayrulecolor{tableheadcolor}\specialrule{\aboverulesep}{0pt}{0pt}%
        \arrayrulecolor{rulecolor}\specialrule{\lightrulewidth}{0pt}{0pt}%
        \arrayrulecolor{white}\specialrule{\belowrulesep}{0pt}{0pt}%
        \arrayrulecolor{rulecolor}}
% Command \bottomline consists of 2 rules (top colour
\newcommand{\bottomline}{ %
        \arrayrulecolor{white}\specialrule{\aboverulesep}{0pt}{0pt}%
        \arrayrulecolor{rulecolor} %
        \specialrule{\heavyrulewidth}{0pt}{\belowbottomsep}}%


\newcommand{\midheader}[2]{%
        \midrule\topmidheader{#1}{#2}}
\newcommand\topmidheader[2]{\multicolumn{#1}{l}{\textbf{\textsc{#2}}} \\%
                \addlinespace[0.5ex]}




\newcommand{\ticks}{\makebox[0pt][l]{$\square$}\raisebox{.15ex}{\hspace{0.1em}}}


\pgfplotstableset{create on use/new/.style={
    create col/expr={\pgfplotstablerow+1},
    fixed,precision=0,
    }
}

\pgfplotstableset{normal/.style ={%
        header=true,
        string type,
        font=\addfontfeature{Numbers={Monospaced}}\small,
        column type=l,
        every odd row/.style={
            before row=
        },
        every head row/.style={
            before row={\topline\rowcolor{tableheadcolor}},
            after row={\midtopline}
        },
        every last row/.style={
            after row=\bottomline
        }
    }
}

\begin{document}

 \begin{table}
\pgfplotstabletypeset[normal,
    col sep=&,
    row sep=\\,
%columns={new,Question,Check,Comments},
%columns/new/.style={column type= {p {2cm} }},
    columns/Question/.style={column type= {p {7cm} }},
    columns/Check/.style={column type=c},
    columns/Comments/.style={column type={p{4cm}}},
]{ %
    Question  & Check & Comments  \\
        \topmidheader{3}{Heading}
    This is row one       & \ticks &  \\   
    This is another row & \ticks & \\
        \midheader{3}{Heading}
   This is another row & \ticks & \\   
    This is another row & \ticks & \\
    This is another row & \ticks & \\
        \midheader{3}{Heading}
   This is another row & \ticks &\\ 
  This is another row & \ticks & \\
        \midheader{3}{Heading}
   This is another row & \ticks & \\
   This is another row & \ticks & \\
   This is another row & \ticks & \\
}
\end{table}


\end{document}

What I want to be able to do is insert a column in front of the Question column, which add the row number but does not count the 'heading' rows for the number count. For example, the last row of the second sub section would be 5 i.e. 2 rows in the first sub section and three rows in the second sub section.

I have created a new column with the command:

   \pgfplotstableset{create on use/new/.style={
        create col/expr={\pgfplotstablerow+1},
        fixed,precision=0,
        }
    }

and then use the columns={new,Question,Check,Comments} within the pgfplotstablestypeset to show the new columns but this results in the following error:Misplaced \noalign.

Can anyone shed any light on what I am doing wrong.

Best Answer

I'm not sure where you want the row numbers to appear. There may be an approach native to pgfplotstable.

One approach would be to manual insert a command at the beginning of each row for which you want such numbers. Alternatively, you could somewhat automate the process of building the table using the following code:

Row numbers in a \makebox of zero width

I put your preamble in its own file which I called original_preamble.tex and placed it in its own directory lib. You'll want to change that. Otherwise, here's a complete solution with an additional keyword row that gives you finer control over how and what is placed in each row.

\documentclass{article}
\input{lib/original_preamble}                      
%% the code here relies on `etoolbox`              
\RequirePackage{etoolbox}                          
%% you don't necessarily need `bbding`, I just     
%% use it because I like the CheckMark it provides.
\RequirePackage{bbding}

\makeatletter
\pgfkeys{/ae/question/table/.cd,
  top header/.code=\ae@question@table@header{topmid}{#1},
  mid header/.code=\ae@question@table@header{mid}{#1},
  row/.code=\ae@question@row@parser{#1},%% new key to better handle formatting of rows
  question/.code=\ae@question@question@list{#1},
}

%% user interface
\newcommand\aequestiontable[1]{%%
  \setcounter{ae@question@row@cnt}{0}%%
  \edef\ae@question@table{ Question  & Check & Comments \noexpand\\}%%
  \pgfkeys{/ae/question/table/.cd,#1}%%
  \ae@question@create@table
}

%% macro to handle formatting of the headers
\def\ae@question@table@header#1#2{%%
  \edef\ae@question@table{%%
    \expandonce\ae@question@table
    \expandafter\noexpand\csname#1header\endcsname{3}{#2}}}

%% macro to handle parsing of the list of questions
%% passed through the `question` keyword
\def\ae@question@question@list#1{%%
  \let\ae@list\relax
  \foreach \myq in {#1}
  {%%
    \edef\myquestion{\noexpand\ae@question@cnt\expandonce\myq\space & \noexpand\ticks\space & \noexpand\\\space}%%
    \ifx\ae@list\relax
      \xdef\ae@list{\expandonce\myquestion}%%
    \else
      \xdef\ae@list{\expandonce\ae@list\expandonce\myquestion}%%
    \fi
  }%%
  \edef\ae@question@table{\expandonce\ae@question@table\expandonce\ae@list}}

%% counter for the row
\newcounter{ae@question@row@cnt}
%% macro to execute the row counter
\def\ae@question@cnt{\makebox[0pt][r]{\stepcounter{ae@question@row@cnt}\arabic{ae@question@row@cnt}\hspace{0.5em}}}

%% macro for building the entire table         
%% this should be the last macro called by  the
%% user interface macro `\aequestiontable`.    
\def\ae@question@create@table{%%
  \edef\ae@question@table{%%
    \noexpand\pgfplotstabletypeset[normal,
           col sep=&,
           row sep=\noexpand\\,
           columns/Question/.style={column type= {p {7cm} }},
           columns/Check/.style={column type=c},
           columns/Comments/.style={column type={p{4cm}}},
       ]{\expandonce\ae@question@table}}%%
  \ae@question@table
  }

%-#-{a}------------------------------------------------------------------------------------
%% new code to accommodate further requests
%% I rewrote your code for the `\ticks`.  Your use of 
%% \raisebox was a bit unusual and didn't accomplish anything
\newcommand{\ticks}{\makebox[0pt][l]{$\square$}}
%% New code for the boxed that has been checked off
\newcommand{\checktick}{\makebox[0pt][l]{$\square$\hspace{-0.70em}\raisebox{0.25ex}[0pt][0pt]{\Checkmark}}}

%% keys to be activated within the
%% keyword `row`
\def\ae@question@row@question{}
\def\ae@question@row@comment{}
\pgfkeys{/ae/question/table/row/.cd,
  question/.store in=\ae@question@row@question,
  check/.code={\booltrue{ae@question@check@box@bool}},
  comment/.store in=\ae@question@row@comment,
}

%% boolean to test whether this row should be ticked off or not.
%% default is set to FALSE
\newbool{ae@question@check@box@bool}
\boolfalse{ae@question@check@box@bool}

%% macro to handle parsing the row via a call to
%% the keyword `row`.  The use of \begingroup and
%% \endgroup here keep settings from leaking from
%% one row to the next.
\def\ae@question@row@parser#1{%%
  \begingroup
    \pgfkeys{/ae/question/table/row/.cd,#1}%%
    \ifbool{ae@question@check@box@bool}
      {\let\ae@question@row@tick@box\checktick}%%
      {\let\ae@question@row@tick@box\ticks}%%
    \xdef\ae@list{%%
      \noexpand\ae@question@cnt            
      \expandonce\ae@question@row@question\space &
      \expandonce\ae@question@row@tick@box\space &
      \noexpand\ae@question@row@comment@formatting{\expandonce\ae@question@row@comment}\space   
      \noexpand\\\space}%%
  \endgroup
  \edef\ae@question@table{\expandonce\ae@question@table\expandonce\ae@list}%%
}

%% macro to handle the formatting for the comments
\def\ae@question@row@comment@formatting#1{%%
  \textcolor{red}{#1}}

%% end of new code
%-#-{a}------------------------------------------------------------------------------------

\makeatother

\begin{document}

\begin{table}
  \aequestiontable{%%
    top header=Heading,
    question={this is row one, This is row two},
    row={
      question={How am I doing?},
      check,
      comment={I'm doing quite well},
    },
    row={
      question={How is the other guy doing?},
      },
    mid header=Heading,
    question={This is row three,This is row four,This is row five}}
\end{table}

\end{document}

enter image description here

Row numbers in their own column

There are five changes to the code above. At the end of each line which I've modified I added the comment

%%<--- <:CHANGE:> <num> 

to you easily identify the changes and compare with the original above

Same details that applied to your original preamble also apply here

\documentclass{article}
\input{lib/original_preamble}                      
%% the code here relies on `etoolbox`              
\RequirePackage{etoolbox}                          
%% you don't necessarily need `bbding`, I just     
%% use it because I like the CheckMark it provides.
\RequirePackage{bbding}

\makeatletter
\pgfkeys{/ae/question/table/.cd,
  top header/.code=\ae@question@table@header{topmid}{#1},
  mid header/.code=\ae@question@table@header{mid}{#1},
  row/.code=\ae@question@row@parser{#1},%% new key to better handle formatting of rows
  question/.code=\ae@question@question@list{#1},
}

%% user interface
\newcommand\aequestiontable[1]{%%
  \setcounter{ae@question@row@cnt}{0}%%
  \edef\ae@question@table{ { } & Question  & Check & Comments \noexpand\\}%%<--- <:CHANGE:> 1
  \pgfkeys{/ae/question/table/.cd,#1}%%
  \ae@question@create@table
}

%% macro to handle formatting of the headers
\def\ae@question@table@header#1#2{%%
  \edef\ae@question@table{%%
    \expandonce\ae@question@table
    \expandafter\noexpand\csname#1header\endcsname{3}{#2}}}

%% macro to handle parsing of the list of questions
%% passed through the `question` keyword
\def\ae@question@question@list#1{%%
  \let\ae@list\relax
  \foreach \myq in {#1}
  {%%
    \edef\myquestion{\noexpand\ae@question@cnt\space & \expandonce\myq\space & \noexpand\ticks\space & \noexpand\\\space}%%<-- <:CHANGE:> 2
    \ifx\ae@list\relax
      \xdef\ae@list{\expandonce\myquestion}%%
    \else
      \xdef\ae@list{\expandonce\ae@list\expandonce\myquestion}%%
    \fi
  }%%
  \edef\ae@question@table{\expandonce\ae@question@table\expandonce\ae@list}}

%% counter for the row
\newcounter{ae@question@row@cnt}
%% macro to execute the row counter
%\def\ae@question@cnt{\makebox[0pt][r]{\stepcounter{ae@question@row@cnt}\arabic{ae@question@row@cnt}\hspace{0.5em}}}
\def\ae@question@cnt{\stepcounter{ae@question@row@cnt}\arabic{ae@question@row@cnt}}%%<--- <:CHANGE:> 3

%% macro for building the entire table         
%% this should be the last macro called by  the
%% user interface macro `\aequestiontable`.    
\def\ae@question@create@table{%%
  \edef\ae@question@table{%%
    \noexpand\pgfplotstabletypeset[normal,
           col sep=&,
           row sep=\noexpand\\,
           columns/Counter/.style={c},%%<-- <:CHANGE:> 4
           columns/Question/.style={column type= {p {7cm} }},
           columns/Check/.style={column type=c},
           columns/Comments/.style={column type={p{4cm}}},
       ]{\expandonce\ae@question@table}}%%
  \ae@question@table
  }

%-#-{a}------------------------------------------------------------------------------------
%% new code to accommodate further requests
%% I rewrote your code for the `\ticks`.  Your use of 
%% \raisebox was a bit unusual and didn't accomplish anything
\newcommand{\ticks}{\makebox[0pt][l]{$\square$}}
%% New code for the boxed that has been checked off
\newcommand{\checktick}{\makebox[0pt][l]{$\square$\hspace{-0.70em}\raisebox{0.25ex}[0pt][0pt]{\Checkmark}}}

%% keys to be activated within the
%% keyword `row`
\def\ae@question@row@question{}
\def\ae@question@row@comment{}
\pgfkeys{/ae/question/table/row/.cd,
  question/.store in=\ae@question@row@question,
  check/.code={\booltrue{ae@question@check@box@bool}},
  comment/.store in=\ae@question@row@comment,
}

%% boolean to test whether this row should be ticked off or not.
%% default is set to FALSE
\newbool{ae@question@check@box@bool}
\boolfalse{ae@question@check@box@bool}

%% macro to handle parsing the row via a call to
%% the keyword `row`.  The use of \begingroup and
%% \endgroup here keep settings from leaking from
%% one row to the next.
\def\ae@question@row@parser#1{%%
  \begingroup
    \pgfkeys{/ae/question/table/row/.cd,#1}%%
    \ifbool{ae@question@check@box@bool}
      {\let\ae@question@row@tick@box\checktick}%%
      {\let\ae@question@row@tick@box\ticks}%%
    \xdef\ae@list{%%
      \noexpand\ae@question@cnt\space & %%<--- <:CHANGE:> 5
      \expandonce\ae@question@row@question\space &
      \expandonce\ae@question@row@tick@box\space &
      \noexpand\ae@question@row@comment@formatting{\expandonce\ae@question@row@comment}\space   
      \noexpand\\\space}%%
  \endgroup
  \edef\ae@question@table{\expandonce\ae@question@table\expandonce\ae@list}%%
}

%% macro to handle the formatting for the comments
\def\ae@question@row@comment@formatting#1{%%
  \textcolor{red}{#1}}

%% end of new code
%-#-{a}------------------------------------------------------------------------------------

\makeatother

\begin{document}

\begin{table}
  \aequestiontable{%%
    top header=Heading,
    question={this is row one, This is row two},
    row={
      question={How am I doing?},
      check,
      comment={I'm doing quite well},
    },
    row={
      question={How is the other guy doing?},
      },
    mid header=Heading,
    question={This is row three,This is row four,This is row five}}
\end{table}

\end{document}

enter image description here

A few points about the details of the code

Perhaps the most important feature that I use throughout my solution is the method of keywords provided by pgf. In the pgf/TikZ manual, there's an entire chapter dedicated to working with keys. If you're new to LaTeX, it is probably not that important to understand how to create keys as it is to know how to use them. There are two main advantage to keys: (1) they get around the limitation imposed via TeX that macros can have at most nine arguments; (2) they make your code cleaner and easier to read.

Also from the pgf/TikZ bundle is the \foreach loop which I use in this code too. This is well worth your time to read up on and experiment with. For processes that you can easily iterate over in some fashion, you can often simplify things by creative use of pgf's \foreach.

The second important feature I'm using is controlling how and when the macros are expanded. This is a very important concept that you'll eventually want to master. But as a beginner, it's not likely to be a pressing issue until you begin to write your own macros. The key to controlling expansion here is the judicious use of \expandafter, \noexpand, and \expandonce (this last one comes from the etoolbox package). The best place to read up on expansion is, of course, the TeX Book. But you might also peruse TeX by Topic. This last resource you can access from the command line via

$ texdoc topic

The etoolbox package also provides a fairly nice interface for creating and using booleans. If you have code in which you want to conditionally perform certain actions, etoolbox boolean macros are nice and easy to understand and use.

To read up on etoolbox, from the command line you can enter

$ texdoc etoolbox
Related Question