In plain TeX, there is a macro \bordermatrix but I am not very satisfied with it. The problem of that is, the “border” is always at the leftmost and topmost, but not any other combinations. For some unknown reason, I am surprised that no one has any problem with it and no one has ever developed a new package to remediate this problem. Thus I do my own.

Dissection of the legacy bordermatrix macro

The code for legacy \bordermatrix, as from the TeXbook, is below

\newdimen\p@renwd \setbox0=\hbox{\tenex B} \p@renwd=\wd0
\def\bordermatrix#1{\begingroup \m@th
  \setbox2=\vbox{\unvcopy0 \global\setbox1=\lastbox}
  \setbox2=\hbox{\unhbox1 \unskip \global\setbox1=\lastbox}
  \setbox2=\hbox{$\kern\wd1\kern-\p@renwd \left( \kern-\wd1
    \vcenter{\kern-\ht1 \unvbox0 \kern-\baselineskip} \,\right)$}

The code is explained below:

% Define the width of a bracket as \p@renwd
\newdimen\p@renwd \setbox0=\hbox{\tenex B} \p@renwd=\wd0

% Define the macro \bordermatrix
  \m@th % Set the mathsurround stuff
  % Put the matrix into box 0, without brackets
     % Redefine \cr to provide inter-row gap
     % Matrix as an \ialign
        $##$\hfil\kern2pt\kern\p@renwd& % First column: Big space at right
          \thinspace\hfil$##$\hfil&& % Second column: Small space at left
          \quad\hfil$##$\hfil % All other columns: space at left as inter-column gap
          \crcr % End of \ialign template
        \omit\strut\hfil\crcr % Small space to separate matrix from the line above
        #1\crcr % The matrix as provided by the user
        \omit\strut\cr % One empty cell as the last row
  % Determine the first column's width:
  % Firstly, extract box0 for its last box inside, i.e. the last row
  % Then, unbox the last row to find the last (i.e. leftmost) column, save as box 1
  % Afterwards, the width of box 1 is taken as the width of first column
  \setbox2=\vbox{\unvcopy0 \global\setbox1=\lastbox}
  \setbox2=\hbox{\unhbox1 \unskip \global\setbox1=\lastbox}
  % Put the bracket into the matrix, and save the result as an \hbox
  \setbox2=\hbox{$ % Start math mode
     $\kern\wd1\kern-\p@renwd % Shift right the first column's width minus bracket's width
     \left( % Print the left bracket
     \kern-\wd1 % Shift back the first column's width
     \global\setbox1=\vbox{\box1\kern2pt} % Save box 1's height + 2pt
     \vcenter{ % Make a vbox to print the matrix in correct position
        \kern-\ht1 % Shift upward a box 1's height as the topmost row should not inside bracket
        \unvbox0 % Print the matrix
        \kern-\baselineskip % Subtract a row's height from the calculation of the matrix's height
      } % Now this vbox's height is one row shorter then box 0
      \,\right) % Leave a tiny space and print the right bracket
  \null\; % Print some small space
  \vbox{\kern\ht1\box2} % Then the bracketed matrix shifted down one row to avoid
                        % the topmost border not overprinting existing text

Herbert Voss wrote a manual “Math mode” that describes an enhanced \bordermatrix so that we can provide user-specified bracket type and also it provided \bordermatrix* as an derived version that puts the border at rightmost column and bottommost row.

K. Border wrote a \kbordermatrix that allows the border to be in different font style.


My work is a more generic version. It allows any combination of the four sides to be the border.

% qbordermatrix.sty - A more flexible \bordermatrix for LaTeX
% Copyright 2010 (c) Adrian S. Tam <>
% This LaTeX package provides three commands, namely,
%   \bordermatrix - similar to the Knuth's version
%   \bordermatrix* - adapted from the manual "Math mode" by Herbert Voss
%                    that provides the border at bottom and right instead
%   \qbordermatrix - Quadri-border matrix, you can select any combination
%                    of the four borders to put outside of the matrix
% The \qbordermatrix macro takes the syntax of the following
%    \qbordermatrix[#1]{#2}{
%       a11 & a12 & a13 & a14   
%       a21 & a22 & a23 & a24   
%       a31 & a32 & a33 & a34
%    }
% The optional parameter #1 provides two characters as the matrix's left and
% right delimiters. The parameter #2 provides a subset of "n", "s", "e", "w"
% to tell which border should be outside of the matrix. Then the matrix is
% provided in the last curly bracket.
% In this sense, \bordermatrix is same as \qbordermatrix{nw} and
% \bordermatrix* is same as \qbordermatrix{se}. An example is given at
% the bottom of this file.
% Compared to the Knuth's version, the matrices constructed by this package
% has the following properties
%  1. The row height is determined dynamically. Thus if the border row is
%     tall, e.g. a display fraction, the bracket is placed in the correct
%     size.
%  2. The matrix is aligned at the middle of the bracket, regardless the
%     heights of the matrix or the border rows
%  3. Different matrix delimiters are allowed, as long as they can fit into
%     the \left and \right pairs in equations
%  4. The output is in a vbox and the "canva" covers exactly the matrix
% Also the spacing around the matrix is a bit tight.
% Please send your comments and enhancement ideas to
\ProvidesPackage{qbordermatrix}[2010/3/24 qbordermatrix v1.0]
% Support of \bordermatrix and \bordermatrix* as described in "Math mode - v.2.43" by
% Herbert Voss
% Determine if an asterisk is following \bordermatrix, and assert \@borderstar
% If no bracket is provided, use parenthesis
% Construction of the bordermatrix
% More flexible \qbordermatrix macro
% If no bracket is provided, use parenthesis
% Construction of the bordermatrix
  % Parse parameters
  \m@th % mathsurround stuff
  % compute bracket width
  % Define carriage-return for array rows
  \def\cr{\crcr\noalign{\kern\matrixrowsep\global\let\cr\endline}} % for a safer \cr
  % Set box0 to contain the matrix without bracket
    \ialign{ % the matrix
      \hfil$##$\hfil\kern 2\p@\kern\@leftbwd & % first column: big space at right for open bracket
      \thinspace\hfil $##$\hfil && % second column: small space at left
      \quad\hfil $##$\hfil % all other columns: big space at left for column separation
      \crcr % end of preamble
      #3\crcr % the matrix itself
  % Determine the last row height
  % Extract last row from box 0 and measure its height
  % Determine the first row height
  % by removing one row at a time from the content of box 0 (copied to box 3).
  % If, after removing a row, the height of the box is less than 4pt, we rollback
  % one step and that is the first row's height
        \loop% Remove kern, skip, and penalty until we found a box to remove
  \setbox\tw@\vbox{\hrule\copy\@ne\hrule} % use \copy\tw@ for taller height
  % Determine the last column width
  % After above, the first row is stored in box 1 and we extract the last
  % column and meausre its width
  % Determine the first column width
  % The entire first row is stored in box 1 and we do the similar iterations
  % to remove one box at a time from box 1 to find the first column width
  % Put the bracket into the matrix:
  % First right shift for first column's width, and put the opening bracket, then
  % left shift to original position to put the matrix, and then shift left to close
  % the bracket and shift back to right.
  % The matrix, however, is also shifted to reflect the desired height of bracket,
  % Print the result
% Example:
% \documentclass{article}
% \usepackage{qbordermatrix}
% \begin{document}
% \hrule y\vrule$\bordermatrix[\{\}]{%
% 0 &   1 &2^{2^2}& 3 & \displaystyle\frac{4}{2} \cr
% a & x_1 & y_2 & z_1 & t_1 \cr
% b & x_3 & y_4 & z_2 & t_2 \cr
% c & x_5 & y_6 & z_3 & t_3 \cr
% d &   1 &2^{2^2}& 3 & \displaystyle\frac{4}{2} \cr
% }$\vrule z\hrule
% \hrule y\vrule$\bordermatrix*[\{\}]{%
% 0 &   1 &2^{2^2}& 3 & \displaystyle\frac{4}{2} \cr
% a & x_1 & y_2 & z_1 & t_1 \cr
% b & x_3 & y_4 & z_2 & t_2 \cr
% c & x_5 & y_6 & z_3 & t_3 \cr
% d &   1 &2^{2^2}& 3 & \displaystyle\frac{4}{2} \cr
% }$\vrule z \hrule
% \hrule y\vrule$\qbordermatrix[\{\}]{nesw}{%
% 0 &   1 &2^{2^2}& 3 & \displaystyle\frac{4}{2} \cr
% a & x_1 & y_2 & z_1 & t_1 \cr
% b & x_3 & y_4 & z_2 & t_2 \cr
% c & x_5 & y_6 & z_3 & t_3 \cr
% d &   1 &2^{2^2}& 3 & \displaystyle\frac{4}{2} \cr
% }$\vrule z
% \hrule
% \end{document}