[jsword-devel] Valid module keys

DM Smith dmsmith at crosswire.org
Sat Jan 11 06:21:03 MST 2014


On Jan 11, 2014, at 1:15 AM, Greg Hellings <greg.hellings at gmail.com> wrote:

> I'm trying to decipher the API so I can fetch a list of the top-level keys in a module. e.g. for a Bible a list of all the Bible books that are valid for a given Book or such. What is the preferred way?

It depends. Typically on use case.

Are you asking specifically about Bibles or modules in general?

Not sure what top-level means to you. It probably differs between different module types. For a dictionary, do you mean all the terms that don't link to others? For a Gen Book do you mean all the first nodes in the tree? For a Bible do you mean all the books of the Bible? What about Bible introductions (e.g. module and testament level)?

And I'm not sure what you mean by valid. There are several levels of valid?

Given a key is it allowable for the module.
Is Genesis allowable for a Bible? How about 1 Hesitations?
Is Fred allowable for a dictionary? How about xyz?
Is Fred allowable for a Daily Devotion? How about March 3?

Does the key have content in the module?
Is Gen 1:1 in the Bible? Is Genesis in the Bible?
Is xyz in the Dictionary?
Is March 3 in the Daily Devotion?

Is the key defined for the versification?
Is Bel and the Dragon defined for the KJV v11n?

Answering for Bibles:
A Bible module (in JSword, we call a module a Book and a Bible module is an AbstractPassageBook) always has a Versification. A Key can only be understood in the context of a Bible's Versification.
Given a Bible Book (aka module), b, you ask it for the Versification:
b.getVersification();
The Versification object has all kinds of methods to query what's allowable. Internally, it has a BibleBookList, which is an ordered list of BibleBook. This can be queried in a variety of ways:

There are two kinds of BibleBook existence questions for a Versification:
1) Given a String, can it be understood as a BibleBook, using getBook(s) or isBook(s). E.g. Ge for Genesis.
2) Is a BibleBook in the Versification using containsBook(bb)

There are 3 different ways to iterate over the list:
1) Iterate using getBookIterator
2) Numerically using getBookCount() and getBook(n)
3) Adjacency using getFirstBook(), getLastBook(), getNextBook(bb), getPreviousBook(bb)


If you are wanting to know whether a particular Bible has a BibleBook, you might be asking whether there is any content for the BibleBook in the module. This can either be determined exactly (is there at least one key in the BibleBook that would return content) or heuristically (Is chapter 1, verse 1 have content for the BibleBook). The decision is one of performance.

Aside, the SWORD module building programs append verse content to the dat file in the order it occurs in the source file. Then they write the start and length to the idx file for that verse. If the verses are in the canonical, versification order then the question can be answered with great performance as a Bible book will have a start and a length in the dat file. If the source is not in canonical, versification order or if the append mode of the module builder is used then this is not true. So, JSword cannot make assumptions about the order of verses in the dat files.

To do the heuristic check:
Build the key for the first chapter and verse of the book, using a verse constructor v = new Verse(v11n, bb, 1, 1).
Then check for existence with b.contains(v)

To do the full check, it really depends upon whether you are wanting to check just one BibleBook or every BibleBook. Assuming the latter case, which needs to check every last verse in the module for existence:
b.getGlobalKeyList() will return the list of all keys that are actually in the Book. Chris B has optimized this to be very fast.
Then create a VerseRange for each BibleBook and test to see if that verse range intersects with the global key list.
To create a VerseRange you supply the first and last verse of the range:
new VerseRange(v11n, new Verse(v11n, bb, 0, 0), new Verse(v11n, bb, v11n.getLastChapter(bb), v11n.getLastVerse(bb, v11n.getLastChapter())
(Note use 1, 1 if you are not interested in the Book Intro or the first chapter intro. The range will include other chapter's intros.)
Then test the global key list to see if it contains any of the keys in the VerseRange. (Note, the contains method on a global key list tests contains all).
JSword does not have a "contain any", which is needed here. (BTW, we can add such if needed)
It'd be something like:
for each verse in the verse range
  if is in the global key list
    then return true as we are done
end for
return false

In Bible Desktop, we want something like this to help build the Book, chapter, verse navigator based on content of the Bible rather than on its Versification. E.g. No sense showing OT book names when the OT is not part of the module. Or showing all the Books when the module only contains John.

It may be that Chris B has implemented something like this for STEP.

If this doesn't answer your question or point you in a useful direction, please ask.

In Him,
	DM

-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/pkcs7-signature
Size: 4145 bytes
Desc: not available
URL: <http://www.crosswire.org/pipermail/jsword-devel/attachments/20140111/429eb5db/attachment.p7s>


More information about the jsword-devel mailing list