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$
  • $\begingroup$ How did you originally get the left-hand side of Equal in In[164]? $\endgroup$ – Algohi Jan 17 '15 at 23:07
  • $\begingroup$ Presumably output of Subscript[t, 1] copied & pasted into quotes. $\endgroup$ – Chris Degnen Jan 18 '15 at 1:10
  • $\begingroup$ \quote, t, Ctrl+-, \quote $\endgroup$ – Stepan Jan 18 '15 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$ – Alexey Popkov Oct 11 '16 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$ – Alexey Popkov Oct 11 '16 at 7:18
5
+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$
  • $\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 '16 at 8:21
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$

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.