@hymnbook/abc 0.0.1 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,4 +1,52 @@
1
- // src/abcTypes.ts
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+
30
+ // src/index.ts
31
+ var index_exports = {};
32
+ __export(index_exports, {
33
+ AbcSong: () => AbcSong,
34
+ ValidationError: () => ValidationError,
35
+ addInfoFieldsToMelody: () => addInfoFieldsToMelody,
36
+ combineMelodyAndLyrics: () => combineMelodyAndLyrics,
37
+ convertStringToAbcTune: () => convertStringToAbcTune,
38
+ extractInfoFields: () => extractInfoFields,
39
+ generateAbcForVerse: () => generateAbcForVerse,
40
+ getField: () => getField,
41
+ getForVerse: () => getForVerse,
42
+ parse: () => parse,
43
+ squashNotesAndLyrics: () => squashNotesAndLyrics,
44
+ stringify: () => stringify,
45
+ validate: () => validate
46
+ });
47
+ module.exports = __toCommonJS(index_exports);
48
+
49
+ // src/types.ts
2
50
  var AbcSong = class {
3
51
  // See also: https://abcnotation.com/wiki/abc:standard:v2.1#information_fields
4
52
  area;
@@ -40,8 +88,8 @@ var AbcSong = class {
40
88
  };
41
89
  };
42
90
 
43
- // src/abc.ts
44
- import * as ABCJS from "abcjs";
91
+ // src/parser.ts
92
+ var ABCJS = __toESM(require("abcjs"), 1);
45
93
 
46
94
  // src/validation.ts
