Early Literature and Scripture Search App – Update

As an update I would like to re-demo the command line version of the versepress app engine. The most notable difference from older pre-beta versions is the fact that one can supply logic to the search. Below is an example using the King James English Bible.

$ ruby versepress.rb "melchi(zedek|sedec)" 
        Genesis  14:18                             And [Melchizedek] king of Salem brought fort...
         Psalms 110:4    ...or ever after the order of [Melchizedek].
        Hebrews   5:6    ...or ever after the order of [Melchisedec].
        Hebrews   5:10   ....priest after the order of [Melchisedec].
        Hebrews   6:20   ...or ever after the order of [Melchisedec].
        Hebrews   7:1                         For this [Melchisedec], king of Salem, priest of....
        Hebrews   7:10   ....loins of his father, when [Melchisedec] met him.
        Hebrews   7:11   ...ld rise after the order of [Melchisedec], and not be called after t...
        Hebrews   7:15   ...at after the similitude of [Melchisedec] there ariseth another priest,
        Hebrews   7:17   ...or ever after the order of [Melchisedec].
        Hebrews   7:21   ...or ever after the order of [Melchisedec]:)

The versepress.com web app currently has only a King James English Bible. But other works are in development. The following is a preview of the searchable SBLGNT (Society of Biblical Literature’s Greek New Testament) :

$ ruby versepress.rb "λέγω(σιν|ν)--pl" koine
         Romans   2:22                               ὁ [λέγων] μὴ μοιχεύειν μοιχεύεις; ὁ....
  Corinthians 1  11:25   ...οτήριον μετὰ τὸ δειπνῆσαι, [λέγων]· Τοῦτο τὸ ποτήριον ἡ καινὴ...
