# How to automatically put the part of a variable name after the first letter in symbolized subscripts?

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.

Example:

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.

-

## 2 Answers

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])  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])


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]  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]
]


Now:

expr = subscriptForm[Hold[ux1 - i1]]


First @ expr

Hold[ux1 - i1]

-
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...

-
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