bible270 0.6.2 → 0.9.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.
@@ -27,6 +27,34 @@ module Bible270
27
27
  # Leave nil to use the built-in session-based sign-in (OmniAuth).
28
28
  attr_accessor :current_reader_resolver
29
29
 
30
+ # Where the engine is mounted in the host application. Set this once, in
31
+ # config/initializers/bible270.rb, and use it everywhere the path is needed:
32
+ #
33
+ # # config/routes.rb
34
+ # mount Bible270::Engine, at: Bible270.config.mount_at
35
+ #
36
+ # # config/initializers/omniauth.rb
37
+ # path_prefix Bible270.config.auth_path_prefix
38
+ #
39
+ # Accepts "daily-bread" or "/daily-bread"; stored with a leading slash and
40
+ # no trailing one.
41
+ attr_reader :mount_at
42
+
43
+ def mount_at=(value)
44
+ path = value.to_s.strip
45
+ path = "/#{path}" unless path.start_with?("/")
46
+ path = path.chomp("/")
47
+ @mount_at = path.empty? ? "/" : path
48
+ end
49
+
50
+ # The prefix OmniAuth's middleware should serve its routes under. Derived
51
+ # from mount_at unless omniauth_path_prefix is set explicitly.
52
+ def auth_path_prefix
53
+ return omniauth_path_prefix if omniauth_path_prefix
54
+
55
+ mount_at == "/" ? "/auth" : "#{mount_at}/auth"
56
+ end
57
+
30
58
  # Where to send the reader after a successful sign-in / sign-out.
31
59
  attr_accessor :after_sign_in_path
32
60
  attr_accessor :after_sign_out_path
@@ -146,6 +174,7 @@ module Bible270
146
174
  @app_name = "Daily Bread"
147
175
  @tagline = "A 270-day journey through Scripture"
148
176
  @require_sign_in_to_participate = true
177
+ self.mount_at = "/daily-bread"
149
178
  @start_date = nil
150
179
  @allow_reader_start_date = true
151
180
  self.omniauth_providers = [:github]
@@ -8,14 +8,14 @@ module Bible270
8
8
  g.orm :active_record
9
9
  end
10
10
 
11
- # Make the engine's migrations available to the host via
11
+ # NOTE: we deliberately do NOT append the engine's db/migrate to the host
12
+ # app's migration paths. Rails already gives mountable engines the task
13
+ #
12
14
  # bin/rails bible270:install:migrations
13
- initializer "bible270.append_migrations" do |app|
14
- unless app.root.to_s.match?(root.to_s)
15
- config.paths["db/migrate"].expanded.each do |path|
16
- app.config.paths["db/migrate"] << path
17
- end
18
- end
19
- end
15
+ #
16
+ # which copies the migrations into the host's db/migrate, where the host
17
+ # owns them and they appear in schema.rb normally. Doing both would define
18
+ # each migration class twice and raise
19
+ # ActiveRecord::DuplicateMigrationNameError.
20
20
  end
21
21
  end
data/lib/bible270/plan.rb CHANGED
@@ -10,15 +10,16 @@ module Bible270
10
10
  # proxy for how much text there is), not by chapter count — so a day landing on
11
11
  # Psalm 119 (176 verses) is not treated as equal to a day on Psalm 117 (2 verses).
12
12
  #
13
- # * Old Testament – read once, cover to cover; WHOLE chapters grouped so each
14
- # day is ~equal in verses (~73/day)
15
- # * New Testament – read through TWICE (~2 chapters/day, every day)
16
- # * Psalms/Proverbs – a WHOLE-CHAPTER daily companion. With only 181 chapters
17
- # over 270 days it cycles ~1.9x. Chapters stay intact; very
18
- # short ones merge with a neighbour, and the one excessively
19
- # long chapter (Psalm 119) is divided into two readings.
13
+ # * Old Testament – read once (excluding Psalms and Proverbs); WHOLE chapters
14
+ # grouped so each day is ~equal in verses (~73/day)
15
+ # * New Testament – read once, one reading every day; the 10 longest chapters
16
+ # (Luke 1 and friends) are divided in two so 260 chapters fill 270 days
17
+ # * Psalms/Proverbs – Psalms once and Proverbs TWICE, interleaved in one track.
18
+ # Longer psalms are divided so the two fill exactly 270 days;
19
+ # Psalm 119 is pinned to 11 sections of 16 verses.
20
20
  #
