4
$\begingroup$

Suppose we have a Notebook with a deeply nested structure (this is a simplified example, the Notebook can be huge):

nb = CreateDocument[{ExpressionCell[0, "Section"], ExpressionCell[1, "Section"], 
    ExpressionCell[2, "Subsection"], ExpressionCell[3, "Subsubsection"], 
    ExpressionCell[4, "Input"], CellGroup[{ExpressionCell[4, "Output"]}]}];

And a cell located inside one of the nested groups:

cellObj = Last@Cells[nb];

If we know how deeply our cell is nested, it is easy to select the outermost CellGroup:

SelectionMove[cellObj, All, CellGroup, 4]

screenshot

But what if we don't know the nesting level? How can we select the outermost CellGroup in this case?

Currently I know only an extremely inefficient iterative approach:

nesting = Module[{n = 1, scPrev, scCurr},
 SelectionMove[cellObj, All, Cell];
 scPrev = SelectedCells[nb];
 While[SelectionMove[cellObj, All, CellGroup, n];
  (scCurr = SelectedCells[nb]) =!= scPrev,
  scPrev = scCurr; ++n];
 n - 1]

SelectionMove[cellObj, All, CellGroup, nesting]
4

Is there a more efficient way?

P.S. The fact that SelectionMove[cellObj, All, CellGroup, 5] doesn't return $Failed in this case I consider as a bug.

$\endgroup$

1 Answer 1

3
$\begingroup$

A simple answer is to specify a large enough value for the fourth argument of SelectionMove, which is very unlikely to be exceeded in real life. The timings linearly depend on it, but are not large:

ListPlot[Table[First[AbsoluteTiming@SelectionMove[cellObj, All, CellGroup, n]], {n, 15}], 
 PlotRange -> All]

output

In real life, it is extremely unlikely to find a Notebook with CellGroup nesting larger than 15. Hence we can simply take this value as a "practical infinity", which ensures that the outermost CellGroup will be selected.

$\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.