# Alternative to NotebookLocate or NotebookFind

In Mathematica 8.0 and older, there are two ways to select cells based on cell tags.

NotebookLocate["CellTag"];
NotebookGet[EvaluationNotebook[]]


and

NotebookFind[EvaluationNotebook[], "CellTag", All, CellTags, AutoScroll -> False];
NotebookGet[EvaluationNotebook[]]


When executing either of these the user selection becomes modified. By manually extracting the cells from the notebook, the user selection is not modified. Therefore, you could run NotebookGet in some type of a loop or in another user interface without messing with user's interactions.

Now NotebookGet[EvaluationNotebook[]] holds the Notebook data. So how can I extract cells as if I had run one of the commands above using NotebookGet[EvaluationNotebook[]]?

EDIT: Here is a working solution http://pastebin.com/mvFPqvVY

## Pre-V9 solution

My answer here turns out to be applicable to this question, too. There I had written this function that goes traverses a notebook's expression tree down to the level of what I will call the "notebook's cells." These are the ones displayed with a cell bracket (so it does not find inline cells).

cells[nb_NotebookObject] := cells[nb, _];
cells[nb_NotebookObject, pat_] := Flatten @ cells[First @ NotebookGet[nb], pat];
cells[cellList_List, pat_] := cells[#, pat] & /@ cellList;
cells[Cell[CellGroupData[group_List, ___]], pat_] := cells[#, pat] & /@ group;
cells[c_Cell, pat_] := If[MatchQ[c, pat], c, {}];
cells[__] := {};


It was the OP, Liam, actually, who wrapped this function in an interface to search by tag, and kindly invited me to include it in this answer:

CellsByTag[notebook_, tag_] := Module[{cells},
cells[nb_NotebookObject] := cells[nb, _];
cells[nb_NotebookObject, pat_] := Flatten@cells[First@NotebookGet[nb], pat];
cells[cellList_List, pat_] := cells[#, pat] & /@ cellList;
cells[Cell[CellGroupData[group_List, ___]], pat_] := cells[#, pat] & /@ group;
cells[c_Cell, pat_] := If[MatchQ[c, pat], c, {}];
cells[__] := {};
cells[notebook, _?(MemberQ[Flatten[{CellTags} /. Options[#]], tag] &)]]


Is this what you are looking for?

V8

Cases[
NotebookGet[EvaluationNotebook[]],
Cell[__, CellTags -> "tag", ___]
, \[Infinity]]


V9

NotebookRead @ First @ Cells[EvaluationNotebook[], CellTags -> "CellTag"]

• @Liam does Cases works for you?
– Kuba
Commented Aug 8, 2013 at 7:28
• Not all Cells will be in level 2 because of CellGroupings. My next reaction was to have Cases select with Infinity. Try running the following in an new notebook. pastebin.com/2vaixT2e Commented Aug 8, 2013 at 16:46
• @Liam You are right, this came to my mind but I forgot to check.
– Kuba
Commented Aug 8, 2013 at 16:49
• I thought you did ;), but you didn't my use cases so it might have worked. Further investigation if you run the following code pastebin.com/BgDGa3eZ then you try running NotebookLocate["MyTag"];NotebookRead[EvaluationNotebook[]] you get 5 elements with Cases vs 2 with NotebookRead Commented Aug 8, 2013 at 16:52
• @Liam Maybe this pattern is enough Cell[__, CellTags -> "MyTag"]? Then I have 2 matching cells, this one with Cases and the one you are looking for. It seems that CellTag is at the end but I'm not sure.
– Kuba
Commented Aug 8, 2013 at 16:59