Можно ли создать упаковщик MakeBoxesStop? - PullRequest
4 голосов
/ 30 июня 2011

Это известно , что выходные выражения передаются через MakeBoxes, чтобы превратить графические выражения в язык ячеек, который интерфейс использует для представления графики (когда $Output имеет параметр по умолчанию FormatType->StandardForm),Например, если мы оценим:

HoldComplete[Graphics[Disk[]]]

, мы получим диск, обернутый HoldComplete:

screenshot

Это потому, что HoldComplete не останавливаетсяMakeBoxes из преобразования его содержимого в наборное выражение:

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

Поэтому мой вопрос: возможно ли сделать некоторые дополнительные определения для MakeBoxes, такие, что перенос любого выражения с головой MakeBoxesStop предотвратит MakeBoxes от преобразования этого выражения в набранную форму?В этом случае выражение должно выглядеть в выводе как любое другое выражение без правил, связанных с символами в нем;в приведенном выше случае:

screenshot

PS Пожалуйста, не предлагайте использовать InputForm, поскольку Меня не устраивает поведение по умолчанию .

1 Ответ

3 голосов
/ 30 июня 2011

Эта функция, кажется, делает это:

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 оболочки в теле.

EDIT

Следующая простая функция создания коробок основана на парсере 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]]]
...