9
$\begingroup$

I have never understood how to easily generate an image preview for a given stylesheet. I also am unclear on how to easily share one. So I'm looking for an implementation or good 3rd party solution for functions to do these things:

StyleSheetPreview[location] (*or StyleSheetBrowse[loc] for loc in wolfram cloud that has many styles*)

Would give something like the built-in styles previewer:

enter image description here

And this would give a way to share them:

StyleSheetShare["newstylesheet"] (*uploads it to wolfram cloud*)
StyleSheetInstall["newstylesheet", "Uninstall" -> True|False] 
(*downloads and installs from wolfram cloud*)

enter image description here

I’ve noticed a number of ResourceFunctions that exist to install things (e.g. GitHubInstall). Might this be a good way to share stylesheets? Or is there another more modern way to create, preview, and deliver them stylesheets?

$\endgroup$
11
  • 6
    $\begingroup$ Paclets are designed exactly for this. Use them. There's supposed to be a paclet repository coming "soon"--as in sometime in the next 5-10 years. In the meantime just distribute them as releases on GitHub. $\endgroup$
    – b3m2a1
    Commented Jan 14, 2020 at 22:05
  • 1
    $\begingroup$ @b3m2a1 I’ve never tried that, could you post a minimal working example of this route? $\endgroup$
    – user5601
    Commented Jan 15, 2020 at 5:49
  • 1
    $\begingroup$ I mean like whats the directory structure, do I make a package with functions that copy or remove the style files and 9-patch images, what’s the conventions, etc. Is there a good tutorial or example of building this paclet for each new stylesheets to share? $\endgroup$
    – user5601
    Commented Jan 15, 2020 at 5:55
  • 1
    $\begingroup$ I’ll post an answer when I have the time but I’ve posted a lot here about how to use paclets. I even wrote up a tutorial. Give my other answers a quick look. $\endgroup$
    – b3m2a1
    Commented Jan 15, 2020 at 5:59
  • 1
    $\begingroup$ But how to extend the built in theme browser would be cool too $\endgroup$
    – user5601
    Commented Jan 15, 2020 at 6:04

1 Answer 1

12
+300
$\begingroup$

Preview Notebooks / Extra Paclet Features

I decided it was worth it to add some extra features to this thing as it's a good example of what paclets can do for you.

First off, I added a little CreateStylesheetPreview function that'll take stylesheets and rasterize them to make a preview. e.g.:

CreateStylesheetPreview[
  {"Default.nb", "ReverseColor.nb" -> "Custom/CodeNotebook.nb"}
  ] // CreateDocument

enter image description here

(Read the source code to see how it's implemented. It's not particularly complex stuff.)

Then I made it so that you can "Include" arbitrary content in your paclet, so we'll add this as a palette. I'll do that as a directory, just to show how it works. Other content can be included directly as files, but I wanted to support both. First we'll create a directory containing the palettes of interest:

Quiet@
  CreateDirectory["~/Desktop/Palettes/Custom/", 
   CreateIntermediateDirectories -> True];
Export[
  "~/Desktop/Palettes/Custom/CodeNotebookPreview.nb",
  CreateStylesheetPreview[
   {"Default.nb", "ReverseColor.nb" -> "Custom/CodeNotebook.nb"}
   ]
  ];

then we can bundle and share it like so:

StylesheetShare[
 sheets[[1]],
 "Includes" -> {
   "~/Desktop/Palettes/Custom" -> "FrontEnd/Palettes/Custom",
   "~/Desktop/StylesheetShare.wl"
   },
 "PackageContext" -> {"StylesheetShare`"}
 ]

CloudObject["https://www.wolframcloud.com/obj/b3m2a1.testing/Paclets/CodeNotebook-1.0.0.paclet"]

You'll notice I also included the package that implements this stuff in there, just for the heck of it.

When you install it, since I didn't bump the "Version" in the Options, if you have an old version installed you'll need to install it like so:

StylesheetInstall["CodeNotebook", "IgnoreVersion" -> True]

Paclet[CodeNotebook, 1.0.0, <>]

Once it's installed you'll see two changes from before, first, in the palettes menu we have this:

enter image description here

which just opens up that preview notebook from before.

Second, we can find that installed package:

FindFile["StylesheetShare`"] // StringTrim[#, $UserBasePacletsDirectory] &

"/Repository/CodeNotebook-1.0.0/Include/StylesheetShare.wl"

