Saino
Saino
这家伙很懒,什么也没写!

注册于 2年前

回答
10
文章
2
关注者
3

虽然+(\myInterval,-0.5cm)不修改参照点,但sin

\documentclass{article}
\usepackage{linegoal}
\usepackage{lipsum}
%\usepackage{lineno}
\usepackage{wrapfig}

\makeatletter
\newdimen\savegoal
\newdimen\saveprevdepth
\newcount\saveprevgraf
\newcount\savepenalty
\newtoks\saveoutput
\newbox\linebox
\newskip\saveskip
\expandafter\let\expandafter\@@output\csname tex_output:D\endcsname
%\let\@@output=\output
%\newif\ifendswithglue
\def\play{%
  \global\@@output=\expandafter{\the\saveoutput}%
  \ifnum\outputpenalty=-1000000
    \setbox\z@\vbox{\unvbox\@cclv\processlastline}%
    \unvbox\z@
    \aftergroup\replay
  \else
    \the\saveoutput
    \global\@@output={\play}%
  \fi
}
\def\processlastline{%
  \global\setbox\linebox=\lastbox
  \ifvoid\linebox\else 
    \unskip
    \ifnum\saveprevgraf=1
      % \parskip and \lineskip
      \unskip
    \else
      \savepenalty=\lastpenalty 
      \unpenalty
      \penalty\numexpr\savepenalty-\widowpenalty\relax
      \nobreak\vskip-\parskip
    \fi
  \fi
}
\def\replay{%
  \ifvoid\linebox\else
    \noindent
    \prevgraf=\numexpr\saveprevgraf-1\relax
    \setbox\linebox=\hbox{\hskip-\leftskip
      \unhbox\linebox
      % \par's \unskip \penalty10000 \hskip\parfillskip and \rightskip
      \unskip\unskip\unpenalty
%      \ifendswithglue
%        \hskip\saveskip
%      \fi
    }%
    \hskip-\dimexpr\linewidth-\savegoal-\leftskip\relax
    \leftskip=\glueexpr\leftskip-\dimexpr\leftskip\relax+\linewidth-\savegoal\relax
    \unhbox\linebox
  \fi}
  
\def\hanghere{%
  \savegoal=\linegoal
%%  \linegoal generates a whatsit, so the skip is not removed by \par
%  \ifnum\lastnodetype=11
%    \endswithgluetrue
%    \saveskip\lastskip
%  \else
%    \endswithgluefalse
%  \fi
  \endgraf
  \saveprevgraf=\prevgraf
  \saveoutput=\expandafter{\the\@@output}%
  \@@output={\play}%
  \penalty-1000000
  \ignorespaces
  \parindent=0pt
}
\def\endhanghere{\par}
\makeatother
\begin{document}
\begin{wrapfigure}[12]{r}[34pt]{5cm} 〈figure〉 \end{wrapfigure}
\lipsum[1]
\begin{hanghere}
\lipsum[2]
\begin{hanghere}
\lipsum[3]
\end{hanghere}
\end{hanghere}
\end{document}

image.png

https://ask.latexstudio.net/ask/question/7232.html 的方案改变而来,基本算是比较完美了。
目前问题是不兼容lineno以及wrapstuff宏包,lineno适配倒是不难,但是很繁琐,等有时间再弄弄。
以及 lualatex 无效,原因待查证。

首先 Q[2cm,c]|X[l] 就很迷惑,表格的每一行都跨列了,直接写成X[c]就可以了。

对于 span cell,当hspan参数为default或者even时,它的宽度就是自身的自然宽度,为minimal时,宽度是其他行这些列的格子宽度之和,所以设置 hspan=minimal 也可以。

你这代码习惯太糟糕了,看了下提问者的四个提问,所有的问题就在于你一直写自己看不懂的代码。不知道有什么用的就把它删掉。看不懂的代码往里加,最后出现什么错误结果是不可控的,放在提问里更让问题难以看懂,咱们应该保证明确知道自己写的每一行都是什么意思。

问题有这么几个:

  1. 1pt的选项没有意义
  2. amsmath, amssymb, amsfonts, MnSymbol, stmaryrd, pgfplotstable, colormaps, gfplots.groupplots,matrix 这些东西对题目里的图像没有用,删掉。
  3. ymode都设为normal了,不要去设置log basis y,那是给log模式用的。
  4. \addplot后面的加号没有意义,为什么要写?

