Mathematica Stack Exchange is a question and answer site for users of Mathematica. Join them; it only takes a minute:

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

This question already has an answer here:

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?

share|improve this question

marked as duplicate by Alexey Popkov, Community May 19 at 5:53

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

    
Does MakeBoxes@@ToHeldExpression@string help? – Simon Woods May 3 '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 3 '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 3 '14 at 10:33
    
Ah yes, I see what you mean. – Simon Woods May 3 '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 3 '14 at 13:01

Conversion to explicit boxes:

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


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

format[string_] := Map[
 If[StringTake[#, 1] == "\!",
    ToExpression[StringReplace[#, "\(" ~~ x : plain ~~ "\)" :> "\(\"" <> x <> "\"\)"]],
    #] &,
 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[\"" <> x <> "\", FontWeight -> Bold]\)", 
 x : LetterCharacter .. :> "\!\(\*StyleBox[\"" <> x <> "\", 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

share|improve this answer

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