5

I wish to set the maximum column count in a TikZ matrix and, if I start a new cell when the maximum count is reached, LaTeX would put the cell in a new row.

One approach would be a command which checks current column number and determine whether to be replaced by an & or a \\.

Background:

I'm making PDF for printing on an array of self adhesive labels like this: self adhesive labels

When creating my labels, I have to insert \\ instead of & if current row is full, which is not convenient. Sometimes I want to modify my file, i.e. remove an item, and I have to move every subsequent \\ to make line breaks correct.

Update:

The code is posted here to provide more explanation. I want to make every position of an element under my control so I anchored the matrix relative to the edge of paper. If there is no offset induced by printer, the bounding box generated by following code will coincide with pre-cut seam on paper.

    \documentclass[a4paper]{article}
    \usepackage{qrcode}
    \usepackage{tikz}
    \usepackage{hyperref}
    \usepackage{xifthen} % provides \isempty test
    \usepackage{pst-barcode}
    \usetikzlibrary{positioning}

    \pagestyle{empty}

    \newcommand{\Label}[2][]{
        \draw (0cm,0cm) rectangle (3cm,-4cm) node (framesoutheast) {};
        \path (0cm,0cm) -- node[midway,anchor=north,inner sep=0pt,yshift=-4mm] (qrcode) {
            \begin{pspicture}(0.9in,0.9in)
                \psbarcode{https://wiki.thu-skyworks.org/#2}{width=0.9 height=0.9}{qrcode}
            \end{pspicture}
            %\qrcode[2cm]{https://wiki.thu-skyworks.org/#2}
            %\XeTeXinputencoding "utf8"
        }(3cm,0cm);
        \node[anchor=south west,inner sep=1mm,outer sep=0pt] (logo) at (0mm,-40mm) {\includegraphics[width=9mm]{any_square_image}};
        \path (logo.east) -- node[anchor=center,text width=19mm,align=center,font=\sffamily\small]{\ifthenelse{\isempty{#1}}{#2}{#1}}
        (logo.east-|framesoutheast);
    }

    \begin{document}

    \begin{tikzpicture}[remember picture,overlay]
        \matrix[row sep={4cm,between origins}, column sep = {32mm,between origins},matrix anchor=north west,inner sep=0pt,xshift=10mm,yshift=-8mm] at (current page.north west) {
        %\XeTeXinputencoding "byte"
            \Label{Label\ one} & \Label[If need\\manual break]{If\ need\ manual\ break} & \Label{Label\ 3} &
            \Label{Label 4} & \Label{Label 5} & \Label{Label 6} \\ % I want to make this line break auto
            \Label{Label 7} \\
        };
    \end{tikzpicture}

    \end{document}
ReeseWang
  • 103
  • 2
    Why do you put them in a matrix? If you make the pictures the proper size and typeset them normally, the line breaking will do what you want. – Pieter van Oostrum Nov 16 '16 at 10:58
  • Possibly related: http://tex.stackexchange.com/questions/202649/automatically-include-a-sequence-of-images/202657#202657 –  Nov 16 '16 at 12:52
  • @PietvanOostrum because I need to specify distance between rows and columns, and specify their position on the page to mach the seam on the paper. – ReeseWang Nov 16 '16 at 14:11
  • @Andrew using loops seems to be a good idea, will come back after some experiment, thanks! – ReeseWang Nov 16 '16 at 14:16
  • @RuoxiWang But can that not be done by making the size of the figure just right? – Pieter van Oostrum Nov 17 '16 at 00:19
  • @PietvanOostrum I'm afraid it's not reliable. First, it seems that some unknown amount of white space will be added between figures and I don't want to get the spacing correct by trial and error. Second, as the content of labels is generated by LaTeX code via my custom macro, there's a chance that some mistake will make the size of the figure inconsistent. Third, seems that the size of figure will increase by a line thickness if I change the bounding box (a rect path) from not drawn to drawn for debugging purpose. – ReeseWang Nov 17 '16 at 14:54
  • OK, I added a solution with a matrix. – Pieter van Oostrum Nov 17 '16 at 15:56

2 Answers2

7

As an alternative to a TiKZ matrix you can use a tcbraster construction from tcolorbox. You define raster columns value, and list all elements. tcbraster will distribute them and will break lines and pages when needed.

Following code shows how to declare it. Option raster force size=false keeps inner boxes size, otherwise inner raster columns boxes are scaled to fit into one text line.

\documentclass{article}
\usepackage[most]{tcolorbox}
\usepackage[hmargin={1cm,1cm},vmargin={1cm,1cm}]{geometry}
\begin{document}
\begin{tcbraster}[raster columns=6, raster every box/.style={blankest, width=3cm}, raster force size=false]
    \foreach \i in {1,...,20}{%
        \tcbincludegraphics{example-image}
        \tcbincludegraphics{example-image-A}
        \tcbincludegraphics{example-image-B}
        \tcbincludegraphics{example-image-C}
    }
\end{tcbraster}
\end{document}

enter image description here

Ignasi
  • 136,588
4

You can use a counter to count the labels. After each label increment the counter. If the counter is 6 you insert \\ and reset the counter, otherwise insert & (or rather what the definition of & is in a matrix, namely \pgfmatrixnextcell).

\newcounter{colnr}
\setcounter{colnr}{0}
\newcommand{\lb}{%
  \stepcounter{colnr}%
  \ifthenelse{\value{colnr}=6}{\setcounter{colnr}{0}\\}{\pgfmatrixnextcell}%
}

Replace all & and \\ in the matrix with \lb, except the final \\.