最近我learned在 Mathematica 中有一些类型的表达式,它们由FrontEnd自动解析。
例如,如果我们评估HoldComplete[Rotate[Style[expr, Red], 0.5]]
,我们会看到FrontEnd不显示原始表达式:
是否可以控制FrontEnd的这种行为?
是否有可能获得由FrontEnd自动解析的完整表达式列表?
使用MakeBoxes
时,我们可以看到对Print
的来电:
On[MakeBoxes]; Print[HoldComplete@Rotate["text", Pi/2]]
但是复制粘贴打印输出会改变表达式:HoldComplete[Rotate["text", 1.5707963267948966]]
。它表明Print
不尊重HoldComplete
。
创建输出Cell
时,也应该调用MakeBoxes
。有没有办法看到它们?
答案 0 :(得分:6)
我找到了post by John Fultz,其中非常明确地解释了图形功能的工作原理:
在版本6中,内核具有 绝对没有任何参与 在生成渲染图像。 显示一个步骤 版本6中的图形非常多 就像用于展示的那些 非图形输出。它起作用 如下:
1)评估表达式,并且 最终产生一些东西 头
Graphics[]
或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
属性。
在发送到FrontEnd之前自动转换的符号列表可以从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
答案 1 :(得分:5)
您所见证的方面有两个方面。首先,将您输入的表达式转录到框中并通过前端渲染这些框。默认情况下,输出使用StandardForm进行排版,StandardForm具有用于渲染图形和几何变换的排版规则。如果您使用InputForm,则没有此类规则。您可以通过Preferences-> Evaluation。来控制使用哪种表单。
您可以通过在输入上使用InputForm或FullForm或使用输出单元格上的InputForm显示来说服自己HoldComplete正确完成其工作。
编辑使用OutputForm:
在[13]中:= OutputForm [%]
Out [13] // OutputForm = HoldComplete [Rotate [expr,0.5]]
关于完整符号列表的问题,它包括图形,几何操作以及可能的其他符号,但我不知道完整列表。
答案 2 :(得分:2)
不是一个答案,但在偏好设置>评估可以选择“仅在转换(输入|输出)到排版表格时使用文本框。”
如果你检查这些,那么使用Cell>转换为...> StandardForm等...将显示旋转[..]而不是视觉旋转结果。
答案 3 :(得分:1)
John Fultz最近answered关于将TableForm
转换为“排版”表达式的问题,值得在此引用它,因为它放大了(虽然部分矛盾){{3中引用的一般解释' }}:
ToBoxes
正在回归正是如此 内核发送到前端 没有变化(除了,在 一般情况下,进行评估 语义和副作用可能 不同,但那不是 你的例子中的问题)。问题在于前端有 两个不同的规格 指定
GridBox
选项...之一 其历史可以追溯到版本3和 其他更广阔的日期 版本6.前端理解 两组选项,但是 规范化收到的任何东西 版本6选项。
GridBox
是唯一拥有的盒子 如此大规模的选择变更, 并且有必要支持新的 我们在v6中添加的功能。但是 前端将继续了解 很久以来的旧选择 时间(可能永远),如旧 选项不仅在某些情况下出现 内核排版结构,但在 传统笔记本文件。ToBoxes[]
的{p>TableForm
正在创建 遗留选项,因为没有 需要更新排版 一段时间TableForm
(ToBoxes[]
另一方面,Grid
使用现代 选项)。转换完成 前端。你可以依靠 前端做转换 你,或者你可以弄清楚如何 选项映射自己。
因此,在这种情况下,表达式转换的最后阶段由FrontEnd完成。