\parbox 的高度不能按条件分配吗?

\parbox 的高度不能按条件分配吗?

我想用条件指定我的高度\parbox,如下所示,但失败了。为什么以及如何处理?

代码:

\documentclass[a4paper]{article}
\usepackage{etoolbox}
\usepackage{geometry}
\geometry{showframe}
\geometry{left=1cm,right=1cm,top=1cm,bottom=1cm}


\parindent0pt
\begin{document}
\newdimen\ccc
\newdimen\bbb
\ccc20pt
\bbb30pt
\def\cond{0}
\newif\ifmycase

Case 1:\\%This case does not work, why?
\eappto\test{\noexpand\fbox{\noexpand\parbox[c][
  \ifcase\cond\relax \dimexpr \ccc + \bbb\relax
  \or \ifmycase 1in\else 20pt\fi
  \fi
  ]
  {50pt}{aa}
}
}
\test\\

|\ifcase\cond 0\or 1\fi| % typeset 0 expected but nothing obtained,why?

Case 2:% This case does not work either, why?
\parbox[c][\ifnum 5 > 4 \dimexpr \ccc + \bbb\relax\else 20pt\fi]{1in}{aa}
\end{document}

答案1

如果你\show\test按照\eappto说明操作,你会看到

> \test=macro:
->\fbox {\parbox [c][ \relax \dimexpr \ccc + \bbb \relax ] {50pt}{aa} } .

由于初始的 ,它将不起作用\relax。它来自哪里?你有

  \ifcase\cond\relax \dimexpr \ccc + \bbb\relax
  \or \ifmycase 1in\else 20pt\fi
  \fi

这就是你从哪里得到的。删除第一个\relax将显示

> \test=macro:
->\fbox {\parbox [c][ \dimexpr \ccc + \bbb \relax ] {50pt}{aa} } .

之前有一个不需要的空格\dimexpr,但这不是问题;它来自

\eappto\test{\noexpand\fbox{\noexpand\parbox[c][

那应该是

\eappto\test{\noexpand\fbox{\noexpand\parbox[c][%

但是,这可能不是您真正想要的,因为在调用时将使用和当前\dimexpr的值,而不是在将项目添加到其中时。\aaa\bbb\test

如果你

\eappto\test{%
  \noexpand\fbox{%
    \noexpand\parbox[c][%
      \ifcase\cond\space % case 0
        \the\dimexpr \ccc + \bbb\relax
      \or
        \ifmycase 1in\else 20pt\fi % case 1
      \fi
    ]
    {50pt}{aa}%
  }%
}

那么你会得到

> \test=macro:
->\fbox {\parbox [c][50.0pt] {50pt}{aa}}.

这更可能是您想要的。在评估\space时将被吞噬,就像宏一样。\ifcase\cond

为什么下面的方法不起作用?

\parbox[c][\ifnum 5 > 4 \dimexpr \ccc + \bbb\relax\else 20pt\fi]{1in}{aa}

这更难。首先:

% latex.ltx, line 11815:
\DeclareRobustCommand\parbox{%
  \@ifnextchar[%]
    \@iparbox
    {\@iiiparbox c\relax[s]}}%

你有一个[追随者\parbox,所以你得到

\@iparbox[c][\ifnum 5 > 4 \dimexpr \ccc + \bbb\relax\else 20pt\fi]{1in}{aa}

现在让我们看看\@iparbox

% latex.ltx, line 11819:
\def\@iparbox[#1]{%
  \@ifnextchar[%]
    {\@iiparbox{#1}}%
    {\@iiiparbox{#1}\relax[s]}}

你有[,所以你得到

\@iiparbox{c}[\ifnum 5 > 4 \dimexpr \ccc + \bbb\relax\else 20pt\fi]{1in}{aa}

好的,什么\@iiparbox

% latex.ltx, line 11823:
\def\@iiparbox#1[#2]{%
  \@ifnextchar[%]
    {\@iiiparbox{#1}{#2}}%
    {\@iiiparbox{#1}{#2}[#1]}}

没有[,所以我们得到

\@iiiparbox{c}{\ifnum 5 > 4 \dimexpr \ccc + \bbb\relax\else 20pt\fi}[c]{1in}{aa}

好,我们继续吧。

% latex.ltx, line 11828:
\long\def\@iiiparbox#1#2[#3]#4#5{%
  \leavevmode
  \@pboxswfalse
  \setlength\@tempdima{#4}%
  \@begin@tempboxa\vbox{\hsize\@tempdima\@parboxrestore#5\@@par}%
    \ifx\relax#2\else
      \setlength\@tempdimb{#2}%
      \edef\@parboxto{to\the\@tempdimb}%
    \fi
    \if#1b\vbox
    \else\if #1t\vtop
    \else\ifmmode\vcenter
    \else\@pboxswtrue $\vcenter
    \fi\fi\fi
    \@parboxto{\let\hss\vss\let\unhbox\unvbox
       \csname bm@#3\endcsname}%
    \if@pboxsw \m@th$\fi
  \@end@tempboxa}

这是\parbox实际排版的地方。您收到的错误消息是

! Extra \else.
\@iiiparbox ...tore #5\@@par }\ifx \relax #2\else
                                                  \setlength \@tempdimb {#2}...

我们上面看到的各种宏\relax在第二个可选参数未使用时使用,因此最后一个宏可以执行此测试。但是使用你#2

\ifx\relax\ifnum 5 > 4 \dimexpr \ccc + \bbb\relax\else 20pt\fi

并与\ifx进行比较,因此此条件丢失。改为使用 开始可选参数:\relax\ifnum\empty

\parbox[c][\empty\ifnum 5 > 4 \dimexpr \ccc + \bbb\relax\else 20pt\fi]{1in}{aa}

相关内容