bible270 1.2.0 → 1.3.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +2 -0
- data/README.md +8 -4
- data/app/helpers/bible270/plan_helper.rb +7 -5
- data/app/models/bible270/reader.rb +3 -2
- data/app/views/bible270/shared/_passage_source.html.erb +7 -3
- data/app/views/bible270/shared/_styles.html.erb +3 -3
- data/db/migrate/20260101000019_change_passage_source_default_to_bible_com.rb +8 -0
- data/lib/bible270/migration_reconciler.rb +9 -0
- data/lib/bible270/translations.rb +72 -19
- data/lib/bible270/version.rb +1 -1
- metadata +2 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 90443d781de608736a3f9fdb35b68b9a85d24d2b2b4f56c3980f54975d239949
|
|
4
|
+
data.tar.gz: cb3dede7983920cf33aaf31b4d6070ec142874063702071512ad60aa387d8899
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: '02703879de6569e5f254de78bd32e4b9c911ca4daef9ca3bc4942ad1816baec285582f10bb1b4d9080d97dfd7588d9c343234cf0a5f2596f82fdfe758113f5a6'
|
|
7
|
+
data.tar.gz: 8e219a377d05acbe62ccea4bc39cf25a1b902bf98cc42495b82c53dbc9282104c14fb3abc55eed09ea910a84cd0e9b05c5063d8836b2eac3798f504fe914653d
|
data/CHANGELOG.md
CHANGED
|
@@ -8,6 +8,8 @@ All notable changes to bible270. Format follows [Keep a Changelog](https://keepa
|
|
|
8
8
|
|
|
9
9
|
- let readers choose reflection emails for every new reflection and reply, only replies to their reflections and mentions of them, or none; administrators can manage the same setting, pending migrations are explained instead of silently hiding it, and existing preferences retain their previous behavior
|
|
10
10
|
- suggest up to five unambiguous reader handles only while a signed-in writer types `@`, with keyboard and touch selection and no change to server-authoritative mention resolution
|
|
11
|
+
- add Bible.com as the first-listed and default reader/admin Scripture source for every offered translation, using chapter links and WLC Hebrew or THGNT Greek when `HEB/GRK` is selected; existing reader choices are preserved
|
|
12
|
+
- add `ALLGRK — LXX OT and Greek NT` immediately after `HEB/GRK`, using Blue Letter Bible's mGNT/LXX routing or Bible.com's GRCBRENT Old Testament and THGNT New Testament
|
|
11
13
|
|
|
12
14
|
### Fixed
|
|
13
15
|
|
data/README.md
CHANGED
|
@@ -462,10 +462,14 @@ config.favicon = false # none; the host's favicon applies
|
|
|
462
462
|
It's emitted by the engine's layout, so if you point `config.layout` at your own layout, add
|
|
463
463
|
`<%= b270_favicon_tag %>` to its `<head>`.
|
|
464
464
|
|
|
465
|
-
References link to Bible
|
|
466
|
-
their profile, and an admin can set the same source for any reader.
|
|
467
|
-
Blue Letter Bible
|
|
468
|
-
|
|
465
|
+
References link to Bible.com by default. Readers choose Bible.com, Bible Gateway, or Blue Letter Bible
|
|
466
|
+
from their profile, and an admin can set the same source for any reader. With `HEB/GRK`,
|
|
467
|
+
Bible Gateway is unavailable: Blue Letter Bible uses WLC for Old Testament, Psalms, and Proverbs and
|
|
468
|
+
mGNT for New Testament, while Bible.com uses WLC and THGNT respectively. The `ALLGRK — LXX OT and
|
|
469
|
+
Greek NT` option also excludes Bible Gateway: Blue Letter Bible uses its mGNT/LXX route for every
|
|
470
|
+
track, while Bible.com uses GRCBRENT for the Old Testament and THGNT for the New Testament. Bible.com
|
|
471
|
+
links open the whole chapter rather than its individual-verse introduction page. Scripture links share one
|
|
472
|
+
dedicated browser tab so moving among the day's passages does not
|
|
469
473
|
leave a trail of open tabs; Ctrl-click, Cmd-click, middle-click, and the browser's context menu still
|
|
470
474
|
open additional tabs when a reader wants to compare passages.
|
|
471
475
|
|
|
@@ -115,7 +115,9 @@ module Bible270
|
|
|
115
115
|
return '#' if reference.blank?
|
|
116
116
|
|
|
117
117
|
selected_version = version || b270_bible_version
|
|
118
|
-
|
|
118
|
+
source = current_reader&.passage_source.presence || Reader::DEFAULT_PASSAGE_SOURCE
|
|
119
|
+
return Translations.passage_url(reference, selected_version, bible_com: true) if source == 'bible_com'
|
|
120
|
+
if source == 'blue_letter_bible' || Translations.original_languages?(selected_version)
|
|
119
121
|
return Translations.passage_url(reference, selected_version, blue_letter: true)
|
|
120
122
|
end
|
|
121
123
|
|
|
@@ -125,8 +127,8 @@ module Bible270
|
|
|
125
127
|
# The named target and noopener are the secure no-JavaScript fallback.
|
|
126
128
|
# Interaction UI retains one opener-backed tab handle on desktop. iOS Safari
|
|
127
129
|
# cannot foreground a reused background tab, so it closes and replaces that
|
|
128
|
-
# script-opened tab on each click. The
|
|
129
|
-
#
|
|
130
|
+
# script-opened tab on each click. The three fixed providers are trusted for
|
|
131
|
+
# this enhanced path.
|
|
130
132
|
def b270_passage_link(reference, **options)
|
|
131
133
|
data = options.fetch(:data, {}).merge(b270_passage_link: true)
|
|
132
134
|
options.merge!(data: data, target: PASSAGE_LINK_TARGET, rel: 'noopener')
|
|
@@ -138,8 +140,8 @@ module Bible270
|
|
|
138
140
|
# used for each track rather than repeating the combined preference code.
|
|
139
141
|
def b270_version_tag(version = nil, track: nil)
|
|
140
142
|
label = version || b270_bible_version
|
|
141
|
-
if label
|
|
142
|
-
label = track.to_s == 'nt' ? 'Greek' : 'Hebrew'
|
|
143
|
+
if Translations.original_languages?(label) && track
|
|
144
|
+
label = label == Translations::ALL_GREEK || track.to_s == 'nt' ? 'Greek' : 'Hebrew'
|
|
143
145
|
end
|
|
144
146
|
|
|
145
147
|
content_tag :span, "(#{label})", class: 'b270-version'
|
|
@@ -25,8 +25,8 @@ module Bible270
|
|
|
25
25
|
# transaction rolls back.
|
|
26
26
|
after_create_commit :notify_of_registration
|
|
27
27
|
|
|
28
|
-
PASSAGE_SOURCES = %w[bible_gateway blue_letter_bible].freeze
|
|
29
|
-
DEFAULT_PASSAGE_SOURCE = '
|
|
28
|
+
PASSAGE_SOURCES = %w[bible_com bible_gateway blue_letter_bible].freeze
|
|
29
|
+
DEFAULT_PASSAGE_SOURCE = 'bible_com'
|
|
30
30
|
DAILY_REMINDER_TIME_FORMAT = %r{\A(?:[01]\d|2[0-3]):[0-5]\d\z}
|
|
31
31
|
DAILY_REMINDER_MINUTES = %w[00 15 30 45].freeze
|
|
32
32
|
DAILY_REMINDER_COLUMNS = %w[daily_reminders daily_reminder_time last_daily_reminder_sent_on].freeze
|
|
@@ -236,6 +236,7 @@ module Bible270
|
|
|
236
236
|
|
|
237
237
|
def bible_gateway? = passage_source == 'bible_gateway'
|
|
238
238
|
def blue_letter_bible? = passage_source == 'blue_letter_bible'
|
|
239
|
+
def bible_com? = passage_source == 'bible_com'
|
|
239
240
|
|
|
240
241
|
# Readers are listed by first name, matching how they are shown — the display
|
|
241
242
|
# name is "First Last", so sorting on it needs only case folding. Surname
|
|
@@ -1,13 +1,17 @@
|
|
|
1
|
-
<% original_languages = reader.effective_bible_version
|
|
1
|
+
<% original_languages = Bible270::Translations.original_languages?(reader.effective_bible_version) %>
|
|
2
2
|
<div class="b270-source-choices" role="radiogroup" aria-label="Reading link source">
|
|
3
|
+
<label class="b270-source-choice">
|
|
4
|
+
<%= radio_button_tag :passage_source, "bible_com", reader.bible_com? %>
|
|
5
|
+
<span>Bible.com</span>
|
|
6
|
+
</label>
|
|
3
7
|
<label class="b270-source-choice <%= 'disabled' if original_languages %>">
|
|
4
8
|
<%= radio_button_tag :passage_source, "bible_gateway",
|
|
5
9
|
!original_languages && reader.bible_gateway?, disabled: original_languages %>
|
|
6
10
|
<span>Bible Gateway</span>
|
|
7
11
|
</label>
|
|
8
|
-
<label class="b270-source-choice
|
|
12
|
+
<label class="b270-source-choice">
|
|
9
13
|
<%= radio_button_tag :passage_source, "blue_letter_bible",
|
|
10
|
-
|
|
14
|
+
reader.blue_letter_bible? || (original_languages && !reader.bible_com?) %>
|
|
11
15
|
<span>Blue Letter Bible</span>
|
|
12
16
|
</label>
|
|
13
17
|
</div>
|
|
@@ -186,9 +186,9 @@
|
|
|
186
186
|
.b270-parts-meta{margin-top:10px;font-size:12.5px;color:var(--faint)}
|
|
187
187
|
.b270-version{font-size:11.5px;color:var(--faint);font-weight:400;letter-spacing:.02em;white-space:nowrap}
|
|
188
188
|
.b270-select{font:inherit;font-size:14px;padding:10px 30px 10px 12px;border:1px solid var(--line);border-radius:9px;background:#fff;color:var(--ink);width:100%;max-width:100%;text-overflow:ellipsis}
|
|
189
|
-
.b270-source-choices{display:flex;align-items:center;gap:
|
|
190
|
-
.b270-source-choice{display:inline-flex;align-items:center;gap:
|
|
191
|
-
.b270-source-choice input{appearance:none;width:
|
|
189
|
+
.b270-source-choices{display:flex;align-items:center;justify-content:space-between;gap:4px;flex-wrap:nowrap;width:100%;margin:8px 0 2px;color:var(--muted);font-size:clamp(10.5px,3.4vw,12.5px)}
|
|
190
|
+
.b270-source-choice{display:inline-flex;align-items:center;gap:4px;cursor:pointer;white-space:nowrap}
|
|
191
|
+
.b270-source-choice input{appearance:none;width:14px;height:14px;margin:0;border:1px solid var(--line);border-radius:3px;background:#fff;display:grid;place-content:center;cursor:pointer;flex:none}
|
|
192
192
|
.b270-source-choice input::before{content:"";width:9px;height:9px;transform:scale(0);transition:transform .1s;clip-path:polygon(14% 44%,0 59%,38% 100%,100% 18%,82% 0,37% 65%);background:var(--paper)}
|
|
193
193
|
.b270-source-choice input:checked{background:var(--gold);border-color:var(--gold)}
|
|
194
194
|
.b270-source-choice input:checked::before{transform:scale(1)}
|
|
@@ -28,6 +28,7 @@ module Bible270
|
|
|
28
28
|
'AddDailyRemindersToBible270Readers' => :check_daily_reminders,
|
|
29
29
|
'AddReflectionsSeenAtToBible270Readers' => :check_reflections_seen_at,
|
|
30
30
|
'AddAllCommentNoticesToBible270Readers' => :check_all_comment_notices,
|
|
31
|
+
'ChangePassageSourceDefaultToBibleCom' => :check_passage_source_default,
|
|
31
32
|
'CreateActiveStorageTables' => :check_active_storage
|
|
32
33
|
}.freeze
|
|
33
34
|
|
|
@@ -195,6 +196,14 @@ module Bible270
|
|
|
195
196
|
table_missing(:bible270_readers, columns: %i[notify_on_all_comments])
|
|
196
197
|
end
|
|
197
198
|
|
|
199
|
+
def check_passage_source_default
|
|
200
|
+
missing = table_missing(:bible270_readers, columns: %i[passage_source])
|
|
201
|
+
return missing if missing.any?
|
|
202
|
+
|
|
203
|
+
column = connection.columns(:bible270_readers).find { |candidate| candidate.name == 'passage_source' }
|
|
204
|
+
column&.default == 'bible_com' ? [] : ['column bible270_readers.passage_source default bible_com']
|
|
205
|
+
end
|
|
206
|
+
|
|
198
207
|
# The Bible270 installer can install Active Storage for reader avatars. A
|
|
199
208
|
# copied database can therefore have the same timestamp mismatch for Rails'
|
|
200
209
|
# generated Active Storage migration as it has for the engine migrations.
|
|
@@ -20,17 +20,36 @@ module Bible270
|
|
|
20
20
|
'ESV' => { label: 'English Standard Version', short: 'English Standard Version', gateway: 'ESV', blue_letter: 'esv' },
|
|
21
21
|
'KJV' => { label: 'King James Version', short: 'King James Version', gateway: 'KJV', blue_letter: 'kjv' },
|
|
22
22
|
'YLT' => { label: 'Young\'s Literal Translation', short: 'Young\'s Literal Translation', gateway: 'YLT', blue_letter: 'ylt' },
|
|
23
|
-
'HEB/GRK' => { label: 'Hebrew and Greek', short: 'Hebrew and Greek', gateway: 'WLC', blue_letter: 'wlc/mgnt' }
|
|
23
|
+
'HEB/GRK' => { label: 'Hebrew and Greek', short: 'Hebrew and Greek', gateway: 'WLC', blue_letter: 'wlc/mgnt' },
|
|
24
|
+
'ALLGRK' => { label: 'LXX Old Testament and Greek New Testament', short: 'LXX OT and Greek NT', gateway: 'LXX', blue_letter: 'mgnt' }
|
|
24
25
|
}.freeze
|
|
25
26
|
|
|
26
27
|
DEFAULT = 'NKJV'
|
|
27
28
|
ORIGINAL_LANGUAGES = 'HEB/GRK'
|
|
29
|
+
ALL_GREEK = 'ALLGRK'
|
|
30
|
+
ORIGINAL_LANGUAGE_CODES = [ORIGINAL_LANGUAGES, ALL_GREEK].freeze
|
|
28
31
|
BLUE_LETTER_BASE_URL = 'https://www.blueletterbible.org'
|
|
32
|
+
BIBLE_COM_BASE_URL = 'https://www.bible.com/bible'
|
|
33
|
+
BIBLE_COM_VERSIONS = {
|
|
34
|
+
'NKJV' => [114, 'NKJV'], 'NASB95' => [100, 'NASB1995'], 'LSB' => [3345, 'LSB'],
|
|
35
|
+
'ESV' => [59, 'ESV'], 'KJV' => [1, 'KJV'], 'YLT' => [821, 'YLT98']
|
|
36
|
+
}.freeze
|
|
37
|
+
BIBLE_COM_ORIGINAL_LANGUAGES = {
|
|
38
|
+
old_testament: [3585, 'WLC'], new_testament: [2270, 'THGNT']
|
|
39
|
+
}.freeze
|
|
40
|
+
BIBLE_COM_ALL_GREEK = {
|
|
41
|
+
old_testament: [2503, 'GRCBRENT'], new_testament: [2270, 'THGNT']
|
|
42
|
+
}.freeze
|
|
29
43
|
BLUE_LETTER_BOOK_CODES = %w[
|
|
30
44
|
gen exo lev num deu jos jdg rut 1sa 2sa 1ki 2ki 1ch 2ch ezr neh est job psa pro ecc sng
|
|
31
45
|
isa jer lam eze dan hos joe amo oba jon mic nah hab zep hag zec mal mat mar luk joh act rom
|
|
32
46
|
1co 2co gal eph php col 1th 2th 1ti 2ti tit phm heb jas 1pe 2pe 1jo 2jo 3jo jud rev
|
|
33
47
|
].freeze
|
|
48
|
+
BIBLE_COM_BOOK_CODES = %w[
|
|
49
|
+
GEN EXO LEV NUM DEU JOS JDG RUT 1SA 2SA 1KI 2KI 1CH 2CH EZR NEH EST JOB PSA PRO ECC SNG
|
|
50
|
+
ISA JER LAM EZK DAN HOS JOL AMO OBA JON MIC NAM HAB ZEP HAG ZEC MAL MAT MRK LUK JHN ACT ROM
|
|
51
|
+
1CO 2CO GAL EPH PHP COL 1TH 2TH 1TI 2TI TIT PHM HEB JAS 1PE 2PE 1JN 2JN 3JN JUD REV
|
|
52
|
+
].freeze
|
|
34
53
|
|
|
35
54
|
module_function
|
|
36
55
|
|
|
@@ -50,6 +69,10 @@ module Bible270
|
|
|
50
69
|
code.to_s.strip.upcase
|
|
51
70
|
end
|
|
52
71
|
|
|
72
|
+
def original_languages?(code)
|
|
73
|
+
ORIGINAL_LANGUAGE_CODES.include?(normalize(code))
|
|
74
|
+
end
|
|
75
|
+
|
|
53
76
|
def label(code)
|
|
54
77
|
VERSIONS.dig(normalize(code), :label)
|
|
55
78
|
end
|
|
@@ -69,10 +92,9 @@ module Bible270
|
|
|
69
92
|
codes.map { |code| ["#{code} — #{short_label(code)}", code] }
|
|
70
93
|
end
|
|
71
94
|
|
|
72
|
-
def passage_url(reference, version, blue_letter: false)
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
end
|
|
95
|
+
def passage_url(reference, version, blue_letter: false, bible_com: false)
|
|
96
|
+
return bible_com_url(reference, version) if bible_com
|
|
97
|
+
return blue_letter_url(reference, version) if blue_letter || original_languages?(version)
|
|
76
98
|
|
|
77
99
|
search = URI.encode_www_form_component(reference)
|
|
78
100
|
gateway = URI.encode_www_form_component(gateway_code(version))
|
|
@@ -85,25 +107,17 @@ module Bible270
|
|
|
85
107
|
# query URL, so link to the first chapter/verse and let its chapter navigation
|
|
86
108
|
# carry the reader onward.
|
|
87
109
|
def blue_letter_url(reference, version = ORIGINAL_LANGUAGES)
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
return "#{BLUE_LETTER_BASE_URL}/" unless book_index
|
|
91
|
-
|
|
92
|
-
book = books[book_index]
|
|
93
|
-
location = reference.to_s.delete_prefix("#{book} ")
|
|
94
|
-
match = location.match(%r{\A(\d+)(?::(\d+))?})
|
|
95
|
-
return "#{BLUE_LETTER_BASE_URL}/" unless match
|
|
96
|
-
|
|
97
|
-
chapter = match[1].to_i
|
|
98
|
-
verse = match[2]&.to_i || 1
|
|
99
|
-
chapter_verses = Versification::VERSES[book]
|
|
100
|
-
return "#{BLUE_LETTER_BASE_URL}/" unless chapter.between?(1, chapter_verses.length)
|
|
101
|
-
return "#{BLUE_LETTER_BASE_URL}/" unless verse.between?(1, chapter_verses[chapter - 1])
|
|
110
|
+
start = reference_start(reference)
|
|
111
|
+
return "#{BLUE_LETTER_BASE_URL}/" unless start
|
|
102
112
|
|
|
113
|
+
book_index, chapter, verse = start
|
|
114
|
+
books = Versification::VERSES.keys
|
|
103
115
|
canonical_chapter = books.first(book_index).sum { |prior| Versification::VERSES[prior].length } + chapter
|
|
104
116
|
new_testament = book_index >= books.index('Matthew')
|
|
105
117
|
reader = if normalize(version) == ORIGINAL_LANGUAGES
|
|
106
118
|
new_testament ? 'mgnt' : 'wlc'
|
|
119
|
+
elsif normalize(version) == ALL_GREEK
|
|
120
|
+
'mgnt'
|
|
107
121
|
else
|
|
108
122
|
VERSIONS.dig(normalize(version), :blue_letter)
|
|
109
123
|
end
|
|
@@ -114,6 +128,45 @@ module Bible270
|
|
|
114
128
|
"#{chapter}/#{verse}/s_#{anchor}"
|
|
115
129
|
end
|
|
116
130
|
|
|
131
|
+
def bible_com_url(reference, version)
|
|
132
|
+
start = reference_start(reference)
|
|
133
|
+
return BIBLE_COM_BASE_URL unless start
|
|
134
|
+
|
|
135
|
+
book_index, chapter, = start
|
|
136
|
+
version_id, version_code = bible_com_version(version, book_index)
|
|
137
|
+
return BIBLE_COM_BASE_URL unless version_id && version_code
|
|
138
|
+
|
|
139
|
+
"#{BIBLE_COM_BASE_URL}/#{version_id}/#{BIBLE_COM_BOOK_CODES[book_index]}." \
|
|
140
|
+
"#{chapter}.#{version_code}"
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
def bible_com_version(version, book_index)
|
|
144
|
+
normalized = normalize(version)
|
|
145
|
+
testament = book_index >= Versification::VERSES.keys.index('Matthew') ? :new_testament : :old_testament
|
|
146
|
+
return BIBLE_COM_ORIGINAL_LANGUAGES[testament] if normalized == ORIGINAL_LANGUAGES
|
|
147
|
+
return BIBLE_COM_ALL_GREEK[testament] if normalized == ALL_GREEK
|
|
148
|
+
|
|
149
|
+
BIBLE_COM_VERSIONS[normalized]
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
def reference_start(reference)
|
|
153
|
+
books = Versification::VERSES.keys
|
|
154
|
+
book_index = books.index { |book| reference.to_s.start_with?("#{book} ") }
|
|
155
|
+
return unless book_index
|
|
156
|
+
|
|
157
|
+
book = books[book_index]
|
|
158
|
+
match = reference.to_s.delete_prefix("#{book} ").match(%r{\A(\d+)(?::(\d+))?})
|
|
159
|
+
return unless match
|
|
160
|
+
|
|
161
|
+
chapter = match[1].to_i
|
|
162
|
+
verse = match[2]&.to_i || 1
|
|
163
|
+
chapter_verses = Versification::VERSES[book]
|
|
164
|
+
return unless chapter.between?(1, chapter_verses.length)
|
|
165
|
+
return unless verse.between?(1, chapter_verses[chapter - 1])
|
|
166
|
+
|
|
167
|
+
[book_index, chapter, verse]
|
|
168
|
+
end
|
|
169
|
+
|
|
117
170
|
# Falls back to the configured default, then to ESV, so a link is never built
|
|
118
171
|
# with a blank version.
|
|
119
172
|
def resolve(code)
|
data/lib/bible270/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: bible270
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.
|
|
4
|
+
version: 1.3.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Andrew vonderLuft
|
|
@@ -173,6 +173,7 @@ files:
|
|
|
173
173
|
- db/migrate/20260101000016_add_daily_reminders_to_bible270_readers.rb
|
|
174
174
|
- db/migrate/20260101000017_add_reflections_seen_at_to_bible270_readers.rb
|
|
175
175
|
- db/migrate/20260101000018_add_all_comment_notices_to_bible270_readers.rb
|
|
176
|
+
- db/migrate/20260101000019_change_passage_source_default_to_bible_com.rb
|
|
176
177
|
- lib/bible270.rb
|
|
177
178
|
- lib/bible270/avatars.rb
|
|
178
179
|
- lib/bible270/configuration.rb
|