7

I'm using Plain TeX and want to be able to abstract away the preamble of an \halign so that I can just call it with a number of columns in a macro like \customalign, and I want to use a macro to make it more legible. However, this minimal example of using a macro to define the structure of the \halign

\edef\preamb{## & ## \cr}
\halign{ \preamb
first line & second column \cr
}

results in these errors:

! Missing # inserted in alignment preamble.
<to be read again> 
                   &
l.3 first line &
                         second column \cr
? 
! Missing # inserted in alignment preamble.
<to be read again> 
                   \cr 
l.3 first line & second column \cr

? 
 )

Am I doing something incorrectly, or is this just not possible?

2 Answers2

10

Yes, you can: \span, when used in the alignment preamble, expands the next token.

\def\preamb{## & ## \cr}
\halign{\span\preamb
first line & second column \cr
}

\bye

As a rule, tokens before the first \cr are not expanded, unless they're preceded by \span. A different approach, if the preamble is stored in a single macro is

\halign\expandafter{\preamb
first line & second column \cr
}

but \span is more versatile.

egreg
  • 1,121,712
3

You can use \span or \expandafter to expand macros in the preamble but in either case it forces a slightly unnatural call structure when you use the macro.

An alternative is to define an alternative command (myhalign here) that builds in the required preamble. You can avoid pre-scanning the alignment body by using a \let to gobble the { in the source allowing the preamble starting with an unmatched \bgroup to be inserted:

\def\myhalign{\afterassignment\xmyhalign\let\tmp=}
\def\xmyhalign{\halign\bgroup\hfil## & ##\hfil \cr}

\myhalign{
first line & second column \cr
1& 2 \cr
}

\bye

enter image description here

David Carlisle
  • 757,742