kbordermatrix.sty 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. \NeedsTeXFormat{LaTeX2e}
  2. \ProvidesPackage{kbordermatrix}[2011/09/21 Bordered matrix with brackets]
  3. % Author: Kim C Border <kcborder@caltech.edu>
  4. % Date: SuperBowl XXXVII (Go Bucs)
  5. % Revised 2003/09/20
  6. % to allow flush right option.
  7. % Revised 2011/09/21
  8. % at urging of Bruno Calfa (CMU)
  9. % to coexist with package arydshln
  10. % by adding \def\@xarraycr ...
  11. % Defines \kbordermatrix along the lines of plain tex's
  12. % \bordermatrix (which is still available in LaTeX).
  13. % In particular, as with \bordermatrix,
  14. % 1. It takes the array as an argument. It does not use \begin{}..\end{}.
  15. % Is this a feature or a bug?
  16. % 2. The first row is spaced a bit further apart from the rest.
  17. % 3. The lower (n-1) by (n-1) block is set off by delimiters.
  18. % 4. There is an invisible bottom row of the same height as the segregated
  19. % top row that adds to the height of the equation.
  20. % Differences from \bordermatrix:
  21. % 1. Square brackets are used in place of parentheses.
  22. % 2. You may use \\ instead of \cr.
  23. % 3. The line heights agree with LaTeX's line heights for the
  24. % array environment, and \arraystretch is respected. This means
  25. % the bottom (n-1) rows align with the rows of an (n-1)-rowed
  26. % \begin{array}..\end{array} (with or without delimiters).
  27. % 4. All columns are centered.
  28. % ** Modified 2003-9-20 to allow flush right option.
  29. % 5. The first column is spaced a bit further apart from the rest.
  30. % Differences from \left\[\begin{array}...\end{array}\right\]
  31. % 1. It takes the array as an argument. It does not use \begin{}..\end{}.
  32. % Is this a feature or a bug?
  33. % 2. Consequently, you cannot use a column specifier (e.g., {l|cr}).
  34. % 3. Consequently the maximum number of columns is not specified.
  35. % 4. Vertical rules must be put in each row in a separate column.
  36. % 5. You can use \hline and \cline.
  37. % At least it works in the cases I have tried, but I offer no guarantees.
  38. % cf. \bordermatrix p. 361, and \vrulealign p. 392 of The TeXbook
  39. % Style parameters, they may be redefined according to taste.
  40. \newcommand{\kbldelim}{[} % Left delimiter
  41. \newcommand{\kbrdelim}{]}% Right delimiter
  42. \newcommand{\kbrowstyle}{\scriptstyle}% Style applied to first row
  43. \newcommand{\kbcolstyle}{\scriptstyle}% Style applied to first column
  44. \newlength{\kbcolsep} % Extra separation after first border column
  45. \newlength{\kbrowsep} % Extra separation after first border row
  46. \setlength{\kbcolsep}{.5\arraycolsep}
  47. \setlength{\kbrowsep}{.2ex}
  48. \newif\ifkbalignright
  49. % Scratch lengths (to be computed)
  50. \newlength{\br@kwd} % Width of delimiter
  51. \newlength{\k@bordht} % Height of border column
  52. % This is it
  53. \newcommand{\kbordermatrix}[1]{%
  54. \begingroup
  55. % \br@kwd depends on font size, so compute it now.
  56. \setbox0=\hbox{$\left\kbldelim\right.$}
  57. \setlength{\br@kwd}{\wd0}
  58. % Compute the array strut based on current value of \arraystretch.
  59. \setbox\@arstrutbox\hbox{\vrule
  60. \@height\arraystretch\ht\strutbox
  61. \@depth\arraystretch\dp\strutbox
  62. \@width\z@}
  63. % Compute height of first row and extra space.
  64. \setlength{\k@bordht}{\kbrowsep}
  65. \addtolength{\k@bordht}{\ht\@arstrutbox}
  66. \addtolength{\k@bordht}{\dp\@arstrutbox}
  67. % turn off mathsurround
  68. \m@th
  69. % Set the first row style
  70. \def\@kbrowstyle{\kbrowstyle}
  71. % Swallow the alignment into box0:
  72. \setbox0=\vbox{%
  73. % Define \cr for first row to include the \kbrowsep
  74. % and to reset the row style
  75. \def\cr{\crcr\noalign{\kern\kbrowsep
  76. \global\let\cr=\endline
  77. \global\let\@kbrowstyle=\relax}}
  78. % Redefine \\ a la LaTeX:
  79. \let\\\@arraycr
  80. % The following are needed to make a solid \vrule with no gaps
  81. % between the lines.
  82. \lineskip\z@skip
  83. \baselineskip\z@skip
  84. % Compute the length of the skip after the first column
  85. \dimen0\kbcolsep \advance\dimen0\br@kwd
  86. % Here begins the alignment:
  87. \ialign{\tabskip\dimen0 % This space will show up after the first column
  88. \kern\arraycolsep\hfil\@arstrut$\kbcolstyle ##$\hfil\kern\arraycolsep&
  89. \tabskip\z@skip % Cancel extra space for other columns
  90. \kern\arraycolsep\hfil$\@kbrowstyle ##$\ifkbalignright\relax\else\hfil\fi\kern\arraycolsep&&
  91. \kern\arraycolsep\hfil$\@kbrowstyle ##$\ifkbalignright\relax\else\hfil\fi\kern\arraycolsep\crcr
  92. % That ends the template.
  93. % Here is the argument:
  94. #1\crcr}% End \ialign
  95. }% End \setbox0.
  96. % \box0 now holds the array.
  97. %
  98. % This next line uses \box2 to hold a throwaway
  99. % copy of \box0, leaving \box0 intact,
  100. % while putting the last row in \box5.
  101. \setbox2=\vbox{\unvcopy0 \global\setbox5=\lastbox}
  102. % We want the width of the first column,
  103. % so we lop off columns until there is only one left.
  104. % It's not elegant or efficient, but at 1 gHz, who cares.
  105. \loop
  106. \setbox2=\hbox{\unhbox5 \unskip \global\setbox3=\lastbox}
  107. \ifhbox3
  108. \global\setbox5=\box2
  109. \global\setbox1=\box3
  110. \repeat
  111. % \box1 now holds the first column of last row.
  112. %
  113. % This next line stores the alignment in \box2,
  114. % while calculating the proper
  115. % delimiter height and placement.
  116. \setbox2=\hbox{$\kern\wd1\kern\kbcolsep\kern-\arraycolsep
  117. \left\kbldelim
  118. \kern-\wd1\kern-\kbcolsep\kern-\br@kwd
  119. %
  120. % Here is the output. The \vcenter aligns the array with the "math axis."
  121. % The negative vertical \kern only shrinks the delimiter's height.
  122. % BTW, I didn't find this in the TeXbook,
  123. % I had to try various \kerns to see what they did in a
  124. % \left[\vcenter{}\right].
  125. \vcenter{\kern-\k@bordht\vbox{\unvbox0}}
  126. \right\kbrdelim$}
  127. \null\vbox{\kern\k@bordht\box2}
  128. %
  129. \endgroup
  130. }