前端对表达式的转换

发布于 2024-10-31 19:09:24 字数 700 浏览 1 评论 0原文

据我最近了解到,Mathematica 中有一些类型的表达式是由前端自动解析的。

例如,如果我们计算 HoldComplete[Rotate[Style[expr, Red], 0.5]],我们会看到前端不显示原始表达式:

Screenshot

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

是否有可能获得前端自动解析的表达式的完整列表?


编辑

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

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

但是复制粘贴打印输出会给出更改的表达式: HoldComplete[Rotate["text", 1.5707963267948966]]。它表明 Print 不尊重 HoldComplete

创建输出 Cell 时,也应该调用 MakeBoxes。有办法看到他们吗?

As I learned recently there are some types of expressions in Mathematica which are automatically parsed by the FrontEnd.

For example if we evaluate HoldComplete[Rotate[Style[expr, Red], 0.5]] we see that the FrontEnd does not display the original expression:

Screenshot

Is it possible to control such behavior of the FrontEnd?

And is it possible to get complete list of expressions those are parsed by the FrontEnd automatically?


EDIT

We can see calls to MakeBoxes when using Print:

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

But copy-pasting the printed output gives changed expression: HoldComplete[Rotate["text", 1.5707963267948966]]. It shows that Print does not respect HoldComplete.

When creating output Cell there should be calls for MakeBoxes too. Is there a way to see them?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

七七 2024-11-07 19:09:24

我找到了 John Fultz 的帖子,其中有非常清晰的解释图形功能如何工作:

在版本 6 中,内核具有
绝对没有任何参与
在生成渲染图像时。
显示 a 时所采取的步骤
版本6的图形非常多
就像那些用于显示的
非图形输出。它的工作原理是
如下:

1) 计算表达式,并且
最终产生一些东西
head 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

这是我们得到的输出:

screenshot

人们可以看到 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

I have found a post by John Fultz with pretty clear explanation of how graphics functionality works:

In version 6, the kernel has
absolutely no involvement whatsoever
in generating the rendered image.
The steps taken in displaying a
graphic in version 6 are very much
like those used in displaying
non-graphical output. It works as
follows:

1) The expression is evaluated, and
ultimately produces something with
head Graphics[] or Graphics3D[].

2) The resulting expression is passed
through MakeBoxes. MakeBoxes has a
set of rules which turns the graphics
expression into the box language which
the front end uses to represent
graphics. E.g.,

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

Internally, we call this the "typeset"
expression. It may be a little weird
thinking of graphics as being
"typeset", but it's fundamentally the
same operation which happens for
typesetting (which has worked this way
for 11 years), so I'll use the term.

3) The resulting typeset expression is
sent via MathLink to the front end.

4) The front end parses the typeset
expression and creates internal
objects which generally have a
one-to-one correspondence to the
typeset expression.

5) The front end renders the internal
objects.

This means that the conversion is performed in the Kernel by a call to MakeBoxes.

This call can be intercepted through high-level code:

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

Here is what we get as output:

screenshot

One can see that MakeBoxes does not respect HoldAllComplete attribute.

The list of symbols which are auto-converted before sending to the FrontEnd one can get from 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
瞳孔里扚悲伤 2024-11-07 19:09:24

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

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

在此处输入图像描述

编辑 使用 OutputForm:

In[13]:= OutputForm[%]

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

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

There are two aspects to what you witness. First, transcription of the expression you entered into boxes and rendering those boxes by Front-End. By default the output is typeset using StandardForm, which has a typesetting rule to render graphics and geometric transforms. If you use InputForm, there are no such rule. You can control which form is used via Preferences->Evaluation.

You can convince yourself that HoldComplete correctly did its job by using InputForm or FullForm on the input, or using InputForm display on the output cell.

enter image description here

EDIT Using the OutputForm:

In[13]:= OutputForm[%]

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

In regard to your question about complete list of symbols, it includes Graphics, geometric operations, and possibly others, but I do not know of the complete list.

十年不长 2024-11-07 19:09:24

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

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

Not quite an answer, but in Preferences > Evaluation there are options to "Only use textual boxes when converting (input|output) to typeset forms."

If you check these, then using Cell > Convert To... > StandardForm etc... will show the Rotate[..] instead of the visually rotated result.

云裳 2024-11-07 19:09:24

约翰·富尔茨 (John Fultz) 最近回答了我的问题关于将 TableForm 转换为“排版”表达式的问题,值得在这里引用,因为它放大了(虽然部分矛盾)我之前的回答

ToBoxes 正在返回什么
内核发送到前端
没有变化(除了,在
一般情况,用于评估
语义和可能的副作用
有所不同,但这不是
您的示例中存在问题)。

问题是前端有
两种不同的规格
指定 GridBox 选项...之一
它可以追溯到版本 3,并且
其他更广泛的设定日期
版本6.前端理解
两组选项,但是
规范化它收到的任何内容
版本 6 选项。

GridBox 是唯一一个具有
如此大规模的选择改变,
并且有必要支持新的
我们在 v6 中添加的功能。但是
前端会继续了解
旧的选择已经很长了
时间(可能永远),如旧
选项不仅出现在某些
内核排版结构,但在
旧笔记本文件。

TableForm

ToBoxes[] 正在创建
遗留选项,因为没有
需要更新排版
TableForm 一会儿(ToBoxes[] of
另一方面,Grid 使用现代的
选项)。转换是通过以下方式完成的
前端。您可以信赖
前端进行转换
你,或者你可以弄清楚如何
选项映射你自己。

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

John Fultz has recently answered my question on converting TableForm to "typeset" expressions and it is worth to cite it here since it amplifies (while partially contradicts) the general explanation cited in my previous answer:

ToBoxes is returning precisely what
the kernel sends to the front end
without variation (except, in the
general case, for the evaluation
semantics and side effects possibly
being different, but that's not an
issue in your example).

The issue is that the front end has
two different specifications for
specifying GridBox options... one of
which dates back to version 3, and the
other, more expansive set dates to
version 6. The front end understands
both sets of options, but
canonicalizes anything it receives to
the version 6 options.

GridBox is the only box which has had
such a wholesale change of options,
and it was necessary to support new
functionality we added in v6. But the
front end will continue to understand
the old options for a seriously long
time (probably forever), as the old
options show up not only in certain
kernel typesetting constructs, but in
legacy notebook files.

ToBoxes[] of TableForm is creating the
legacy options, as there's been no
need to update the typesetting of
TableForm in a while (ToBoxes[] of
Grid, on teh other hand, uses modern
options). The conversion is done by
the front end. You could rely on the
front end to do the conversion for
you, or you could figure out how the
options map yourself.

So in this case the final stage of the conversion of the expression is done by the FrontEnd.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文