更新

更新

此代码的目标是将三段文本排列在一行上,如果三段文本中的任何一段太长,则将中心文本降低\baselineskip

\documentclass{article}

\usepackage[showframe,papersize={5.5in,8.5in}]{geometry}
\newlength{\testwd}

\newcommand{\entry}[4][]{%
    \setbox1=\hbox{\strut\bfseries#2}%
    \setbox2=\hbox{\strut\itshape#3}%
    \setbox3=\hbox{\strut#4}%
    \setlength{\testwd}{\ifdim\wd1>\wd3 \wd1\else\wd3\fi}% Which is longer, L or R? Use it.
    \noindent%
        \if###1##\else\llap{#1\thinspace}\fi
        \hbox to 0pt{\box1\hss}%
        \hfill
        %% If the longer side (L or R) is longer than the half the remaining area around
        %% the center text, drop the center text.
        \ifdim\dimexpr \testwd - (\linewidth - \wd2)/2\relax>0pt\lower\baselineskip\fi
        \hbox{\box2}%
        \hfill
        \hbox to 0pt{\hss\box3}%
    \par
}

\begin{document}

\entry{Left side text}{Center Text}{Right text}

\entry{Left side text that is rather long}{Center Text}{Right side text}

\entry{Left side text}{Center Text}{Right side text that is rather long}

\end{document}

得出的结果为:

程序文本示例

出于好奇,我想知道是否有一种方法可以做到这一点而无需明确设置\testwd?换句话说,是否可以将的计算\testwd纳入是否降低中心文本的决策中?或者,有没有更有效的方法来做到这一点?(有如何使文本在同一行左对齐、居中对齐、右对齐?,但这并没有达到相同的效果,因为长行会相互覆盖,特别是中间的文本。当然,如果左右文本相互覆盖,那么一切都将不复存在。在这种情况下,这种情况不会发生,所以不是问题。)例如,这在音乐会节目中很有用。

答案1

以下测量每个文本组件的长度,并使用该长度作为将中心文本放置在\makecell[t]具有空白第一行或按原样的结构内的条件。

在此处输入图片描述

\documentclass{article}

\usepackage[showframe,papersize={5.5in,8.5in}]{geometry}

\usepackage{makecell}

\newlength{\LeftItem}
\newlength{\CentreItem}
\newlength{\RightItem}

\newcommand{\entry}[3]{%
  \par
  \settowidth{\LeftItem}{\bfseries #1}%
  \settowidth{\CentreItem}{\itshape #2}%
  \settowidth{\RightItem}{#3}%
  \noindent
  \makebox[0pt][l]{\bfseries #1}\hfill
  \makebox[0pt]{%
    \ifdim\LeftItem>.5\dimexpr\linewidth-\CentreItem\relax
      \makecell[t]{\strut \\ \itshape #2}%
    \else
      \ifdim\RightItem>.5\dimexpr\linewidth-\CentreItem\relax
        \makecell[t]{\strut \\ \itshape #2}%
      \else
        \itshape #2%
      \fi
    \fi
  }\hfill
  \makebox[0pt][r]{#3}%
  \par
}

\begin{document}

\entry{Left side text}{Center Text}{Right text}

\entry{Left side text that is rather long}{Center Text}{Right side text}

\entry{Left side text}{Center Text}{Right side text that is rather long}

\end{document}

代码将确保内容适合\linewidth,并且元素的长度被精确测量。这可能会导致构造中所有内容仍设置在同一行上,但彼此非常接近。因此,通过以下方式添加一点缓冲区可能是可行的:

\newcommand{\entry}[3]{%
  % ...
  \settowidth{\CentreItem}{\itshape ~#2~}% Add space on either side of centre item
  % ...
}

答案2

更新

这是经过修改的代码,其中考虑了 @DavidCarlisle 和 @JohnKormylo 的建议。我在最长的左/右和中间文本之间添加了间距;也使用了\rlap和 ,\llap而不是自己滚动。输出完全相同。

\documentclass{article}

\usepackage[showframe,papersize={5.5in,8.5in}]{geometry}

%% #1: optional marginal character; #2: left text; #3: center text; #4: right text
\newcommand{\entry}[4][]{%
    \begingroup
        \setbox0=\hbox{\strut\bfseries#2}%
        \setbox2=\hbox{\strut\itshape#3}%
        \setbox4=\hbox{\strut#4}%
        %% Which is longer, L or R? Use it:
        \setlength{\dimen0}{\ifdim\wd0>\wd4 \wd0\else\wd4\fi}%
        \noindent%
            \if###1##\else\llap{#1\thinspace}\fi %% Optional marginal character
            \rlap{\box0}%
            \hfill
            %% If space between longest L/R entry and center text
            %% is less than 0.5em, lower the center text by \baselineskip:
            \ifdim\dimexpr \dimen0 - (\linewidth - \wd2 - 0.5em)/2\relax>0pt
                \lower\baselineskip
            \fi
            \hbox{\box2}%
            \hfill
            \llap{\box4}%
        \par
    \endgroup
}

\begin{document}

\entry{Left side text}{Center Text}{Right text}

\entry{Left side text that is rather long}{Center Text}{Right side text}

\entry{Left side text}{Center Text}{Right side text that is rather long}

\end{document}

相关内容