21
- # Genesis→Malachi finishes on day 270, as does the second pass through the NT.
21
+ # Genesis→Malachi, Revelation 22, Psalm 150 and the second Proverbs 31 all land
22
+ # in the closing days.
22
23
  module Plan
23
24
  DAYS = 270
24
25
 
@@ -118,6 +119,65 @@ module Bible270
118
119
  groups
119
120
  end
120
121
 
122
+ # ---- dividing chapters to fill a fixed number of days ------------------
123
+ #
124
+ # Whole chapters are preferred; when a track has fewer chapters than days to
125
+ # fill, the longest chapters are divided until the counts match. Each extra
126
+ # division goes to whichever chapter currently carries the heaviest reading,
127
+ # so the longest are always split first.
128
+
129
+ # weights: verses per chapter, in order. pinned: {index => fixed part count}.
130
+ # Returns the number of readings each chapter becomes.
131
+ def divide_to_fill(weights, target, pinned = {})
132
+ parts = Array.new(weights.size, 1)
133
+ pinned.each { |i, n| parts[i] = n }
134
+ candidates = (0...weights.size).reject { |i| pinned.key?(i) }
135
+
136
+ while parts.sum < target && candidates.any?
137
+ heaviest = candidates.max_by { |i| weights[i].fdiv(parts[i]) }
138
+ parts[heaviest] += 1
139
+ end
140
+ parts
141
+ end
142
+
143
+ # Turn [book, chapter] pairs plus a part count into readings. A reading is
144
+ # [book, chapter] when whole, or [book, chapter, from, to] when it's a slice.
145
+ def expand_readings(chapters, parts)
146
+ chapters.each_with_index.flat_map do |(book, chapter), idx|
147
+ n = parts[idx]
148
+ next [[book, chapter]] if n == 1
149
+
150
+ total = verses_for(book, chapter)
151
+ base = total / n
152
+ extra = total % n
153
+ v = 1
154
+ n.times.map do |k|
155
+ size = base + (k < extra ? 1 : 0)
156
+ reading = [book, chapter, v, v + size - 1]
157
+ v += size
158
+ reading
159
+ end
160
+ end
161
+ end
162
+
163
+ def segment_length(segment)
164
+ segment.size == 2 ? verses_for(segment[0], segment[1]) : (segment[3] - segment[2] + 1)
165
+ end
166
+
167
+ # "Luke 2" for a whole chapter, "Luke 1:1\u201340" for part of one.
168
+ def format_segment(segment)
169
+ book, chapter, from, to = segment
170
+ return "#{book} #{chapter}" if from.nil?
171
+
172
+ from == to ? "#{book} #{chapter}:#{from}" : "#{book} #{chapter}:#{from}\u2013#{to}"
173
+ end
174
+
175
+ # Chapters that ended up divided, as {[book, chapter] => reading count}.
176
+ def divided(chapters, parts)
177
+ chapters.each_with_index.select { |_, i| parts[i] > 1 }
178
+ .to_h { |ch, i| [ch, parts[i]] }
179
+ end
180
+
121
181
  # ---- Old Testament ----------------------------------------------------
122
182
 
123
183
  def ot_groups
@@ -136,140 +196,120 @@ module Bible270
136
196
  @ot_verse_loads ||= ot_groups.map { |g| g.sum { |b, c| verses_for(b, c) } }
137
197
  end
138
198
 
