blkarray.sty

D. P. Carlisle

October 4, 2000

Warning !

This style option is in the early stages of development. If you want to use an extended array or tabular in a document, consider using one of the options in the ARRAY package, available from most TEX-servers.

The commands defined in this style are quite likely to have both their user-interface, and their internal definitions changed in later versions.

1 Introduction

This style option implements an environment, blockarray, that may be used in the same way as the array or tabular environments of standard L^{A}TEX, or their extended versions defined in array.sty. If used in math-mode, blockarray acts like array, otherwise it acts like tabular.

The main feature of this style is that it uses a new method of defining column types. In the simplest form, this has been given a syntax matching the

\newcolumntype command of array.sty.
\BAnewcolumntype{C}{>{\large}c}

defines a column of large centred text.

In array.sty column specifiers defined via \newcolumntype are re-written in a preliminary stage to the primitive types, which are then treated by a completely different mechanism (basically a nested \if testing each token against one of the predefined column types, c, l, >, …

In blockarray.sty, all column specifiers have equal standing, most of the specifiers of Lamport’s original are defined using \BAnewcolumntype, e.g.

\BAnewcolumntype{c}   {>{\hfil}<{\hfil}}

There are one or two other features built into blockarray, these will be introduced in no particular order.

1.1 Explicit Column Separators in the Preamble

As described in the L^{A}TEX book, originally specifiers like | and @-expressions were always considered to be part of the preceding column (except for expressions before the first column). This can be inconvenient if that column type is going to be over ridden by a \multicolumn specification, consider:

    \begin{tabular}{c|c|c}
     11 & 22                    & 33 \\
     1  &\multicolumn{1}{l|}{2} &  3 \\
     11 & 22                    & 33
    \end{tabular}

11 22 33 1 2 3 11 22 33

The rule needs to be specified again in the \multicolumn argument as {l|}, blockarray lets you move the rule into the third column, by specifying & in the preamble like so:

    \begin{blockarray}{c|c&|c}
     11 & 22                     & 33 \\
     1  &\BAmulticolumn{1}{l}{2} &  3 \\
     11 & 22                     & 33
    \end{blockarray}

11 22 33 1 2 3 11 22 33

I first came across the idea of having such a feature in an array preamble when Rainer Schöpf gave a brief introduction to various enhanced array styles. An implementation by Denys Duchier had a feature like this, however I have not seen that style so I do not know the details.

1.2 Blocks

Sometimes you want whole blocks of the table to have a different format, this is often the case with headings for instance. This can be accomplished using lots of \multicolumn commands, but this style lets you specify the format for such a block in the usual syntax for column specifiers:

    \begin{blockarray}{*{3}{c}}
     11 & 22 & 33 \\
     1  & 2  &  3 \\
    \begin{block}{*{3}{>{\bf}l}}
     11 & 22 & 33 \\
     1  & 2  & 3  \\
    \end{block}
     1  & 2  &  3
    \end{blockarray}

11 22 33 1 2 3 11 22 33 1 2 3 1 2 3

1.3 Delimiters

People often want to put delimiters around sub-arrays of a larger array, delimiters can now be specified in the preamble argument:

    \begin{blockarray}{[cc]c\}}
     11 & 22  & 33 \\
     1  & 2   &  3 \\
    \begin{block}{(ll)l\}}
     11 & 22 & 33 \\
     1  & 2  & 3  \\
    \end{block}
     1  & 2   &  3
    \end{blockarray}

\begin{matrix}[ & ] & \} & 11 22 33 1 2 3 \\ ( & ) & \} & 11 22 33 1 2 3 \\ [ & ] & \} & 1 2 3 \end{matrix}

Note how in the previous example the nested block was not spanned by the [ ]. each section of the ‘outer’ block was separately bracketed. If instead of the block environment we use block*, then the outer brackets will span the inner block, however it is not possible to specify any delimiters in the argument of block*.

    \begin{blockarray}{[cc]c\}}
     11 & 22  & 33 \\
     1  & 2   &  3 \\
    \begin{block*}{lll}
     11 & 22 & 33 \\
     1  & 2  & 3  \\
    \end{block*}
     1  & 2   &  3
    \end{blockarray}

[  ] \} \begin{matrix}11 & 22 & 33 \\ 1 & 2 & 3 \\ 11 & 22 & 33 \\ 1 & 2 & 3 \\ 1 & 2 & 3 \end{matrix}

The delimiters, ( ) [ ] \{ \} have been pre-defined as column specifiers, however any delimiter, including these ones can be specified using the specifiers

\Left and \Right

\Left{⟨text⟩}{⟨delimiter⟩} specifies a delimiter together with a ‘label’ which will be vertically centred with respect to the block. Note that the delimiter and the label take up no horizontal space, and so extra space must be left with a !- or @-expression or the text will over-print adjacent columns.

