允许 Latex 使用破折号连接单词

允许 Latex 使用破折号连接单词

我知道问题是 LaTeX 不会对已经包含连字符的单词进行连字符连接。

可以通过使用提供特殊替换的包来解决这个问题,extdash该替换可以代替连字符,但不会阻止单词被连字符连接。

我现在的问题是,是否有可能让普通连字符以这种精确的方式运行。我不想以特殊的方式编写所有连字符。相反,我希望 LaTeX 自动应用该行为(除非我为此目的使用特殊的连字符命令)。

这是可行的吗?如果可以,该怎么做呢?

答案1

传统的印刷惯例是避免使用连字符连接这样的单词,因此这样的规则被 Knuth 编入了 TeX 程序中。

但是,仍然可以插入允许中断的连字符,方法是欺骗 TeX 认为我们有两个单独的单词(通过插入空的粘连符)。如果我们愿意输入特殊序列(如\Hyphdash或 )而\-/不是连字符,这可以很容易地做到,这正是 等软件包所提供的extdash。但如果我们坚持在 TeX 文件中输入常规连字符,那么“经典”TeX 引擎(即除 LuaTeX 之外的引擎)只提供一种将常规连字符视为其他东西的方法,那就是将 的 catcode 更改-为 active,以便它成为一个扩展为更长内容的宏。但是,只要在-常规文本以外的任何地方使用 ,这都会导致问题,这种情况很常见(请参阅 Steven 的回答中的问题示例)。我想,如果在经典 TeX 世界中存在一个很好的解决方案,那么像 这样的一些软件包extdash就会解决它。

(实际上,有一种非常合理的方法,但由于某种原因,在 TeX 世界中并不十分流行:那就是使用一些“智能”的外部脚本预处理输入文件,仅用\Hyphdash(或其扩展)或其他内容替换常规文本中出现的连字符。但出于某种原因,人们希望在 TeX 内部完成所有操作。)

LuaTeX 允许更广泛地访问 TeX 内部结构,因此很多事情都成为可能,许多 catcode 和宏相关的麻烦也消失了。例如,LuaTeX 有一个hyphenate回调,可用于修改其执行的常规连字操作。此回调获取一个节点列表,我们可以在其中任意插入任意节点(连字符)。这比使用宏执行所有操作要容易得多(很难设置适当的输入,稍后将其扩展为我们需要的输入,而不会受到其他干扰)。甚至还有一个lang.hyphenate函数,我们可以使用它简单地执行常规连字操作。

以下似乎有效:将以下内容放入文件中,例如hyphenateall.lua

function hyphenate_always(head, tail)
   local n = head
   while n do
      if node.type(n.id) == 'glyph' and n.char == string.byte('-') then
         -- Insert an infinite penalty before, and a zero-width glue node after, the hyphen.
         -- Like writing "\nobreak-\hspace{0pt}" or equivalently "\penalty10000-\hskip0pt"
         local p = node.new(node.id('penalty'))
         p.penalty = 10000
         head, p = node.insert_before(head, n, p)
         local g = node.new(node.id('glue'))
         head, g = node.insert_after(head, n, g)
         n = g
      end
      n = n.next
   end
   lang.hyphenate(head, tail)
end

luatexbase.add_to_callback('hyphenate', hyphenate_always, 'Hyphenate even words containing hyphens')

并将其放入\directlua{require('hyphenateall')}您的.tex文件中。


例如(借用 Steven 的回答中的例子):

输出

\documentclass{article}
% Not needed -- used in this example just to show it's not needed :-)
\newcommand\?{\nobreak-\hspace{0pt}}
\begin{document}

\begin{minipage}[t]{0in}
\hbox{Before:} often hungry Works: often\?hungry What about: often-hungry
\end{minipage}\hspace{1in}%
\directlua{require('hyphenateall')}%
\begin{minipage}[t]{0in}
 \hbox{After:} often hungry Works: often\?hungry What about: often-hungry
\end{minipage}

\end{document}

请注意,调用之后\directlua,我们不需要特殊的语法来获取额外的连字符。

答案2

您可以通过更改 的 catcode 来实现此目的-,但这会破坏所有类型的东西,因为-在数学中不仅是破折号,而且还是负号(以及尺寸符号,如\kern-1pt\vspace{-\baselineskip}\rule[-1pt]{1pt}{3pt})。

因此,下面的 MWE 仅仅是一个演示,而不是实际的建议。在 MWE 中显示了两个零宽度minipage,没有然后是 active -

\documentclass{article}
\let\svdash-
{\catcode`-=\active %
\gdef-{\nobreak\svdash\nobreak\hspace{0pt}}
}
\begin{document}
\begin{minipage}[t]{0in}
\catcode`-=12 %
First,
asteroid

Then,
shower

Last,
asteroid-shower
\end{minipage}\hspace{1in}%
\begin{minipage}[t]{0in}
\catcode`-=\active %
First,
asteroid

Then,
shower

Last,
asteroid-shower
\end{minipage}
\end{document}

在此处输入图片描述

因此,更好的方法是(如extdash包中所述)指定一个特殊宏作为这种特殊类型的连字符。在这里我选择\?,结果与之前的 MWE 输出相同:

\documentclass{article}
\newcommand\?{\nobreak-\nobreak\hspace{0pt}}
\begin{document}
\begin{minipage}[t]{0in}
First,
asteroid

Then,
shower

Last,
asteroid-shower
\end{minipage}\hspace{1in}%
\begin{minipage}[t]{0in}
First,
asteroid

Then,
shower

Last,
asteroid\?shower
\end{minipage}
\end{document}

相关内容