2

I'm trying to loop though a comma delimited list and print out the elements in a table. Here is the code that works half-way for doing this:

\documentclass[10pt,a4paper]{article}

% \usepackage[includeheadfoot, margin=1.5cm,headsep=25pt,footskip=25pt,a4paper]{geometry} 
\usepackage[left=1.0cm, right=1.0cm, top=2cm, bottom=3cm, bindingoffset=0cm, showframe=true]{geometry}
\setlength{\headsep}{30pt}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage{marvosym}
%\usepackage{setspace}
\usepackage{array}
\usepackage[english=nohyphenation]{hyphsubst}
\usepackage[english]{babel}
\usepackage{booktabs}
%\setlength{\heavyrulewidth}{2pt}
\usepackage{fancyhdr}
\usepackage{tabularx}
\usepackage{tikz} % for using foreach loops
\usepackage{xspace}
\usepackage{ifthen} % http://texdoc.net/texmf-dist/doc/latex/base/ifthen.pdf

\usepackage[nomessages]{fp} % http://ctan.org/pkg/fp. For doing calculations like add, subtract, divide, etc.
% for moving the tables to the left
\usepackage[strict]{changepage}

%\usepackage{pgfmath,pgfkeys} % https://tex.stackexchange.com/questions/117427/rounding-up-decimal-number-using-latex-3
%\newcommand\RoundingUpFunction[1]{%
%  \pgfmathparse{ceil(#1)}%
%  \pgfmathprintnumber[int trunc]{\pgfmathresult}%
%}
% \RoundingUpFunction{2.7}

\fancyhf{}

%% Top center
\chead{
    This is the header
}
\cfoot{}
\renewcommand{\headrulewidth}{0.4pt}
\pagestyle{fancy}

% This is for the list of skills
\usepackage{forarray}
\newcommand{\nCols}{0} % change this in doc - but first need to define it here in the pre-amble
\newcommand{\nRows}{0}
\newcommand{\skillsList}{0}

% This is for putting ampersands inside conditionals for tables
% https://tex.stackexchange.com/questions/7590/how-to-programmatically-make-tabular-rows-using-whiledo/7594#7594
% https://tex.stackexchange.com/questions/165126/how-do-i-use-the-ampersand-inside-a-foreach-or-conditional-or-other-group-e
\makeatletter
\newtoks\@tabtoks
\newcommand\addtabtoks[1]{\global\@tabtoks\expandafter{\the\@tabtoks#1}}
\newcommand\eaddtabtoks[1]{\edef\mytmp{#1}\expandafter\addtabtoks\expandafter{\mytmp}}
\newcommand*\resettabtoks{\@tabtoks{}}
\newcommand*\printtabtoks{\the\@tabtoks}
\makeatother

\begin{document}
\def\and{&\xspace}
% -------------------------------------------------------- Summary --------------------------------------------------------
\begin{adjustwidth}{-0.02cm}{}
\begin{tabularx}{\textwidth}{@{}>{\raggedright}p{2.2cm}@{}p{16.8cm}@{}}
\textbf{Summary} & This is a summary.
\end{tabularx}
\end{adjustwidth}
% -------------------------------------------------------------------------------------------------------------------------


% -------------------------------------------------------- Skills ---------------------------------------------------------
% list the skills 
\renewcommand{\skillsList}{a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x} % 
\renewcommand{\nCols}{4} % this is the total number of columns for the skills only (need to add one for the label)

% count all the skills to get the number of skills. This will allow calculation of the number of rows.
\newcounter{nSkills}
\ForEachX{,}{\stepcounter{nSkills}}{\skillsList}

% calculate the number of rows as the ceil(number of skills/number of columns)
\FPdiv\nRows\thenSkills\nCols
%\def\zeropfive{0.5}
%\FPadd\nRows\nRows\zeropfive
\FPround\nRows\nRows0
% nRows is \nRows
number of skills: \thenSkills

% Now create the table
%\textbf{IT Skills} & This & here & is filler & a lot of it \\
%\textbf{IT Skills} & 1 & 2 & 3 & 4

\begin{adjustwidth}{-0.02cm}{}
\begin{tabularx}{\textwidth}{@{}>{\raggedright}p{2.2cm}@{}>{\raggedright}X@{}>{\raggedright}X@{}>{\raggedright}X@{}>{\raggedright\arraybackslash}X@{}}
\resettabtoks
\foreach \r in {1,...,\nRows}{  % https://stackoverflow.com/questions/2561791/iteration-in-latex
    \foreach \c in {1,...,\nCols}{
        \ForEachX{,}{ 
            % The number of the element of the list is: \r-(\c-1)*nRows
            \FPsub\factor\c1
            \FPmul\term\factor\nRows
            \FPadd\rowElementToShow\r\term
            \FPtrunc\rowElementToShow\rowElementToShow0

            \ifthenelse{\equal{\the\thislevelcount}{\rowElementToShow}}{
                %\ifthenelse{\the\thislevelcount < \thenSkills}{
                    \addtabtoks{&} \eaddtabtoks{\the\thislevelcount} \addtabtoks{\thislevelitem}  % \addtabtoks{& blah & blah & blah \\ }
                %}{}
            }{}
        }{\skillsList}  
    }
    \addtabtoks{\\}
}
\printtabtoks
\end{tabularx}
\end{adjustwidth}
% -------------------------------------------------------------------------------------------------------------------------


\end{document}

And here is what this code outputs:

PDF output from code above

I would like to have the same output except with the skill beside each number, so 1:a 7:g etc. The variable for this should be \thislevelitem, but this variable in addtabtoks{} gives no output, and in eaddtabtoks{} gives an error, even though \thislevelcount is available. Any thoughts on what I could do to fix this?

Thanks!

2

I don't really know about forarray; here's an implementation that seems to do what you want in a more general way.

With \defineskills{...} you define the set of skills; there's an optional argument for new sets, see the example.

With \numberofskills (possibly with an optional argument) you print the number; finally \tableofskills prints the table.

\documentclass{article}
\usepackage{xparse,array,tabularx}

\ExplSyntaxOn
\NewDocumentCommand{\defineskills}{ O{default} m }
 {
  \shafique_defineskills:nn { #1 } { #2 }
 }

\NewDocumentCommand{\numberofskills}{ O{default} }
 {
  \shafique_numberofskills:n { #1 }
 }

\NewDocumentCommand{\tableofskills}{ O{default} m }
 {
  \shafique_tableofskills:nn { #1 } { #2 }
 }

\seq_new:N \g_shafique_skills_default_seq
\int_new:N \l_shafique_rows_int
\tl_new:N \l_shafique_body_tl
\dim_new:N \l_shafique_numberwd_dim

\cs_new_protected:Npn \shafique_defineskills:nn #1 #2
 {
  \seq_if_exist:cF { g_shafique_skills_#1_seq }
   {
    \seq_new:c { g_shafique_skills_#1_seq }
   }
  \seq_set_from_clist:cn { g_shafique_skills_#1_seq } { #2 }
 }

\cs_new:Npn \shafique_numberofskills:n #1
 {
  \int_to_arabic:n { \seq_count:c { g_shafique_skills_#1_seq } }
 }

\cs_new_protected:Npn \shafique_tableofskills:nn #1 #2
 {
  % compute the number of rows
  \int_compare:nTF
   {
    \int_mod:nn { \seq_count:c { g_shafique_skills_#1_seq } } { #2 } = 0
   }
   {% exact multiple
    \int_set:Nn \l_shafique_rows_int { \seq_count:c { g_shafique_skills_#1_seq } / #2 }
   }
   {% else truncate division and add one
    \int_set:Nn \l_shafique_rows_int
     {
      \int_div_truncate:nn { \seq_count:c { g_shafique_skills_#1_seq } } { #2 } + 1
     }
   }
  \tl_clear:N \l_shafique_body_tl
  \hbox_set:Nn \l_tmpa_box { \int_to_arabic:n { \seq_count:c { g_shafique_skills_#1_seq } } }
  \dim_set:Nn \l_shafique_numberwd_dim { \box_wd:N \l_tmpa_box }
  \int_step_inline:nnnn { 1 } { 1 } { \l_shafique_rows_int }
   {
    \shafique_fill_row:nnn { #1 } { ##1 } { #2 }
   }
  \shafique_print_table:n { #2 }
 }

\cs_new_protected:Npn \shafique_fill_row:nnn #1 #2 #3
 {% #1 is the name of the sequence
  % #2 is the row number
  % #3 is the number of columns
  \int_step_inline:nnnn { 0 } { 1 } { #3 - 1 }
   {
    \tl_put_right:Nx \l_shafique_body_tl
     {
      \int_compare:nF
       {
        #2 + \l_shafique_rows_int * ##1 > \seq_count:c { g_shafique_skills_#1_seq }
       }
       {
        \exp_not:N \makebox[\l_shafique_numberwd_dim][r]
         {
          \int_to_arabic:n { #2 + \l_shafique_rows_int * ##1 }
         }
        : \c_space_tl
        \seq_item:cn { g_shafique_skills_#1_seq } { #2 + \l_shafique_rows_int * ##1 }
       }
      \int_compare:nTF { ##1 = #3 -1 } { \exp_not:N \\ } { & }
     }
   }
 }

\cs_new_protected:Npn \shafique_print_table:n #1
 {
  \par\noindent
  \begin{tabularx}{\textwidth}
   {
    @{} *{#1}{>{\raggedright\arraybackslash}X@{}}
   }
  \tl_use:N \l_shafique_body_tl
  \end{tabularx}
 }

\ExplSyntaxOff

\begin{document}
\defineskills{a,b,c,d,e,f,g}

The number of skills is \numberofskills

\medskip

\tableofskills{4}

\bigskip

\defineskills[new]{a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x}

The number of skills is \numberofskills[new]

\medskip

\tableofskills[new]{4}

\end{document}

enter image description here

I put the skill into a sequence and, for printing the table, I do a double loop, first on rows and then on columns to retrieve the right item.

  • many thanks for this. It works. I would like to customize this (e.g. I would like to add in bold "IT Skills" to the left of the 1 (under Summary) and remove the numbering, leaving only the skills). But I do not at all recognize, from the LaTeX books I have been reading, any of the commands you have used. Can you direct me to some resources I could use to learn how to modify this code (and to write this kind of code myself)? Thanks! – Shafique Jamal Mar 13 '14 at 1:54
  • @ShafiqueJamal This is the programmer interface to the LaTeX3 kernel, which is being developed and is available for usage with LaTeX. – egreg Mar 13 '14 at 8:24

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.