把这些乱七八糟的删掉,结果就对了。

另外你这个运算量太大了点,跑起来特别慢,最好还是用别的软件画好插进来。如果你能够用lualatex编译的话,可以用下面的代码代替xfp宏包,速度会快很多

%!TEX program=lualatex
\documentclass{standalone}
\usepackage{euler}
\usepackage{xcolor}
%\usepackage{xfp}
\usepackage{pgfplots}
\pgfplotsset{height=8cm,width=14cm}
\catcode`\%=12
\def\fpeval#1{\directlua{tex.sprint(string.format("%f",#1))}}
\catcode`\%=14
\begin{document}
\begin{tikzpicture}
    \begin{loglogaxis}[
        enlargelimits=false,
        grid=both,
        ymin=5e-6,ymax=1,
        ymode=normal,
xlabel= $\mathnormal{Wave\quad length}$,
ylabel=$\mathnormal{amplitude\quad transmission}$,
        log basis x=10,
        domain=1e-3:1e7,samples=360
        ]
        \addplot[no marks,ultra thick,darkgray]{\fpeval{math.exp(((0.4697*0.025/\x)^2)*(-3.1415))}};
        \addplot[no marks,ultra thick,gray]{\fpeval{1-math.exp(((0.4697*0.8/\x)^2)*(-3.1415))}};
        \addplot[no marks,ultra thick,magenta]{\fpeval{math.exp(((0.4697*0.8/\x)^2)*(-3.1415))}};
        \addplot[no marks,ultra thick,pink]{\fpeval{1-math.exp(((0.4697*8/\x)^2)*(-3.1415))}};
        \addplot[no marks,ultra thick,blue]{\fpeval{math.exp(((0.4697*2.5/\x)^2)*(-3.1415))}};
        \addplot[no marks,ultra thick,green]{\fpeval{math.exp(((0.4697*8/\x)^2)*(-3.1415))}};
        \addplot[no marks,ultra thick,orange]{\fpeval{math.exp(((0.4697*25/\x)^2)*(-3.1415))}};
\legend{$\mathnormal{\lambda=0.025mm}$,
    $\mathnormal{\lambda=0.8mm}$,
    $\mathnormal{\lambda=0.8mm}$,
    $\mathnormal{\lambda=8mm}$,
    $\mathnormal{\lambda=2.5mm}$,
    $\mathnormal{\lambda=8mm}$,
    $\mathnormal{\lambda=25mm}$,
}
\end{loglogaxis}
\end{tikzpicture}
\end{document} 

image.png

\begin{tblr}{rowsep=0pt,colspec={lcccccccQ[c,cmd=\hbox,appto=\unskip]}}
  \hline\hline
  系统 & Mn1 & Mn2 & Mn3 & Ni1 & Ni2 & Ni3 & Ni4 & 参考图 \\ \hline
  A & $3.278$ & $2.955$ & $3.270$ & $0.664$ & $0.601$ & $0.688$ & $0.663$ & (a) \\
  B & $3.229$ & --- & --- & $0.479$ & $0.518$ & $0.537$ & --- & (b) \\
  C & $3.219$ & --- & --- & $0.475$ & $0.510$ & $0.513$ & --- & (c) \\
  \hline\hline
\end{tblr}

image.png

如果允许descripition嵌套可以用楼上@u3793 的回答。
严格按问题的要求我这里手搓了一个实现,非常非常复杂,大概需要编译两到三次。
使用方法就是

\begin{nobreaklist}{enumerate}
  \item item 1
  \item item 2\\the line 2
\end{nobreaklist}

默认情况下,算上列表标签,一行的内容超过行宽的60%就会另起一行,可以用\SetNobreaklistLimit修改阈值和\ResetNobreaklistLimit恢复默认。

  1. 这个环境除紧随第一个 \item 的段落,其他段可嵌套别的列表环境。
  2. nobreaklist 自身不能放在别的列表内部,技术上虽然可以实现(更复杂),但这种排版的效果并不必要,并且非常不规范。
  3. 费了一些工夫 make enumitem happy,enumitem 宏包大致上可以正常使用,但它魔改太多,不敢保证 100% 兼容。

