[Tex/LaTex] babel shorthand “| doesn’t work in macros

babelligaturesmacrosshorthands

The package babel with the ngerman option (and most other languages as well, but not english) provides the shorthand "|, which prevents a ligature at the given position (see p. 81 of the babel documentation, e.g. Auf"|lage will result in the word Auflage without an fl-ligature (as is desired because, in German, you don't want ligatures across morpheme borders).

However, when placed in a macro, "| doesn't work anymore. Why is this and how can I circumvent it?

\documentclass{article}

%\usepackage[T1]{fontenc}% doesn't help
\usepackage[ngerman]{babel}

\newcommand{\foo}{"|}

\begin{document}

ff

f"|f

f\foo f

\end{document}

output of above code

Best Answer

It works if you switch the shorthand on before defining the command, or if you define the command after \begin{document} when shorthands are active.

As Joseph commented, it's recommendable to switch it off immediately afterwards, so that the active shorthand doesn't affect other commands.

\documentclass{article}
\usepackage[ngerman]{babel}
\shorthandon{"}
\newcommand{\foo}{"|}
\shorthandoff{"}
\begin{document}
ff

f"|f

f\foo f
\end{document}

example output

Alternatively, you could switch it on locally within the macro definition, similar as written here by egreg, and made robust, so it can be used within moving arguments, such as \chapter and \section headings and captions.

\DeclareRobustCommand{\foo}{\shorthandon{"}\scantokens{"|\endinput}}

However, it might be useful to have a part in the preamble where shorthands are active, as in the first solution, so you can use them in your commands such as in text arguments to macros.