bomdb 0.4.0 → 0.5.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: ed29a8b091ac7a85d4094e529a263c7b31f3cbed
4
- data.tar.gz: df521bfa0632df2c26abc1e428d99c053238f6ae
3
+ metadata.gz: f7fbd83f638d94be3f15c4cf8442e2cdeccf8b1e
4
+ data.tar.gz: 2625af19b7be4478cd1abf1a39900ff41d21e10c
5
5
  SHA512:
6
- metadata.gz: 78ff3e653b5a63293b576926f2083d3c7f440fbeb21c0adc6141d235568a00f210b8cbb7dffaf184cf3964d0b8c308d3c6dcb43ec06b5d563a66f96383566497
7
- data.tar.gz: e0eec88eeecf615ac5a505162936cba47722a255b71e8ba5cafba7dc45c503b711a5fedc5b4fb362ed9c4c1fc4511e0e27bddbfe4e14842c091cf69a5a1e0e63
6
+ metadata.gz: 3c3d9acb48871cf5676c901c3d45b233a4d7e208da3d873b5b63930a2dbbe3d8456472b3045597f61493f8181b468f7d9a82defe4354d4252857ad2ded14ddcd
7
+ data.tar.gz: 58c3914913e18e8aa645997b13599d33e4c5876ce9fbf0e0928fd17e8603baf20ef87dd50f20822922fc2761fe2e6db5907fe58f0d8350012ffff667c62d8e48
@@ -1,18 +1,25 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- bomdb (0.4.0)
4
+ bomdb (0.5.0)
5
5
  colorize (~> 0.7)
6
6
  constellation (~> 0.1)
7
7
  levenshtein-ffi (~> 1.1)
8
+ mericope (~> 0.1.1)
8
9
  sequel (~> 4.21)
9
10
  sqlite3 (~> 1.3)
10
- text_clean
11
+ text_clean (~> 0)
11
12
  thor (~> 0.19)
12
13
 
13
14
  GEM
14
15
  remote: https://rubygems.org/
15
16
  specs:
17
+ activesupport (4.2.1)
18
+ i18n (~> 0.7)
19
+ json (~> 1.7, >= 1.7.7)
20
+ minitest (~> 5.1)
21
+ thread_safe (~> 0.3, >= 0.3.4)
22
+ tzinfo (~> 1.1)
16
23
  byebug (4.0.5)
17
24
  columnize (= 0.9.0)
18
25
  colorize (0.7.5)
@@ -20,18 +27,23 @@ GEM
20
27
  constellation (0.1.1)
21
28
  multi_json
22
29
  diff-lcs (1.2.5)
23
- ffi (1.9.3)
30
+ ffi (1.9.8)
31
+ i18n (0.7.0)
32
+ json (1.8.2)
24
33
  levenshtein-ffi (1.1.0)
25
34
  ffi (~> 1.9)
35
+ mericope (0.1.1)
36
+ activesupport (~> 4.0)
37
+ minitest (5.6.0)
26
38
  multi_json (1.11.0)
27
39
  rake (10.4.2)
28
40
  rspec (3.2.0)
29
41
  rspec-core (~> 3.2.0)
30
42
  rspec-expectations (~> 3.2.0)
31
43
  rspec-mocks (~> 3.2.0)
32
- rspec-core (3.2.2)
44
+ rspec-core (3.2.3)
33
45
  rspec-support (~> 3.2.0)
34
- rspec-expectations (3.2.0)
46
+ rspec-expectations (3.2.1)
35
47
  diff-lcs (>= 1.2.0, < 2.0)
36
48
  rspec-support (~> 3.2.0)
37
49
  rspec-mocks (3.2.1)
@@ -42,6 +54,9 @@ GEM
42
54
  sqlite3 (1.3.10)
43
55
  text_clean (0.2.2)
44
56
  thor (0.19.1)
57
+ thread_safe (0.3.5)
58
+ tzinfo (1.2.2)
59
+ thread_safe (~> 0.1)
45
60
 
46
61
  PLATFORMS
47
62
  ruby
data/README.md CHANGED
@@ -117,7 +117,14 @@ Suppose you have a new Book of Mormon text file that has been scanned from OCR o
117
117
  Given this text:
118
118
 
