@goplayerjuggler/abc-tools 1.0.19 → 1.0.20

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@goplayerjuggler/abc-tools",
3
- "version": "1.0.19",
3
+ "version": "1.0.20",
4
4
  "description": "sorting algorithm and implementation for ABC tunes; plus other tools for parsing and manipulating ABC tunes",
5
5
  "main": "src/index.js",
6
6
  "scripts": {
@@ -620,6 +620,7 @@ function toggleMeter_4_4_to_4_2(abc, currentMeter) {
620
620
  const defaultCommentForReelConversion =
621
621
  "*abc-tools: convert to M:4/4 & L:1/16*";
622
622
  const defaultCommentForHornpipeConversion = "*abc-tools: convert to M:4/2*";
623
+ const defaultCommentForPolkaConversion = "*abc-tools: convert to M:4/4*";
623
624
  const defaultCommentForJigConversion = "*abc-tools: convert to M:12/8*";
624
625
  /**
625
626
  * Adjusts bar lengths and L, M fields - a
@@ -682,6 +683,20 @@ function convertStandardJig(jig, comment = defaultCommentForJigConversion) {
682
683
  return result;
683
684
  }
684
685
 
686
+ function convertStandardPolka(t, comment = defaultCommentForPolkaConversion) {
687
+ const meter = getMeter(t);
688
+ if (!Array.isArray(meter) || !meter || !meter[0] === 2 || !meter[1] === 4) {
689
+ throw new Error("invalid meter");
690
+ }
691
+
692
+ let result = //toggleMeter_4_4_to_4_2(reel, meter);
693
+ toggleMeterDoubling(t, [2, 4], [4, 4], meter);
694
+ if (comment) {
695
+ result = result.replace(/(\nK:)/, `\nN:${comment}$1`);
696
+ }
697
+ return result;
698
+ }
699
+
685
700
  /**
686
701
  * Adjusts bar lengths and M field to alter a
687
702
  * hornpipe written in the normal way (M:6/8) so it’s
@@ -792,6 +807,19 @@ function convertToStandardJig(jig, comment = defaultCommentForJigConversion) {
792
807
  return result;
793
808
  }
794
809
 
810
+ function convertToStandardPolka(t, comment = defaultCommentForPolkaConversion) {
811
+ const meter = getMeter(t);
812
+ if (!Array.isArray(meter) || !meter || !meter[0] === 4 || !meter[1] === 4) {
813
+ throw new Error("invalid meter");
814
+ }
815
+
816
+ let result = toggleMeterDoubling(t, [2, 4], [4, 4], meter);
817
+ if (comment) {
818
+ result = result.replace(`\nN:${comment}`, "");
819
+ }
820
+ return result;
821
+ }
822
+
795
823
  function convertToStandardHornpipe(
796
824
  hornpipe,
797
825
  comment = defaultCommentForHornpipeConversion
@@ -1033,21 +1061,19 @@ function canDoubleBarLength(abc) {
1033
1061
  rhythm = getHeaderValue(abc, "R");
1034
1062
  if (
1035
1063
  !rhythm ||
1036
- ["reel", "hornpipe", "jig"].indexOf(rhythm.toLowerCase()) < 0
1064
+ ["reel", "hornpipe", "jig", "polka"].indexOf(rhythm.toLowerCase()) < 0
1037
1065
  ) {
1038
1066
  return false;
1039
1067
  }
1040
1068
  return (
1041
- !abc.match(/\[M:/) && //inline meter marking
1042
- !abc.match(/\[L:/) &&
1043
- (((rhythm === "reel" || rhythm === "hornpipe") &&
1044
- l.equals(new Fraction(1, 8)) &&
1045
- meter[0] === 4 &&
1046
- meter[1] === 4) ||
1047
- (rhythm === "jig" &&
1069
+ (!abc.match(/\[M:/) && //inline meter marking
1070
+ !abc.match(/\[L:/) &&
1071
+ (((rhythm === "reel" || rhythm === "hornpipe") &&
1048
1072
  l.equals(new Fraction(1, 8)) &&
1049
- meter[0] === 6 &&
1050
- meter[1] === 8))
1073
+ meter[0] === 4 &&
1074
+ meter[1] === 4) ||
1075
+ (rhythm === "jig" && meter[0] === 6 && meter[1] === 8))) ||
1076
+ (rhythm === "polka" && meter[0] === 2 && meter[1] === 4)
1051
1077
  );
1052
1078
  }
1053
1079
  function canHalveBarLength(abc) {
@@ -1056,17 +1082,11 @@ function canHalveBarLength(abc) {
1056
1082
  rhythm = getHeaderValue(abc, "R");
1057
1083
  if (
1058
1084
  !rhythm ||
1059
- ["reel", "hornpipe", "jig"].indexOf(rhythm.toLowerCase()) < 0
1085
+ ["reel", "hornpipe", "jig", "polka"].indexOf(rhythm.toLowerCase()) < 0
1060
1086
  ) {
1061
1087
  return false;
1062
1088
  }
1063
1089
 
1064
- if (
1065
- !rhythm ||
1066
- ["reel", "hornpipe", "jig"].indexOf(rhythm.toLowerCase()) < 0
1067
- ) {
1068
- return false;
1069
- }
1070
1090
  return (
1071
1091
  !abc.match(/\[M:/) && //inline meter marking
1072
1092
  !abc.match(/\[L:/) &&
@@ -1078,10 +1098,8 @@ function canHalveBarLength(abc) {
1078
1098
  l.equals(new Fraction(1, 8)) &&
1079
1099
  meter[0] === 4 &&
1080
1100
  meter[1] === 2) ||
1081
- (rhythm === "jig" &&
1082
- l.equals(new Fraction(1, 8)) &&
1083
- meter[0] === 12 &&
1084
- meter[1] === 8))
1101
+ (rhythm === "jig" && meter[0] === 12 && meter[1] === 8) ||
1102
+ (rhythm === "polka" && meter[0] === 4 && meter[1] === 4))
1085
1103
  );
1086
1104
  }
1087
1105
 
@@ -1090,9 +1108,11 @@ module.exports = {
1090
1108
  canHalveBarLength,
1091
1109
  convertStandardJig,
1092
1110
  convertStandardHornpipe,
1111
+ convertStandardPolka,
1093
1112
  convertStandardReel,
1094
1113
  convertToStandardJig,
1095
1114
  convertToStandardHornpipe,
1115
+ convertToStandardPolka,
1096
1116
  convertToStandardReel,
1097
1117
  defaultCommentForReelConversion,
1098
1118
  doubleBarLength,
@@ -135,12 +135,7 @@ function getBarAccidentals(barTokens, keyAccidentals) {
135
135
 
136
136
  const noteInfos = extractNoteInfo(token);
137
137
 
138
- for (const {
139
- noteLetter,
140
- octaveMarkers,
141
- accidental,
142
- noteWithOctave
143
- } of noteInfos) {
138
+ for (const { noteLetter, accidental, noteWithOctave } of noteInfos) {
144
139
  const baseNoteLetter = noteLetter.toUpperCase();
145
140
 
146
141
  if (accidental) {
@@ -171,8 +166,7 @@ function getBarAccidentals(barTokens, keyAccidentals) {
171
166
  function addAccidentalsForMergedBar(
172
167
  secondBarTokens,
173
168
  firstBarAccidentals,
174
- keyAccidentals,
175
- musicText
169
+ keyAccidentals
176
170
  ) {
177
171
  const modifiedTokens = [];
178
172
  const secondBarAccidentals = new Map();
@@ -206,12 +200,7 @@ function addAccidentalsForMergedBar(
206
200
  let needsModification = false;
207
201
  const modificationsNeeded = [];
208
202
 
209
- for (const {
210
- noteLetter,
211
- octaveMarkers,
212
- accidental,
213
- noteWithOctave
214
- } of noteInfos) {
203
+ for (const { noteLetter, accidental, noteWithOctave } of noteInfos) {
215
204
  const baseNoteLetter = noteLetter.toUpperCase();
216
205
  const firstBarAccidental = firstBarAccidentals.get(noteWithOctave);
217
206
  const keyAccidental = keyAccidentals.get(baseNoteLetter) || null;
@@ -347,12 +336,7 @@ function removeRedundantAccidentals(
347
336
  let needsModification = false;
348
337
  const modificationsNeeded = [];
349
338
 
350
- for (const {
351
- noteLetter,
352
- octaveMarkers,
353
- accidental,
354
- noteWithOctave
355
- } of noteInfos) {
339
+ for (const { noteLetter, accidental, noteWithOctave } of noteInfos) {
356
340
  const baseNoteLetter = noteLetter.toUpperCase();
357
341
  const keyAccidental = keyAccidentals.get(baseNoteLetter) || null;
358
342
  const currentAccidental = secondHalfAccidentals.get(noteWithOctave);
@@ -422,10 +406,9 @@ function removeRedundantAccidentals(
422
406
  /**
423
407
  * Reconstruct music text from tokens
424
408
  * @param {Array<object>} tokens - Array of token objects
425
- * @param {string} originalMusicText - Original music text for spacing reference
426
409
  * @returns {string} - Reconstructed music text
427
410
  */
428
- function reconstructMusicFromTokens(tokens, originalMusicText) {
411
+ function reconstructMusicFromTokens(tokens) {
429
412
  if (tokens.length === 0) return "";
430
413
 
431
414
  let result = "";