Current section
Files
Jump to
Current section
Files
lib/librarian.ex
defmodule BibleEx.Librarian do
@moduledoc false
require Logger
alias BibleEx.BibleData
@doc ~S"""
Returns the book number from a string.
"""
def find_book_number(book: book) do
book_lower = String.downcase(book)
cond do
book_lower == "" ->
nil
BibleData.books()[book_lower] ->
BibleData.books()[book_lower]
BibleData.osis_books()[book_lower] ->
BibleData.osis_books()[book_lower]
BibleData.shortened_books()[book_lower] ->
BibleData.shortened_books()[book_lower]
BibleData.variants()[book_lower] ->
BibleData.variants()[book_lower]
true ->
nil
end
end
# Validate that a book is in the bible, does not validate mispellings.
def check_book(book: book) do
book_lower = String.downcase(book)
Map.has_key?(BibleData.books(), book_lower) ||
Map.has_key?(BibleData.osis_books(), book_lower) ||
Map.has_key?(BibleData.shortened_books(), book_lower)
end
# Returns the osis, abbr, name, and short versions of a book title.
def get_book_names(book: book) do
found_book =
case BibleEx.typeof(book) do
"binary" ->
find_book_number(book: book)
"number" ->
book
"nil" ->
nil
"atom" ->
nil
end
case found_book do
nil ->
%{}
found_book ->
# book_names = BibleData.book_names()
list = Enum.at(BibleData.book_names(), found_book - 1)
# list = Enum.at(book_names, found_book - 1)
Map.merge(%{}, %{
osis: Enum.at(list, 0),
abbr: Enum.at(list, 1),
name: Enum.at(list, 2),
short: Enum.at(list, 3)
})
end
end
# Gets the last verse number in a specified book or book or chapter.
def get_last_verse_number(book: book) do
get_last_verse_number(book: book, chapter: nil)
end
def get_last_verse_number(book: book, chapter: chapter) do
found_book =
case BibleEx.typeof(book) do
"binary" ->
find_book_number(book: book)
"number" ->
book
end
case found_book do
nil ->
nil
_found_book_not_nil ->
found_chapter =
case chapter do
nil ->
length(Enum.at(BibleData.last_verse(), found_book - 1))
found ->
found
end
if length(Enum.at(BibleData.last_verse(), found_book - 1)) < found_chapter ||
found_chapter < 1 do
nil
else
book = Enum.at(BibleData.last_verse(), found_book - 1)
Enum.at(book, found_chapter - 1)
end
end
end
def get_last_chapter_number(book: book) do
found_book =
case BibleEx.typeof(book) do
"binary" ->
find_book_number(book: book)
"number" ->
book
end
if found_book > BibleData.last_verse() do
nil
else
length(Enum.at(BibleData.last_verse(), found_book - 1))
end
end
def get_last_verse(book: book) do
get_last_verse(book: book, chapter: nil)
end
def get_last_verse(book: book, chapter: chapter) do
book_number =
case BibleEx.typeof(book) do
"binary" ->
find_book_number(book: book)
"number" ->
book
end
book_chapter =
case chapter do
nil ->
length(Enum.at(BibleData.last_verse(), book_number - 1))
chapter ->
chapter
end
book_names = get_book_names(book: book)
if is_nil(book_number) do
nil
else
case Map.get(book_names, :name, nil) do
nil ->
nil
book_name ->
BibleEx.Verse.new(
book: book_name,
chapter_number: book_chapter,
verse_number: get_last_verse_number(book: book_number, chapter: book_chapter)
)
end
end
end
def get_verses(book: book, chapter: chapter) do
get_verses(book: book, chapter: chapter, start_verse: nil, end_verse: nil)
end
def get_verses(book: book, chapter: chapter, start_verse: start_verse, end_verse: end_verse) do
book_number =
case BibleEx.typeof(book) do
"binary" ->
find_book_number(book: book)
"number" ->
book
end
if is_nil(book_number) do
nil
else
case chapter do
nil ->
nil
chapter ->
# check if chapter is out of range
start_verse =
if !is_nil(start_verse) do
start_verse
else
1
end
end_verse =
if !is_nil(end_verse) do
end_verse
else
BibleData.last_verse()
|> Enum.at(book_number - 1)
|> Enum.at(chapter - 1)
end
case start_verse > end_verse do
true ->
nil
false ->
case end_verse do
nil ->
nil
last_verse ->
book_names = get_book_names(book: book)
case Map.get(book_names, :name, nil) do
nil ->
nil
book_name ->
Enum.map(start_verse..last_verse, fn x ->
BibleEx.Verse.new(
book: book_name,
chapter_number: chapter,
verse_number: x
)
end)
end
end
end
end
end
end
# Returns a Chapter? object that corresponds to the
# last chapter within a book.
def get_last_chapter(book: book) do
found_book =
case BibleEx.typeof(book) do
"binary" ->
find_book_number(book: book)
"number" ->
book
end
if found_book > BibleData.last_verse() do
nil
else
book_names = get_book_names(book: book)
case Map.get(book_names, :name, nil) do
nil ->
nil
book_name ->
last_chapter = length(Enum.at(BibleData.last_verse(), found_book - 1))
BibleEx.Chapter.new(book: book_name, chapter_number: last_chapter)
end
end
end
def get_chapters(book: book) do
get_chapters(book: book, start_chapter: nil, end_chapter: nil)
end
def get_chapters(book: book, start_chapter: start_chapter) do
get_chapters(book: book, start_chapter: start_chapter, end_chapter: nil)
end
def get_chapters(book: book, start_chapter: start_chapter, end_chapter: end_chapter) do
found_book =
case BibleEx.typeof(book) do
"binary" ->
find_book_number(book: book)
"number" ->
book
end
if found_book > BibleData.last_verse() do
nil
else
book_names = get_book_names(book: book)
if is_nil(found_book) do
nil
else
case Map.get(book_names, :name, nil) do
nil ->
nil
book_name ->
case start_chapter > end_chapter do
true ->
nil
false ->
# if start_chapter is nil, start at beginning of book
start_chapter =
if is_nil(start_chapter) do
1
else
start_chapter
end
# if end_chapter is nil, use start chapter
end_chapter =
if is_nil(end_chapter) do
start_chapter
else
end_chapter
end
# if either are outside of range then bring them back to book limit
start_chapter =
if start_chapter < 1 do
1
else
start_chapter
end
end_chapter =
if end_chapter > length(Enum.at(BibleData.last_verse(), found_book - 1)) do
length(Enum.at(BibleData.last_verse(), found_book - 1))
else
end_chapter
end
Enum.map(start_chapter..end_chapter, fn x ->
BibleEx.Chapter.new(book: book_name, chapter_number: x)
end)
end
end
end
end
end
def identify_reference_type(book: book) do
identify_reference_type(
book: book,
start_chapter: nil,
start_verse: nil,
end_chapter: nil,
end_verse: nil
)
end
def identify_reference_type(
book: book,
start_chapter: start_chapter
) do
identify_reference_type(
book: book,
start_chapter: start_chapter,
start_verse: nil,
end_chapter: nil,
end_verse: nil
)
end
def identify_reference_type(
book: book,
start_chapter: start_chapter,
start_verse: start_verse
) do
identify_reference_type(
book: book,
start_chapter: start_chapter,
start_verse: start_verse,
end_chapter: nil,
end_verse: nil
)
end
def identify_reference_type(
book: book,
start_chapter: start_chapter,
start_verse: start_verse,
end_chapter: end_chapter
) do
identify_reference_type(
book: book,
start_chapter: start_chapter,
start_verse: start_verse,
end_chapter: end_chapter,
end_verse: nil
)
end
def identify_reference_type(
book: _book,
start_chapter: start_chapter,
start_verse: start_verse,
end_chapter: end_chapter,
end_verse: end_verse
) do
cond do
is_nil(start_chapter) and is_nil(end_chapter) ->
if !is_nil(start_verse) do
if !is_nil(end_verse) do
:verse_range
else
:verse
end
else
:book
end
!is_nil(start_chapter) and !is_nil(end_chapter) and start_chapter != end_chapter ->
:chapter_range
!is_nil(start_chapter) and (is_nil(end_chapter) or end_chapter == start_chapter) ->
if !is_nil(start_verse) do
if !is_nil(end_verse) do
:verse_range
else
:verse
end
else
:chapter
end
!is_nil(start_verse) and !is_nil(end_verse) ->
:verse_range
!is_nil(start_verse) ->
:verse
true ->
nil
end
end
def verify_reference(book: book) when not is_nil(book) do
verified = true
found_book =
case BibleEx.typeof(book) do
"binary" ->
find_book_number(book: book)
"number" ->
book
end
verified =
if !(found_book > 0 and length(BibleData.last_verse()) >= found_book) do
false
else
verified
end
verified
end
def verify_reference(book: book, start_chapter: start_chapter) when not is_nil(book) do
verified = true
found_book =
case BibleEx.typeof(book) do
"binary" ->
find_book_number(book: book)
"number" ->
book
end
verified =
if !(found_book > 0 and length(BibleData.last_verse()) >= found_book) do
false
else
verified
end
## if book is not verified at this point, short-circuit
verified =
case verified do
true ->
if !is_nil(start_chapter) do
books_last_verse = length(BibleData.last_verse() |> Enum.at(found_book - 1))
if !(start_chapter > 0 and books_last_verse >= start_chapter) do
false
else
verified
end
else
verified
end
false ->
false
end
verified
end
def verify_reference(book: book, start_chapter: start_chapter, start_verse: start_verse)
when not is_nil(book) do
verified = true
found_book =
case BibleEx.typeof(book) do
"binary" ->
find_book_number(book: book)
"number" ->
book
end
verified =
if !(found_book > 0 and length(BibleData.last_verse()) >= found_book) do
false
else
verified
end
## if book is not verified at this point, short-circuit
verified =
case verified do
true ->
if !is_nil(start_chapter) do
books_last_verse = length(BibleData.last_verse() |> Enum.at(found_book - 1))
if !(start_chapter > 0 and books_last_verse >= start_chapter) do
false
else
verified
end
else
verified
end
false ->
false
end
# book is not in bible
verified =
if is_nil(found_book) do
false
else
case !is_nil(start_verse) do
true ->
if !is_nil(start_chapter) do
books_last_verse_books_start_chapter =
BibleData.last_verse()
|> Enum.at(found_book - 1)
|> Enum.at(start_chapter - 1)
if !(start_verse > 0 and
books_last_verse_books_start_chapter >= start_verse) do
false
else
verified
end
else
false
end
false ->
verified
end
end
verified
end
def verify_reference(book: book, start_chapter: start_chapter, end_verse: end_verse)
when not is_nil(book) do
verified = true
found_book =
case BibleEx.typeof(book) do
"binary" ->
find_book_number(book: book)
"number" ->
book
end
verified =
if !(found_book > 0 and length(BibleData.last_verse()) >= found_book) do
false
else
verified
end
## if book is not verified at this point, short-circuit
verified =
case verified do
true ->
if !is_nil(start_chapter) do
books_last_verse = length(BibleData.last_verse() |> Enum.at(found_book - 1))
if !(start_chapter > 0 and books_last_verse >= start_chapter) do
false
else
verified
end
else
verified
end
false ->
false
end
verified =
case !is_nil(end_verse) do
true ->
very_last_verse =
BibleData.last_verse()
|> Enum.at(found_book - 1)
|> Enum.at(start_chapter - 1)
if end_verse <= 0 or very_last_verse < end_verse do
false
else
verified
end
false ->
verified
end
verified
end
def verify_reference(
book: book,
start_chapter: _start_chapter,
start_verse: _start_verse,
end_chapter: _end_chapter
)
when not is_nil(book) do
## end_chapter alone is always a bad reference because the end_verse must be included
false
end
def verify_reference(
book: book,
start_chapter: start_chapter,
start_verse: start_verse,
end_chapter: end_chapter,
end_verse: end_verse
)
when not is_nil(book) do
verified = true
found_book =
case BibleEx.typeof(book) do
"binary" ->
find_book_number(book: book)
"number" ->
book
end
verified =
if !(found_book < 1 or (found_book > 0 and length(BibleData.last_verse()) >= found_book)) do
false
else
verified
end
verified =
if is_nil(found_book) do
false
else
if !is_nil(start_chapter) do
# books_last_verse = length(BibleData.last_verse()[found_book - 1])
books_last_verse = length(BibleData.last_verse() |> Enum.at(found_book - 1))
if !(start_chapter > 0 and books_last_verse >= start_chapter) do
false
else
verified
end
if !is_nil(end_chapter) and start_chapter > end_chapter do
false
else
verified
end
else
if !is_nil(end_chapter) or !is_nil(end_verse) do
false
else
verified
end
end
verified =
case !is_nil(start_verse) do
true ->
books_last_verse_books_start_chapter =
BibleData.last_verse()
|> Enum.at(found_book - 1)
|> Enum.at(start_chapter - 1)
if !(start_verse > 0 and books_last_verse_books_start_chapter >= start_verse) do
false
else
verified
end
if !is_nil(end_verse) and !is_nil(start_verse) do
if start_verse > end_verse do
false
else
verified
end
else
verified
end
false ->
verified
end
verified =
case !is_nil(end_chapter) do
true ->
books_last_verse = length(BibleData.last_verse() |> Enum.at(found_book - 1))
if !(books_last_verse >= end_chapter) do
false
else
verified
end
false ->
verified
end
verified =
case !is_nil(end_verse) do
true ->
if is_nil(end_chapter) do
false
else
very_last_verse =
BibleData.last_verse()
|> Enum.at(found_book - 1)
|> Enum.at(end_chapter - 1)
if end_verse > 0 and
very_last_verse >= end_verse do
verified
else
if end_verse < start_verse do
false
else
verified
end
end
end
false ->
verified
end
verified
end
verified
end
def create_reference_string(book: _book) do
nil
end
def create_reference_string(book: book, start_chapter: start_chapter) do
reference = ""
reference =
case !is_nil(book) and !is_nil(start_chapter) do
true ->
reference <> book <> " #{start_chapter}"
false ->
reference
end
if(reference == "", do: nil, else: reference)
end
def create_reference_string(book: book, start_chapter: start_chapter, start_verse: start_verse) do
reference = ""
reference =
case !is_nil(book) and !is_nil(start_chapter) do
true ->
reference = reference <> book <> " #{start_chapter}"
case !is_nil(start_verse) do
true ->
reference <> ":#{start_verse}"
false ->
reference
end
false ->
reference
end
if(reference == "", do: nil, else: reference)
end
def create_reference_string(
book: book,
start_chapter: start_chapter,
start_verse: start_verse,
end_chapter: end_chapter
) do
reference = ""
reference =
case !is_nil(book) and !is_nil(start_chapter) do
true ->
reference = reference <> book <> " #{start_chapter}"
if !is_nil(start_verse) and !is_nil(end_chapter) and end_chapter != start_chapter do
# true ->
reference = reference <> ":#{start_verse}"
reference = reference <> " - #{end_chapter}"
end_chapter_last_verse = get_last_verse_number(book: book, chapter: end_chapter)
if !is_nil(end_chapter_last_verse) do
reference = reference <> ":#{end_chapter_last_verse}"
reference
else
reference
end
# if !is_nil(end)
else
reference =
if !is_nil(end_chapter) and end_chapter != start_chapter do
reference = reference <> "-#{end_chapter}"
reference
else
reference
end
reference
end
false ->
reference
end
if(reference == "", do: nil, else: reference)
end
def create_reference_string(
book: book,
start_chapter: start_chapter,
start_verse: start_verse,
end_chapter: end_chapter,
end_verse: end_verse
) do
reference = ""
reference =
case !is_nil(book) and !is_nil(start_chapter) do
true ->
reference = reference <> book <> " #{start_chapter}"
if !is_nil(start_verse) and !is_nil(end_chapter) and end_chapter != start_chapter do
# true ->
reference = reference <> ":#{start_verse}"
reference = reference <> " - #{end_chapter}"
if !is_nil(end_verse) do
reference = reference <> ":#{end_verse}"
reference
else
end_chapter_last_verse = get_last_verse_number(book: book, chapter: end_chapter)
if !is_nil(end_chapter_last_verse) do
reference = reference <> ":#{end_chapter_last_verse}"
reference
else
reference
end
end
# if !is_nil(end)
else
reference =
if !is_nil(end_verse) and is_nil(start_verse) do
reference = reference <> ":1"
reference
else
if !is_nil(start_verse) do
reference = reference <> ":#{start_verse}"
reference
else
reference
end
end
reference =
if !is_nil(end_chapter) do
reference =
if is_nil(start_verse) and is_nil(end_verse) do
# when only rendering chapter range
# when it's the same chapter, do not show range
reference =
if start_chapter != end_chapter do
reference <> "-#{end_chapter}"
else
reference
end
reference
else
# when rendering chapter:verse - chapter:verse range
if start_chapter != end_chapter do
reference <> " - #{end_chapter}"
else
reference
end
reference
end
reference
else
reference
end
reference =
if !is_nil(end_verse) do
reference =
if !is_nil(start_verse) do
reference <> "-#{end_verse}"
else
if !is_nil(end_chapter) do
reference <> " - #{end_chapter}:#{end_verse}"
else
reference <> ":#{end_verse}"
end
end
# reference = reference <> ":1"
reference
else
reference
end
reference
end
false ->
reference =
if is_nil(start_chapter) and is_nil(start_verse) do
book
else
reference
end
reference
end
if(reference == "", do: nil, else: reference)
end
end