chordsheetjs 5.1.3 → 6.0.2

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.
@@ -0,0 +1,5 @@
1
+ #!/bin/sh
2
+ . "$(dirname "$0")/_/husky.sh"
3
+
4
+ yarn readme
5
+ git add README.md
package/README.md CHANGED
@@ -466,6 +466,9 @@ Inherits from <a href="#ChordSheetParser">ChordSheetParser</a></p>
466
466
  <dt><a href="#TITLE">TITLE</a> : <code>string</code></dt>
467
467
  <dd><p>Title meta directive. See <a href="https://www.chordpro.org/chordpro/directives-title/">https://www.chordpro.org/chordpro/directives-title/</a></p>
468
468
  </dd>
469
+ <dt><a href="#TRANSPOSE">TRANSPOSE</a> : <code>string</code></dt>
470
+ <dd><p>Transpose meta directive. See: <a href="https://www.chordpro.org/chordpro/directives-transpose/">https://www.chordpro.org/chordpro/directives-transpose/</a></p>
471
+ </dd>
469
472
  <dt><a href="#YEAR">YEAR</a> : <code>string</code></dt>
470
473
  <dd><p>Year meta directive. See <a href="https://www.chordpro.org/chordpro/directives-year/">https://www.chordpro.org/chordpro/directives-year/</a></p>
471
474
  </dd>
