Working with Stylesheets
Stylesheets are used by the Wolfram System to control the appearance and behavior of notebooks based on any and all available options provided by the notebook interface. At its most basic, a stylesheet is a collection of special cells in a notebook referenced by another notebook or applied as part of a notebook's options. In this latter case, the stylesheet is referred to as "embedded" within the notebook, as a private or local stylesheet.
StyleDefinitions | option for notebooks that specifies the file with definitions for the styles that can be used in a notebook |
StyleData["style"] | low-level representation of the contents of a style definition cell |
A stylesheet is a notebook containing StyleData cells. A simple stylesheet notebook expression could be as simple as the following.
Notebook[{
Cell[StyleData["Section"],
FontColor->Gray],
Cell[StyleData["Subsection"],
FontFamily->"Helvetica"]
}]
The above example defines only two styles, Section and Subsection, with just one option setting for each. With no more information than this, the Section and Subsection cells in the working notebook would not look much different from each other. They will both be the same size (normal text) and have the same margins, one will be gray and one will be black, and they will also be in different fonts.
The lack of variation is due to the lack of more extensive formatting information. Normally, these formatting details come from the default stylesheet, which is named "Default" in menus and dialog boxes, and is specified in notebook expressions as StyleDefinitions->"Default.nb". When editing a stylesheet, the default styles are always included as the initial reference point for any changes to be made to the styles it defines. This is visible in the stylesheet editing interface and in the stylesheet notebook expression as the first cell, but with an argument to StyleData indicating a stylesheet rather than a style name.
Notebook[{
Cell[StyleData[StyleDefinitions -> "Default.nb"]],
Cell[StyleData["Section"],
FontColor->Gray],
Cell[StyleData["Subsection"],
FontFamily->"Georgia"]
}]
Every style defined in this stylesheet will inherit the options for the named styles from the specified stylesheet at the top, in this case Default.nb. Multiple stylesheets can be specified as a stack of similar individual cells, and the inheritance of option settings will cascade down in order. With this configuration in this simple example, Section and Subsection are now differentiated from each other in many different ways as defined by the default stylesheet, except for the gray color and the other font family, which are now being applied by the newly edited style definitions.
The next section illustrates the process of editing or creating new styles through the stylesheet editing interface, followed by sections going into more detailed specifics about inheritance, environments, advanced stylesheet editing, and advanced option settings of particular interest to stylesheet developers.
The process is simple for creating a new style or making changes to an existing style via the Format menu. For the following example, use a new blank default format notebook and change the format of the Section cell style to black with no line across the top.
Begin by selecting Format ▶ Edit Stylesheet. This immediately embeds a fresh stylesheet into your document if it does not already contain one. The style changes made here will only affect the notebook containing this private stylesheet. The following image shows the stylesheet, its toolbar, and the main editing area below it (the editing area begins with a cell referencing an existing stylesheet called Default.nb and must remain in place).
A stylesheet is essentially just another notebook containing cells of a special type recognized by the system as style definitions. Any cells of that type added here affect the appearance or behavior of cells in an actual document that are set to the same style name. Edited in this example is Section, a common style available in the Choose a style pop-up menu:
Select Section from the menu and the style cell for it is inserted into the main editing area, where it is labeled "Local definition for style Section". The term "local" refers to its being part of a stylesheet local to the document, rather than referenced from the application layout.
Another way to insert a style definition cell is by entering the name in the toolbar field. It must be entered precisely the same as any existing style name, or it can also be a new style name of your choosing. Press the Enter key for it to be inserted into the editing area.
With the cell bracket selected, any settings available through the document interface menus can be directly applied and will affect any cells of that style the same way. Use Format ▶ Text Color ▶ Black to change the text color.
This method will not work on any cells in your document that already have custom formatting of a similar type applied to them. This is because of inheritance, a concept related to cascading stylesheets—formatting settings that are acquired through various levels of reference. The first cell in this stylesheet makes reference to Default.nb, and by clicking on that you can see it makes reference to Core.nb. The chain of references positions your new local stylesheet between Default and your actual document content, so any changes to cells in your document will override the same type of settings in the stylesheet.
Besides the document interface menus, another more detailed method for changing settings is to use the Option Inspector. This is the only available interface for modifying the line above the Section cell. With the style cell still selected, choose Format ▶ Option Inspector to access Cell Options and CellFrame.
The CellFrame option takes a list of lists, and in this case the last value is set to 1, which means the frame side that is above the cell will be 1 pixel.
Change that value to zero and press Enter to remove the line above the cell. Note that this option is now marked with an "x" out to the left to indicate it has been altered from the default settings (refer to "The Option Inspector" to learn more about this feature and the settings it can control).
With the new settings for Section applied, close the stylesheet window, begin a new Section cell in your document using its shortcut or the Format ▶ Style ▶ Section menu, and begin typing in it to see that the color is now black and the line above is gone.
Inheritance is a concept related to cascading stylesheets—formatting settings that are acquired through various levels of reference. The first cell in a stylesheet typically makes reference to an existing stylesheet, such as Default.nb, and by clicking on that you can see it makes reference to another, Core.nb. Wherever any particular option setting falls in the stack of referenced stylesheets and styles controls the end result in your actual document content. The end of this stack of accumulated effects is the actual cell in the working document. If it has an option applied, such as FontColor->Red, that option will override any other setting of FontColor throughout the inheritance stack.
$FrontEnd | default settings for all options in the notebook interface |
Core.nb | base stylesheet defining low-level cell appearance and behavior |
Default.nb |
user-selectable stylesheet, typically Default.nb for new documents
|
Private stylesheet (if present) | result of editing a document's stylesheet |
"Notebook" local style definition in stylesheet | special style definition in stylesheet applying options at the notebook level |
Style environment settings in stylesheet | environments are discussed in the following section |
Notebook‐level option settings | settings applied at notebook-level scope |
Cell‐level option settings | settings applied at the cell level |
The standard stylesheet/style definitions inheritance stack for notebook and cell options. Settings are applied in downward order.
StyleData["style","environment"] | represents the contents of a style definition cell in the style environment "environment" |
The second argument to StyleData is typically the name of the environment the settings should apply to.
Style environments offer a method of switching settings for documents without changing stylesheets. Typical environments include SlideShow and Printout. Many specialized behaviors are dependent on a document's environment setting. For example, a slide show operates as it does because of page break settings that are otherwise irrelevant to the normal working environment. Similarly, printing is affected by those same page breaks, but the Printout environment also scales all content down to a more appropriate size for the printed page. Font metrics are also set to a higher resolution for printing.
Environments can be set differently for the screen than for printing, by means of two different menus: Format ▶ Screen Environment and File ▶ Printing Settings ▶ Printing Environment. By default, the document interface sets the screen environment to Working and the printing environment to Printout. Therefore, it is important to note that this is not a WYSIWYG configuration. That is to say, "What You See Is" not "What You Get" in all circumstances, but this can be changed by the user via the described menus.
Explore the default stylesheet to discover how alternate environments are organized. Simply choose to edit the stylesheet of a new document, then click on the Default.nb link in the first cell under the editing interface toolbar. Open any of the sections to find style definitions, which in most cases are also cell groups, because Working environment style definition cells (with no environment defined in StyleData) always group style definition cells for other environments of the same style name.
One particularly interesting technique exploiting environments is to set CellOpen->False in all but the environment you want that particular cell to be displayed in. In this manner it is possible to create environments for different language translations of the same content that are switchable across environments named for each language. Another use is to display and hide utility cells like the slide dividers inserted by the Slide Show palette. These dividers are defined with page break settings creating discrete slide views in the SlideShow environment, while also "disappearing" in that same viewing mode because the CellOpen->False setting is applied there as well.
Developing a custom stylesheet can be a quick and simple or long and involved process, depending on how much customization is required. If the stylesheet is to service a unique document design for a technical article or textbook, you should anticipate developing a hundred or more style definitions with potentially scores of customized option settings for each, possibly in multiple environments, depending on deployment requirements.
In such a situation, the recommended procedure is to first create a notebook containing examples for all the various kinds of cells that need to be defined, all with the appropriate style names, which may be the same as those currently used by the document interface, but could also be any name desired. With a complete template notebook, begin editing the stylesheet while it remains private to the template notebook. Settings will be immediately visible in the template notebook, in the context of the document as a whole.
Besides the methods for applying cell options described in "Basic Editing Process", a sometimes more efficient method is to unformat the style definition cell expression using Cell ▶ Show Expression. This will expose the underlying syntax of the cell expression, and anyone comfortable with notebook programming and common cell options should be able to work in this mode to build up option settings in a reasonably quick manner.
Once your private stylesheet is completed, you can save it into your application layout using the Install Stylesheet button in the editing interface toolbar. Another method is to simply select all the style definition cells and copy them into a new notebook, since stylesheets are simply notebooks of these special cells. Save that in a location to be applied to any document using the Format ▶ Stylesheet ▶ Other menu, or save it in one of the special stylesheet paths to become listed in the stylesheet menu when restarting the front end.
FrontEnd`FileName[{$UserBaseDirectory,"SystemFiles","FrontEnd","StyleSheets"}]
FrontEnd`FileName[{$InstallationDirectory,"SystemFiles", "FrontEnd","StyleSheets"}]
Stylesheets contained in directories are grouped under submenus in the Stylesheet menu. Add-on applications following the same layout also add stylesheets to the menu.
Cell grouping behavior is typically controlled at the stylesheet level and impacts a document's overall hierarchical structure. Experiment with applying settings from the Cell ▶ Grouping menu on your template notebook contents to explore the various possible effects. Inspect the cell expressions for quick access to the option syntax to be applied to your custom style definitions. Learn more about cell grouping in the help system starting with Controlling Cell Grouping.
Automatic numbering is another typical setting defined in a stylesheet, particularly for technical documents. Explore these settings in the Journal Article or Preprint stylesheets by selecting a new template of either from File ▶ New ▶ Styled Notebook. Begin your inspection by choosing to edit the stylesheet, then click on the referenced stylesheet and open the following sections to access the numbered list items for some examples of autonumbering styles.
Most of the settings a style would be developed for can be found in the Option Inspector under the Cell Options category. Of particular interest are options such as CellFrame and CellFrameLabels, the latter being similar to CellDingbat in accepting any cell expression, which allows for many interesting ways to label or otherwise "decorate" cell contents. An extreme example of the use of CellFrameLabels is in the Demonstrations stylesheet, where all the initially displayed content of the template file is derived from stylesheet settings. Select File ▶ New ▶ Demonstration and then unformat all the cell expressions to see that they are devoid of content.
The Demonstration stylesheet also highlights a method for inheriting settings from other distinct style definitions. StyleData accepts an additional argument of the same form as the referenced stylesheets listed at the top of the stylesheet itself. Instead of pointing to a stylesheet, the argument points to a different style from which to inherit settings.
Cell[StyleData["Section", StyleDefinitions->StyleData["Title"]],
FontColor->Gray]
Cell[StyleData["Section", "Printout", StyleDefinitions->StyleData["Title", "Printout"]],
FontColor->Gray]
Lastly, perhaps the most interesting and most powerful method of specifying cell options is to use formulas. This is possible because the front end contains its own computational kernel supporting many of the functions in the Wolfram Language. These are discoverable using the FEPrivate` context while typing the function name of interest to see what is offered by command completion. Try, for example, FEPrivate`If or FEPrivate`SameQ. Additionally, it is possible to exploit CurrentValue[] for any option as part of a formula to dynamically control another option setting. This technique can be found in the slide show stylesheets, in settings such as the following, where the value of the window width is being multiplied by the factor of 0.135 for the left-hand cell margin setting.
CellMargins->{{
0.135 FrontEnd`AbsoluteCurrentValue[{WindowSize, 1}],
0.03 FrontEnd`AbsoluteCurrentValue[{WindowSize, 1}]},
{1.5 Inherited, 1.5 Inherited}}
A word of warning: stylesheets are parsed by the front end at all times during all aspects of document editing and processing, so it is important to be cautious with formulas for option settings, particularly that they remain efficient calculations. Dynamic[] can also be used, but because of the iterative nature of the way stylesheets are parsed by the front end, avoiding its use is suggested unless you have no other methods available for achieving your formatting objective.