Thessalonians 1   5:3                             ὅταν [λέγωσιν]· Εἰρήνη καὶ ἀσφάλεια, τότε...
        Hebrews   2:6          διεμαρτύρατο δέ πού τις [λέγων]· Τί ἐστιν ἄνθρωπος ὅτι μιμ...
        Hebrews   2:12                                 [λέγων]· Ἀπαγγελῶ τὸ ὄνομά σου τοῖ...
        Hebrews   4:7    ....ἡμέραν, Σήμερον, ἐν Δαυὶδ [λέγων] μετὰ τοσοῦτον χρόνον, καθὼ...
        Hebrews   6:14                                 [λέγων]· Εἰ μὴν εὐλογῶν εὐλογήσω σ...
        Hebrews   8:11   ...ἕκαστος τὸν ἀδελφὸν αὐτοῦ, [λέγων]· Γνῶθι τὸν κύριον, ὅτι πάν...
        Hebrews   9:20                                 [λέγων]· Τοῦτο τὸ αἷμα τῆς διαθήκη...
        Hebrews  10:8                         ἀνώτερον [λέγων] ὅτι Θυσίας καὶ προσφορὰς κ...
        Hebrews  12:26   ...εν τότε, νῦν δὲ ἐπήγγελται [λέγων]· Ἔτι ἅπαξ ἐγὼ σείσω οὐ μόν...
           Acts   1:3    ...ντα ὀπτανόμενος αὐτοῖς καὶ [λέγων] τὰ περὶ τῆς βασιλείας τοῦ....
           Acts   2:40   ...ρατο, καὶ παρεκάλει αὐτοὺς [λέγων]· Σώθητε ἀπὸ τῆς γενεᾶς τῆς...
           Acts   3:25   ...ὸς πρὸς τοὺς πατέρας ὑμῶν, [λέγων] πρὸς Ἀβραάμ Καὶ ἐν τῷ σπέρ...
           Acts   5:28                                 [λέγων]· Παραγγελίᾳ παρηγγείλαμεν....
           Acts   5:36   ....τῶν ἡμερῶν ἀνέστη Θευδᾶς, [λέγων] εἶναί τινα ἑαυτόν, ᾧ προσε...
           Acts   8:9    ...ων τὸ ἔθνος τῆς Σαμαρείας, [λέγων] εἶναί τινα ἑαυτὸν μέγαν,
           Acts   8:19                                 [λέγων]· Δότε κἀμοὶ τὴν ἐξουσίαν τ...
           Acts   8:26   ...ίου ἐλάλησεν πρὸς Φίλιππον [λέγων]· Ἀνάστηθι καὶ πορεύου κατὰ...
           Acts  10:26       ὁ δὲ Πέτρος ἤγειρεν αὐτὸν [λέγων]· Ἀνάστηθι· καὶ ἐγὼ αὐτὸς ἄ...
           Acts  11:4    ...ς ἐξετίθετο αὐτοῖς καθεξῆς [λέγων]·
           Acts  12:7    ...ν τοῦ Πέτρου ἤγειρεν αὐτὸν [λέγων]· Ἀνάστα ἐν τάχει· καὶ ἐξέπ...
           Acts  15:13   ...αι αὐτοὺς ἀπεκρίθη Ἰάκωβος [λέγων]· Ἄνδρες ἀδελφοί, ἀκούσατέ....
           Acts  16:9    ...ὼς καὶ παρακαλῶν αὐτὸν καὶ [λέγων]· Διαβὰς εἰς Μακεδονίαν βοή...
           Acts  16:28   ...εν δὲ φωνῇ μεγάλῃ ὁ Παῦλος [λέγων]· Μηδὲν πράξῃς σεαυτῷ κακόν...
           Acts  19:4    ...βάπτισμα μετανοίας, τῷ λαῷ [λέγων] εἰς τὸν ἐρχόμενον μετ’ αὐτ...
           Acts  19:26   ...ς μετέστησεν ἱκανὸν ὄχλον, [λέγων] ὅτι οὐκ εἰσὶν θεοὶ οἱ διὰ....
           Acts  21:21   ....τὰ ἔθνη πάντας Ἰουδαίους, [λέγων] μὴ περιτέμνειν αὐτοὺς τὰ τ...
           Acts  21:40   ...ώνησεν τῇ Ἑβραΐδι διαλέκτῳ [λέγων]
           Acts  22:26   ...θὼν τῷ χιλιάρχῳ ἀπήγγειλεν [λέγων]· Τί μέλλεις ποιεῖν; ὁ γὰρ....
           Acts  24:2    ...ατο κατηγορεῖν ὁ Τέρτυλλος [λέγων]· Πολλῆς εἰρήνης τυγχάνοντε...
           Acts  25:14   ...ἀνέθετο τὰ κατὰ τὸν Παῦλον [λέγων]· Ἀνήρ τίς ἐστιν καταλελειμ...
           Acts  26:22   ...τε καὶ μεγάλῳ, οὐδὲν ἐκτὸς [λέγων] ὧν τε οἱ προφῆται ἐλάλησαν...
           Acts  27:10                                 [λέγων] αὐτοῖς· Ἄνδρες, θεωρῶ ὅτι....
           Acts  27:24                                 [λέγων]· Μὴ φοβοῦ, Παῦλε· Καίσαρί....
           Acts  27:33   ....ἅπαντας μεταλαβεῖν τροφῆς [λέγων]· Τεσσαρεσκαιδεκάτην σήμερο...
           Acts  28:26                                 [λέγων]· Πορεύθητι πρὸς τὸν λαὸν τ...

Another interesting feature in relation to such documents is the standard “tagging” scheme. The versepress tagging feature is due to finish testing very soon. I’ll post a tag demo in the near future.

Thor CLI KJV Bible Search Engine – part 3

In part 1 I created a simple CLI (command line interface) Bible Search Engine. I then built a Thor version. It’s cool. It works. But I can’t lookup verses very easily. So, I want to remedy this situation. I just add a new Thor method to my bbl Thor task:

[code]
desc "ref [bookname,verseref]", "display a particular verse"
#method_options :sort => :boolean
def ref(bookname="genesis", verseref="001:001")
inside(Bbl.source_root) {
output = search_for_phrase
shell.say pretty(output, verseref, false)
}
end
[/code]

Now I get the following:

[code]
$ thor bbl:ref john 003:013
[/code]

john 003:013 And no man hath ascended up to heaven, but he that came down from heaven, even the Son of man which is in heaven.
john_1 003:013 Marvel not, my brethren, if the world hate you.
Now, it occurred to me that we could play around with some numerals. Before proceeding, I must say I’m not one of those “Bible code” guys. I am, however, a big fan of Don Knuth, author of Things a Computer Scientist Rarely Talks About and 3:16. In 3:16, Don surveys the sixteenth verse of the third chapter of every book in the Bible with a third chapter. Who said the Bible was boring anyway?

