解释输入单元格框表达式的问题

时间:2011-11-27 02:41:31

标签: wolfram-mathematica

如何将从单元格表达式中提取的任意框规范转换为输入表达式?

这是我对Save Mathematica code in FullForm syntax的答案的问题。在该上下文中,模式匹配用于从使用Import读取的笔记本表达式中提取框规范。

我认为ToExpressionMakeExpression可以完成盒子解释的工作,但在某些情况下却没有。

考虑包含表达式的输入单元格:

StringForm["a = ``", 1]

这种细胞的细胞表达如下:

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

我可以从此单元格中取BoxData子表达式,并使用ToExpression获取与我评估原始单元格相同的输出:

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

但现在考虑以下输入表达式:

StringForm["a = ``", 1]

您必须仔细查看区别:a是斜体。这是相应的单元格表达式:

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

如果我正常评估这个细胞,我会得到预期的结果。但是,如果我尝试将ToExpression应用于BoxData子表达式,就像之前一样:

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

发生错误:

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

对于许多(如果不是全部)内联字符串框转义序列,会发生同样的错误。我已尝试将表单明确指定为ToExpressionMakeExpression,但我得到了相同的错误。这让我想到了我的问题......

我需要做些什么才能模仿Mathematica从输入单元格表达式解释方框的方式?

2 个答案:

答案 0 :(得分:5)

我认为这是一个错误。以下是我测试过的几个例子:

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

例如,我们从您的案例开始:

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

Out[747]= a = ``

如果我们现在检查细胞,那就是:

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

而不是

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

(这是删除了换行符的初始版本)。而且,我认为,这应该是从一开始就应该有的。现在:

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

Out[746]= a = ``

所以这已经很好了。

我不知道这项工作有多普遍,但它似乎适用于我尝试过的例子。主要问题是,在对aItalic等内容进行“字符串化”时,它应该是\\\"a\\\"\\\"Italic\\\"而不是\"a\"和{{1}转义失败的转义本身就丢失了。

答案 1 :(得分:2)

老实说,我不确定你要做什么,但我怀疑你需要使用FrontEnd本身进行处理。这是一个通用的例子:

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

但是,我不知道你真正希望得到什么格式。