@hebcal/leyning 8.0.0 → 8.1.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.
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- /*! @hebcal/leyning v8.0.0 */
1
+ /*! @hebcal/leyning v8.1.0 */
2
2
  'use strict';
3
3
 
4
4
  var core = require('@hebcal/core');
@@ -263,11 +263,11 @@ function lookupFestival(holiday) {
263
263
  }
264
264
  const result = src.fullkriyah ? clone(src) : src;
265
265
  if (result.fullkriyah) {
266
- Object.values(result.fullkriyah).forEach(aliyah => {
266
+ for (const aliyah of Object.values(result.fullkriyah)) {
267
267
  if (typeof aliyah.k === 'number') {
268
268
  aliyah.k = BOOK[aliyah.k];
269
269
  }
270
- });
270
+ }
271
271
  }
272
272
  if (src.note) {
273
273
  result.note = src.note;
@@ -310,32 +310,23 @@ function getLeyningKeyForEvent(ev, il = false) {
310
310
  }
311
311
  return desc;
312
312
  }
313
+ const cholHaMoedDay = ev.cholHaMoedDay;
313
314
  if (day == 1 && month === core.months.TISHREI) {
314
315
  return isShabbat ? 'Rosh Hashana I (on Shabbat)' : 'Rosh Hashana I';
315
- } else if (ev.cholHaMoedDay) {
316
+ } else if (cholHaMoedDay) {
316
317
  // Sukkot or Pesach
317
318
  if (isShabbat) {
318
319
  return holiday + ' Shabbat Chol ha-Moed';
319
320
  } else if (desc == 'Sukkot VII (Hoshana Raba)') {
320
321
  return 'Sukkot Final Day (Hoshana Raba)';
321
322
  }
322
- if (isPesach && ev.cholHaMoedDay) {
323
+ if (isPesach && cholHaMoedDay) {
323
324
  if (dow === 0 && desc === 'Pesach IV (CH\'\'M)') {
324
325
  return 'Pesach Chol ha-Moed Day 2 on Sunday';
325
326
  } else if (dow === 1 && desc === 'Pesach V (CH\'\'M)') {
326
327
  return 'Pesach Chol ha-Moed Day 3 on Monday';
327
328
  }
328
329
  }
329
- // If Shabbat falls on the third day of Chol ha-Moed Pesach,
330
- // the readings for the third, fourth, and fifth days are moved ahead
331
- let cholHaMoedDay = ev.cholHaMoedDay;
332
- if (isPesach && cholHaMoedDay >= 3) {
333
- if (dow == 0 && cholHaMoedDay == 4) {
334
- cholHaMoedDay = 3;
335
- } else if (dow == 1 && cholHaMoedDay == 5) {
336
- cholHaMoedDay = 4;
337
- }
338
- }
339
330
  return `${holiday} Chol ha-Moed Day ${cholHaMoedDay}`;
340
331
  } else if (ev.chanukahDay) {
341
332
  if (isShabbat && isRoshChodesh) {
@@ -391,7 +382,6 @@ function getLeyningKeyForEvent(ev, il = false) {
391
382
  return 'Chanukah Day 7 (on Rosh Chodesh)'; // 1st of Tevet
392
383
  }
393
384
  }
394
-
395
385
  if (isRoshChodesh) {
396
386
  return desc;
397
387
  }
@@ -493,14 +483,16 @@ function specialReadings2(parsha, hd, il, aliyot) {
493
483
  if (special.fullkriyah) {
494
484
  const aliyotMap = clone(aliyot);
495
485
  mergeAliyotWithSpecial(aliyotMap, special.fullkriyah);
496
- Object.keys(special.fullkriyah).map(k => reason[k] = key);
486
+ for (const num of Object.keys(special.fullkriyah)) {
487
+ reason[num] = key;
488
+ }
497
489
  aliyot = aliyotMap;
498
490
  }
499
491
  }
500
492
  const parshaName = parshaToString(parsha);
501
493
  const events0 = core.HebrewCalendar.getHolidaysOnDate(hd, il) || [];
502
494
  const events = events0.filter(ev => !(ev.getFlags() & core.flags.ROSH_CHODESH));
503
- events.forEach(ev => {
495
+ for (const ev of events) {
504
496
  if (ev.getDesc() === 'Shabbat Shuva') {
505
497
  handleSpecial(`Shabbat Shuva (with ${parshaName})`);
506
498
  } else {
@@ -509,7 +501,7 @@ function specialReadings2(parsha, hd, il, aliyot) {
509
501
  handleSpecial(key);
510
502
  }
511
503
  }
512
- });
504
+ }
513
505
  if (!haft) {
514
506
  const day = hd.getDate();
515
507
  if (parshaName === 'Pinchas' && day > 17) {
@@ -667,7 +659,7 @@ const Bereshit={num:1,hebrew:"בְּרֵאשִׁית",book:1,haft:{k:"Isaiah",b:
667
659
  * @property {LeyningNames} name
668
660
  * @property {string[]} [parsha] - An array of either 1 (regular) or 2 (doubled parsha).
669
661
  * `undefined` for holiday readings
670
- * @property {number} [parshaNum] - 1 for Bereshit, 2 for Noach, etc. `undefined` for holiday readings
662
+ * @property {number|number[]} [parshaNum] - 1 for Bereshit, 2 for Noach, etc. `undefined` for holiday readings
671
663
  * @property {string} summary - Such as `Genesis 1:1 - 6:8`
672
664
  * @property {Aliyah|Aliyah[]} haft - Haftarah object(s)
673
665
  * @property {string} haftara - Haftarah, such as `Isaiah 42:5 – 43:11`
@@ -701,6 +693,19 @@ function getHaftaraKey(parsha) {
701
693
  }
702
694
  }
703
695
 
696
+ /**
697
+ * Transliterated English and Hebrew names of this parsha
698
+ * @param {string|string[]} parsha untranslated name like 'Pinchas' or ['Pinchas'] or ['Matot','Masei']
699
+ * @return {LeyningNames}
700
+ */
701
+ function makeLeyningNames(parsha) {
702
+ const name = parshaToString(parsha);
703
+ return {
704
+ en: name,
705
+ he: parsha.map(s => core.Locale.lookupTranslation(s, 'he')).join('־')
706
+ };
707
+ }
708
+
704
709
  /**
705
710
  * Looks up regular leyning for a weekly parsha with no special readings
706
711
  * @private
@@ -711,26 +716,22 @@ function getLeyningForParshaShabbatOnly(parsha) {
711
716
  const raw = lookupParsha(parsha);
712
717
  const fullkriyah = {};
713
718
  const book = BOOK[raw.book];
714
- Object.keys(raw.fullkriyah).forEach(num => {
715
- const src = raw.fullkriyah[num];
716
- const reading = {
719
+ for (const [num, src] of Object.entries(raw.fullkriyah)) {
720
+ const aliyah = {
717
721
  k: book,
718
722
  b: src[0],
719
723
  e: src[1]
720
724
  };
721
- fullkriyah[num] = reading;
722
- });
723
- Object.values(fullkriyah).map(aliyah => calculateNumVerses(aliyah));
725
+ calculateNumVerses(aliyah);
726
+ fullkriyah[num] = aliyah;
727
+ }
724
728
  const name = parshaToString(parsha);
725
729
  const parshaNameArray = raw.combined ? [raw.p1, raw.p2] : [name];
726
730
  const parts = makeLeyningParts(fullkriyah);
727
731
  const summary = makeSummaryFromParts(parts);
728
732
  /** @type {Leyning} */
729
733
  const result = {
730
- name: {
731
- en: name,
732
- he: parshaNameArray.map(s => core.Locale.lookupTranslation(s, 'he')).join('־')
733
- },
734
+ name: makeLeyningNames(parshaNameArray),
734
735
  parsha: parshaNameArray,
735
736
  parshaNum: raw.num,
736
737
  summary,
@@ -832,18 +833,20 @@ function getLeyningForParshaHaShavua(ev, il = false) {
832
833
  const reasons = Object.keys(reason);
833
834
  if (reasons.length !== 0) {
834
835
  result.reason = reason;
835
- reasons.forEach(num => {
836
+ for (const num of reasons) {
836
837
  if (num === 'haftara' || num === 'sephardic') {
837
838
  const haftObj = result[num === 'haftara' ? 'haft' : 'seph'];
838
839
  const hafts = Array.isArray(haftObj) ? haftObj : [haftObj];
839
- hafts.forEach(haft => haft.reason = reason[num]);
840
+ for (const haft of hafts) {
841
+ haft.reason = reason[num];
842
+ }
840
843
  } else {
841
844
  const aliyah = result.fullkriyah[num];
842
845
  if (typeof aliyah === 'object') {
843
846
  aliyah.reason = reason[num];
844
847
  }
845
848
  }
846
- });
849
+ }
847
850
  }
848
851
  return result;
849
852
  }
@@ -888,6 +891,18 @@ function findParshaHaShavua(saturday, il) {
888
891
  if (!parsha.chag) {
889
892
  return parsha;
890
893
  }
894
+ // Special case between YK and Simchat Torah
895
+ if (saturday.getMonth() === core.months.TISHREI) {
896
+ const dd = saturday.getDate();
897
+ const simchatTorah = il ? 22 : 23;
898
+ if (dd > 10 && dd <= simchatTorah) {
899
+ return {
900
+ parsha: ['Vezot Haberakhah'],
901
+ chag: false,
902
+ num: 54
903
+ };
904
+ }
905
+ }
891
906
  // Search for next regular parsha, which could even spill into next year
892
907
  const endOfYear = new core.HDate(1, core.months.TISHREI, hyear + 1).abs() - 1;
893
908
  const endAbs = endOfYear + 30;
@@ -922,48 +937,44 @@ function findParshaHaShavua(saturday, il) {
922
937
  */
923
938
  function getLeyningOnDate(hdate, il, wantarray = false) {
924
939
  const dow = hdate.getDay();
925
- const hyear = hdate.getFullYear();
926
- const sedra = core.HebrewCalendar.getSedra(hyear, il);
927
- const parsha = sedra.lookup(hdate);
928
- if (dow === 6 && !parsha.chag) {
929
- const parshaEvent = new core.ParshaEvent(hdate, parsha.parsha, il);
930
- const reading = getLeyningForParshaHaShavua(parshaEvent, il);
931
- return wantarray ? [reading] : reading;
940
+ if (dow === 6) {
941
+ const hyear = hdate.getFullYear();
942
+ const sedra = core.HebrewCalendar.getSedra(hyear, il);
943
+ const parsha = sedra.lookup(hdate);
944
+ if (!parsha.chag) {
945
+ const parshaEvent = new core.ParshaEvent(hdate, parsha.parsha, il);
946
+ const reading = getLeyningForParshaHaShavua(parshaEvent, il);
947
+ return wantarray ? [reading] : reading;
948
+ }
932
949
  }
933
950
  const events = core.HebrewCalendar.getHolidaysOnDate(hdate, il) || [];
934
951
  const arr = [];
935
- for (let i = 0; i < events.length; i++) {
936
- const ev = events[i];
952
+ let hasFullKriyah = false;
953
+ for (const ev of events) {
937
954
  const reading = getLeyningForHoliday(ev, il);
938
955
  if (reading) {
939
- if (wantarray) {
940
- arr.push(reading);
941
- const mincha = getMincha(ev, il);
942
- if (mincha) {
943
- arr.push(mincha);
944
- }
945
- } else {
946
- return reading;
956
+ arr.push(reading);
957
+ if (reading.fullkriyah) {
958
+ hasFullKriyah = true;
959
+ }
960
+ const mincha = getMincha(ev, il);
961
+ if (mincha) {
962
+ arr.push(mincha);
947
963
  }
948
964
  }
949
965
  }
950
- if (wantarray && arr.length !== 0) {
951
- return arr;
952
- }
953
- if (dow === 1 || dow === 4) {
966
+ if (!hasFullKriyah && (dow === 1 || dow === 4)) {
954
967
  const saturday = hdate.onOrAfter(6);
955
- const parsha2 = findParshaHaShavua(saturday);
956
- const reading = getLeyningForParsha(parsha2.parsha);
957
- const result = {
958
- name: reading.name,
959
- parsha: reading.parsha,
960
- parshaNum: reading.parshaNum,
961
- weekday: reading.weekday
968
+ const parsha = findParshaHaShavua(saturday);
969
+ const reading = {
970
+ name: makeLeyningNames(parsha.parsha),
971
+ parsha: parsha.parsha,
972
+ parshaNum: parsha.num,
973
+ weekday: getWeekdayReading(parsha.parsha)
962
974
  };
963
- return wantarray ? [result] : result;
975
+ arr.unshift(reading);
964
976
  }
965
- // no reading today: it's not Shabbat, Mon/Thu, or a Torah-reading holiday
966
- return wantarray ? [] : undefined;
977
+ return wantarray ? arr : arr[0];
967
978
  }
968
979
  const minchaSuffix = ' (Mincha)';
969
980
 
@@ -1035,11 +1046,11 @@ function writeFullKriyahCsv(stream, hyear, il) {
1035
1046
  const events = events0.filter(ev => ev.getDesc() !== 'Rosh Chodesh Tevet');
1036
1047
  const parshaDates = getParshaDates(events);
1037
1048
  stream.write('"Date","Parashah","Aliyah","Reading","Verses"\r\n');
1038
- events.forEach(ev => {
1049
+ for (const ev of events) {
1039
1050
  if (ev.getFlags() === core.flags.PARSHA_HASHAVUA || !parshaDates[ev.getDate().toString()]) {
1040
1051
  writeFullKriyahEvent(stream, ev, il);
1041
1052
  }
1042
- });
1053
+ }
1043
1054
  }
1044
1055
 
1045
1056
  /**
@@ -1108,13 +1119,13 @@ function writeCsvLines(stream, ev, reading, il, isParsha) {
1108
1119
  const parsha = isParsha ? ev.basename() : getLeyningKeyForEvent(ev, il) || ev.render();
1109
1120
  const date = fmtDate(ev.getDate().greg());
1110
1121
  const lines = getFullKriyahLines(reading);
1111
- lines.forEach(s => {
1122
+ for (const s of lines) {
1112
1123
  const code = s[0].charCodeAt(0);
1113
1124
  if (code < 48 || code > 57) {
1114
1125
  s[0] = `"${s[0]}"`;
1115
1126
  }
1116
1127
  stream.write(`${date},"${parsha}",${s[0]},"${s[1]}",${s[2]}\r\n`);
1117
- });
1128
+ }
1118
1129
  stream.write('\r\n');
1119
1130
  }
1120
1131
 
@@ -1126,8 +1137,7 @@ function writeCsvLines(stream, ev, reading, il, isParsha) {
1126
1137
  function getFullKriyahLines(reading) {
1127
1138
  const lines = [];
1128
1139
  if (reading.fullkriyah) {
1129
- Object.keys(reading.fullkriyah).forEach(num => {
1130
- const a = reading.fullkriyah[num];
1140
+ for (const [num, a] of Object.entries(reading.fullkriyah)) {
1131
1141
  if (typeof a !== 'undefined') {
1132
1142
  var _reading$reason;
1133
1143
  const k = num == 'M' ? 'maf' : num;
@@ -1137,7 +1147,7 @@ function getFullKriyahLines(reading) {
1137
1147
  }
1138
1148
  lines.push([k, aliyah, a.v || '']);
1139
1149
  }
1140
- });
1150
+ }
1141
1151
  }
1142
1152
  let specialHaftara = false;
1143
1153
  if (reading.haftara) {
@@ -1158,13 +1168,12 @@ function getFullKriyahLines(reading) {
1158
1168
  lines.push(['Alternate Haftara', haftara, reading.triHaftaraNumV || '']);
1159
1169
  }
1160
1170
  if (reading.megillah) {
1161
- Object.keys(reading.megillah).forEach(num => {
1162
- const a = reading.megillah[num];
1171
+ for (const [num, a] of Object.entries(reading.megillah)) {
1163
1172
  if (typeof a !== 'undefined') {
1164
1173
  const aliyah = formatAliyahWithBook(a);
1165
1174
  lines.push([`Megillah Ch. ${num}`, aliyah, a.v || '']);
1166
1175
  }
1167
- });
1176
+ }
1168
1177
  }
1169
1178
  return lines;
1170
1179
  }
@@ -1186,6 +1195,7 @@ exports.getWeekdayReading = getWeekdayReading;
1186
1195
  exports.hasFestival = hasFestival;
1187
1196
  exports.lookupFestival = lookupFestival;
1188
1197
  exports.lookupParsha = lookupParsha;
1198
+ exports.makeLeyningNames = makeLeyningNames;
1189
1199
  exports.makeLeyningParts = makeLeyningParts;
1190
1200
  exports.makeLeyningSummary = makeLeyningSummary;
1191
1201
  exports.makeSummaryFromParts = makeSummaryFromParts;