如何让LaTeX在包含破折号的单词上进行连字符划分?

128

在我正在编写的LaTeX文档中,由于单词“multi-disciplinary”恰好出现在行末,因此我收到一个overfull hbox警告。

我可以通过将其更改为multi-discipli\-nary来消除此特定警告,但由于该单词在论文中经常使用,同样的问题也会在其他地方发生。

我想使用\hyphenation{}命令,但显然我的尝试\hyphenation{multi-disci-pli-na-ry}不起作用,因为它不能正确理解第一个短横线。

我需要哪种咒语才能在已包含破折号的单词中获得正确的缩进?

额外问题:我在哪里可以找到自己的答案?


1
额外答案:在谷歌搜索“latex断字”可以得到各种有用的结果,包括LaTeX维基书中的答案:http://en.wikibooks.org/wiki/LaTeX/Formatting#Hyphenation - Mica
5
@mica:不,它没有。我几年前就读过所有那些页面。@geoff:如果latex在这里断字会很好,但在这个例子中会导致“未满箱 hbox”,因此latex选择不断字。 - Gyom
1
这个问题似乎与Latex有关,应该迁移到tex.stackexchange.com。 - Drew Steen
3
谢谢您的评论,@DrewSteen。显然我同意。但是为了辩护一下,当我提出这些问题时,还没有tex.SX这样的东西 :-) - Gyom
哦,我完全明白。这实际上是与StackExchange迁移系统相关的自动评论。 - Drew Steen
显示剩余3条评论
10个回答

75

问题(如KennyTM所指出)是LaTeX不会对带有破折号的单词进行连字处理。幸运的是,有一个标准包(ncctools的一部分)可以解决这个问题,称为extdash。它定义了新的连字和破折号命令,不会破坏连字,并允许或阻止在破折号处换行。我喜欢将其与shortcuts选项一起使用,以便我可以使用例如\-/而不是\Hyphdash。以下是您想要的:

\usepackage[shortcuts]{extdash} ... multi\-/disciplinary

为了避免在连字符处断开,使用multi\=/disciplinary (顺便说一句:《芝加哥风格手册》建议删除像"multi"这样的词缀的连字符,除非没有它这个单词就不明确或不可理解。)

这很不错,但是当我在章节字符串中使用时,它会产生一个超链接警告:Package hyperref Warning: Token not allowed in a PDF string。此时,另一个提议的解决方案(\def\hyph{-\penalty0\hskip0pt\relax})可行。 - Dr. Jan-Philip Gehrcke
3
@Jan-PhilipGehrcke:这些警告也可以使用\texorpdfstring进行修复(它为进入章节标题的字符串提供条件编译)。我将使用隐藏在语义宏中(这里可能是\multidisciplinary)的用法。是的,它并不完美。 - Blaisorblade

55

以下内容来自https://texfaq.org/FAQ-nohyph:

TeX不会给已经连字符化的单词再次添加连字符。例如,“Smyth-Postlethwaite”这个(讽刺)英国姓氏就不会被连字化,这可能会引起麻烦。虽然这是正确的英语排版风格(对于其他语言而言可能不正确),但是如果必须这样做,您可以使用\hyph命令替换名称中的连字符。

 \def\hyph{-\penalty0\hskip0pt\relax}

这不是通常情况下此FAQ建议的内容... hyphenat软件包定义了一组这样的命令(用于在各种标点符号处引入连字符)。


或者你可以使用\newcommand新建一个命令,该命令会扩展为multi-discipli\-nary(使用“查找 + 替换所有”替换现有单词)。


非常感谢。正如我所怀疑的那样,没有“完美”的答案。因为我不是那个文档中唯一的作者,我不想强迫其他人在每个地方都使用\newcommand(这就是我寻求基于\hyphenation的东西的原因)。我想我会默认保持它“原样”,并在Latex抱怨过度填充hboxes时手动添加显式连字符。 - Gyom

28
我使用软件包hyphenat,然后像芬兰词汇Internet-yhteys(英文Internet connection)这样写复合词,格式为Internet\hyp yhteys。看起来很滑稽,但似乎是我发现的最优雅的方法。

6

multi-disciplinary 不需要连接符号,如kennytm所解释的那样。但是 multi-\-disciplinarymultidisciplinary 具有相同的连字号使用机会。

