2

I'm trying to merge / glue two arrays.

For example:

\documentclass[]{article}
\usepackage{graphics}
\begin{document}
\newcommand{\maybe}[1]{#1}
$\begin{array}{c}a\\b\end{array}\maybe{\begin{array}{c}\scalebox{10}{C}\\d\end{array}}$
\end{document}

This clearly doesn't work: The lines of the two arrays aren't aligned. I'd want it to behave as if it were $\begin{array}{cc}a\maybe{&\scalebox{10}{C}}\\b\maybe{&d}\end{array}}$. But I'd like to avoid having to add \maybe (which is here because I'll use the same code several times and sometimes I won't want to show this part) everywhere.

2

REVISED ANSWER, based on comments with the OP. Since it was desired to modify the vertical spacing of earlier arrays, based on that of later arrays, the only feasible solution is to save the arrays, rather than rendering them, and then choose which ones to merge, at the end.

The logic uses the \definearray{<label>}{<array>} macro to define the component arrays that may or may not make it into the final array. The macro uses the listofitems package to parse the cells of the array into \array<label>[<row>,<col>] indexed data. Once all the arrays are defined, the macro \mergearrays{<comma-separated-label-list>} will combine the data from the arrays in the label list in the appropriate fashion. That appropriate fashion requires a 3-nested loop of <row>-<comma-separated-label-list>-<col> in order to regurgitate the raw tokens in the proper ...&...&...\\... form to be digested by a TABstack.

As one can see in the MWE, the vertical spacing adjusts so as to keep the baseline of each merged row aligned.

Note: done in text mode, but add \stackMath to change that. Stacking gap set (here as 10pt) but can be adjusted to suit. Likewise for intercolumn gap (currently 1ex).

\documentclass[]{article}
\usepackage{graphics}
\usepackage{tabstackengine,listofitems,pgffor}
\newtoks\arraytoks
\newcommand\definearray[2]{\setsepchar{\\/&}%
  \expandafter\readlist\expandafter*\csname array#1\endcsname{#2}}
\newcommand\addtoarray[1]{\global\arraytoks\expandafter{\the\arraytoks#1}}%
\newcommand\mergearrays[1]{%
  \setsepchar{,}%
  \readlist*\arraylist{#1}%
  \arraytoks{}%
  \foreach\Row in{1,...,\expandafter\listlen\csname array\arraylist[1]\endcsname[]}{%
    \ifnum\Row=1\relax\else\addtoarray{\\}\fi
    \foreachitem\Arr\in\arraylist[]{%
      \ifnum\Arrcnt=1\relax\else\addtoarray{&}\fi
      \expandafter\foreachitem\expandafter\Col\expandafter\in%
        \csname array\Arr\endcsname[\Row]{%
        \ifnum\Colcnt=1\relax\else\addtoarray{&}\fi
        \expandafter\addtoarray\expandafter{\Col}%
      }%
    }%
  }%
  \expandafter\tabbedShortstack\expandafter{\the\arraytoks}%
}
\parskip 1em
\setstackgap{S}{10pt}
\setstacktabbedgap{1ex}
\begin{document}
\definearray{A}{a\\b}
\definearray{B}{\scalebox{10}{C}\\d}
\definearray{C}{e & g\\f & \scalebox{5}{H}}
Array A: \fbox{\mergearrays{A}},
\quad
Array B: \fbox{\mergearrays{B}},
\quad
Array C: \fbox{\mergearrays{C}}.\par
Merging A and B: \fbox{\mergearrays{A, B}}\par
Merging A and C: \fbox{\mergearrays{A, C}}\par
Merging B and C: \fbox{\mergearrays{B, C}}\par
Merging C, B and A: \fbox{\mergearrays{C, B, A}}
\end{document}

enter image description here

It works for arbitrary numbers of rows and columns, as long as each array shares the same number of rows. Here is a 3-row example:

\definearray{A}{a\\\scalebox{2}{B}\\c}
\definearray{B}{\scalebox{7}{D}\\e\\f}
\definearray{C}{g & j\\h & \scalebox{4}{K}\\i& l}
Array A: \fbox{\mergearrays{A}},
\quad
Array B: \fbox{\mergearrays{B}},
\quad
Array C: \fbox{\mergearrays{C}}.\par
Merging A and B: \fbox{\mergearrays{A, B}}\par
Merging A and C: \fbox{\mergearrays{A, C}}\par
Merging B and C: \fbox{\mergearrays{B, C}}\par
Merging C, B and A: \fbox{\mergearrays{C, B, A}}

enter image description here

|improve this answer|||||
  • The baseline aligning is good but I'd also want the "cells" to automagically fit the size of the content. If I understand your code correctly, it doesn't and you have to manually specify the height with \setstackgap. – xavierm02 Oct 26 '17 at 10:30
  • @xavierm02 The problem is that the ab array does not and cannot know in advance the layout of Cd and so cannot automagically adjust if they are defined as two separate arrays. Put them in a single TABstack, and then, sure, it can be done. – Steven B. Segletes Oct 26 '17 at 10:52
  • @xavierm02 For example, this will work: \documentclass[]{article} \usepackage{graphics} \usepackage{tabstackengine} \setstackgap{S}{10pt} \stackMath \begin{document} \newcommand{\maybe}[1]{#1} $\tabbedShortstack{a&\scalebox{10}{C}\\b&d}$ $\tabbedShortstack{a&d\\b&\scalebox{10}{C}}$ \end{document} – Steven B. Segletes Oct 26 '17 at 10:55
  • So there's no way to have a magical \glue operation so that \glue{\begin{array}{l}1\\2\end{array}}{\begin{array}{c}3\\4\end{array}} behaves just like \begin{array}{lc}1&3\\2&4\end{array}? – xavierm02 Oct 26 '17 at 11:23
  • @xavierm02 What could be done (might not satisfy your need) is to save the desired contents (i.e., tokens) of individual columns, and then at the end, assemble them. into a matrix/array/stack. – Steven B. Segletes Oct 26 '17 at 14:01

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.