Features Help Download

Lomse Hacking Guide

2.1. The Document class

Lomse operates in the domain of music books. That is, Lomse deals with documents, written in LDP language, containing texts, images, scores, exercises, graphics, headers, footers, etc.

The LDP language is an ‘external representation’, that is, something oriented to be stored in a file and to be human readable, easy to enter with a QWERTY keyboard.

This type of representation is not the most appropriate for processing. Therefore, to be usable in a program it has to be transformed into a suitable format, more flexible and powerful for processing. This is the ‘internal model’, to be described later.

The Document class is a facade object that contains, basically, the internal model for the LDP document. The Document class encapsulates all the library internals, providing the basic API for creating and using an LDP document.

It is an observable class and, therefore, inherits methods for notifying observers (other registered objects) when changes occur to the document.

From a Lomse user application point of view, the only mechanism for creating a Document is by requesting it to the LomseDoorway object. See LomseDoorway class for details on using the library and creating documents.

Internally, a Document object is created by compiling the LDP code that describes its content. See Document object creation, later in this chapter.

2.1.1. The InternalModel class

The InternalModel is a container for the objects that describe the content of an LDP document. These objects are generically named “Internal Model Objects” or, simply, “IMOs”.

There is, practically, a one-to-one correspondance between LDP elements and IMO objects. So, for instance, LDP tag ‘score’ is modelled by a ImoScore object.

The internal model is, basically, a tree of IMOs, and the InternalModel object contains the tree root. This root object is, normally, an ImoDocument object. It represents the content of a LDP tag ‘lenmusdoc’, that is, a whole LDP document. IMO objects and the structure of the internal model tree is described in detail in section The internal representation.

Class Document could have stored the root of the IMO tree, making class InternalModel unnecessary, but I preferred to create a proxy object, InternalModel to create an isolation and abstraction layer. That gave me more freedom to change the internal model design without affecting other classes.

Important

The real important ‘thing’ is not class InternalModel but its content: the tree of IMO objects. Therefore, along this document the term ‘internal model’ will be used for refering to the tree of IMO objetcs, reserving word InternalModel to refer to that specific class.

Another source of trouble, at beginning, is the difference between classes Document and ImoDocument. As said, class Document is a container for class InternalModel wich in turn contains the root node of the internal model: an object of class ImoDocument. Therefore, both objects, Document and ImoDocument, represents the same thing: the content of an LDP document. The only difference is the point of view:

  • global point of view: Document class as the object managed by the Lomse library, or
  • internal model representation: ImoDocument class as the root node of the representation.

Therefore, althought the term ‘document’ could refer both to class Document or to class ImoDocument, in practise there sould not be any problem, as context information would give you a clue.

The internal model is described in detail in chapter The internal representation.

2.1.2. Document object creation

A Document object is created by compiling the LDP code that describes its content. There are five alternatives:

int from_file(const std::string& filename);
int from_string(const std::string& source);
int from_input(LdpReader& reader);
void create_empty();
void create_with_empty_score();

Method from_file receives the full path to a local filesystem file. Lomse library can deal with .lms plain files and .lmb zipped files. There are plans to extend Lomse to deal with MusicXML files an LDP files in XML and compressed XML format.

For other LDP sources (i.e. database, network) methods from_string and from_input provides great flexibility for extending the options to solve any application needs. It is just either:

  • developing code to get the LDP content from your specific sources and passing it as string to the Lomse library, or
  • developing a reader for your specific database/filesystem and passing it to method from_input.

All these methods passes the LDP source to a Compiler object and it creates the InternalModel as result. See The LDP compiler for details.