劝说 (la)tex“默默地超越‘好品味’的界限”,以避免水平框过满

劝说 (la)tex“默默地超越‘好品味’的界限”,以避免水平框过满

我的理解基于阅读本网站,是 (la)tex 在尝试排版段落时最多执行三次:一次基于\pretolerance,一次基于\tolerance,一次基于\emergencystretch。 (我不知道该microtype包会如何影响这一点。)如果第三次传递(要求最不严格)仍然无法排版段落,tex 会“放弃”并留下一个过满的水平盒子。

对于熟悉窄栏杂志和报纸(有时是教科书,等等)中出现的排版的普通读者来说,过满的水平盒子很多\tolerance比对或 的宽松要求更明显\emergencystretch。考虑到现代计算机的速度,tex 继续以逐渐放松的要求进行传递似乎是相当合理的,直到它能够排版段落,或者得到非常糟糕的值,以至于结果实际上比满溢的水平盒子“突出”得更多。如果 TeX 遵循这种方法,那么每次需要额外的传递时可能仍会发出警告。但如果用户希望稍后切换到不同的文档类,或者出于其他原因而更愿意忽略警告,那么排版混乱的段落可能感觉不像是打脸,而更像是满溢的水平盒子。

因此,问题是:
是否有可能通过包来修改 (La)TeX 的行为,以便它在“放弃”并允许过满的水平盒子之前执行额外的传递,并自动(和逐步)放宽参数?

答案1

这是一个环境的定义autotolerantpar,它会自动扩大\tolerance\emergencystretch直到不再溢出。

笔记:

  • 我真的不知道它是否会比仅仅使用产生更好的结果\sloppy。请测试。
  • 效率很低。只能用于单个段落。
  • 它会破坏任何花哨的东西,比如垂直模式下的规则或颜色切换,但纯文本应该没问题。
  • 使用\tolstarttolerance\tolmaxtolerance\tolstartemergencystretch、进行调整\tolmaxemergencystretch。参见下文。
  • 公差和紧急拉伸将从开始\tolstarttolerance\tolstartemergencystretch然后简单地加倍,直到不再溢出或达到最大值。

代码如下:

\documentclass{article} 

\usepackage{lipsum}

\usepackage{environ}

\makeatletter
\newcount\tolstarttolerance
\tolstarttolerance200
\newcount\tolmaxtolerance
\tolmaxtolerance9999
\newdimen\tolstartemergencystretch
\tolstartemergencystretch\p@
\newdimen\@tolmaxemergencystretch
\newcommand\tolmaxemergencystretch{3em}
\newif\if@toloverflow
\newif\if@tolabort


\NewEnviron{autotolerantpar}
{%
  \par
  \@tolmaxemergencystretch\tolmaxemergencystretch
  \tolerance\tolstarttolerance
  \emergencystretch\tolstartemergencystretch
  \@tolmakebox
  \loop
   \if@toloverflow
    \@tolaborttrue
    \multiply\tolerance\tw@
    \ifnum\tolerance>\tolmaxtolerance
      \tolerance\tolmaxtolerance
     \else
      \@tolabortfalse
    \fi
    \multiply\emergencystretch\tw@
    \ifdim\emergencystretch>\@tolmaxemergencystretch
      \emergencystretch\@tolmaxemergencystretch
     \else
      \@tolabortfalse
    \fi
    \if@tolabort
      \global\@toloverflowfalse
     \else
      \@tolmakebox
    \fi
  \repeat
  \BODY
  \par
  \ignorespaces
}

\newcommand\@tolmakebox
{%
  \setbox\@tempboxa=%
  \vbox
  {%
    \hbadness=\@M
    \hfuzz=\maxdimen
    \hsize\linewidth
    \BODY
    \par
    \global\@toloverflowfalse
    \loop
      \setbox\@tempboxa=\lastbox
     \unless\ifvoid\@tempboxa
      \setbox\@tempboxa=\hbox to\linewidth{\unhbox\@tempboxa}%
      \ifnum\badness>10000
        \global\@toloverflowtrue
      \fi
      \unskip
      \unskip
      \unskip
      \unpenalty
    \repeat
  }%
}
\makeatother



