1
$\begingroup$

Using V12 on windows.

This is the problem. I am calling an external function (Rubi in this case, but it could be anything), which ends up printing a cell (image) to the Console. I simply want to capture this cell and export it to PDF file.

Even if I redirect the output to the current notebook, I can't use the command Export["image.pdf", NotebookRead[PreviousCell[]]]; to do what I want, since the code which call the external function runs in a loop.

Is there a way to do the same as Export["image.pdf", NotebookRead[PreviousCell[]]]; but to use the Message console as the notebook instead of the current notebook?

To make it more clear, here is a MWE.

CurrentValue[$FrontEnd, {"PrintAction"}] = {"PrintToConsole"};

(*a function which prints an image to console*)
externalFunction[max_] := Print[Plot[Sin[x], {x, -max, max}]];

(*run a loop calling the function, and export its output*)
Do[
 externalFunction[n];

 (*need something like this*)
 (*Export["t.pdf",MessagesNotebookRead[PreviousCell[]]]; ??*) 
 ,
 {n, 1, 5}
 ]

enter image description here

Directing the Print to the current notebook does not work

CurrentValue[$FrontEnd, {"PrintAction"}] = {"PrintToNotebook"};
externalFunction[max_] := Print[Plot[Sin[x], {x, -max, max}]];
Do[
 externalFunction[n];
 Export["t.pdf", NotebookRead[PreviousCell[]]];
 ,
 {n, 1, 5}
 ]

Since PreviousCell[] in the above is not what I want, it will read the cell before the actual loop itself.

Also this does not work

CurrentValue[$FrontEnd, {"PrintAction"}] = {"PrintToNotebook"};
externalFunction[max_] := Print[Plot[Sin[x], {x, -max, max}]];
Do[
 Export["t.pdf", externalFunction[n]]
 ,
 {n, 1, 5}
 ]

I could not find a way to tell Mathematica to use the Messages console notebook as the notebook to the PreviousCell[]

What is the best way export a cell in Messages console to pdf file? It will be the last cell each time, as in the above example. This is done in a loop. Each iteration generates one Rubi cell in the Messages console and I need to capture that cell as an image.

Appendix

If someone would like to try this with the actual Rubi output, here is a MWE

<< Rubi`
CurrentValue[$FrontEnd, {"PrintAction"}] = {"PrintToConsole"};
Do [
 Steps[Int[x Sin[x], x]];
 (*save output in console to image, how?*)
 Steps[Int[x Cos[x], x]]
 (*save output in console to image, how?*)
 ,
 {n, 2}
 ]

enter image description here

$\endgroup$
  • 2
    $\begingroup$ Could you use Last[Cells[MessagesNotebook[]]] instead of PreviousCell[]? You wouldn't need to change the printing action then. $\endgroup$ – Gerli Oct 14 '19 at 12:04
2
$\begingroup$

For your MWE the simplest solution is to dynamically redefine the Print function in the Block scope:

Do[
 Block[{Print := (Export[ToString[n] <> ".pdf", Echo@#, OverwriteTarget -> "KeepBoth"];) &},
  externalFunction[n];
  ]
 , {n, 1, 5}]

This will print every output in the evaluation notebook and immediately Export it after this. With this solution externalFunction may print any number of outputs which will be correctly saved as separate PDF files according to the new in version 12 OverwriteTarget -> "KeepBoth" option. If Rubi uses for printing other function than Print you can redefine it in the same way. If you have high requirements you may need to apply Internal`InheritedBlock and the Villegas-Gayley trick instead of simple Block showed above. But I don't think it is really necessary in your case.

Another approach (which more directly answers the question as it is stated in the title) is suggested in the comment by Gerli:

Do[
 externalFunction[n];
 Export[ToString[n] <> ".pdf", Last[Cells[MessagesNotebook[]]]]
 , {n, 1, 5}]

It assumes that every evaluation of externalFunction results in printing of exactly one Cell in the MessagesNotebook[].

$\endgroup$
1
$\begingroup$

After some more time playing with this, I found this solution which seems to work. But I would be happy to accept a better solution.

Instead of using PreviousCell, I should use NextCell, but also have to delete each output cell as it is generated for this to work. So the MWE now is

 SetDirectory[NotebookDirectory[]]

<< Rubi`

CurrentValue[$FrontEnd, {"PrintAction"}] = {"PrintToNotebook"};
Do [
 Steps[Int[x Sin[x], x]];
 Export["t1.pdf", NotebookRead[NextCell[]]];
 NotebookDelete[Cells[EvaluationNotebook[], GeneratedCell -> True]];

 Steps[Int[x Tan[x], x]];
 Export["t2.pdf", NotebookRead[NextCell[]]];
 NotebookDelete[Cells[EvaluationNotebook[], GeneratedCell -> True]];

 Steps[Int[x Log[x], x]];
 Export["t3.pdf", NotebookRead[NextCell[]]];
 NotebookDelete[Cells[EvaluationNotebook[], GeneratedCell -> True]];
 ,
 {n, 1}
 ]

This generated 1.pdf and 2.pdf and 3.pdf all with the correct images for each call.

enter image description here

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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