139
- # ---- New Testament (read through TWICE) -------------------------------
199
+ # ---- New Testament (read once, one reading every day) ------------------
140
200
  #
141
- # 260 chapters x 2 passes = 520 chapter-readings over 270 days, so ~2 chapters
142
- # a day and no rest days. Each pass gets its own half of the plan (135 days),
143
- # so Revelation 22 lands on day 135 and again on day 270. Within a pass, whole
144
- # chapters are grouped so each day is ~equal in verses.
201
+ # 260 chapters over 270 days, so the 10 longest chapters are each divided in
202
+ # two — Luke 1, Matthew 26 and 27, Mark 14, Luke 9, 12 and 22, John 6 and 8,
203
+ # and Acts 7. That gives exactly one reading a day with no days off, and
204
+ # brings the longest reading down from Luke 1's 80 verses to 58.
145
205
 
146
- NT_PASSES = 2
206
+ NT_PASSES = 1
147
207
 
148
- def nt_days_per_pass = DAYS / NT_PASSES
208
+ def nt_chapters = @nt_chapters ||= flatten(NT)
149
209
 
150
- def nt_chapters
151
- @nt_chapters ||= flatten(NT) * NT_PASSES
210
+ def nt_parts
211
+ @nt_parts ||= divide_to_fill(nt_chapters.map { |b, c| verses_for(b, c) }, DAYS)
152
212
  end
153
213
 
154
- def nt_groups
155
- @nt_groups ||= begin
156
- chapters = flatten(NT)
157
- weights = chapters.map { |b, c| verses_for(b, c) }
158
- one_pass = balance_by_weight(chapters, weights, nt_days_per_pass)
159
- one_pass * NT_PASSES
160
- end
214
+ def nt_readings
215
+ @nt_readings ||= expand_readings(nt_chapters, nt_parts)
161
216
  end
162
217
 
163
218
  def nt_plan
164
- @nt_plan ||= nt_groups.map { |g| format_reference(g) }
219
+ @nt_plan ||= nt_readings.map { |seg| format_segment(seg) }
165
220
  end
166
221
 
167
222
  def nt_verse_loads
168
- @nt_verse_loads ||= nt_groups.map { |g| g.sum { |b, c| verses_for(b, c) } }
223
+ @nt_verse_loads ||= nt_readings.map { |seg| segment_length(seg) }
169
224
  end
170
225
 
171
- # Days on which the NT track has content (now every day).
172
- def nt_content_days
173
- @nt_content_days ||= nt_plan.count { |r| !r.nil? }
174
- end
226
+ # Every day now carries a New Testament reading.
227
+ def nt_content_days = @nt_content_days ||= nt_plan.count { |r| !r.nil? }
175
228
 
176
- # 1-indexed day on which the second pass through the NT begins.
177
- def nt_second_pass_start_day = nt_days_per_pass + 1
229
+ def nt_rest_days = []
178
230
 
179
- # ---- Psalms & Proverbs (whole-chapter companion, cycles ~1.9x) --------
231
+ def divided_nt_chapters = @divided_nt_chapters ||= divided(nt_chapters, nt_parts)
232
+
233
+ # ---- Psalms & Proverbs -------------------------------------------------
180
234
  #
