bomdb 0.0.1 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +2 -12
- data/Gemfile.lock +3 -1
- data/README.md +25 -1
- data/bomdb.gemspec +2 -1
- data/data/book_of_mormon.db +0 -0
- data/lib/bomdb.rb +15 -1
- data/lib/bomdb/cli/application.rb +217 -71
- data/lib/bomdb/diff/aligner.rb +72 -0
- data/lib/bomdb/diff/dwdiff.rb +28 -0
- data/lib/bomdb/export/base.rb +24 -0
- data/lib/bomdb/export/books.rb +15 -0
- data/lib/bomdb/export/contents.rb +100 -0
- data/lib/bomdb/export/editions.rb +15 -0
- data/lib/bomdb/export/result.rb +29 -0
- data/lib/bomdb/export/verses.rb +20 -0
- data/lib/bomdb/import/base.rb +31 -1
- data/lib/bomdb/import/books.rb +3 -12
- data/lib/bomdb/import/contents.rb +137 -0
- data/lib/bomdb/import/editions.rb +26 -0
- data/lib/bomdb/import/refs.rb +65 -0
- data/lib/bomdb/import/verses.rb +31 -50
- data/lib/bomdb/models/edition.rb +27 -0
- data/lib/bomdb/models/verse.rb +47 -0
- data/lib/bomdb/query.rb +29 -18
- data/lib/bomdb/schema.rb +28 -28
- data/lib/bomdb/version.rb +1 -1
- data/spec/bomdb/query_spec.rb +27 -0
- data/spec/bomdb/schema_spec.rb +28 -0
- data/spec/spec_helper.rb +11 -0
- metadata +33 -5
- data/data/books.json +0 -17
- data/data/verses.json +0 -145590
- data/lib/bomdb/import/biblical_refs.rb +0 -359
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e9e5b23505580c0871d836fffd14b2355a636562
|
4
|
+
data.tar.gz: 7c31fa7627d57d7f6a179d21ad8ccab40dcc108d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 69b236b5a23555654d6c2b311c7acd9f0c7767ff902957a50a0ed91db8c4c231b28e058e191f698ca840afbed8da02738cb3ffe9cc12d37cff009b71552f415b
|
7
|
+
data.tar.gz: f3bff6acf0729645bbd90677a229db21db19fe59ea2adec262bd086318b16adf3e917ce503244b6f0cf6effb95d9a6c8b1b6c45ab91c8b1b9355ffaac4483a1d
|
data/.gitignore
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,7 +1,8 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
bomdb (0.0
|
4
|
+
bomdb (0.1.0)
|
5
|
+
colorize (~> 0.7)
|
5
6
|
constellation (~> 0.1)
|
6
7
|
sequel (~> 4.21)
|
7
8
|
sqlite3 (~> 1.3)
|
@@ -12,6 +13,7 @@ GEM
|
|
12
13
|
specs:
|
13
14
|
byebug (4.0.5)
|
14
15
|
columnize (= 0.9.0)
|
16
|
+
colorize (0.7.5)
|
15
17
|
columnize (0.9.0)
|
16
18
|
constellation (0.1.1)
|
17
19
|
multi_json
|
data/README.md
CHANGED
@@ -4,6 +4,7 @@ This is a command-line tool (packaged as a Ruby gem) that provides multiple edit
|
|
4
4
|
|
5
5
|
## Usage
|
6
6
|
|
7
|
+
### SHOW a formatted edition of the Book of Mormon
|
7
8
|
Let's show the 1992 edition of the Book of Mormon:
|
8
9
|
|
9
10
|
```bash
|
@@ -26,7 +27,7 @@ Moroni 10:34 And now I bid unto all farewell. I soon go to rest in the paradise
|
|
26
27
|
Suppose we want to remove the book, chapter, and verse headings from the output:
|
27
28
|
|
28
29
|
```bash
|
29
|
-
$ bomdb show 1829 --no-
|
30
|
+
$ bomdb show 1829 --no-verse
|
30
31
|
|
31
32
|
I Nephi having been born of goodly parents, therefore I was taught somewhat in all the learning of my father...
|
32
33
|
# ... etc ...
|
@@ -40,6 +41,29 @@ $ bomdb show 1829 --exclude Bible-OT
|
|
40
41
|
# ... shows 6080 verses instead of the usual 6604
|
41
42
|
```
|
42
43
|
|
44
|
+
### ALIGN a new Book of Mormon text file
|
45
|
+
|
46
|
+
Suppose you have a new Book of Mormon text file that has been scanned from OCR or otherwise entered as a text file. It would take a lot of work to manually align all 6604 verses with the "standard" book, chapter, and verse numbers. Instead, BomDB helps automate this process:
|
47
|
+
|
48
|
+
Given this text:
|
49
|
+
|
50
|
+
```
|
51
|
+
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.
|
52
|
+
```
|
53
|
+
|
54
|
+
You can automatically align and annotate it:
|
55
|
+
|
56
|
+
```bash
|
57
|
+
$ bomdb align my_typed_bom.txt
|
58
|
+
|
59
|
+
# preamble text skipped...
|
60
|
+
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.
|
61
|
+
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.
|
62
|
+
# ... shows 6601 more verses
|
63
|
+
```
|
64
|
+
|
65
|
+
Note that `align` requires the [dwdiff](http://linux.die.net/man/1/dwdiff) command on your system.
|
66
|
+
|
43
67
|
## Installation
|
44
68
|
|
45
69
|
Add this line to your application's Gemfile:
|
data/bomdb.gemspec
CHANGED
@@ -13,7 +13,7 @@ Gem::Specification.new do |spec|
|
|
13
13
|
spec.homepage = "http://bomdb.wordtree.org"
|
14
14
|
spec.license = "MIT"
|
15
15
|
|
16
|
-
spec.files = `git ls-files -z`.split("\x0")
|
16
|
+
spec.files = `git ls-files -z`.split("\x0").reject{ |f| f =~ %r|data/.*\.json| }
|
17
17
|
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
18
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
19
|
spec.require_paths = ["lib"]
|
@@ -23,6 +23,7 @@ Gem::Specification.new do |spec|
|
|
23
23
|
spec.add_dependency 'sqlite3', '~> 1.3'
|
24
24
|
spec.add_dependency 'thor', '~> 0.19'
|
25
25
|
spec.add_dependency 'constellation', '~> 0.1'
|
26
|
+
spec.add_dependency 'colorize', '~> 0.7'
|
26
27
|
|
27
28
|
# spec.add_development_dependency 'bundler', '~> 1.7'
|
28
29
|
spec.add_development_dependency 'rake', '~> 10.0'
|
data/data/book_of_mormon.db
CHANGED
Binary file
|
data/lib/bomdb.rb
CHANGED
@@ -15,13 +15,27 @@ module BomDB
|
|
15
15
|
end
|
16
16
|
end
|
17
17
|
|
18
|
+
require 'byebug'
|
19
|
+
|
18
20
|
require 'bomdb/version'
|
19
21
|
require 'bomdb/config'
|
20
22
|
require 'bomdb/schema'
|
21
23
|
require 'bomdb/query'
|
22
24
|
|
25
|
+
require 'bomdb/diff/dwdiff'
|
26
|
+
require 'bomdb/diff/aligner'
|
27
|
+
|
23
28
|
require 'bomdb/import/base'
|
24
29
|
require 'bomdb/import/result'
|
25
30
|
require 'bomdb/import/books'
|
26
31
|
require 'bomdb/import/verses'
|
27
|
-
require 'bomdb/import/
|
32
|
+
require 'bomdb/import/editions'
|
33
|
+
require 'bomdb/import/contents'
|
34
|
+
require 'bomdb/import/refs'
|
35
|
+
|
36
|
+
require 'bomdb/export/base'
|
37
|
+
require 'bomdb/export/result'
|
38
|
+
require 'bomdb/export/books'
|
39
|
+
require 'bomdb/export/verses'
|
40
|
+
require 'bomdb/export/editions'
|
41
|
+
require 'bomdb/export/contents'
|
@@ -1,128 +1,274 @@
|
|
1
1
|
require 'thor'
|
2
2
|
require 'bomdb'
|
3
|
+
require 'colorize'
|
3
4
|
|
4
5
|
module BomDB
|
5
6
|
module Cli
|
6
7
|
class Application < Thor
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
8
|
+
|
9
|
+
|
10
|
+
|
11
|
+
desc "import FILE", "import data from FILE into database, e.g. books.json"
|
12
|
+
option :type, :type => :string, :default => nil
|
13
|
+
option :format, :type => :string, :default => 'json'
|
14
|
+
def import(file)
|
15
|
+
type = (options[:type] || type_from_file(file)).downcase
|
16
|
+
format = (options[:format] || format_from_file(file)).downcase
|
17
|
+
|
18
|
+
importer =
|
19
|
+
case type
|
20
|
+
when 'books' then BomDB::Import::Books.new(BomDB.db)
|
21
|
+
when 'verses' then BomDB::Import::Verses.new(BomDB.db)
|
22
|
+
when 'editions' then BomDB::Import::Editions.new(BomDB.db)
|
23
|
+
when 'contents' then BomDB::Import::Contents.new(BomDB.db)
|
24
|
+
when 'refs' then BomDB::Import::Refs.new(BomDB.db)
|
20
25
|
else
|
21
26
|
puts "Unknown import type #{type}"
|
22
27
|
exit -1
|
23
28
|
end
|
29
|
+
|
30
|
+
result = importer.import(read(file), format: format)
|
31
|
+
show_result_and_maybe_exit(result)
|
24
32
|
end
|
25
33
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
34
|
+
|
35
|
+
|
36
|
+
desc "export TYPE", "export data from the database, e.g. books"
|
37
|
+
option :format, :type => :string, :default => 'json'
|
38
|
+
option :editions, :type => :string, :default => :all
|
39
|
+
def export(type)
|
40
|
+
format = options[:format].downcase
|
41
|
+
|
42
|
+
exporter =
|
43
|
+
case type
|
44
|
+
when 'books' then BomDB::Export::Books.new(BomDB.db)
|
45
|
+
when 'verses' then BomDB::Export::Verses.new(BomDB.db)
|
46
|
+
when 'editions' then BomDB::Export::Editions.new(BomDB.db)
|
47
|
+
when 'contents' then BomDB::Export::Contents.new(BomDB.db, edition_prefixes: options[:editions])
|
48
|
+
# when 'refs' then BomDB::Export::Refs.new(BomDB.db)
|
49
|
+
else
|
50
|
+
puts "Unknown import type #{type}"
|
51
|
+
exit -1
|
52
|
+
end
|
53
|
+
|
54
|
+
result = exporter.export(format: format)
|
55
|
+
if result.success?
|
56
|
+
puts result.to_s
|
57
|
+
else
|
58
|
+
show_result_and_maybe_exit(result)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
|
63
|
+
|
64
|
+
desc "create", "create a new Book of Mormon database"
|
65
|
+
option :file, :type => :string, :default => BomDB.config.db_path,
|
66
|
+
:description => "the filepath of the database file on disk"
|
67
|
+
option :bare, :type => :boolean, :default => false,
|
68
|
+
:description => "create a bare database without any data"
|
69
|
+
option :delete, :type => :boolean, :default => false, :aliases => [:y],
|
70
|
+
:description => "don't ask for confirmation before overwriting an existing database"
|
71
|
+
def create
|
72
|
+
db_path = options[:file]
|
73
|
+
|
74
|
+
if File.exist?(db_path) and !options[:delete]
|
75
|
+
puts "Database file '#{db_path}' exists. Delete? (y/N) "
|
32
76
|
if $stdin.gets.chomp.downcase != "y"
|
33
77
|
puts "Exiting..."
|
34
78
|
exit -1
|
35
79
|
end
|
80
|
+
verbing = 'Overwriting'
|
81
|
+
else
|
82
|
+
verbing = 'Creating'
|
36
83
|
end
|
37
84
|
|
38
|
-
#
|
39
|
-
|
85
|
+
puts "#{verbing} database '#{db_path}' ..."
|
86
|
+
schema = BomDB::Schema.create(db_path)
|
87
|
+
puts "Created the following tables:"
|
88
|
+
schema.db.tables.each{ |t| puts "\t#{t}" }
|
40
89
|
|
41
|
-
|
42
|
-
|
90
|
+
unless options[:bare]
|
91
|
+
puts "Importing books..."
|
92
|
+
import('books.json')
|
43
93
|
|
44
|
-
|
45
|
-
|
94
|
+
puts "Importing verses..."
|
95
|
+
import('verses.json')
|
46
96
|
|
47
|
-
|
48
|
-
|
97
|
+
puts "Importing editions..."
|
98
|
+
import('editions.json')
|
49
99
|
|
100
|
+
puts "Importing contents..."
|
101
|
+
import('contents.json')
|
102
|
+
|
103
|
+
puts "Importing refs..."
|
104
|
+
import('refs.json')
|
105
|
+
end
|
106
|
+
|
107
|
+
puts "Done."
|
50
108
|
end
|
51
109
|
|
110
|
+
|
111
|
+
|
52
112
|
desc "show EDITION RANGE", "show an edition of the Book of Mormon, or a RANGE of verses"
|
53
|
-
option :
|
54
|
-
|
55
|
-
option :
|
56
|
-
|
57
|
-
option :sep, :type => :string, :default =>
|
113
|
+
option :verse, :type => :boolean, :default => true,
|
114
|
+
:description => "show book, chapter, verse annotations"
|
115
|
+
option :exclude, :type => :string, :aliases => [:x],
|
116
|
+
:description => "exclude verses that are references, e.g. Bible-OT references"
|
117
|
+
option :sep, :type => :string, :default => " ",
|
118
|
+
:description => "separator between annotations and content, defaults to ' '"
|
119
|
+
option :linesep, :type => :string, :default => "\n",
|
120
|
+
:description => "separator between verses. Defaults to newline ('\\n')."
|
121
|
+
option :color, :type => :boolean, :default => true,
|
122
|
+
:description => "show chapter and verse in color"
|
123
|
+
option :"for-alignment", :type => :boolean, :default => false,
|
124
|
+
:description => "show output in 'alignment' mode. Useful for debugging 'align' subcommand issues."
|
58
125
|
def show(edition = '1829', range = nil)
|
59
|
-
|
126
|
+
body_format = nil
|
127
|
+
if options[:"for-alignment"]
|
128
|
+
linesep = " "
|
129
|
+
verse_format = verse_format_for_alignment(options[:color])
|
130
|
+
else
|
131
|
+
linesep = options[:linesep]
|
132
|
+
if options[:verse]
|
133
|
+
if options[:color]
|
134
|
+
verse_format = lambda{ |b,c,v| b.colorize(:yellow) + ' ' +
|
135
|
+
c.to_s.colorize(:green) + ':' +
|
136
|
+
v.to_s.colorize(:light_green) }
|
137
|
+
else
|
138
|
+
verse_format = nil
|
139
|
+
end
|
140
|
+
else
|
141
|
+
verse_format = lambda{ |b,c,v| '' }
|
142
|
+
end
|
143
|
+
end
|
144
|
+
BomDB::Query.new(
|
60
145
|
edition: edition,
|
61
146
|
exclude: options[:exclude]
|
62
147
|
# range: range
|
63
|
-
)
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
sep: options[:sep]
|
148
|
+
).print(
|
149
|
+
verse_format: verse_format,
|
150
|
+
body_format: body_format,
|
151
|
+
sep: options[:sep],
|
152
|
+
linesep: linesep
|
69
153
|
)
|
70
154
|
end
|
71
155
|
|
156
|
+
|
157
|
+
|
72
158
|
desc "editions", "list available editions of the Book of Mormon"
|
73
|
-
|
159
|
+
option :all, :type => :boolean, :default => false
|
74
160
|
def editions
|
75
|
-
eds = BomDB.db[:
|
76
|
-
|
77
|
-
|
78
|
-
|
161
|
+
eds = BomDB.db[:editions].
|
162
|
+
left_outer_join(:contents, :edition_id => :edition_id).
|
163
|
+
select_group(:edition_name).
|
164
|
+
select_append{ Sequel.as(count(:verse_id), :count) }.
|
165
|
+
order(:edition_name).
|
166
|
+
map { |r| "#{r[:count]} verses\t#{r[:edition_name]}" }
|
167
|
+
puts eds.join("\n")
|
79
168
|
end
|
80
169
|
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
170
|
+
|
171
|
+
|
172
|
+
desc "references TYPE", "list reference types or references of TYPE"
|
173
|
+
def references(type=nil)
|
174
|
+
if type.nil?
|
175
|
+
rts = BomDB.db[:refs].
|
176
|
+
select_group(:ref_name).
|
177
|
+
select_append{ Sequel.as(count(ref_id), :count) }.
|
178
|
+
map { |r| "#{r[:ref_name]} (#{r[:count]} refs)" }
|
179
|
+
puts rts.join("\n")
|
180
|
+
else
|
181
|
+
rts = BomDB.db[:refs].where(:ref_name => type).
|
182
|
+
map{ |r| "#{r[:ref_book]} #{r[:ref_chapter]}:#{r[:ref_verse]}" }
|
183
|
+
puts rts.join("\n")
|
85
184
|
end
|
86
|
-
puts rts.join('\n')
|
87
185
|
end
|
88
186
|
|
89
|
-
private
|
90
187
|
|
91
|
-
|
92
|
-
|
188
|
+
|
189
|
+
desc "align FILE EDITION", "give verse annotations from EDITION to a new Book of Mormon text FILE that lacks verse annotations"
|
190
|
+
option :dwdiff, :type => :string, :default => "/usr/local/bin/dwdiff",
|
191
|
+
:description => "the filepath of the dwdiff binary (shell command)"
|
192
|
+
option :'edition-only', :type => :boolean, :default => false,
|
193
|
+
:description => "show the alignment-formatted edition output only (useful for debugging)"
|
194
|
+
option :'diff-only', :type => :boolean, :default => false,
|
195
|
+
:description => "show the dwdiff output only (useful for debugging)"
|
196
|
+
def align(file, edition = '1829')
|
197
|
+
io = StringIO.new
|
198
|
+
|
199
|
+
BomDB::Query.new(edition: edition).print(
|
200
|
+
verse_format: verse_format_for_alignment,
|
201
|
+
linesep: ' ',
|
202
|
+
io: io
|
203
|
+
)
|
204
|
+
if options[:'edition-only']
|
205
|
+
puts io.string
|
206
|
+
exit
|
207
|
+
end
|
208
|
+
|
209
|
+
dwdiff = Diff::Dwdiff.new(options[:dwdiff])
|
210
|
+
diff = dwdiff.diff(io.string, File.read(file))
|
211
|
+
|
212
|
+
if options[:'diff-only']
|
213
|
+
puts diff
|
214
|
+
exit
|
215
|
+
end
|
216
|
+
|
217
|
+
puts Diff::Aligner.parse(diff)
|
93
218
|
end
|
94
219
|
|
95
|
-
def import_books(file, reset = true)
|
96
|
-
data = File.read(file || datafile("books.json"))
|
97
220
|
|
98
|
-
import = BomDB::Import::Books.new(BomDB.db)
|
99
|
-
import.reset if reset
|
100
221
|
|
101
|
-
|
222
|
+
private
|
223
|
+
|
224
|
+
def datafile(file)
|
225
|
+
|
102
226
|
end
|
103
227
|
|
104
|
-
def
|
105
|
-
|
228
|
+
def read(file)
|
229
|
+
File.read(relative_or_data_file(file))
|
230
|
+
end
|
106
231
|
|
107
|
-
|
108
|
-
|
232
|
+
def relative_or_data_file(file)
|
233
|
+
if File.exist?(file)
|
234
|
+
file
|
235
|
+
else
|
236
|
+
if File.basename(file) == file
|
237
|
+
# Try our gem's data directory as a fallback for this file
|
238
|
+
File.join(BomDB.config.data_dir, file)
|
239
|
+
else
|
240
|
+
$stderr.puts "File not found: #{file}"
|
241
|
+
exit -1
|
242
|
+
end
|
243
|
+
end
|
244
|
+
end
|
109
245
|
|
110
|
-
|
246
|
+
def format_from_file(file)
|
247
|
+
case File.extname(file).downcase
|
248
|
+
when ".txt" then "text"
|
249
|
+
when ".json" then "json"
|
250
|
+
else
|
251
|
+
$stderr.puts "Unable to determine format from file: #{file}"
|
252
|
+
exit -1
|
253
|
+
end
|
111
254
|
end
|
112
255
|
|
113
|
-
def
|
114
|
-
|
115
|
-
|
256
|
+
def type_from_file(file)
|
257
|
+
type = File.basename(file).gsub(/\.(txt|json)$/, '').downcase
|
258
|
+
end
|
116
259
|
|
117
|
-
|
260
|
+
def verse_format_for_alignment
|
261
|
+
verse_format = lambda do |book, chapter, verse|
|
262
|
+
"[|#{book} #{chapter}:#{verse}|]"
|
263
|
+
end
|
118
264
|
end
|
119
265
|
|
120
266
|
def show_result_and_maybe_exit(result)
|
121
|
-
if
|
122
|
-
puts
|
123
|
-
|
124
|
-
puts
|
125
|
-
#
|
267
|
+
if result.success?
|
268
|
+
$stderr.puts "Success"
|
269
|
+
else
|
270
|
+
$stderr.puts result.message
|
271
|
+
# $stderr.puts "Try again with '--reset'? (NOTE: data may be deleted)"
|
126
272
|
exit -1
|
127
273
|
end
|
128
274
|
end
|