Проблемы, интерпретирующие выражения ячеек ячеек

Как преобразовать произвольную спецификацию окна, извлеченную из выражения ячейки, в входное выражение?

Это вызвало проблему с моим ответом на Сохранить код Mathematica в синтаксисе FullForm. В этом контексте сопоставление образцов использовалось для извлечения спецификаций ящиков из выражений ноутбука, прочитанных с помощью Import.

Я думал, что ToExpression или MakeExpression будет выполнять работу с интерпретатором коробки, но в некоторых случаях они этого не делают.

Рассмотрим входную ячейку, содержащую выражение:

StringForm["a = ``", 1]

Ячейное выражение для такой ячейки выглядит следующим образом:

Cell[BoxData[
 RowBox[{"StringForm", "[", 
  RowBox[{"\"\<a = ``\>\"", ",", " ", "1"}], "]"}]], "Input"]

Я могу выполнить подвыражение BoxData из этой ячейки и использовать ToExpression для получения того же результата, как если бы я оценил исходную ячейку:

ToExpression @
  BoxData[
    RowBox[{"StringForm", "[", 
      RowBox[{"\"\<a = ``\>\"", ",", " ", "1"}], "]"}]]

Но теперь рассмотрим следующее входное выражение:

StringForm["a = ``", 1]

Вам нужно будет внимательно посмотреть на разницу: a выделен курсивом. Вот соответствующее выражение ячейки:

Cell[BoxData[
 RowBox[{"StringForm", "[", 
  RowBox[{"\"\<\!\(\*
StyleBox[\"a\",
FontSlant->\"Italic\"]\) = ``\>\"", ",", " ", "1"}], "]"}]], "Input"]

Если я правильно оцениваю эту ячейку, я получаю ожидаемый результат. Но если я попробую применить ToExpression к подвыражению BoxData, как и раньше:

ToExpression @
  BoxData[
   RowBox[{"StringForm", "[", 
    RowBox[{"\"\<\!\(\*
  StyleBox[\"a\",
  FontSlant->\"Italic\"]\) = ``\>\"", ",", " ", "1"}], "]"}]]

возникает ошибка:

StringForm::string : String expected at position 1 in StringForm[]\) = '',
FontSlant->"\~\(\*\nStyleBox["a Italic, 1].

Такая же ошибка возникает для многих, если не всех, из последовательностей escape-последовательности встроенных строк. Я пробовал явно указывать форму ToExpression и MakeExpression, но я получаю ту же ошибку. Это подводит меня к моему вопросу...

Что мне нужно сделать, чтобы подражать тому, как Mathematica интерпретирует ящики из выражения входных ячеек?

Ответ 1

Я думаю, что это ошибка. Вот работа, которая работала над несколькими примерами, которые я тестировал:

Clear[toExpression];
toExpression[bd_BoxData] :=
   ToExpression[bd /.
      s_String :>
         StringReplace[
            StringReplace[s, "\n" :> ""],
            ShortestMatch[(start : "\(\*") ~~ body__ ~~ (end : "\)")] :> 
                   StringJoin[start, StringReplace[body, "\"" :> "\\\""], end]
         ]
   ];

Например, мы начинаем с вашего случая:

In[747]:= 
 BoxData["\"\<\!\(\*
    StyleBox[\"a\",
       FontSlant->\"Italic\"]\) = ``\>\""]//toExpression

Out[747]= a = ``

Если мы сейчас исследуем ячейку, это:

BoxData["\<\"\\!\\(\\*StyleBox[\\\"a\\\",FontSlant->\\\"Italic\\\"]\\)\ = ``\"\>"]

вместо

BoxData["\"\<\!\(\*StyleBox[\"a\",FontSlant->\"Italic\"]\) = ``\>\""]

(который является исходным, когда удалены новые строки). И, я бы сказал, это то, что должно было быть с самого начала. Сейчас:

In[746]:= [email protected]
   BoxData["\<\"\\!\\(\\*StyleBox[\\\"a\\\",FontSlant->\\\"Italic\\\"]\\) = ``\"\>"]

Out[746]= a = ``

Итак, это уже отлично работает.

Я не знаю, насколько универсальна эта работа вокруг, но, похоже, это работает на примерах, которые я пытался. Основная проблема заключалась в том, что при "подтягивании" таких вещей, как a и Italic, он должен был быть \\\"a\\\" и \\\"Italic\\\", а не \"a\" и \"Italic\" - отсутствовали escape файлы для экранов.

Ответ 2

Честно говоря, я не уверен, что вы пытаетесь сделать, но я подозреваю, что вам нужно будет использовать FrontEnd для обработки. Вот общий пример:

[email protected]tEnd`CellPrint[
  BoxData[RowBox[{"StringForm", "[", RowBox[{"\"\<\!\(\*
         StyleBox[\"a\",
         FontSlant->\"Italic\"]\) = ``\>\"", ",", " ", "1"}], "]"}]]
]

Однако я не знаю, какой формат вы хотите получить.