6

Given a macro that accepts a matrix as an argument

\newcommand{tabler}[1]{\matrix(m)[matrix of nodes, ampersand replacement=\&]{#1};}

I would like to determine the number of columns in matrix m, to be able to iterate over them, starting from the highest column.

Background/Motivation:

Given a list of column widths of size n, and a (* x m) matrix, I want to apply the column widths to the columns of the matrix, starting with column m - n +1.

Visualizing what I'm trying to do:

\tabler{col 1\&col 2\&col 3\&col 4}{3,1,3}
|--col 1--|--col 2--|--col 3––|--col 4––|
          | width 3 | width 1 | width 3 |

Having determined the highest column, I would iterate over the columns, similar to the technique used here, starting from the top, and apply the column styles in reverse order.

Edit for clarification: Effectively, I'm trying to apply the list of column widths to the n right-most columns. I don't know how to directly access the highest column with the tikz style command column x/.stlye which is 1-indexed. Python-style list indexing (where l[-1] returns the last element of list l) would be similarly helpful.

Update: Following @Kevin C's pointer to the \pgf@matrix@numberofcolumns macro, I tried (unsuccessfully) to print the number of columns in the matrix by using the pgfkeys .store in key handler (but don't fully understand the expansion rules to be honest).

Example code:

\documentclass{scrartcl}

\usepackage{xparse, tikz}
\usetikzlibrary{matrix}

\makeatletter
\newcommand\totcol{\pgf@matrix@numberofcolumns}
\makeatother

\pgfkeys{
/tabler/execute macro/.style = {/tabler/save/.expand once=#1},
/tabler/save/.store in=\numcols
}

\NewDocumentCommand\tabler{m}{
    \matrix(m)[/tabler/execute macro={\totcol},
            matrix of nodes,
            ampersand replacement=\&] at (0,0)
    {#1};
    \node at (0,0) {\numcols{}};
}

\begin{document}

\begin{tikzpicture}
\tabler{a \& b\& c \& d \& e\\}
\end{tikzpicture}

\end{document} 

This fails with Undefined control sequence [...] \numcols — what am I missing?

Please let me know if there are better/more elegant ways to accomplish what I've outlined.

10
  • 3
    Are you a mathematician? – percusse Jan 29 '15 at 22:53
  • 1
    @percusse, just to know: why the question? – Sigur Jan 30 '15 at 0:02
  • 2
    Are 'n' and 'n' different? If so, I don't understand at all. If not, might be slightly less confusing not to suggest they are by using different formatting. – cfr Jan 30 '15 at 1:49
  • 4
    @Sigur Every sentence is logically valid and I know all the concepts involved but I still don't understand anything ;) – percusse Jan 30 '15 at 12:28
  • 1
    The way you define \tabler suggests that it takes one argument, but when you use it later, \tabler seems to take two arguments. I don't quite understand what n is. And what is its relation to {3,1,3}? – Herr K. Jan 30 '15 at 22:00
7

PGF has an internal macro that stores the number of columns in a matrix: \pgf@matrix@numberofcolumns. So you can access it by putting, say,

\makeatletter
\newcommand\totcol{\pgf@matrix@numberofcolumns}
\makeatother

in the preamble, and use \totcol to do whatever you need with the styles.

1
  • Thank you. That's very promising — from what I understand, \pgf@matrix@numberofcolumns is only defined during the creation of the matrix — I will try to save it to a macro with the /.store in Key Handler in pgf. – Julian Jan 30 '15 at 22:22
4

The answer by Herr K. is correct. However, here are two more details that may be important to be able to fully appreciate this answer.

  1. \pgf@matrix@numberofcolumns is a count, i.e. the TeX version of a LaTeX counter. This is evident from pgfmodulematrix.code.tex. So to use it you need a \the or something of that sort.
  2. The arguably most convenient way of retrieving it is to use execute at end matrix. This is a pgf key that does not seem to have found its way in the pgfmanual.

\documentclass[tikz,border=3.14mm]{standalone}
\usetikzlibrary{matrix}
\makeatletter
\tikzset{store number of columns in/.style={execute at end matrix={
\xdef#1{\the\pgf@matrix@numberofcolumns}}},
store number of rows in/.style={execute at end matrix={
\xdef#1{\the\pgfmatrixcurrentrow}}}}
\makeatother
\begin{document}
\begin{tikzpicture}
\matrix[matrix of nodes,store number of columns in=\mymatcols,
store number of rows in=\mymatrows] (mat){
a & b & c & d & e\\
a & b & c & d & e\\
a & b & c & d & e\\
};
\draw[latex-latex] ([yshift=1ex]mat.north west) -- ([yshift=1ex]mat.north east)
node[midway,fill=white]{\mymatcols};
\draw[latex-latex] ([xshift=-1ex]mat.north west) -- ([xshift=-1ex]mat.south west)
node[midway,fill=white]{\mymatrows};
\end{tikzpicture}
\end{document}

enter image description here

Since this is related information, I also add a way to retrieve the number of rows.

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.