如何将从单元格表达式中提取的任意框规范转换为输入表达式?
这是我对Save Mathematica code in FullForm
syntax的答案的问题。在该上下文中,模式匹配用于从使用Import
读取的笔记本表达式中提取框规范。
我认为ToExpression
或MakeExpression
可以完成盒子解释的工作,但在某些情况下却没有。
考虑包含表达式的输入单元格:
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].
对于许多(如果不是全部)内联字符串框转义序列,会发生同样的错误。我已尝试将表单明确指定为ToExpression
和MakeExpression
,但我得到了相同的错误。这让我想到了我的问题......
我需要做些什么才能模仿Mathematica从输入单元格表达式解释方框的方式?
答案 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 = ``
所以这已经很好了。
我不知道这项工作有多普遍,但它似乎适用于我尝试过的例子。主要问题是,在对a
和Italic
等内容进行“字符串化”时,它应该是\\\"a\\\"
和\\\"Italic\\\"
而不是\"a\"
和{{1}转义失败的转义本身就丢失了。
答案 1 :(得分:2)
老实说,我不确定你要做什么,但我怀疑你需要使用FrontEnd本身进行处理。这是一个通用的例子:
FrontEndExecute@FrontEnd`CellPrint[
BoxData[RowBox[{"StringForm", "[", RowBox[{"\"\<\!\(\*
StyleBox[\"a\",
FontSlant->\"Italic\"]\) = ``\>\"", ",", " ", "1"}], "]"}]]
]
但是,我不知道你真正希望得到什么格式。