在我正在处理的文档中,我需要排版大量以下形式的矩阵
\def\x{\mathrm{x}}
\def\X{\mathbf{x}}
\begin{pmatrix}
& \x & \X & \x & \x\\
& & \X & \x & \x\\
& & \X & \x & \x\\
& & \X & & \x\\
& & & & \\
\end{pmatrix}
其中每个条目都是空白、\x 或 \X。我想知道如何最好地定义一个环境,以便我可以编写
\begin{mymatrix}
xXxx\\-Xxx\\-X-x\\-X--\\
\end{mymatrix}
使用活动字符,我可以轻松更改x
、X
和-
在环境中的扩展方式。然而,棘手的是管理它们应该扩展成什么——具体来说,如何管理&
。因为,我们只想&
在下一个标记不是 时扩展\\
。
答案1
\documentclass{article}
\usepackage{amsmath}
\usepackage{xparse}
\ExplSyntaxOn
\tl_new:N \l_freddie_xxmatrix_tl
\seq_new:N \l_freddie_xxmatrix_seq
\NewDocumentCommand{\Xxmatrix}{m}
{
% clear the variable that becomes the body of the matrix
\tl_clear:N \l_freddie_xxmatrix_tl
% split at \\
\seq_set_split:Nnn \l_freddie_xxmatrix_seq { \\ } { #1 }
% insert & between each item
\seq_map_inline:Nn \l_freddie_xxmatrix_seq
{
% split at each item
\seq_set_split:Nnn \l_tmpa_seq { } { ##1 }
% reconstitute the row with &
\tl_put_right:Nx \l_freddie_xxmatrix_tl
{
\seq_use:Nn \l_tmpa_seq { & }
}
% add the row to the body
\tl_put_right:Nn \l_freddie_xxmatrix_tl { \\ }
}
% replace - with nothing, x with \mathrm{x}, X with \mathbf{x}
\tl_replace_all:Nnn \l_freddie_xxmatrix_tl { - } { }
\tl_replace_all:Nnn \l_freddie_xxmatrix_tl { x } { \mathrm{x} }
\tl_replace_all:Nnn \l_freddie_xxmatrix_tl { X } { \mathbf{x} }
% print the matrix
\freddie_printmatrix:V \l_freddie_xxmatrix_tl
}
\cs_new_protected:Nn \freddie_printmatrix:n
{
\begin{pmatrix} #1 \end{pmatrix}
}
\cs_generate_variant:Nn \freddie_printmatrix:n { V }
\ExplSyntaxOff
\begin{document}
\[
\Xxmatrix{
xXxx \\
-Xxx \\
---- \\
-X-x
}
\]
\end{document}
更经典的版本,带有-xX
变成数学活动字符。记住后面的\\
。
\documentclass{article}
\usepackage{amsmath}
\newcommand{\Xxmatrix}[1]{%
\begingroup
\makemathactive{x}{\freddiex}%
\makemathactive{X}{\freddieX}%
\makemathactive{-}{\freddienothing}%
\begin{pmatrix}#1\end{pmatrix}%
\endgroup
}
\mathchardef\standardx=\mathcode`x
\newcommand{\makemathactive}[2]{%
\begingroup\lccode`~=`#1\lowercase{\endgroup\def~}{#2}%
\mathcode`#1="8000
}
\makeatletter
\newcommand{\freddiecheck}{\kernel@ifnextchar\\{}{&}}
\makeatother
\newcommand{\freddiex}{\mathrm{\standardx}\freddiecheck}
\newcommand{\freddieX}{\mathbf{\standardx}\freddiecheck}
\newcommand{\freddienothing}{\freddiecheck}
\begin{document}
\[
\Xxmatrix{
xXxx \\
-Xxx \\
---- \\
-X-x \\
}
\]
\end{document}
答案2
我仍在思考如何解决多余的列...我还使用了Q
andq
而不是X
and x
,因为活动x
会干扰pmatrix
调用。
\documentclass{article}
\usepackage{amsmath}
\def\x{\mathrm{x}}
\def\X{\mathbf{x}}
\begin{document}
\[
\catcode`-=\active
\catcode`Q=\active
\catcode`q=\active
\def-{&}
\def Q{\X&}
\def q{\x&}
\begin{pmatrix}
qQqq\\-Qqq\\-Q-q\\-Q--\\
\end{pmatrix}
\]
\end{document}
以下方法使用负字距来覆盖额外的列。
\documentclass{article}
\usepackage{amsmath}
\def\x{\mathrm{x}}
\def\X{\mathbf{x}}
\def\backup{\kern-9pt}
\begin{document}
\[
\catcode`-=\active
\catcode`Q=\active
\catcode`q=\active
\def-{&}
\def Q{\X&}
\def q{\x&}
\left(
\begin{matrix}
qQqq\\-Qqq\\-Q-q\\-Q--\\
\end{matrix}
\backup\right)
\]
\end{document}