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:
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?
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?
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[]
orGraphics3D[]
.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:
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
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With