3
$\begingroup$

I have the following code that successfully adds a style:

SetOptions[EvaluationNotebook[],
  StyleDefinitions->Notebook[{
    Cell[StyleData[StyleDefinitions-> 
        (FrontEnd`FileName[{"Report"},"StandardReport.nb",
         CharacterEncoding->"UTF-8"])]],
    Cell[StyleData["complexSymbols"],StyleMenuListing->None,
        TagBoxOptions->
        {SyntaxForm->"symbol"},ShowStringCharacters->False,
        ShowAutoStyles->False,ZeroWidthTimes->True,
        FontWeight->Plain,FontFamily->"Times",
        TemplateBoxOptions->{DisplayFunction-> 
        (RowBox[{#}]&),SyntaxForm->"symbol"}]}]]

But this example code sets the stylesheet to StandardReport.nb before adding the custom style that I need to use. While that is my preferred stylesheet, I would like my code to not be restricted to that stylesheet. How do I similarly add my custom style without changing the current stylesheet?

Edit: Corrected a typo in the code above. I had too many close-brackets.

Edit: Partial success, but it introduces a new problem.

Let's say I start with a notebook where I assign a stylesheet. I call:

Options[EvaluationNotebook[], StyleDefinitions]

The result I get is:

{StyleDefinitions -> FrontEnd`FileName[{"Report"}, "StandardReport.nb", 
   CharacterEncoding -> "UTF-8"]}

I then execute:

SetOptions[EvaluationNotebook[], StyleDefinitions -> Notebook[
  {Cell[StyleData[StyleDefinitions -> 
     (StyleDefinitions /. (Options[EvaluationNotebook[], StyleDefinitions]))]], 
   Cell[StyleData["complexSymbols"], StyleMenuListing -> None, 
     TagBoxOptions -> {SyntaxForm -> "symbol"}, 
     ShowStringCharacters -> False, ShowAutoStyles -> False, 
     ZeroWidthTimes -> True, FontWeight -> Plain, FontFamily -> "Times", 
     TemplateBoxOptions -> {DisplayFunction -> (RowBox[{#}] &), 
       SyntaxForm -> "symbol"}]}]]

And when I look at Options[EvaluationNotebook[],{StyleDefinitions,Cell}] again, I get the following:

{StyleDefinitions -> Notebook[
  {Cell[
    StyleData[
     StyleDefinitions -> 
      FrontEnd`FileName[{"Report"}, "StandardReport.nb", 
       CharacterEncoding -> "UTF-8"]]], 
   Cell[StyleData["complexSymbols"], ShowAutoStyles -> False, 
     ShowStringCharacters -> False, ZeroWidthTimes -> True, 
     StyleMenuListing -> None, FontFamily -> "Times", 
     FontWeight -> Plain, TagBoxOptions -> {SyntaxForm -> "symbol"}, 
     TemplateBoxOptions -> {DisplayFunction -> (RowBox[{#1}] &), 
     SyntaxForm -> "symbol"}]}, Visible -> False, 
     FrontEndVersion -> 
     "12.0 for Microsoft Windows (64-bit) (April 8, 2019)", 
     StyleDefinitions -> "Default.nb"]}

Which makes sense. But now suppose that I save this notebook, reopen it later, and then reexecute the SetOptions line. This screws everything up because it is trying to add the style again. I suppose I could go through and parse the options definition to see if it needs to be added, and if it does to see if it needs to go in as an additional cell vs as the first cell added, but it strikes me that there must be a better way.

Context: This is part of a package. When the package is loaded, it adds this style that it needs to operate. Different users may have different stylesheets, and some of them may have already put modifications to the stylesheets in place. I want to respect all of those settings, and just add my style (if it isn't already present).

$\endgroup$
2
  • $\begingroup$ Do you want it to respect the current stylesheet when you run it or do you want to set additional styles which will be preserved when user changes the stylesheet? If the latter please add some context because it will be a tough one. $\endgroup$
    – Kuba
    May 4, 2019 at 8:00
  • $\begingroup$ The former. All I am looking for is to add the new style to whatever the user has already defined as the current style sheet. If the user then changes the stylesheet later, that’s the user’s problem. Oh, and in case if wasn’t clear, I am not wanting to change the source stylesheet thereby affecting any new notebooks created with that stylesheet; I am wanting the style added to the current notebook only. $\endgroup$ May 4, 2019 at 15:29

1 Answer 1

3
$\begingroup$

Ok, got it to work. It feels inelegant, but I'll take the win.

startingStyles=
  StyleDefinitions/.Options[EvaluationNotebook[],StyleDefinitions];

complexSymbolStyle=Cell[StyleData["complexSymbols"],StyleMenuListing->None,
  TagBoxOptions->{SyntaxForm->"symbol"},ShowStringCharacters->False,
  ShowAutoStyles->False,ZeroWidthTimes->True,FontWeight->Plain,FontFamily->"Times",
  TemplateBoxOptions->{DisplayFunction->(RowBox[{#}]&),SyntaxForm->"symbol"}];

customstyle={Cell[StyleData[StyleDefinitions->placeholder]],complexSymbolStyle};

If[FreeQ[startingStyles,"complexSymbols"],
  If[Head[startingStyles]===Notebook,
    AppendTo[startingStyles[[1]],complexSymbolStyle];
      SetOptions[EvaluationNotebook[],StyleDefinitions->startingStyles],
    SetOptions[EvaluationNotebook[],
      StyleDefinitions->Notebook[customstyle/.placeholder->startingStyles]]],
  Null];
$\endgroup$
2
  • 2
    $\begingroup$ addStyle[nb_NotebookObject,newStyle:Cell[StyleData[styleName_,___],___]]:=Module[ {sd} , sd = Echo@CurrentValue[nb,StyleDefinitions] ; If[ CurrentValue[nb, {StyleDefinitions, styleName}] =!= {} , Return[True, Module] ] ; If[ MatchQ[sd, _Notebook] , SetOptions[nb, StyleDefinitions->Insert[sd, newStyle, {1, -1}]] ; Return[True, Module] ] ; SetOptions[nb, StyleDefinitions-> Notebook[ { Cell[StyleData[StyleDefinitions->sd]], newStyle } ] ] ; True ] here is the same idea but maybe a little cleaner. $\endgroup$
    – Kuba
    May 4, 2019 at 22:12
  • 3
    $\begingroup$ Then you can use it addStyle[EvaluationNotebook[], Cell[StyleData["Test"], Background -> Red]] $\endgroup$
    – Kuba
    May 4, 2019 at 22:12

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.