我承认我不知道为什么这样可以。这与此处描述的行为不同(重点是我的):

命令\-在单词中插入一个自动换行符。这也成为该单词中允许断字的唯一时刻


2
将“-”替换为“--”不会改变输出结果,至少在overleaf.com的默认设置下是如此(可能是pdflatex,但overleaf实际上并没有说明)。 - Camille Goudeseune

5
multi\hskip0pt-\hskip0pt disciplinary

您可以例如定义为

\def\:{\hskip0pt}

然后编写

multi\:-\:disciplinary

注意,babel俄语语言包具有其自己的一组破折号,不会禁止连字,例如"~(双引号+波浪符)。

1
应该是“多学科的”。就像你的MWE一样,它会过度使用连字符。只需设置\setlength{\textwidth}{0.1cm}以尝试。 - LaRiFaRi

5

我也遇到过同样的问题。我使用hyphenat加上以下宏:

\RequirePackage{hyphenat}
\RequirePackage{expl3}


% The following defs make sure words that contain an explicit `-` (hyphen) are still hyphenated the normal way, and double- and triple hyphens keep working the way they should. Just don't use a `-` as the last token of your document. Also note that `-` is now a macro that is not fully expandable

\ExplSyntaxOn

% latex2e doesn't like commands starting with 'end', apparently expl3 doesn't have any problems with it
\cs_new:Npn \hyphenfix_emdash:c {---}
\cs_new:Npn \hyphenfix_endash:c {--}

\cs_new:Npn \hyphenfix_discardnext:NN #1#2{#1}


\catcode`\-=\active

\cs_new_protected:Npn -{
    \futurelet\hyphenfix_nexttok\hyphenfix_i:w
}

\cs_new:Npn \hyphenfix_i:w {
    \cs_if_eq:NNTF{\hyphenfix_nexttok}{-}{
        %discard the next `-` token
        \hyphenfix_discardnext:NN{\futurelet\hyphenfix_nexttok\hyphenfix_ii:w}
    }{
        % from package hyphenat
        \hyp
    }
}

\cs_new:Npn \hyphenfix_ii:w {
    \cs_if_eq:NNTF{\hyphenfix_nexttok}{-}{
        \hyphenfix_discardnext:NN{\hyphenfix_emdash:c}
    }{
        \hyphenfix_endash:c
    }
}


\ExplSyntaxOff

请注意,这个方法使用了来自latex3的expl3 包。它将“-”字符变成一个主动字符,用于向前扫描以查看它后面是否跟着更多的破折号。如果是这样,它仍然是一个“-”,以确保“--”和“---”继续工作。如果没有,它就变成了来自hyphenat的\hyp 命令,从而使剩下单词中的断字生效。这是一种通用的解决方案,使包含显式连字号的所有单词都能正常换行。
请注意,“-”会变成一个不完全可扩展的宏,因此请尝试在加载其他可能不希望“-”成为宏的软件包之后再包含它。
编辑:这是我的第二个版本,第一个版本在破折号后跟随“{”或“}”时不太健壮。这个版本不会出现这种情况,但与第一个版本不同,这个版本中的“-”不是完全可扩展的宏。
编辑2:我用于修复这个问题的模块最终演变成了以下形式。由于我不再使用LaTeX,并且已经超过10年没写过这个,所以我不知道以下内容是否仍然有效。购买者自负!
\RequirePackage{hyphenat}
\RequirePackage{expl3}


% The following defs make sure words that contain an explicit `-` (hyphen) are still hyphenated the normal way, and double- and triple hyphens keep working the way they should. Just don't use a `-` as the last token of your document. Also note that `-` is now a macro that is not fully expandable

% The original hyphen is available as the \hp command.

\ExplSyntaxOn

\cs_new:Npn \hp {-}

% make hyphen the normal character
\cs_new:Npn \hyphenfixdisabled {
  \catcode`\-=12\relax
}


\cs_new:Npn \hyphenfix_emdash:c {---}
\cs_new:Npn \hyphenfix_endash:c {--}

\cs_new:Npn \hyphenfix_discardnext:NN #1#2{#1}

\cs_new:Npn \hyphenfix_ignore:c {-}


