Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

Let's say I'm debugging a program step by step and want to Print some expressions (using ShowIt, for example).

Is there a way to output the result of Print on top of already printed expressions instead of at the bottom?

share|improve this question
add comment

2 Answers 2

up vote 11 down vote accepted

This is admittedly messy, but something along these lines might work:

insertBelowEvaluationCell[expr_] := 
  (SelectionMove[EvaluationNotebook[], After, EvaluationCell]; 
   NotebookWrite[EvaluationNotebook[], Cell[BoxData@ToBoxes[expr], "Print"]])

This function moves the insertion point just below the evaluation cell before inserting the text or expression to be printed.

Let's test it:

insertBelowEvaluationCell /@ Range[10]

Problems:

  • This messes with the insertion point in the notebook which can be modified interactively as well. Perhaps it's better to write the output into a separate notebook instead.

  • It does not work in command line mode (without a front end).

  • It's slow (noticeably slower than Print).

share|improve this answer
    
It looks good, thanks. I accept your answer for now. –  Faysal Aberkane Apr 11 '12 at 15:47
1  
I don't think there's a way to do it without a front end (unless you are on a terminal interpreting escape sequences, in which case you could output the relevant ones with Print, but even then, you might have problems determining how many lines to go up). –  celtschk Jun 14 '12 at 10:38
add comment

This is an arguably even messier solution than Szabolcs', and its performance isn't going to win any awards, but it has some (somewhat dubious) advantages:

  1. It allows you to choose whatever target you want for the printing, putting things in an arbitrary notebook, and the output will appear at the current selection in that notebook;
  2. After that, printing won't affect the current selection;
  3. You can have many different targets for printing;
  4. It provides another use for the seemingly useless CellTags feature!

The function in question creates a dummy cell that will eventually contain the output as a side-effect, and returns a closure that you call like Print (more or less; it only takes one argument) in order to direct output to that target cell. The function is here:

Pillsy`UpsideDownPrinter[nb_: InputNotebook[]] :=
 With[{
   tag = ToString@FileHash[
      StringToStream@ToString@{NotebookGet@nb, Date[]}]},
  NotebookWrite[nb, Cell["", CellTags -> tag]];
  Function[content,
   Module[{nbExpr = NotebookGet[nb], pos},
     pos = Position[nbExpr, Cell[___, CellTags -> tag, ___]];
     NotebookPut[
      MapAt[
       Replace[#,
         Cell[stuff_, opts___] :>
          Cell[CellGroup[{Cell[content], Cell[stuff]}], opts]] &,
       nbExpr,
       pos],
      nb]];]]

First, NotebookWrite is used to create a Cell in the target notebook with a unique CellTag (which is what all the FileHash stuff is for), and then we continually modify the target notebook's structure using standard Mathematica structural operations. The stuff with CellGroup allows us to effectively create a "linked list" of generated cells in a (probably futile) stab at maintaining some degree of efficiency.

You use it like so:

printer = Pillsy`UpsideDownPrinter[];

printer["foo!"]; printer["bar!"]; printer["baz!"];

which will give output that looks like

"baz!"
"bar!"
"foo!"
share|improve this answer
    
This looks interesting, I'll test it tomorrow. It's a good example of what can be achieved by manipulating notebooks. –  Faysal Aberkane Apr 11 '12 at 23:09
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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