7
$\begingroup$

I want to create a textual style that has some CellEvaluationFunction that processes the contents of the cell a certain way. Particularly, it has to do something with the contents of inline cells (formulas in the middle of the text).

The problem is that it seems the CellEvaluationFunction receives an already parsed string (something like what you would get when you "copy as input", so I lose the inline cells. If the cell is one of those that start with an empty box, boxdata, like in StandardForm or TraditionalForm, then the function does get the box structure, but then the writing is not the same: spaces become boxes, it formats as formulas, and inline cells get formatted as text.

How could I solve this?

Basic example

Cell[TextData[{
 "hello ",
 Cell[BoxData[
  FormBox[
   FractionBox["3", "x"], TraditionalForm]],
  FormatType->"TraditionalForm"]
}], "myText", CellEvaluationFunction->myEvalFun, Evaluatable->True]

suppose I want it turned into the string "hello PP\frac{3}{8}PP", and in general, the textual part remaining the same and the inline cells wrapped in PP in TeXForm

$\endgroup$
13
  • $\begingroup$ @MikeHoneychurch yes, I see a red x^2 when I execute the output cell you get after executing the example $\endgroup$
    – Rojo
    Commented Mar 1, 2012 at 0:29
  • $\begingroup$ @MikeHoneychurch, you actually are executing "the output cell" right? $\endgroup$
    – Rojo
    Commented Mar 1, 2012 at 0:46
  • $\begingroup$ Could you please include a Cell Expression with appearance that you want, with inline boxes, etc.? $\endgroup$
    – Mr.Wizard
    Commented Mar 1, 2012 at 0:56
  • 1
    $\begingroup$ Rojo, whoops. I've had several windows open and working on a few things at once. the result is lack of attention! $\endgroup$ Commented Mar 1, 2012 at 1:05
  • 1
    $\begingroup$ @Rojo If you want to understand how the FE communicates with the kernel, you should learn to use LinkSnooper. I use it all the time to see what's actually being passed back and forth on the links. Look up LinkSnooper in the docs, which links to a Javadoc page that documents it. Given the sorts of things you express an interest in, I think you would find it a highly instructive tool. If you have any questions about using it, post them here and I'll try to keep an eye out for them. $\endgroup$
    – John Fultz
    Commented Mar 1, 2012 at 12:20

1 Answer 1

9
$\begingroup$

You're not going to get this to work on raw TextData cells. The FE evaluates TextData cells using EnterTextPacket, which merely sends a string along. And, so, the contents must be encoded as a string. Which means you're going to lose all of your typesetting structure. So, let's assume that you've embedded the above cell in a typeset cell where we'll have some more choices. E.g.,

Cell[BoxData[Cell[TextData[{
  "hello ",
  Cell[BoxData[
   FormBox[
    FractionBox["3", "x"], TraditionalForm]]]
 }]]], "myText",
 Evaluatable->True,
 CellEvaluationFunction->myEvalFun]

Now the FE is going to send an EnterExpressionPacket which maintains the full box structure, including inline cells, and that we can work with. From that starting point, I wrote a version of myEvalFun which works for your sample input. It's not very robust...in particular, it assumes that the cell contains one TextData cell with, at most, one level of BoxData cells inside of it. And that the contents of the TextData cell contain nothing other than strings and BoxData cells (other valid TextData contents include StyleBoxes, ButtonBoxes, and TextData cells). But I think it'll give you a good starting point to work from.

myEvalFun[boxes_, form_] := Module[{inlineExprs, val, topExpr},
  inlineExprs = 
   Cases[boxes, 
    Cell[val : BoxData[_], ___] :> 
     "PP" <> ToString[TeXForm[ToExpression[val, form]]] <> "PP", 
    Infinity];
  topExpr = boxes[[1]] /. Cell[_BoxData, ___] :> "``";
  topExpr = 
   topExpr /. {Cell[TextData[{val___String}], ___] :> StringJoin[val],
      Cell[val_String] :> val};
  If[StringQ[topExpr], StringForm[topExpr, Sequence @@ inlineExprs], 
   "Error"]]
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.