\catcode`\-=\active


%Making hyphen an active character throughout a document can lead to unexpected errors, especially if it is being edited by multiple persons. This note command at the beginning of what will be the meaning of `-' will hopefully help diagnose errors resulting from hyphen behaving unexpectedly.
\catcode`\!=11
\catcode`\.=11

\let \Note:hyphen_is_an_active_character!_see_hyphenfix.tex! \relax

\cs_new_protected:Npn \hyphenfix_fixhyphen:w{
    \if_mode_math:
        \hp
    \else: \use_i_after_fi:nw {
        \Note:hyphen_is_an_active_character!_see_hyphenfix.tex!
        \futurelet\hyphenfix_nexttok\hyphenfix_i:w
        }
    \fi:
}
\catcode`\!=12
\catcode`\.=12

\cs_new:Npn \hyphenfix_i:w {
    \cs_if_eq:NNTF{\hyphenfix_nexttok}{-}{
        %discard the next `-` token
        \hyphenfix_discardnext:NN{\futurelet\hyphenfix_nexttok\hyphenfix_ii:w}
    }{
        % from package hyphenat
        \hyp
    }
}

\cs_new:Npn \hyphenfix_ii:w {
    \cs_if_eq:NNTF{\hyphenfix_nexttok}{-}{
        \hyphenfix_discardnext:NN{\hyphenfix_emdash:c}
    }{
        \hyphenfix_endash:c
    }
}

\cs_new:Npn \hyphenfixenable {
  \catcode`\-=\active
  \let-\hyphenfix_fixhyphen:w
}
\cs_new:Npn \hyphenfixdisable {
  \let-\hyphenfix_ignore:c
  \catcode`\-=12\relax
}

\catcode`\-=12\relax

\ExplSyntaxOff

抱歉,似乎在宏“/futurelet”上引发了一些错误。 - Peterlits Zo
1
@PeterlitsZo 抱歉,这段代码已经超过10年了。我很久没有使用LaTeX了,所以现在这段代码对我来说几乎是无法理解的。它曾经在我那个时候为我工作过。我附上了我的代码最后一个版本,也许可以帮助你。 - JanKanis

1

用于 Cyrillic 的babel宏包定义了命令"=,应该使用它来代替破折号: 因此, 你可以写по"=своєму,并且它会正确地断字。

然而,对于英语,该命令"=未定义。您可以按照以下方式定义它

\useshorthands{"}
\defineshorthand{"=}{\penalty1000\discretionary{-}{}{-}\penalty10000\hskip0pt}

然后,pseudo"=metric将被正确地断字。实际上,这是从这里得到的答案:https://tex.stackexchange.com/questions/99334/hyphenation-of-words-connected-with-a-double-triple-dash,建议使用组合符号"|。使用"=的好处是,它现在可以在多语言文档中工作,当您同时拥有西里尔字母和英语时,并且与仅具有西里尔字母的文档兼容。

-1

由于Latex认为multi-disciplinary是一个单词并且有首选连字符,你可以说明这是两个不同的单词。例如:multi-\hspace{0pt}disciplinary就足以解决此问题。


1
这不就是和 https://dev59.com/83I95IYBdhLWcg3wsQL9#8075536 基本上一样吗? - samcarter_is_at_topanswers.xyz

-2

我在这里回答了类似的问题:LaTeX breaking up too many words

我的回答是:

你应该在导言区设置连字符惩罚值:

\hyphenpenalty=750

750的值适合我在信纸(8.5x11英寸)上使用12 pt字体的两列布局需求。根据您的需求调整该值。数字越高,连字符就越少。您可能还想看一下hyphenat包,它提供了比只有连字符惩罚更多的功能。


1
他在询问如何避免使用连字符,而不是关于如何定义限制的问题。 - Andras Gyomrey

-3
为了避免连字号在已经有连字符的单词中断,我使用了不间断空格~与反向空格\!的组合。例如,命令
3~\!\!\!\!-~\!\!\!D

在文本中使用时,抑制单词3-D中的连字号。这可能不是最好的解决方案,但对我起作用了!


5
这是对相反问题的回答。同时,正如试图编辑您的帖子并指出的那样,有一种更好的方法可以完成您所做的事情:\mbox {3-D} - zwol

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接