1.4 Automatic Numbering

A column specifier \BAenum specifies that the row number is to be printed (in a !-expression) at that point in each row, this number may be accessed with \label in the usual way. The number is a standard L^{A}TEX counter, BAenumi, and so the appearence may be changed by altering the default definition of \theBAenumi.

1.5 Footnotes

The \footnote command may be used inside blockarray. Two styles are supported. If the test BAtablenotes is true (by default, or after \BAtablenotestrue) then footnotes will appear at the end of the table, with lines set to the width of the table. If BAtablenotes is false, footnotes within the table will be treated as standard footnotes, with the text (usually) appearing at the foot of the page.

If table notes are being set, the footnote counter is reset at the start of the table. Also an extended version of \footnotetext can be used. As described in the book, \footnotetext[2]{xxx} will produce a text marked with the footnote symbol for ‘2’. However for tablenotes, the optional argument may also be any non-numeric text, in which case it is set directly at the start of the footnote text. So you can go

\footnotetext[\sc source:]{xxx} or \footnotetext[\sc note:]{xxx} any-

where in the table body, before the first numbered footnote.

If BAtablenotes is false the footnote text will not appear at the foot of the page if the whole blockarray environment is in an environment which treats footnotes in a special way (eg another blockarray). So if you have a complicated table which requires tablenotes, but for TEXnical reasons you wish to enter it in the .tex file as nested blockarray environments, you may set \BAtablenotestrue for the outer environment, and then locally set it to false before each of the nested environments. This will ensure that footnotes from all parts of the table will be collected together at the end.

This table is set with \BAtablenotestrue.

ONE  TWO^{∗}
l-one  l-two
l-three^{∗} l-four

source: Chicago Manual of Style. note: The above attribution is incorrect.

∗ Footnote to l-three.

r-one  r-two
r-three^{∗} r-four

source: Chicago Manual of Style. note: The above attribution is incorrect.

∗ Footnote to r-three

THREE^{†}  FOUR

source: Chicago Manual of Style.

∗ Note on TWO. This is a reasonably long footnote, to show the line breaking. † Note on THREE.

In this example, the outer table is set with \BAtablenotestrue, but each of the inner tables is set with a local setting \BAtablenotesfalse.

Also the footnotes have been set in a single paragraph. Tablenotes will be set ‘run in’ a paragraph, after a \BAparfootnotes declaration.

ONE  TWO^{∗}
l-one  l-two
l-three^{†} l-four

r-one  r-two
r-three^{‡} r-four
THREE^{§}  FOUR

source: Chicago Manual of Style. note: The above attribution is incorrect. ^{∗}Note on TWO. This is a reasonably long footnote, to show the line breaking. †Footnote to l-three. ^{‡}Footnote to r-three ^{§}Note on THREE.

1.6 Non Aligned Material

The primitive \noalign command may be used with standard L^{A}TEX arrays, but paragraphs inside \noalign are broken into lines that are the width of the page, (or at least the current value of \hsize) not to the final width of the table. Within a blockarray \BAnoalign specifies material to be packaged into a parbox the same width as the table. This makes a ‘hole’ in the current block. \BAnoalign* is similar, but any delimiters in the current block span across the non-aligned paragraphs.

\begin{blockarray}{\BAenum!{.\quad}cc\Right{\}}{\tt block 1}}
\BAnoalign*{... The paragraphs ...}
\begin{block}{\BAenum!{.\quad}(rr\Right{\}}{{\tt block 2} ...}}
\begin{block*}{\BAenum!{.\quad}(ll)}
\begin{block}{\BAenum!{.\quad}>{\bf}l\{c\Right{\}}{\tt block 3}}
\BAmultirow{50pt}{... Spanning ...}
\begin{block}{\BAenum!{.\quad}\{l\}l\Right{\}}{\tt block 4}}
\BAnoalign{\centering Unlike  ...}

                    }block 1

1. ccc  cc
2. c ccccccccc

The paragraphs in a

\BAnoalign* are set to the

final width of the table. (

}block 2, with a nested block*

3.  rrr  rr
4.  rrr  r
5. lll  ll
6. l  lll
7.  r  r

}block 1 8. ccc

\begin{matrix}9. LLL \\ 10. LL \\ 11. L \end{matrix} \{ Spanning all the rows in a block. \}block 3
{  }  }block 4 12. ll  l

Unlike \BAnoalign*,
\BAnoalign breaks any

delimiters in the current

block.

{  }  }block 4 13. l  lll

}block 1 14.  c  c

1.7 Spanning Rows and Columns

The previous table had an example of the use of a \BAmultirow command. If an entry contains \BAmultirow{⟨dimen⟩}{⟨par-mode material⟩} then the ⟨par-mode material⟩ will appear in a box at least ⟨dimen⟩ wide, spanning all the rows in the current block. If the other entries in that column of the current block are not empty, they will be over printed by the spanning text.