119
119
  ```
120
- I, Nephi, having been born of goodly parents, therefore I was taught somewhat in all the learning of my father; and having seen many afflictions in the course of my days--nevertheless, having been highly favored of the Lord in all my days; yea, having had a great knowledge of the goodness and the mysteries of God, therefore I make a record of my proceedings in my days; yea, I make a record in the language of my father, which consists of the learning of the Jews and the language of the Egyptians. And I know that the record which I make is true; and I make it with mine own hand; and I make it according to my knowledge.
120
+ I, Nephi, having been born of goodly parents, therefore I was taught somewhat
121
+ in all the learning of my father; and having seen many afflictions in the course
122
+ of my days--nevertheless, having been highly favored of the Lord in all my days;
123
+ yea, having had a great knowledge of the goodness and the mysteries of God,
124
+ therefore I make a record of my proceedings in my days; yea, I make a record in
125
+ the language of my father, which consists of the learning of the Jews and the
126
+ language of the Egyptians. And I know that the record which I make is true; and
127
+ I make it with mine own hand; and I make it according to my knowledge.
121
128
  ```
122
129
 
123
130
  You can automatically align and annotate it:
@@ -125,14 +132,67 @@ You can automatically align and annotate it:
125
132
  ```bash
126
133
  $ bomdb align my_typed_bom.txt
127
134
 
128
- # preamble text skipped...
135
+ 1 Nephi 1:1 I, Nephi, having been born of goodly parents, therefore I was taught somewhat in all the learning of my father; and having seen many afflictions in the course of my days--nevertheless, having been highly favored of the Lord in all my days; yea, having had a great knowledge of the goodness and the mysteries of God, therefore I make a record of my proceedings in my days;
129
136
  1 Nephi 1:2 yea, I make a record in the language of my father, which consists of the learning of the Jews and the language of the Egyptians.
130
137
  1 Nephi 1:3 And I know that the record which I make is true; and I make it with mine own hand; and I make it according to my knowledge.
131
- # ... shows 6601 more verses
132
138
  ```
133
139
 
