2011-06-30 64 views
4

is known输出表达式通过MakeBoxes将图形表达式转换为前端用来表示图形的框语言(当$Output具有默认选项FormatType->StandardForm时)。举例来说,如果我们评价:是否可以创建MakeBoxesStop包装?

HoldComplete[Graphics[Disk[]]] 

我们得到了一个盘由HoldComplete包裹:

screenshot

这是因为HoldComplete不会转换其内容排版表达停止MakeBoxes

In[4]:= [email protected][Graphics[Disk[]]] 
Out[4]= RowBox[{"HoldComplete", "[", GraphicsBox[DiskBox[{0, 0}]], "]"}] 

所以我的问题是:是否有可能作出一些额外的定义t MakeBoxes这样包装任何表达与头MakeBoxesStop将阻止MakeBoxes将此表达式转换为排版形式?在这种情况下,表达式应该将输出看作没有任何与其中的符号相关的规则的任何其他表达式;在上述情况下:

screenshot

P.S.请不要建议使用InputForm,因为I am not satisfied with its default behavior

+1

正如我在过去几次谈话中提到的那样,* HoldComplete短语并不会阻止MakeBoxes * ...令人困惑。 'HoldComplete'在评估阶段很重要,并且为了渲染(转换为盒子)只是一个普通的包装。我不明白你为什么在这里提到它。渲染/ FE最重要的是表达式的结果框形式,这与内核中发生的评估完全分离。 –

+0

@Leonnid @Alexey - 关于'在FE中渲染与内核中发生的事情'的评论让我想起了[this](http://forums.wolfram.com/mathgroup/archive/2008/Jan/msg00427.html )回复John Fultz给MathGroup的一篇文章。会强制遗留图形渲染帮助吗? (可能是一个愚蠢的建议,但认为我会分享) – telefunkenvf14

+0

@ telefunkenvf14我是错误的人问这个问题。但是IMO将表达式以箱子的形式发送给FE,即使它是图形比发送图像更清晰,所以我不会强制传统图形渲染,除非真的有必要。 –

回答

3

这个功能似乎做到这一点:

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]]] 
+0

我发表了第一个工作版本。我可以很好地想象,它可以变得更短,并且在HoldComplete中总是不需要(特别是对于生成的符号)。 –

+0

@Leonid似乎没有必要'ToLowerCase'所有的符号:移动他们在另一个上下文[足够](http://stackoverflow.com/questions/6224185/making-customized-inputform-and-shortinputform/6230478 #6230478)。我不清楚'MakeBoxes'是如何递归应用于原始表达式的,但似乎这个过程是由'MakeBoxes'本身控制的,我觉得可以通过添加一个合适的头部来阻止这个递归过程在任意头部定义为'MakeBoxes'。 –

+0

@Leonid当然,这个定义必须将表达式进一步转换为'BoxForm's,但不考虑'Graphics'等符号的'FormatValues'等。 –

相关问题