tl;dr
I need a way to apply style edits in stylesheets, even when I can't use cmd+Shift+E
ntl;wr
A while back I wrote a suite of stylesheet editing tools to automate operations I did in batch, which basically just finds all Cell[StyleData[style],___] cells. The tools work great, except for when I need to apply the edits I've performed.
For example, try this:
new = CreateDocument[Cell[BoxData@"input", "Input"],
System`ClosingSaveDialog -> False];
SetOptions[new,
StyleDefinitions ->
Notebook[{
Cell[StyleData[StyleDefinitions -> "Default.nb"]],
Cell[StyleData["Input"]],
Cell[BoxData@ToBoxes@Unevaluated@
SetOptions[Cells[][[2]],
Background -> LightBlue
],
"Input",
InitializationCell -> True],
Cell[BoxData@ToBoxes@Unevaluated[
SelectionMove[
Cells[][[2]],
All,
Cell
];
FrontEndTokenExecute@"ToggleShowExpression";
FrontEndTokenExecute@"ToggleShowExpression";
],
"Input"]
},
StyleDefinitions -> "PrivateStylesheetFormatting.nb"]
];
FrontEndTokenExecute[new, "EditStyleDefinitions"];
FrontEndTokenExecute["EvaluateInitialization"]
It'll apply the styling with SetOptions but doesn't update.
I can force updating using the "ToggleShowExpression" calls in the second input cell there, but that only works if I can actually move to the cell.
Usually I'm building styles in a notebook, so I can, but sometimes this doesn't work. Case in point, I've recently been playing with the hidden style notebooks that Mathematica opens to track style changes. E.g.
$DefaultStyleNotebook :=
SelectFirst[FrontEndExecute@FrontEnd`ObjectChildren[$FrontEnd],
Quiet@NotebookFileName@# ===
FileNameJoin@{$InstallationDirectory,
"SystemFiles", "FrontEnd", "StyleSheets", "Default.nb"} &
]
That's the (usually hidden) notebook that sets all the default styles. Now I can set its properties using StylesheetEdit[style, ops], but the changes can't be applied because I can't use "ToggleShowExpression".
I've looked through many of the front-end packets, but can't find where whatever "cascade-update" type functionality the front end uses to apply these updates is hidden.
Can anyone help me out? Note that the real dream would be something that I can just evaluate in the kernel, but which preserves the CellObject. (i.e. no rewriting with NotebookWrite)
Example
As an example this is the sort of syntax I'm using:
SSEdit["Input", True,
FontColor -> Red
]
where the True just means create a new Cell with StyleData["Input",...] if it doesn't exist in the style definitions notebook.
After application this is what we see:
And then we revert it like this:
SSEdit["Input", True,
FontColor -> Inherited
]
Which we can see does indeed revert the change:
But here's the annoying code I have to use to get those changes to apply:
SSApplyEdits[cells : {__CellObject}] :=
With[{e = EvaluationCell[]},
Do[
SelectionMove[c, All, Cell,
AutoScroll -> False];
FrontEndTokenExecute[ParentNotebook@c,"ToggleShowExpression"];
FrontEndTokenExecute[ParentNotebook@c,"ToggleShowExpression"];,
{c, cells}
];
SelectionMove[e, After, Cell]
];


"Default.nb"via yours$DefaultStyleNotebookhave immediate effect on the opened Notebooks (checked with Mathematica 11.1.1 on Windows 7 x64). Is the situation different for you? From the other hand, have you triedFrontEndTokenExecute[$DefaultStyleNotebook, "ToggleShowExpression"]? – Alexey Popkov May 02 '17 at 02:38SetOptionsthe changes don't immediately apply. Same goes when I use it on something other than the$DefaultStyleNotebook. The"ToggleShowExpression"only works when the cell is selected in the notebook. When I get a chance I'll try just usingExportPacketon the notebook. Ought to apply the changes, I think. – b3m2a1 May 02 '17 at 02:41SetOptionson the in-memory stylesheet (I just can't imagine)? – Alexey Popkov May 02 '17 at 02:45StyleDatacells and then I useSetOptionson those. Originally I did this with the style notebook open and so"ToggleShowExpression"sufficed but once I moved to the hidden in-memory notebooks my original code failed. Supplying the notebook object to"ToggleShowExpression"works, but opening and closing the cells can be incredibly distracting, so hopefullyExportPacketwill do. – b3m2a1 May 02 '17 at 02:50SetOptionsyou always can useNotebookRead-Insert-NotebookWriteon aCellObject. But it will open closed cell groups unfortunately. An alternative is an in-memory modification of the stylesheet Notebook expression as a whole and then writing it instead of the original usingNotebookPut. – Alexey Popkov May 02 '17 at 02:58"ToggleShowExpression"works even when no cell is selected, so you can simply deselect the cell before calling it. – Alexey Popkov May 02 '17 at 03:06CellObjectso no rewrite will do it for me.ExportPacketworks but makes an annoying beep I'll have to deal with."ToggleShowExpression"with no selection doesn't trigger updates. Let me post an example of the kind of thing I'm doing. Might clarify things some. – b3m2a1 May 02 '17 at 03:14FrontEndExecute@ExportPacket[]doesn't work for updating the styles afterSetOptions(as well asRasterize[""]) butFrontEndExecute@ExportPacket[Notebook[{Cell[""]}], "BoundingBox"]works, andExportString["", "MGF"]also works. – Alexey Popkov May 02 '17 at 03:18NotebookWrite[cellObject, Cell[StyleData["Input"], ...]]doesn't destroy theCellObject. – Alexey Popkov May 02 '17 at 03:35c = EvaluationCell[];NotebookWrite[c, NotebookRead@c];c === EvaluationCell[]. Even if you evaluate this in two steps:c = EvaluationCell[];NotebookWrite[c, NotebookRead@c];andPreviousCell[] === cyou still getFalse. – b3m2a1 May 02 '17 at 03:40NotebookWritesimply didn't work for the stylesheet because it hasEditable -> False. – Alexey Popkov May 02 '17 at 03:53