如果修改了文章,最好是删除.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}

image.png

对于嵌套的情况,偶尔排版正确是巧合,一般情况可能会无法正确定位

\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}

image.png
有一个临时的解决方案,手动地设置所在行的位置\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}

image.png

@u1077 的例子

\documentclass{ctexart}
\makeatletter
\let\hangfrom\@hangfrom
\makeatother
\begin{document}
劳仑衣普桑,认至将指点效则机,最你更枝。想极整月正进好志次回总般,段然取向使张规军证回,世市总李率英茄持伴。

\hangfrom{第二段:}水厂共当而面三张,白家决空给意层般,单重总歼者新。每建马先口住月大,究平克满现易手,省否何安苏京。两今此叫证程事元七调联派业你,全它精据间属医拒严力步青。

\noindent
\hangfrom{这回开始不缩进写第三段:}她己道按收面学上全始,形万然许压己金史好,力住记赤则引秧。处高方据近学级素专,者往构支明系状委起查,增子束孤不般前。

你要的是这个效果么?
  
\end{document}

image.png

这个东西本来很简单,

\Large
2021年\begin{tabular}[b]{c}
  哈尔滨师大附中\\
  \begin{tabular}[t]{@{}c@{}}
  辽宁省实验中学\\
  东北师大附中
  \end{tabular}
\end{tabular}高三第一次联考

这样就完事,间距还想宽一点就把里面的@{}c@{}换成c
写成一个环境也行,用\alignhere标记对齐位置。