@@ -1176,8 +1179,11 @@ Represents a Chord, consisting of a root, suffix (quality) and bass
1176
1179
  * [.toChordSymbolString(key)](#Chord+toChordSymbolString) ⇒ <code>string</code>
1177
1180
  * [.isChordSymbol()](#Chord+isChordSymbol) ⇒ <code>boolean</code>
1178
1181
  * [.toNumeric(key)](#Chord+toNumeric) ⇒ [<code>Chord</code>](#Chord)
1182
+ * [.toNumeral(key)](#Chord+toNumeral) ⇒ [<code>Chord</code>](#Chord)
1183
+ * [.toNumeralString(key)](#Chord+toNumeralString) ⇒ <code>string</code>
1179
1184
  * [.isNumeric()](#Chord+isNumeric) ⇒ <code>boolean</code>
1180
1185
  * [.toNumericString(key)](#Chord+toNumericString) ⇒ <code>string</code>
1186
+ * [.isNumeral()](#Chord+isNumeral) ⇒ <code>boolean</code>
1181
1187
  * [.toString()](#Chord+toString) ⇒ <code>string</code>
1182
1188
  * [.normalize()](#Chord+normalize) ⇒ [<code>Chord</code>](#Chord)
1183
1189
  * [.useModifier(newModifier)](#Chord+useModifier) ⇒ [<code>Chord</code>](#Chord)
@@ -1231,7 +1237,7 @@ Determines whether the chord is a chord symbol
1231
1237
  <a name="Chord+toNumeric"></a>
1232
1238
 
1233
1239
  ### chord.toNumeric(key) ⇒ [<code>Chord</code>](#Chord)
1234
- Converts the chord to a numeric chord, using the supplied kye as a reference.
1240
+ Converts the chord to a numeric chord, using the supplied key as a reference.
1235
1241
  For example, a chord symbol A# with reference key E will return the numeric chord #4.
1236
1242
 
1237
1243
  **Kind**: instance method of [<code>Chord</code>](#Chord)
@@ -1241,6 +1247,33 @@ For example, a chord symbol A# with reference key E will return the numeric chor
1241
1247
  | --- | --- | --- |
1242
1248
  | key | <code>Key</code> \| <code>string</code> | the reference key |
1243
1249
 
1250
+ <a name="Chord+toNumeral"></a>
1251
+
1252
+ ### chord.toNumeral(key) ⇒ [<code>Chord</code>](#Chord)
1253
+ Converts the chord to a numeral chord, using the supplied key as a reference.
1254
+ For example, a chord symbol A# with reference key E will return the numeral chord #IV.
1255
+
1256
+ **Kind**: instance method of [<code>Chord</code>](#Chord)
1257
+ **Returns**: [<code>Chord</code>](#Chord) - the numeral chord
1258
+
1259
+ | Param | Type | Default | Description |
1260
+ | --- | --- | --- | --- |
1261
+ | key | <code>Key</code> \| <code>string</code> \| <code>null</code> | <code></code> | the reference key. The key is required when converting a chord symbol |
1262
+
1263
+ <a name="Chord+toNumeralString"></a>
1264
+
1265
+ ### chord.toNumeralString(key) ⇒ <code>string</code>
1266
+ Converts the chord to a numeral chord string, using the supplied kye as a reference.
1267
+ For example, a chord symbol A# with reference key E will return the numeral chord #4.
1268
+
1269
+ **Kind**: instance method of [<code>Chord</code>](#Chord)
1270
+ **Returns**: <code>string</code> - the numeral chord string
1271
+ **See**: {toNumeral}
1272
+
1273
+ | Param | Type | Description |
1274
+ | --- | --- | --- |
1275
+ | key | <code>Key</code> \| <code>string</code> | the reference key |
1276
+
1244
1277
  <a name="Chord+isNumeric"></a>
1245
1278
 
1246
1279
  ### chord.isNumeric() ⇒ <code>boolean</code>
@@ -1261,6 +1294,12 @@ For example, a chord symbol A# with reference key E will return the numeric chor
1261
1294
  | --- | --- | --- |
1262
1295
  | key | <code>Key</code> \| <code>string</code> | the reference key |
1263
1296
 
1297
+ <a name="Chord+isNumeral"></a>
1298
+
1299
+ ### chord.isNumeral() ⇒ <code>boolean</code>
1300
+ Determines whether the chord is a numeral
1301
+
1302
+ **Kind**: instance method of [<code>Chord</code>](#Chord)
1264
1303
  <a name="Chord+toString"></a>
1265
1304
 
1266
1305
  ### chord.toString() ⇒ <code>string</code>
@@ -1271,7 +1310,7 @@ Converts the chord to a string, eg `Esus4/G#` or `1sus4/#3`
1271
1310
  <a name="Chord+normalize"></a>
1272
1311
 
1273
1312
  ### chord.normalize() ⇒ [<code>Chord</code>](#Chord)
1274
- Normalizes the chord:
1313
+ Normalizes the chord root and bass notes:
1275
1314
  - Fb becomes E
1276
1315
  - Cb becomes B
1277
1316
  - B# becomes C
@@ -1281,7 +1320,8 @@ Normalizes the chord:
1281
1320
  - 7# becomes 1
1282
1321
  - 3# becomes 4
1283
1322
 
1284
- If the chord is already normalized, this will return a copy.
1323
+ Besides that it normalizes the suffix. For example, `sus2` becomes `2`, `sus4` becomes `sus`.
1324
+ All suffix normalizations can be found in `src/normalize_mappings/suffix-mapping.txt`.
1285
1325
 
1286
1326
  **Kind**: instance method of [<code>Chord</code>](#Chord)
1287
1327
  **Returns**: [<code>Chord</code>](#Chord) - the normalized chord
@@ -1484,6 +1524,12 @@ Time meta directive. See https://www.chordpro.org/chordpro/directives-time/
1484
1524
  ## TITLE : <code>string</code>
1485
1525
  Title meta directive. See https://www.chordpro.org/chordpro/directives-title/
1486
1526
 
1527
+ **Kind**: global constant
1528
+ <a name="TRANSPOSE"></a>
1529
+
1530
+ ## TRANSPOSE : <code>string</code>
1531
+ Transpose meta directive. See: https://www.chordpro.org/chordpro/directives-transpose/
1532
+
1487
1533
  **Kind**: global constant
1488
1534
  <a name="YEAR"></a>
1489
1535
 
package/lib/chord.js CHANGED
@@ -12,6 +12,8 @@ var _utilities = require("./utilities");
12
12
 
13
13
  var _key = _interopRequireDefault(require("./key"));
14
14
 
15
+ var _suffixNormalizeMapping = _interopRequireDefault(require("./normalize_mappings/suffix-normalize-mapping"));
16
+
15
17
  var _constants = require("./constants");
16
18
 
17
19
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
@@ -36,11 +38,17 @@ function _checkPrivateRedeclaration(obj, privateCollection) { if (privateCollect
36
38
 
37
39
  function _classPrivateMethodGet(receiver, privateSet, fn) { if (!privateSet.has(receiver)) { throw new TypeError("attempted to get private field on non-instance"); } return fn; }
38
40
 
39
- function _classPrivateFieldGet(receiver, privateMap) { var descriptor = _classExtractFieldDescriptor(receiver, privateMap, "get"); return _classApplyDescriptorGet(receiver, descriptor); }
41
+ function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }
42
+
43
+ function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
44
+
45
+ function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
46
+
47
+ function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); }
40
48
 
41
- function _classExtractFieldDescriptor(receiver, privateMap, action) { if (!privateMap.has(receiver)) { throw new TypeError("attempted to " + action + " private field on non-instance"); } return privateMap.get(receiver); }
49
+ function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); }
42
50
 
43
- function _classApplyDescriptorGet(receiver, descriptor) { if (descriptor.get) { return descriptor.get.call(receiver); } return descriptor.value; }
51
+ function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
44
52
 
45
53
  function _wrapRegExp() { _wrapRegExp = function _wrapRegExp(re, groups) { return new BabelRegExp(re, void 0, groups); }; var _super = RegExp.prototype, _groups = new WeakMap(); function BabelRegExp(re, flags, groups) { var _this = new RegExp(re, flags); return _groups.set(_this, groups || _groups.get(re)), _setPrototypeOf(_this, BabelRegExp.prototype); } function buildGroups(result, re) { var g = _groups.get(re); return Object.keys(g).reduce(function (groups, name) { return groups[name] = result[g[name]], groups; }, Object.create(null)); } return _inherits(BabelRegExp, RegExp), BabelRegExp.prototype.exec = function (str) { var result = _super.exec.call(this, str); return result && (result.groups = buildGroups(result, this)), result; }, BabelRegExp.prototype[Symbol.replace] = function (str, substitution) { if ("string" == typeof substitution) { var groups = _groups.get(this); return _super[Symbol.replace].call(this, str, substitution.replace(/\$<([^>]+)>/g, function (_, name) { return "$" + groups[name]; })); } if ("function" == typeof substitution) { var _this = this; return _super[Symbol.replace].call(this, str, function () { var args = arguments; return "object" != _typeof(args[args.length - 1]) && (args = [].slice.call(args)).push(buildGroups(args, _this)), substitution.apply(this, args); }); } return _super[Symbol.replace].call(this, str, substitution); }, _wrapRegExp.apply(this, arguments); }
46
54
 
@@ -48,23 +56,12 @@ function _inherits(subClass, superClass) { if (typeof superClass !== "function"
48
56
 
49
57
  function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
50
58
 
51
- var MAJOR_SCALE = [null, 'M', 'm', 'm', 'M', 'M', 'm', 'dim'];
52
-
53
59
  function normalizeSuffix(suffix) {
54
- if (suffix === 'M') {
55
- return '';
56
- }
57
-
58
- return suffix;
59
- }
60
-
61
- function chordSuffix(noteNumber, suffix) {
62
- if ((0, _utilities.isEmptyString)(suffix)) {
63
- var defaultSuffix = MAJOR_SCALE[noteNumber];
64
- return normalizeSuffix(defaultSuffix);
60
+ if (_suffixNormalizeMapping["default"][suffix] === '[blank]') {
61
+ return null;
65
62
  }
66
63
 
67
- return normalizeSuffix(suffix);
64
+ return _suffixNormalizeMapping["default"][suffix] || suffix;
68
65
  }
69
66
 
70
67
  var chordRegex = /*#__PURE__*/_wrapRegExp(/^([A-G])(#|b)?((?:(?![\t-\r \/\xA0\u1680\u2000-\u200A\u2028\u2029\u202F\u205F\u3000\uFEFF])[\s\S])*)(\/([A-G])(#|b)?)?$/i, {
@@ -83,7 +80,16 @@ var numericChordRegex = /*#__PURE__*/_wrapRegExp(/^(#|b)?([1-7])((?:(?![\t-\r \/
83
80
  bassBase: 6
84
81
  });
85
82
 
86
- var regexes = [numericChordRegex, chordRegex];
83
+ var sortedNumerals = _toConsumableArray(_constants.ROMAN_NUMERALS).sort(function (numeralA, numeralB) {
84
+ return numeralB.length - numeralA.length;
85
+ });
86
+
87
+ var numerals = [].concat(_toConsumableArray(sortedNumerals), _toConsumableArray(sortedNumerals.map(function (numeral) {
88
+ return numeral.toLowerCase();
89
+ }))).join('|');
90
+ var numeralChordRegex = // eslint-disable-next-line max-len
91
+ new RegExp("^(?<modifier>#|b)?(?<base>".concat(numerals, ")(?<suffix>[^/\\s]*)(\\/(?<bassModifier>#|b)?(?<bassBase>").concat(numerals, "))?$"));
92
+ var regexes = [numericChordRegex, numeralChordRegex, chordRegex];
87
93
  /**
88
94
  * Represents a Chord, consisting of a root, suffix (quality) and bass
89
95
  */
@@ -122,15 +128,24 @@ var Chord = /*#__PURE__*/function () {
122
128
  set: void 0
123
129
  });
124
130
 
131
+ this.suffix = (0, _utilities.presence)(suffix);
125
132
  this.root = root || new _key["default"]({
126
133
  note: base,
127
- modifier: modifier
134
+ modifier: modifier,
135
+ minor: suffix === 'm'
128
136
  });
129
- this.suffix = (0, _utilities.presence)(suffix);
130
- this.bass = bass || (bassBase ? new _key["default"]({
131
- note: bassBase,
132
- modifier: bassModifier
133
- }) : null);
137
+
138
+ if (bass) {
139
+ this.bass = bass;
140
+ } else if (bassBase) {
141
+ this.bass = new _key["default"]({
142
+ note: bassBase,
143
+ modifier: bassModifier,
144
+ minor: suffix === 'm'
145
+ });
146
+ } else {
147
+ this.bass = null;
148
+ }
134
149
  }
135
150
 
136
151
  _createClass(Chord, [{
@@ -162,11 +177,18 @@ var Chord = /*#__PURE__*/function () {
162
177
 
163
178
  var keyObj = _key["default"].wrap(key);
164
179
 
165
- return new Chord({
166
- suffix: chordSuffix(_classPrivateFieldGet(this, _rootNote), this.suffix),
167
- root: this.root.toChordSymbol(keyObj),
168
- bass: (_this$bass = this.bass) === null || _this$bass === void 0 ? void 0 : _this$bass.toChordSymbol(keyObj)
180
+ var rootKey = this.root.toChordSymbol(keyObj).normalizeEnharmonics(keyObj);
181
+ var chordSymbolChord = new Chord({
182
+ suffix: normalizeSuffix(this.suffix),
183
+ root: rootKey,
184
+ bass: (_this$bass = this.bass) === null || _this$bass === void 0 ? void 0 : _this$bass.toChordSymbol(keyObj).normalizeEnharmonics(rootKey)
169
185
  });
186
+
187
+ if (this.root.isMinor()) {
188
+ chordSymbolChord = chordSymbolChord.makeMinor();
189
+ }
190
+
191
+ return chordSymbolChord;
170
192
  }
171
193
  /**
172
194
  * Converts the chord to a chord symbol string, using the supplied key as a reference.
@@ -193,7 +215,7 @@ var Chord = /*#__PURE__*/function () {
193
215
  return _classPrivateMethodGet(this, _is, _is2).call(this, _constants.SYMBOL);
194
216
  }
195
217
  /**
196
- * Converts the chord to a numeric chord, using the supplied kye as a reference.
218
+ * Converts the chord to a numeric chord, using the supplied key as a reference.
197
219
  * For example, a chord symbol A# with reference key E will return the numeric chord #4.
198
220
  * @param {Key|string} key the reference key
199
221
  * @returns {Chord} the numeric chord
@@ -202,20 +224,77 @@ var Chord = /*#__PURE__*/function () {
202
224
  }, {
203
225
  key: "toNumeric",
204
226
  value: function toNumeric(key) {
205
- var _this$bass2;
227
+ var _this$bass3;
206
228
 
207
229
  if (this.isNumeric()) {
208
230
  return this.clone();
209
231
  }
210
232
 
233
+ if (this.isNumeral()) {
234
+ var _this$bass2;
235
+
236
+ return this.set({
237
+ root: this.root.toNumeric(),
238
+ bass: (_this$bass2 = this.bass) === null || _this$bass2 === void 0 ? void 0 : _this$bass2.toNumeric()
239
+ });
240
+ }
241
+
211
242
  var keyObj = _key["default"].wrap(key);
212
243
 
213
244
  return new Chord({
214
- suffix: chordSuffix(_classPrivateFieldGet(this, _rootNote), this.suffix),
245
+ suffix: normalizeSuffix(this.suffix),
215
246
  root: this.root.toNumeric(keyObj),
216
- bass: (_this$bass2 = this.bass) === null || _this$bass2 === void 0 ? void 0 : _this$bass2.toNumeric(keyObj)
247
+ bass: (_this$bass3 = this.bass) === null || _this$bass3 === void 0 ? void 0 : _this$bass3.toNumeric(keyObj)
217
248
  });
218
249
  }
250
+ /**
251
+ * Converts the chord to a numeral chord, using the supplied key as a reference.
252
+ * For example, a chord symbol A# with reference key E will return the numeral chord #IV.
253
+ * @param {Key|string|null} key the reference key. The key is required when converting a chord symbol
254
+ * @returns {Chord} the numeral chord
255
+ */
256
+
257
+ }, {
258
+ key: "toNumeral",
259
+ value: function toNumeral() {
260
+ var _this$bass5;
261
+
262
+ var key = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;
263
+
264
+ if (this.isNumeral()) {
265
+ return this.clone();
266
+ }
267
+
268
+ if (this.isNumeric()) {
269
+ var _this$bass4;
270
+
271
+ return this.set({
272
+ root: this.root.toNumeral(),
273
+ bass: (_this$bass4 = this.bass) === null || _this$bass4 === void 0 ? void 0 : _this$bass4.toNumeral()
274
+ });
275
+ }
276
+
277
+ var keyObj = _key["default"].wrap(key);
278
+
279
+ return new Chord({
280
+ suffix: normalizeSuffix(this.suffix),
281
+ root: this.root.toNumeral(keyObj),
282
+ bass: (_this$bass5 = this.bass) === null || _this$bass5 === void 0 ? void 0 : _this$bass5.toNumeral(keyObj)
283
+ });
284
+ }
285
+ /**
286
+ * Converts the chord to a numeral chord string, using the supplied kye as a reference.
287
+ * For example, a chord symbol A# with reference key E will return the numeral chord #4.
288
+ * @param {Key|string} key the reference key
289
+ * @returns {string} the numeral chord string
290
+ * @see {toNumeral}
291
+ */
292
+
293
+ }, {
294
+ key: "toNumeralString",
295
+ value: function toNumeralString(key) {
296
+ return this.toNumeral(key).toString();
297
+ }
219
298
  /**
220
299
  * Determines whether the chord is numeric
221
300
  * @returns {boolean}
@@ -239,6 +318,16 @@ var Chord = /*#__PURE__*/function () {
239
318
  value: function toNumericString(key) {
240
319
  return this.toNumeric(key).toString();
241
320
  }
321
+ /**
322
+ * Determines whether the chord is a numeral
323
+ * @returns {boolean}
324
+ */
325
+
326
+ }, {
327
+ key: "isNumeral",
328
+ value: function isNumeral() {
329
+ return _classPrivateMethodGet(this, _is, _is2).call(this, _constants.NUMERAL);
330
+ }
242
331
  /**
243
332
  * Converts the chord to a string, eg `Esus4/G#` or `1sus4/#3`
244
333
  * @returns {string} the chord string
@@ -256,7 +345,7 @@ var Chord = /*#__PURE__*/function () {
256
345
  return chordString;
257
346
  }
258
347
  /**
259
- * Normalizes the chord:
348
+ * Normalizes the chord root and bass notes:
260
349
  * - Fb becomes E
261
350
  * - Cb becomes B
262
351
  * - B# becomes C
@@ -266,14 +355,26 @@ var Chord = /*#__PURE__*/function () {
266
355
  * - 7# becomes 1
267
356
  * - 3# becomes 4
268
357
  *
269
- * If the chord is already normalized, this will return a copy.
358
+ * Besides that it normalizes the suffix. For example, `sus2` becomes `2`, `sus4` becomes `sus`.
359
+ * All suffix normalizations can be found in `src/normalize_mappings/suffix-mapping.txt`.
360
+ *
270
361
  * @returns {Chord} the normalized chord
271
362
  */
272
363
 
273
364
  }, {
274
365
  key: "normalize",
275
- value: function normalize() {
276
- return _classPrivateMethodGet(this, _process, _process2).call(this, 'normalize');
366
+ value: function normalize(key) {
367
+ if (!(0, _utilities.presence)(key)) {
368
+ return _classPrivateMethodGet(this, _process, _process2).call(this, 'normalize').set({
369
+ suffix: (0, _utilities.presence)(normalizeSuffix(this.suffix))
370
+ });
371
+ }
372
+
373
+ return this.set({
374
+ root: this.root.normalizeEnharmonics(key),
375
+ suffix: (0, _utilities.presence)(normalizeSuffix(this.suffix)),
376
+ bass: this.bass ? this.bass.normalizeEnharmonics(this.root.toString()) : null
377
+ });
277
378
  }
278
379
  /**
279
380
  * Switches to the specified modifier
@@ -317,15 +418,26 @@ var Chord = /*#__PURE__*/function () {
317
418
  value: function transpose(delta) {
318
419
  return _classPrivateMethodGet(this, _process, _process2).call(this, 'transpose', delta);
319
420
  }
421
+ }, {
422
+ key: "makeMinor",
423
+ value: function makeMinor() {
424
+ if (!this.suffix || this.suffix[0] !== 'm') {
425
+ return this.set({
426
+ suffix: "m".concat(this.suffix || '')
427
+ });
428
+ }
429
+
430
+ return this.clone();
431
+ }
320
432
  }, {
321
433
  key: "set",
322
434
  value: function set(properties) {
323
- var _this$bass3;
435
+ var _this$bass6;
324
436
 
325
437
  return new this.constructor(_objectSpread({
326
438
  root: this.root.clone(),
327
439
  suffix: this.suffix,
328
- bass: (_this$bass3 = this.bass) === null || _this$bass3 === void 0 ? void 0 : _this$bass3.clone()
440
+ bass: (_this$bass6 = this.bass) === null || _this$bass6 === void 0 ? void 0 : _this$bass6.clone()
329
441
  }, properties));
330
442
  }
331
443
  }], [{
package/lib/constants.js CHANGED
@@ -3,7 +3,7 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.VERSE = exports.TAB = exports.SYMBOL = exports.NUMERIC = exports.NONE = exports.INDETERMINATE = exports.CHORUS = void 0;
6
+ exports.VERSE = exports.TAB = exports.SYMBOL = exports.ROMAN_NUMERALS = exports.NUMERIC = exports.NUMERAL = exports.NONE = exports.INDETERMINATE = exports.CHORUS = void 0;
7
7
 
8
8
  /**
9
9
  * Used to mark a paragraph as verse
@@ -47,4 +47,8 @@ exports.TAB = TAB;
47
47
  var SYMBOL = 'symbol';
48
48
  exports.SYMBOL = SYMBOL;
49
49
  var NUMERIC = 'numeric';
50
- exports.NUMERIC = NUMERIC;
50
+ exports.NUMERIC = NUMERIC;
51
+ var NUMERAL = 'numeral';
52
+ exports.NUMERAL = NUMERAL;
53
+ var ROMAN_NUMERALS = ['I', 'II', 'III', 'IV', 'V', 'VI', 'VII'];
54
+ exports.ROMAN_NUMERALS = ROMAN_NUMERALS;
package/lib/key.js CHANGED
@@ -11,6 +11,8 @@ var _note = _interopRequireDefault(require("./note"));
11
11
 
12
12
  var _constants = require("./constants");
13
13
 
14
+ var _enharmonicNormalize = _interopRequireDefault(require("./normalize_mappings/enharmonic-normalize"));
15
+
14
16
  var _MODIFIER_TRANSPOSITI;
15
17
 
16
18
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
@@ -43,17 +45,24 @@ var FLAT = 'b';
43
45
  var SHARP = '#';
44
46
  var MODIFIER_TRANSPOSITION = (_MODIFIER_TRANSPOSITI = {}, _defineProperty(_MODIFIER_TRANSPOSITI, SHARP, 1), _defineProperty(_MODIFIER_TRANSPOSITI, FLAT, -1), _MODIFIER_TRANSPOSITI);
45
47
 
46
- var symbolKeyRegex = /*#__PURE__*/_wrapRegExp(/^([A-G])(#|b)?$/i, {
48
+ var symbolKeyRegex = /*#__PURE__*/_wrapRegExp(/^([A-G])(#|b)?(m)?$/i, {
47
49
  note: 1,
48
- modifier: 2
50
+ modifier: 2,
51
+ minor: 3
52
+ });
53
+
54
+ var numericKeyRegex = /*#__PURE__*/_wrapRegExp(/^(#|b)?([1-7])(m)?$/, {
55
+ modifier: 1,
56
+ note: 2,
57
+ minor: 3
49
58
  });
50
59
 
51
- var numericKeyRegex = /*#__PURE__*/_wrapRegExp(/^(#|b)?([1-7])$/, {
60
+ var numeralKeyRegex = /*#__PURE__*/_wrapRegExp(/^(#|b)?(I{1,3}|IV|VI{0,2}|i{1,3}|iv|vi{0,2})$/, {
52
61
  modifier: 1,
53
62
  note: 2
54
63
  });
55
64
 
56
- var regexes = [symbolKeyRegex, numericKeyRegex];
65
+ var regexes = [symbolKeyRegex, numericKeyRegex, numeralKeyRegex];
57
66
 
58
67
  var _set = /*#__PURE__*/new WeakSet();
59
68
 
@@ -61,14 +70,17 @@ var Key = /*#__PURE__*/function () {
61
70
  function Key(_ref) {
62
71
  var note = _ref.note,
63
72
  _ref$modifier = _ref.modifier,
64
- modifier = _ref$modifier === void 0 ? null : _ref$modifier;
73
+ modifier = _ref$modifier === void 0 ? null : _ref$modifier,
74
+ _ref$minor = _ref.minor,
75
+ minor = _ref$minor === void 0 ? false : _ref$minor;
65
76
 
66
77
  _classCallCheck(this, Key);
67
78
 
68
79
  _classPrivateMethodInitSpec(this, _set);
69
80
 
70
- this.note = note instanceof _note["default"] ? note : new _note["default"](note);
81
+ this.note = note instanceof _note["default"] ? note : _note["default"].parse(note);
71
82
  this.modifier = modifier || null;
83
+ this.minor = !!minor || false;
72
84
  }
73
85
 
74
86
  _createClass(Key, [{
@@ -85,6 +97,11 @@ var Key = /*#__PURE__*/function () {
85
97
 
86
98
  return delta;
87
99
  }
100
+ }, {
101
+ key: "isMinor",
102
+ value: function isMinor() {
103
+ return this.note.isMinor();
104
+ }
88
105
  }, {
89
106
  key: "clone",
90
107
  value: function clone() {
@@ -97,7 +114,7 @@ var Key = /*#__PURE__*/function () {
97
114
  return this.clone();
98
115
  }
99
116
 
100
- var transposeDistance = this.note.getTransposeDistance() + (MODIFIER_TRANSPOSITION[this.modifier] || 0);
117
+ var transposeDistance = this.note.getTransposeDistance(key.minor) + (MODIFIER_TRANSPOSITION[this.modifier] || 0);
101
118
  return key.transpose(transposeDistance).normalize().useModifier(key.modifier);
102
119
  }
103
120
  }, {
@@ -120,6 +137,18 @@ var Key = /*#__PURE__*/function () {
120
137
  value: function isChordSymbol() {
121
138
  return this.is(_constants.SYMBOL);
122
139
  }
140
+ }, {
141
+ key: "isNumeral",
142
+ value: function isNumeral() {
143
+ return this.is(_constants.NUMERAL);
144
+ }
145
+ }, {
146
+ key: "equals",
147
+ value: function equals(_ref2) {
148
+ var note = _ref2.note,
149
+ modifier = _ref2.modifier;
150
+ return this.note.equals(note) && this.modifier === modifier;
151
+ }
123
152
  }, {
124
153
  key: "toNumeric",
125
154
  value: function toNumeric(key) {
@@ -127,39 +156,69 @@ var Key = /*#__PURE__*/function () {
127
156
  return this.clone();
128
157
  }
129
158
 
159
+ if (this.isNumeral()) {
160
+ return _classPrivateMethodGet(this, _set, _set2).call(this, {
161
+ note: this.note.toNumeric()
162
+ });
163
+ }
164
+
130
165
  var numericKey = new Key({
131
166
  note: 1
132
167
  });
133
168
  var symbolKey = key.clone();
134
- var reference = this.clone().normalize().useModifier(key.modifier);
169
+ var reference = this.clone().normalize().useModifier(key.modifier).normalizeEnharmonics(key);
135
170
 
136
171
  while (!symbolKey.equals(reference)) {
137
172
  numericKey = numericKey.transposeUp().useModifier(key.modifier);
138
- symbolKey = symbolKey.transposeUp().normalize().useModifier(key.modifier);
173
+ symbolKey = symbolKey.transposeUp().normalize().useModifier(key.modifier).normalizeEnharmonics(key);
139
174
  }
140
175
 
141
176
  return numericKey;
142
177
  }
143
- }, {
144
- key: "equals",
145
- value: function equals(_ref2) {
146
- var note = _ref2.note,
147
- modifier = _ref2.modifier;
148
- return this.note.equals(note) && this.modifier === modifier;
149
- }
150
178
  }, {
151
179
  key: "toNumericString",
152
180
  value: function toNumericString(key) {
153
181
  return this.toNumeric(key).toString();
154
182
  }
183
+ }, {
184
+ key: "toNumeral",
185
+ value: function toNumeral(key) {
186
+ if (this.isNumeral()) {
187
+ return this.clone();
188
+ }
189
+
190
+ if (this.isNumeric()) {
191
+ return _classPrivateMethodGet(this, _set, _set2).call(this, {
192
+ note: this.note.toNumeral()
193
+ });
194
+ }
195
+
196
+ var numeralKey = new Key({
197
+ note: 'I'
198
+ });
199
+ var symbolKey = key.clone();
200
+ var reference = this.clone().normalize().useModifier(key.modifier).normalizeEnharmonics(key);
201
+
202
+ while (!symbolKey.equals(reference)) {
203
+ numeralKey = numeralKey.transposeUp().useModifier(key.modifier);
204
+ symbolKey = symbolKey.transposeUp().normalize().useModifier(key.modifier).normalizeEnharmonics(key);
205
+ }
206
+
207
+ return numeralKey;
208
+ }
209
+ }, {
210
+ key: "toNumeralString",
211
+ value: function toNumeralString(key) {
212
+ return this.toNumeral(key).toString();
213
+ }
155
214
  }, {
156
215
  key: "toString",
157
216
  value: function toString() {
158
- if (this.is(_constants.NUMERIC)) {
159
- return "".concat(this.modifier || '').concat(this.note);
217
+ if (this.isChordSymbol()) {
218
+ return "".concat(this.note).concat(this.modifier || '');
160
219
  }
161
220
 
162
- return "".concat(this.note).concat(this.modifier || '');
221
+ return "".concat(this.modifier || '').concat(this.note);
163
222
  }
164
223
  }, {
165
224
  key: "transpose",
@@ -266,6 +325,21 @@ var Key = /*#__PURE__*/function () {
266
325
  });
267
326
  }
268
327
 
328
+ return this.clone();
329
+ }
330
+ }, {
331
+ key: "normalizeEnharmonics",
332
+ value: function normalizeEnharmonics(key) {
333
+ if (key) {
334
+ var rootKeyString = key.minor ? "".concat(key, "m") : key.toString();
335
+ var enharmonics = _enharmonicNormalize["default"][rootKeyString];
336
+ var thisKeyString = this.toString();
337
+
338
+ if (enharmonics && enharmonics[thisKeyString]) {
339
+ return Key.parse(enharmonics[thisKeyString]);
340
+ }
341
+ }
342
+
269
343
  return this.clone();
270
344
  }
271
345
  }], [{
@@ -303,7 +377,8 @@ var Key = /*#__PURE__*/function () {
303
377
  function _set2(attributes) {
304
378
  return new this.constructor(_objectSpread({
305
379
  note: this.note.clone(),
306
- modifier: this.modifier
380
+ modifier: this.modifier,
381
+ minor: !!this.minor
307
382
  }, attributes));
308
383
  }
309
384