Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Problems interpreting input cell box expressions

How do I convert an arbitrary box specification extracted from a cell expression into an input expression?

This came up as a problem with my answer to Save Mathematica code in FullForm syntax. In that context, pattern matching was being used to extract box specifications from notebook expressions read using Import.

I thought that ToExpression or MakeExpression would do the job of box interpretation, but in some circumstances they do not.

Consider an input cell that contains the expression:

StringForm["a = ``", 1]

The cell expression for such a cell looks like this:

Cell[BoxData[
 RowBox[{"StringForm", "[", 
  RowBox[{"\"\<a = ``\>\"", ",", " ", "1"}], "]"}]], "Input"]

I can take the BoxData subexpression from this cell and use ToExpression to obtain the same output as if I had evaluated the original cell:

ToExpression @
  BoxData[
    RowBox[{"StringForm", "[", 
      RowBox[{"\"\<a = ``\>\"", ",", " ", "1"}], "]"}]]

But now consider the following input expression:

StringForm["a = ``", 1]

You'll have to look closely to see the difference: the a is in italics. Here is the corresponding cell expression:

Cell[BoxData[
 RowBox[{"StringForm", "[", 
  RowBox[{"\"\<\!\(\*
StyleBox[\"a\",
FontSlant->\"Italic\"]\) = ``\>\"", ",", " ", "1"}], "]"}]], "Input"]

If I evaluate this cell normally, I get the expected result. But if I try applying ToExpression to the BoxData subexpression like before:

ToExpression @
  BoxData[
   RowBox[{"StringForm", "[", 
    RowBox[{"\"\<\!\(\*
  StyleBox[\"a\",
  FontSlant->\"Italic\"]\) = ``\>\"", ",", " ", "1"}], "]"}]]

an error occurs:

StringForm::string : String expected at position 1 in StringForm[]\) = '',
FontSlant->"\~\(\*\nStyleBox["a Italic, 1].

The same kind of error occurs for many, if not all, of the inline string box escape sequences. I've tried explicitly specifying the form to ToExpression and MakeExpression, but I get the same error. Which brings me to my question...

What do I have to do to emulate the way Mathematica interprets the boxes from an input cell expression?

like image 506
WReach Avatar asked Nov 27 '11 02:11

WReach


2 Answers

I think this is a bug. Here is a work-around that worked on a couple of examples I tested:

Clear[toExpression];
toExpression[bd_BoxData] :=
   ToExpression[bd /.
      s_String :>
         StringReplace[
            StringReplace[s, "\n" :> ""],
            ShortestMatch[(start : "\(\*") ~~ body__ ~~ (end : "\)")] :> 
                   StringJoin[start, StringReplace[body, "\"" :> "\\\""], end]
         ]
   ];

For example, we start with your case:

In[747]:= 
 BoxData["\"\<\!\(\*
    StyleBox[\"a\",
       FontSlant->\"Italic\"]\) = ``\>\""]//toExpression

Out[747]= a = ``

If we examine the cell now, it is:

BoxData["\<\"\\!\\(\\*StyleBox[\\\"a\\\",FontSlant->\\\"Italic\\\"]\\)\ = ``\"\>"]

instead of

BoxData["\"\<\!\(\*StyleBox[\"a\",FontSlant->\"Italic\"]\) = ``\>\""]

(which is the initial one with newlines removed). And, I'd argue, this is what it should have been from the start. Now:

In[746]:= ToExpression@
   BoxData["\<\"\\!\\(\\*StyleBox[\\\"a\\\",FontSlant->\\\"Italic\\\"]\\) = ``\"\>"]

Out[746]= a = ``

So this already works fine.

I don't know how universal this work-around it, but it seems to work for examples I tried. The main problem was that, when "stringifying" things like a and Italic, it should have been \\\"a\\\" and \\\"Italic\\\" rather than \"a\" and \"Italic\" - the escapes for escapes themselves were missing.

like image 74
Leonid Shifrin Avatar answered Oct 14 '22 20:10

Leonid Shifrin


Honestly I am not sure what you're trying to do, but I suspect you will need to use the FrontEnd itself for processing. Here is a generic example:

FrontEndExecute@FrontEnd`CellPrint[
  BoxData[RowBox[{"StringForm", "[", RowBox[{"\"\<\!\(\*
         StyleBox[\"a\",
         FontSlant->\"Italic\"]\) = ``\>\"", ",", " ", "1"}], "]"}]]
]

However, I don't know what format you actually want to get.

like image 2
Mr.Wizard Avatar answered Oct 14 '22 20:10

Mr.Wizard