Closed jamlen closed 10 years ago
For now you can do something like the following, where you call osis_to_readable("long", "1Cor.2.5")
. It only works on a single OSIS (a book, chapter, verse, or range), not a sequence of several OSISes.
bcv_parser = require("./en_bcv_parser.js").bcv_parser
bcv = new bcv_parser
bcv.set_options osis_compaction_strategy: "bcv", book_alone_strategy: "full", book_sequence_strategy: "include", consecutive_combination_strategy: "combine", book_range_strategy: "include"
abbrevs =
"Gen": ["Genesis","Gen","Ge"]
"Exod": ["Exodus","Exod","Ex"]
"Lev": ["Leviticus","Lev","Lv"]
"Num": ["Numbers","Num","Nu"]
"Deut": ["Deuteronomy","Deut","Dt"]
"Josh": ["Joshua","Josh"]
"Judg": ["Judges","Judg","Jg"]
"Ruth": ["Ruth","Ruth","Rt"]
"1Sam": ["1 Samuel","1 Sam","1 Sa"]
"2Sam": ["2 Samuel","2 Sam","2 Sa"]
"1Kgs": ["1 Kings","1 Kgs","1 Kg"]
"2Kgs": ["2 Kings","2 Kgs","2 Kg"]
"1Chr": ["1 Chronicles","1 Chr","1 Ch"]
"2Chr": ["2 Chronicles","2 Chr","2 Ch"]
"Ezra": ["Ezra","Ezra","Ezr"]
"Neh": ["Nehemiah","Neh"]
"Esth": ["Esther","Esth","Est"]
"Job": ["Job"]
"Ps": ["Psalms","Ps","Ps","Psalm"]
"Prov": ["Proverbs","Prov","Pr"]
"Eccl": ["Ecclesiastes","Eccl","Ec"]
"Song": ["Song of Songs","Song","Sg"]
"Isa": ["Isaiah","Isa","Is"]
"Jer": ["Jeremiah","Jer","Je"]
"Lam": ["Lamentations","Lam","La"]
"Ezek": ["Ezekiel","Ezek","Ezk"]
"Dan": ["Daniel","Dan","Dn"]
"Hos": ["Hosea","Hos","Ho"]
"Joel": ["Joel","Joel","Jl"]
"Amos": ["Amos","Amos","Am"]
"Obad": ["Obadiah","Obad","Ob"]
"Jonah": ["Jonah","Jonah","Jon"]
"Mic": ["Micah","Mic"]
"Nah": ["Nahum","Nah","Na"]
"Hab": ["Habakkuk","Hab"]
"Zeph": ["Zephaniah","Zeph","Zph"]
"Hag": ["Haggai","Hag"]
"Zech": ["Zechariah","Zech","Zch"]
"Mal": ["Malachi","Mal"]
"Matt": ["Matthew","Matt","Mt"]
"Mark": ["Mark","Mark","Mk"]
"Luke": ["Luke","Luke","Lk"]
"John": ["John","John","Jn"]
"Acts": ["Acts","Acts","Ac"]
"Rom": ["Romans","Rom","Ro"]
"1Cor": ["1 Corinthians","1 Cor","1 Co"]
"2Cor": ["2 Corinthians","2 Cor","2 Co"]
"Gal": ["Galatians","Gal"]
"Eph": ["Ephesians","Eph"]
"Phil": ["Philippians","Phil"]
"Col": ["Colossians","Col"]
"1Thess": ["1 Thessalonians","1 Thess","1 Th"]
"2Thess": ["2 Thessalonians","2 Thess","2 Th"]
"1Tim": ["1 Timothy","1 Tim","1 Ti"]
"2Tim": ["2 Timothy","2 Tim","2 Ti"]
"Titus": ["Titus"]
"Phlm": ["Philemon","Phlm","Phm"]
"Heb": ["Hebrews","Heb"]
"Jas": ["James","Jas"]
"1Pet": ["1 Peter","1 Pet","1 Pt"]
"2Pet": ["2 Peter","2 Pet","2 Pt"]
"1John": ["1 John","1 John","1 Jn"]
"2John": ["2 John","2 John","2 Jn"]
"3John": ["3 John","3 John","3 Jn"]
"Jude": ["Jude"]
"Rev": ["Revelation","Rev","Rv"]
"Tob": ["Tobit","Tob"]
"Jdt": ["Judith","Jdt"]
"GkEsth": ["Greek Esther","Gk Esth","Gk Est"]
"Wis": ["Wisdom","Wis"]
"Sir": ["Sirach","Sir"]
"Bar": ["Baruch","Bar"]
"PrAzar": ["Prayer of Azariah","Pr Azar"]
"Sus": ["Susannah","Sus"]
"Bel": ["Bel and the Dragon","Bel"]
"SgThree": ["Song of the Three Young Men","SgThree"]
"EpJer": ["Epistle of Jeremiah","Ep Jer"]
"1Macc": ["1 Maccabees","1 Macc","1 Mc"]
"2Macc": ["2 Maccabees","2 Macc","2 Mc"]
"3Macc": ["3 Maccabees","3 Macc","3 Mc"]
"4Macc": ["4 Maccabees","4 Macc","4 Mc"]
"1Esd": ["1 Esdras","1 Esd"]
"2Esd": ["2 Esdras","2 Esd"]
"PrMan": ["Prayer of Manasseh","Pr Man"]
separators =
"bc": " "
"bv": " "
"cv": ":"
"range_b": "\u2014"
"range_c": "\u2014"
"range_v": "\u2013"
"sequence": ", "
output_types =
"long": 0
"short": 1
"shorter": 2
"single": 3
single_chapter_books = {}
osis_to_readable = (output_type, osis) ->
[start, end] = osis.split "-"
if end?
handle_range start, end, output_type
else
handle_single start, output_type
handle_range = (start, end, output_type) ->
[sb, sc, sv] = start.split "."
[eb, ec, ev] = end.split "."
if sb is eb
if sc is ec
"#{handle_single(start, output_type, true, true)}#{separators.range_v}#{ev}"
else
if ev?
start += ".1" unless sv?
"#{handle_single(start, output_type, false, true)}#{separators.range_c}#{ec}#{separators.cv}#{ev}"
else if sv?
"#{handle_single(start, output_type, false, true)}#{separators.range_c}#{ec}#{separators.cv}#{get_end_verse eb, ec}"
else
"#{handle_single(start, output_type, false, true)}#{separators.range_c}#{ec}"
else if ec?
start += ".1" unless sc?
start += ".1" if ev? and not sv?
end += ".#{get_end_verse eb, ec}" if sv? and not ev?
# Always `is_single_chapter=true` because we're in multiple books and we're always including the chapter (because `if ec?` is true).
"#{handle_single(start, output_type, true, true)}#{separators.range_b}#{handle_single(end, output_type, true)}"
else
is_single_chapter = true
if sc?
ec = get_end_chapter eb
end += ".#{ec}"
end += ".#{get_end_verse eb, ec}" if sv?
else is_single_chapter = false
"#{handle_single(start, output_type, is_single_chapter, true)}#{separators.range_b}#{handle_single(end, output_type, is_single_chapter)}"
handle_single = (osis, output_type, is_single_chapter=true, is_range_start=false) ->
[b, c, v] = osis.split "."
if c?
if v?
if c is "1" and (v isnt "1" or is_range_start) and is_single_chapter_book(b)
"#{get_best_book b, output_type, is_single_chapter}#{separators.bv}#{v}"
else
"#{get_best_book b, output_type, is_single_chapter}#{separators.bc}#{c}#{separators.cv}#{v}"
else
"#{get_best_book b, output_type, is_single_chapter}#{separators.bc}#{c}"
else
get_best_book b, output_type, is_single_chapter
get_best_book = (b, output_type, is_single_chapter) ->
output_id = output_types[output_type] || 0
while output_id > 0
break if abbrevs[b][output_id]?
output_id--
output_id = output_types["single"] if is_single_chapter and output_id == 0 and abbrevs[b][output_types["single"]]?
abbrevs[b][output_id]
is_single_chapter_book = (book) ->
return single_chapter_books[book] if single_chapter_books[book]?
osis = bcv.parse("#{book} 2").osis()
[start, end] = osis.split "-"
out = if end? then false else true
single_chapter_books[book] = out
out
get_end_chapter = (b) ->
[start, end] = bcv.parse("#{b} 1-999").osis().split("-")
[b, c, v] = end.split(".")
c
get_end_verse = (b, c) ->
[start, end] = bcv.parse("#{b} #{c}").osis().split("-")
[b, c, v] = end.split(".")
v
tests = [
["long", "Matt.2", "Matthew 2"]
["short", "Matt.2", "Matt 2"]
["shorter", "Matt.2", "Mt 2"]
["long", "Ps.2", "Psalm 2"]
["long", "Ps.2-Ps.47", "Psalms 2\u201447"]
["short", "Ps.2-Ps.47", "Ps 2\u201447"]
["shorter", "Ps.2-Ps.47", "Ps 2\u201447"]
["long", "Ps.2.3-Ps.4", "Psalms 2:3\u20144:8"]
["long", "Ps.2-Ps.4.3", "Psalms 2:1\u20144:3"]
["long", "Job-Ps", "Job\u2014Psalms"]
["long", "Job.21-Ps", "Job 21\u2014Psalm 150"]
["long", "Job.21-Ps.2", "Job 21\u2014Psalm 2"]
["long", "Job.21-Ps.2:4", "Job 21\u2014Psalm 2:4"]
["long", "Ps-Prov", "Psalms\u2014Proverbs"]
["shorter", "Ps-Prov", "Ps\u2014Pr"]
["long", "Ps.21-Prov", "Psalm 21\u2014Proverbs 31"]
["long", "Ps.21-Prov.2", "Psalm 21\u2014Proverbs 2"]
["long", "Ps.21-Prov.2.4", "Psalm 21:1\u2014Proverbs 2:4"]
["long", "Gen-Rev", "Genesis\u2014Revelation"]
["long", "Gen-Rev.22", "Genesis 1\u2014Revelation 22"]
["long", "Gen-Rev.22.21", "Genesis 1:1\u2014Revelation 22:21"]
["long", "Gen.1-Rev", "Genesis 1\u2014Revelation 22"]
["short", "Gen.1.1-Rev", "Gen 1:1\u2014Rev 22:21"]
["shorter", "Phlm.1.1", "Phm 1:1"]
["shorter", "Phlm.1.2", "Phm 2"]
["shorter", "Phlm.1.1-Phlm.1.2", "Phm 1\u20132"]
["shorter", "Phlm.1.3-Phlm.1.4", "Phm 3\u20134"]
["shorter", "Phlm.1.1-Heb.4.5", "Phm 1\u2014Heb 4:5"]
["shorter", "Phlm.1.2-Heb.4.5", "Phm 2\u2014Heb 4:5"]
["shorter", "Phlm.1.1-Heb.4", "Phm 1\u2014Heb 4:16"]
["shorter", "Phlm.1.2-Heb.4", "Phm 2\u2014Heb 4:16"]
["shorter", "Phlm.1.1-Heb", "Phm 1\u2014Heb 13:25"]
["shorter", "Phlm.1.2-Heb", "Phm 2\u2014Heb 13:25"]
["shorter", "Phlm-Heb", "Phm\u2014Heb"]
["shorter", "Phlm-Heb.6", "Phm 1\u2014Heb 6"]
["shorter", "Phlm-Heb.6.8", "Phm 1\u2014Heb 6:8"]
["shorter", "Phlm.1-Heb", "Phm 1\u2014Heb 13"]
["shorter", "Phlm.1-Heb.6", "Phm 1\u2014Heb 6"]
["shorter", "Phlm.1-Heb.6.8", "Phm 1\u2014Heb 6:8"]
["shorter", "Obad-Phlm", "Ob\u2014Phm"]
["shorter", "Obad-Phlm.1", "Ob 1\u2014Phm 1"]
["shorter", "Obad-Phlm.1.1", "Ob 1\u2014Phm 1:1"]
["shorter", "Obad-Phlm.1.2", "Ob 1\u2014Phm 2"]
["shorter", "Obad.1-Phlm", "Ob 1\u2014Phm 1"]
["shorter", "Obad.1-Phlm.1.1", "Ob 1\u2014Phm 1:1"]
["shorter", "Obad.1-Phlm.1.2", "Ob 1\u2014Phm 2"]
["shorter", "Obad.1.1-Phlm", "Ob 1\u2014Phm 25"]
["shorter", "Obad.1.1-Phlm.1", "Ob 1\u2014Phm 25"]
["shorter", "Obad.1.1-Phlm.1.1", "Ob 1\u2014Phm 1:1"]
["shorter", "Obad.1.1-Phlm.1.2", "Ob 1\u2014Phm 2"]
["shorter", "Obad.1.2-Phlm", "Ob 2\u2014Phm 25"]
["shorter", "Obad.1.2-Phlm.1", "Ob 2\u2014Phm 25"]
["shorter", "Obad.1.2-Phlm.1.1", "Ob 2\u2014Phm 1:1"]
["shorter", "Obad.1.2-Phlm.1.2", "Ob 2\u2014Phm 2"]
]
for test in tests
[output_type, in_osis, expected] = test
readable = osis_to_readable(output_type, in_osis)
#check_osis = bcv.parse(in_osis).osis()
#out_osis = bcv.parse(readable).osis()
if expected isnt readable
console.log in_osis, "expected", expected, "got", readable
#if out_osis isnt check_osis
# console.log readable, "/", in_osis, "expected", check_osis, "got", out_osis
This script has been very helpful. Thank you. However when testing 1Cor.1.3-1Cor.1.10
it returns 1 Corinthians 3-10
.
I believe I have found the issue. In the method is_single_chapter_book
[start, end] = osis.split "-"
should be changed to [start, end] = osis.split "."
When I take the code above and run osis_to_readable("long", "1Cor.1.3-1Cor.1.10")
, it returns 1 Corinthians 1:3-10
for me. Your second comment suggests that maybe you're not using osis_compaction_strategy: "bcv"
?
The is_single_chapter_book
function basically checks whether, say, "1Cor 2" is a chapter (and thus has more than one chapter) or a verse, assuming that the "bcv" osis_compaction_strategy
will return a range if it's a chapter. You could achieve the same result by split
ting on the .
and seeing whether the second element returned is equal to 1
(single-chapter book) or 2
(multi-chapter book). Then the function wouldn't rely on a specific osis_compaction_strategy
.
How would I not be using the _osis_compactionstrategy: "bcv" if I am passing in a valid osis reference? I am using the same method with parameters osis_to_readable("long", "1Cor.1.3-1Cor.1.10")
when testing the reference. Thank you for your time & code!
Here's the relevant line in the above code:
bcv.set_options osis_compaction_strategy: "bcv", book_alone_strategy: "full", book_sequence_strategy: "include", consecutive_combination_strategy: "combine", book_range_strategy: "include"
The osis_compaction_strategy
controls the output from the bcv_parser
, not its input; it affects how specific you want the output to be. So, given the input "Gen 1-50", a b
strategy returns "Gen"; a "bc" strategy returns "Gen.1-Gen.50", and a "bcv" strategy returns "Gen.1.1-Gen.50.26". All are correct but are at varying levels of detail.
The above code uses "bcv" because "bcv" always returns a range if more than one verse is involved, which is convenient for several of the functions. The default is "b", which assumes you want the shortest available osis that can represent the input.
The above code also assumes that the other options are set as above; the output of osis_to_readable
might be unexpected if they're set differently. Hope that helps!
For future readers of this topic, I've since created a repo that converts from OSIS to a human-readable format: https://github.com/openbibleinfo/Bible-Reference-Formatter
Is there a method available on the OSIS to give it back in a human readable format?
For example:
'1Cor.2.5' => '1 Corinthians 2:5'