Wolfram mathematica 可以创建MakeBoxesStop包装器吗?
它要求输出表达式通过Wolfram mathematica 可以创建MakeBoxesStop包装器吗?,wolfram-mathematica,mathematica-frontend,Wolfram Mathematica,Mathematica Frontend,它要求输出表达式通过makebox来将图形表达式转换为前端用于表示图形的box语言(当$output具有默认选项FormatType->StandardForm时)。例如,如果我们评估: HoldComplete[Graphics[Disk[]]] 我们得到一个由HoldComplete包装的磁盘: 这是因为holdplete不会停止makebox将其内容转换为排版表达式: In[4]:= MakeBoxes@HoldComplete[Graphics[Disk[]]] Out[4]= Ro
makebox
来将图形表达式转换为前端用于表示图形的box语言(当$output
具有默认选项FormatType->StandardForm
时)。例如,如果我们评估:
HoldComplete[Graphics[Disk[]]]
我们得到一个由HoldComplete
包装的磁盘:
这是因为holdplete
不会停止makebox
将其内容转换为排版表达式:
In[4]:= MakeBoxes@HoldComplete[Graphics[Disk[]]]
Out[4]= RowBox[{"HoldComplete", "[", GraphicsBox[DiskBox[{0, 0}]], "]"}]
所以我的问题是:是否有可能对makebox
进行一些额外的定义,以便用headmakebox-stop
包装任何表达式,从而阻止makebox
将该表达式转换为排版形式?在这种情况下,表达式在输出中的外观应与任何其他表达式相同,其中没有与符号关联的规则;在上述情况下:
注意:请不要建议使用
InputForm
,因为。此功能似乎可以:
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]]]];
如果不希望对MakeBoxesStop
中的表达式求值,请在正文中添加适当的属性和Unevaluated
包装
编辑
以下简单的方框生成函数基于Mathematica解析器:
那么,我们需要:
Clear[MakeBoxesStopAlt];
MakeBoxesStopAlt /: MakeBoxes[MakeBoxesStopAlt[expr_], form_] := toBoxes[expr]
例如:
In[327]:= MakeBoxesStopAlt[Graphics[Disk[]]]
Out[327]= Graphics[Disk[List[0, 0]]]
我出版了第一个工作版本。我可以很好地想象,它可以缩短很多,而且并不总是需要在
HoldComplete
中包装东西(特别是对于生成的符号)。@Leonid似乎没有必要ToLowerCase
所有符号:在另一个上下文中移动它们。我不知道如何将makebox
递归应用于原始表达式的确切细节,但这个过程似乎是由makebox
本身控制的,我觉得可以通过向makebox
@Leonid添加适当的定义,在任意头部停止这个递归过程,此定义必须将表达式进一步转换为BoxForm
s,但不考虑Graphics
等符号的FormatValues
。@Alexey您关于ToLowerCase
的说法是正确的-这是第一个版本的产物,没有对新符号进行本地化。至于你停止制作盒子的策略,祝你好运。我所能说的是,由于您仍然需要它来处理您想要“阻止”它的头部内部部分,因此我认为这种策略没有什么意义(此外,它听起来很复杂,并且依赖于makebox
的实现细节)。在这个解决方案中,我尝试在尽可能高的级别上重用makebox
。如果您需要特定符号的列表,也可以使用我的代码。@Alexey实际上我看过您的代码,当将符号移动到另一个上下文时,它对您有效,除非我使用更长的名称,否则它对我无效,因为我不想放弃系统'
上下文。使用较长的名称将有效地带来与使用小写字母相同的混乱,因此我想我不在乎使用哪一个。正如我在过去的对话中多次提到的,短语HoldComplete并没有停止MakeBoxs。。。这令人困惑HoldComplete
在评估阶段很重要,为了呈现(转换为方框)的目的,它只是一个普通的包装器。我不明白你为什么在这里提到它。对于渲染/FE来说,重要的是表达式的结果框形式,这与内核中发生的计算是完全不同的主题。@leonid@Alexey-关于“FE中的渲染与内核中发生的事情”的评论让我想起了John Fultz对MathGroup帖子的回复。强制传统图形渲染会有帮助吗?(可能是一个愚蠢的建议,但我想与大家分享)@telefunkenvf14我问错了这个问题。但是,我将以方框形式发送表达式到FE,即使它是图形,也比发送图像更干净,因此我不会强制传统图形渲染,除非确实需要。密切相关:。
Clear[MakeBoxesStopAlt];
MakeBoxesStopAlt /: MakeBoxes[MakeBoxesStopAlt[expr_], form_] := toBoxes[expr]
In[327]:= MakeBoxesStopAlt[Graphics[Disk[]]]
Out[327]= Graphics[Disk[List[0, 0]]]