8
$\begingroup$

I've tried ToString[], but it doesn't work properly with subscripts:

image

How to convert expr containing subscript to a string with exactly the same FullForm that "expr" has?


UPDATE by xzczd

There actually exists a more general issue behind the specific problem above, that is, how to convert an expression containing 2D format into corresponding string that retains the format programmatically? For example, how to convert

{a^b + 1, 1.23*10^2, 2 Subscript[a, b]}
(* Please Press Ctrl+Shift+N to convert it to standard form *)

Mathematica graphics

to

{"\!\(\*SuperscriptBox[\(a\), \(b\)]\)+1", "1.23\[Times]\!\(\*SuperscriptBox[\(10\), \(2\
\)]\)", "2\!\(\*SubscriptBox[\(a\), \(b\)]\)"}

Mathematica graphics

The attempt is easy to achieve by hand: we just need to place quotes around the expression and place a \[Times] between 1.23 and 10^2, but how to do this with program? ToString won't work, as shown above.

$\endgroup$
5
  • $\begingroup$ How did you originally get the left-hand side of Equal in In[164]? $\endgroup$ Jan 17, 2015 at 23:07
  • $\begingroup$ Presumably output of Subscript[t, 1] copied & pasted into quotes. $\endgroup$ Jan 18, 2015 at 1:10
  • $\begingroup$ \quote, t, Ctrl+-, \quote $\endgroup$
    – Stepan
    Jan 18, 2015 at 10:10
  • 1
    $\begingroup$ @Stepan Which Mathematica version do you use? I get "\!\(t\_1\)" only with version 5.2, but both with versions 8.0.4 and 11.0.0 I get "\!\(\*SubscriptBox[\(t\), \(1\)]\)" (Win7 x64). $\endgroup$ Oct 11, 2016 at 7:13
  • 1
    $\begingroup$ @xzczd ToString always creates the same string from identical expressions but there is no simple way to convert "\!\(t\_1\)" to "\!\(\*SubscriptBox[\(t\), \(1\)]\)" or backward. Moreover, there are many ways to display visually the same using different code, for example ToString["\!\(t\_1\)", StandardForm] // FullForm returns entirely different string which is rendered identical to "\!\(t\_1\)". $\endgroup$ Oct 11, 2016 at 7:18

2 Answers 2

7
+50
$\begingroup$

how to convert a expression containing 2D format into corresponding string that retains the format programmatically? For example, how to convert

{a^b + 1, 1.23*10^2, 2 Subscript[a, b]}
(* Please Press Ctrl+Shift+N to convert it to standard form *)

Mathematica graphics

to

{"\!\(\*SuperscriptBox[\(a\), \(b\)]\)+1", "1.23\[Times]\!\(\*SuperscriptBox[\(10\), \(2\
\)]\)", "2\!\(\*SubscriptBox[\(a\), \(b\)]\)"}

Mathematica graphics

The easiest way is to prevent evaluation of the expressions what can be done with Unevaluated and HoldAll. First, define the function

toString = Function[expr, ToString[Unevaluated@expr, StandardForm], HoldAll];

Now you can simply apply this function to an expression:

screenshot

You can Map it over the list for obtaining separate string for every expression in the list:

screenshot

Or you can make this function Listable and it will thread over the lists automatically:

toString = Function[expr, ToString[Unevaluated@expr, StandardForm], {HoldAll, Listable}];

screenshot

$\endgroup$
5
  • $\begingroup$ Oh… seems that I'm still not familiar enough with evaluation control, I simply forgot about its possibility and get bogged down in the mud of low level notebook structure! +1 of course. $\endgroup$
    – xzczd
    Oct 11, 2016 at 8:21
  • $\begingroup$ Is there a way to add a mathematical expression to the subscript, and then convert everything to a string? For example, let's say I want to convert Subscript["p", 2 + 3] to a string (in Mathematica, this would look like $p_{2+3}$) and concatenate it with the string "Test". Using your formula, I tried ToString2[Subscript["p", 2 + 3]] <> "Test" but it yields $p_{2 + 3} \text{Test}$ instead of $p_5 \text{Test}$. Any idea? $\endgroup$
    – alejnavab
    Jan 19 at 1:35
  • 1
    $\begingroup$ @alejnavab toString[Evaluate@Subscript["p", 2 + 3]] <> "Test". $\endgroup$ Jan 19 at 3:09
  • $\begingroup$ @AlexeyPopkov Thanks! One last question, related to my previous one. I want to add a string in the subscript as well as a mathematical expression. Using my previous example, I'd like to get $p_{\text{Hi} 5}$ (the string is "Hi", the mathematical expression is "2+3"). I tried using ToString2[Subscript["p", "Hi" 2 + 3]] but it yields $p_{3+2\text{Hi}}$ instead of $p_{\text{Hi} 5}$. How can this be done? I can't directly use ToString2[Subscript["p", "Hi5"]] because I want to use a formula in the subscript. $\endgroup$
    – alejnavab
    Mar 23 at 18:09
  • $\begingroup$ @alejnavab toString[Evaluate@Subscript["p", Row[{"Hi" , 2 + 3}]]]. $\endgroup$ Mar 23 at 23:57
4
$\begingroup$

Obtaining the box form from FullForm[ToBoxes["t1"]] (that's t subscript 1) - the box form can be used in a function like so:-

make[x_, n_] := 
 ToExpression[
  StringJoin["\"\\!\\(\\*SubscriptBox[\\(", ToString[x], "\\), \\(", 
   ToString[n], "\\)]\\)\""]]

make[t, 1]

make[t, 1] == "t1" (* again, t subscript 1 *)

True

To convert a subscripted variable another function can be used:-

f[x_] := Module[{a, b},
  a = x[[1]];
  b = x[[2]];
  make[a, b]]

f[t1]

"t1"

To convert an expression such as the following more manipulations will be needed.

expr = s + Subscript[t, 1] + u (* Hold can be used to preserve the order *)

s + u + t1

The problem is a matter of manipulating the output from this ...

ToBoxes[expr]

RowBox[{"s", "+", "u", "+", SubscriptBox["t", "1"]}]

... to the output here:

ToBoxes["s+u+t1"] (* expr with t subscript 1 pasted into quotes*)

(* "\"s+u+\\!\\(\\*SubscriptBox[\\(t\\), \\(1\\)]\\)\"" *)

For this example the manipulation can be done like so:

z = ToBoxes[expr];

ToExpression[
 StringJoin["\"",
  First[z] /. SubscriptBox[a_, b_] :>
    StringJoin["\\!\\(\\*SubscriptBox[\\(", a, "\\), \\(", b, "\\)]\\)"],
  "\""]]

"s+u+t1"

The output here includes t subscript 1.

$\endgroup$
0

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.