Is there a way to track which part of the input text maps to the output elements/svg?

77 views
Skip to first unread message

FAbad

unread,
Feb 19, 2025, 12:15:16 PM2/19/25
to MathJax Users
Hi!

I'm just curious if MathJax has an intermal mapping of the tex that generated a specific dom node, or if there's a way to hook to MathJax/parse the output to get the corresponding input tex for a given output, short of tagging the input tex with something like \cssId? The use case I'm thinking of is to have something like: when editing tex with a live preview, hovering/clicking on a specific mathjax dom output would place the cursor on the line of tex that generated that clicked output.

Thank you!

Murray

unread,
Feb 21, 2025, 4:55:46 AM2/21/25
to MathJax Users
Hello FABad

Davide will no doubt have a more sophisticated way of going about this, but the following demo is a rough start for what you're trying to do.

It's a proof of concept, and works for things like numbers and variables (a...z), and some symbols like square root and integral, but not for Greek letters or no doubt many other math entities.

It works by identifying the content of the clicked math item, then finding what's the index of that item (it could be say, the third 'x" in the expression), then goes looking for the 3rd "x" in the text box, and puts the cursor there.

It falls over for things like "sin" since if you click on the "i" it will find the first "i" in the text box, not the first "\sin".

But if you really need something that moves the cursor to the appropriate part of the input expression, it could be a starting point for you.

Here's the demo:


Hope it helps
Regards
Murray

Davide Cervone

unread,
Feb 25, 2025, 10:45:51 AM2/25/25
to mathja...@googlegroups.com
FABad:

Murray's solution is very interesting, and may be what you are looking for.  I read your request slightly differently, which was that you wanted to click on a typeset expression and get back the original TeX code for that expression, not the individual TeX command that produced the character you clicked on, which is what Murray's code tries to do.

If that is what you want, then you can use the configuration

MathJax = {
  options: {
    renderActions: {
      clickTex: [175,
        (doc) => {for (const math of doc.math) MathJax.config.clickTex(math)},
        (math, doc) => MathJax.config.clickTex(math)
      ]
    }
  },
  clickTex(item) {
    item.typesetRoot.addEventListener('click', (event) => alert(item.math));
  }
}

to provide for that.  This adds an action to MathJax's list of render actions that comes after the typesetting has been performed (the 175 places it after typesetting at 150), and adds a click event handler to the typeset output.  The event handler simply puts up an alert with the original TeX code, but you can replace that alert with whatever action you need to take.  It is not clear to me how you want to map this back to your original document without some kind of identification for the individual equation, since there could be two copies of the identical equation, so this doesn't tell you which one it is.  Your editor could wrap the equation in a tag with an identifying ID that you can match to the equations in the original source, but in that case, you would not need the actual TeX, but just the id from the parent element of the clicked one.  But that[s a problem of you to deal with, I guess.

As an aside, in v4 (now out in beta release), the nodes in the output from MathJax has data-latex attributes that indicate the individual piece of the original TeX that produced that node (though it is not perfect, and there are a number of issues that need to be kept in mind).  That might be helpful if Murray's approach is the one you were really looking for.

Davide


--
You received this message because you are subscribed to the Google Groups "MathJax Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to mathjax-user...@googlegroups.com.
To view this discussion visit https://groups.google.com/d/msgid/mathjax-users/b7cc92c5-1f19-489a-b364-f8bc6e3b67b3n%40googlegroups.com.

FAbad

unread,
Feb 26, 2025, 10:39:39 AM2/26/25
to MathJax Users
Thank you Murray and Davide for your responses! These approaches are very useful, and will look at them closer!

Thank you again for your time!

Murray

unread,
Jun 10, 2026, 1:27:29 AM (yesterday) Jun 10
to MathJax Users
I finally got a chance to update my example to MathJax version 4, where it was much easier to implement.


I make use of the class "mjx-selected" (which MathJax adds to an expression on click) to determine where in the Latex the relevant expression comes from. 

My demo works OK, but the "mjx-selected" class is removed from the typeset math expression, thus losing MathJax's "info" facility. It stays visible sometimes, but only rarely. It seems I'm interfering with MathJax's onClick event, or something.

Not an earth-shattering issue, but maybe there's a simple workaround?

Regards
Murray

Davide Cervone

unread,
11:07 AM (3 hours ago) 11:07 AM
to mathja...@googlegroups.com
I make use of the class "mjx-selected" (which MathJax adds to an expression on click) to determine where in the Latex the relevant expression comes from. 

My demo works OK, but the "mjx-selected" class is removed from the typeset math expression, thus losing MathJax's "info" facility. It stays visible sometimes, but only rarely. It seems I'm interfering with MathJax's onClick event, or something.

Not an earth-shattering issue, but maybe there's a simple workaround?

The mix-selected class is part of MathJax's expression explorer, which is in effect when the math expression is focused.  When the focus moves to another element, the explorer stops and the mjx-selected class is removed.

I suppose you could note the item that was selected, and then after your LaTeX text area becomes focused, add the mix-selected class again, but you would then be responsible for removing that class if the user tabs to or clicks on the math and starts the expression explorer again.  You might need to add more event handlers for such things.  Might be a bit delicate to cover all the bases.

Davide

Reply all
Reply to author
Forward
0 new messages