nCoda Lychee Docs

Basic Concepts

Lychee manages an MEI document during a score editing session. Lychee performs nearly-instantaneous conversion between various representations (Abjad, LilyPond, and MEI) with optional version control integration, and provides a connection point for user interfaces (whether over the web, to a desktop application, or a commandline).

While Lychee is developed primarily for use as the core of nCoda, we are developing Lychee with other use cases in mind so that our work benefits a larger audience.

Introduction, Audiences, API Stability

This documentation is designed for three types of Lychee users, each with their own needs:

  1. People who want to use existing Lychee functionality for purposes we predicted, for example as the backend of nCoda. These users will primarily refer to the Session Management section. Furthermore, the Lychee version numbers are designed for these users: once we reach version 1.0, any backward-incompatible change to the Session Management API will be signalled with a new “major” version number, which we intend to be infrequent.
  2. People who want to use existing Lychee functionality for purposes we did not predict. (No example use case here, or else we would have predicted it). In addition to the Session Management API, we expect these users to be interested in the rest of the Workflow and Action Management APIs, the Lychee-MEI (LMEI) specification, the MEI Document Representation, the Views Processing (Partial Document Updates) functionality, and the VCS: Version Control System Management section. (Indeed, this includes most of Lychee). We have not yet decided what level of API stability to offer for these modules: backward-incompatible changes may be signalled either with a new “major” or “minor” version number.
  3. People developing Lychee, who may need to modify the behaviour of API functions, and who will be expected to use and develop internal interfaces where appropriate. In addition to the above, these users will be interested in class- and module-level private functions, including the inner workings of the format converters. Internal APIs may change at any time, so we have clearly marked them with a warning against use in external software. If you would like to use an internal Lychee API in external software, please ask us to consider making the internal API public!

There are two additional points worth making explicit. First, you may not fit cleanly into one of the categories described above. Second, there’s a good chance you won’t need to read most of the documentation here.

Starter Example

Lychee is a complex complex of software, but most functionality is simple enough to use! This example shows one way to get started with Lychee.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
import lychee.signals
import lychee.workflow

def print_converted(document, **kwargs):
    print(str(document))

sess = lychee.workflow.session.InteractiveSession()
lychee.signals.outbound.REGISTER_FORMAT.emit(dtype='verovio')
lychee.signals.outbound.CONVERSION_FINISHED.connect(print_converted)
sess.run_workflow(dtype='lilypond', doc="d''2")

Line 7: create an InteractiveSession instance so Lychee sets up the workflow.

Line 8: use REGISTER_FORMAT to ask Lychee to produce output suitable for Verovio.

Line 9: connect print_converted() so it is called when Lychee finishes outbound conversion.

Line 10: call run_workflow() on your InteractiveSession instance to give Lychee your LilyPond document (just a D half note in this case).

If you run this example in an interactive Python shell, you should see print_converted() print out an MEI document that can be used as input to Verovio. You will also see several log messages (note that CRITICAL indicates the importance of a message–remember to read the full message to see whether it indicates a success or failure!)

In the future, the REGISTER_FORMAT signal will be replaced by a method of the InteractiveSession class. However, CONVERSION_FINISHED will survive as the only means by which Lychee outputs data after running a workflow. While this is admittedly clumsy when using Lychee in an interactive Python shell, it’s very useful for Lychee’s intended use cases.

Program Modules

The following top-level modules constitute the core functionality of Lychee.

  • converters: A collection of encoding format converters between the internal Lychee-MEI (LMEI) format and various external representations (such as standard MEI, Abjad, and LilyPond). There are also modules to export data from the version control system, and information about the Lychee-MEI document itself.
  • document: Representation of a Lychee-MEI document. Manage files-on-disk, in-memory representations, and access document metadata without having to figure out all of Lychee-MEI.
  • namespaces: A collection of constants to be used as namespaced XML tag names and attribute names. Use these to avoid accidental use of non-namespaced tag names.
  • signals: Action definitions for use with Lychee’s event-driven programming model.
  • tui: Commandline textual interface.
  • vcs: Handles interaction with Mercurial, the version control system used internally by Lychee.
  • views: Functionality for Lychee to track several discrete musical fragments simultaneously, and to allow partial updates to documents.
  • workflow: Functionality required to set up and manage a Lychee document editing session, and to run the various workflow steps.

Generic Workflow

Lychee uses the same generic workflow for every action. There are four steps: inbound, document, VCS, and outbound. The inbound and outbound steps always have a conversion sub-step, and may also have a views sub-step. Depending on the runtime configuration and the action requested, Lychee may run only a single step, or up to all six.

The inbound step converts from an external format into Lychee-MEI (the inbound conversion). This will usually be followed by the inbound views step, where Lychee determines which portion of the Lychee-MEI document is modified by the incoming external document. The inbound step may be skipped if there is no incoming change, for example if a user wants to see the existing document in a different external format.

The document step creates, modifies, and deletes portions of the Lychee-MEI document according to the inbound change. Both the in-memory and on-disk representations may be modified. The document step may be skipped if there is no incoming change.

The VCS step manages the repository holding the Lychee-MEI document. This may involve committing a new changeset, updating to another bookmark, or even computing a diff. The VCS step may be skipped if there is no incoming change, if the VCS is disabled, or for many other reasons. Do note that the VCS step is disabled by default; you can enable it when you create an InteractiveSession instance.

The outbound step produces documents in an external format according to the (newly-changed) Lychee-MEI document. The outbound views step first determines which portion of the Lychee-MEI document to send out, then then outbound conversion step runs the conversion and emits the result. The outbound step may be skipped if no external formats are registered. The outbound views step may be skipped for external formats where it does not apply (like vcs_outbound). Also note that the outbound steps are repeated if more than one external format is registered.