\begin{document}

\lipsum[1]
\begin{autotolerantpar}
\mbox{somelongtextwhichcantbebroken}
\mbox{somelongtextwhichcantbebroken}
\mbox{somelongtextwhichcantbebroken}
\mbox{somelongtextwhichcantbebroken}
\mbox{somelongtextwhichcantbebroken}
\mbox{somelongtextwhichcantbebroken}
\mbox{somelongtextwhichcantbebroken}
\mbox{somelongtextwhichcantbebroken}
\mbox{somelongtextwhichcantbebroken}
\mbox{somelongtextwhichcantbebroken}
\mbox{somelongtextwhichcantbebroken}
\mbox{somelongtextwhichcantbebroken}
\mbox{somelongtextwhichcantbebroken}
\mbox{somelongtextwhichcantbebroken}
\mbox{somelongtextwhichcantbebroken}
\mbox{somelongtextwhichcantbebroken}
\mbox{somelongtextwhichcantbebroken}
\mbox{somelongtextwhichcantbebroken}
\mbox{somelongtextwhichcantbebroken}
\mbox{somelongtextwhichcantbebroken}
\mbox{somelongtextwhichcantbebroken}
\mbox{somelongtextwhichcantbebroken}
\mbox{somelongtextwhichcantbebroken}
\mbox{somelongtextwhichcantbebroken}
\mbox{somelongtextwhichcantbebroken}
\mbox{somelongtextwhichcantbebroken}
\mbox{somelongtextwhichcantbebroken}
\mbox{somelongtextwhichcantbebroken}
\mbox{somelongtextwhichcantbebroken}
\end{autotolerantpar}
\lipsum[1]

\end{document}

答案2

正如评论中所述,我通常发现\emergencystretch比 效果更好\tolerance。在下面的例子中,即使容差为 9999,也会产生过满的行,容差为 10000 允许段落对齐,但我认为结果不如 令人满意\emergencystretch(尽管两者都很糟糕)。

有一个测试案例,其中容忍度产生更好的结果,这将会很有趣。

在此处输入图片描述

\documentclass{article}




\def\a{OneLongWord and AnotherLongWord CamelCasedWordsLookUgly. }
\def\b{VeryVeryVeryLongUnbreakable WordsInThisParagraph. }
\def\c{\par \noindent X\dotfill X\par\typeout{===}\hyphenchar\the\font=-1 \a\a\a\a\b\a\b\b\a\a\par}

\begin{document}




\c

{\tolerance 9999 \c}

{\tolerance 10000 \c}


{\emergencystretch\hsize \c}

\end{document}

使用提供的示例,我再次认为它\emergencystretch有优势。使用\emergencystrech仍会在日志中产生警告的段落(\tolerance与增加的容忍度不同,默认设置为 9)默默接受)在这两种情况下,设置都不理想,通常有某种方法可以获得更好的间距。在这种情况下,您可以调整url包设置,然后使用默认设置设置段落。我知道您想避免查看此特定段落的细节,但我认为使用更灵活的连字方案(这基本上是 URL 中发生的事情)是一种通用技术,可以替代摆弄空白。

\def\d{\par \noindent X\dotfill X\par
Moreover, this sort of differential equation, in which some sort of force
goes in the opposite direction from what it controls, shows up all over.
Certainly it occurs in many other physics situations (e.g., springs and pendulums, 
as well as the motion of air molecules in sound waves), but also in 
areas like economics and ecology.  I have even seen it applied to 
romance: see \url{http://opinionator.blogs.nytimes.com/2009/05/26/guest-column-loves-me-loves-me-not-do-the-math/}\par}

\begin{document}

\d

{\expandafter\def\expandafter\UrlBreaks\expandafter{\UrlBreaks\do\-}
\Urlmuskip = 0mu plus 2mu
\d}


{\emergencystretch=2em \tolerance=300 \d}

{\emergencystretch=2em \d}

在此处输入图片描述

相关内容