README.md

# BibleEx

This is a port of the Dart package https://github.com/joshpetit/reference_parser to Elixir.

An Elixir package that parses strings for bible references. You can parse single references or multiple references from a string in a variety of formats.

Really 99% of what you need to know will be found in 
[Parsing References](#parsing-references)
headers. But if you have more complicated needs this package can handle those!

<!-- toc -->
- [Usage](#usage)
  * [Parsing References](#parsing-references)
  * [Objects and References](#objects-and-references)
    + [Reference](#reference)
    + [Verses](#verses)
    + [Chapters](#chapters)
    + [Books](#books)
  * [Constructing References](#constructing-references)
    + [Invalid References](#invalid-references)
<!-- tocstop -->

# Usage

to include this in your Swift application:
```elixir
import BibleEx
```

## Parsing References
use the `parse_references` function to retrieve a single reference:

```elixir
alias BibleEx.RefParser
refs = RefParser.parse_references("I like Mat 2:4-10 and 1john 3:16")
```
This will return two reference objects, one describing "Matthew 2:4-10" and the other "1 John 3:16"

**Note**: The word 'is' will be parsed as the book of Isaiah.
```
[
  %BibleEx.Reference{
    book: "Matthew",
    book_names: %{abbr: "MAT", name: "Matthew", osis: "Matt", short: "Mt"},
    book_number: 40,
    reference: "Matthew 2:4-10",
    reference_type: :verse_range,
    start_chapter: %BibleEx.Chapter{
      ...
    }
  ...
  },
  %BibleEx.Reference{
  book: "1 John",
  book_names: %{abbr: "1JO", name: "1 John", osis: "1John", short: "1 Jn"},
  book_number: 62,
  reference: "1 John 3:16",
  reference_type: :verse,
  start_chapter: %BibleEx.Chapter{
    ...
  }
  ...
]

```

## Objects and References

### Reference
Reference objects are the broadest kind of reference.
You can directly construct one by following this format:

```elixir
genesis_ref = Reference.new(book: "Genesis", start_chapter: 2, start_verse: 3, end_chapter: 4, end_verse: 5)
```
```
%BibleEx.Reference{
  book: "Genesis",
  book_names: %{abbr: "GEN", name: "Genesis", osis: "Gen", short: "Gn"},
  book_number: 1,
  reference: "Genesis 2:3 - 4:5",
  reference_type: :chapter_range,
  start_chapter: %BibleEx.Chapter{
    ...
  }
}
```


Their most important fields are these:
```elixir
genesis_ref.reference # The string representation (osis_reference, short_reference, and abbr also available)
genesis_ref.start_verse_number
genesis_ref.end_verse_number
genesis_ref.start_chapter_number
genesis_ref.end_chapter_number
genesis_ref.reference_type # :verse, :chapter, :verse_range, :chapter_range, :book
```
Based on what is passed in, the constructor will figure out
certain fields. For example, if you were to construct `Reference('James')`
the last chapter and verse numbers in James will be initialized accordingly.

There are many other fields that may prove useful such as 
ones that subdivid the reference, look [here](#other-fun stuff)

-------

### Verses

`Reference` objects have a `start_verse` and `end_verse` field
that return objects of the Verse type.
```elixir
genbook = Reference.new(book: "Genesis")
first_verse = genbook.start_verse;

# same as first_verse above
first = Verse(book: "Genesis", chapter_number: 1, verse_number: 1)

%BibleEx.Verse{
  book: "Genesis",
  book_names: %{abbr: "GEN", name: "Genesis", osis: "Gen", short: "Gn"},
  book_number: 1,
  reference_type: :verse,
  reference: "Genesis 1:1",
  chapter_number: 1,
  verse_number: 1,
  is_valid: true
}
```

You can also construct `Reference`s that 'act' like
verses by using the named constructor
```elixir
gen_11 = Reference.verse(book: "Genesis", chapter: 1, verse: 1)

%BibleEx.Reference{
  book: "Genesis",
  book_names: %{abbr: "GEN", name: "Genesis", osis: "Gen", short: "Gn"},
  book_number: 1,
  reference: "Genesis 1:1",
  reference_type: :verse,
  start_chapter: %BibleEx.Chapter{
    ...
  }
  ...
}
```

------

### Chapters
```elixir
james5 = RefParser.parse_references("James 5 is a chapter") |> List.first()
```
The `james5` object now holds a `Reference` to "James 5". Despite this, start_verse_number and end_verse_number are initialized to the first and last verses in James 5. 
```elixir
james5.start_verse_number # 1
james5.end_verse_number # 20
james5.reference_type # :chapter
```

The Reference object also has start/end chapter fields
```elixir
james510 = RefParser.parse_references("James 5-10 is cool") |> List.first()
james510.start_chapter_number # 5
james510.end_chapter_number # 10
```

Just like verses you can create chapter objects:

```elixir
john1 = Chapter.new(book: "John", chapter_number: 1)
```
------

### Books
```elixir
ecc = RefParser.parse_references("Ecclesiastes is hard to spell") |> List.first()
ecc.start_chapter_number # 1
ecc.end_chapter_number # 12
ecc.reference_type # :chapter_range
```
Books are the equivalent of a `Reference` object.

## Constructing References

### Verses
```elixir
matt24 = Reference.new(book: "Mat", start_chapter: 2, start_verse: 4)
matt24 = Reference.verse(book: "Mat", chapter: 2, verse: 4)
matt24 = Verse.new(book: "Matt", chapter_number: 2, verse_number: 4)
```

Note that the `verse` object has different fields than a
`Reference` object. Check the API.

### Verse Ranges
```elixir
matt2410 = Reference.new(book: "Mat", start_chapter: 2, start_verse: 4, end_chapter: nil, end_verse: 10)
matt2410 = Reference.verse_range(book: "Mat", chapter: 2, start_verse: 4, end_verse: 10)
```
These are equivalents that create a reference to 'Matthew 2:4-10'.

### Invalid References
All references have an `is_valid` field that says whether this reference
is within the bible.

```elixir
mcd = Reference.new(book: "McDonald", start_chapter: 2, start_verse: 4, end_chapter: 10)
print(mcd.is_valid) # false, as far as I know at least.
```
**Notice that the other fields are still initialized!!** So if needed, make
sure to check that a reference is valid before using it.
```elixir
mcd.reference # "McDonald 2:4-10"
mcd.book # "McDonald"
mcd.start_verse_number # 4
mcd.osis_book # nil, and so will be other formats.
```

The same logic applies to chapters and verse numbers.
```elixir
jude2 = Reference.new(book: "Jude", start_chapter: 2, start_verse: 10)
jude2.is_valid # false (Jude only has one chapter)
```

## Installation

If [available in Hex](https://hex.pm/docs/publish), the package can be installed
by adding `bible_ex` to your list of dependencies in `mix.exs`:

```elixir
def deps do
  [
      {
        :bible_ex,
        git: "https://github.com/mazz/bible_ex.git", branch: "main"
      }
  ]
end
```

Documentation can be generated with [ExDoc](https://github.com/elixir-lang/ex_doc)
and published on [HexDocs](https://hexdocs.pm). Once published, the docs can
be found at <https://hexdocs.pm/bible_ex>.