So, with our Thor tool it turns out we can pull the long list of 3:16 verses very easily:
[code]$ thor bbl:ref . 003:016[/code]

acts 003:016 And his name through faith in his name hath made this man strong, whom ye see and know: yea, the faith which is by him hath given him this perfect soundness in the presence of you all.
chronicles_1 003:016 And the sons of Jehoiakim: Jeconiah his son, Zedekiah his son.
chronicles_2 003:016 And he made chains, as in the oracle, and put them on the heads of the pillars; and made an hundred pomegranates, and put them on the chains.
colossians 003:016 Let the word of Christ dwell in you richly in all wisdom; teaching and admonishing one another in psalms and hymns and spiritual songs, singing with grace in your hearts to the Lord.
corinthians_1 003:016 Know ye not that ye are the temple of God, and that the Spirit of God dwelleth in you?
corinthians_2 003:016 Nevertheless when it shall turn to the Lord, the vail shall be taken away.
daniel 003:016 Shadrach, Meshach, and Abednego, answered and said to the king, O Nebuchadnezzar, we are not careful to answer thee in this matter.
deuteronomy 003:016 And unto the Reubenites and unto the Gadites I gave from Gilead even unto the river Arnon half the valley, and the border even unto the river Jabbok, which is the border of the children of Ammon;
ecclesiastes 003:016 And moreover I saw under the sun the place of judgment, that wickedness was there; and the place of righteousness, that iniquity was there.
ephesians 003:016 That he would grant you, according to the riches of his glory, to be strengthened with might by his Spirit in the inner man;
exodus 003:016 Go, and gather the elders of Israel together, and say unto them, The LORD God of your fathers, the God of Abraham, of Isaac, and of Jacob, appeared unto me, saying, I have surely visited you, and seen that which is done to you in Egypt:
ezekiel 003:016 And it came to pass at the end of seven days, that the word of the LORD came unto me, saying,
galations 003:016 Now to Abraham and his seed were the promises made. He saith not, And to seeds, as of many; but as of one, And to thy seed, which is Christ.
genesis 003:016 Unto the woman he said, I will greatly multiply thy sorrow and thy conception; in sorrow thou shalt bring forth children; and thy desire shall be to thy husband, and he shall rule over thee.
habakkuk 003:016 When I heard, my belly trembled; my lips quivered at the voice: rottenness entered into my bones, and I trembled in myself, that I might rest in the day of trouble: when he cometh up unto the people, he will invade them with his troops.
hebrews 003:016 For some, when they had heard, did provoke: howbeit not all that came out of Egypt by Moses.
&#0133
&#0133
&#0133

Crazy. In the next installment I’ll figure out a way to filter by groups of books such as Torah, NT, OT, Pauline, etc.

Thor CLI KJV Bible Search Engine – part 2

In part 1 I showed how I created a simple CLI (command line interface) Bible Search Engine. The problem is that one must always reference the path to the Bible text files. So I will create a Thor task which will eliminate this dependence on the user giving a path (or having to change to the text file directory). First, I create a directory called bbl (which means Bible) inside my _thor directory (which is just a collection of task directories) and then copy the source files there. I’ll create a bbl.rb file which holds my Ruby code creating a Thor task.
[code]
_thor/bbl$ ls
bbl.rb books

_thor/bbl$ more bbl.rb
class Bbl < Thor

def self.source_root
# the permanent location of the text files on my system
‘~/projects/_thor/bbl/books’
end

end
Now we can install the Thor task so the system always knows about it:
[code]
_thor/bbl$ thor install bbl.rb
Please specify a name for bbl.rb in the system repository [bbl.rb]: bbl
Storing thor file in your system repository
[/code]

[code]
_thor/bbl$ thor installed
Modules Namespaces
——- ———-
bbl bbl

bbl

thor bbl:find [PHRASE] # find a phase given as list of words on param line
[/code]

Now we can search through the Bible from anywhere on the system. Here is an example from the home directory:
[code]
author@his-laptop:~$ cd ~
author@his-laptop:~$ thor bbl:find "thou art a priest"
psalms 110:004 The LORD hath sworn, and will not repent, Thou art a priest for ever after the order of Melchizedek.
hebrews 005:006 As he saith also in another place, Thou art a priest for ever after the order of Melchisedec.
hebrews 007:017 For he testifieth, Thou art a priest for ever after the order of Melchisedec.
hebrews 007:021 (For those priests were made without an oath; but this with an oath by him that said unto him, The Lord sware and will not repent, Thou art a priest for ever after the order of Melchisedec:)
[/code]

