12

With your help, I have figured out how to replace + or - in math mode with a custom macro: How can I make every occurrence of `+` and `-` be replaced by a macro, but only in math mode?

Now, I need to extend this by replacing only binary - (e.g. x-y or x - y), but not unary - (e.g. x + -x or -z). Thus, I need to, in some sense, test to see whether a - is unary, or binary, which is what TeX does anyway when figuring out spacing around -.

So how does TeX do it?

  • 4
    Interesting question. TeX decides whether - has unary or binary spacing depending on the surrounding atoms. You can find a table covering all possible cases in the TeXbook on page 170 and in TeX by topic (screenshot). You could register a LuaTeX callback in mlist_to_hlist which walks the nodes, detects binary minus, and replaces it (only node, no macro). – Henri Menke Sep 19 '17 at 5:31
  • 1
    I would just use separate macros for \unaryminus and \binminus given your other spacing requirements. – David Carlisle Sep 19 '17 at 9:11
  • @DavidCarlisle I think the OP wants to keep + and - made math active. – user4686 Sep 19 '17 at 9:21
  • 1
    @jfbu I know but see earlier questions, OP has already disabled all the automatic math spacing and inserted custom spacing based on operator precedence, doing that while allowing the automatic switching of \mathbin to \mathord is probably too fragile to be worth it. – David Carlisle Sep 19 '17 at 9:49
  • 1
    you're going to have to do something manual. a quick-and-very-dirty approach might be to wrap braces around any unary plus or minus. as already pointed out, you have obliterated the information that tex needs to tell the difference. – barbara beeton Sep 19 '17 at 14:36
13

There are six basic atom types: Ord, Op, Bin, Rel, Open, Close and Punct. There are other atom types, but they're treated like Ord ones as far as spacing is concerned (a somewhat special case is Inner).

An atom of type Bin is turned into Ord if it isn't surrounded on both sides by atoms compatible with its nature. The following table shows what happens when the atom to the right of the Bin (here +) is an Ord; there are 36 possible combinations, you can try the other 30. For instance, “Ord Bin Open” is the counterpart of “Close Bin Ord”, where the Bin remains such, like also in “Close Bin Open”.

\baselineskip=1.2\baselineskip

\halign{#\unskip\hfil &\qquad #\unskip\hfil\cr
  $x+a$    & Ord Bin Ord   \cr
  $\sum+a$ & Op Bin Ord    \cr
  $++a$    & Bin Bin Ord   \cr
  $=+a$    & Rel Bin Ord   \cr
  $(+a$    & Open Bin Ord  \cr
  $)+a$    & Close Bin Ord \cr
  $,+a$    & Punct Bin Ord \cr
}

\bye

Compile with pdftex.

enter image description here

As you see from the picture, only in lines 1, 3 and 6 the middle + behaves like a binary operator, in the other lines it becomes an Ord.

Note also that a trailing Bin will always be treated like an Ord (say when you type \lim_{x\to0-}, because it has nothing after it, similarly to a leading one, like in $-1$.

This is not available at the macro level and is decided upon at a deep stage when TeX is interpreting a math list for later transforming it into a horizontal list.

6

I know this does not answer the question, but my comment turned out too long.

For a + or - to decide if it is binary or unary it must get information from what was before it. Compare 1-3 with 1^{-3} or even 1\times-3. How can you achieve that at macro level? It is impossible if only + and - are macros. Basically you would need a parser of the whole math expression. To start with, the math mode may end with $ or \) or \] or $$ or \end{equation} or \end{align} etc... thus you will have to go for something like <start of math>\PARSE{....}<end of math> input, or hack very deep into $. Of course math-engines like l3fp know how to distinguish a unary minus from a binary one, but you have to write a full parser for that, and the math expressions they handle are not quite the same as the math TeX can typeset. Thus at macro level it is very difficult, and not feasible from having only + and - converted to macros.

The math list atoms manipulated by TeX are not accessible at macro level (I don't think e-TeX \lastnodetype would help much).

However as per @HenriMenke's comment you may use LuaTeX's callbacks.

  • from tex.stackexchange.com/questions/391885/… it appears the OP has a starting point which isn't actually TeX math mode expression. So probably the question is better addressed at this starting point... – user4686 Sep 19 '17 at 10:07
  • The only look-ahead math primitive I know (not even recommended for use in LaTeX) is \over. And I don't see any way to adapt that to the current problem. – Steven B. Segletes Sep 19 '17 at 12:56

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.