Skip to content
Urs Liska edited this page Mar 24, 2015 · 2 revisions

General Usage of openLilyLib

Loading Libraries and Modules

Initializing openLilyLib

Given you have properly installed openLilyLib you initialize it by inserting

\include "openlilylib"

at the top of your input file. If you have several input files (or e.g. library files) you can use that command multiple times without worries as openLilyLib will only be included and parsed once.

Once openLilyLib has been initialized you have access to the libraries that are its individual parts. But apart from this you will already have access to openLilyLib's infrastructure, which consists of several concepts and a number of useful commands. (Basically openLilyLib makes the functionality it needs for itself available for end users or library developers.) This is discussed in Common Functionality.

This page describes the general concepts and commands for using openLilyLib. For information on any given library please refer to the library's documentation.

Loading Libraries

openLilyLib is a collection of libraries that extend LilyPond's functionality with specific features. In order to use these features a library has to be loaded with the command \useLibrary which exists in two forms:

\useLibrary <library-name> % Library names are case-insensitive

\useLibrary \with {
  optionOne = value        % option values can be of any Scheme type
  optionTwo = value
}
<library-name>

% Example
\include "openlilylib"
\useLibrary GridLY

\useLibrary \with
  colorize = ##f
}
scholarly

\useLibrary will load the given library if it hasn't already been loaded. If options are given they are passed to the library, but it is up to each library to make any use of them. Passing options that are not recognized by a library simply does nothing, so it doesn't harm either.

Loading Modules

Some libraries expose their full functionality as a self-contained unit by loading the library, while others provide more control and allow loading their functionality in fine-grained units or modules.

Loading a module is very similar to loading a library, and the command \useModule has a very similar interface to \useLibrary:

\useModule #'(<library> path to module)

\useModule \with {
  optionOne = value
  optionOne = value
}
#'(<library> path to module)

% Example:
\include "openlilylib"
\useLibrary ScholarLY
\useModule #'(scholarly annotate)

Again, modules are loaded only once, and it is up to the library maintainers to support options or not.

Note: Before a module is loaded the containing library has to be loaded, as \useModule isn't capable of implicitly loading the library (yet).

Note: In theory \useModule can also be invoked using the dotted list notation, e.g. \useModule scholarly.annotate, but due to a parser bug in LilyPond (that was discovered on this occasion) this can cause problems depending on what comes next in the input file. Basically if the next item is a Scheme expression everything works fine but LilyPond expressions tend to fail. If you want to use the more modern dot notation you can always add an "empty" expression afterwards, e.g.

\include "openlilylib"
\useLibrary ScholarLY
\useModule scholarly.annotate
#(display "")
%...

Unified Configuration

openLilyLib provides a unified interface to handling library configuration. Libraries and modules can expose options to configure their behaviour. You have already seen the options that can be passed to a library or module while loading them, but options can be set (with some more control) with the independent command \setOption:

\setOption <library.path.to.option> <value>

% Examples
\setOption scholarly.annotate.print ##t
\setOption comptools.page-breaks #'(20 37 52 66 83 91)

Some options may be changed along the way (e.g. to switch a feature on and off) while others have a global effect. Please refer to the library's documentation for more information on the available options and their effects.

Users can make use of this unified interface to store data or options for their own purposes, e.g. in house or project libraries. Please refer to Common Functionality for more information.

Basic Interface for Library Writers

TODO: All of the following should be moved to a dedicated Contributor's Guide. It was a bad idea in the first draft to mix things up that way.

Each library lives in the repository's /ly directory and the top-level directory name corresponds to the library name.

Library Initialization

A library can have a file __init__.ly inside its main directory. If present this file is read before for the first time any module from within the library is loaded. So you can use that file for setting up any common infrastructure, for example to initialize shared variables.

Configuration Management

It is strongly recommended that libraries use configuration variables to control their behaviour (if any kind of behaviour control is appropriate for the library). For this openLilyLib provides a unified infrastructure as already described above. A library can maintain any number of (nested) options that are centrally managed through openLilyLib. To make options known to the system (and accessible to the user) use the \registerOption command in the library's __init__.ily file:

\registerOption <library.path.to.option> <default>
% Example
\registerOption test.my.option "Hello"
\registerOption test.my.other-option #f

Options specified this way can be retrieved with \getOption as described above, and the user can use \setOption to configure the library's behaviour in concrete projects.

Options can have any kind of Scheme value, which also includes (nested) lists or even music expressions (for example key or time signatures or markup). It is up to the library maintainers to make use of that variety, but may we will provide extended functionality to manage complex options in the future.

Directory Structure

Generally we suggest libraries to have flat directory structures, that is usually all files should live within the root directory of the library. A hierarchical representation is set up through the metadata and tags in particular. However it is of course possible to use subdirectories to group functionality that belongs together.

Loading Modules and Individual Units

Any directory (and this includes the library's root directory) can contain a __main__.ily file which represents the directory as a module. Loading that file is considered loading that module, and the file should behave accordingly and load the whole module. The main files are not loaded directly but by passing the containing directory name as the argument to \loadModule. If there is a library test containing a sub directory containing a __main__.ily file then \loadModule "test/sub" will load __main__.ily from within test. If you want users to be able to load the library as a whole write the appropriate code in test/__main__.ily.

Clone this wiki locally