7

I want to work on a notebook programmatically with CellObjects.

lets create a notebook for example:

nb = CreateDocument[{TextCell["a", "Title"], Cell["b", "Subtitle"], 
 Cell["c", "Text"]}];

this gives the CellObjects of the notebook:

cells = Cells[nb]

Now i want to have a function like:

 getCellStyle/@cells

Out:

 {"Title", "Subtitle", "Text"}

I know that i could work with selections as suggested in this question: How can I get the style of selected cells?

But its more practical in my case to work directly with the CellObjects. I think there must be a way to get the style, since the CellObjects look in the FrontEnd like CellObject["style"]

I just want to extract that "style".

sacratus
  • 1,556
  • 10
  • 18

2 Answers2

6

Something more documented:

NotebookRead[ PreviousCell[] ][[2]]
"Section"

It seems there is something exactly what you need, quite not ready probably since in Experimental` context:

Experimental`CellStyleNames[ PreviousCell[] ]
"Output"

and Experimental`CellStyleNames[] gives you styles of all cells in notebook!, quite useful sometimes. Keep in mind that it is undocumented.

p.s. closer look reveals that it is nothing more than CellInformation approach:

ClearAttributes[Experimental`CellStyleNames, ReadProtected];

Block[{$ContextPath},

 AppendTo[$ContextPath, "Experimental`"];

 AppendTo[$ContextPath, "NotebookTools`UtilitiesDump`"];

 ?? Experimental`CellStyleNames
 ]

enter image description here

take a closer look at the very first definition, now you have new way to set cell style:

(Experimental`CellStyleNames[#] = "Title") & @ PreviousCell[]

Kuba
  • 136,707
  • 13
  • 279
  • 740
  • Nice discovery. To clarify: ``Experimental```CellStyleNames@Cells[nb] works, i.e., directly on the CellObjects. So getCellStyles = Experimental`CellStyleNames – Rolf Mertig Apr 01 '15 at 08:38
  • 1
    not exactly ... – Rolf Mertig Apr 01 '15 at 08:41
  • @RolfMertig Agree, but PreviousCell is a cell object. – Kuba Apr 01 '15 at 08:42
  • sure. How do I escape a quote in comments? – Rolf Mertig Apr 01 '15 at 08:45
  • @RolfMertig You have to wrap with one more that you want to display inside, and if here is one at the end you have to add whitespace. – Kuba Apr 01 '15 at 08:45
  • thank you Kuba, this answered two of my questions! But its funny that Experimental-CellStyleNames does internally exactly the same thing, that i was doing as my workaround before ^^ Before i was using ("Style" /. Developer-CellInformation[#] & ) to get the CellStyle, but i was thinking that its a very slow way to find out the CellStyle, because CellInformation gives you much more Information than needed in this case. The boxes-method by kguler is in fact faster: I improved it a little bit: getCellStyle[cell_CellObject] := If[StringQ[#], #, $Failed] &@ToExpression[ToBoxes[cell]〚1, -1〛] – sacratus Apr 02 '15 at 08:14
  • @sacratus great I could help, Thanks for info about performance. ;) – Kuba Apr 02 '15 at 08:35
4
Last /@ FilterRules[Developer`CellInformation[nb], "Style"]
(* {"Title", "Subtitle", "Text"} *)

Or

SelectionMove[nb, All, Notebook]; "Style" /.  Developer`CellInformation[nb]
(* {"Title", "Subtitle", "Text"} *)

Working with CellObjects:

RawBoxes[ToBoxes[#][[1, -1]]] & /@ Cells[nb]
(* {"Title", "Subtitle", "Text"}  *)
kglr
  • 394,356
  • 18
  • 477
  • 896
  • thank you for your solution, it works for the most cases, but you did not used the CellObjects. I specify my question, why i need to work with CellObjects... – sacratus Apr 01 '15 at 00:28
  • 1
    @sacratus, just added a method that works with CellObjects. Not sure how robust it is though. – kglr Apr 01 '15 at 00:31
  • Nice this is what i wanted, but instead of RawBoxes one should use ToExpression so that the function returns a String instead of RawBoxes. Thank You! – sacratus Apr 01 '15 at 00:43
  • @sacratus it works with cell objects: "Style" /. Developer`CellInformation@PreviousCell[] – Kuba Apr 01 '15 at 07:07
  • The last one is RawBoxes[""Input""] for example. So it looks ok but it isn't. – Kuba Nov 15 '15 at 09:27