`documentclass{ctexart}
begin{document}
进入列表:begin{enumerate}
item 第一条目
item 第二条目
end{enumerate}
end{document}`
编译结果是
我想要的结果如下图
如果允许descripition嵌套可以用楼上@u3793 的回答。
严格按问题的要求我这里手搓了一个实现,非常非常复杂,大概需要编译两到三次。
使用方法就是
\begin{nobreaklist}{enumerate}
\item item 1
\item item 2\\the line 2
\end{nobreaklist}
默认情况下,算上列表标签,一行的内容超过行宽的60%就会另起一行,可以用\SetNobreaklistLimit
修改阈值和\ResetNobreaklistLimit
恢复默认。
\item
的段落,其他段可嵌套别的列表环境。如果修改了文章,最好是删除.aux文件重新编译,否则有几率位置错乱。
\documentclass{article}
\usepackage{linegoal}
\usepackage{lipsum}
\usepackage{enumitem}
\makeatletter
% \nobreaklist@@command to save orginal \command
\let\nobreaklist@@trivlist=\@trivlist
\let\nobreaklist@@noitemerr=\@noitemerr
\let\nobreaklist@@item=\@item
\let\nobreaklist@relax=\relax
\newcounter{nobreaklist}
\newif\if@nobreaklist@prevgrafknown
\def\nobreaklist@first@@item[#1]{%
% save item info (label and parshape)
\nobreaklist@@item[#1]%
\let\@noitemerr\nobreaklist@@noitemerr
% manually label with \everypar set in \@item
\the\everypar
% use \@setpar info set in \@trivlist to restore \par
\@restorepar
% detect prevgraf right after \par restored
% succeeding \par's will change \prevgraf
\unless\if@nobreaklist@prevgrafknown
\par
\edef\nobreaklist@prevgraf{\the\prevgraf}%
\immediate\write\@auxout{\gdef\string\nobreaklist@prevgraf@\romannumeral\c@nobreaklist{\nobreaklist@prevgraf}}%
\@latex@warning@no@line{Position for nobreaklist changed.
Rerun to get it right}%
\fi
\let\@item=\nobreaklist@second@@item
}
\def\nobreaklist@second@@item[#1]{%
\nobreaklist@@item[#1]%
% parshape for paragraphs other than the first
\expandafter\everypar\expandafter{\the\everypar \parshape\@ne\@totalleftmargin\linewidth}%
\let\@item=\nobreaklist@@item
}
% max proportion of \linewidth when the list par start
\def\nobreaklist@leftmargini@max@proportion{0.6}
\let\nobreaklist@leftmargini@max@proportion@default=\nobreaklist@leftmargini@max@proportion
\def\SetNobreaklistLimit#1{\def\nobreaklist@leftmargini@max@proportion{#1}}
\def\ResetNobreaklistLimit{%
\let\nobreaklist@leftmargini@max@proportion=\nobreaklist@leftmargini@max@proportion@default}
% #1: enumerate or itemize
% #2: code to set \make@enumitem@happy or empty
\def\donobreaklist#1#2{%
\let\make@enumitem@happy=\@firstofone
#2%
% unique even this feature not used
\stepcounter{nobreaklist}%
% restart to orginal list env
% define here to use #1
\long\def\nobreaklist@restart##1\nobreaklist@relax{%
\fi
% restore global modifications in \list
\global\advance\@listdepth\m@ne
\addtocounter{nobreaklist}\m@ne
% match \begingroup from \begin{nobreaklist}
\endgroup
% enter vmode to disable this feature
\par
% \begin takes cares of group matching, env name and hooks
\begin{nobreaklist}{#1}%
}%
% vmode don't need this feature
\ifvmode
\make@enumitem@happy{\csname #1\endcsname}
\else
% \prevgraf saved in aux file
\@ifundefined{nobreaklist@prevgraf@\romannumeral\c@nobreaklist}
{\@nobreaklist@prevgrafknownfalse}
{\@nobreaklist@prevgrafknowntrue}%
\if@nobreaklist@prevgrafknown
\edef\nobreaklist@prevgraf{\csname nobreaklist@prevgraf@\romannumeral\c@nobreaklist\endcsname}%
% rewrite to aux
\immediate\write\@auxout{\gdef\string\nobreaklist@prevgraf@\romannumeral\c@nobreaklist{\nobreaklist@prevgraf}}%
\fi
% even first run does this to detect linegoal
% because \@itemlabel is known only after \list called
% this will save a compile run
\def\@trivlist{%
% tune vertical spacing
% \partopsep not needed: always horizontal mode
\if@nobreaklist@prevgrafknown
\ifnum \nobreaklist@prevgraf>1
\itemsep=\z@
\parsep=\parskip
\topsep=\z@
\fi
\fi
\if@nmbrlist
% not \stepcounter, avoid resettings
\addtocounter{\@listctr}\@ne
\fi
% In enumerate or itemize,
% \makelabel{LABEL} is \hss\llap{LABEL},
% which ensures \hbox{\makelabel{LABEL}} being zero width.
% Then the label is placed as \hbox{LABEL}
% at \labelsep left from \@totalleftmargin,
% following an \hskip \itemindent.
% No need to take care of \itemindent,
% since it's additional indention to \leftmargin
% only on the first line of item paragraph
\setbox\@tempboxa=\hbox{%
\hbox{\@itemlabel}%
\if@nmbrlist
% restore initial state of the counter (global)
\addtocounter{\@listctr}\m@ne
\fi
\hskip\labelsep}%
% wrap \hskip in hbox to avoid line break
% Update: replace \kern with \hbox to work with line start
% \kern\wd\@tempboxa
\hbox to\wd\@tempboxa{}%
% using \linegoal in \dimexpr isn't essentially allowed
% but it's we can use it at the end of the expression
% for the subtle fact that \linegoal's expansion has a \relax inside,
% which is approximately \linewidth\relax\LNGL@set@linegoal,
% then recompile to be the actual linegoal and \relax
%
% note that \linegoal ignores \leftmargin's set by parshape
% \linegoal = \linewidth-\pdfxpos+\trueleftmargin
% and we need
% \leftmargin = \pdfxpos-\trueleftmargin-\@totalleftmargin
\leftmargin=\dimexpr\linewidth-\@totalleftmargin-\linegoal\relax
% if too long
\ifdim \dimexpr\leftmargin+\@totalleftmargin\relax>
\nobreaklist@leftmargini@max@proportion\dimexpr\linewidth+\@totalleftmargin\relax
\nobreaklist@restart
\else
% make \lastbox non-void to avoid the itemindent removal in \@item,
% place hbox here because \linegoal is the last command
% that generates non-hbox horizontal item
\hbox{}%
\nobreaklist@@trivlist
% no need to be global, \begin{nobreaklist} has \begingroup
% if want to use \nobreaklist ... \endnoreaklist, change to \global\let here
\let\@trivlist=\nobreaklist@@trivlist\fi}%
% disable the first \par which is in \@trivlist
% then there will be a \@setpar in \@trivlist too
\let\par\relax
\make@enumitem@happy{\csname #1\endcsname}%
% parshape for the paragraph starting this environment
% \parshape\tw@ \z@ \dimexpr\linewidth+\leftmargin\relax \@totalleftmargin \linewidth
\if@nobreaklist@prevgrafknown
\nobreaklist@parshape\nobreaklist@prevgraf
\else
\parshape=1
\dimexpr\@totalleftmargin-\leftmargin\relax
\dimexpr\linewidth+\leftmargin+\rightmargin\relax
\fi
% disable the \par in \@item
\let\par\relax
% disable verticle adjustments executed after the \par
% (\addpenalty and \addvspcce)
% which assume to be vertical mode,
% and simply give a \@noitemerr when in horzontal mode,
% but the mode will be horizontal since \par is disabled.
\let\@noitemerr\relax
\let\@item=\nobreaklist@first@@item
\fi
% parameter delimiter for \nobreaklist@restart
\nobreaklist@relax}
% set parshape
% #1: \prevgraf after current line
\def\nobreaklist@parshape#1{%
\edef\@parshape@str{%
\dimexpr\@totalleftmargin-\leftmargin\relax
\dimexpr\linewidth+\leftmargin+\rightmargin\relax}%
\@tempcnta=#1%
\@temptokena={}%
\loop
\ifnum\@tempcnta>0
\@temptokena=\expandafter{\the\@temptokena\@parshape@str}%
\advance\@tempcnta-1
\repeat
\parshape \numexpr#1+1\relax \the\@temptokena \@totalleftmargin \linewidth
}
% make enumitem happy
\@ifpackageloaded{enumitem}{%
% #2: dummy, absorb the empty argument
% provided in case it's let to \donobreaklist
% #3: enumitem's key=val list
\def\make@enumitem@happy@and@donobreaklist#1#2[#3]{%
\donobreaklist{#1}{%
\def\make@enumitem@happy##1{##1[#3]}%
}%
}%
}{%
\let\make@enumitem@happy@and@donobreaklist=\donobreaklist
}
% #2: list environment type, only works for enumerate and itemize
\newenvironment{nobreaklist}[2][]{%
% if #1 is not empty
\unless\if\relax\detokenize{#1}\relax
\@namedef{nobreaklist@prevgraf@\romannumeral\numexpr\c@nobreaklist+1\relax}{#1}%
\fi
\@ifnextchar[%
{\make@enumitem@happy@and@donobreaklist{#2}{}}%
{\donobreaklist{#2}{}}%
}{\endlist}
\makeatother
\begin{document}
some \begin{nobreaklist}{enumerate}
\item item 1
\item item 2\\the line 2
\end{nobreaklist}
\lipsum[1][1-8] \begin{nobreaklist}{enumerate}[label=(\emph{\alph *})]
\item item 1
\item item 2\\the line 2
\end{nobreaklist}
\lipsum[1][1-6] \begin{nobreaklist}{enumerate}
\item item 1
\item item 2\\the line 2
\end{nobreaklist}
\SetNobreaklistLimit{0.8}
\lipsum[1][1-6] \begin{nobreaklist}{enumerate}
\item item 1
\item item 2\\the line 2
\end{nobreaklist}
\end{document}
对于嵌套的情况,偶尔排版正确是巧合,一般情况可能会无法正确定位
\begin{itemize}
\item \lipsum[1][1-4]\par para 2 \begin{nobreaklist}{enumerate}[label=(\emph{\alph *})]
\item item 2.1
\item test \begin{nobreaklist}{itemize}
\item item 2.2.1
\item item 2.2.2
\end{nobreaklist}
\par
\lipsum[2][1-4]\begin{nobreaklist}{enumerate}
\item item 1
\item item 2
\end{nobreaklist}
\end{nobreaklist}
\end{itemize}
有一个临时的解决方案,手动地设置所在行的位置\begin{nobreaklist}[<行数>]{enumerate}
\begin{itemize}
\item \lipsum[1][1-4]\par para 2 \begin{nobreaklist}{enumerate}[label=(\emph{\alph *})]
\item item 2.1
\item test \begin{nobreaklist}{itemize}
\item item 2.2.1
\item item 2.2.2
\end{nobreaklist}
\par
\lipsum[2][1-4]\begin{nobreaklist}[5]{enumerate}
\item item 1
\item item 2
\end{nobreaklist}
\end{nobreaklist}
\end{itemize}
minipage小页不能断页,还要设置宽度,不自由
@u7483 想要断页的现在最优办法是嵌套description环境