2011-06-30 62 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'等。 –

相關問題