181
- # Chapters are kept WHOLE. Because there are only 181 Psalms/Proverbs
182
- # chapters but 270 days, the track reads through roughly twice, cycling.
183
- # Two adjustments keep daily portions roughly even without chopping text:
184
- # * very short chapters merge with a neighbour (no trivial 2-verse days)
185
- # * only excessively long chapters (> PP_LONG_CHAPTER verses) are split
186
- # into balanced parts — in practice just Psalms 78, 89, and 119.
187
-
188
- PP_MIN_DAY = 12 # keep merging until a portion reaches at least this many verses
189
- PP_DAY_TARGET = 22 # soft cap: stop merging once a portion would exceed this
190
- PP_LONG_CHAPTER = 100 # only an excessively long chapter is split; in the whole
191
- # Psalter+Proverbs that is Psalm 119 (176v) alone, since
192
- # the next longest chapter is Psalm 78 at 72 verses
193
- PP_SPLIT_PARTS = 2 # such a chapter is divided into this many readings
194
-
195
- # The base cycle of readings (whole chapters, short ones merged, long ones
196
- # split). Each portion is an array of segments; a segment is either
197
- # [book, chapter] (whole) or [book, chapter, from, to] (part of a chapter).
198
- def pp_base_portions
199
- @pp_base_portions ||= begin
200
- units = flatten(PP).map { |b, c| [b, c, verses_for(b, c)] }
201
- portions = []
202
- buf = []
203
- buflen = 0
204
- units.each do |book, ch, len|
205
- if len > PP_LONG_CHAPTER
206
- unless buf.empty?
207
- portions << buf
208
- buf = []
209
- buflen = 0
210
- end
211
- nparts = PP_SPLIT_PARTS
212
- base = len / nparts
213
- extra = len % nparts
214
- v = 1
215
- nparts.times do |i|
216
- size = base + (i < extra ? 1 : 0)
217
- portions << [[book, ch, v, v + size - 1]]
218
- v += size
219
- end
220
- else
221
- if !buf.empty? && buflen >= PP_MIN_DAY && buflen + len > PP_DAY_TARGET
222
- portions << buf
223
- buf = []
224
- buflen = 0
225
- end
226
- buf << [book, ch]
227
- buflen += len
228
- end
229
- end
230
- portions << buf unless buf.empty?
231
- portions
235
+ # Psalms once and Proverbs TWICE across the 270 days, in one daily track.
236
+ #
237
+ # Proverbs supplies 31 x 2 = 62 readings (whole chapters), leaving 208 days
238
+ # for the Psalms. Since there are only 150 psalms, longer ones are divided:
239
+ #
240
+ # * Psalm 119 is pinned to 11 sections of exactly 16 verses (176 = 11 x 16),
241
+ # which matches its 22 eight-verse acrostic stanzas, two per section.
242
+ # * The remaining 48 divisions go to whichever psalm currently carries the
243
+ # heaviest reading, so the longest are split first and no single reading
244
+ # runs long.
245
+ #
246
+ # The 62 Proverbs readings are then spaced evenly through the 270 days, which
247
+ # lands Proverbs 31 on day 135 and again on day 270.
248
+
249
+ PROVERBS_PASSES = 2
250
+ PSALM_119_SECTION_SIZE = 16
251
+
252
+ def proverbs_reading_count = flatten([["Proverbs", 31]]).size * PROVERBS_PASSES
253
+
254
+ def psalm_reading_count = DAYS - proverbs_reading_count
255
+
256
+ def psalm_chapters
257
+ @psalm_chapters ||= (1..Versification.chapter_count("Psalm")).map { |c| ["Psalm", c] }
258
+ end
259
+
260
+ # How many readings each psalm is divided into (index 0 == Psalm 1).
261
+ # Psalm 119 is pinned to 11 sections of PSALM_119_SECTION_SIZE verses.
262
+ def psalm_parts
263
+ @psalm_parts ||= begin
264
+ weights = psalm_chapters.map { |b, c| verses_for(b, c) }
265
+ i119 = 118
266
+ divide_to_fill(weights, psalm_reading_count, i119 => weights[i119] / PSALM_119_SECTION_SIZE)
267
+ end
268
+ end
269
+
270
+ def psalm_readings
271
+ @psalm_readings ||= expand_readings(psalm_chapters, psalm_parts)
272
+ end
273
+
274
+ # Proverbs 1..31, repeated PROVERBS_PASSES times, always whole chapters.
275
+ def proverbs_readings
276
+ @proverbs_readings ||= begin
277
+ chapters = (1..Versification.chapter_count("Proverbs")).map { |c| ["Proverbs", c] }
278
+ chapters * PROVERBS_PASSES
232
279
  end
