MEI Document Representation¶
Most external developers will not need to use this module directly. We recommend using functionality in Workflow and Action Management whenever possible.
Document class represents a Lychee-MEI document. If version control integration is
enabled, this is managed by the
Guidelines for Using Lychee-MEI Documents¶
These guidelines help guarantee the integrity of the LMEI document, and avoid duplicating error-prone code. These are absolute requirements for Lychee developers and very strong recommendations for external Lychee users.
- For every capability the
Documentclass offers, no other module or class may offer this functionality. This avoids duplicating functionality and thereby introducing possible errors. Other modules and classes may “shadow”
- No filesystem access can happen outside the
documentmodule. The version control system is an exception, though it must be used properly (for example, through the
mercurial-hugmodule) and in the proper place (
lychee.vcs). This helps manage a range of potential problems, like XML-related security issues, data races, and so on.
- Document manipulation at a level higher than a Lychee-MEI
<section>should be performed by the
Documentclass itself. In a situation of “worst case” corruption, where a Lychee-MEI file cannot be loaded from the filesystem, this allows recovering the rest of a document by discarding or ignoring the corrupted
- Capabilities offered by private functions and methods in the
documentmodule may be changed to a public function or method if required by another module. Before doing this, carefully consider the implications: once a function or method becomes part of the public API, it is very difficult to change. Would it be better to add the functionality to the
Documentclass? Should the function or method be renamed? Does the function or method make sense in the context of the other public functions and methods?
Lychee developers may be interested in the internal functions and methods, documented here:
Document Module Public Interface¶
Object representing an MEI document. Use methods prefixed with
getto obtain portions of the document, automatically loading from files if required. Use methods prefixed with
putto submit a new portion to replace the existing portion outright.
If you do not provide a
repository_pathargument to the initialization method, no files will be written. Additionally, the
save_everything()method therefore will not work, and all
get_()methods will not return useful data until they have been given data.
When you use a
put_()method, the element(s) replace those already present in this
Documentinstance, but they will not be written to the document’s directory until you call
save_everything()or the context manager exits, if applicable.
The recommended way to use a
Documentwith file output is as a context manager (using a
withstatement). This way, you cannot forget to save your changes to the filesystem.
Getter for elements in the
Parameters: what (str) – The element name to find. See the list of valid values below. Returns: A list of the requested elements. Return type: list of
You may request the following elements:
- a role (arranger, author, composer, editor, funder, librettist, lyricist, or sponsor)
The “respStmt” child elements describe Lychee users who have edited this document, whether or not they hold a more specific role.
Also note that, if a role-specific element (such as
<composer>) corresponds to a Lychee user, the role-specific element will contain a
<persName>with a @nymref attribute that holds the @xml:id value of a
<persName>given in the
<respStmt>. For example, if this work’s composer is also the only person who has edited this score:
>>> etree.dump(doc.get_from_head('composer')) <composer> <persName nymref="#p1234"/> </composer> >>> etree.dump(doc.get_from_head('respStmt')) <respStmt> <persName xml:id="p1234"> <persName type="full">Danceathon Smith</persName> </persName> </respStmt>
At this point in time,
get_from_head()does not raise (its own) exceptions. If the “what” argument is invalid, this is treated the same as a missing element, so the return value will be
Load and return the MEI header metadata.
<meiHead>portion of the MEI document.
<meiHead>element is missing or it contains a
<ptr>without a @target attribute
Load and return the whole score, excluding metadata and “inactive”
<score>element with relevant
<section>elements in the proper order.
lychee.exceptions.SectionNotFoundErrorif one or more of the
<section>elements require for the
<score>cannot be found.
Caches the returned
<score>for later access.
Load and return a section of the score.
Returns: The section with an
<section>with the specified @xml:id can be found.
<section>is found but cannot be loaded because it is invalid.
If the section is not already loaded,
get_section()will try to fetch it from the filesystem, if a repository is configured.
By default, return the ordered @xml:id attributes of active
<section>elements in this score. If
True, return the @xml:id attributes of all
<section>elements in this MEI document, in arbitrary order.
Parameters: all_sections (bool) – Whether to return the IDs of all sections in this document, rather than just the sections currently active in the score. Returns: A list of the section IDs. Return type: list of str
<section>to another position in the score.
<section>to move is not found in the repository.
Note that this function simply moves the indicated section to the requested position, but does not save the
Documentinstance or anything else (e.g., does not cause an outbound conversion that would update code external to Lychee).
Save new header metadata.
Param: new_head: An
<meiHead>element that should replace the existing one.
get_from_head(), but with setting instead.
This method is not implemented. Refer to T109 for more information.
Save a new score in place of the existing one.
Parameters: new_music (
lxml.etree.Element) – The <score> element to use in place of the existing one.
Returns: The @xml:id attributes of all top-level
<section>elements found in
new_music, in the order they were found.
Return type: list of str
The “score order” in
new_musicreplaces the existing “score order.” Note that existing <section> elements that aren’t part of
new_musicare not deleted—they remain tracked internally. Also note that any <section> elements already contained in the local list of sections is replaced by the section that has a matching @xml:id in
new_music. Sections that don’t have an @xml:id will be given one.
Add or replace a
<section>in the current MEI document.
Parameters: new_section (
lxml.etree.Element) – A new section or a replacement for an existing section with the same @xml:id attribute.
Returns: The @xml:id of the saved
Return type: str
new_sectionis missing an @xml:id attribute, or has an invalid @xml:id attribute, a new one is created.
Write the MEI document(s) into files.
Returns: A list of the absolute pathnames that are part of this Lychee-MEI document. Return type: list of str Raises:
lychee.exceptions.CannotSaveErrorif the document cannot be written to the filesystem (this happens when
repository_pathwas not supplied on initialization).
A Lychee-MEI document is a complex of various XML elements. This method arranges for the documents stored in memory to be saved into files in the proper arrangement as specified by the order.
Note that the return value includes any file in the document. The files may not have been modified, and in fact may not even have been saved at all—they are simply part of this document.