2

I know that \- is already used for hyphenation and inside tabbing. How can I patch this command such that it does something else, but only inside math environments? I tried the following:

\documentclass[12pt, preview]{article}  % standalone, preview, varwidth=10cm
\usepackage[ngerman]{babel}
\usepackage{xparse, blindtext, etoolbox}
\usepackage{blindtext}
\let\hyphen\-\relax
\def\here{XXXXXXXXXXXX}
%\renewcommand{\-}{\relax\ifmmode(my cmd)\else\hyphen\fi\here}
%\renewrobustcmd{\-}{\relax\ifmmode(my cmd)\else\hyphen\fi\here}
\RenewDocumentCommand{\-}{}{\relax\ifmmode(my cmd)\else\hyphen\fi\here}
\begin{document}
a\-b  $a\-b$
\Blindtext
\end{document}

However I observed some weird effects:

  • the \renewcommand and \renewrobustcmd generally yield the same results, but with \RenewDocumentCommand sometimes things go out of margin.

  • when using the standalone class, weird things happen:

    • when using preview option, none of the commands work as intendent and the RenewDocumentCommand version even throws an error ! Argument of \OT1\" has an extra }
    • without preview (remove blindtext) everything works as intended

What the heck is going on?

frougon
  • 24,283
  • 1
  • 32
  • 55
  • I can't test now but beware that \- is robust, so a simple \let\hyphen\- won't do what you probably think. – campa Feb 21 '20 at 10:09
  • Also \protect\def means nothing (in that place \protect is just \relax), maybe you meant \protected\def. – campa Feb 21 '20 at 10:12
  • @campa ok, I changed it for etoolbox's renewrobustcmd. To be honest my knowledge of low level TeX is rather limited. – Hyperplane Feb 21 '20 at 10:19
  • If what you want is a one-character command, the digits are there for use in such a situation. So maybe \0 for the "narrow" minus. – barbara beeton Feb 22 '20 at 00:57

2 Answers2

3

You might do as follows, but I'm not recommending it.

\documentclass[12pt]{article}
\usepackage[ngerman]{babel}
\usepackage{etoolbox}

\makeatletter
\robustify\-
\let\latex@hyphen\-
\renewrobustcmd{\-}{%
  \ifmmode
   (my cmd)%
  \else
   \expandafter\latex@hyphen
  \fi
}
\makeatother

\begin{document}

a\-b

$a\-b$

\end{document}
egreg
  • 1,121,712
  • 1
    Please refresh my memory: this works because \- has been declared by \DeclareRobustCommand, so \robustify replaces the LaTeX protection mechanics by the low-level etex one, and that's why \let works. Or am I as usual completely off? – campa Feb 21 '20 at 10:37
  • 1
    @campa You're right. – egreg Feb 21 '20 at 10:39
  • I guess one could use letltxmacro as an alternative? – frougon Feb 21 '20 at 10:43
  • 1
    @frougon That's more complicated for several reasons. – egreg Feb 21 '20 at 10:44
  • @egreg Can you please tell a bit more? The example appears to work with \LetLtxMacro{\latex@hyphen}{\-}. – frougon Feb 21 '20 at 10:48
  • 1
    @frougon Yes, but not if you use \DeclareRobustCommand\-{...} to renew the definition. – egreg Feb 21 '20 at 10:50
  • @egreg Ah, right. I guess the \LetLtxMacro and \DeclareRobustCommand mechanisms interfere when used on commands with the same name. Thanks for the info. – frougon Feb 21 '20 at 10:56
  • @egreg I actually made a new question regarding this https://tex.stackexchange.com/questions/529433/definitive-way-to-patch-commands – Hyperplane Feb 21 '20 at 13:34
0

I was unhappy with the previous answer, as it doesn't work in all circumstances (e.g. inside tikz-nodes). In a last ditch effort, after trying etoolbox's \appto and variants to no avail, I tried the "brute force" approach: copy paste and edit the source code from the LaTeX2e manual.

% original definition in LaTeX2e
\DeclareRobustCommand{\-}{%
  \discretionary{%
    \char \ifnum\hyphenchar\font<\z@
      \defaulthyphenchar
    \else
      \hyphenchar\font
    \fi
  }{}{}%
  \fi
}

It works like a charm (demo below). The big disadvantage is of course that, should the LaTeX2e source change, the change isn't carried over automatically. This raises the question:

Is there any way in LaTeX to achieve 100% the same behaviour without having to copy paste the source?

EDIT: I posted this a new question: Definitive way to pre- and append code to commands? it seems like there is not (!)

\documentclass[12pt]{article}  % also works in [preview]standalone
\usepackage[ngerman]{babel}
\usepackage{blindtext, tikz}
\usepackage{xparse, etoolbox}
\usepackage{amsmath}
\def\hyphen{\textbf{(hyphen)}}
\def\mycmd{\textbf{(my cmd)}}

\makeatletter
\undef{\-}
\DeclareRobustCommand{\-}{%
  \ifmmode
    \mycmd
  \else
  %\@dischyph%
  \discretionary{%
    \char \ifnum\hyphenchar\font<\z@
      \defaulthyphenchar
    \else
      \hyphenchar\font
    \fi
  }{}{}%
    \hyphen% (just for debugging purpose)
  \fi
}
\makeatother

\begin{document}
\par text\-text 
\par $math\-math$
\par $\text{text inside math \- text inside math}$
\section*{sections: test\-test $math\-math$}
\begin{figure}
\begin{tikzpicture}
\node[draw] at (0,0) {tikz node};
\node[draw] at (6,0) {text\-text $math\-math$};
\end{tikzpicture}
\caption{text\-text $math\-math$}
\end{figure}
\Blindtext
\end{document}
  • the original definition is available as \@dischyph you don't need to copy the code – David Carlisle Feb 21 '20 at 13:54
  • @DavidCarlisle if I do that I get TeX capacity exceeded, sorry [input stack size=5000]. in the provided example. – Hyperplane Feb 21 '20 at 14:09
  • 2
    then you did something wrong (you need to avide using the same internal name for the robust command) But in anycase the strongly recommended solution here is not to patch \- it is much better to use a new name for the new functionality. TeX being a macro expansion language you can rewrite anything at any point but it's a power best avoided if you want the resulting documents to be readable by humans, anyone seeing \- in a tex file (and not having read every line of code in your macro files) will assume that \- means what any tex tutorial says it means. – David Carlisle Feb 21 '20 at 14:13
  • @DavidCarlisle not sure what I did wrong then, all I did was replace the lines \discretionary... up to \hyphen with \@dischyph. Regarding your second point, I don't think anyone will miss hyphenation in math mode, and it will be very obvious what the macro will be doing in the end (a modified minus sign -- hence I really want only a 1 character macro. At the moment I use \p and \m but those are less readable honestly). – Hyperplane Feb 21 '20 at 14:22