这个功能似乎做到这一点:
Clear[MakeBoxesStop];
MakeBoxesStop /: MakeBoxes[MakeBoxesStop[expr_], form_] :=
Module[{heldHeads =
Join @@ Cases[expr,s_Symbol[___] :> HoldComplete[s], {0, Infinity},
Heads -> True],
modified, direct, tempContext = ToString[Unique[]] <> "`"},
Block[{$ContextPath = $ContextPath, $Packages = $Packages},
BeginPackage[tempContext];
modified =
Join @@ Map[
Function[head,
ToExpression[ToLowerCase[ToString[Unevaluated[head]]],InputForm, HoldComplete],
HoldAllComplete],
heldHeads];
EndPackage[];
With[{newexpr =
expr /. (List @@ Thread[HoldPattern /@ heldHeads -> modified, HoldComplete])},
With[{result =
MakeBoxes[newexpr, form] /.
Thread[Rule @@
Map[List @@
Map[Function[head, ToString[Unevaluated[head]], HoldAllComplete], #] &,
{modified , heldHeads}]]
},
Remove @@ Names[tempContext <> "*"];
result]]]];
它不会赢得比赛的优雅,也可以不是很干净,但似乎做你要求什么:
In[270]:= MakeBoxesStop[Graphics[Disk[]]]
Out[270]= Graphics[Disk[List[0, 0]]]
如果您不想在MakeBoxesStop
内进行评估,请在主体中添加适当的属性和Unevaluated
包装。
编辑
下面简单的盒子决策功能是基于数学解析器发布here:
Clear[toBoxes];
toBoxes[expr_] :=
First[parse[tokenize[[email protected][expr]]] //. {
head_String[elem_] :> RowBox[{head, "[", elem, "]"}],
head_String[elems___] :> RowBox[{head, "[", RowBox[Riffle[{elems}, ","]], "]"}]}]
然后,我们需要:
Clear[MakeBoxesStopAlt];
MakeBoxesStopAlt /: MakeBoxes[MakeBoxesStopAlt[expr_], form_] := toBoxes[expr]
例如:
In[327]:= MakeBoxesStopAlt[Graphics[Disk[]]]
Out[327]= Graphics[Disk[List[0, 0]]]
正如我在过去几次谈话中提到的那样,* HoldComplete短语并不会阻止MakeBoxes * ...令人困惑。 'HoldComplete'在评估阶段很重要,并且为了渲染(转换为盒子)只是一个普通的包装。我不明白你为什么在这里提到它。渲染/ FE最重要的是表达式的结果框形式,这与内核中发生的评估完全分离。 –
@Leonnid @Alexey - 关于'在FE中渲染与内核中发生的事情'的评论让我想起了[this](http://forums.wolfram.com/mathgroup/archive/2008/Jan/msg00427.html )回复John Fultz给MathGroup的一篇文章。会强制遗留图形渲染帮助吗? (可能是一个愚蠢的建议,但认为我会分享) – telefunkenvf14
@ telefunkenvf14我是错误的人问这个问题。但是IMO将表达式以箱子的形式发送给FE,即使它是图形比发送图像更清晰,所以我不会强制传统图形渲染,除非真的有必要。 –