8

Let's say we have a cell:


(*newline*)
(*newline*)
Plot[
    x, 
    {x, 0, 1}
]
(*newline*)    
Plot[x, {x, 0, 2}]

How to read it expression by expression?

So e.g to read Plots one by one, in whatever form, Boxes, Hold[expression], String?

Here's my attempt:

SelectionMove[PreviousCell[] (*cellobject in general*), All, Cell];

text = First[ FrontEndExecute[ FrontEnd`ExportPacket[NotebookSelection[], "InputText"]] ]; (1)

Module[{stream = StringToStream[text], temp}, temp = ReadList[stream, Hold[Expression]]; Close[stream]; temp ]

{Hold[Plot[x, {x, 0, 1}]], Hold[Plot[x, {x, 0, 2}]]}

Quite long, and problematic because it changes selection.

I think there should be better way since this is what FrontEnd is doing anyway, reading expression by expression:

{
    1, Abort[]
}
2
$Aborted
2

(*1*) - How do I extract the contents of a selected cell as plain text?

Kuba
  • 136,707
  • 13
  • 279
  • 740

2 Answers2

3

Instead of SelectionMove and NotebookSelection one can use NotebookRead[PreviousCell[]] and then cleanup the text returned by the ExportPacket.

Thread @ MakeExpression[
 "{" <> 
  StringReplace[
   First[FrontEndExecute[FrontEnd`ExportPacket[NotebookRead[PreviousCell[]], "InputText"]]], 
   {"\r\n " -> "", "\r\n" -> ","}] 
  <> "}", 
 StandardForm] /. HoldComplete[Null] :> Nothing

Output for the two examples:

{HoldComplete[Plot[x, {x, 0, 1}]], HoldComplete[Plot[x, {x, 0, 2}]]}

and

{HoldComplete[{1, Abort[]}], HoldComplete[2]}
Karsten7
  • 27,448
  • 5
  • 73
  • 134
2

Here is a slight modification of Karsten's answer. Previously I felt it was too similar, but I suppose it cannot hurt to post it. The main difference is that I avoid MakeExpression. I also like the alternative in your question, which is to use StringToStream.

read[cObj_] :=
 DeleteCases[#, HoldComplete[Null]] &@(
   ToExpression[#, InputForm, 
      HoldComplete] & /@
    (StringSplit[#, "\n"] &)@
     First@FrontEndExecute@
       FrontEnd`ExportPacket[NotebookRead@cObj, "PlainText"]
   )
Jacob Akkerboom
  • 12,215
  • 45
  • 79
  • Not general enough, if you have a cell indentical as my example: {"(*newline*)\r", "(*newline*)\r", "Plot[\r", "x,\r", "{x,0,1}\r", "]\ \r", "(*newline*)\r", "Plot[x,{x,0,2}]"} so StringSplit has to be more careful. – Kuba May 04 '16 at 16:19
  • @Kuba hmm thats strange, I thought "\n" caught all newlines on my other computer (OSX). – Jacob Akkerboom May 04 '16 at 20:23