233
280
  end
234
281
 
235
- def pp_cycle_length = pp_base_portions.size
282
+ # True when the given 1-indexed day is one of the evenly spaced Proverbs days.
283
+ def proverbs_day?(day)
284
+ n = proverbs_reading_count
285
+ (day * n / DAYS) > ((day - 1) * n / DAYS)
286
+ end
287
+
288
+ # One reading per day, Psalms and Proverbs interleaved.
289
+ def pp_readings
290
+ @pp_readings ||= begin
291
+ psalms = psalm_readings.dup
292
+ proverbs = proverbs_readings.dup
293
+ (1..DAYS).map { |day| proverbs_day?(day) ? proverbs.shift : psalms.shift }
294
+ end
295
+ end
236
296
 
237
297
  def pp_plan
238
- @pp_plan ||= (0...DAYS).map { |d| format_pp(pp_base_portions[d % pp_cycle_length]) }
298
+ @pp_plan ||= pp_readings.map { |seg| format_segment(seg) }
239
299
  end
240
300
 
241
301
  def pp_verse_loads
242
- @pp_verse_loads ||= (0...DAYS).map do |d|
243
- pp_base_portions[d % pp_cycle_length].sum do |s|
244
- s.size == 2 ? verses_for(s[0], s[1]) : (s[3] - s[2] + 1)
245
- end
246
- end
302
+ @pp_verse_loads ||= pp_readings.map { |seg| segment_length(seg) }
247
303
  end
248
304
 
249
- # Format a portion, collapsing consecutive whole chapters ("Psalm 24–25")
250
- # and rendering split parts as verse ranges ("Psalm 119:1–22").
251
- def format_pp(portion)
252
- parts = []
253
- i = 0
254
- while i < portion.size
255
- s = portion[i]
256
- if s.size == 2 # whole chapter
257
- book, ch = s
258
- j = i
259
- while j + 1 < portion.size && portion[j + 1].size == 2 &&
260
- portion[j + 1][0] == book && portion[j + 1][1] == portion[j][1] + 1
261
- j += 1
262
- end
263
- last = portion[j][1]
264
- parts << (ch == last ? "#{book} #{ch}" : "#{book} #{ch}\u2013#{last}")
265
- i = j + 1
266
- else # part of a chapter
267
- book, ch, from, to = s
268
- parts << (from == to ? "#{book} #{ch}:#{from}" : "#{book} #{ch}:#{from}\u2013#{to}")
269
- i += 1
270
- end
271
- end
272
- parts.join(", ")
305
+ # 1-indexed days carrying a Proverbs reading.
306
+ def proverbs_days
307
+ @proverbs_days ||= (1..DAYS).select { |d| proverbs_day?(d) }
308
+ end
309
+
310
+ # Psalms that end up divided, as {chapter => number of readings}.
311
+ def divided_psalms
312
+ @divided_psalms ||= divided(psalm_chapters, psalm_parts).to_h { |ch, n| [ch[1], n] }
273
313
  end
274
314
 
275
315
  # ---- public API -------------------------------------------------------
@@ -336,15 +376,20 @@ module Bible270
336
376
 
337
377
  def totals
