8

It is very easy and convenient to write textual labels as Strings in the WYSIWYG mode. For example, I define a short form describing a linear model: "2D3O", which means "two descriptors of type D and tree descriptors of type O". Everything is good so far. Now I wish to add superscripts and use standard palette to add them. I get

screenshot

Looks nice. But at some point I have a lot of such labels and wish to apply some formatting to all of them at once. For example, I wish to make all the digits Bold and all the letters Gray. FullForm shows internal structure and I see the string representation of boxes:

screenshot

This is not a format easy to deal with. The tutorial explains how to convert ordinary boxes to its string representation using ToString. But what is the general way to convert string representation of boxes into explicit boxes?

Alexey Popkov
  • 61,809
  • 7
  • 149
  • 368
  • Does MakeBoxes@@ToHeldExpression@string help? – Simon Woods May 03 '14 at 10:16
  • @Simon It works with the example in question but fails with this: "3\!\(\*SuperscriptBox[\(R\), \(2\)]\)2O". MakeBoxes returns a box structure with redundant space character (representing multiplication produced by ToHeldExpression). – Alexey Popkov May 03 '14 at 10:27
  • Generally speaking, ToExpression is very fragile way to convert string representation of boxes because it requires syntactically correct expression inside of the string. – Alexey Popkov May 03 '14 at 10:33
  • Ah yes, I see what you mean. – Simon Woods May 03 '14 at 10:38
  • I mean that formatted string should look as original in the sence of the spacings between characters (and there are not additional spacings in my examples). – Alexey Popkov May 03 '14 at 13:01
  • @AlexeyPopkov Those are not spacings but the way FE is interpreting such expression. I don't know how to fight this without decomposing everythig. Take a look at StringForm["\!\(\*SuperscriptBox[\(````\), \(``\)]\)", Style["R", Gray], Style[3, Bold], Style[1, Bold]] – Kuba May 03 '14 at 13:24
  • @Kuba Conversion of string representation of boxes into explicit boxes is a kind of task which one expect to be implemented by WRI. I hope it is implemented but I failed to find any built-in way. Implementing this is probably not a fun considering Jonh Fultz's comments. – Alexey Popkov May 03 '14 at 17:00
  • @Kuba Your new approach works very well with my current set of labels (+1). – Alexey Popkov May 03 '14 at 21:19
  • @AlexeyPopkov uff, great :) and thanks for motivation to read about this syntax :) – Kuba May 03 '14 at 21:26
  • 2
    The Wolfram Function Repository has an entry for this now. ResourceFunction["StringToBoxes"]. The docs provide some good example usage. – Tanner Legvold Jan 04 '21 at 03:56

1 Answers1

4

Conversion to explicit boxes:

ClearAll[expr, myStyle, string];
expr = ("\!\(" ~~ Longest[Except["\!"]] .. ~~ "\)");
plain = (Except[{"\*", "\)"}] ..);

myStyle[string_] := StringReplace[string, {
x : DigitCharacter :> "!(*StyleBox[&quot;" <> x <> "&quot;, FontColor -> RGBColor[1,0,0]])", x : LetterCharacter :> "!(*StyleBox[&quot;" <> x <> "&quot;, FontColor -> RGBColor[0,0,1]])"}]

format[string_] := Map[ If[StringTake[#, 1] == "!", ToExpression[StringReplace[#, "(" ~~ x : plain ~~ ")" :> "(&quot;" <> x <> "&quot;)"]], #] &, StringSplit[string, x : expr :> x] ] /. x_String :> myStyle[x] // Row

enter image description here


Unfinished pure string approach:

ClearAll[expr, myStyle, boxFormat, scanner];
expr = ("\!\(" ~~ Longest[Except["\!"]] .. ~~ "\)");

myStyle[string_] := StringReplace[string, {
x : DigitCharacter .. :> "!(*StyleBox[&quot;" <> x <> "&quot;, FontWeight -> Bold])", x : LetterCharacter .. :> "!(*StyleBox[&quot;" <> x <> "&quot;, FontColor -> GrayLevel[0.5`]])"}]

boxFormat[string_] := StringReplace[string, "(" ~~ x : (Except["*"] ~~ __) ~~ ")" :> "(" <> myStyle[x] <> ")"];

scanner = If[StringTake[#, 1] == "!", boxFormat@#, myStyle@#] &;

Usage:

string = "\!\(\*SuperscriptBox[\(D3\), \(1\)]\) 1 \!\(\*SuperscriptBox[\(R\), \(1\)]\)"

scanner /@ StringSplit[string, x : expr :> x] // StringJoin

enter image description here

enter image description here

Kuba
  • 136,707
  • 13
  • 279
  • 740