테이블의 수직 정렬: m-열, 행 크기 - 마지막 열의 문제

테이블의 수직 정렬: m-열, 행 크기 - 마지막 열의 문제

안타깝게도 나에게 문제가 생겼습니다.m-열( array패키지)조정된 행 높이. 어떻게든에서는마지막 열(그곳에서만) 텍스트는 다음과 같습니다중앙에 있지 않음수직으로.

확인 해봐:

여기에 이미지 설명을 입력하세요

\documentclass{article}
\usepackage{array}

\begin{document}

\begin{tabular}{|m{0.18cm}|m{0.18cm}|m{0.18cm}|}
\hline
a & b & c  \\[2ex]
\hline
0 & 0 & 0  \\
\hline
\end{tabular}

\end{document}

답변1

제 생각에는 이는 버그이므로 보고되어야 합니다. 참을성이 없는 사용자를 위한 조정: 너비가 0이고 패딩이 없는 추가 열을 하나 추가합니다. 문제가 있는 줄을 앞에 추가하는 것을 잊지 \\마세요 &!

\documentclass{article}
\usepackage{array}

\begin{document}

\begin{tabular}{|m{0.18cm}|m{0.18cm}|m{0.18cm}|@{}m{0pt}@{}}
\hline
a & b & c &\\[2ex]
\hline
0 & 0 & 0 \\
\hline
\end{tabular}

\end{document}

답변2

@tohecz의 질문과 답변은 서문 토큰 "m", "b" 등이 수행하는 작업과 이것이 어떻게 관련되는지 \\및 선택적 인수에 대해 최소한 하나의 근본적인 오해가 있음을 나타냅니다.

"m" 토큰아니다사용 가능한 공간에서 재료를 수직으로 중앙에 배치합니다!

토큰 "c", "l" 및 "r"은 수평 셀(한 줄 높이)을 생성하고 수직 정렬 지점은 각 셀의 기준선입니다. 이제 "p", "m" 및 "b"는 특정 너비와 여러 줄의 셀을 생성합니다. 수직 정렬은 각각 첫 번째 줄, 상자 중앙 및 맨 아래 줄입니다. 따라서 예제를 약간 수정하고 실행하면 다음과 같습니다.

\begin{tabular}{|p{0.18cm}|m{0.18cm}|b{0.18cm}|l|}
\hline
a\newline a & b\newline b & c\newline c\newline c& d \\
\hline
\end{tabular}

그리고 우리가 얻는 것은

여기에 이미지 설명을 입력하세요

따라서 이것은 모두 "d"를 포함하는 셀의 기준선을 기준으로 배치됩니다.

이제 선택적 인수는 \\정렬 지점에서 아래쪽으로만 공간을 확장합니다.~ 아니다실제 셀의 크기를 확장합니다. 또한 실제로 이 공간을 추가하는 것이 아니라 다음 행에 최소한 해당 공간이 있는지 확인하는 것뿐입니다. 예를 들어 위의 경우 \\[2ex]첫 번째 열의 셀이 이보다 더 아래로 내려가기 때문에 아무런 효과가 없습니다.

그럼 원래 질문과 그 입력으로 돌아가서: 각 셀에는 한 줄만 있기 때문에 모두 정렬되어야 하지만 "m"은~ 아니다사용 가능한 공간의 중앙에 콘텐츠를 배치하는 효과가 있습니다. 대신 에서 요청한 추가 공간이 \\[2ex]그 뒤에 옵니다(또는 그래야 합니다... 그게 버그입니다).

버그를 방지하고 어떤 일이 발생하는지 확인하기 위해 "l" 열을 추가해 보겠습니다.

\begin{tabular}{|m{0.18cm}|m{0.18cm}|m{0.18cm}|l|}
\hline
a & b & c & d \\[2ex]
\hline
a\newline a & b & c & d \\[2ex]
\hline
\end{tabular}

결과는

여기에 이미지 설명을 입력하세요

첫 번째 행은 "m" 내부에 한 줄만 있고 2ex가 기준선과 다음 행 사이에 있는 경우 "m"과 "l"이 나란히 있음을 보여줍니다.

두 번째 줄에는 내부에 2개의 줄이 있는 "m"이 있으며 거기에서 2ex가 행 기준선에서 다음 행으로 이동하고 "m"도 수직 중앙에 있지 않다는 것을 다시 볼 수 있습니다.

따라서 다음과 같은 추가(숨겨진 행 종류)를 사용하라는 제안은 다음과 같습니다.

\begin{tabular}{|m{0.18cm}|m{0.18cm}|m{0.18cm}|@{}m{0pt}@{}}
\hline
a & b & c &             x\\[4ex]   % x normally being a space
\hline
a\newline a & b & c &   x\\[4ex]
\hline
\end{tabular}

실제로는 현재 버그를 활용하고 있습니다. 즉, 숨겨진 질문의 "공백"이 실제로 위쪽으로 밀려서 보이는 행이 이제 다소 중앙에 표시됩니다(위에 "x"를 넣어 표시했습니다).

여기에 이미지 설명을 입력하세요

따라서 이것이 해결되는 순간 위의 트릭은 더 이상 작동하지 않습니다.

그렇다면 버그는 무엇입니까?

