7

正如我最近了解到的, Mathematica中有一些类型的表达式可以由 FrontEnd 自动解析。

例如,如果我们评估HoldComplete[Rotate[Style[expr, Red], 0.5]],我们会看到 FrontEnd 不显示原始表达式:

截屏

是否可以控制前端的这种行为?

是否可以获得由 FrontEnd 自动解析的表达式的完整列表?


编辑

我们可以MakeBoxes在使用时看到调用Print

On[MakeBoxes]; Print[HoldComplete@Rotate["text", Pi/2]]

但是复制粘贴打印输出会改变表达式:HoldComplete[Rotate["text", 1.5707963267948966]]. 说明Print不尊重HoldComplete

在创建输出时Cell也应该有要求MakeBoxes。有没有办法看到它们?

4

4 回答 4

6

我找到了John Fultz 的一篇文章,其中非常清楚地解释了图形功能的工作原理:

在版本 6 中,内核完全不参与生成渲染图像。在版本 6 中显示图形所采取的步骤与显示非图形输出所采用的步骤非常相似。它的工作原理如下:

1) 表达式被求值,最终产生带有 headGraphics[]或的东西Graphics3D[]

2) 结果表达式通过MakeBoxes. MakeBoxes有一套规则将图形表达式转换为前端用来表示图形的框语言。例如,

In[9]:= MakeBoxes[Graphics[{Point[{0, 0}]}], StandardForm]
Out[9]= GraphicsBox[{PointBox[{0, 0}]}]

在内部,我们称之为“排版”表达式。将图形视为“排版”可能有点奇怪,但它基本上与排版的操作相同(这种方式已经工作了 11 年),所以我将使用这个术语。

3) 生成的排版表达式通过 MathLink 发送到前端。

4)前端解析排版表达式并创建内部对象,这些对象通常与排版表达式一一对应。

5)前端渲染内部对象。

这意味着转换是在内核中通过调用MakeBoxes.

这个调用可以通过高级代码拦截:

list = {};
MakeBoxes[expr_, form_] /; (AppendTo[list, HoldComplete[expr]]; 
    True) := Null;
HoldComplete[Rotate[Style[expr, Red], 0.5]]
ClearAll[MakeBoxes];
list

这是我们得到的输出:

截屏

一看就知道MakeBoxes不尊重HoldAllComplete属性。

在发送到前端之前自动转换的符号列表可以从FormatValues

In[1]:= list = 
  Select[Names["*"], 
   ToExpression[#, InputForm, 
     Function[symbol, Length[FormatValues@symbol] > 0, HoldAll]] &];
list // Length

During evaluation of In[1]:= General::readp: Symbol I is read-protected. >>

Out[2]= 162
于 2011-04-28T06:19:16.627 回答
5

你所见证的有两个方面。首先,将您输入的表达式转录到框中并由前端渲染这些框。默认情况下,输出是使用 StandardForm 排版的,它有一个排版规则来呈现图形和几何变换。如果使用 InputForm,则没有这样的规则。您可以通过 Preferences->Evaluation 控制使用哪种形式。

您可以通过在输入上使用 InputForm 或 FullForm 或在输出单元格上使用 InputForm display 来说服自己 HoldComplete 正确地完成了它的工作。

在此处输入图像描述

使用 OutputForm编辑:

In[13]:= 输出形式[%]

Out[13]//OutputForm= HoldComplete[Rotate[expr, 0.5]]

关于你关于符号完整列表的问题,它包括图形、几何运算,可能还有其他,但我不知道完整列表。

于 2011-04-11T12:26:04.097 回答
2

不是一个完整的答案,但在“首选项”>“评估”中有“仅在将(输入|输出)转换为排版形式时使用文本框”的选项。

如果您检查这些,则使用 Cell > Convert To... > StandardForm etc... 将显示 Rotate[..] 而不是视觉旋转的结果。

于 2011-04-11T15:12:30.590 回答
1

John Fultz 最近回答了我关于转换TableForm为“排版”表达式的问题,值得在这里引用它,因为它放大了(虽然部分矛盾)我之前回答中引用的一般解释:

ToBoxes准确地返回内核发送到前端的内容而没有变化(在一般情况下,评估语义和副作用可能不同,但这在您的示例中不是问题)。

问题是前端有两种不同的规范来指定GridBox选项......其中一个可以追溯到版本 3,而另一个更广泛的集合可以追溯到版本 6。前端理解这两组选项,但规范化任何内容它接收到版本 6 选项。

GridBox是唯一一个对选项进行了如此大规模更改的盒子,并且有必要支持我们在 v6 中添加的新功能。但是前端将继续理解旧选项很长一段时间(可能永远),因为旧选项不仅出现在某些内核排版结构中,而且出现在遗留笔记本文件中。

ToBoxes[]of正在创建遗留选项,因为有一段时间TableForm不需要更新排版 (另一方面,of 使用现代选项)。转换由前端完成。您可以依靠前端为您进行转换,或者您可以自己弄清楚选项如何映射。TableFormToBoxes[]Grid

所以在这种情况下,表达式转换的最后阶段由前端完成。

于 2011-06-07T02:52:10.033 回答