Skip to content

Option Handling

Urs Liska edited this page Jul 5, 2017 · 2 revisions

As mentioned on the Basic Usage page packages and modules can be configured with options. Options that have been defined in the package/modules can be modified and retrieved with the \setOption and \getOption commands.

Handling Package/Module Options

\setOption <option-path> value sets the value of a registered option. Trying to set an option that is not registered will be discarded, but a warning is issued to help debugging the issue. The Scheme syntax (setOption ... can also be used, but note the difference in the symbol-list notation:

% suppress annotation output on console
\setOption scholarly.annotate.print ##f

% Set the “border-width” property of “analysis.frames”
#(setOption '(analysis frames border-width) 0.45)

\getOption <option-path> may be used to retrieve a value from options. This may not seem too useful in the case of package/module options, but there might be uses for it, especially if options are set programmatically:

% Current notehead style of the Just Intonation package
\getOption ji.show.notehead-style

% Targets to which annotations are exported
(getOption '(scholarly annotate export-targets))

Generic Use of Options

The option handling infrastructure is also very useful out of the package/module context, as it can be used to create a natural interface for the configuration of score appearance or compilation. Additionally it can be used to store arbitrary data for reuse in a score.

Disclaimer:
The implementation (and use) of this functionality will change significantly. Right now all package options, user configuration and data are maintained in one single tree object, which is convoluted and probably inefficient. This will be changed so the “generic” use will get a new command interface.

Registering Options

In order to be used options have to be registered with \registerOption <path> <init> where <path> is an arbitrary path in the tree an <init> the initial value (often this will be ##f or the empty list #'()). Note that the first element must not interfere with any other possible first-level element, including oll-core, loaded-packages, loaded-modules or any package name that may be loaded before or later. (If a custom option's first element should coincide with a package name the option tree branches will be merged, so this will not necessarily result in erroneous behaviour. However it should be avoided anyway.) In order to do that the first element should be something like my-options or another reference to “local”/“custom” or the concrete project. (This is one of the issues indicated by the above disclaimer).

\registerOption my-opts.score-type #'score
\registerOption local.last-editor "Urs Liska"
\registerOption custom.collection.intervals
#'((0 . #f)
   (1 . #f)
   (2 . #f)
   (3 . #f)
   (4 . #f)
   ; ...
   (12 . #f))

The last example may serve as an indication how openLilyLib options may be used to store data, in this case it might be filled with analytical data collected during the parsing of the music.

Once an option has been registered it can be accessed with \setOption and \getOption as described above.

Advanced Setting of Options

\setOption has an optional first boolean argument which - if set - makes the command behave like \registerOption by implicitly creating intermediate nodes before trying to access an unregistered option. This will rarely be useful except when the optional argument is for some reason or another determined programmatically.

\setChildOption <path> <child> <value> accepts a symbol-list as path (like \setOption) plus the name of a child option. The main path must exist but the child may implicitly be created. The main use of this command is when iterating over a list of options that aren't known in advance, for example from a \with {} block.

% Define an alist with grob names as keys and colors as values.
% This would be passed as items to a \with {} block
#(define options
  `((NoteHead . ,red)
    (Stem . ,green)
    (Flag . ,blue)))

#(for-each
   (lambda (o)
     (setChildOption '(local grob-colors) (car o) (cdr o)))
    options)

Retrieving Option Values

\getOptionWithFallback <path> <default> retrieves an option value, but different from the regular \getOption it doesn't fail when the option isn't registerd but instead returns the given default value.

\getChildOption <path> <child> corresponds to \setChildOption in so far as it appends the child node to the main path for retrieval.

\getChildOptionWithFallback <path> <child> <default> should by now be self-explaining.

Introspection of Options

oll-core provides some functions to inspect various aspects of the option tree.

\displayOption simply pretty-prints the whole option tree object. The function is useful for debugging and for learning about the internals of the option handling mechanism.

\describePackage <package> prints a (not-very-polished) representation of a (loaded) package's metadata (as provided by the package maintainer). It contains a number of interesting items, but the most commonly useful may be the list of exported modules in a package.

\displayModuleOptions <module> lists all options and values in a module or package. If <module> is a single symbol it is interpreted as a package name, if it is a symbol-list it's the path to a module. If either of them is not loaded (or e.g. misspelled) a warning is printed. This function is useful for finding out/recalling which options a module supports and to which value they are currently set.