MathGroup Archive 2007

[Date Index] [Thread Index] [Author Index]

Search the Archive

Style sheet primer

  • To: mathgroup at smc.vnet.net
  • Subject: [mg76590] Style sheet primer
  • From: John Fultz <jfultz at wolfram.com>
  • Date: Thu, 24 May 2007 06:11:31 -0400 (EDT)
  • Reply-to: jfultz at wolfram.com

I've been thinking about how to address the stylesheet issues.  I could=
 write an 
extremely long email on the topic addressing all questions to date, but I've=
 
decided it might be more manageable to begin with a primer on the concepts,=
 then 
address the applications by addressing the various unanswered questions on=
 this 
group in separate emails.

Sorry for those who've been waiting for several days for a response like=
 this on 
the stylesheet issue.  Responding to these questions takes considerable time=
 
free from the distractions of work and life which have seemed to come up 
frequently for me, lately.

Some new concepts in the version 6 stylesheet mechanism...

* Inherited stylesheets - A stylesheet may inherit from other stylesheets.=
 If 
stylesheet B inherits from stylesheet A, then B gets all of A's styles plus=
 any 
defined in B.  B can override A in several ways...
  + It can add new options to an existing style
  + It can add new styles
  + It can completely replace an existing style
  + It can't remove a style, but it can replace it with a null style that 
doesn't appear on the menus.
A stylesheet can inherit from multiple stylesheets, in which case they are 
simply combined with earlier stylesheets taking priority (this is very=
 similar, 
incidentally, to what has always happened if you have multiple definitions=
 of a 
named style in a single stylesheet).  Note that in 5.2, there was an=
 extremely 
limited inheritance model...all stylesheets inherited from Default.nb.

* Inherited styles - A named style may inherit from any other named style. =
 
Similarly, a named environment may inherit from any other named environment.=
  
This inheritance only takes place within the current stylesheet (or its 
ancestors), though...you cannot inherit from a style from a completely=
 different 
stylesheet.

* Private or embedded stylesheets - This is not a new concept, but it's done=
 
differently now. This is a one-off stylesheet which is embedded in the=
 notebook. 
Previously, this was done by embedding an entire copy of the stylesheet in a=
 
notebook.  This is no longer necessary in a world of inherited stylesheets. =
 You 
can now embed a very tiny stylesheet which inherits from a canonical=
 stylesheet 
and contains only the changes (i.e. new styles, changed existing styles).

* Core.nb - The Core stylesheet is very nice example of what inherited 
stylesheets allow.  Core doesn't contain enough styles to constitute a=
 useful 
stylesheet.  But it does contain those styles which really ought to be at=
 the 
core of every other stylesheet.  For example, it contains all of the style 
information which supports default syntax coloring.  Without this=
 information, 
all of the syntax coloring will appear styleless (i.e. black, plain).  
Reproducing this in every single stylesheet is unnecessary, and creates more=
 
opportunities for mistakes to happen in any individual stylesheet.  But that=
 
doesn't mean that a certain stylesheet might not add to or override a few of=
 the 
syntax styles.  Every stylesheet we ship inherits from Core (although not=
 always 
directly...a stylesheet might inherit from Default, which in turn inherits=
 from 
Core).

* MenuPosition - Since we now have stylesheets like Core which are only=
 useful 
as parents of other stylesheets, we should hide them from the menus. =
 Therefore, 
stylesheets have a MenuPosition option which is set at the notebook level. =
 
Setting the MenuPosition->None removes it from the menu entirely.  Any=
 positive 
number allows you to specify specifically where the stylesheet should be in=
 the 
menu.  Stylesheets with equivalent positive numbers are sorted=
 alphabetically.  
This mechanism of removing stylesheets from the menu is also being used when=
 we 
want to stop supporting some stylesheets, but keep them around for backward=
 
compatibility.

The MenuPosition option also works for individual styles, serving a very=
 similar 
purpose (this replaces the StyleMenuListing option for 5.2).  The interfaces=
 
provided for creating new styles will always put your styles at the bottom=
 fo 
the Styles menu.

* MenuCommandKey - This option applies to styles and allows you to set the 
command key for a style to be "1"-"9".  The command-key assignments are no 
longer order-sensitive.  However, for the moment, conflict management is=
 left up 
to you.  The behavior of a stylesheet with multiple styles assigned to the=
 same 
MenuCommandKey is undefined.

* Legacy stylesheets - The front end enters a slightly different mode when 
reading a stylesheet created by 5.2 and earlier.  For example, in new 
stylesheets, it respects only the MenuCommandKey and MenuPosition options=
 when 
constructing the Style menu, whereas in legacy stylesheet it respects the 
StyleMenuListing option and assigns command keys according to the order of=
 the 
