Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

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

1 Answer 1

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

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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