Skip to content

Commit f6b8c84

Browse files
committed
Add Psalms (30-day schedule) to daily learning
1 parent c5f2090 commit f6b8c84

11 files changed

+247
-21
lines changed

README.md

+62
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ Supports several learning schedules
88
* Daf Yomi (Babylonian Talmud / Bavli) - `dafYomi`
99
* Mishna Yomi - `mishnaYomi`
1010
* Nach Yomi - `nachYomi`
11+
* Psalms / Tehillim (30 day cycle) - `psalms`
1112
* Yerushalmi Yomi (Jerusalem Talmud)
1213
* Vilna edition - `yerushalmi-vilna`
1314
* Schottenstein edition - `yerushalmi-schottenstein`
@@ -56,6 +57,9 @@ and Ketuvim (Writings).</p>
5657
<dt><a href="#ShemiratHaLashonEvent">ShemiratHaLashonEvent</a></dt>
5758
<dd><p>Event wrapper around a Sefer Shemirat HaLashon instance</p>
5859
</dd>
60+
<dt><a href="#PsalmsEvent">PsalmsEvent</a></dt>
61+
<dd><p>Event wrapper around a daily Psalms / Tehillim</p>
62+
</dd>
5963
</dl>
6064

6165
## Constants
@@ -94,6 +98,9 @@ cycle began (2 February 1980 for Vilna,
9498
<dt><a href="#shemiratHaLashon">shemiratHaLashon(hdate)</a> ⇒ <code>any</code></dt>
9599
<dd><p>Looks up Sefer Shemirat HaLashon Calendar for date</p>
96100
</dd>
101+
<dt><a href="#dailyPsalms">dailyPsalms(date)</a> ⇒ <code>any</code></dt>
102+
<dd><p>Calculates Daily Psalms (Tehillim) for 30-day cycle.</p>
103+
</dd>
97104
</dl>
98105

99106
## Typedefs
@@ -536,6 +543,50 @@ Returns a link to sefaria.org
536543

537544
### shemiratHaLashonEvent.getCategories() ⇒ <code>Array.&lt;string&gt;</code>
538545
**Kind**: instance method of [<code>ShemiratHaLashonEvent</code>](#ShemiratHaLashonEvent)
546+
<a name="PsalmsEvent"></a>
547+
548+
## PsalmsEvent
549+
Event wrapper around a daily Psalms / Tehillim
550+
551+
**Kind**: global class
552+
553+
* [PsalmsEvent](#PsalmsEvent)
554+
* [new PsalmsEvent(date, reading)](#new_PsalmsEvent_new)
555+
* [.render([locale])](#PsalmsEvent+render) ⇒ <code>string</code>
556+
* [.url()](#PsalmsEvent+url) ⇒ <code>string</code>
557+
* [.getCategories()](#PsalmsEvent+getCategories) ⇒ <code>Array.&lt;string&gt;</code>
558+
559+
<a name="new_PsalmsEvent_new"></a>
560+
561+
### new PsalmsEvent(date, reading)
562+
563+
| Param | Type |
564+
| --- | --- |
565+
| date | <code>HDate</code> |
566+
| reading | <code>Array.&lt;number&gt;</code> \| <code>Array.&lt;string&gt;</code> |
567+
568+
<a name="PsalmsEvent+render"></a>
569+
570+
### psalmsEvent.render([locale]) ⇒ <code>string</code>
571+
Returns name of reading
572+
573+
**Kind**: instance method of [<code>PsalmsEvent</code>](#PsalmsEvent)
574+
575+
| Param | Type | Description |
576+
| --- | --- | --- |
577+
| [locale] | <code>string</code> | Optional locale name (defaults to active locale). |
578+
579+
<a name="PsalmsEvent+url"></a>
580+
581+
### psalmsEvent.url() ⇒ <code>string</code>
582+
Returns a link to sefaria.org
583+
e.g. https://www.sefaria.org/Psalms.1-9?lang=b
584+
585+
**Kind**: instance method of [<code>PsalmsEvent</code>](#PsalmsEvent)
586+
<a name="PsalmsEvent+getCategories"></a>
587+
588+
### psalmsEvent.getCategories() ⇒ <code>Array.&lt;string&gt;</code>
589+
**Kind**: instance method of [<code>PsalmsEvent</code>](#PsalmsEvent)
539590
<a name="vilna"></a>
540591

541592
## vilna
@@ -607,6 +658,17 @@ Looks up Sefer Shemirat HaLashon Calendar for date
607658
| --- | --- |
608659
| hdate | <code>HDate</code> |
609660

661+
<a name="dailyPsalms"></a>
662+
663+
## dailyPsalms(date) ⇒ <code>any</code>
664+
Calculates Daily Psalms (Tehillim) for 30-day cycle.
665+
666+
**Kind**: global function
667+
668+
| Param | Type | Description |
669+
| --- | --- | --- |
670+
| date | <code>HDate</code> \| <code>Date</code> \| <code>number</code> | Hebrew or Gregorian date |
671+
610672
<a name="MishnaYomi"></a>
611673

612674
## MishnaYomi : <code>Object</code>

package-lock.json

+10-10
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@hebcal/learning",
3-
"version": "1.3.4",
3+
"version": "1.4.0",
44
"description": "Daily learning schedules: Daf Yomi, Mishna Yomi, etc",
55
"main": "dist/index.js",
66
"module": "dist/index.mjs",
@@ -23,7 +23,7 @@
2323
},
2424
"homepage": "https://github.com/mjradwin/hebcal-learning#readme",
2525
"dependencies": {
26-
"@hebcal/core": "^4.1.0"
26+
"@hebcal/core": "^4.1.1"
2727
},
2828
"files": [
2929
"types.d.ts",
@@ -56,7 +56,7 @@
5656
"eslint-config-google": "^0.14.0",
5757
"jsdoc": "^4.0.2",
5858
"jsdoc-to-markdown": "^8.0.0",
59-
"rollup": "^3.23.1",
59+
"rollup": "^3.24.0",
6060
"ttag-cli": "^1.10.5"
6161
}
6262
}

src/MishnaYomiEvent.spec.js

+8-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,13 @@
11
import test from 'ava';
22
import {MishnaYomiEvent} from './MishnaYomiEvent';
3-
import {HDate} from '@hebcal/core';
3+
import {HDate, Locale} from '@hebcal/core';
4+
import poAshkenazi from './ashkenazi.po.json';
5+
import poHe from './he.po.json';
6+
7+
Locale.addTranslations('ashkenazi', poAshkenazi);
8+
Locale.addTranslations('a', poAshkenazi);
9+
Locale.addTranslations('he', poHe);
10+
Locale.addTranslations('h', poHe);
411

512
test('MishnaYomiEvent-url', (t) => {
613
const my = [{k: 'Berakhot', v: '3:6'}, {k: 'Berakhot', v: '4:1'}];

src/index.js

+1
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,4 @@ export {yerushalmiYomi, YerushalmiYomiEvent, vilna, schottenstein} from './yerus
88
export {chofetzChaim, ChofetzChaimEvent} from './chofetzChaim';
99
export {dailyRambam1, DailyRambamEvent} from './rambam';
1010
export {shemiratHaLashon, ShemiratHaLashonEvent} from './shemiratHaLashon';
11+
export {dailyPsalms, PsalmsEvent} from './psalms';

src/psalms.js

+95
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
import {HDate, Event, flags, Locale, gematriya} from '@hebcal/core';
2+
3+
const schedule = [
4+
[],
5+
[1, 9],
6+
[10, 17],
7+
[18, 22],
8+
[23, 28],
9+
[29, 34],
10+
[35, 38],
11+
[39, 43],
12+
[44, 48],
13+
[49, 54],
14+
[55, 59],
15+
[60, 65],
16+
[66, 68],
17+
[69, 71],
18+
[72, 76],
19+
[77, 78],
20+
[79, 82],
21+
[83, 87],
22+
[88, 89],
23+
[90, 96],
24+
[97, 103],
25+
[104, 105],
26+
[106, 107],
27+
[108, 112],
28+
[113, 118],
29+
['119:1', '119:96'],
30+
['119:97', '119:176'],
31+
[120, 134],
32+
[135, 139],
33+
[140, 144],
34+
[145, 150],
35+
];
36+
37+
/**
38+
* Calculates Daily Psalms (Tehillim) for 30-day cycle.
39+
* @param {HDate|Date|number} date - Hebrew or Gregorian date
40+
* @return {any}
41+
*/
42+
export function dailyPsalms(date) {
43+
const hd = new HDate(date);
44+
const dd = hd.getDate();
45+
if (dd === 29 && hd.daysInMonth() === 29) {
46+
return [140, 150]; // read both 29th and 30th
47+
}
48+
return schedule[dd];
49+
}
50+
51+
/**
52+
* Event wrapper around a daily Psalms / Tehillim
53+
*/
54+
export class PsalmsEvent extends Event {
55+
/**
56+
* @param {HDate} date
57+
* @param {number[]|string[]} reading
58+
*/
59+
constructor(date, reading) {
60+
super(date, `Psalms ${reading[0]}-${reading[1]}`, flags.USER_EVENT);
61+
this.reading = reading;
62+
this.alarm = false;
63+
this.category = 'Psalms';
64+
}
65+
/**
66+
* Returns name of reading
67+
* @param {string} [locale] Optional locale name (defaults to active locale).
68+
* @return {string}
69+
*/
70+
render(locale) {
71+
locale = locale || Locale.getLocaleName();
72+
if (typeof locale === 'string') {
73+
locale = locale.toLowerCase();
74+
}
75+
const book = Locale.gettext('Psalms', locale);
76+
const reading = this.reading;
77+
if ((locale === 'he' || locale === 'he-x-nonikud') && typeof reading[0] === 'number') {
78+
return book + ' ' + gematriya(reading[0]) + '-' + gematriya(reading[1]);
79+
}
80+
return book + ' ' + reading[0] + '-' + reading[1];
81+
}
82+
/**
83+
* Returns a link to sefaria.org
84+
* e.g. https://www.sefaria.org/Psalms.1-9?lang=b
85+
* @return {string}
86+
*/
87+
url() {
88+
const str = this.getDesc().replace(' ', '.').replace(/:/g, '.');
89+
return `https://www.sefaria.org/${str}?lang=bi`;
90+
}
91+
/** @return {string[]} */
92+
getCategories() {
93+
return ['dailyPsalms'];
94+
}
95+
}

src/psalms.spec.js

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import test from 'ava';
2+
import {dailyPsalms, PsalmsEvent} from './psalms';
3+
import {HDate} from '@hebcal/core';
4+
5+
test('dailyPsalms', (t) => {
6+
t.deepEqual(dailyPsalms(new HDate(1, 'Av', 5783)), [1, 9]);
7+
t.deepEqual(dailyPsalms(new HDate(18, 'Sivan', 5783)), [88, 89]);
8+
t.deepEqual(dailyPsalms(new HDate(29, 'Sivan', 5783)), [140, 144]);
9+
t.deepEqual(dailyPsalms(new HDate(30, 'Sivan', 5783)), [145, 150]);
10+
t.deepEqual(dailyPsalms(new HDate(29, 'Tamuz', 5783)), [140, 150]);
11+
});
12+
13+
test('PsalmsEvent.url', (t) => {
14+
const hd = new HDate(2, 'Av', 5783);
15+
const reading = dailyPsalms(hd);
16+
const ev = new PsalmsEvent(hd, reading);
17+
t.is(ev.url(), 'https://www.sefaria.org/Psalms.10-17?lang=bi');
18+
});
19+
20+
test('PsalmsEvent.render', (t) => {
21+
const hd = new HDate(3, 'Av', 5783);
22+
const reading = dailyPsalms(hd);
23+
const ev = new PsalmsEvent(hd, reading);
24+
t.is(ev.render('en'), 'Psalms 18-22');
25+
});

src/register.js

+12-6
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,9 @@ import {yerushalmiYomi, YerushalmiYomiEvent, vilna, schottenstein} from './yerus
88
import {chofetzChaim, ChofetzChaimEvent, chofetzChaimStart} from './chofetzChaim';
99
import {dailyRambam1, DailyRambamEvent, rambam1Start} from './rambam';
1010
import {shemiratHaLashon, ShemiratHaLashonEvent, shemiratHaLashonStart} from './shemiratHaLashon';
11-
import po_he from './he.po.json';
12-
import po_ashkenazi from './ashkenazi.po.json';
11+
import {dailyPsalms, PsalmsEvent} from './psalms';
12+
import poHe from './he.po.json';
13+
import poAshkenazi from './ashkenazi.po.json';
1314

1415
DailyLearning.addCalendar('dafYomi', function(hd) {
1516
const abs = hd.abs();
@@ -87,7 +88,12 @@ DailyLearning.addCalendar('shemiratHaLashon', function(hd) {
8788
return new ShemiratHaLashonEvent(hd, reading);
8889
});
8990

90-
Locale.addTranslations('he', po_he);
91-
Locale.addTranslations('h', po_he);
92-
Locale.addTranslations('ashkenazi', po_ashkenazi);
93-
Locale.addTranslations('a', po_ashkenazi);
91+
DailyLearning.addCalendar('psalms', function(hd) {
92+
const reading = dailyPsalms(hd);
93+
return new PsalmsEvent(hd, reading);
94+
});
95+
96+
Locale.addTranslations('he', poHe);
97+
Locale.addTranslations('h', poHe);
98+
Locale.addTranslations('ashkenazi', poAshkenazi);
99+
Locale.addTranslations('a', poAshkenazi);

src/register.spec.js

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import test from 'ava';
2+
import './register';
3+
import {DailyLearning, HDate} from '@hebcal/core';
4+
5+
test('lookup', (t) => {
6+
const hd = new HDate(17, 'Sivan', 5783);
7+
const ev = DailyLearning.lookup('psalms', hd);
8+
t.is(typeof ev, 'object');
9+
t.is(ev.getDesc(), 'Psalms 83-87');
10+
});

src/yerushalmi.spec.js

+8-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,13 @@
11
import test from 'ava';
22
import {yerushalmiYomi, YerushalmiYomiEvent, vilna, schottenstein} from './yerushalmi';
3-
import {HDate, greg} from '@hebcal/core';
3+
import {HDate, greg, Locale} from '@hebcal/core';
4+
import poAshkenazi from './ashkenazi.po.json';
5+
import poHe from './he.po.json';
6+
7+
Locale.addTranslations('ashkenazi', poAshkenazi);
8+
Locale.addTranslations('a', poAshkenazi);
9+
Locale.addTranslations('he', poHe);
10+
Locale.addTranslations('h', poHe);
411

512
test('yerushalmiYomi-small', (t) => {
613
const toTest = [

types.d.ts

+13
Original file line numberDiff line numberDiff line change
@@ -169,4 +169,17 @@ declare module '@hebcal/learning' {
169169
url(): string;
170170
getCategories(): string[];
171171
}
172+
173+
/**
174+
* Calculates Daily Psalms (Tehillim) for 30-day cycle.
175+
* @param date - Hebrew or Gregorian date
176+
*/
177+
export function dailyPsalms(date: Date | HDate | number): any;
178+
179+
export class PsalmsEvent extends Event {
180+
constructor(date: HDate, reading: any);
181+
render(locale?: string): string;
182+
url(): string;
183+
getCategories(): string[];
184+
}
172185
}

0 commit comments

Comments
 (0)