Преобразование выражений с помощью FrontEnd

Как я недавно узнал, в 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 тоже. Есть ли способ увидеть их?

4 ответа

Решение

Я нашел пост Джона Фульца с довольно четким объяснением того, как работает графическая функциональность:

В версии 6 ядро ​​абсолютно не участвует в генерации визуализированного изображения. Шаги, предпринятые при отображении графики в версии 6, очень похожи на те, которые используются при отображении неграфического вывода. Это работает следующим образом:

1) Выражение оценивается и в конечном итоге производит что-то с головой Graphics[] или же Graphics3D[],

2) Полученное выражение передается через MakeBoxes, MakeBoxes имеет набор правил, который превращает графическое выражение в язык ячеек, который интерфейс использует для представления графики. Например,

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

Внутренне, мы называем это "typeset" выражением. Может быть, немного странно думать о графике как о "набранной форме", но по сути это та же самая операция, которая происходит для набора текста (которая работала таким образом в течение 11 лет), поэтому я буду использовать этот термин.

3) Полученное выражение набора текста отправляется через интерфейс MathLink на внешний интерфейс.

4) Внешний интерфейс анализирует выражение typeset и создает внутренние объекты, которые обычно имеют взаимно однозначное соответствие выражению typeset.

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

Есть два аспекта того, что вы видите. Во-первых, транскрипция выражения, которое вы ввели в блоки, и рендеринг этих блоков с помощью Front-End. По умолчанию выходные данные набираются с использованием StandardForm, у которого есть правило набора для визуализации графики и геометрических преобразований. Если вы используете InputForm, такого правила нет. Вы можете контролировать, какая форма используется через Настройки-> Оценка.

Вы можете убедиться, что HoldComplete правильно выполнил свою работу, используя InputForm или FullForm на входе или используя отображение InputForm на выходной ячейке.

РЕДАКТИРОВАТЬ, используя OutputForm:

В [13]: = OutputForm [%]

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

Что касается вашего вопроса о полном списке символов, он включает в себя графику, геометрические операции и, возможно, другие, но я не знаю, полный список.

Не совсем ответ, но в Предпочтения> Оценка есть варианты "Использовать только текстовые поля при преобразовании (ввод | вывод) в наборные формы".

Если вы проверите это, то с помощью Cell > Convert To... > StandardForm и т. Д.... будет показан Rotate[..] вместо визуально повернутого результата.

Джон Фульц недавно ответил на мой вопрос о конвертации TableForm "набирать" выражения, и здесь стоит привести это, поскольку оно усиливает (хотя и частично противоречит) общее объяснение, приведенное в моем предыдущем ответе:

ToBoxes возвращает именно то, что ядро ​​отправляет внешнему интерфейсу без изменений (за исключением, в общем случае, семантики оценки и побочных эффектов, возможно, отличающихся, но это не проблема в вашем примере).

Проблема в том, что у внешнего интерфейса есть две разные спецификации для определения GridBox параметры... один из которых относится к версии 3, а другой - к более обширному набору дат для версии 6. Интерфейс понимает оба набора параметров, но канонизирует все, что получает, до параметров версии 6.

GridBox это единственная коробка, в которой было такое массовое изменение опций, и было необходимо поддерживать новую функциональность, которую мы добавили в v6. Но передний конец будет продолжать понимать старые опции в течение долгого времени (возможно, навсегда), поскольку старые опции появляются не только в некоторых конструкциях набора текста ядра, но и в старых файлах ноутбуков.

ToBoxes[] из TableForm создает устаревшие параметры, так как не было необходимости обновлять набор TableForm через некоторое время (ToBoxes[] из Gridс другой стороны, использует современные опции). Преобразование выполняется внешним интерфейсом. Вы могли бы полагаться на интерфейс, чтобы сделать преобразование для вас, или вы могли бы выяснить, как параметры отображаются самостоятельно.

Таким образом, в этом случае последний этап преобразования выражения выполняется FrontEnd.

Другие вопросы по тегам