Skip to content

Automatic Code Generation

ahankinson edited this page Mar 1, 2012 · 15 revisions

MEI Customization process

The core MEI schema is written using an XML "meta-schema" language developed by the Text Encoding Initiative. "ODD," or "One-Document-Does-it-all" allows developers to create formal rules for the encoding language (MEI or TEI) but also provides the ability to supply the documentation inline with the rules.

Once these rules and documentation are in place, the Roma processor can be used to generate a formal XML Schema language (RelaxNG, W3C Schema, i.e., XSD, or DTD) RelaxNG is the preferred schema language for validating MEI-encoded files. Roma may also be used to generate HTML or PDF documentation for the schema.

One further advantage to using ODD is the idea of customizations. Roma requires two ODD-encoded files: A "source" containing all possible element and attribute definitions separated into logical modules (e.g. MEI.mensural for mensural notation, MEI.neumes for neume notation, etc.), and a "customization" which defines which modules should be in the resulting XML schema and documentation. MEI comes with a default customization which turns on all modules.

Also included in this customization process is the ability to define new elements or attributes, or even re-define existing elements and attributes in the source. Adding a new type of music notation to MEI would simply require a customization file that defines the logic for that specific type of notation. See, for example, an existing customization file for defining a new approach to neume notation. How this works is beyond the scope of this document, but it is important to know that this exists.

Generating a custom libmei library

The parseschema2.py script in the tools/ directory allows developers to supply an MEI customization and the script will generate custom C++ code that defines explicit classes for each element in MEI, and getters and setters for every attribute defined on them. Libmei ships with the most recent versions of the MEI modules in the src/modules directory.

The easiest way to generate a new library is by using a pre-compiled ODD file. You can either install the roma2 script from the TEI project (Instructions) or you can use the MEI Customization web service. Either of these will generate a "Compiled ODD" file.

To generate new C++ modules, run the parseschema2.py script with the compiled ODD, e.g.,:

$> python parseschema2.py -m compiled_odd.xml -o src -l cpp

Where -m is the path to the compiled ODD, -o is the output directory for the modules, and -l is the language you wish to output. This will generate the .cpp and .h files for the elements in each of the MEI modules.

The Includes process

While getters and setters on the attributes of all the elements expose quite a bit of functionality, there are other functions that are specific to some elements that it would be nice to support, like getMembers() on a <tie> element. However, since all the code is auto-generated from the MEI spec, we need a way to "include" extra methods that doesn't get clobbered when we re-generate the library.

When we auto-generate the MEI module code, we place special comments on each element that look like this:

C++ /* include <elementname> */

Python # <elementname>

Clone this wiki locally