4

众所周知,通过输出表达式MakeBoxes将图形表达式转换为前端用来表示图形的框语言(当$Output有默认选项时FormatType->StandardForm)。例如,如果我们评估:

HoldComplete[Graphics[Disk[]]]

我们得到一个由以下内容包裹的磁盘HoldComplete

截屏

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

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

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

截屏

PS 请不要建议使用InputForm,因为我对它的默认行为不满意

4

1 回答 1

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包装器。

编辑

以下简单的盒子制作功能基于此处发布的 Mathematica 解析器:

Clear[toBoxes];
toBoxes[expr_] :=
  First[parse[tokenize[ToString@FullForm[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]]]
于 2011-06-30T12:33:43.287 回答