\makeatletter
\def\parse@align#1#2#3\alignhere{%
  \def\@helper##1{\begin{tabular}[b]{#1}
    #3
    \begin{tabular}[t]{##1}}%
  \expandafter\@helper\expandafter{#2}}
\newenvironment{centertable}[2][]{%
  \ifx\\#1\\%
    \def\inner@preamble{#2}%
  \else
    \def\inner@preamble{#1}%
  \fi
  \parse@align{#2}\inner@preamble
}
{\end{tabular}\end{tabular}}
\makeatother

\fbox{\Large
2021年\begin{centertable}[@{}c@{}]{c}% [...]是内部表格的导言,默认跟外层相同
  哈尔滨师大附中\\
  \alignhere 辽宁省实验中学\\
  东北师大附中
\end{centertable}高三第一次联考
}

如果非要像正常一样书写,可以用tikz标记位置,代价是编译速度会慢很多。

\documentclass{ctexart}
\usepackage{tabularray}
\usepackage{tikz}
\usetikzlibrary{tikzmark} % \subnode

\SetTblrInner{rowsep=0pt} % 设置多行文字的行间距

\makeatletter
\ExplSyntaxOn
\int_new:N \g_centertblr_num_int % 编号避免标记名字重复
\tl_new:N \l_centertblr_current_label_tl
\bool_new:N \g_centertblr_odd_row_count_bool
\NewDocumentEnvironment { centertblr } { O{c} m +b }
  {
    \tl_set:Nx \l_centertblr_current_label_tl { centertblr-mark-\int_use:N \g_centertblr_num_int }
    
    \begin { tikzpicture }
      [
        baseline = ( \l_centertblr_current_label_tl.base ), % 1
        remember~picture
      ]
      
      \node
        [
          anchor = base,
          baseline = ( \l_centertblr_current_label_tl.base ), % 2 对齐设置两次
          inner~sep = 0,
        ]
        {
          \begin { tblr } [#1] {#2}
            \SetRows% 最中间的行处标记
              {
                preto = {
                  \bool_if:NTF \g_centertblr_odd_row_count_bool 
                    {
                      \int_compare:nNnT { \c@rownum * 2 - 1} = { \c@rowcount }
                        { \subnode { \l_centertblr_current_label_tl } {} }
                    }
                    {
                      \int_compare:nNnT { \c@rownum * 2 } = { \c@rowcount }
                        { \subnode { \l_centertblr_current_label_tl-up } {} }
                      \int_compare:nNnT { \c@rownum * 2 - 2} = { \c@rowcount }
                        { \subnode { \l_centertblr_current_label_tl-down } {} }
                    }
                  }
                }
              \bool_gset:Nn \g_centertblr_odd_row_count_bool % node 里面不能写\path,保存以在外面用
                { \int_if_odd_p:n { \int_use:N \c@rowcount } }
              #3
            \end { tblr }
          };
        \bool_if:NF \g_centertblr_odd_row_count_bool
          {
            \path (\l_centertblr_current_label_tl-up) -- (\l_centertblr_current_label_tl-down)
             coordinate[midway] (\l_centertblr_current_label_tl);% 标记中间两行anchor的中点
          }
      \end { tikzpicture }
    }
  { \int_gincr:N \g_centertblr_num_int }
\ExplSyntaxOff
\makeatother

\begin{document}

\fbox{\Large
2021年\begin{centertblr}{Q[c,leftsep=0pt,rightsep=0pt]} % leftsep, rightsep 用来设置多行环境的左右间距
  哈尔滨师大附中\\
  辽宁省实验中学\\
  东北师大附中
\end{centertblr}高三第一次联考
}

\fbox{\Large
  2022年\begin{centertblr}{Q[c,leftsep=0pt,rightsep=0pt]}
    金华市\\
    衢州市
  \end{centertblr}初三第一次联考
}

\fbox{\Large
  2021年\begin{centertblr}{Q[c,leftsep=0pt,rightsep=0pt]}
    哈尔滨师大\rule[-2cm]{1pt}{2cm}附中\\
    东北师大附中\\
    辽宁省实验中学
  \end{centertblr}高三第一次联考
}

\fbox{\Large
  2021年\begin{centertblr}{Q[c,leftsep=0pt,rightsep=0pt]}
    哈尔滨师大\rule[-2cm]{1pt}{2cm}附中\\
    东北师大附中\\
  \end{centertblr}高三第一次联考
}

\end{document}

image.png

lua-visual-debug查看盒子的输出如下
image.png

第一行:
宽度为\parindent的空盒子+\hfill粘连+middle<空格>+\hfill+tail<空格>+\parfillskip
第二行:
宽度为\parindent的空盒子+\hfill+middle<空格>+\hfill+tail+\parfillskip
第三行:
宽度为\parindent的空盒子+\hfill+middle<空格>+\hfill+tail<空格>+\hfill+空盒子+\parfillskip
第四行:
宽度为\parindent的空盒子+空盒子+空格+\hfill粘连+middle<空格>+\hfill+空盒子+\parfillskip
第五行:
宽度为\parindent的空盒子+\hfill+middle<空格>+\parfillskip
第六行
宽度为\parindent的空盒子+空盒子+空格+\hfill粘连+middle<空格>+\parfillskip
第七行:
宽度为\parindent的空盒子+\hfill+middle<空格>+\hfill+空格+空盒子+\parfillskip
第八行:
空格+\hfill+middle<空格>+\hfill+空盒子+\hfil
第九行:
middle<空格>+\hfill+tail+\hfil
第十行:
middle+\parfillskip

补充一些细节

  1. 控制序列的单词后的空格直接就不会读入,所以\hfil {}123严格等于\hfil{}123
  2. 段首会插入宽度为\parindent的空盒子,如果有\noindent,则什么也不插入(而不是零宽的空盒子);
  3. LaTeX默认\parfillskip的粘连相当于\hfil,它在有更高级的\hfill存在时会被覆盖;
  4. 因为\par前用户难免会输入空格,如something<Return>\par或者paragraph<Return><Return>paragrah,段落末行的最后一个粘连会被吃掉,所以\hfill\par\hfill无效,要想起作用,可以再加一个粘连如\hfill\ \hfill\hfill,或者空盒子;
  5. \\的意义相当于\unskip\nobreak\hfil\break\unskip会去掉当前列的最后一个粘连,所以第九行末尾没有空格;
  6. TeX引擎并未区分强制断行自动断行,对引擎而言,它做的就是“一行写满了换一行”的自动断行,TeX会在可以断行的地方用一些内部参数来衡量断行的代价,\nobreak\break是一些调整此参数的命令。所以TeX无法区分\\后的粘连是在正常文档流之中还是紧随一个强制断行,干脆就吃掉断行后的所有间距。

发布
问题