Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

So here is what I have thought:

Use ToString and StringLength in order to get the number of characters in the variable name. If it is bigger than one, change variable name by putting everything but the first character as subscript. Symbolize subscipt to avoid issues.


Going from $ux1 - i1$ to $u_{x1}-i_1$

$x$ is a variable but I do not want any interference with u_{x...}!

About the symbolization of subscripts I looked up and found this: Needs["Notation`"]; Symbolize[ParsedBoxWrapper[SubscriptBox["", ""]]];

For the rest I have not been able to do it mainly because I do not manage to make the function go through an expression and change all the elements of it. I also tried to use Replace but failed.

share|improve this question
up vote 2 down vote accepted

It is not entirely clear to me what you are actually trying to accomplish. Using subscripts in Mathematica often needlessly complicates things. Since you are looking for an automated replacement I think you prefer not to enter subscripts manually which I think is wise. I believe it also means you are looking for a formatting function.

A basic approach is to work with strings. We may write:

ux1 - i1 /. s_Symbol /; Context[s] === $Context :>
  (Subscript[#, "" <> ##2] & @@ Characters @ SymbolName[s])

enter image description here

If string output is not acceptable we may wish to use HoldForm to keep elements from evaluating. This is important if for example x1 or i are Symbols with a value:

x1 = i = "Fail!";

ux1 - i1 /. s_Symbol /; Context[s] === $Context :>
 (HoldForm @@@ MakeExpression /@ Subscript[#, "" <> ##2] & @@ Characters @ SymbolName[s])

enter image description here

Additionally you may consider the case where these replacements must be done inside a held expression, where e.g. i1 has a global value. You will need Unevaluated and RuleCondition:

i1 = x1 = i = "Fail!";

Hold[ux1 - i1] /. s_Symbol /; Context[s] === $Context :> 
  RuleCondition[HoldForm @@@ MakeExpression /@ Subscript[#, "" <> ##2] & @@ 
     Characters @ SymbolName @ Unevaluated @ s]

enter image description here

If I am correct that you want this for formatting purposes you might make use of a formatting wrapper, which will allow you to extract the original unmodified expression, or define rules for function to work with that expression.

MakeBoxes[subscriptForm[expr_], fmt_] :=
 MakeBoxes[#, fmt] &[
  expr /. s_Symbol /; Context[s] === $Context :>
    RuleCondition[HoldForm @@@ MakeExpression /@ Subscript[#, "" <> ##2] & @@
      Characters @ SymbolName @ Unevaluated @ s]


expr = subscriptForm[Hold[ux1 - i1]]

enter image description here

First @ expr
Hold[ux1 - i1]
share|improve this answer
Waow I am going to take time to digest all of this, I will probably learn new things before being able to understand all this code. Thank you very much for this answer. – Ouistiti Aug 22 '13 at 18:04
@Ouistiti You're welcome. Let me know if you need help understanding any of it; you're right, there's a lot there. I believe the only undocumented thing I used is RuleCondition which you can read about here. – Mr.Wizard Aug 23 '13 at 2:26

You mean something like this?

f[x_] := If[Length[#] > 1 && MemberQ[Names[$Context <> "*"], ToString@x], 
    Subscript[ToExpression@First@#, ToExpression@StringJoin@Rest@#], x]&
    @ StringSplit[ToString[x], ""];

It first defines a pure function, where # is the unnamed argument. Then it applies it to the list of characters of x converted to a string. A simpler example of this method:

# Log[2, #] & @ 3

This is the same as 3 Log[2, 3].

Use the expression from above like this on general expressions:

Map[f, ux1 - i1, -1]

-Subscript[i, 1] + Subscript[u, x1]

It should work for simple expressions, but I can't guarantee it for more complex stuff. I always avoid ToExpression wherever I can (which is pretty much always). There are lots of opportunities for unforeseen side effects...

share|improve this answer
Yes but how to use it on whole expression such as my example: ux1-i1. If you have time I would also be very interested in understanding your function, especially the end of it, what is the part after the If[] doing ? – Ouistiti Aug 21 '13 at 14:11
@Ouistiti See my edit – Volker Aug 21 '13 at 14:38

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

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