문제는 매우 미묘합니다. 규칙이 작동하는 테이블을 만들려면 에서 수직으로 아래쪽으로 건너뛸 수 없습니다 \\[2ex]. 대신 행 중 하나에 일반 깊이를 확장하는 깊이를 가진 보이지 않는 규칙/상자가 배치됩니다 2ex. 이렇게 하지 않으면 수직 공간을 추가하는 위치에서 수직 규칙이 중단됩니다.

단점은 행에 비정상적인 깊이가 있는 경우 "정상" 깊이와 관련하여 측정되기 때문에 이러한 추가 공간이 부족할 수 있다는 것입니다.

게다가 array이 보이지 않는 스트럿을 마지막 행의 재료 끝에 배치하는 것은 "버그"입니다. m-열이 수직으로 중앙에 있기 때문에 단순히 잘못됩니다. 따라서 여기에서는 스트럿이 $\vcenter{... c \strut}$대신 에 일종의 끝이 나면서 "c"가 위쪽으로 움직이는 것을 볼 수 있습니다 $\vcenter{... c}$\strut.

그 이유는 \halign테이블을 작성하는 데 사용되는 TeX의 기본 메커니즘의 이상한 동작 때문입니다. LaTeX에 도달하면 \\[2ex]처리되었지만 $\vcenter{... c열을 형성하는 나머지 자료(즉, }$.

따라서 \\[ex]스트럿을 계산하고 추가한 다음 TeX에게 열이 완료되었음을( \cr내부적으로 사용) 알려주고 그 결과 TeX가 열 템플릿의 나머지 부분( }$...공간 및 규칙 포함)을 입력 스트림에 복사하고 결국 빙고가 됩니다. 내부 스트럿으로 vcenter.

가능한 수정 방법은 기둥 템플릿의 오른쪽 부분에서만 발생하도록 스트럿 배치를 지연시키는 것입니다. 그 시간에는 범위 지정이 값을 다시 변경하므로 이는 약간 까다롭습니다. 따라서 이는 전역 작업이어야 합니다.

\documentclass{article}
\usepackage{array}

\makeatletter
\def\@classz{\@classx
   \@tempcnta \count@
   \prepnext@tok
   \@addtopreamble{\ifcase \@chnum
      \hfil
      \d@llarbegin
      \insert@column
      \d@llarend\fmi@fix \hfil \or
      \hskip1sp\d@llarbegin \insert@column \d@llarend\fmi@fix \hfil \or
      \hfil\hskip1sp\d@llarbegin \insert@column \d@llarend\fmi@fix \or
   $\vcenter
   \@startpbox{\@nextchar}\insert@column \@endpbox $\fmi@fix
    \or
   \vtop \@startpbox{\@nextchar}\insert@column \@endpbox\fmi@fix \or
   \vbox \@startpbox{\@nextchar}\insert@column \@endpbox\fmi@fix
  \fi}\prepnext@tok}

\def\@mkpream#1{\gdef\@preamble{}\@lastchclass 4 \@firstamptrue
   \let\@sharp\relax \let\@startpbox\relax \let\@endpbox\relax
   \let\fmi@fix\relax
   \@temptokena{#1}\@tempswatrue
   \@whilesw\if@tempswa\fi{\@tempswafalse\the\NC@list}%
   \count@\m@ne
   \let\the@toks\relax
   \prepnext@tok
   \expandafter \@tfor \expandafter \@nextchar
    \expandafter :\expandafter =\the\@temptokena \do
   {\@testpach
   \ifcase \@chclass \@classz \or \@classi \or \@classii
     \or \save@decl \or \or \@classv \or \@classvi
     \or \@classvii \or \@classviii
     \or \@classx
     \or \@classx \fi
   \@lastchclass\@chclass}%
   \ifcase\@lastchclass
   \@acol \or
   \or
   \@acol \or
   \@preamerr \thr@@ \or
   \@preamerr \tw@ \@addtopreamble\@sharp \or
   \or
   \else  \@preamerr \@ne \fi
   \def\the@toks{\the\toks}}   


\def\@xargarraycr#1{\gdef\fmi@fix
 {\@tempdima #1\advance\@tempdima \dp\@arstrutbox
  \vrule \@depth\@tempdima \@width\z@\global\let\fmi@fix\relax}\cr}
\let\fmi@fix\relax

\makeatother

\begin{document}

\begin{tabular}{|m{0.18cm}|m{0.18cm}|}
\hline
a&c \\[2ex]
\hline
0& 0  \\
\hline
\end{tabular}

\end{document}

내가 말했듯이 이것은 다소 섬세하기 때문에 다른 것들을 많이 손상시키지 않고 그런 유형의 변경을 하는 것이 안전할지 확신할 수 없습니다(결국 array꽤 많이 사용되는 정말 오래된 패키지(25년 이상)이고 문제는 처음부터 거기에 있습니다.

어쨌든 위의 변경으로 우리는 이제 다음을 얻습니다.

여기에 이미지 설명을 입력하세요

이것이 우리가 해야 할 일이지만 아마도 사람들이 "m" 열을 지정한다고 생각했을 때 기대했던 것은 아닐 수도 있습니다.

업데이트

LaTeX의 2018-04 릴리스(또는 그 이전 릴리스)부터 실제 버그가 위의 개요대로 수정되었습니다. 이는 (불행히도) 위에서 제안하고 정답으로 표시된 트릭이 더 이상 작동하지 않는다는 것을 의미합니다. 그러나 제가 설명했듯이 그것은 "m"의 사양이 무엇인지에 대한 잘못된 가정에 기반을 두고 있습니다.

관련 정보