styles (i.e. 5.2 behavior).



Now, let me go over some problems with the previous design, and how we deal=
 with 
those problems in v6....

* Installed stylesheets can be modified and saved (i.e. the old Edit 
Stylesheet->Shared).  This is bad because there is simply no guarantee that=
 you 
can even write to the installation directory.  Also, somebody could change a=
 
stylesheet like Default.nb in such a way as to permanently damage the system=
 and 
necessitate a re-install.  Built-in stylesheets are no longer editable or 
savable.

* Creating new stylesheets (embedded or public) freezes your stylesheet at=
 the 
version of Mathematica you're using.  For example, anybody who created a 5.2=
 
stylesheet based upon a copy of Default.nb will find that many things appear=
 
broken (graphics don't appear the same, syntax coloring might not show up 
correctly) because you are essentially using a 5.2 version of Default.nb. =
 By 
using inherited stylesheets, you are now inheriting from the canonical 
stylesheet.  If you make a stylesheet which inherits from Default.nb in 6.0,=
 and 
then open the notebook in Mathematica 7, it will inherit the Mathematica 7 
stylesheet, and any new features in that stylesheet.

* Creating a stylesheet from scratch is a heavyweight process, but that's=
 the 
only option that was really available in 5.2.  Very few people have the 
resources or desire to create a stylesheet from scratch.  Much more=
 typically, 
people want to tweak existing stylesheets.  In fact, very commonly, all=
 people 
want to do is to just add or change a very small number of styles.  The 
inherited stylesheet mechanism is perfect for this.



So here's a few of the interesting implications of the new mechanism which=
 may 
not be immediately obvious...

* Embedded stylesheets are now very small and manageable.
* Your modification of a system stylesheet need not have a different name. =
 For 
example, if you want to change the behavior of Default.nb, make a new=
 Default.nb 
which inherits from Default.nb and put it in $BaseDirectory or 
$UserBaseDirectory.  The copy in $[User]BaseDirectory will inherit from the=
 one 
in the layout, and you'll only see the one instance in the menu.
* This allows us to create custom interfaces which streamline the most=
 common 
stylesheet tasks users wish to do.


Now, here comes the rough part.  All of the underlying technologies have a=
 solid 
implementation, but some of the user interface could still use some work,=
 and 
it's largely undocumented.  For example, I think we have a very good=
 beginning 
to an interface for working with embedded stylesheets, although it could 
certainly use a style inspector.  Creating named stylesheets is considerably=
 
awkward right now.

Finalizing the interfaces would have required delaying Mathematica.  We=
 decided 
not to do this because, frankly, the whole of Mathematica 6 is really good=
 and 
we were eager to get it out the door.  Also, except for the lack of 
documentation, the situation really isn't any worse than 5.2, which was also=
 
undocumented and considerably awkward in every aspect of stylesheet=
 editing.

Finally, before I go onto answering specific questions, let me outline the 
syntax for the style data cells.  As a review, a 5.2 style cells look like 
this...

(* defines a style *)
Cell[StyleData[stylename_String], opts]

(* defines an environment *)
Cell[StyleData[All, environment_String], opts]

(* defines an environment-specific tweak to a style *)
Cell[StyleData[style_String, environment_String], opts]

(* Set notebook-level options *)
Cell[StyleData["Notebook"], opts]

6.0 now allows the following new StyleData[] forms as the first argument of=
 a 
Cell:

(* Inherit from another stylesheet.  This should always appear before any=
 style 
definitions *)
StyleData[StyleDefinitions->stylesheet_String]

(* This defines how a style or environment is inherited...*)
StyleData[stylename_String, StyleDefinitions->source]
StyleData[All, environmentname_String, StyleDefinitions->source]
StyleData[stylename_String, environment_String, StyleDefinitions->source]

Possible values of source:
=09Inherited: Inherit from the style named 'stylename' in the parent=
 stylesheet 
(this is the default)
=09None: Do *not* inherit the style from anywhere
=09StyleData[style_String]: Inherit from 'style' as defined in the current or=
 
parent stylesheet
=09StyleData[All, environment_String]: Inherit from 'environment'
=09StyleData[style_String, environment_String]: Inherit from the 
environment-specific definition of style

More followup to specific questions coming shortly.

Sincerely,
 
John Fultz
jfultz at wolfram.com
User Interface Group
Wolfram Research, Inc.




  • Prev by Date: Re: Re: Weird result in Mathematica 6
  • Next by Date: Re: Re: Compatibility woes
  • Previous by thread: Re: Re: Re: Re: Re: 6.0 not seeing style
  • Next by thread: Re: Style sheet primer