338
378
  {
339
- ot: flatten(OT).size, # 748 chapters
340
- nt: flatten(NT).size, # 260 chapters per pass
341
- nt_passes: NT_PASSES, # read through twice
342
- nt_chapters_read: nt_chapters.size, # 520 chapter-readings
343
- pp: flatten(PP).size, # 181 chapters
344
- pp_verses: flatten(PP).sum { |b, c| verses_for(b, c) }, # 3376 verses
345
- pp_cycle: pp_cycle_length, # base portions before cycling
379
+ ot: flatten(OT).size, # 748 chapters
380
+ nt: flatten(NT).size, # 260 chapters, read once
381
+ nt_passes: NT_PASSES,
382
+ nt_readings: nt_readings.size, # 270 - one every day
383
+ nt_divided: divided_nt_chapters.size, # 10 long chapters halved
384
+ psalms: Versification.chapter_count("Psalm"), # 150
385
+ psalm_readings: psalm_readings.size, # 208
386
+ proverbs: Versification.chapter_count("Proverbs"), # 31
387
+ proverbs_passes: PROVERBS_PASSES,
388
+ proverbs_readings: proverbs_reading_count, # 62
389
+ pp: flatten(PP).size, # 181 chapters
390
+ pp_verses: flatten(PP).sum { |b, c| verses_for(b, c) },
346
391
  ot_verses: flatten(OT).sum { |b, c| verses_for(b, c) },
347
- nt_verses: nt_chapters.sum { |b, c| verses_for(b, c) },
392
+ nt_verses: flatten(NT).sum { |b, c| verses_for(b, c) },
348
393
  days: DAYS
349
394
  }
350
395
  end
@@ -1,4 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
  module Bible270
3
- VERSION = "0.6.2"
3
+ VERSION = "0.9.0"
4
4
  end
@@ -10,8 +10,8 @@ module Bible270
10
10
  class InstallGenerator < Rails::Generators::Base
11
11
  source_root File.expand_path("templates", __dir__)
12
12
 
13
- class_option :mount_at, type: :string, default: "/reading-plan",
14
- desc: "Path the engine is mounted at"
13
+ class_option :mount_at, type: :string, default: "/daily-bread",
14
+ desc: "Path the engine is mounted at (default /daily-bread)"
15
15
  class_option :providers, type: :string, default: "github",
16
16
  desc: "Comma-separated OmniAuth providers (e.g. github,google_oauth2)"
17
17
 
@@ -21,7 +21,8 @@ module Bible270
21
21
  end
22
22
 
23
23
  def add_route
24
- route %(mount Bible270::Engine, at: "#{mount_at}")
24
+ # Driven by config.mount_at so the path is defined in exactly one place.
25
+ route "mount Bible270::Engine, at: Bible270.config.mount_at"
25
26
  end
26
27
 
27
28
  def show_next_steps
@@ -58,9 +59,6 @@ module Bible270
58
59
  provider_list.map { |p| ":#{p}" }.join(", ")
59
60
  end
60
61
 
61
- def omniauth_path_prefix
62
- "#{mount_at}/auth"
63
- end
64
62
  end
65
63
  end
66
64
  end
@@ -2,6 +2,12 @@
2
2
  #
3
3
  # bible270 configuration. See the gem README for the full reference.
4
4
  Bible270.configure do |config|
5
+ # --- Where the plan lives --------------------------------------------------
6
+ # Change this one value to move the plan; config/routes.rb and
7
+ # config/initializers/omniauth.rb both read it, so nothing else needs editing.
8
+ # (Remember to update the callback URLs registered with each OAuth provider.)
9
+ config.mount_at = "<%= mount_at %>"
10
+
5
11
  config.app_name = "Daily Bread"
6
12
  config.tagline = "A 270-day journey through Scripture"
7
13
 
@@ -2,15 +2,17 @@
2
2
  #
3
3
  # OmniAuth middleware for bible270's built-in sign-in.
4
4
  #
5
- # IMPORTANT: path_prefix must match where the engine is mounted, so that
6
- # OmniAuth's callback (<prefix>/:provider/callback) lands on the engine's
7
- # route. bible270 derives its sign-in button paths from the same value.
5
+ # path_prefix must match where the engine is mounted, so that OmniAuth's
6
+ # callback (<prefix>/:provider/callback) lands on the engine's route. Rather
7
+ # than repeat the path, we read it from Bible270.config.mount_at — set once in
8
+ # config/initializers/bible270.rb, which Rails loads before this file
9
+ # (initializers run in alphabetical order, and "bible270" precedes "omniauth").
8
10
  #