47
95
  var ValidationError = class extends Error {
@@ -53,15 +101,155 @@ function validate(result, message) {
53
101
  throw new ValidationError(message || "Value is not true");
54
102
  }
55
103
 
56
- // src/abc.ts
104
+ // src/deparser.ts
105
+ var addInfoFieldsToMelody = (song, abc) => {
106
+ let result = "";
107
+ result += song.referenceNumber === void 0 ? "" : "X:" + song.referenceNumber + "\n";
108
+ result += song.title === void 0 ? "" : "T:" + song.title + "\n";
109
+ result += song.area === void 0 ? "" : "A:" + song.area + "\n";
110
+ result += song.book === void 0 ? "" : "B:" + song.book + "\n";
111
+ result += song.composer === void 0 ? "" : "C:" + song.composer + "\n";
112
+ result += song.discography === void 0 ? "" : "D:" + song.discography + "\n";
113
+ result += song.fileUrl === void 0 ? "" : "F:" + song.fileUrl + "\n";
114
+ result += song.group === void 0 ? "" : "G:" + song.group + "\n";
115
+ result += song.history === void 0 ? "" : "H:" + song.history + "\n";
116
+ result += song.instruction === void 0 ? "" : "I:" + song.instruction + "\n";
117
+ result += song.key === void 0 ? "" : "K:" + song.key + "\n";
118
+ result += song.unitNoteLength === void 0 ? "" : "L:" + song.unitNoteLength + "\n";
119
+ result += song.meter === void 0 ? "" : "M:" + song.meter + "\n";
120
+ result += song.macro === void 0 ? "" : "m:" + song.macro + "\n";
121
+ result += song.notes === void 0 ? "" : "N:" + song.notes + "\n";
122
+ result += song.origin === void 0 ? "" : "O:" + song.origin + "\n";
123
+ result += song.parts === void 0 ? "" : "P:" + song.parts + "\n";
124
+ result += song.tempo === void 0 ? "" : "Q:" + song.tempo + "\n";
125
+ result += song.rhythm === void 0 ? "" : "R:" + song.rhythm + "\n";
126
+ result += song.remark === void 0 ? "" : "r:" + song.remark + "\n";
127
+ result += song.source === void 0 ? "" : "S:" + song.source + "\n";
128
+ result += song.symbolLine === void 0 ? "" : "s:" + song.symbolLine + "\n";
129
+ result += song.userDefined === void 0 ? "" : "U:" + song.userDefined + "\n";
130
+ result += song.voice === void 0 ? "" : "V:" + song.voice + "\n";
131
+ result += song.transcription === void 0 ? "" : "Z:" + song.transcription + "\n";
132
+ return result + abc;
133
+ };
134
+ var durationToString = (duration) => {
135
+ duration /= 4;
136
+ if (duration > 3 / 8) return (duration * 4).toString();
137
+ if (duration == 1 / 4) return "";
138
+ if (duration == 3 / 8) return "3/2";
139
+ if (duration == 1 / 8) return "/2";
140
+ if (duration == 3 / 16) return "3/4";
141
+ if (duration == 1 / 16) return "/4";
142
+ if (duration == 3 / 32) return "3/8";
143
+ if (duration == 1 / 32) return "/8";
144
+ if (duration == 3 / 64) return "3/16";
145
+ return "";
146
+ };
147
+ var voiceBarToString = (voice) => {
148
+ let result = "";
149
+ switch (voice.type) {
150
+ case "bar_thin":
151
+ result += "|";
152
+ break;
153
+ case "bar_thin_thick":
154
+ result += "|]";
155
+ break;
156
+ case "bar_thin_thin":
157
+ result += "||";
158
+ break;
159
+ case "bar_thick_thin":
160
+ result += "[|";
161
+ break;
162
+ case "bar_right_repeat":
163
+ result += ":|";
164
+ break;
165
+ case "bar_left_repeat":
166
+ result += "|:";
167
+ break;
168
+ case "bar_dbl_repeat":
169
+ result += "::";
170
+ break;
171
+ }
172
+ if (voice.startEnding) result += voice.startEnding;
173
+ return result + " ";
174
+ };
175
+ var voiceNoteToString = (voice, durationMultiplier, isBeam) => {
176
+ let notes = "";
177
+ let lyrics = "";
178
+ const duration = durationToString(voice.duration / durationMultiplier);
179
+ if (voice.startBeam) isBeam = true;
180
+ if (voice.endBeam) isBeam = false;
181
+ voice.chord?.forEach((chord) => {
182
+ const parsedChordName = chord.name.replaceAll(/♭/g, "b").replaceAll(/♯/g, "#");
183
+ notes += `"${parsedChordName}"`;
184
+ });
185
+ if (voice.pitches && voice.pitches?.length > 1) notes += "[";
186
+ voice.pitches?.forEach((pitch) => {
187
+ let note = pitch.name + duration;
188
+ if (pitch.startSlur) note = "(".repeat(pitch.startSlur.length) + note;
189
+ if (pitch.endSlur) note += ")".repeat(pitch.endSlur.length);
190
+ if (pitch.startTie) note += "-";
191
+ notes += note;
192
+ });
193
+ if (voice.pitches && voice.pitches?.length > 1) notes += "]";
194
+ if (voice.rest) {
195
+ if (voice.rest.type == "spacer") {
196
+ notes += "y";
197
+ } else if (voice.rest.type == "multimeasure") {
198
+ notes += "Z" + durationToString(voice.duration / 4);
199
+ } else {
200
+ notes += "z" + duration;
201
+ }
202
+ }
203
+ if (voice.pitches) {
204
+ voice.lyric?.forEach((lyric) => {
205
+ let text = lyric.syllable.replace(/ /g, "~");
206
+ if (text == "") text = "*";
207
+ lyrics += text + lyric.divider;
208
+ });
209
+ }
210
+ if (!isBeam) notes += " ";
211
+ return {
212
+ notes,
213
+ lyrics,
214
+ isBeam
215
+ };
216
+ };
217
+ var stringify = (song) => {
218
+ const durationParts = (song.unitNoteLength || "1/8").split("/");
219
+ const durationMultiplier = durationParts.length > 1 ? +durationParts[0] / +durationParts[1] : +durationParts[0];
220
+ const melody = song.melody.flatMap((line) => {
221
+ const notes = [];
222
+ const lyrics = [];
223
+ let isBeam = false;
224
+ line.forEach((voice) => {
225
+ switch (voice.el_type) {
226
+ case "bar":
227
+ notes.push(voiceBarToString(voice));
228
+ break;
229
+ case "note":
230
+ const result2 = voiceNoteToString(voice, durationMultiplier, isBeam);
231
+ notes.push(result2.notes);
232
+ lyrics.push(result2.lyrics);
233
+ isBeam = result2.isBeam;
234
+ break;
235
+ }
236
+ });
237
+ const result = [notes.join("").trim()];
238
+ const mergedLyrics = lyrics.join("").trim();
239
+ if (mergedLyrics.length > 0) {
240
+ result.push("w: " + mergedLyrics);
241
+ }
242
+ return result;
243
+ }).join("\n");
244
+ return addInfoFieldsToMelody(song, melody);
245
+ };
246
+
247
+ // src/parser.ts
57
248
  var parse = (abc) => {
58
249
  abc = abc.replace(/%.*/g, "").replaceAll(/\n+/g, "\n");
59
250
  const song = new AbcSong();
60
251
  extractInfoFields(abc, song);
61
252
  const tuneObject = convertStringToAbcTune(abc);
62
- if (tuneObject === void 0) {
63
- return void 0;
64
- }
65
253
  song.clef = tuneObject.lines[0].staff[0].clef || song.clef;
66
254
  song.keySignature = tuneObject.lines[0].staff[0].key || song.keySignature;
67
255
  song.melody = tuneObject.lines.map((line) => line.staff[0].voices[0]);
@@ -149,7 +337,7 @@ var extractInfoFields = (abc, song) => {
149
337
  song.transcription = getField(abc, "Z");
150
338
  return abc.replace(/%.*\n/g, "").replace(/(^|\n) *\t*[ABCDFGHIKLMmNOPQRrSsTUVXZ]:.*/g, "").replace(/\n+/g, "\n").replace(/^\n*/g, "").replace(/\n*$/g, "");
151
339
  };
152
- var extractNotesAndLyrics = (abc) => {
340
+ var squashNotesAndLyrics = (abc) => {
153
341
  const notes = [];
154
342
  const lyrics = [];
155
343
  abc.split("\n").map((it) => it.trim()).forEach((it) => {
@@ -164,41 +352,13 @@ var extractNotesAndLyrics = (abc) => {
164
352
  lyrics: lyrics.join(" ")
165
353
  };
166
354
  };
167
- var addInfoFieldsToMelody = (song, abc) => {
168
- let result = "";
169
- result += song.referenceNumber === void 0 ? "" : "X:" + song.referenceNumber + "\n";
170
- result += song.title === void 0 ? "" : "T:" + song.title + "\n";
171
- result += song.area === void 0 ? "" : "A:" + song.area + "\n";
172
- result += song.book === void 0 ? "" : "B:" + song.book + "\n";
173
- result += song.composer === void 0 ? "" : "C:" + song.composer + "\n";
174
- result += song.discography === void 0 ? "" : "D:" + song.discography + "\n";
175
- result += song.fileUrl === void 0 ? "" : "F:" + song.fileUrl + "\n";
176
- result += song.group === void 0 ? "" : "G:" + song.group + "\n";
177
- result += song.history === void 0 ? "" : "H:" + song.history + "\n";
178
- result += song.instruction === void 0 ? "" : "I:" + song.instruction + "\n";
179
- result += song.key === void 0 ? "" : "K:" + song.key + "\n";
180
- result += song.unitNoteLength === void 0 ? "" : "L:" + song.unitNoteLength + "\n";
181
- result += song.meter === void 0 ? "" : "M:" + song.meter + "\n";
182
- result += song.macro === void 0 ? "" : "m:" + song.macro + "\n";
183
- result += song.notes === void 0 ? "" : "N:" + song.notes + "\n";
184
- result += song.origin === void 0 ? "" : "O:" + song.origin + "\n";
185
- result += song.parts === void 0 ? "" : "P:" + song.parts + "\n";
186
- result += song.tempo === void 0 ? "" : "Q:" + song.tempo + "\n";
187
- result += song.rhythm === void 0 ? "" : "R:" + song.rhythm + "\n";
188
- result += song.remark === void 0 ? "" : "r:" + song.remark + "\n";
189
- result += song.source === void 0 ? "" : "S:" + song.source + "\n";
190
- result += song.symbolLine === void 0 ? "" : "s:" + song.symbolLine + "\n";
191
- result += song.userDefined === void 0 ? "" : "U:" + song.userDefined + "\n";
192
- result += song.voice === void 0 ? "" : "V:" + song.voice + "\n";
193
- result += song.transcription === void 0 ? "" : "Z:" + song.transcription + "\n";
194
- return result + abc;
195
- };
196
355
  var convertStringToAbcTune = (abc) => {
197
356
  const objectArray = ABCJS.parseOnly(abc);
198
357
  const object = objectArray;
199
358
  validate(object != null, "Tune object may not be null");
200
359
  validate(object.length > 0, "Tune object may not be empty");
201
360
  validate(object[0].lines != null, "Tune object lines may not be null");
361
+ object[0].lines = object[0].lines.filter((it) => it.staff);
202
362
  validate(object[0].lines.length > 0, "Tune object lines are empty");
203
363
  validate(object[0].lines[0].staff != null, "Staffs may not be null");
204
364
  validate(object[0].lines[0].staff.length > 0, "Staffs are empty");
@@ -221,10 +381,10 @@ var processAbcLyrics = (object) => {
221
381
  )
222
382
  );
223
383
  };
224
- var combineMelodyAndLyrics = (melody, lyrics) => {
384
+ var combineMelodyAndLyrics = (melody, lyrics, options = { trimLines: false }) => {
225
385
  const song = new AbcSong();
226
386
  const rawMelody = extractInfoFields(melody, song);
227
- const melodyLines = rawMelody.replaceAll(/\n+/g, "\n").trim().split("\n");
387
+ const melodyLines = rawMelody.replaceAll(/\n+/g, "\n").trim().split("\n").map((it) => it.trim()).map((it) => options.trimLines ? it.replaceAll(/(^y+|y+$)*/gi, "").replaceAll(/ *y* *(\|+]*) *y* */gi, " $1 ").trim() : it);
228
388
  const lyricLines = lyrics.replaceAll(/\n+/g, "\n").trim().split("\n");
229
389
  const mixedMelody = [];
230
390
  for (let i = 0; i < Math.max(melodyLines.length, lyricLines.length); i++) {
@@ -239,24 +399,26 @@ var getForVerse = (melody, verse) => melody.subMelodies.find((it) => (
239
399
  // `.includes()` won't work due to the Realm data type of `verseUuids`.
240
400
  it.verseUuids.some((it2) => it2 == verse.uuid)
241
401
  ));
242
- var generateAbcForVerse = (verse, activeMelody) => {
402
+ var generateAbcForVerse = (verse, activeMelody, options = { trimLines: false }) => {
243
403
  if (activeMelody === void 0) {
244
404
  return "";
245
405
  }
246
406
  const melody = getForVerse(activeMelody, verse)?.melody || activeMelody.melody;
247
- return combineMelodyAndLyrics(melody, verse.abcLyrics || "");
407
+ return combineMelodyAndLyrics(melody, verse.abcLyrics || "", options);
248
408
  };
249
- export {
409
+ // Annotate the CommonJS export names for ESM import in node:
410
+ 0 && (module.exports = {
250
411
  AbcSong,
251
412
  ValidationError,
252
413
  addInfoFieldsToMelody,
253
414
  combineMelodyAndLyrics,
254
415
  convertStringToAbcTune,
255
416
  extractInfoFields,
256
- extractNotesAndLyrics,
257
417
  generateAbcForVerse,
258
418
  getField,
259
419
  getForVerse,
260
420
  parse,
421
+ squashNotesAndLyrics,
422
+ stringify,
261
423
  validate
262
- };
424
+ });
@@ -3,7 +3,7 @@ import { SynthOptions } from 'abcjs';
3
3
  type AccidentalName = "flat" | "natural" | "sharp" | "dblsharp" | "dblflat" | "quarterflat" | "quartersharp";
4
4
  type ChordPlacement = "above" | "below" | "left" | "right" | "default";
5
5
  type StemDirection = "up" | "down" | "auto" | "none";
6
- type AbcType = "bar_thin" | "bar_thin_thick" | "bar_thin_thin" | "bar_thick_thin" | "bar_right_repeat" | "bar_left_repeat" | "bar_double_repeat";
6
+ type AbcType = "bar_thin" | "bar_thin_thick" | "bar_thin_thin" | "bar_thick_thin" | "bar_right_repeat" | "bar_left_repeat" | "bar_dbl_repeat";
7
7
  type AbcElementType = "note" | "bar";
8
8
  type Clef = "treble" | "tenor" | "bass" | "alto" | "treble+8" | "tenor+8" | "bass+8" | "alto+8" | "treble-8" | "tenor-8" | "bass-8" | "alto-8" | "none" | "perc";
9
9
  type NoteHeadType = "normal" | "harmonic" | "rhythm" | "x" | "triangle";
@@ -44,6 +44,7 @@ interface VoiceItemBar {
44
44
  type: AbcType;
45
45
  startChar: number;
46
46
  endChar: number;
47
+ startEnding?: string;
47
48
  }
48
49
  interface NoteProperties {
49
50
  duration: number;
@@ -51,6 +52,8 @@ interface NoteProperties {
51
52
  lyric?: AbcLyric[];
52
53
  chord?: AbcChord[];
53
54
  rest?: AbcRest;
55
+ startBeam?: boolean;
56
+ endBeam?: boolean;
54
57
  }
55
58
  interface VoiceItemNote extends NoteProperties {
56
59
  el_type: "note";
@@ -220,18 +223,52 @@ declare class AbcSong {
220
223
  clef: AbcClef;
221
224
  keySignature: KeySignature;
222
225
  }
223
- interface NoteGroupInterface {
226
+ type NoteGroupInterface = {
224
227
  notes: string;
225
228
  lyrics: string;
226
- }
229
+ };
227
230
 
228
- declare const parse: (abc: string) => AbcSong | undefined;
231
+ /**
232
+ * Generates an AbcSong object from an ABC notation string.
233
+ * This function does some extra processing to handle slurs and lyrics properly.
234
+ * If you do not want this, use `convertStringToAbcTune` directly.
235
+ *
236
+ * @param abc
237
+ */
238
+ declare const parse: (abc: string) => AbcSong;
239
+ /**
240
+ * Get an info/header field from an ABC notation string.
241
+ * @param abc
242
+ * @param field
243
+ * @param _default
244
+ */
229
245
  declare const getField: (abc: string, field: string, _default?: string) => (string | undefined);
246
+ /**
247
+ * Extract info/header fields from an ABC notation string into an AbcSong object and return the remaining melody string.
248
+ * @param abc
249
+ * @param song
250
+ */
230
251
  declare const extractInfoFields: (abc: string, song: AbcSong) => string;
231
- declare const extractNotesAndLyrics: (abc: string) => NoteGroupInterface;
232
- declare const addInfoFieldsToMelody: (song: AbcSong, abc: string) => string;
252
+ /**
253
+ * Extract notes and lyrics from an ABC notation string as a single line for each.
254
+ * Note that you must first remove info/header fields before using this function.
255
+ * @param abc
256
+ */
257
+ declare const squashNotesAndLyrics: (abc: string) => NoteGroupInterface;
258
+ /**
259
+ * Converts and validates an ABC notation string into a TuneObject.
260
+ * @param abc
261
+ */
233
262
  declare const convertStringToAbcTune: (abc: string) => TuneObject;
234
- declare const combineMelodyAndLyrics: (melody: string, lyrics: string) => string;
263
+ /**
264
+ * Combine multi line lyrics line with a multi line melody into a single ABC notation string.
265
+ * @param melody
266
+ * @param lyrics
267
+ * @param options
268
+ */
269
+ declare const combineMelodyAndLyrics: (melody: string, lyrics: string, options?: {
270
+ trimLines?: boolean;
271
+ }) => string;
235
272
 
236
273
  type Verse = {
237
274
  uuid: string;
@@ -247,10 +284,31 @@ type AbcMelody = {
247
284
  };
248
285
 
249
286
  declare const getForVerse: (melody: AbcMelody, verse: Verse) => AbcSubMelody | undefined;
250
- declare const generateAbcForVerse: (verse: Verse, activeMelody?: AbcMelody) => string;
287
+ /**
288
+ * Combine an ABC melody with the lyrics of a verse into a single ABC notation string.
289
+ *
290
+ * @param verse
291
+ * @param activeMelody - The active melody to use. The method returns an empty string if this is undefined.
292
+ * @param options { trimLines?: boolean } - Whether to trim `y` spacers from start/end of lines.
293
+ */
294
+ declare const generateAbcForVerse: (verse: Verse, activeMelody?: AbcMelody, options?: {
295
+ trimLines?: boolean;
296
+ }) => string;
251
297
 
252
298
  declare class ValidationError extends Error {
253
299
  }
254
300
  declare function validate(result: boolean, message?: string): void;
255
301
 
256
- export { type AbcChord, type AbcClef, type AbcElementType, type AbcLine, type AbcLyric, type AbcMelody, type AbcPitch, type AbcPitchStartSlur, type AbcRest, AbcSong, type AbcStaff, type AbcSubMelody, type AbcType, type Accidental, type AccidentalName, type AudioTrack, type AudioTrackNote, type AudioTrackProgram, type AudioTrackText, type AudioTracks, type BracePosition, type ChordPlacement, type ChordType, type Clef, type KeyAccidentalName, type KeyRoot, type KeySignature, type MetaText, type Mode, type NoteGroupInterface, type NoteHeadType, type NoteLetter, type NoteProperties, type StemDirection, type TuneObject, ValidationError, type Verse, type VoiceItem, type VoiceItemBar, type VoiceItemClef, type VoiceItemGap, type VoiceItemKey, type VoiceItemNote, type VoiceItemStem, addInfoFieldsToMelody, combineMelodyAndLyrics, convertStringToAbcTune, extractInfoFields, extractNotesAndLyrics, generateAbcForVerse, getField, getForVerse, parse, validate };
302
+ /**
303
+ * Converts an AbcSong object's info fields to ABC notation and merges them with the given melody string.
304
+ * @param song
305
+ * @param abc
306
+ */
307
+ declare const addInfoFieldsToMelody: (song: AbcSong, abc: string) => string;
308
+ /**
309
+ * Convert an AbcSong object to an ABC notation string.
310
+ * @param song
311
+ */
312
+ declare const stringify: (song: AbcSong) => string;
313
+
314
+ export { type AbcChord, type AbcClef, type AbcElementType, type AbcLine, type AbcLyric, type AbcMelody, type AbcPitch, type AbcPitchStartSlur, type AbcRest, AbcSong, type AbcStaff, type AbcSubMelody, type AbcType, type Accidental, type AccidentalName, type AudioTrack, type AudioTrackNote, type AudioTrackProgram, type AudioTrackText, type AudioTracks, type BracePosition, type ChordPlacement, type ChordType, type Clef, type KeyAccidentalName, type KeyRoot, type KeySignature, type MetaText, type Mode, type NoteGroupInterface, type NoteHeadType, type NoteLetter, type NoteProperties, type StemDirection, type TuneObject, ValidationError, type Verse, type VoiceItem, type VoiceItemBar, type VoiceItemClef, type VoiceItemGap, type VoiceItemKey, type VoiceItemNote, type VoiceItemStem, addInfoFieldsToMelody, combineMelodyAndLyrics, convertStringToAbcTune, extractInfoFields, generateAbcForVerse, getField, getForVerse, parse, squashNotesAndLyrics, stringify, validate };
package/dist/index.d.ts CHANGED
@@ -3,7 +3,7 @@ import { SynthOptions } from 'abcjs';
3
3
  type AccidentalName = "flat" | "natural" | "sharp" | "dblsharp" | "dblflat" | "quarterflat" | "quartersharp";
4
4
  type ChordPlacement = "above" | "below" | "left" | "right" | "default";
5
5
  type StemDirection = "up" | "down" | "auto" | "none";
6
- type AbcType = "bar_thin" | "bar_thin_thick" | "bar_thin_thin" | "bar_thick_thin" | "bar_right_repeat" | "bar_left_repeat" | "bar_double_repeat";
6
+ type AbcType = "bar_thin" | "bar_thin_thick" | "bar_thin_thin" | "bar_thick_thin" | "bar_right_repeat" | "bar_left_repeat" | "bar_dbl_repeat";
7
7
  type AbcElementType = "note" | "bar";
8
8
  type Clef = "treble" | "tenor" | "bass" | "alto" | "treble+8" | "tenor+8" | "bass+8" | "alto+8" | "treble-8" | "tenor-8" | "bass-8" | "alto-8" | "none" | "perc";
9
9
  type NoteHeadType = "normal" | "harmonic" | "rhythm" | "x" | "triangle";
@@ -44,6 +44,7 @@ interface VoiceItemBar {
44
44
  type: AbcType;
45
45
  startChar: number;
46
46
  endChar: number;
47
+ startEnding?: string;
47
48
  }
48
49
  interface NoteProperties {
49
50
  duration: number;
@@ -51,6 +52,8 @@ interface NoteProperties {
51
52
  lyric?: AbcLyric[];
52
53
  chord?: AbcChord[];
53
54
  rest?: AbcRest;
55
+ startBeam?: boolean;
56
+ endBeam?: boolean;
54
57
  }
55
58
  interface VoiceItemNote extends NoteProperties {
56
59
  el_type: "note";
@@ -220,18 +223,52 @@ declare class AbcSong {
220
223
  clef: AbcClef;
221
224
  keySignature: KeySignature;
222
225
  }
223
- interface NoteGroupInterface {
226
+ type NoteGroupInterface = {
224
227
  notes: string;
225
228
  lyrics: string;
226
- }
229
+ };
227
230
 
228
- declare const parse: (abc: string) => AbcSong | undefined;
231
+ /**
232
+ * Generates an AbcSong object from an ABC notation string.
233
+ * This function does some extra processing to handle slurs and lyrics properly.
234
+ * If you do not want this, use `convertStringToAbcTune` directly.
235
+ *
236
+ * @param abc
237
+ */
238
+ declare const parse: (abc: string) => AbcSong;
239
+ /**
240
+ * Get an info/header field from an ABC notation string.
241
+ * @param abc
242
+ * @param field
243
+ * @param _default
244
+ */
229
245
  declare const getField: (abc: string, field: string, _default?: string) => (string | undefined);
246
+ /**
247
+ * Extract info/header fields from an ABC notation string into an AbcSong object and return the remaining melody string.
248
+ * @param abc
249
+ * @param song
250
+ */
230
251
  declare const extractInfoFields: (abc: string, song: AbcSong) => string;
231
- declare const extractNotesAndLyrics: (abc: string) => NoteGroupInterface;
232
- declare const addInfoFieldsToMelody: (song: AbcSong, abc: string) => string;
252
+ /**
253
+ * Extract notes and lyrics from an ABC notation string as a single line for each.
254
+ * Note that you must first remove info/header fields before using this function.
255
+ * @param abc
256
+ */
257
+ declare const squashNotesAndLyrics: (abc: string) => NoteGroupInterface;
258
+ /**
259
+ * Converts and validates an ABC notation string into a TuneObject.
260
+ * @param abc
261
+ */
233
262
  declare const convertStringToAbcTune: (abc: string) => TuneObject;
234
- declare const combineMelodyAndLyrics: (melody: string, lyrics: string) => string;
263
+ /**
264
+ * Combine multi line lyrics line with a multi line melody into a single ABC notation string.
265
+ * @param melody
266
+ * @param lyrics
267
+ * @param options
268
+ */
269
+ declare const combineMelodyAndLyrics: (melody: string, lyrics: string, options?: {
270
+ trimLines?: boolean;
271
+ }) => string;
235
272
 
236
273
  type Verse = {
237
274
  uuid: string;
@@ -247,10 +284,31 @@ type AbcMelody = {
247
284
  };
248
285
 
249
286
  declare const getForVerse: (melody: AbcMelody, verse: Verse) => AbcSubMelody | undefined;
250
- declare const generateAbcForVerse: (verse: Verse, activeMelody?: AbcMelody) => string;
287
+ /**
288
+ * Combine an ABC melody with the lyrics of a verse into a single ABC notation string.
289
+ *
290
+ * @param verse
291
+ * @param activeMelody - The active melody to use. The method returns an empty string if this is undefined.
292
+ * @param options { trimLines?: boolean } - Whether to trim `y` spacers from start/end of lines.
293
+ */
294
+ declare const generateAbcForVerse: (verse: Verse, activeMelody?: AbcMelody, options?: {
295
+ trimLines?: boolean;
296
+ }) => string;
251
297
 
252
298
  declare class ValidationError extends Error {
253
299
  }
254
300
  declare function validate(result: boolean, message?: string): void;
255
301
 
256
- export { type AbcChord, type AbcClef, type AbcElementType, type AbcLine, type AbcLyric, type AbcMelody, type AbcPitch, type AbcPitchStartSlur, type AbcRest, AbcSong, type AbcStaff, type AbcSubMelody, type AbcType, type Accidental, type AccidentalName, type AudioTrack, type AudioTrackNote, type AudioTrackProgram, type AudioTrackText, type AudioTracks, type BracePosition, type ChordPlacement, type ChordType, type Clef, type KeyAccidentalName, type KeyRoot, type KeySignature, type MetaText, type Mode, type NoteGroupInterface, type NoteHeadType, type NoteLetter, type NoteProperties, type StemDirection, type TuneObject, ValidationError, type Verse, type VoiceItem, type VoiceItemBar, type VoiceItemClef, type VoiceItemGap, type VoiceItemKey, type VoiceItemNote, type VoiceItemStem, addInfoFieldsToMelody, combineMelodyAndLyrics, convertStringToAbcTune, extractInfoFields, extractNotesAndLyrics, generateAbcForVerse, getField, getForVerse, parse, validate };
302
+ /**
303
+ * Converts an AbcSong object's info fields to ABC notation and merges them with the given melody string.
304
+ * @param song
305
+ * @param abc
306
+ */
307
+ declare const addInfoFieldsToMelody: (song: AbcSong, abc: string) => string;
308
+ /**
309
+ * Convert an AbcSong object to an ABC notation string.
310
+ * @param song
311
+ */
312
+ declare const stringify: (song: AbcSong) => string;
313
+
314
+ export { type AbcChord, type AbcClef, type AbcElementType, type AbcLine, type AbcLyric, type AbcMelody, type AbcPitch, type AbcPitchStartSlur, type AbcRest, AbcSong, type AbcStaff, type AbcSubMelody, type AbcType, type Accidental, type AccidentalName, type AudioTrack, type AudioTrackNote, type AudioTrackProgram, type AudioTrackText, type AudioTracks, type BracePosition, type ChordPlacement, type ChordType, type Clef, type KeyAccidentalName, type KeyRoot, type KeySignature, type MetaText, type Mode, type NoteGroupInterface, type NoteHeadType, type NoteLetter, type NoteProperties, type StemDirection, type TuneObject, ValidationError, type Verse, type VoiceItem, type VoiceItemBar, type VoiceItemClef, type VoiceItemGap, type VoiceItemKey, type VoiceItemNote, type VoiceItemStem, addInfoFieldsToMelody, combineMelodyAndLyrics, convertStringToAbcTune, extractInfoFields, generateAbcForVerse, getField, getForVerse, parse, squashNotesAndLyrics, stringify, validate };