Как заставить LaTeX переносить слово, содержащее тире?


107

В документе LaTeX, который я пишу, я получаю предупреждение о переполнении hbox из-за слова «мультидисциплинарный», которое оказывается в конце строки.

Я могу избавиться от этого предупреждения, заменив его на multi-discipli\-nary, но та же проблема возникнет и в другом месте, поскольку это слово часто используется в статье.

Я бы хотел использовать \hyphenation{}вместо этого команду, но, очевидно, мой предварительный \hyphenation{multi-disci-pli-na-ry}вариант не работает, потому что он неправильно понимает первую черту.

Какое заклинание мне нужно, чтобы получить правильный отступ в слове, уже содержащем тире?

Дополнительный вопрос: где я мог сам найти ответ на этот вопрос?


Почему слово сломать на жесткой шумихе - проблема? Разве не "много- \ новая строка"?
Джефф Риди,

1
Бонусный ответ: поиск в Google «латексных переносов» дал всевозможные полезные результаты, включая латексную вики-книгу, в которой есть ответ: en.wikibooks.org/wiki/LaTeX/Formatting#Hyphenation
Mica

3
@mica: нет, это не так. Я прочитал все эти страницы много лет назад. @geoff: было бы нормально, если бы латекс поставил там дефис. но в этом примере это вызовет «неполный ящик», а латекс вообще не переносит дефис.
Gyom

Можете ли вы поставить обратную косую черту на первую в команде \ переноса?
Брайан Постоу,

1
Спасибо за комментарий @DrewSteen. Очевидно, я согласен. Но в свою защиту, когда я задавал эти вопросы, не существовало такого понятия, как tex.SX :-)
Gyom

Ответы:


52

С https://texfaq.org/FAQ-nohyph :

TeX не будет переносить слово, которое уже было перенесено. Например, (карикатурная) английская фамилия Смит-Постлтуэйт не будет переноситься через дефис, что может вызвать проблемы. Это правильный английский стиль набора (он может быть неправильным для других языков), но при необходимости вы можете заменить дефис в имени \hyph командой, определенной

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

Это не то, что обычно рекомендуют в этом FAQ… hyphenatПакет определяет набор таких команд (для введения точек переноса в различные знаки препинания).


Или вы можете \newcommandиспользовать команду, которая расширяется до multi-discipli\-nary(используйте Search + Replace All, чтобы заменить существующие слова).


Большое спасибо. Как я и подозревал, «идеального» ответа не существует. Поскольку я не единственный автор этого документа, я действительно не хочу заставлять других использовать \newcommandвезде (вот почему я искал что-то на основе \hyphenation). Думаю, я просто оставлю его «как есть» по умолчанию и добавлю явные дефисы вручную, когда Latex жалуется на переполнение боксов.
Gyom

63

Проблема (как заметил Кенни) в том, что LaTeX не переносит слова с тире. К счастью, есть стандартный пакет (часть ncctools), который решает именно эту проблему, и называется extdash. Это определяет новые команды дефиса и тире, которые не нарушают расстановку переносов и которые могут разрешать или предотвращать перенос строки в дефисе / тире. Я предпочитаю использовать его с shortcutsопцией, поэтому я могу использовать, например, \-/вместо \Hyphdash. Вот что вам нужно:

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

Чтобы предотвратить разрыв этого дефиса, используйте multi\=/disciplinary

(Кроме того: Чикагское руководство по стилю рекомендует опускать дефисы, прикрепляющие такие аффиксы, как «мульти», если слово без него не является двусмысленным или непонятным.)


Это замечательно, но это дает предупреждение hyperref , когда я использую его в главе строки: Package hyperref Warning: Token not allowed in a PDF string. Там работает другое предложенное решение ( \def\hyph{-\penalty0\hskip0pt\relax}).
Доктор Ян-Филип Герке

1
@ Jan-PhilipGehrcke: эти предупреждения также можно исправить с помощью \texorpdfstring(который обеспечивает условную компиляцию для строк, которые входят в заголовки глав). Я скрываю употребление внутри семантических макросов (здесь, наверное \multidisciplinary). Да не идеально.
Blaisorblade

22

Я использую пакет, hyphenatа затем пишу сложные слова, такие как финское слово Internet-yhteys (англ. Internet connection ) как Internet\hyp yhteys. Выглядит глупо, но кажется самым элегантным способом, который я нашел.


6

multi-disciplinaryне будет переноситься через дефис, как объяснил kennytm. Но multi-\-disciplinaryимеет те же возможности расстановки переносов, что multidisciplinaryи.

Признаюсь, я не знаю, почему это работает. Это отличается от поведения, описанного здесь (выделено мной):

Команда \-вставляет дискреционный дефис в слово. Это также становится единственной точкой, где в этом слове разрешается переносить слова .


Замена -на -\-не меняет вывод, по крайней мере, с настройками по умолчанию на overleaf.com (возможно, pdflatex, но на обороте ничего не сказано).
Camille Goudeseune

4

У меня такая же проблема. Я использую дефис плюс следующий макрос:

\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

Обратите внимание, что здесь используется пакет эксплоре3 из latex3.

Это делает -символ активным, который просматривает вперед, чтобы увидеть, не следует ли за ним еще тире. Если это так, он остается -, чтобы убедиться --и ---продолжить работу. В противном случае он становится \hypкомандой от дефиса, разрешая разрывы слов в остальной части слова. Это универсальное решение, при котором все слова, содержащие явные дефисы, переносятся как обычно.

Обратите внимание, что это -становится макросом, который нельзя полностью раскрыть, поэтому попробуйте включить его после загрузки других пакетов, которые не могут -быть макросом.

Изменить: это моя вторая версия, первая версия была менее надежной, если после дефиса был {или }. Этого нет, но, в отличие от первой версии, -в этой версии нельзя полностью расширить.


3
multi\hskip0pt-\hskip0pt disciplinary

Например, вы можете определить как

\def\:{\hskip0pt}

а затем напишите

multi\:-\:disciplinary

Обратите внимание, что в пакете русского языка babel есть собственный набор дефисов, который не запрещает расстановку переносов, например "~(двойные кавычки + тильда).


1
Должно быть multi-\hskip0pt disciplinary. Как и в вашем MWE, он слишком сильно раздувается. Просто установите \setlength{\textwidth}{0.1cm}, чтобы попробовать это.
LaRiFaRi

-3

Я ответил примерно так: LaTeX разбивает слишком много слов

Я сказал:

вы должны установить штраф за перенос где-нибудь в преамбуле:

\hyphenpenalty=750

Значение 750 соответствовало моим потребностям в макете из двух столбцов на бумаге формата Letter (8,5x11 дюймов) с шрифтом 12 pt. Отрегулируйте значение в соответствии со своими потребностями. Чем выше число, тем меньше переносов будет. Вы также можете взглянуть на пакет дефисов, он обеспечивает немного больше, чем просто штраф за перенос


1
Он спрашивает, как избежать дефисов, а не о том, как определить пределы.
Андрас Дьомрей

-4

Чтобы избежать переноса в слове, уже написанном через дефис, я использовал неразрывный пробел ~в сочетании с обратным пробелом \!. Например, команда

3~\!\!\!\!-~\!\!\!D

используется в тексте, не переносить перенос в слове 3-D. Наверное, не лучшее решение, но у меня оно сработало!


4
Это ответ на вопрос, противоположный заданному. Кроме того , как человек , который пытался изменить свой пост в точку , что из указанных, есть гораздо лучший способ сделать то , что вы сделали: \mbox{3-D}.
zwol
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.