openlyrics-parser
Version:
Parses and extracts data from OpenLyrics files, and creates them!
429 lines (352 loc) • 26.1 kB
Markdown
# Documentation & Examples: Building/Creating OpenLyrics XML Files
## Usage
Simply import `OpenLyricsBuilder`, then pass the song data to it, and it will return a `string` of XML data which you can then do what you need to with it.
### For TypeScript projects
```typescript
import { OpenLyricsBuilder, IBuilderOptions } from 'openlyrics-parser';
const opts: IBuilderOptions = {
properties: { titles: 'Amazing Grace' },
verses: [
{
name: 'v1',
lines: ['Amazing grace how sweet the sound', 'that saved a wretch like me'],
},
],
};
const xmlDoc: string = OpenLyricsBuilder(opts);
console.log(xmlDoc);
```
### For JavaScript projects
```javascript
const { OpenLyricsBuilder } = require('openlyrics-parser');
const opts = {
properties: { titles: 'Amazing Grace' },
verses: [
{
name: 'v1',
lines: ['Amazing grace how sweet the sound', 'that saved a wretch like me'],
},
],
};
const xmlDoc = OpenLyricsBuilder(opts);
console.log(xmlDoc);
```
## Documentation
A single object is passed to `OpenLyricsBuilder` which has 5 possible properties on it, two of which are required.
- [`meta` Object](#meta-object)
- [`properties` Object - ⚠️REQUIRED](#properties-object---⚠️required)
- [`format` Array](#format-array)
- [`verses` Array - ⚠️REQUIRED](#verses-array---⚠️required)
- [`instruments` Array](#instruments-array)
For most simple songs you will only need to bother with the `properties` object and `verses` array.
### `meta` Object
This object is optional and it contains information about the document itself. The property names match the names specified in [the OpenLyrics Metadata docs](https://docs.openlyrics.org/en/latest/dataformat.html#metadata).
| Property | Type | Required | Default Value |
|:--------------|:---------|:---------|:----------------------------|
|`createdIn` | `string` | No | `'openlyrics-parser 1.1.1'` |
|`chordNotation`| `string` | No | `undefined` |
|`lang` | `string` | No | `'en'` |
|`modifiedIn` | `string` | No | `'openlyrics-parser 1.1.1'` |
### `properties` Object - ⚠️REQUIRED
This required object contains information about the song. Read about the properties in [the OpenLyrics Song Properties docs](https://docs.openlyrics.org/en/latest/dataformat.html#song-properties)
| Property | Type | Required | Description |
|:----------------------------|:-------------------------------|:---------|:----------------------------|
| `titles` | `string` or `IBuilderTitle[]` | ⚠️Yes | For a simple single title just provide a string. For multiples, an array of objects: See [the `IBuilderTitle[]` docs](#properties--titles-ibuildertitle) below. |
| `authors` | `string` or `IBuilderAuthor[]` | No | For a simple single author just provide a string. For multiples, an array of objects: See [the `IBuilderAuthor[]` docs](#properties--authors-ibuilderauthor) below. |
| `ccliNo` | `string` or `number` | No | The CCLI license number for this song |
| `comments` | `string[]` | No | Any additional, unspecified user data about this song |
| `copyright` | `string` or `number` | No | The copyright information of the song. In some countries it is a legal requirement to display copyright information during the presentation of songs. The <copyright> tag has no specific format, though it is recommended that the value contains at least the year and copyright holder of the song |
| `key` | `string` | No | The key the song is in, eg: `'C#'` |
| `keywords` | `string` | No | A space separated list of words used for more precise results when searching for a song in a song database |
| `publisher` | `string` | No | The publisher of the song |
| `released` or `releaseDate` | `string` or `number` | No | The year or date when a song was released or published. OpenLyrics 0.8 uses the `releaseDate` property, while 0.9 uses `released`. Using either one will result in the `released` property being set for version 0.9 compatibility |
| `songBooks` | `IBuilderSongBook[]` | No | Most songs come from some sort of collection of songs (a book or a folder of some sort). It may be useful to track where the song comes from. See [the `IBuilderSongBook[]` docs](#properties--songbooks-ibuildersongbook) below.|
| `tempo` | `string` or `number` | No | The tempo of the song, which can be expressed as a number, eg: `90` (as BPM), or as text, eg: `'slow'` or `'moderate'` |
| `themes` | `IBuilderTheme[]` | No | Used to categorize the song. See [the `IBuilderTheme[]` docs](#properties--themes-ibuildertheme) below.|
| `timeSignature` | `string` | No | Used to define the time signature of the song, eg: `'3/4'` |
| `transposition` | `string` or `number` | No | Used when it is necessary to move the key or the pitch of chords up or down. The value must be an integer between `-11` and `11` |
| `variant` | `string` | No | A description which is used to differentiate songs which are identical, but may be performed or sung differently |
| `verseOrder` | `string` | No | A space-separated string of verse and instrument `name`s defines the order in which the verses and instrumental parts are typically sung or performed. eg: `'v1 v2 c c v1'` |
| `version` | `string` or `number` | No | Any text or "version number" of the song since song can be updated over time, sometimes to add additional verses, sometimes to fix spelling or grammatical errors |
#### `properties` => `titles: IBuilderTitle[]`
If a song has more than one title you must provide the titles in the form of these object. Each title object can have these properties. See [the OpenLyrics Titles documentation](https://docs.openlyrics.org/en/latest/dataformat.html#titles) for more information
| Property | Type | Required | Description |
|:----------------|:---------|:---------|:--------------------------|
|`value` | `string` | ⚠️Yes | The title of the song |
|`lang` | `string` | No | The language of the title, eg: `'en'` or `'de'`. This should match languages specified elsewhere if different from the document language. |
|`transliteration`| `string` | No | If a title has been transliterated from another language, store that language code here. Only set this when also setting `lang`
|`original` | `boolean`| No | This marks a particular title as being the original title. You only need to set this to `true` on one title, you can omit setting a value on all other titles |
**Examples**
```js
[
{ value: "Amazing Grace", lang:'en-US', original: true },
{ value: 'Erstaunliche Anmut', lang: 'de-DE' }
]
```
<!-- cSpell:disable -->
```js
[
{ value: "הבה נגילה", lang: 'he', },
{ value: 'Hava Nagila', lang: 'he', transliteration: 'en' },
{ value: 'Hava naguila', lang: 'he', transliteration: 'fr' },
{ value: 'Let Us Rejoice', lang: 'en' },
{ value: 'Réjouissons-nous', lang: 'fr' },
]
```
<!-- cSpell:enable -->
#### `properties` => `authors: IBuilderAuthor[]`
If a song has more than one author you must provide the authors in the form of these object. Each author object can have these properties. See [the OpenLyrics Authors documentation](https://docs.openlyrics.org/en/latest/dataformat.html#authors) for more information
| Property | Type | Required | Description |
|:----------|:---------|:---------|:--------------------------|
|`value` | `string` | ⚠️Yes | The author name |
|`type` | `string` | No | The type of author, eg: `'words'`, `'music'`, `'translation'`, or `'arrangement'`|
|`lang` | `string` | No | The language the song has been translated to by this author. This is only needed if the author `type` is `'translation'`. This should match languages specified elsewhere if different from the document language. |
**Example**
```js
[
{ value: 'John Newton' },
{ value: 'Chris Rice', type: 'words' },
{ value: 'Richard Wagner', type: 'music' },
{ value: 'František Foo', type: 'translation', lang: 'cs' },
]
```
#### `properties` => `songBooks: IBuilderSongBook[]`
Most songs come from some sort of collection of songs (a book or a folder of some sort). It may be useful to track where the song comes from. Each song book object can have these properties. Read more about them in [the OpenLyrics SongBooks docs](https://docs.openlyrics.org/en/latest/dataformat.html#song-books)
| Property | Type | Required | Description |
|:----------|:---------------------|:---------|:--------------------------|
|`name` | `string` | ⚠️Yes | The name of the song book |
|`entry` | `string` or `number` | No | The index of the song within the song book. This could be a page number for example |
**Example**
```js
[
{ name: "Rippon's Selection of Hymns" },
{ name: 'My Cool Hymn Book', entry: 42 },
{ name: 'Another Book', entry: '19b' },
]
```
#### `properties` => `themes: IBuilderTheme[]`
Themes are used to categorize songs. Having songs categorized can be useful when choosing songs for a ceremony or for a particular sermon topic. Each theme just has a simple string value and an optional language specified. Read about them in [the OpenLyrics Themes docs](https://docs.openlyrics.org/en/latest/dataformat.html#themes)
| Property | Type | Required | Description |
|:----------|:---------|:---------|:-----------------------------|
|`value` | `string` | ⚠️Yes | A single theme for this song |
|`lang` | `string` | No | The language of this theme. This should match languages specified elsewhere if different from the document language. |
**Example**
<!-- cSpell:disable -->
```js
[
{ value: 'Adoration' },
{ value: 'Adoração', lang: 'pt-BR' },
{ value: 'Grace', lang: 'en-US' },
{ value: 'Graça', lang: 'pt-BR' },
{ value: 'Salvation', lang: 'en-US' },
{ value: 'Salvação', lang: 'pt-BR' },
]
```
<!-- cSpell:enable -->
### `format` Array
This optional object contains information about any custom format tags on the document. Read about them in [the OpenLyrics Formatting Extensions docs](https://docs.openlyrics.org/en/latest/dataformat.html#formatting-extensions). You should only need to use this if your song will use custom `<tag>` nodes which your song presentation software can interpret.
| Property | Type | Required | Default Value |
|:--------------|:----------------------|:---------|:----------------------------|
|`application` | `string` | ⚠️Yes | The name of the target application or processor identifier that will use the specified format tags |
|`tags` | `IBuilderFormatTag[]` | ⚠️Yes | An array of tag objects, described below |
#### `format` => `tags: IBuilderFormatTag[]`
| Property | Type | Required | Default Value |
|:---------|:---------|:---------|:----------------------------|
|`name` | `string` | ⚠️Yes | The name of this tag |
|`open` | `string` | ⚠️Yes | The opening portion of this tag. This will be prepended to whatever text is wrapped in a `<tag>` within the lyrics. |
|`close` | `string` | ⚠️Yes | The closing portion of this tag. This will be appended to whatever text is wrapped in a `<tag>` within the lyrics. |
ℹ️ Note: If the `open` or `close` contains any XML/HTML carat characters they will be automatically replaced with the corresponding HTML entity so it can be stored properly within the song XML document. For example: `<` is replaced with `<` and `>` is replaced with `>` .
**Example**
```js
[
{
application: 'CoolLyricsPro XD',
tags: [
{ name: 'red', open: '<span style="color:red">', close: '</span>' },
{ name: 'bold', open: '<strong>', close: '</strong>' }
],
},
{
application: 'A Different App',
tags: [
{ name: 'red', open: '{{red|', close: '}}' },
{ name: 'bold', open: '{{bold|', close: '}}' }
],
},
]
```
### `verses` Array - ⚠️REQUIRED
This required array of objects is used to describe all of the words of the song and other data related to them. Read about the supported properties on [the OpenLyrics Song Lyrics docs](https://docs.openlyrics.org/en/latest/dataformat.html#song-lyrics)
| Property | Type | Required | Default Value |
|:-----------------|:------------------------------------|:---------|:----------------------------|
|`name` | `string` | ⚠️Yes | The name of this verse. Can be anything string like: `'v1'`, `'v2'`, `'c'`, etc. |
|`lines` | `string[]` or `IBuilderVerseLine[]` | ⚠️Yes | Each verse can contain multiple "lines" of text. Pass a string in the array for each line. Any `\n`or `\r` line break character will be transformed into a `<br/>` tag. Alternatively for anything more complex an `IBuilderVerseLine[]` may be passed instead of a plain `string[]` See [the `IBuilderVerseLine[]` Docs](#verses--lines-ibuilderverseline) below. |
|`optionalBreak` | `boolean` | No | If `true` an application can decide to break the verse in two slides if it doesn’t fit on one screen |
|`lang` | `string` | No | The language this verse is written in. This should match languages specified elsewhere if different from the document language. |
|`transliteration` | `string` | No | If a verse has been transliterated from another language, store that language code here. Only set this when also setting `lang` |
#### `verses` => `lines: IBuilderVerseLine[]`
| Property | Type | Required | Default Value |
|:-----------------|:-----------------------------|:---------|:----------------------------|
| `content` | `IBuilderVerseLineContent[]` | ⚠️Yes | An array of items that can appear on this line of this verse. See [the `IBuilderVerseLineContent[]` docs](#verses--lines--content-ibuilderverselinecontent) below. |
| `part` | `string` | No | This line of this verse can have a part, for example `'men'` or `'women'` are common parts to use. Read more about this on [the OpenLyrics Verse Parts Docs](https://docs.openlyrics.org/en/latest/dataformat.html#verse-parts-groups-of-lines) |
| `optionalBreak` | `boolean` | No | If `true` an application can decide to break this line in two slides if it doesn’t fit on one screen |
| `repeat` | `number` | No | The number of times this particular line should be repeated. Read more about this on [the OpenLyrics Line Repeat Docs](https://docs.openlyrics.org/en/latest/dataformat.html#line-repeat) |
#### `verses` => `lines` => `content: IBuilderVerseLineContent[]`
The content of a line on a verse can be one of four types: `'text'`, `'comment'`, `'tag'`, or `'chord'` . Each of these object types have slightly different properties.
See the examples below to understand how to best use the objects together to get the desired XML output.
**Verse Line Content Object Type: `text`**
A text object is used to define song lyric text
| Property | Type | Required | Default Value |
|:---------|:-----------|:---------|:----------------------------|
|`type` | `'text'` | ⚠️Yes | Setting `type:'text'` defines this as song lyric content. |
|`value` | `string` | ⚠️Yes | The lyric text content. Any `\n`or `\r` line break character will be transformed into a `<br/>` tag. |
**Verse Line Content Object Type: `comment`**
A comment object is used to adding non-visible information about a particular part of a song. For example, a comment could contain the style in which to play or sing any particular set of lyrics.
Read more about this in [the OpenLyrics Lyric Comments Docs](https://docs.openlyrics.org/en/latest/dataformat.html#comments-in-lyrics)
| Property | Type | Required | Default Value |
|:---------|:-----------|:---------|:----------------------------|
|`type` | `'comment'`| ⚠️Yes | Setting `type:'comment'` defines this as a comment |
|`value` | `string` | ⚠️Yes | The text of the comment |
**Verse Line Content Object Type: `tag`**
A tag object is used to adding non-visible information about a particular part of a song. For example, a comment could contain the style in which to play or sing any particular set of lyrics.
Read more about this in [the OpenLyrics Lyric Comments Docs](https://docs.openlyrics.org/en/latest/dataformat.html#comments-in-lyrics)
| Property | Type | Required | Default Value |
|:---------|:-----------|:---------|:----------------------------|
|`type` | `'tag'` | ⚠️Yes | Setting `type:'tag'` defines this as a tag |
|`name` | `string` | ⚠️Yes | The name of the tag defined in [the `format` => `tags` property](#format--tags-iformattag) on the song |
|`value` | `string` | ⚠️Yes | The text that appears between the opening and closing tag |
**Verse Line Content Object Type: `chord`**
A chord object is used do define a chord that should be played at a particular part of a song. A chord can exist before a certain word in the lyrics, or it can contain a particular set of lyrics within it.
Read more about this in [the OpenLyrics Chords Docs](https://docs.openlyrics.org/en/latest/dataformat.html#chords)
| Property | Type | Required | Default Value |
|:-----------|:-----------|:---------|:----------------------------|
|`type` | `'chord'` | ⚠️Yes | Setting `type:'chord'` defines this as a chord |
|`bass` | `string` | No | Describes the foreign bass of the chord if any. The values should marked with English notation |
|`root` | `string` | No | Describes the root note of the chord. The values should marked with English notation |
|`structure` | `string` | No | Describes the kind of the chord. This element is optional, if not present, the default value is the major |
|`upbeat` | `boolean` | No | Used to mark when a chord starts with a music pause |
|`value` | `string` | No | The text inside of the chord. If omitted the chord will have no content and be a self-closing XML node. |
**Mixed objects example**
To best understand how these objects can be used together, let's first look at the XML output we want to achieve for a line. I've added some line breaks, which are not normally there, to make this more readable (normally everything with a `<lines>` tag is on the same line). Note where `\n` are turned into `<br/>` tags as well.
```xml
<verse name="v1">
<lines part="men">
<chord root="D" bass="F#"/>Amazing grace<br/>
<chord root="C" structure="min" bass="Eb"/>
how sweet the sound that saved <chord root="B7" upbeat="true">a wretch like me</chord>
</lines>
<lines part="women">
<comment>sing this quietly</comment>
<chord root="D" bass="F#"/>Amazing grace<br/>
<chord root="C"/>
how sweet the sound that saved <chord root="B7"/>a <tag name="red">wretch</tag> like me
</lines>
</verse>
```
To achieve that output, here what would need to be passed to the `lines` property of a verse
```js
verses: {
name: 'v1',
lines: [
{
part: "men",
content: [
{type: "chord", root: "D", bass: "F#"},
{type: "text", value: "Amazing grace\n"},
{type: "chord", root: "C", structure: "min", bass: "Eb"},
{type: "text", value: "how sweet the sound that saved "},
{type: "chord", root: "B7", upbeat: true, value: "a wretch like me"}
]
}
{
part: "women",
content: [
{type: "comment", value: "sing this quietly"},
{type: "chord", root: "D", bass: "F#"},
{type: "text", value: "Amazing grace\n"},
{type: "chord", root: "C",},
{type: "text", value: "how sweet the sound that saved "},
{type: "chord", root: "B7" },
{type: "text", value: "a "},
{type: "tag", name:"red", value: "wretch"}
{type: "text", value: " like me"}
]
}
]
}
```
### `instruments` Array
This optional array of objects is used to describe all of the instrumental music in the song. It is very similar to the above `verses` but it cannot contain any words, only `chord`s or `beat`s. All `beat`s may only contain `chord`s. No text is allowed anywhere inside of `instruments`. Read about the supported properties on [the OpenLyrics Instrumental Parts docs](https://docs.openlyrics.org/en/latest/dataformat.html#instrumental-parts)
| Property | Type | Required | Default Value |
|:----------|:---------------------------|:---------|:----------------------------|
|`name` | `string` | ⚠️Yes | The name of this instrumental section. Should be similar to a verse name like `'i'` (intro), `'s'` (solo), etc. See [the docs](https://docs.openlyrics.org/en/latest/dataformat.html#instrumental-parts) for examples. |
|`lines` | `IBuilderInstrumentLine[]` | ⚠️Yes | An array of instrument lines. See below for details. |
#### `instruments` => `lines: IBuilderInstrumentLine[]`
| Property | Type | Required | Default Value |
|:----------|:----------------------------------|:---------|:----------------------------|
|`content` | `IBuilderInstrumentLineContent[]` | ⚠️Yes | An array of objects to create `<chord>`s and `<beat>`s in this line |
|`part` | `string` | No | The name of this instrumental part, eg: `'piano'`, `'guitar'`, etc. |
|`repeat` | `number` | No | The number of times this line should be repeated |
#### `instruments` => `lines` => `content: IBuilderInstrumentLineContent[]`
The `content` array for each line of an instrumental part can only contain one of two types of objects. `type: 'chord'`, or `type: 'beat'`. Nothing else is possible to add here. An object with `type: 'chord'` works exactly like it does above for verses. An object with `type: 'beat'` simply contains an array of `type: 'chord'` objects, it is only there as a container for chords.
**Instrument Line Content Object Type: `chord`**
A chord object is used do define a chord that should be played at a particular part of a song. A chord can exist before a certain word in the lyrics, or it can contain a particular set of lyrics within it. It is identical to the chords used for a verse except that it has no `value` property.
Read more about this in [the OpenLyrics Chords Docs](https://docs.openlyrics.org/en/latest/dataformat.html#chords)
| Property | Type | Required | Default Value |
|:-----------|:-----------|:---------|:----------------------------|
|`type` | `'chord'` | ⚠️Yes | Setting `type:'chord'` defines this as a chord |
|`bass` | `string` | No | Describes the foreign bass of the chord if any. The values should marked with English notation |
|`root` | `string` | No | Describes the root note of the chord. The values should marked with English notation |
|`structure` | `string` | No | Describes the kind of the chord. This element is optional, if not present, the default value is the major |
|`upbeat` | `boolean` | No | Used to mark when a chord starts with a music pause |
**Instrument Line Content Object Type: `beat`**
A beat represents a beat in the music. A beat tag can contains only chords. But it is not mandatory to separate beats.
Read more about this in [the OpenLyrics Instrumental Parts Docs](https://docs.openlyrics.org/en/latest/dataformat.html#instrumental-parts)
| Property | Type | Required | Default Value |
|:-----------|:-------------------|:---------|:----------------------------|
|`type` | `'beat'` | ⚠️Yes | Setting `type:'beat'` defines this as a beat |
|`chords` | `{type:'chord'}[]` | ⚠️Yes | An array of `type:'chord'` objects, which are defined above |
**Instrument Example**
The following XML example shows an instrumentation section, with a single line. That line contains some chords, and some beats which contain more chords each.
```xml
<instrument name="i">
<lines part="piano" repeat="2">
<chord root="D"/>
<chord root="D" structure="sus4" />
<beat><chord root="C"/><chord root="A" bass="C#" /></beat>
<beat><chord root="G"/><chord root="B"/></beat>
</lines>
</instrument>
```
To generate that output here are the needed objects:
```js
instruments: [
{
name: 'i',
lines: [
{
part: 'piano',
repeat: 2,
content: [
{ type: 'chord', root: 'D'},
{ type: 'chord', root: 'D', structure: 'sus4' },
{
type: 'beat',
chords: [
{ type: 'chord', root: 'C'},
{ type: 'chord', root:'A', bass: 'C#' }
]
},
{
type: 'beat',
chords: [
{ type: 'chord', root: 'G' },
{ type: 'chord', root: 'B' }
]
},
]
}
]
}
]
```