+@node Simple Specifier Usage
+@section Simple Specifier Usage
+@cindex specifier examples
+@cindex examples, specifier
+@cindex adding a button to a toolbar
+@cindex toolbar button, adding
+
+A useful specifier application is adding a button to a toolbar. XEmacs
+provides several toolbars, one along each edge of the frame. Normally
+only one is used at a time, the default. The default toolbar is
+actually a specifier object which is the value of
+@code{default-toolbar}. @xref{Toolbar Intro}.
+
+The specification of a toolbar is simple: it is a list of buttons.
+Each button is a vector with four elements: an icon, a command, the
+enabled flag, and a help string. Let's retrieve the instance of the
+toolbar you see in the selected frame.
+
+@example
+(specifier-instance default-toolbar)
+@end example
+
+The value returned is, as promised, a list of vectors. Now let's build
+up a button, and add it to the toolbar. Our button will invoke the last
+defined keyboard macro. This is an alternative to
+@code{name-last-kbd-macro} for creating a persistent macro, rather than
+an alias for @kbd{C-x e}.
+
+A toolbar button icon can be quite sophisticated, with different images
+for button up, button down, and disabled states, and a similar set with
+captions. We'll use a very simple icon, but we have to jump through a
+few non-obvious hoops designed to support the sophisticated applications.
+The rest of the button descriptor is straightforward.
+
+@example
+(setq toolbar-my-kbd-macro-button
+ `[ (list (make-glyph "MyKbdMac"))
+ (lambda () (interactive) (execute-kbd-macro ,last-kbd-macro))
+ t
+ "Execute a previously defined keyboard macro." ])
+
+(set-specifier default-toolbar
+ (cons toolbar-my-kbd-macro-button
+ (specifier-specs default-toolbar 'global))
+ 'global)
+@end example
+
+To remove the button, just substitute the function @code{delete} for the
+@code{cons} above.
+
+What is the difference between @code{specifier-instance}, which we used
+in the example of retrieving the toolbar descriptor, and
+@code{specifier-specs}, which was used in the toolbar manipulating code?
+@code{specifier-specs} retrieves a copy of the instantiator, which is
+abstract and does not depend on context. @code{specifier-instance}, on
+the other hand, actually instantiates the specification, and returns the
+result for the given context. Another way to express this is:
+@code{specifier-specs} takes a @emph{locale} as an argument, while
+@code{specifier-instance} takes a @emph{domain}. The reason for
+providing @code{specifier-instance} is that sometimes you wish to see
+the object that XEmacs will actually use. @code{specifier-specs}, on
+the other hand, shows you what the programmer (or user) requested. When
+a program manipulates specifications, clearly it's the latter that is
+desirable.
+
+In the case of the toolbar descriptor, it turns out that these are the
+same: the instancing process is trivial. However, many specifications
+have non-trivial instancing. Compare the results of the following forms
+on my system. (The @samp{(cdr (first ...))} form is due to my use of
+Mule. On non-Mule XEmacsen, just use @code{specifier-specs}.)
+
+@example
+(cdr (first (specifier-specs (face-font 'default) 'global)))
+=> "-*--14-*jisx0208*-0"
+
+(specifier-instance (face-font 'default))
+#<font-instance "-*--14-*jisx0208*-0" on #<x-device on ":0.0" 0x970> 0xe0028b 0x176b>
+@end example
+
+In this case, @code{specifier-instance} returns an opaque object;
+programs can't work on it, they can only pass it around. Worse, in some
+environments the instantiation will fail, resulting in a different value
+(when another instantiation succeeds), or worse yet, an error, if all
+attempts to instance the specifier fail. @code{specifier-instance} is
+context-dependent, even for the exact same specification.
+@code{specifier-specs} is deterministic, and only depends on the
+specifications.
+
+Note that in the toolbar-changing code we operate in the global locale.
+This means that narrower locales, if they have specifications, will
+shadow our changes. (Specifier instancing does not merge
+specifications. It selects the "highest-priority successful
+specification" and instances that.)
+
+In fact, in our example, it seems pretty likely that different buffers
+@emph{should} have different buttons. (The icon can be the same, but
+the keyboard macro you create in a Dired buffer is highly unlikely to be
+useful in a LaTeX buffer!) Here's one way to implement this:
+
+@example
+(setq toolbar-my-kbd-macro-button
+ `[ (list (make-glyph "MyKbdMac"))
+ (lambda () (interactive) (execute-kbd-macro ,last-kbd-macro))
+ t
+ "Execute a previously defined keyboard macro." ])
+
+(set-specifier default-toolbar
+ (cons toolbar-my-kbd-macro-button
+ (cond ((specifier-specs default-toolbar
+ (current-buffer)))
+ ((specifier-specs default-toolbar
+ 'global)))
+ (current-buffer))
+@end example
+
+Finally, a cautionary note: the use of @code{specifier-specs} in the
+code above is for expository purposes. Don't use it in production code.
+In fact, the @code{set-specifier} form above is likely to fail
+occasionally, because you can add many specifications for the same
+locale.
+
+In these cases, @code{specifier-specs} will return a list. A further
+refinement is that a specification may be associated with a set of
+@dfn{specifier tags}. If the list of specifier tags is non-nil, then
+@code{specifier-specs} will return a cons of the tag set and the
+instantiator. Evidently @code{specifier-specs} is a bit unreliable.
+(For toolbars, the code above should work 99% of the time, because
+toolbars are rarely changed. Since instantiation is trivial, multiple
+specs are not useful---the first one always succeeds.)
+
+In fact, @code{specifier-specs} is intended to be used to display specs
+to humans with a minimum of clutter. The robust way to access
+specifications is via @code{specifier-spec-list}. @xref{Adding
+Specifications}, for the definition of @dfn{spec-list}. @xref{Retrieving
+Specifications}, for documentation of @code{specifier-specs} and
+@code{specifier-spec-list}. To get the desired effect, replace the form
+@code{(specifier-spec default-toolbar 'global)} with
+
+@example
+(cdr (second (first (specifier-spec-list default-toolbar 'global))))
+@end example
+
+(It should be obvious why the example uses the lazy unreliable method!)
+