9
11
  # OmniAuth 2.0+ only allows POST to the request phase (CVE-2015-9284);
10
12
  # omniauth-rails_csrf_protection supplies the Rails-aware token check, and
11
13
  # bible270's sign-in controls are already POST forms.
12
14
  Rails.application.config.middleware.use OmniAuth::Builder do
13
- path_prefix "<%= omniauth_path_prefix %>"
15
+ path_prefix Bible270.config.auth_path_prefix
14
16
 
15
17
  <% provider_list.each do |p| -%>
16
18
  provider :<%= p %>,
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: 0.6.2
4
+ version: 0.9.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrew vonderLuft
@@ -65,12 +65,39 @@ dependencies:
65
65
  - - "~>"
66
66
  - !ruby/object:Gem::Version
67
67
  version: '5.0'
68
+ - !ruby/object:Gem::Dependency
69
+ name: simplecov
70
+ requirement: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - "~>"
73
+ - !ruby/object:Gem::Version
74
+ version: 0.22.0
75
+ type: :development
76
+ prerelease: false
77
+ version_requirements: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - "~>"
80
+ - !ruby/object:Gem::Version
81
+ version: 0.22.0
82
+ - !ruby/object:Gem::Dependency
83
+ name: coveralls_reborn
84
+ requirement: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - "~>"
87
+ - !ruby/object:Gem::Version
88
+ version: 0.29.0
89
+ type: :development
90
+ prerelease: false
91
+ version_requirements: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - "~>"
94
+ - !ruby/object:Gem::Version
95
+ version: 0.29.0
68
96
  description: 'Drop-in Rails engine that adds a social daily Bible reading plan over
69
- 270 days: the Old Testament once, the New Testament twice, and a whole-chapter Psalms/Proverbs
70
- companion. Daily portions are balanced by verse count so each day takes about the
71
- same time to read, and chapters are never split except Psalm 119. Readers check
72
- off each day''s readings, leave reflections, and see one another''s progress. Designed
73
- to mount cleanly into a host Rails app such as ComfortableMediaSurfer.'
97
+ 270 days: Old Testament and New Testament once, with Psalms/Proverbs alongside.
98
+ Daily portions are balanced by verse count so each day takes about the same time
99
+ to read. Readers check off each day''s readings, leave reflections, and see one
100
+ another''s progress. Designed to mount cleanly into a host Rails app such as ComfortableMediaSurfer.'
74
101
  email:
75
102
  - wonder@hey.com
76
103
  executables: []
@@ -127,11 +154,11 @@ files:
127
154
  - lib/generators/bible270/install/install_generator.rb
128
155
  - lib/generators/bible270/install/templates/bible270.rb.tt
129
156
  - lib/generators/bible270/install/templates/omniauth.rb.tt
130
- homepage: https://gknt.org
157
+ homepage: https://github.com/avonderluft/bible270
131
158
  licenses:
132
159
  - MIT
133
160
  metadata:
134
- homepage_uri: https://gknt.org
161
+ homepage_uri: https://github.com/avonderluft/bible270
135
162
  source_code_uri: https://github.com/avonderluft/bible270
136
163
  bug_tracker_uri: https://github.com/avonderluft/bible270/issues
137
164
  changelog_uri: https://github.com/avonderluft/bible270/blob/main/CHANGELOG.md
@@ -153,6 +180,6 @@ requirements: []
153
180
  rubygems_version: 4.0.16
154
181
  specification_version: 4
155
182
  summary: 'A mountable Rails engine: a 270-day, verse-balanced Bible reading plan (OT
156
- once, NT twice, Psalms/Proverbs alongside) with per-user check-offs, comments, and
183
+ and NT once, Psalms/Proverbs alongside) with per-user check-offs, comments, and
157
184
  shared community progress.'
158
185
  test_files: []