134
140
  Note that `align` requires the [dwdiff](http://linux.die.net/man/1/dwdiff) command on your system.
135
141
 
142
+ ### Custom Queries
143
+
144
+ Here's a simple way to analyze the Book of Mormon to see the wherefore/therefore divergence leading to the [Mosiah Priority](http://signaturebookslibrary.org/new-approaches-to-the-book-of-mormon-10/) (Mosiah was written before 1 Nephi) hypothesis:
145
+
146
+ ```ruby
147
+ $ bundle exec irb -rbomdb
148
+ irb(main):001:0> q = BomDB::Query.new(exclude: 'Bible-OT')
149
+ => #<BomDB::Query:0x007f90ad1cb408 @edition=1829, @exclude="Bible-OT", @headings=false>
150
+ irb(main):002:0> q.books.map{ |book,content| [book, content.scan(/wherefore/i).size, content.scan(/therefore/i).size] }
151
+ => [
152
+ ["1 Nephi", 99, 13], ["2 Nephi", 126, 6], ["Jacob", 53, 1],
153
+ ["Enos", 6, 0], ["Jarom", 3, 0], ["Omni", 6, 0], ["Words of Mormon", 5, 0],
154
+ ["Mosiah", 0, 122], ["Alma", 3, 288], ["Helaman", 0, 63],
155
+ ["3 Nephi", 3, 96], ["4 Nephi", 0, 5], ["Mormon", 0, 22],
156
+ ["Ether", 63, 26], ["Moroni", 38, 0]
157
+ ]
158
+ ```
159
+
160
+ Or perhaps a little more visually:
161
+ ```ruby
162
+ require 'bomdb'
163
+
164
+ q = BomDB::Query.new(exclude: "Bible-OT")
165
+
166
+ q.books.each do |book,content|
167
+ words = content.scan(/ +/).size
168
+ puts book.ljust(18) +
169
+ 'W' * (content.scan(/wherefore/i).size.to_f / words * 2000) +
170
+ 'T' * (content.scan(/therefore/i).size.to_f / words * 2000)
171
+ end
172
+
173
+ # 1 Nephi WWWWWWWWT
174
+ # 2 Nephi WWWWWWWWWWWWWW
175
+ # Jacob WWWWWWWWWWW
176
+ # Enos WWWWWWWWWW
177
+ # Jarom WWWWWWWW
178
+ # Omni WWWWWWWW
179
+ # Words of Mormon WWWWWWWWWWW
180
+ # Mosiah TTTTTTTT
181
+ # Alma TTTTTT
182
+ # Helaman TTTTTT
183
+ # 3 Nephi TTTTTTT
184
+ # 4 Nephi TTTTT
185
+ # Mormon TTTT
186
+ # Ether WWWWWWWTTT
187
+ # Moroni WWWWWWWWWWWW
188
+ ```
189
+
190
+ Other possible enumerables on a Query include:
191
+
192
+ - books: enumerate on each book of the Book of Mormon
193
+ - chapters: enumerate on each book and chapter of the Book of Mormon
194
+ - wordgroups(N): enumerate on consecutive N words, e.g. each 1000 words
195
+
136
196
  ## Installation
137
197
 
138
198
  Ruby 2.1 is required. You should also have a normal build environment set up, e.g. command line tools on the mac, or GCC on Linux.
@@ -24,8 +24,9 @@ Gem::Specification.new do |spec|
24
24
  spec.add_dependency 'thor', '~> 0.19'
25
25
  spec.add_dependency 'constellation', '~> 0.1'
26
26
  spec.add_dependency 'colorize', '~> 0.7'
27
- spec.add_dependency 'text_clean'
27
+ spec.add_dependency 'text_clean', '~> 0'
28
28
  spec.add_dependency 'levenshtein-ffi', '~> 1.1'
29
+ spec.add_dependency 'mericope', '~> 0.1.1'
29
30
 
30
31
  # spec.add_development_dependency 'bundler', '~> 1.7'
31
32
  spec.add_development_dependency 'rake', '~> 10.0'
Binary file
@@ -1,4 +1,5 @@
1
1
  require 'sequel'
2
+ require 'mericope'
2
3
 
3
4
  dbfile = ARGV.first || "book_of_mormon.db"
4
5
 
@@ -5,13 +5,17 @@ module BomDB
5
5
  class Verses < Export::Base
6
6
  def export_json
7
7
  verses = []
8
- @db[:verses].join(:books, :book_id => :book_id).
8
+ @db[:verses].
9
+ join(:books, :book_id => :book_id).
9
10
  where(:verse_heading => nil).
10
11
  order(:book_sort, :verse_chapter).
11
- select_group(:book_name, :verse_chapter).
12
- select_append{ Sequel.as(max(:verse_number), :count) }.
13
12
  each do |v|
14
- verses << { book: v[:book_name], chapter: v[:verse_chapter], verses: v[:count] }
13
+ verses << {
14
+ range_id: v[:verse_range_id],
15
+ book: v[:book_name],
16
+ chapter: v[:verse_chapter],
17
+ verse: v[:verse_number]
18
+ }
15
19
  end
16
20
  Export::Result.new(success: true, body: JSON.pretty_generate(verses))
17
21
  end
@@ -9,30 +9,38 @@ module BomDB
9
9
  # Expected data format is:
10
10
  # [
11
11
  # {
12
- # "book": String,
13
- # "chapter": Int,
14
- # "verses": Int
12
+ # "range_id": Int, # the mericope range ID
13
+ # "book": String, # the name of the book, e.g. 1 Nephi
14
+ # "chapter": Int, # the chapter number
15
+ # "verse": Int # the verse number
15
16
  # },
16
17
  # ...
17
18
  # ]
18
19
  def import_json(data, **args)
20
+ book, chapter = nil, nil
21
+ verse_model = Models::Verse.new(@db)
19
22
  data.each do |r|
20
- # Create a heading per chapter
21
- Models::Verse.new(@db).find_or_create(
22
- chapter: r['chapter'],
23
- verse: nil,
24
- book_name: r['book'],
25
- heading: true
26
- )
27
-
28
- # Create as many verses as is called for per chapter
29
- (1..r['verses']).each do |verse_number|
23
+ if r['chapter'] != chapter || r['book'] != book
24
+ # Create a heading per chapter
30
25
  Models::Verse.new(@db).find_or_create(
31
26
  chapter: r['chapter'],
32
- verse: verse_number,
33
- book_name: r['book']
27
+ verse: nil,
28
+ book_name: r['book'],
29
+ heading: true
34
30
  )
31
+ chapter = r['chapter']
35
32
  end
33
+
34
+ if r['book'] != book
35
+ puts "Importing chapters & verses for '#{r['book']}'"
36
+ book = r['book']
37
+ end
38
+ verse_model.find_or_create(
39
+ chapter: r['chapter'],
40
+ verse: r['verse'],
41
+ book_name: r['book'],
42
+ range_id: r['range_id']
43
+ )
36
44
  end
37
45
  Import::Result.new(success: true)
38
46
  rescue Sequel::UniqueConstraintViolation => e
@@ -16,19 +16,28 @@ module BomDB
16
16
  end
17
17
 
18
18
  # Create a verse and return its verse_id
19
- def create(chapter:, verse:, book_name: nil, book_id: nil, heading: false)
19
+ def create(chapter:, verse:, book_name: nil, book_id: nil, heading: false, range_id: nil)
20
20
  @db[:verses].insert(
21
21
  book_id: book_by_name_or_id(book_name, book_id),
22
22
  verse_chapter: chapter,
23
23
  verse_number: verse,
24
- verse_heading: heading ? 0 : nil
24
+ verse_heading: heading ? 0 : nil,
25
+ verse_range_id: range_id
25
26
  )
26
27
  end
27
28
 
28
29
  # Returns a verse_id after finding or creating the verse
29
- def find_or_create(**args)
30
- verse = find(**args)
31
- (verse && verse[:verse_id]) || create(**args)
30
+ def find_or_create(chapter:, verse:, book_name: nil, book_id: nil, heading: false, range_id: nil)
31
+ v = find(
32
+ chapter: chapter, verse: verse,
33
+ book_name: book_name, book_id: book_id,
34
+ heading: heading
35
+ )
36
+ (v && v[:verse_id]) || create(
37
+ chapter: chapter, verse: verse,
38
+ book_name: book_name, book_id: book_id,
39
+ heading: heading, range_id: range_id
40
+ )
32
41
  end
33
42
 
34
43
  protected
@@ -2,7 +2,7 @@ require 'bomdb/models/edition'
2
2
 
3
3
  module BomDB
4
4
  class Query
5
- def initialize(edition:, exclude: nil, headings: false)
5
+ def initialize(edition: 1829, exclude: nil, headings: false)
6
6
  @edition = edition
7
7
  @exclude = exclude
8
8
  @headings = headings
@@ -35,6 +35,38 @@ module BomDB
35
35
  query.each(&block)
36
36
  end
37
37
 
38
+ def chapters
39
+ groups = query.all.group_by do |x|
40
+ [x[:book_name], x[:verse_chapter]]
41
+ end
42
+ Enumerator.new(groups.size) do |y|
43
+ groups.each do |heading, rows|
44
+ content = rows.map{ |r| r[:content_body] }.join(" ")
45
+ y.yield(heading, content)
46
+ end
47
+ end
48
+ end
49
+
50
+ def books
51
+ groups = query.all.group_by{ |x| x[:book_name] }
52
+ Enumerator.new(groups.size) do |y|
53
+ groups.each do |heading, rows|
54
+ content = rows.map{ |r| r[:content_body] }.join(" ")
55
+ y.yield(heading, content)
56
+ end
57
+ end
58
+ end
59
+
60
+ def wordgroups(wordcount)
61
+ content = query.all.map{ |r| r[:content_body] }.join(" ")
62
+ groups = content.scan(/[^ ]+/).each_slice(wordcount).map{ |w| w.join(" ") }
63
+ Enumerator.new(groups.size) do |y|
64
+ groups.each do |g|
65
+ y.yield(g)
66
+ end
67
+ end
68
+ end
69
+
38
70
  def print(verse_format: nil, body_format: nil, sep: ' ', linesep: "\n", io: $stdout)
39
71
  shown = false
40
72
  verse_format ||= lambda{ |book, chapter, verse| "#{book}#{sep}#{chapter}:#{verse}" }
@@ -37,6 +37,8 @@ module BomDB
37
37
  integer :verse_number, :null => true
38
38
  integer :verse_heading, :null => true
39
39
 
40
+ integer :verse_range_id, :unique => true, :null => true
41
+
40
42
  index [:book_id, :verse_chapter, :verse_number, :verse_heading], :unique => true
41
43
  end if include?(tables, :verses)
42
44
 
@@ -1,3 +1,3 @@
1
1
  module BomDB
2
- VERSION = "0.4.0"
2
+ VERSION = "0.5.0"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bomdb
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Duane Johnson
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-04-14 00:00:00.000000000 Z
11
+ date: 2015-04-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: sequel
@@ -84,14 +84,14 @@ dependencies:
84
84
  name: text_clean
85
85
  requirement: !ruby/object:Gem::Requirement
86
86
  requirements:
87
- - - ">="
87
+ - - "~>"
88
88
  - !ruby/object:Gem::Version
89
89
  version: '0'
90
90
  type: :runtime
91
91
  prerelease: false
92
92
  version_requirements: !ruby/object:Gem::Requirement
93
93
  requirements:
94
- - - ">="
94
+ - - "~>"
95
95
  - !ruby/object:Gem::Version
96
96
  version: '0'
97
97
  - !ruby/object:Gem::Dependency
@@ -108,6 +108,20 @@ dependencies:
108
108
  - - "~>"
109
109
  - !ruby/object:Gem::Version
110
110
  version: '1.1'
111
+ - !ruby/object:Gem::Dependency
112
+ name: mericope
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - "~>"
116
+ - !ruby/object:Gem::Version
117
+ version: 0.1.1
118
+ type: :runtime
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - "~>"
123
+ - !ruby/object:Gem::Version
124
+ version: 0.1.1
111
125
  - !ruby/object:Gem::Dependency
112
126
  name: rake
113
127
  requirement: !ruby/object:Gem::Requirement