是否有可能完美地对齐基线p/bNiceMatrix
?(当你有一个大矩阵时,错位是相当明显的......)
平均能量损失
\documentclass{article}
\usepackage{nicematrix}
\begin{document}
\begin{equation}
\rlap{\rule{57mm}{0.11pt}}0 = \begin{NiceMatrix}[baseline=2]
0 & 1 \\
0 & 1 \\
0 & 1 \\
\end{NiceMatrix}\quad
0 = \begin{pNiceMatrix}[baseline=2]
0 & 2 \\
0 & 2 \\
0 & 2 \\
\end{pNiceMatrix}\quad
0 = \begin{bNiceMatrix}[baseline=2]
0 & 3 \\
0 & 3 \\
0 & 3 \\
\end{bNiceMatrix}
\end{equation}
\end{document}
结果
感谢大家的回复。
更新:@Ruixi Zhang 建议的补丁解决了错位问题。
更新 2 (2021-11-26):该补丁似乎有副作用。
测试代码
\usepackage{booktabs}
\usepackage{nicematrix}
...
\begin{table}[h]
\caption{A table}
\centering
\begin{NiceTabular}{ll}[cell-space-limits=3pt]
\toprule
a & b \\
\midrule
\Block{}{new\\line} & c \\
\bottomrule
\end{NiceTabular}
\end{table}
答案1
(2021/11/23)的6.4版本nicematrix
解决了该bug nicematrix
。
这是一个 MWE。
最终,我没有使用 Ruixi Zhang 的 LaTeX 补丁(参见其他答案),因为当在矩阵中的某个地方使用{array}
该命令时似乎会产生后果。\Block
\\
\documentclass{article}
\usepackage{nicematrix}
\begin{document}
\begin{equation}
\rlap{\rule{57mm}{0.11pt}}0 = \begin{NiceMatrix}[baseline=2]
0 & 1 \\
0 & 1 \\
0 & 1 \\
\end{NiceMatrix}\quad
0 = \begin{pNiceMatrix}[baseline=2]
0 & 2 \\
0 & 2 \\
0 & 2 \\
\end{pNiceMatrix}\quad
0 = \begin{bNiceMatrix}[baseline=2]
0 & 3 \\
0 & 3 \\
0 & 3 \\
\end{bNiceMatrix}
\end{equation}
\end{document}
与往常一样nicematrix
,您需要进行多次编译。
答案2
这是一个“双重”错误。第一部分在 LaTeX 内核本身中,第二部分在软件包中nicematrix
。
该错误的第一部分存在于底层
array
环境中(自 LaTeX2.09 以来就一直存在)。我两年前就向 LaTeX 团队报告了这个问题(https://github.com/latex3/latex2e/issues/147)。任何修复将要破坏了向后兼容性,因此修复不太可能在内核中实现。问题在于,每行
array
都有一个“支柱”。该支柱的高度与深度之比为 7:3。但它的高度应为<half baseline> + <math axis>
,深度应为<half baseline> - <math axis>
。在大多数情况下,差异非常小,但仍然明显到足以导致错位。例如,在 Computer Modern Math 中设置了基线间隔
10pt
的文章12pt
应具有 8.5pt 的支柱高度和 3.5pt 的支柱深度。但是 LaTeX 将支柱高度设置为约 8.4pt,将支柱深度设置为约 3.6pt,从而导致微小的 0.1/2=0.05pt 错位。该错误的第二部分是在环境中
NiceArrayWithDelims
。即使我们修复了内核支柱行为,仍然存在 0.4pt 的错位。问题似乎出在 中。似乎缺少 的\vcenter{ \skip_vertical:N -\l_tmpa_dim ... \skip_vertical:N -\l_tmpb_dim }
偏移量。\arrayrulewidth
没有简单的方法来修补 LaTeX3 环境,所以我将直接复制
NiceArrayWithDelims
下面的整个定义。只替换了两行代码。因此,此修复程序是不是需要认真对待。它只是暂时的解决办法。
完整代码:
\documentclass{article}
\usepackage{nicematrix}
% Fix the LaTeX kernel part of the bug
\usepackage{etoolbox}
\makeatletter
\AtBeginDocument{%
% nicematrix loads array.sty
\patchcmd\@array
{\arraystretch \@tempdima}
{\dimexpr\arraystretch\baselineskip/2
+\arraystretch\extrarowheight
+\fontdimen22\textfont\tw@\relax}
{\typeout{Fixed array strut height for array.sty}}
{\typeout{Couldn't patch \string\@array}}%
\patchcmd\@array
{\arraystretch \dp \strutbox}
{\dimexpr\arraystretch\baselineskip
-\arraystretch\baselineskip/2
-\fontdimen22\textfont\tw@\relax}
{\typeout{Fixed array strut depth for array.sty}}
{\typeout{Couldn't patch \string\@array}}%
\let\@@array\@array
}
\makeatother
% `Fix' the package bug.
% Only two lines are replaced!!!
% Not to be taken as a serious fix!!!
\makeatletter
\ExplSyntaxOn
\RenewDocumentEnvironment { NiceArrayWithDelims }
{ m m O { } m ! O { } t \CodeBefore }
{
\bool_if:NT \c__nicematrix_revtex_bool \__nicematrix_patch_for_revtex:
\__nicematrix_provide_pgfsyspdfmark:
\bool_if:NT \c__nicematrix_footnote_bool \savenotes
\bgroup
\tl_gset:Nn \g__nicematrix_left_delim_tl { #1 }
\tl_gset:Nn \g__nicematrix_right_delim_tl { #2 }
\tl_gset:Nn \g__nicematrix_preamble_tl { #4 }
\int_gzero:N \g__nicematrix_block_box_int
\dim_zero:N \g__nicematrix_width_last_col_dim
\dim_zero:N \g__nicematrix_width_first_col_dim
\bool_gset_false:N \g__nicematrix_row_of_col_done_bool
\str_if_empty:NT \g__nicematrix_name_env_str
{ \str_gset:Nn \g__nicematrix_name_env_str { NiceArrayWithDelims } }
\__nicematrix_adapt_S_column:
\bool_if:NTF \l__nicematrix_NiceTabular_bool
\mode_leave_vertical:
\__nicematrix_test_if_math_mode:
\bool_if:NT \l__nicematrix_in_env_bool { \__nicematrix_fatal:n { Yet~in~env } }
\bool_set_true:N \l__nicematrix_in_env_bool
\cs_gset_eq:NN \__nicematrix_old_CT@arc@ \CT@arc@
\cs_if_exist:NT \tikz@library@external@loaded
{
\tikzexternaldisable
\cs_if_exist:NT \ifstandalone
{ \tikzset { external / optimize = false } }
}
\int_gincr:N \g__nicematrix_env_int
\bool_if:NF \l__nicematrix_block_auto_columns_width_bool
{ \dim_gzero_new:N \g__nicematrix_max_cell_width_dim }
\seq_gclear:N \g__nicematrix_blocks_seq
\seq_gclear:N \g__nicematrix_pos_of_blocks_seq
\seq_gclear:N \g__nicematrix_pos_of_stroken_blocks_seq
\seq_gclear:N \g__nicematrix_pos_of_xdots_seq
\tl_gclear_new:N \g__nicematrix_code_before_tl
\tl_gclear:N \g__nicematrix_row_style_tl
\bool_gset_false:N \g__nicematrix_aux_found_bool
\tl_if_exist:cT { c__nicematrix _ \int_use:N \g__nicematrix_env_int _ tl }
{
\bool_gset_true:N \g__nicematrix_aux_found_bool
\use:c { c__nicematrix _ \int_use:N \g__nicematrix_env_int _ tl }
}
\tl_gclear:N \g__nicematrix_aux_tl
\tl_if_empty:NF \g__nicematrix_code_before_tl
{
\bool_set_true:N \l__nicematrix_code_before_bool
\tl_put_right:NV \l__nicematrix_code_before_tl \g__nicematrix_code_before_tl
}
\bool_if:NTF \l__nicematrix_NiceArray_bool
{ \keys_set:nn { NiceMatrix / NiceArray } }
{ \keys_set:nn { NiceMatrix / pNiceArray } }
{ #3 , #5 }
\tl_if_empty:NF \l__nicematrix_rules_color_tl
{ \exp_after:wN \__nicematrix_set_CT@arc@: \l__nicematrix_rules_color_tl \q_stop }
\IfBooleanTF { #6 } \__nicematrix_pre_array_i:w \__nicematrix_pre_array:
}
{
\bool_if:NTF \l__nicematrix_light_syntax_bool
{ \use:c { end __nicematrix-light-syntax } }
{ \use:c { end __nicematrix-normal-syntax } }
\c_math_toggle_token
\skip_horizontal:N \l__nicematrix_right_margin_dim
\skip_horizontal:N \l__nicematrix_extra_right_margin_dim
\hbox_set_end:
\bool_if:NT \l__nicematrix_width_used_bool
{
\int_compare:nNnT \g__nicematrix_total_X_weight_int = 0
{ \__nicematrix_error:n { width~without~X~columns } }
}
\int_compare:nNnT \g__nicematrix_total_X_weight_int > 0
{
\tl_gput_right:Nx \g__nicematrix_aux_tl
{
\bool_set_true:N \l__nicematrix_X_columns_aux_bool
\dim_set:Nn \l__nicematrix_X_columns_dim
{
\dim_compare:nNnTF
{
\dim_abs:n
{ \l__nicematrix_width_dim - \box_wd:N \l__nicematrix_the_array_box }
}
<
{ 0.001 pt }
{ \dim_use:N \l__nicematrix_X_columns_dim }
{
\dim_eval:n
{
( \l__nicematrix_width_dim - \box_wd:N \l__nicematrix_the_array_box )
/ \int_use:N \g__nicematrix_total_X_weight_int
+ \l__nicematrix_X_columns_dim
}
}
}
}
}
\int_compare:nNnT \l__nicematrix_last_row_int > { -2 }
{
\bool_if:NF \l__nicematrix_last_row_without_value_bool
{
\int_compare:nNnF \l__nicematrix_last_row_int = \c@iRow
{
\__nicematrix_error:n { Wrong~last~row }
\int_gset_eq:NN \l__nicematrix_last_row_int \c@iRow
}
}
}
\int_gset_eq:NN \c@jCol \g__nicematrix_col_total_int
\bool_if:nTF \g__nicematrix_last_col_found_bool
{ \int_gdecr:N \c@jCol }
{
\int_compare:nNnT \l__nicematrix_last_col_int > { -1 }
{ \__nicematrix_error:n { last~col~not~used } }
}
\int_gset_eq:NN \g__nicematrix_row_total_int \c@iRow
\int_compare:nNnT \l__nicematrix_last_row_int > { -1 } { \int_gdecr:N \c@iRow }
\int_compare:nNnT \l__nicematrix_first_col_int = 0
{
\skip_horizontal:N \col@sep
\skip_horizontal:N \g__nicematrix_width_first_col_dim
}
\bool_if:NTF \l__nicematrix_NiceArray_bool
{
\str_case:VnF \l__nicematrix_baseline_tl
{
b \__nicematrix_use_arraybox_with_notes_b:
c \__nicematrix_use_arraybox_with_notes_c:
}
\__nicematrix_use_arraybox_with_notes:
}
{
\int_compare:nNnTF \l__nicematrix_first_row_int = 0
{
\dim_set_eq:NN \l_tmpa_dim \g__nicematrix_dp_row_zero_dim
\dim_add:Nn \l_tmpa_dim \g__nicematrix_ht_row_zero_dim
}
{ \dim_zero:N \l_tmpa_dim }
\int_compare:nNnTF \l__nicematrix_last_row_int > { -2 }
{
\dim_set_eq:NN \l_tmpb_dim \g__nicematrix_ht_last_row_dim
\dim_add:Nn \l_tmpb_dim \g__nicematrix_dp_last_row_dim
}
{ \dim_zero:N \l_tmpb_dim }
\hbox_set:Nn \l_tmpa_box
{
\c_math_toggle_token
\tl_if_empty:NF \l__nicematrix_delimiters_color_tl
{ \color { \l__nicematrix_delimiters_color_tl } }
\exp_after:wN \left \g__nicematrix_left_delim_tl
\vcenter
{
% \skip_vertical:N -\l_tmpa_dim
\skip_vertical:n { -\l_tmpa_dim - \arrayrulewidth }
\hbox
{
\bool_if:NTF \l__nicematrix_NiceTabular_bool
{ \skip_horizontal:N -\tabcolsep }
{ \skip_horizontal:N -\arraycolsep }
\__nicematrix_use_arraybox_with_notes_c:
\bool_if:NTF \l__nicematrix_NiceTabular_bool
{ \skip_horizontal:N -\tabcolsep }
{ \skip_horizontal:N -\arraycolsep }
}
% \skip_vertical:N -\l_tmpb_dim
\skip_vertical:n { -\l_tmpb_dim + \arrayrulewidth }
}
\tl_if_empty:NF \l__nicematrix_delimiters_color_tl
{ \color { \l__nicematrix_delimiters_color_tl } }
\exp_after:wN \right \g__nicematrix_right_delim_tl
\c_math_toggle_token
}
\bool_if:NTF \l__nicematrix_delimiters_max_width_bool
{
\__nicematrix_put_box_in_flow_bis:nn
\g__nicematrix_left_delim_tl \g__nicematrix_right_delim_tl
}
\__nicematrix_put_box_in_flow:
}
\bool_if:NT \g__nicematrix_last_col_found_bool
{
\skip_horizontal:N \g__nicematrix_width_last_col_dim
\skip_horizontal:N \col@sep
}
\bool_if:NF \l__nicematrix_Matrix_bool
{
\int_compare:nNnT \c@jCol < \g__nicematrix_static_num_of_col_int
{ \__nicematrix_error:n { columns~not~used } }
}
\group_begin:
\globaldefs = 1
\__nicematrix_msg_redirect_name:nn { columns~not~used } { error }
\group_end:
\__nicematrix_after_array:
\egroup
\iow_now:Nn \@mainaux { \ExplSyntaxOn }
\iow_now:Nn \@mainaux { \char_set_catcode_space:n { 32 } }
\iow_now:Nx \@mainaux
{
\tl_gset:cn { c__nicematrix_ \int_use:N \g__nicematrix_env_int _ tl }
{ \exp_not:V \g__nicematrix_aux_tl }
}
\iow_now:Nn \@mainaux { \ExplSyntaxOff }
\bool_if:NT \c__nicematrix_footnote_bool \endsavenotes
}
\ExplSyntaxOff
\makeatother
\begin{document}
\begin{equation}
\rlap{\rule{57mm}{0.11pt}}0 = \begin{NiceMatrix}[baseline=2]
0 & 1 \\
\rlap{\color{red}\rule{5.7mm}{0.11pt}}0 & 1 \\
0 & 1 \\
\end{NiceMatrix}\quad
0 = \begin{pNiceMatrix}[baseline=2]
0 & 2 \\
\rlap{\color{red}\rule{5.7mm}{0.11pt}}0 & 2 \\
0 & 2 \\
\end{pNiceMatrix}\quad
0 = \begin{bNiceMatrix}[baseline=2]
0 & 3 \\
\rlap{\color{red}\rule{5.7mm}{0.11pt}}0 & 3 \\
0 & 3 \\
\end{bNiceMatrix}
\end{equation}
\end{document}
里面的代码\AtBeginDocument{...}
是从我自己的补丁文件中提取出来的(https://github.com/RuixiZhang42/font-pairing-guide/blob/master/mtpro2-patch.tex),截至撰写本文时为 852–866 行。它仅涵盖array.sty
。更彻底的修复作为从 850 行到 911 行的代码提供。
答案3
这不是一个真正的答案,而只是\patchcmd
修补 LaTeX3 环境(结束)的一种可能方法NiceArrayWithDelims
,以便缩短“完整代码”示例中的相应部分@RuixiZhang 的回答。
\makeatletter
\ExplSyntaxOn
% patch \cs{environment NiceArrayWidthDelims end aux }
\char_set_catcode_space:n {32} % restore catcode of space char
\expandafter\patchcmd
\csname environment~ NiceArrayWithDelims~ end~ aux~ \endcsname
{\skip_vertical:N -\l_tmpa_dim}
{\skip_vertical:n {-\l_tmpa_dim -\arrayrulewidth }}
{}{\fail}
\expandafter\patchcmd
\csname environment~ NiceArrayWithDelims~ end~ aux~ \endcsname
{\skip_vertical:N -\l_tmpb_dim }
{\skip_vertical:n {-\l_tmpb_dim +\arrayrulewidth }}
{}{\fail}
\ExplSyntaxOff
\makeatother