3

I am trying to avoid hyphenation over odd pages, and I would like to do it manually: forbid hyphenation of some words.

When I embrace the hyphenated word in \hbox, some other adjacent word after re-compilation gets hyphenated, so I need to re-run the compiler several times.

\hyphenpenalty and other penalties work for the whole paragraph, but I want to forbid breaking of just several adjacent words.

I know I can embrace every word in \hbox, but is there any other option?

Mico
  • 506,678
pantlmn
  • 1,366
  • 8
  • 17

2 Answers2

4

Here's a LuaLaTeX-based solution. It consists of (i) a Lua function that encases each word in its argument in an \mbox{...} "wrapper" to make it un-hyphenatable, while still allowing line breaks between words, and (ii) a LaTeX macro named \nohyph that invokes the Lua function. The argument of the LaTeX macro should be the string of consecutive words that mustn't be hyphenated.

enter image description here

% !TEX TS-program = lualatex
\documentclass{article}
\usepackage{luacode}
\begin{luacode}
function nohyph ( x )
   x = string.gsub ( x , "%a+", "\\mbox{%0}" )
   return ( tex.sprint (x) )
end
\end{luacode}
\newcommand\nohyph[1]{\directlua{nohyph(\luastring{#1})}}

\usepackage[textwidth=1mm]{geometry} % set an extremely narrow measure
\setlength\parindent{0pt}

\begin{document}
useful handful helpful
---
\nohyph{useful handful helpful}
\end{document}
Mico
  • 506,678
3

You could enclose every entity separated by a space in an \mbox in an automated fashion. I defined the macro \nohyphen which does exactly that.

\nohyphen{list of words} -> \mbox{list} \mbox{of} \mbox{words}

This also means, that to protect spaces you have to wrap the relevant entry in braces, as in {$a = b$}. Otherwise this would also be split at the spaces an chaos ensues.

\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn

\seq_new:N \l_pantlmn_words_seq

\cs_new_protected:Npn \pantlmn_nohyphens:n #1
 {
  \seq_set_split:Nnn \l_pantlmn_words_seq { ~ } { #1 }
  \seq_map_inline:Nn \l_pantlmn_words_seq
   { \mbox { ##1 } ~ }
  \tex_unskip:D
 }

\NewDocumentCommand \nohyphen { m }
 {
  \pantlmn_nohyphens:n { #1 }
 }

\ExplSyntaxOff
\begin{document}
\fbox{%
  \parbox{2em}{%
    overly longish dictionary words {$a = b$}
  }%
}
\quad
\fbox{%
  \parbox{2em}{%
    \nohyphen{overly longish dictionary words {$a = b$}}
  }%
}
\end{document}

enter image description here

Alternative

You can also add words to a list, which should not be hyphenated, when enclosed in \nohyphen. I borrowed the example words from Mico's answer for this. You can add words in a comma separated list via \addnohyphen. This way you don't need to enclose formulas in braces. On the other hand, this solution is only practical if you want to suppress hyphenation for a few words only.

The leading x is there merely to allow hyphenation of useful, because TeX prohibits hyphenation for the first word of a paragraph.

\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn

\seq_new:N \l_pantlmn_words_seq
\tl_new:N \l_pantlmn_nohyphen_tl

\cs_new_protected:Npn \pantlmn_nohyphens:n #1
 {
  \seq_set_split:Nnn \l_pantlmn_words_seq { ~ } { #1 }
  \seq_map_inline:Nn \l_pantlmn_words_seq
   {
    \str_case:nVTF { ##1 } \l_pantlmn_nohyphen_tl
     { \mbox { ##1 } ~ }
     { ##1 ~ }
   }
  \tex_unskip:D
 }

\cs_new_protected:Npn \pantlmn_add_nohyphen:n #1
 {
  \clist_map_inline:nn { #1 }
   {
    \tl_gput_right:Nn \l_pantlmn_nohyphen_tl { { ##1 } { } }
   }
 }

\NewDocumentCommand \nohyphen { m }
 {
  \pantlmn_nohyphens:n { #1 }
 }

\NewDocumentCommand \addnohyphen { m }
 {
  \pantlmn_add_nohyphen:n { #1 }
 }

\ExplSyntaxOff
\begin{document}
\addnohyphen{useful,handful}

\fbox{%
  \parbox{1em}{%
    x useful handful helpful {$a = b$}
  }%
}
\quad
\fbox{%
  \parbox{1em}{%
    x \nohyphen{useful handful helpful $a = b$}
  }%
}
\end{document}

enter image description here

Henri Menke
  • 109,596