# How to redefine infix (binary, relational) operator spacing so that precedence can be communicated visually?

Assume we have an infix binary operator * with precedence level 0 (highest precedence), and another infix binary operator @, with precedence level 1 (lower than *). Also, assume we have two relational operators ~ (precedence level 2) and ~ (precedence level 3).

Note: the symbols I have chosen don't matter, I am trying to select arbitrary ones, because I might need to define arbitrary operators in my use case.

An expression involving these operators should look something like this:

a*b @ c*d ~ a*b || a*b ~ c @ d

The spaces in this expression match up with the precedence level (0 spaces for precedence level 0, and so on).

I'd like to do something similar in LaTeX by defining operators with a command that looks something like this:

\precedenceop{<relational or binary operator?>}{<precedence level>}{<symbol>}

I have learned today that:

• \medmuskip controls spacing for binary operators, \thickmuskip for relational operators

• I can use the xstring package to deal with conditional cases

So I envision that my command would look something like:

\usepackage{amsmath}
\usepackage{xstring}

\newcommand{\precedenceop}[3]{%
\IfEqCase{#1}{%
{rel}{<do stuff with \thickmuskip using #2 (the precedence level) and #3 (the symbol)>}%
{bin}{<do stuff with \medmuskip using #2 (the precedence level) and #3 (the symbol)>}%
}[\PackageError{tree}{Undefined option to tree: #1 (should be rel or bin)}{}]%
}


Another question I made attempted to go about the problem a different way, and had a suggested solution of manipulating the skips using something like:

\mspace{-\muexpr\medmuskip/2}
<symbol, #3>
\mspace{-\muexpr\medmuskip/2}


But it would be nicer if the 2 in this solution could be replaced by some function of #2 (preferably, some type of multiplication, because then 0 would map to 0mu, 1 could map to 2mu, and 2 could map to 4mu, and so on).

Anyway, how should I make the pieces come together properly to do what I'd like?

• are you interested into parsing the expression to add parentheses automatically according to the precedence levels encountered?
– user4686
Sep 19, 2017 at 10:08
• @jfbu not so much, since I want to the precedence to be communicated somewhat without parentheses -- so, those would only be used manually, when they have to be used for whatever reason Sep 19, 2017 at 16:52
• ok! the most powerful thing would be to parse the expression to convert it into some abstract tree of evaluations. How much are your problems TeX related? For example, using TeX math mode with various spacing is indeed nice as demonstrated by David C., but when you copy paste from PDF I don't know if you get anything usable. (I just tried from Skim to Emacs buffer and spaces are there (I was surprised) but the || is gone). Thus a pure-ascii manipulation could prove more usable than TeX typesetting which is basically final thing. (I get control characters when copying from Acrobat)
– user4686
Sep 19, 2017 at 17:04
• @jfbu I am not sure I totally understand. I don't really have a need to copy from the PDF to a text document, so I don't know if I mind if the copy/paste does not work. Usually, the copy-paste does not work well for me from PDF even on normal documents, or on non-TeX generated PDFs? Sep 19, 2017 at 17:09
• I don't know exactly your aims, hence please excuse if I am off the mark. I was just commenting that the approach as in @DavidCarlisle's post is a final one from which you can't do much afterwards. Imagine you decide you want to draw nested boxes around operands, then relying on TeX math mode analysis will not help. You need some pre-analysis for more control, that's all I am trying to convey.
– user4686
Sep 19, 2017 at 17:38

\documentclass{article}

\newcommand\declareop[3]{%
\newcommand#1{%
\mskip\muexpr\medmuskip*#2\relax
{#3}%
\mskip\muexpr\medmuskip*#2\relax
}}

\declareop\mytimes{0}{*}
\declareop\myat{1}{@}
\declareop\mysim{2}{\sim}
\declareop\myor{3}{\|}

\begin{document}

$a\mytimes b \myat c\mytimes d \mysim a\mytimes b \myor a\mytimes b \mysim c\myat d$
\end{document}


this uses muskip expressions to multiply the base \medmuskip value by the precedence integer scaling the stretch and shrink by the same amount. The original symbol is surrounded by {} (as {#3} in the definition) so that it is converted to a mathord and loses any spacing rules that it would have by default, so just gets the space specified here.