There is a column specification corresponding to \BAmultirow. if

\BAmultirow{⟨dimen⟩}

appears in the preamble, then each entry in that column will be packaged as a paragraph, in a box at least ⟨dimen⟩ wide, spanning all the rows in the current block. If this is the last column in the block, you can not use the optional argument to \\, and no entry in the column must be empty, it must at least have {} in it. (If you need to ask why, you don’t want to know!)

Similarly there is a column specification corresponding to \BAmulticolumn. if \BAmulticolumn{⟨number⟩}{⟨column specification⟩} appears in the preamble to a block, then the rows in the block should have less entries than the outer block, the columns will line up as expected.

 \begin{blockarray}{r|lccr|c}
 aaa&bbb&ccc&ddd&eee&fff\\
 \begin{block}{(r|\BAmulticolumn{4}{>{\bf}l}|c)}
 111&The second entry in each &333\\
 \end{block}
 a&b&c&d&e&f\\
 \begin{block}{[r|lccr\{\BAmultirow{1in}]}
 111&222&333&444&555&Each entry\\
 1&2&3&4&5&in this column is packaged as a paragraph.\\
 1&2&3&4&5&\relax\\
 \end{block}
 a&b&c&d&e&f
 \end{blockarray}

aaa bbb ccc ddd  eee  fff
a b  c  d  e  f

(

)
111 The second entry in each  333
1 row of this block spans 4  3
1 columns of the blockarray.  3
a b  c  d  e  f
a b  c  d  e  f [ {

Each entry

in this column is packaged as a paragraph.

] 111 222 333 444  555_{1 2  3  4  5}_{1 2  3  4  5}_{1 2  3  4  5}_{1 2  3  4  5}

a b  c  d  e  f

1.8 Horzontal Lines

For technical reasons (explained in the code section) the standard \hline does not work with blockarray. \BAhline may be used in just the same way, although currently it is implemented using… \BAhhline. The \hhline from hhline.sty, would work, but this is a new implementation, more in the spirit of this style.

    \begin{blockarray}{||c||c&|cc||cc||}
    \BAhhline{|t:=:t:=&|==#==:t|}
    0&  1  & 2   &  3 &4&5\\
    \BAhline
    0&  1  & 2   &  3&4&5\\
    \BAhline\BAhline
    0&  1  & 2   &  3&4&5\\
    \BAhhline{||-||-..||.-}
    0&  1  & 2   &  3&4&5\\
    \BAhhline{=::=""::"=}
    0&  1  & 2   &  3&4&5\\
    \BAhhline{|b:=:b:=""::"=:b|}
    \end{blockarray}

0 1 2 3 4 5 0 1 2 3 4 5 0 1 2 3 4 5 0 1 2 3 4 5 0 1 2 3 4 5

Both \hline and \hhline increase the (minimum) height of the following row

by \BAextraheightafterhline, which defaults to 0pt. array.sty introduced a

parameter, known in this style as \BAextrarowheight, which is a length added to the default height of all the rows. One of the stated reasons for introducing this was to stop horizontal lines touching large entries like accented capitals, however increasing all the row heights has an effect rather similar to setting \arraystretch. This style allows the the extra height just to be added after the horizontal rule.

1.9 Further Thoughts

• The main point of any environment based on \halign is to make entries line up. Using this style as currently implemented, it is easy to spoil this alignment by putting different @ expressions or rules in the same column in different blocks. In practice, if you want different @ expressions, you need to do boxing tricks to make sure that they all have the same width. This could be done automatically by the \halign, if the @-expressions and rules were put in a separate column. (This fact could be hidden from the user, by a method similar to the multicolumn column specification).

• The [tcb] optional argument does not really work at present, I have not done a proper implementation, as I do not know what to do about horizontal rules.

Standard L^{A}TEX lines [t] and [b] up like this: xx 1 2 3 xx 1 2 3 xx

However if there are horizontal lines, it looks like: xx 1 2 3 xx 1 2 3 xx

I think I want it to look like this: xx 1 2 3 xx 1 2 3 xx

This would be reasonably easy to achieve in a ‘full’ blockarray, as each row is taken off and inspected, however I would like an array that only uses the features of the original implementation to be processed by the ‘quick’ system. Any ideas?

• Many user-level commands and parameters defined in this style are named \BA… This is to avoid clashes with the standard environments, especially if these are nested inside blockarray. If array and tabular were re-defined in terms of blockarray, many commands could be renamed, for example,

\BAextrarowheight, \BAmulticolumn, \BAhline.

• This style uses a lot of macros, and every use of the blockarray uses a lot more. Does it work at all on a PC?