And so at that point you could just do <<StylesheetShare` to load the package

If you want to distribute multiple packages you can do that by adding their names to the "PackageContext" list.

Original

Wrote up a package to do the sharing.

First load the package from GitHub:

Get["https://github.com/b3m2a1/mathematica-tools/raw/master/StylesheetShare.wl"]

This exposes two functions, StylesheetShare and StylesheetInstall

Next get some sheets to share. Here are a few that are already in a package of mine:

stylesheetsDir = 
  "~/Documents/Wolfram Mathematica/Applications/BTools/FrontEnd/StyleSheets/BTools";

sheets =
 FileNames[
  "*.nb", 
  stylesheetsDir
  ]

(* Out:

{
 ~/Documents/Wolfram Mathematica/Applications/BTools/FrontEnd/StyleSheets/BTools/CodeNotebook.nb,
 ~/Documents/Wolfram Mathematica/Applications/BTools/FrontEnd/StyleSheets/BTools/CodePackage.nb,
 ~/Documents/Wolfram Mathematica/Applications/BTools/FrontEnd/StyleSheets/BTools/CodePackagePlain.nb,
 ~/Documents/Wolfram Mathematica/Applications/BTools/FrontEnd/StyleSheets/BTools/DocGen.nb,
 ~/Documents/Wolfram Mathematica/Applications/BTools/FrontEnd/StyleSheets/BTools/MarkdownNotebook.nb,
 ~/Documents/Wolfram Mathematica/Applications/BTools/FrontEnd/StyleSheets/BTools/SyntaxHighlighting.nb
 }

*)

Then we can share a single sheet:

StylesheetShare[
 sheets[[1]]
 ]

CloudObject["https://www.wolframcloud.com/obj/b3m2a1.testing/Paclets/CodeNotebook-1.0.0.paclet"]

And then install that:

StylesheetInstall[
 "CodeNotebook", 
 "WolframID" -> "b3m2a1.testing"
 ]

Paclet[CodeNotebook,1.0.0,<>]

enter image description here

Or you can share the entire directory:

StylesheetShare[
 stylesheetsDir,
 "Name" -> "MySheets"
 ]

CloudObject["https://www.wolframcloud.com/obj/b3m2a1.testing/Paclets/MySheets-1.0.0.paclet"]

There are a bunch of little settings you can use in StylesheetShare if you want:

Options[StylesheetShare]

{"Version" -> "1.0.0", "Name" -> Automatic, "Creator" -> Automatic, 
 "Description" -> "A stylesheets paclet", 
 "BuildDirectory" :> CreateDirectory[], "MenuName" -> "Custom", 
 "PacletsRoot" -> "", Permissions -> "Public", AppearanceElements -> All, 
 AutoCopy -> False, CloudObjectNameFormat -> Automatic, 
 CloudObjectURLType -> Automatic, IconRules -> Automatic, 
 MetaInformation -> {}, SharingList -> {}, SourceLink -> Automatic}

But that should be enough to get you started

$\endgroup$
6
  • $\begingroup$ Can you give some suggestions as to how the preview gallery would work? $\endgroup$
    – user5601
    Commented Jan 25, 2020 at 20:24
  • $\begingroup$ @user5601 basically you’d set up a Notebook with all the content you’d like to see as changes (basically standard cell styles), then Rasterize it with a set of different style sheets set as the StyleDefinitions. You can get all of the stylesheet available in the styles menu using something like FEPrivate`GetMenuPopupList $\endgroup$
    – b3m2a1
    Commented Jan 25, 2020 at 20:28
  • 1
    $\begingroup$ @user5601 you’ll make a custom template Notebook for the preview, I figure. No way good way to get only the relevant cell styles programmatically (there are usually lots of like TemplateBox styles in there too). $\endgroup$
    – b3m2a1
    Commented Jan 25, 2020 at 20:32
  • 1
    $\begingroup$ So if I understand correctly, to support any sort of "share with preview" I'll need to package two things 1. styledefinitions notebook 2. a template notebook using (1). Ok but then what do I do with both of those files, your StylesheetShare works for just (1) right? $\endgroup$
    – user5601
    Commented Jan 27, 2020 at 19:22
  • 2
    $\begingroup$ @user5601 I'll write up an extension to make it easy to include other directories. You can include your previews as a palette or something or add a package that will generate it when called. $\endgroup$
    – b3m2a1
    Commented Jan 27, 2020 at 23:56

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.