在列表项上方插入小线而不添加额外空间(续)

在列表项上方插入小线而不添加额外空间(续)

这是在列表中的项目上方插入小线而不添加额外空间。我想控制水平线的长度与最宽 \item在列表中。

下面,我手动传入文本作为长度的依据。虽然这是一个可以接受的解决方法,但我想看看是否有一些简单的方法来消除 的参数\sepitem

在此处输入图片描述

代码:

\documentclass{article}

\usepackage{enumitem}
\usepackage{xcolor}
\usepackage{calc}

%% Adapted from 
%%    https://tex.stackexchange.com/questions/341614/
%%            insert-small-line-above-an-item-in-a-list-without-adding-extra-space
\newcommand\sepitem[1]{\item\raisebox{1.90ex}[0pt]{\rlap{\color{orange}\rule{\widthof{#1}}{0.8pt}}}}

\newcommand{\ShortText}{Short text.}
\newcommand{\LongText}{Somewhat wider text.}

\begin{document}
\begin{enumerate}[noitemsep]
\item \ShortText
\item \ShortText
\sepitem{\ShortText}A
\end{enumerate}
%% -------------------
\begin{enumerate}[noitemsep]
\item \LongText
\item \ShortText
\sepitem{\LongText}A
\end{enumerate}

\end{document} 

答案1

这里的问题是收集 的文本\item,我只能通过重新定义它来解决这个问题,这样它就可以接受一个带有文本的参数,即\item{Text}。没有必要将文本放在括号中,但只考虑其中的部分(或第一个标记)。基本上,将最长的文本放在括号中就足够了。

\sepitem不必写。但是使用此解决方案,可以使用\item{\sep Text}可选参数。\item

为了使其即使最宽的项目出现在 sep 行之后也能正常工作,项目中的最大宽度enumerate存储在文件中\jobname.eiw。这意味着,您必须编译两次才能获得正确的长度。如果您更改项目,则需要再次编译两次。

行长度受限,以便\linewidth支持多行项目。但请注意,太长的文本可能会导致错误Dimension too large

代码:

\documentclass{article}

\usepackage{enumitem}
\usepackage{xcolor}
\usepackage{calc}
\usepackage{etoolbox}

\makeatletter
\newcounter{enumscnt}
\setcounter{enumscnt}{0}
\newdimen\max@itemwidth
\newdimen\storedmax@itemwidth
\newdimen\eiw@tempdim
\newbox\eiw@box

\AtBeginDocument{%
    \InputIfFileExists{\jobname.eiw}{}{}%
}

\AtEndDocument{%
    \if@filesw\newwrite\tf@eiw
    \immediate\openout\tf@eiw\jobname.eiw\fi
}

% when reading \jobname.eiw, define macros like e.g.
% \max@[email protected]
\newcommand{\maxitemwidth}[2]{%
    \expandafter\def\csname max@item@width.#1\endcsname{#2}%
}

\newcommand{\eiw@before@environment}{%
    \stepcounter{enumscnt}%
    \max@itemwidth0pt\relax
    % prevent error in first run
    \@ifundefined{max@item@width.\the\c@enumscnt}{%
        \maxitemwidth{\the\c@enumscnt}{0pt}%
    }{}%
    % initialize with stored maximum
    \storedmax@itemwidth\csname max@item@width.\the\c@enumscnt\endcsname\relax
}

\newcommand{\eiw@after@environment}{%
    % write new maximum
    \protected@write\@auxout{}%
        {\string\@writefile{eiw}{\string\maxitemwidth{\the\c@enumscnt}{\the\max@itemwidth}}}%
}

\BeforeBeginEnvironment{enumerate}{\eiw@before@environment}
\AfterEndEnvironment{enumerate}{\eiw@after@environment}

\let\orig@item\item

\def\item{%
    \@ifnextchar[{\new@@item}{\new@item}%
}
\def\new@item#1{%
    \getmaxitemwidth{#1}%
    \orig@item #1%
}
\def\new@@item[#1]#2{%
    \getmaxitemwidth{#2}%
    \orig@item[#1] #2%
}

\def\getmaxitemwidth#1{%
    \setbox\eiw@box\hbox{#1}\global\eiw@tempdim\wd\eiw@box
    % limit to \linewidth
    \ifdim\eiw@tempdim>\linewidth
        \eiw@tempdim\linewidth\relax
    \fi
    % get new maximum
    \ifdim\eiw@tempdim>\max@itemwidth
        \global\max@itemwidth\eiw@tempdim\relax
    \fi
    % use bigger of stored or new maximum
    \ifdim\storedmax@itemwidth<\max@itemwidth
        \storedmax@itemwidth\max@itemwidth\relax
    \fi
}

% \sep instead of \sepitem
\newcommand\sep{%
    \raisebox{1.90ex}[0pt]{\rlap{\color{orange}\rule{\storedmax@itemwidth}{0.8pt}}}%
}
\makeatother

\newcommand{\ShortText}{Short text.}
\newcommand{\LongText}{Somewhat wider text.}

\begin{document}
\begin{enumerate}[noitemsep]
\item{\ShortText}
\item{\ShortText}
\item{\sep A}
\end{enumerate}
%% -------------------
\begin{enumerate}[noitemsep]
\item{\LongText}
\item{\ShortText}
\item{\sep A}
\end{enumerate}
%% -------------------
\begin{enumerate}[noitemsep]
\item{\LongText}
\item{\ShortText}
\item[x.]{\sep A}
\item{\LongText\ Test}
\end{enumerate}
%% -------------------
\begin{enumerate}[noitemsep]
\item Somewhat wider text.
\item Short text.
\item[x.] \sep A
\item[y.]{Some very long text, too long for a single line. But one sentece is not enough, so here is another one.}
\end{enumerate}

\end{document}

结果:

在此处输入图片描述

相关内容