Another advantage of running output through the Thor library is that we can perform post-processing to clean up the output (notice the use of Thor’s shell.set_color method):

We get a cleaner presentation:

[code]
_thor/bbl$ thor bbl:find "Thou art a priest"
[/code]

psalms 110:004 The LORD hath sworn, and will not repent, << Thou art a priest >> for ever after the order of Melchizedek.
hebrews 005:006 As he saith also in another place, << Thou art a priest >> for ever after the order of Melchisedec.
hebrews 007:017 For he testifieth, << Thou art a priest >> for ever after the order of Melchisedec.
hebrews 007:021 (For those priests were made without an oath; but this with an oath by him that said unto him, The Lord sware and will not repent, << Thou art a priest >> for ever after the order of Melchisedec:)

fun with sqlite3

We already have sqlite3 installed. So creating a new database is easy:

[code]
..mypath/db$ sqlite3 test.sqlite3
SQLite version 3.7.2
Enter ".help" for instructions
Enter SQL statements terminated with a ";"
sqlite>
[/code]

We add some tables:
[code]
sqlite> create table categories (name varchar(10), id smallint);
sqlite> create table products(name varchar(20), id smallint, category_id smallint);
[/code]

List our new tables:
[code]
sqlite> .schema
CREATE TABLE categories (name varchar(10), id smallint);
CREATE TABLE products(name varchar(20), id smallint, category_id smallint);
sqlite>
[/code]

Now insert some data:
[code]
sqlite> insert into categories values (‘catholicism’, 1);
sqlite> insert into categories values (‘baptist’, 2);
sqlite> insert into categories values (‘chino orthodox’, 3);
sqlite> insert into categories values (‘redneck’, 4);
sqlite> insert into products values (‘bible’, 1, 2);
sqlite> insert into products values (‘candle’, 2, 1);
sqlite> insert into products values (‘gun’, 3, 4);
sqlite> insert into products values (‘chopsticks’, 4, 3);
[/code]

List content of tables:
[code]
sqlite> select * from categories;
catholicism|1
baptist|2
chino orthodox|3
redneck|4
sqlite>
[/code]
[code]
sqlite> select * from products;
bible|1|2
candle|2|1
gun|3|4
chopsticks|4|3
sqlite>
[/code]

Okay. In this simple design there is a one-to-many relationship between tables. A category has many products. A category is just a category. It has no foreign keys. The products tables has a foreign key called “category_id.”

Now we can join the data:

[code]
sqlite> select p.name, c.name from products p inner join categories c on p.category_id = c.id;
bible|baptist
candle|catholicism
gun|redneck
chopsticks|chino orthodox
sqlite>
[/code]

Why did I use the “inner join” construct? Honestly, I don’t even think about this. I always think first in terms of inner join. If I need more complicated logic then perhaps I will use an “left join” construct.

[code]
sqlite> select p.name, c.name from products p left join categories c on p.category_id = c.id;
bible|baptist
candle|catholicism
gun|redneck
chopsticks|chino orthodox
[/code]

Hey! The results are the same! Why? Only because of the state of the data.

Let us change the data:
[code]
sqlite> update products set category_id = null where id = 3;
sqlite> select * from products;
bible|1|2
candle|2|1
gun|3|
chopsticks|4|3
sqlite>
[/code]

Now what category does the “gun” item belong to? We don’t know. Maybe it belongs to the Baptists or the Catholics?

Run the query again with both queries:

[code]
sqlite> select p.name, c.name from products p inner join categories c on p.category_id = c.id;
bible|baptist
candle|catholicism
chopsticks|chino orthodox
sqlite>
[/code]
[code]
sqlite> select p.name, c.name from products p left join categories c on p.category_id = c.id;
bible|baptist
candle|catholicism
gun|
chopsticks|chino orthodox
sqlite>
[/code]

Wow. The first query only shows products that have valid categories. The second query allows the invalid categories. So it returns the intersection and layers it on top of the invalid data.

Now we can ask which products need a category:
[code]
sqlite> select p.name, c.name from products p left join categories c on p.category_id = c.id where p.category_id is null;
gun|
sqlite>
[/code]
Ooooh! Someone in the Church Bookstore forgot to update the category of the gun item!