# Apply lefthyphenmin to parts of a word spelled with hyphens

In German, there are some words that have a single letter separated with a hyphen, for example "E-Ink-Display", "E-Auto" (electric car), "E-Mail", "x-Achse" (x-axis) and many more. When hyphenating these, the single letter must not be split up.

Is there a way (maybe with \lefthyphenmin) to apply this rule globally without having to use \nobreakdash or similar everytime such a word is used?

MWE:

\documentclass{article}
\usepackage{showframe}
\usepackage[american,ngerman,shorthands=off]{babel}
\usepackage{amsmath}
\begin{document}
xxxxx xxxxx xxxxxxxxx xxxx xxxx xxx xxxxx xxxxxxxx xxxxxx xxxxx E-Auto

should look like this:

xxxxx xxxxx xxxxxxxxx xxxx xxxx xxx xxxxx xxxxxxxx xxxxxx xxxxx E\nobreakdash-Auto
\end{document}


• What's the reason for shorthands=off? Jul 23 '20 at 12:27
• @egreg I use lualatex and enter specials characters directly. The quote as an active character causes too many issues with tikz, minted and other packages. Jul 23 '20 at 12:40

As you are using babel with luatex, you can use \babelposthyphenation:

\usepackage[american,ngerman,shorthands=off]{babel}

\babelposthyphenation{ngerman}{ ^().=() }
{ {},
{ pre=-, no=-, penalty=10000 }
}


See Non–standard hyphenation with luatex for further info. Here I used the trick to limit the capture, because the ^ (word start) must be outside. It works with more or less straight texts (eg, no whatsits in the middle of a word). . is any char and = is an explicit hyphen. Perhaps the pattern can be fine tuned and ‘any char’ is not the best option, but it can be replaced by a list of chars.

EDIT. Here is a better pattern:

\babelposthyphenation{ngerman}{ ^{A}*(){a}=() }


With {A}* we consider the possibility of leading characters like ( or “, because {A} means ‘non-letter’ (it's the same as %A in lua). This part is placed before that to be processed, which is enclosed between () ().

• It would probably be good to replace . (matches "any character") with the equivalent of Lua's %a (match a "single alphabetical character").
– Mico
Jul 23 '20 at 15:06
• @Mico Yes, indeed, or even as I said with a list of chars. To ease defining patterns without having to deal with catcodes, in this context %a is entered {a}. But I'll edit it (not right now). Jul 23 '20 at 16:52
• This works really well and feels like the best solution to me. I just had to be careful to load \RequirePackage[ngerman=ngerman-x-latest]{hyphsubst} before this command. Jul 24 '20 at 9:52

Since you use LuaLaTeX, you can (a) set up a Lua function that replace all instances of <single alphabetical character>-<letter character(s)> with <single alphabetical character>\nobreakdash-<letter character(s)> and (b) assign the function to LuaTeX's process_input_buffer callback. That way, it'll act like a preprocessor on the input code, before TeX starts its usual processing.

(The framelines in the preceding screenshot are drawn by the showframe package.)

\documentclass{article}
\usepackage{showframe}
\usepackage[american,ngerman,shorthands=off]{babel}
\usepackage{amsmath} % for "\nobreakdash" macro

\usepackage{luacode} % for 'luacode' environment
\begin{luacode}

function nbdash ( s )
return ( s:gsub ( "(%A%a)%-(%a+)" , "%1\\nobreakdash-%2" ) )
end
luatexbase.add_to_callback ( "process_input_buffer" , nbdash , "nbdash" )

\end{luacode}

\begin{document}
xxxxx xxxxx xxxxxxxxx xxxx xxxx xxx xxxxx xxxxxxxx xxxxxx xxxxx E-Auto

xxxxx xxxxx xxxxxxxxx xxxx xxxx xxx xxxxx xxxxxxxx xxxxxx xxxxx x-Achse
\end{document}


Use U+2011 NON-BREAKING HYPHEN

\documentclass{article}
\usepackage{showframe}
\usepackage[american,ngerman,shorthands=off]{babel}
\usepackage{amsmath}
\begin{document}

xxxxx xxxxx xxxxxxxxx xxxx xxxx xxx xxxxx xxxxxxxx xxxxxx xxxxx E^^^^2011Auto

xxxxx xxxxx xxxxxxxxx xxxx xxxx xxx xxxxx xxxxxxxx xxxxxx xxxxx E‑Auto

should look like this:

xxxxx xxxxx xxxxxxxxx xxxx xxxx xxx xxxxx xxxxxxxx xxxxxx xxxxx E\nobreakdash-Auto

\end{document}


• Is there any way to get this effect without changing every usage? Jul 23 '20 at 13:01