scripref 1.2.2 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Changelog +10 -0
- data/LICENSE +1 -1
- data/lib/scripref/basic_methods.rb +11 -5
- data/lib/scripref/bookname.rb +87 -9
- data/lib/scripref/bookorder.rb +36 -8
- data/lib/scripref/english.rb +76 -29
- data/lib/scripref/formatter.rb +7 -7
- data/lib/scripref/german.rb +76 -28
- data/lib/scripref/parser.rb +55 -54
- data/lib/scripref/passage.rb +3 -56
- data/lib/scripref/processor.rb +2 -0
- data/lib/scripref/sorter.rb +52 -0
- data/lib/scripref.rb +2 -1
- data/test/test_bookname.rb +13 -5
- data/test/test_english.rb +13 -13
- data/test/test_formatter.rb +3 -8
- data/test/test_german.rb +12 -12
- data/test/test_parser.rb +11 -0
- data/test/test_sorter.rb +48 -0
- metadata +3 -2
- data/test/test_passage.rb +0 -91
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 41762855bac59cfd4181dacab1ae3cb5d5fa879e08e841d60d9fbde5170a5f65
|
|
4
|
+
data.tar.gz: debe69c84f21f2d0af4e5ba88ddd8a0ee89c78ca449a4dc0ee302c593ecb46a0
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 40877991379c9c1d743fa68575fdc2de3d8f16984483e0b121aa306913f18f5c06af30cc0fee604ea8c2d9678989811388a8c2e12980a74ee7a390051da56345
|
|
7
|
+
data.tar.gz: b80cdba6be11573f7691913d8415a0c45874996e6050ef4f6fd91535006ffcffb2cdaa4e714b5ede4649b617abfb6a795c73b3b2d655420786fe78c574eec2f5
|
data/Changelog
CHANGED
|
@@ -1,3 +1,13 @@
|
|
|
1
|
+
2.0.0
|
|
2
|
+
Major release with following breaking changes:
|
|
3
|
+
Rewrite Bookorder and Bookname and adapt Formatter#format accordingly.
|
|
4
|
+
Remove Comparable mixin and depending methods from Passage and implement
|
|
5
|
+
Sorter instead.
|
|
6
|
+
Rename all osis_*_id names to book_id.
|
|
7
|
+
Rename OSIS_BOOK_ID_TO_BOOK_NAME -> BOOKNAMES_HASH
|
|
8
|
+
|
|
9
|
+
Further: Implement a lot of internal optimizations.
|
|
10
|
+
|
|
1
11
|
1.2.2
|
|
2
12
|
Extend German abbreviations.
|
|
3
13
|
|
data/LICENSE
CHANGED
|
@@ -18,17 +18,23 @@ module Scripref
|
|
|
18
18
|
NUMBER_RE
|
|
19
19
|
end
|
|
20
20
|
|
|
21
|
-
# Regular expression to match a book
|
|
21
|
+
# Regular expression to match a book
|
|
22
22
|
def book_re
|
|
23
23
|
return @book_re if @book_re
|
|
24
|
-
books_res_as_strings =
|
|
25
|
-
|
|
26
|
-
|
|
24
|
+
books_res_as_strings = []
|
|
25
|
+
each_bookname do |bn|
|
|
26
|
+
bn.each_name do |n|
|
|
27
|
+
books_res_as_strings << (n.gsub(/([^\dA-Z])/, '\1?').gsub('.', '\.'))
|
|
27
28
|
end
|
|
28
|
-
end
|
|
29
|
+
end
|
|
29
30
|
@book_re = Regexp.compile(books_res_as_strings.map {|s| '(\b' << s << '\b\.?\s*)' }.join('|'), nil)
|
|
30
31
|
end
|
|
31
32
|
|
|
33
|
+
# Enumerator over booknames
|
|
34
|
+
def each_bookname &blk
|
|
35
|
+
booknames_hash.each_value(&blk)
|
|
36
|
+
end
|
|
37
|
+
|
|
32
38
|
end
|
|
33
39
|
|
|
34
40
|
end
|
data/lib/scripref/bookname.rb
CHANGED
|
@@ -5,28 +5,106 @@ module Scripref
|
|
|
5
5
|
|
|
6
6
|
class Bookname
|
|
7
7
|
|
|
8
|
-
attr_reader :
|
|
8
|
+
attr_reader :book_id
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
10
|
+
# @param book_id OSID-ID of the book
|
|
11
|
+
# @param name full name of the book
|
|
12
|
+
# @param abbrevs possible abbreviations for the book
|
|
13
|
+
# @param alternatives further Bookname instances with alternative names and abbreviations for book
|
|
14
|
+
def initialize book_id:, name:, abbrevs: [], alternatives: []
|
|
15
|
+
@book_id = book_id
|
|
16
|
+
@name = name
|
|
13
17
|
@abbrevs = Array(abbrevs)
|
|
18
|
+
@alternatives = Array(alternatives)
|
|
14
19
|
end
|
|
15
20
|
|
|
16
|
-
|
|
17
|
-
|
|
21
|
+
# Format the bookname (full name or abbreviation)
|
|
22
|
+
# @param abbrev_level if 0 full name, if >0 an abbreviation
|
|
23
|
+
def format abbrev_level: 0
|
|
24
|
+
case
|
|
25
|
+
when abbrev_level == 0
|
|
26
|
+
@name
|
|
27
|
+
when abbrev_level > 0
|
|
28
|
+
@abbrevs[abbrev_level - 1] || @abbrevs[-1] || @name
|
|
29
|
+
else
|
|
30
|
+
fail ArgumentError, 'negative values for abbrev_level are not allowed'
|
|
31
|
+
end
|
|
18
32
|
end
|
|
19
33
|
|
|
20
|
-
|
|
21
|
-
|
|
34
|
+
# Enumerator over all names (name and name of alternatives)
|
|
35
|
+
def each_name
|
|
36
|
+
if block_given?
|
|
37
|
+
yield @name
|
|
38
|
+
@alternatives.each do |bn|
|
|
39
|
+
bn.each_name do |alt_name|
|
|
40
|
+
yield alt_name
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
else
|
|
44
|
+
enum_for :each_name
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
# Enumerator over all names and abbreviations (including alternatives)
|
|
49
|
+
def each_string
|
|
50
|
+
if block_given?
|
|
51
|
+
yield @name
|
|
52
|
+
@abbrevs.each do |a|
|
|
53
|
+
yield a
|
|
54
|
+
end
|
|
55
|
+
@alternatives.each do |bn|
|
|
56
|
+
bn.each_string do |s|
|
|
57
|
+
yield s
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
else
|
|
61
|
+
enum_for :each_string
|
|
62
|
+
end
|
|
22
63
|
end
|
|
23
64
|
|
|
24
65
|
def to_s
|
|
25
|
-
@
|
|
66
|
+
@name
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
# Convert the instance to an equivalent string representation
|
|
70
|
+
def dump
|
|
71
|
+
s = Kernel.format('%s: %s', @book_id, [@name, @abbrevs].flatten.join('|'))
|
|
72
|
+
[s, @alternatives.map(&:dump).map {|s| s.sub(/^.+?: /, '')}].flatten.join(', ')
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def inspect
|
|
76
|
+
Kernel.format('#<%s %s>', self.class, dump.inspect)
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def == other
|
|
80
|
+
other.respond_to?(:dump) && dump == other.dump
|
|
26
81
|
end
|
|
27
82
|
|
|
28
83
|
alias to_str to_s
|
|
29
84
|
|
|
85
|
+
class << self
|
|
86
|
+
|
|
87
|
+
# Helper method to create Bookname instances from a String
|
|
88
|
+
# @param s string to parse
|
|
89
|
+
# format: [book_id]: [full name]|[abbrev1]|[abbrev2]|...(, [alternative name]|[abbrev1],...]*
|
|
90
|
+
# @example Format
|
|
91
|
+
# Zeph: Zefanja|Zef, Zephanja|Zeph
|
|
92
|
+
# @example Code equivalent
|
|
93
|
+
# Bookname.new(book_id: :Zeph, name: 'Zefanja', abbrevs: ['Zef'], alternatives: Bookname.new(book_id: :Zeph, name: 'Zephanja', abbrevs: ['Zeph']))
|
|
94
|
+
def parse s
|
|
95
|
+
book_id, rest = s.split(/:\s*/).map(&:strip)
|
|
96
|
+
book_id = book_id.to_sym
|
|
97
|
+
org, *alternatives = rest.split(/,\s*/).map(&:strip)
|
|
98
|
+
name, *abbrevs = org.split('|').map(&:strip)
|
|
99
|
+
alternatives.map! do |s|
|
|
100
|
+
n, *a = s.split('|').map(&:strip)
|
|
101
|
+
Bookname.new(book_id: book_id, name: n, abbrevs: a)
|
|
102
|
+
end
|
|
103
|
+
Bookname.new(book_id: book_id, name: name, abbrevs: abbrevs, alternatives: alternatives)
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
end
|
|
107
|
+
|
|
30
108
|
end
|
|
31
109
|
|
|
32
110
|
end
|
data/lib/scripref/bookorder.rb
CHANGED
|
@@ -3,18 +3,46 @@
|
|
|
3
3
|
|
|
4
4
|
module Scripref
|
|
5
5
|
|
|
6
|
-
#
|
|
6
|
+
# Module to handle differend orderings of bible books using standardized IDs
|
|
7
7
|
# (see https://wiki.crosswire.org/OSIS_Book_Abbreviations)
|
|
8
8
|
module Bookorder
|
|
9
9
|
|
|
10
10
|
# Canonical order (the default order without any apocryphal books)
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
11
|
+
module Canonical
|
|
12
|
+
|
|
13
|
+
BOOK_IDS = %i[
|
|
14
|
+
Gen Exod Lev Num Deut Josh Judg Ruth 1Sam 2Sam 1Kgs 2Kgs 1Chr 2Chr Ezra
|
|
15
|
+
Neh Esth Job Ps Prov Eccl Song Isa Jer Lam Ezek Dan Hos Joel Amos Obad
|
|
16
|
+
Jonah Mic Nah Hab Zeph Hag Zech Mal Matt Mark Luke John Acts Rom 1Cor
|
|
17
|
+
2Cor Gal Eph Phil Col 1Thess 2Thess 1Tim 2Tim Titus Phlm Heb Jas 1Pet
|
|
18
|
+
2Pet 1John 2John 3John Jude Rev
|
|
19
|
+
]
|
|
20
|
+
|
|
21
|
+
def book2num book_id
|
|
22
|
+
@book2num ||= BOOK_IDS.zip(1..).to_h
|
|
23
|
+
@book2num[book_id]
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# Luther order (without any apocryphal books)
|
|
29
|
+
module Luther
|
|
30
|
+
|
|
31
|
+
BOOK_IDS = %i[
|
|
32
|
+
Gen Exod Lev Num Deut Josh Judg Ruth 1Sam 2Sam 1Kgs 2Kgs 1Chr 2Chr Ezra
|
|
33
|
+
Neh Esth Job Ps Prov Eccl Song Isa Jer Lam Ezek Dan Hos Joel Amos Obad
|
|
34
|
+
Jonah Mic Nah Hab Zeph Hag Zech Mal Matt Mark Luke John Acts Rom 1Cor
|
|
35
|
+
2Cor Gal Eph Phil Col 1Thess 2Thess 1Tim 2Tim Titus Phlm 1Pet 2Pet 1John
|
|
36
|
+
2John 3John Heb Jas Jude Rev
|
|
37
|
+
]
|
|
38
|
+
|
|
39
|
+
def book2num book_id
|
|
40
|
+
@book2num ||= BOOK_IDS.zip(1..).to_h
|
|
41
|
+
@book2num[book_id]
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
end
|
|
45
|
+
|
|
18
46
|
end
|
|
19
47
|
|
|
20
48
|
end
|
data/lib/scripref/english.rb
CHANGED
|
@@ -8,34 +8,81 @@ module Scripref
|
|
|
8
8
|
# Mixin for parsing references in English.
|
|
9
9
|
module English
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
Genesis
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
1
|
|
21
|
-
|
|
22
|
-
|
|
11
|
+
booknames = <<-END
|
|
12
|
+
Gen: Genesis|Gen
|
|
13
|
+
Exod: Exodus|Ex
|
|
14
|
+
Lev: Leviticus|Lev
|
|
15
|
+
Num: Numbers|Num
|
|
16
|
+
Deut: Deuteronomy|Deut
|
|
17
|
+
Josh: Joshua|Josh
|
|
18
|
+
Judg: Judges|Judg
|
|
19
|
+
Ruth: Ruth|Rth
|
|
20
|
+
1Sam: 1 Samuel|1 Sam
|
|
21
|
+
2Sam: 2 Samuel|2 Sam
|
|
22
|
+
1Kgs: 1 Kings|1 Kgs
|
|
23
|
+
2Kgs: 2 Kings|2 Kgs
|
|
24
|
+
1Chr: 1 Chronicles|1 Chron
|
|
25
|
+
2Chr: 2 Chronicles|2 Chron
|
|
26
|
+
Ezra: Ezra|Ezr
|
|
27
|
+
Neh: Nehemiah|Neh
|
|
28
|
+
Esth: Esther|Esth
|
|
29
|
+
Job: Job|Job
|
|
30
|
+
Ps: Psalms|Ps
|
|
31
|
+
Prov: Proverbs|Prov
|
|
32
|
+
Eccl: Ecclesiastes|Eccles
|
|
33
|
+
Song: Song of Songs|Song
|
|
34
|
+
Isa: Isaiah|Isa
|
|
35
|
+
Jer: Jeremiah|Jer
|
|
36
|
+
Lam: Lamentations|Lam
|
|
37
|
+
Ezek: Ezekiel|Ezek
|
|
38
|
+
Dan: Daniel|Dan
|
|
39
|
+
Hos: Hosea|Hos
|
|
40
|
+
Joel: Joel|Joel
|
|
41
|
+
Amos: Amos|Am
|
|
42
|
+
Obad: Obadiah|Obad
|
|
43
|
+
Jonah: Jonah|Jon
|
|
44
|
+
Mic: Micah|Mic
|
|
45
|
+
Nah: Nahum|Nah
|
|
46
|
+
Hab: Habakkuk|Hab
|
|
47
|
+
Zeph: Zephaniah|Zeph
|
|
48
|
+
Hag: Haggai|Hag
|
|
49
|
+
Zech: Zechariah|Zech
|
|
50
|
+
Mal: Malachi|Mal
|
|
51
|
+
Matt: Matthew|Matt
|
|
52
|
+
Mark: Mark|Mrk
|
|
53
|
+
Luke: Luke|Luk
|
|
54
|
+
John: John|John
|
|
55
|
+
Acts: Acts|Acts
|
|
56
|
+
Rom: Romans|Rom
|
|
57
|
+
1Cor: 1 Corinthians|1 Cor
|
|
58
|
+
2Cor: 2 Corinthians|2 Cor
|
|
59
|
+
Gal: Galatians|Gal
|
|
60
|
+
Eph: Ephesians|Eph
|
|
61
|
+
Phil: Philippians|Phil
|
|
62
|
+
Col: Colossians|Col
|
|
63
|
+
1Thess: 1 Thessalonians|1 Thess
|
|
64
|
+
2Thess: 2 Thessalonians|2 Thess
|
|
65
|
+
1Tim: 1 Timothy|1 Tim
|
|
66
|
+
2Tim: 2 Timothy|2 Tim
|
|
67
|
+
Titus: Titus|Tit
|
|
68
|
+
Phlm: Philemon|Philem
|
|
69
|
+
Heb: Hebrews|Heb
|
|
70
|
+
Jas: James|Jas
|
|
71
|
+
1Pet: 1 Peter|1 Pet
|
|
72
|
+
2Pet: 2 Peter|2 Pet
|
|
73
|
+
1John: 1 John|1 Joh
|
|
74
|
+
2John: 2 John|2 Joh
|
|
75
|
+
3John: 3 John|3 Joh
|
|
76
|
+
Jude: Jude|Jud
|
|
77
|
+
Rev: Revelation|Rev
|
|
23
78
|
END
|
|
24
79
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
1 Joh, 2 Joh, 3 Joh, Jud, Rev
|
|
32
|
-
END
|
|
33
|
-
|
|
34
|
-
# Array of book names.
|
|
35
|
-
BOOK_NAMES = Bookorder::CANONICAL.zip(book_names, book_abbrevs).map {|osis_book_id, names, abbrevs| Bookname.new(osis_id: osis_book_id, names: names, abbrevs: abbrevs)}
|
|
36
|
-
|
|
37
|
-
# Map of OSIS book ID to instance of Bookname
|
|
38
|
-
OSIS_BOOK_ID_TO_BOOK_NAME = Bookorder::CANONICAL.zip(BOOK_NAMES).map {|id, n| [id, n]}.to_h
|
|
80
|
+
# Mapping of OSIS book ID to instance of Bookname
|
|
81
|
+
BOOKNAMES_HASH = {}
|
|
82
|
+
booknames.each_line do |l|
|
|
83
|
+
bn = Bookname.parse(l)
|
|
84
|
+
BOOKNAMES_HASH[bn.book_id] = bn
|
|
85
|
+
end
|
|
39
86
|
|
|
40
87
|
# Separator between chapter and verse.
|
|
41
88
|
CV_SEPARATOR = ':'
|
|
@@ -77,9 +124,9 @@ module Scripref
|
|
|
77
124
|
POSTFIX_MORE_FOLLOWING_VERSES_RE = /ff\b\s*/o
|
|
78
125
|
|
|
79
126
|
# Check if book has only one chapter
|
|
80
|
-
# @param
|
|
81
|
-
def book_has_only_one_chapter?
|
|
82
|
-
%i[Obad Phlm 2John 3John Jude].include?(
|
|
127
|
+
# @param book_id OSIS-ID of the book
|
|
128
|
+
def book_has_only_one_chapter? book_id
|
|
129
|
+
%i[Obad Phlm 2John 3John Jude].include?(book_id)
|
|
83
130
|
end
|
|
84
131
|
|
|
85
132
|
# Regular expression to match punctuation marks
|
data/lib/scripref/formatter.rb
CHANGED
|
@@ -5,14 +5,14 @@ module Scripref
|
|
|
5
5
|
|
|
6
6
|
class Formatter
|
|
7
7
|
|
|
8
|
-
attr_accessor :
|
|
8
|
+
attr_accessor :abbrev_level, :cv_separator, :hyphen_separator, :pass_separator
|
|
9
9
|
|
|
10
10
|
# @param mods one or more modules to include
|
|
11
|
-
# @param
|
|
12
|
-
def initialize *mods,
|
|
11
|
+
# @param abbrev_level if 0 full name, if >0 an abbreviation
|
|
12
|
+
def initialize *mods, abbrev_level: 0
|
|
13
13
|
@mods = mods
|
|
14
14
|
mods.each {|m| extend m}
|
|
15
|
-
@
|
|
15
|
+
@abbrev_level = abbrev_level
|
|
16
16
|
end
|
|
17
17
|
|
|
18
18
|
# Formats a reference (array of passages and maybe separators)
|
|
@@ -28,9 +28,9 @@ module Scripref
|
|
|
28
28
|
end
|
|
29
29
|
|
|
30
30
|
# Formats a book
|
|
31
|
-
# @param
|
|
32
|
-
def format_book
|
|
33
|
-
|
|
31
|
+
# @param book_id OSIS-ID for book
|
|
32
|
+
def format_book book_id
|
|
33
|
+
booknames_hash[book_id].format(abbrev_level: abbrev_level)
|
|
34
34
|
end
|
|
35
35
|
|
|
36
36
|
# Formats a chapter
|
data/lib/scripref/german.rb
CHANGED
|
@@ -8,33 +8,81 @@ module Scripref
|
|
|
8
8
|
# Mixin for parsing references in German.
|
|
9
9
|
module German
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
1. Mose
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
11
|
+
booknames = <<-END
|
|
12
|
+
Gen: 1. Mose|1. Mos|1Mo|1M
|
|
13
|
+
Exod: 2. Mose|2. Mos|2Mo|2M
|
|
14
|
+
Lev: 3. Mose|3. Mos|3Mo|3M
|
|
15
|
+
Num: 4. Mose|4. Mos|4Mo|4M
|
|
16
|
+
Deut: 5. Mose|5. Mos|5Mo|5M
|
|
17
|
+
Josh: Josua|Jos
|
|
18
|
+
Judg: Richter|Ri
|
|
19
|
+
Ruth: Ruth|Ruth|Rt
|
|
20
|
+
1Sam: 1. Samuel|1. Sam|1Sam|1Sm
|
|
21
|
+
2Sam: 2. Samuel|2. Sam|2Sam|2Sm
|
|
22
|
+
1Kgs: 1. Könige|1. Kön|1Kön|1Kö
|
|
23
|
+
2Kgs: 2. Könige|2. Kön|2Kön|2Kö
|
|
24
|
+
1Chr: 1. Chronika|1. Chr|1Chr|1Ch
|
|
25
|
+
2Chr: 2. Chronika|2. Chr|2Chr|2Ch
|
|
26
|
+
Ezra: Esra|Esr
|
|
27
|
+
Neh: Nehemia|Neh
|
|
28
|
+
Esth: Esther|Est
|
|
29
|
+
Job: Hiob|Hi
|
|
30
|
+
Ps: Psalm|Ps, Psalmen
|
|
31
|
+
Prov: Sprüche|Spr
|
|
32
|
+
Eccl: Prediger|Pred
|
|
33
|
+
Song: Hohelied|Hohel|Hoh|Hl
|
|
34
|
+
Isa: Jesaja|Jes
|
|
35
|
+
Jer: Jeremia|Jer
|
|
36
|
+
Lam: Klagelieder|Klag
|
|
37
|
+
Ezek: Hesekiel|Hes
|
|
38
|
+
Dan: Daniel|Dan
|
|
39
|
+
Hos: Hosea|Hos
|
|
40
|
+
Joel: Joel|Joel
|
|
41
|
+
Amos: Amos|Amos|Am
|
|
42
|
+
Obad: Obadja|Obad|Ob
|
|
43
|
+
Jonah: Jona|Jona|Jon
|
|
44
|
+
Mic: Micha|Mich|Mi
|
|
45
|
+
Nah: Nahum|Nah
|
|
46
|
+
Hab: Habakuk|Hab
|
|
47
|
+
Zeph: Zefanja|Zef, Zephanja|Zeph
|
|
48
|
+
Hag: Haggai|Hag
|
|
49
|
+
Zech: Sacharja|Sach
|
|
50
|
+
Mal: Maleachi|Mal
|
|
51
|
+
Matt: Matthäus|Mat|Mt
|
|
52
|
+
Mark: Markus|Mar|Mr
|
|
53
|
+
Luke: Lukas|Luk|Lk
|
|
54
|
+
John: Johannes|Joh|Jh
|
|
55
|
+
Acts: Apostelgeschichte|Apg
|
|
56
|
+
Rom: Römer|Röm|Rö
|
|
57
|
+
1Cor: 1. Korinther|1. Kor|1Ko
|
|
58
|
+
2Cor: 2. Korinther|2. Kor|2Ko
|
|
59
|
+
Gal: Galater|Gal
|
|
60
|
+
Eph: Epheser|Eph
|
|
61
|
+
Phil: Philipper|Phil
|
|
62
|
+
Col: Kolosser|Kol
|
|
63
|
+
1Thess: 1. Thessalonicher|1. Thes|1.Thes|1Thes|1Th
|
|
64
|
+
2Thess: 2. Thessalonicher|2. Thes|2.Thes|2Thes|2Th
|
|
65
|
+
1Tim: 1. Timotheus|1. Tim|1Tim
|
|
66
|
+
2Tim: 2. Timotheus|2. Tim|2Tim
|
|
67
|
+
Titus: Titus|Tit
|
|
68
|
+
Phlm: Philemon|Philem|Phm
|
|
69
|
+
Heb: Hebräer|Heb
|
|
70
|
+
Jas: Jakobus|Jak
|
|
71
|
+
1Pet: 1. Petrus|1. Pet|1Pet|1Pe
|
|
72
|
+
2Pet: 2. Petrus|2. Pet|2Pet|2Pe
|
|
73
|
+
1John: 1. Johannes|1. Joh|1Joh|1Jo
|
|
74
|
+
2John: 2. Johannes|2. Joh|2Joh|2Jo
|
|
75
|
+
3John: 3. Johannes|3. Joh|3Joh|3Jo
|
|
76
|
+
Jude: Judas|Jud
|
|
77
|
+
Rev: Offenbarung|Off
|
|
20
78
|
END
|
|
21
79
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
Joh|Jh, Apg, Röm|Rö, 1. Kor|1Ko, 2. Kor|2Ko, Gal, Eph, Phil, Kol,
|
|
29
|
-
1. Thes|1.Thes|1Thes|1Th, 2. Thes|2.Thes|2Thes|2Th, 1. Tim|1Tim, 2. Tim|2Tim, Tit, Philem|Phm, Heb, Jak, 1. Pet|1Pet|1Pe, 2. Pet|2Pet|2Pe,
|
|
30
|
-
1. Joh|1Joh|1Jo, 2. Joh|2Joh|2Jo, 3. Joh|3Joh|3Jo, Jud, Off
|
|
31
|
-
END
|
|
32
|
-
|
|
33
|
-
# Array of book names.
|
|
34
|
-
BOOK_NAMES = Bookorder::CANONICAL.zip(book_names, book_abbrevs).map {|osis_book_id, names, abbrevs| Bookname.new(osis_id: osis_book_id, names: names, abbrevs: abbrevs)}
|
|
35
|
-
|
|
36
|
-
# Map of OSIS book ID to instance of Bookname
|
|
37
|
-
OSIS_BOOK_ID_TO_BOOK_NAME = Bookorder::CANONICAL.zip(BOOK_NAMES).map {|id, n| [id, n]}.to_h
|
|
80
|
+
# Mapping of OSIS book ID to instance of Bookname
|
|
81
|
+
BOOKNAMES_HASH = {}
|
|
82
|
+
booknames.each_line do |l|
|
|
83
|
+
bn = Bookname.parse(l)
|
|
84
|
+
BOOKNAMES_HASH[bn.book_id] = bn
|
|
85
|
+
end
|
|
38
86
|
|
|
39
87
|
# Separator between chapter and verse.
|
|
40
88
|
CV_SEPARATOR = ','
|
|
@@ -76,9 +124,9 @@ module Scripref
|
|
|
76
124
|
POSTFIX_MORE_FOLLOWING_VERSES_RE = /ff\b\s*/o
|
|
77
125
|
|
|
78
126
|
# Check if book has only one chapter
|
|
79
|
-
# @param
|
|
80
|
-
def book_has_only_one_chapter?
|
|
81
|
-
%i[Obad Phlm 2John 3John Jude].include?(
|
|
127
|
+
# @param book_id OSIS-ID of the book
|
|
128
|
+
def book_has_only_one_chapter? book_id
|
|
129
|
+
%i[Obad Phlm 2John 3John Jude].include?(book_id)
|
|
82
130
|
end
|
|
83
131
|
|
|
84
132
|
# Regular expression to match punctuation marks
|
data/lib/scripref/parser.rb
CHANGED
|
@@ -6,7 +6,7 @@ require 'strscan'
|
|
|
6
6
|
|
|
7
7
|
module Scripref
|
|
8
8
|
|
|
9
|
-
class Parser
|
|
9
|
+
class Parser
|
|
10
10
|
|
|
11
11
|
attr_reader :error
|
|
12
12
|
|
|
@@ -21,12 +21,28 @@ module Scripref
|
|
|
21
21
|
# Parsing a string of a scripture reference
|
|
22
22
|
# @param str string to parse
|
|
23
23
|
def parse str
|
|
24
|
-
|
|
24
|
+
@scanner = StringScanner.new(str)
|
|
25
25
|
@result = []
|
|
26
26
|
@error = nil
|
|
27
27
|
start
|
|
28
28
|
end
|
|
29
29
|
|
|
30
|
+
def format_error
|
|
31
|
+
if error
|
|
32
|
+
format("%s\n%s\n%s^", error, @scanner.string, ' ' * @scanner.pointer)
|
|
33
|
+
else
|
|
34
|
+
''
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def inspect
|
|
39
|
+
"#<#{self.class} #{@mods.inspect}>"
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
alias << parse
|
|
43
|
+
|
|
44
|
+
private
|
|
45
|
+
|
|
30
46
|
# start of parsing grammer
|
|
31
47
|
def start
|
|
32
48
|
@text = ''
|
|
@@ -35,14 +51,14 @@ module Scripref
|
|
|
35
51
|
|
|
36
52
|
# try to parse first book
|
|
37
53
|
def b1
|
|
38
|
-
s = scan(book_re) or return nil
|
|
54
|
+
s = @scanner.scan(book_re) or return nil
|
|
39
55
|
@text << s
|
|
40
|
-
@b1 = @b2 =
|
|
56
|
+
@b1 = @b2 = str2book_id(s)
|
|
41
57
|
@c1 = @v1 = @c2 = @v2 = nil
|
|
42
58
|
|
|
43
59
|
if pass_sep
|
|
44
60
|
b1 or give_up 'EOS or book expected!'
|
|
45
|
-
elsif check(Regexp.new(chapter_re.source + cv_sep_re.source))
|
|
61
|
+
elsif @scanner.check(Regexp.new(chapter_re.source + cv_sep_re.source))
|
|
46
62
|
@c1 = @v1 = nil
|
|
47
63
|
@c2 = @v2 = nil
|
|
48
64
|
c1
|
|
@@ -60,7 +76,7 @@ module Scripref
|
|
|
60
76
|
|
|
61
77
|
# try parse first chapter
|
|
62
78
|
def c1
|
|
63
|
-
s = scan(chapter_re) or return nil
|
|
79
|
+
s = @scanner.scan(chapter_re) or return nil
|
|
64
80
|
@text << s
|
|
65
81
|
@c1 = @c2 = s.to_i
|
|
66
82
|
@v1 = @v2 = nil
|
|
@@ -78,7 +94,7 @@ module Scripref
|
|
|
78
94
|
|
|
79
95
|
# try to parse first verse
|
|
80
96
|
def v1
|
|
81
|
-
s = scan(verse_re) or return nil
|
|
97
|
+
s = @scanner.scan(verse_re) or return nil
|
|
82
98
|
@text << s
|
|
83
99
|
@v1 = @v2 = s.to_i
|
|
84
100
|
|
|
@@ -92,7 +108,7 @@ module Scripref
|
|
|
92
108
|
|
|
93
109
|
if hyphen
|
|
94
110
|
b2 or (
|
|
95
|
-
if check(Regexp.new(chapter_re.source + cv_sep_re.source))
|
|
111
|
+
if @scanner.check(Regexp.new(chapter_re.source + cv_sep_re.source))
|
|
96
112
|
c2
|
|
97
113
|
else
|
|
98
114
|
v2 or give_up 'Chapter or verse expected!'
|
|
@@ -108,14 +124,14 @@ module Scripref
|
|
|
108
124
|
|
|
109
125
|
# try to parse second book
|
|
110
126
|
def b2
|
|
111
|
-
s = scan(book_re) or return nil
|
|
127
|
+
s = @scanner.scan(book_re) or return nil
|
|
112
128
|
@text << s
|
|
113
|
-
@b2 =
|
|
129
|
+
@b2 = str2book_id(s)
|
|
114
130
|
@c2 = @v2 = nil
|
|
115
131
|
|
|
116
132
|
if pass_sep
|
|
117
133
|
b1 or give_up 'EOS or book expected!'
|
|
118
|
-
elsif check(Regexp.new(chapter_re.source + cv_sep_re.source))
|
|
134
|
+
elsif @scanner.check(Regexp.new(chapter_re.source + cv_sep_re.source))
|
|
119
135
|
c2
|
|
120
136
|
else
|
|
121
137
|
if book_has_only_one_chapter?(@b2)
|
|
@@ -129,7 +145,7 @@ module Scripref
|
|
|
129
145
|
|
|
130
146
|
# try to parse second chapter
|
|
131
147
|
def c2
|
|
132
|
-
s = scan(chapter_re) or return nil
|
|
148
|
+
s = @scanner.scan(chapter_re) or return nil
|
|
133
149
|
@text << s
|
|
134
150
|
@c2 = s.to_i
|
|
135
151
|
|
|
@@ -144,7 +160,7 @@ module Scripref
|
|
|
144
160
|
|
|
145
161
|
# try to parse second verse
|
|
146
162
|
def v2
|
|
147
|
-
s = scan(verse_re) or return nil
|
|
163
|
+
s = @scanner.scan(verse_re) or return nil
|
|
148
164
|
@text << s
|
|
149
165
|
@v2 = s.to_i
|
|
150
166
|
|
|
@@ -163,16 +179,16 @@ module Scripref
|
|
|
163
179
|
|
|
164
180
|
# try to parse <tt>end of string</tt>
|
|
165
181
|
def epsilon
|
|
166
|
-
if eos?
|
|
182
|
+
if @scanner.eos?
|
|
167
183
|
push_passage
|
|
168
184
|
return @result
|
|
169
185
|
end
|
|
170
186
|
nil
|
|
171
187
|
end
|
|
172
188
|
|
|
173
|
-
# try to parse separator
|
|
189
|
+
# try to parse separator of chapter and verse
|
|
174
190
|
def cv_sep
|
|
175
|
-
if s = scan(cv_sep_re)
|
|
191
|
+
if s = @scanner.scan(cv_sep_re)
|
|
176
192
|
@text << s
|
|
177
193
|
s
|
|
178
194
|
else
|
|
@@ -182,7 +198,7 @@ module Scripref
|
|
|
182
198
|
|
|
183
199
|
# try to parse hyphen
|
|
184
200
|
def hyphen
|
|
185
|
-
if s = scan(hyphen_re)
|
|
201
|
+
if s = @scanner.scan(hyphen_re)
|
|
186
202
|
@text << s
|
|
187
203
|
s
|
|
188
204
|
else
|
|
@@ -192,7 +208,7 @@ module Scripref
|
|
|
192
208
|
|
|
193
209
|
# try to parse separator between passages
|
|
194
210
|
def pass_sep
|
|
195
|
-
if s = scan(pass_sep_re)
|
|
211
|
+
if s = @scanner.scan(pass_sep_re)
|
|
196
212
|
push_passage
|
|
197
213
|
@result << PassSep.new(s)
|
|
198
214
|
s
|
|
@@ -203,7 +219,7 @@ module Scripref
|
|
|
203
219
|
|
|
204
220
|
# try to parse verse separator
|
|
205
221
|
def verse_sep
|
|
206
|
-
if s = scan(verse_sep_re)
|
|
222
|
+
if s = @scanner.scan(verse_sep_re)
|
|
207
223
|
push_passage
|
|
208
224
|
@result << VerseSep.new(s)
|
|
209
225
|
s
|
|
@@ -214,7 +230,7 @@ module Scripref
|
|
|
214
230
|
|
|
215
231
|
# try to parse addons for verses
|
|
216
232
|
def verse_addon
|
|
217
|
-
if s = scan(verse_addon_re)
|
|
233
|
+
if s = @scanner.scan(verse_addon_re)
|
|
218
234
|
@text << s
|
|
219
235
|
s.to_sym
|
|
220
236
|
else
|
|
@@ -224,7 +240,7 @@ module Scripref
|
|
|
224
240
|
|
|
225
241
|
# try to parse postfixes for verse
|
|
226
242
|
def verse_postfix
|
|
227
|
-
s = (scan(postfix_one_following_verse_re) or scan(postfix_more_following_verses_re))
|
|
243
|
+
s = (@scanner.scan(postfix_one_following_verse_re) or @scanner.scan(postfix_more_following_verses_re))
|
|
228
244
|
if s
|
|
229
245
|
@text << s
|
|
230
246
|
s.to_sym
|
|
@@ -239,48 +255,43 @@ module Scripref
|
|
|
239
255
|
@a1 = @a2 = nil
|
|
240
256
|
end
|
|
241
257
|
|
|
242
|
-
def
|
|
258
|
+
def str2book_id str
|
|
243
259
|
s = str.strip
|
|
244
260
|
s.sub! /\.$/, ''
|
|
245
|
-
|
|
261
|
+
str2book_id_cache(s) or calculate_str2book_id(s)
|
|
246
262
|
end
|
|
247
263
|
|
|
248
|
-
def
|
|
264
|
+
def calculate_str2book_id str
|
|
249
265
|
s = str.strip
|
|
250
266
|
s.sub! /\.$/, ''
|
|
251
|
-
@books_str ||= ('#' <<
|
|
267
|
+
@books_str ||= ('#' << each_bookname.map(&:each_name).flat_map(&:to_a).join('#') << '#')
|
|
252
268
|
pattern = s.chars.map {|c| Regexp.escape(c) << '[^#]*'}.join
|
|
253
269
|
re = /(?<=#)#{pattern}(?=#)/
|
|
254
270
|
names = @books_str.scan(re)
|
|
255
|
-
uniq_numbers = names.map {|n|
|
|
271
|
+
uniq_numbers = names.map {|n| str2book_id_cache(n)}.uniq
|
|
256
272
|
if uniq_numbers.size != 1
|
|
257
|
-
unscan
|
|
273
|
+
@scanner.unscan
|
|
258
274
|
give_up format("Abbreviation %s is ambiguous it matches %s!", s, names.join(', '))
|
|
259
275
|
end
|
|
260
|
-
names.first
|
|
276
|
+
book_id = str2book_id_cache(names.first)
|
|
277
|
+
@str2book_id_cache[s] = book_id
|
|
278
|
+
book_id
|
|
261
279
|
end
|
|
262
280
|
|
|
263
|
-
def
|
|
264
|
-
unless @
|
|
265
|
-
@
|
|
266
|
-
|
|
267
|
-
bn.
|
|
268
|
-
@
|
|
269
|
-
end
|
|
270
|
-
bn.abbrevs.each do |n|
|
|
271
|
-
@str2osis_book_id[n] = bn.osis_id
|
|
281
|
+
def init_str2book_id_cache
|
|
282
|
+
unless @str2book_id_cache
|
|
283
|
+
@str2book_id_cache = {}
|
|
284
|
+
each_bookname do |bn|
|
|
285
|
+
bn.each_string do |s|
|
|
286
|
+
@str2book_id_cache[s] = bn.book_id
|
|
272
287
|
end
|
|
273
288
|
end
|
|
274
289
|
end
|
|
275
290
|
end
|
|
276
291
|
|
|
277
|
-
def
|
|
278
|
-
|
|
279
|
-
@
|
|
280
|
-
end
|
|
281
|
-
|
|
282
|
-
def inspect
|
|
283
|
-
"#<#{self.class} #{@mods.inspect}>"
|
|
292
|
+
def str2book_id_cache str
|
|
293
|
+
init_str2book_id_cache
|
|
294
|
+
@str2book_id_cache[str]
|
|
284
295
|
end
|
|
285
296
|
|
|
286
297
|
def give_up msg
|
|
@@ -288,16 +299,6 @@ module Scripref
|
|
|
288
299
|
fail ParserError, format_error
|
|
289
300
|
end
|
|
290
301
|
|
|
291
|
-
def format_error
|
|
292
|
-
if error
|
|
293
|
-
format("%s\n%s\n%s^", error, string, ' ' * pointer)
|
|
294
|
-
else
|
|
295
|
-
''
|
|
296
|
-
end
|
|
297
|
-
end
|
|
298
|
-
|
|
299
|
-
alias << parse
|
|
300
|
-
|
|
301
302
|
end
|
|
302
303
|
|
|
303
304
|
class ParserError < RuntimeError; end
|
data/lib/scripref/passage.rb
CHANGED
|
@@ -5,70 +5,17 @@ module Scripref
|
|
|
5
5
|
|
|
6
6
|
Passage = Struct.new(:text, :b1, :c1, :v1, :b2, :c2, :v2, :a1, :a2, keyword_init: true) do
|
|
7
7
|
|
|
8
|
-
include Comparable
|
|
9
|
-
|
|
10
8
|
def to_a
|
|
11
9
|
[b1, c1, v1, b2, c2, v2]
|
|
12
10
|
end
|
|
13
11
|
|
|
14
|
-
def
|
|
15
|
-
return unless other.kind_of? Passage
|
|
16
|
-
|
|
17
|
-
end
|
|
18
|
-
|
|
19
|
-
# Returns true if the instance and the given passage overlap.
|
|
20
|
-
# That means both has at least one verse in common.
|
|
21
|
-
def overlap? passage
|
|
22
|
-
fail ArgumentError, 'value must be a passage' unless passage.kind_of? Passage
|
|
23
|
-
a = self.to_numeric_array
|
|
24
|
-
b = passage.to_numeric_array
|
|
25
|
-
[a[0..2] <=> b[3..5], b[0..2] <=> a[3..5]].max < 1
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
# Returns an array of b1, c1, v1
|
|
29
|
-
def start
|
|
30
|
-
[b1, c1, v1]
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
# Returns an array of b2, c2, v2
|
|
34
|
-
def end
|
|
35
|
-
[b2, c2, v2]
|
|
36
|
-
end
|
|
37
|
-
|
|
38
|
-
def to_numeric_array max: 999, ff: 3
|
|
39
|
-
_b1 = Passage.book_id2num[b1]
|
|
40
|
-
_c1 = c1 || 1
|
|
41
|
-
_v1 = v1 || 1
|
|
42
|
-
_b2 = Passage.book_id2num[b2]
|
|
43
|
-
_c2 = c2 || max
|
|
44
|
-
_v2 = v2 || max
|
|
45
|
-
if _v2 == :f
|
|
46
|
-
_v2 = _v1 + 1
|
|
47
|
-
end
|
|
48
|
-
if _v2 == :ff
|
|
49
|
-
_v2 = _v1 + ff
|
|
50
|
-
end
|
|
51
|
-
[_b1, _c1, _v1, _b2, _c2, _v2]
|
|
12
|
+
def == other
|
|
13
|
+
return false unless other.kind_of? Passage
|
|
14
|
+
to_a == other.to_a
|
|
52
15
|
end
|
|
53
16
|
|
|
54
17
|
alias to_s text
|
|
55
18
|
|
|
56
|
-
@book_id2num = {}
|
|
57
|
-
osis_book_ids = %i[
|
|
58
|
-
Gen Exod Lev Num Deut Josh Judg Ruth 1Sam 2Sam 1Kgs 2Kgs 1Chr 2Chr Ezra
|
|
59
|
-
Neh Esth Job Ps Prov Eccl Song Isa Jer Lam Ezek Dan Hos Joel Amos Obad
|
|
60
|
-
Jonah Mic Nah Hab Zeph Hag Zech Mal Matt Mark Luke John Acts Rom 1Cor
|
|
61
|
-
2Cor Gal Eph Phil Col 1Thess 2Thess 1Tim 2Tim Titus Phlm Heb Jas 1Pet
|
|
62
|
-
2Pet 1John 2John 3John Jude Rev
|
|
63
|
-
]
|
|
64
|
-
osis_book_ids.each_with_index do |book_id, i|
|
|
65
|
-
@book_id2num[book_id] = i+1
|
|
66
|
-
end
|
|
67
|
-
|
|
68
|
-
class << self
|
|
69
|
-
attr_reader :book_id2num
|
|
70
|
-
end
|
|
71
|
-
|
|
72
19
|
end
|
|
73
20
|
|
|
74
21
|
end
|
data/lib/scripref/processor.rb
CHANGED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
module Scripref
|
|
5
|
+
|
|
6
|
+
class Sorter
|
|
7
|
+
|
|
8
|
+
def initialize *mods
|
|
9
|
+
@mods = mods
|
|
10
|
+
mods.each {|m| extend m}
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def sort *references
|
|
14
|
+
passages = references.flatten.select {|e| e.kind_of? Scripref::Passage}
|
|
15
|
+
passages.sort do |p1, p2|
|
|
16
|
+
signum(p1, p2)
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
alias << sort
|
|
21
|
+
|
|
22
|
+
# Mixin to sort ascending by start verse and desending by end verse of passages
|
|
23
|
+
module SortUpDown
|
|
24
|
+
def signum pass1, pass2
|
|
25
|
+
a, b = passage2arr(pass1), passage2arr(pass2)
|
|
26
|
+
a[0, 3] + b[3, 3] <=> b[0, 3] + a[3, 3]
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
# Mixin to sort ascending by start verse and ascending by end verse of passages
|
|
31
|
+
module SortUpUp
|
|
32
|
+
def signum pass1, pass2
|
|
33
|
+
a, b = passage2arr(pass1), passage2arr(pass2)
|
|
34
|
+
a <=> b
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# Default sorting
|
|
39
|
+
|
|
40
|
+
include SortUpDown
|
|
41
|
+
|
|
42
|
+
private
|
|
43
|
+
|
|
44
|
+
def passage2arr pass
|
|
45
|
+
b1 = book2num(pass.b1)
|
|
46
|
+
b2 = book2num(pass.b2)
|
|
47
|
+
[b1, pass.c1 || 1, pass.v1 || 1, b2, pass.c2 || Float::INFINITY, pass.v2 || Float::INFINITY]
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
end
|
data/lib/scripref.rb
CHANGED
|
@@ -5,7 +5,7 @@ require 'delegate'
|
|
|
5
5
|
|
|
6
6
|
module Scripref
|
|
7
7
|
|
|
8
|
-
VERSION = '
|
|
8
|
+
VERSION = '2.0.0'
|
|
9
9
|
|
|
10
10
|
require_relative 'scripref/bookname'
|
|
11
11
|
require_relative 'scripref/bookorder'
|
|
@@ -15,6 +15,7 @@ module Scripref
|
|
|
15
15
|
require_relative 'scripref/parser'
|
|
16
16
|
require_relative 'scripref/passage'
|
|
17
17
|
require_relative 'scripref/processor'
|
|
18
|
+
require_relative 'scripref/sorter'
|
|
18
19
|
|
|
19
20
|
class Token < DelegateClass(String)
|
|
20
21
|
def initialize *args
|
data/test/test_bookname.rb
CHANGED
|
@@ -8,15 +8,23 @@ class TestBookname < Test::Unit::TestCase
|
|
|
8
8
|
include Scripref
|
|
9
9
|
|
|
10
10
|
def setup
|
|
11
|
-
@zef = Bookname.new(
|
|
11
|
+
@zef = Bookname.new(book_id: :Zeph, name: 'Zefanja', abbrevs: %w(Zefan Zef), alternatives: Bookname.new(book_id: :Zeph, name: 'Zephanja', abbrevs: 'Zeph'))
|
|
12
12
|
end
|
|
13
13
|
|
|
14
|
-
def
|
|
15
|
-
assert_equal
|
|
14
|
+
def test_each_name
|
|
15
|
+
assert_equal %w(Zefanja Zephanja), @zef.each_name.to_a
|
|
16
16
|
end
|
|
17
17
|
|
|
18
|
-
def
|
|
19
|
-
assert_equal
|
|
18
|
+
def test_each_string
|
|
19
|
+
assert_equal %w(Zefanja Zefan Zef Zephanja Zeph), @zef.each_string.to_a
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def test_parse
|
|
23
|
+
assert_equal @zef, Bookname.parse('Zeph: Zefanja|Zefan|Zef, Zephanja|Zeph')
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def test_dump
|
|
27
|
+
assert_equal 'Zeph: Zefanja|Zefan|Zef, Zephanja|Zeph', @zef.dump
|
|
20
28
|
end
|
|
21
29
|
|
|
22
30
|
end
|
data/test/test_english.rb
CHANGED
|
@@ -13,7 +13,7 @@ class TestEnglish < Test::Unit::TestCase
|
|
|
13
13
|
end
|
|
14
14
|
|
|
15
15
|
def test_size_of_book_array
|
|
16
|
-
assert_equal 66, English::
|
|
16
|
+
assert_equal 66, English::BOOKNAMES_HASH.size
|
|
17
17
|
end
|
|
18
18
|
|
|
19
19
|
def test_book_re
|
|
@@ -32,20 +32,20 @@ class TestEnglish < Test::Unit::TestCase
|
|
|
32
32
|
assert_match book_re, 'Rev'
|
|
33
33
|
end
|
|
34
34
|
|
|
35
|
-
def
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
35
|
+
def test_book2book_id
|
|
36
|
+
assert_book_id :Gen, 'Genesis'
|
|
37
|
+
assert_book_id :Matt, 'Matthew'
|
|
38
|
+
assert_book_id :Rev, 'Revelation'
|
|
39
|
+
assert_book_id :Gen, 'Gen'
|
|
40
|
+
assert_book_id :Gen, 'Ge'
|
|
41
|
+
assert_book_id :'2Tim', '2 Tim'
|
|
42
|
+
assert_book_id :'2Tim', '2Tim'
|
|
43
|
+
assert_book_id :'2Tim', '2Tm'
|
|
44
|
+
assert_book_id :Matt, 'Mat'
|
|
45
|
+
assert_book_id :Rev, 'Rev'
|
|
46
46
|
end
|
|
47
47
|
|
|
48
|
-
def
|
|
48
|
+
def assert_book_id id, str
|
|
49
49
|
assert_equal id, @parser.parse(str).first.b1
|
|
50
50
|
end
|
|
51
51
|
|
data/test/test_formatter.rb
CHANGED
|
@@ -170,7 +170,8 @@ class TestFormatter < Test::Unit::TestCase
|
|
|
170
170
|
|
|
171
171
|
def test_two_refs_with_book_with_only_one_chapter
|
|
172
172
|
text = 'Obadja 3.5'
|
|
173
|
-
|
|
173
|
+
t1, t2 = text.split(dot)
|
|
174
|
+
assert_formated_text_for_ast text, [pass(text: t1, b1: :Obad, c1: 1, v1: 3, b2: :Obad, c2: 1, v2: 3), dot, pass(text: t2, b1: :Obad, c1: 1, v1: 5, b2: :Obad, c2: 1, v2: 5)]
|
|
174
175
|
end
|
|
175
176
|
|
|
176
177
|
######################################################################
|
|
@@ -261,18 +262,12 @@ class TestFormatter < Test::Unit::TestCase
|
|
|
261
262
|
######################################################################
|
|
262
263
|
|
|
263
264
|
def test_formatting_with_book_abbrevs
|
|
264
|
-
@german_formatter.
|
|
265
|
+
@german_formatter.abbrev_level = 1
|
|
265
266
|
text = 'Mat 3,4; Mar; Joh 3,16'
|
|
266
267
|
t1, t2, t3 = text.split(semi)
|
|
267
268
|
assert_formated_text_for_ast text, [pass(text: t1, b1: :Matt, c1: 3, v1: 4, b2: :Matt, c2: 3, v2: 4), semi, pass(text: t2, b1: :Mark, b2: :Mark), semi, pass(text: t3, b1: :John, c1: 3, v1: 16, b2: :John, c2: 3, v2: 16)]
|
|
268
269
|
end
|
|
269
270
|
|
|
270
|
-
def test_exception_for_unhandled_bookformat
|
|
271
|
-
assert_raise NoMethodError do
|
|
272
|
-
@german_formatter.bookformat = :unknown
|
|
273
|
-
@german_formatter.format [pass(text: 1, b1: :Exod, c1: 3, v1: 4, b2: :Deut, c2: 6, v2: 7)]
|
|
274
|
-
end
|
|
275
|
-
end
|
|
276
271
|
private
|
|
277
272
|
|
|
278
273
|
def assert_formated_text_for_ast text, ast
|
data/test/test_german.rb
CHANGED
|
@@ -13,7 +13,7 @@ class TestGerman < Test::Unit::TestCase
|
|
|
13
13
|
end
|
|
14
14
|
|
|
15
15
|
def test_size_of_book_array
|
|
16
|
-
assert_equal 66, German::
|
|
16
|
+
assert_equal 66, German::BOOKNAMES_HASH.size
|
|
17
17
|
end
|
|
18
18
|
|
|
19
19
|
def test_book_re
|
|
@@ -32,19 +32,19 @@ class TestGerman < Test::Unit::TestCase
|
|
|
32
32
|
assert_match book_re, 'Off'
|
|
33
33
|
end
|
|
34
34
|
|
|
35
|
-
def
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
35
|
+
def test_book2book_id
|
|
36
|
+
assert_book_id :Gen, '1. Mose'
|
|
37
|
+
assert_book_id :Matt, 'Matthäus'
|
|
38
|
+
assert_book_id :Rev, 'Offenbarung'
|
|
39
|
+
assert_book_id :Gen, '1. Mo'
|
|
40
|
+
assert_book_id :Gen, '1.Mo'
|
|
41
|
+
assert_book_id :Gen, '1M'
|
|
42
|
+
assert_book_id :Matt, 'Mat'
|
|
43
|
+
assert_book_id :Phil, 'Phil'
|
|
44
|
+
assert_book_id :Rev, 'Off'
|
|
45
45
|
end
|
|
46
46
|
|
|
47
|
-
def
|
|
47
|
+
def assert_book_id id, str
|
|
48
48
|
@parser ||= Scripref::Parser.new(Scripref::German)
|
|
49
49
|
assert_equal id, @parser.parse(str).first.b1
|
|
50
50
|
end
|
data/test/test_parser.rb
CHANGED
|
@@ -333,6 +333,17 @@ class TestParser < Test::Unit::TestCase
|
|
|
333
333
|
assert_parsed_ast_for_text [pass(text: text, b1: :Ps, c1: 23, v1: 6, b2: :Ps, c2: 23, v2: 6)], text
|
|
334
334
|
end
|
|
335
335
|
|
|
336
|
+
def test_alternatives
|
|
337
|
+
# In German Zephanja is alternative name for Zefanja
|
|
338
|
+
a = pass(b1: :Zeph, c1: 2, b2: :Zeph, c2: 2).to_a
|
|
339
|
+
assert_equal a, @parser.parse('Zefanja 2').first.to_a
|
|
340
|
+
assert_equal a, @parser.parse('Zefa 2').first.to_a
|
|
341
|
+
assert_equal a, @parser.parse('Zef 2').first.to_a
|
|
342
|
+
assert_equal a, @parser.parse('Zephanja 2').first.to_a
|
|
343
|
+
assert_equal a, @parser.parse('Zepha 2').first.to_a
|
|
344
|
+
assert_equal a, @parser.parse('Zeph 2').first.to_a
|
|
345
|
+
end
|
|
346
|
+
|
|
336
347
|
private
|
|
337
348
|
|
|
338
349
|
def assert_equal_passage expected, actual
|
data/test/test_sorter.rb
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
require_relative 'test_helper'
|
|
5
|
+
|
|
6
|
+
class TestSorter < Test::Unit::TestCase
|
|
7
|
+
|
|
8
|
+
include Scripref
|
|
9
|
+
include Test::Helper
|
|
10
|
+
|
|
11
|
+
def setup
|
|
12
|
+
@john_1 = pass(b1: :John, c1: 1, b2: :John, c2: 1)
|
|
13
|
+
@john_1_1_3 = pass(b1: :John, c1: 1, v1: 1, b2: :John, c2: 1, v2: 3)
|
|
14
|
+
@john_1_1_18 = pass(b1: :John, c1: 1, v1: 1, b2: :John, c2: 1, v2: 18)
|
|
15
|
+
@john_2 = pass(b1: :John, c1: 2, b2: :John, c2: 2)
|
|
16
|
+
@heb_9 = pass(b1: :Heb, c1: 9, b2: :Heb, c2: 9)
|
|
17
|
+
@jas_1 = pass(b1: :Jas, c1: 1, b2: :Jas, c2: 1)
|
|
18
|
+
@pet_1 = pass(b1: :'1Pet', c1: 1, b2: :'1Pet', c2: 1)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def test_canonical_default
|
|
22
|
+
sorter = Sorter.new(Bookorder::Canonical)
|
|
23
|
+
assert_equal [@john_1, @heb_9, @jas_1, @pet_1], sorter.sort([@heb_9, @pet_1, @jas_1, @john_1])
|
|
24
|
+
assert_equal [@john_1_1_18, @john_1_1_3], sorter.sort([@john_1_1_3, @john_1_1_18])
|
|
25
|
+
assert_equal [@john_1, @john_1_1_18, @john_1_1_3, @john_2], sorter.sort([@john_1, @john_1_1_3, @john_2, @john_1_1_18])
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def test_canonical_sort_up_up
|
|
29
|
+
sorter = Sorter.new(Bookorder::Canonical, Sorter::SortUpUp)
|
|
30
|
+
assert_equal [@john_1_1_3, @john_1_1_18], sorter.sort([@john_1_1_3, @john_1_1_18])
|
|
31
|
+
assert_equal [@john_1_1_3, @john_1_1_18, @john_1, @john_2], sorter.sort([@john_1, @john_1_1_3, @john_2, @john_1_1_18])
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def test_luther_default
|
|
35
|
+
sorter = Sorter.new(Bookorder::Luther)
|
|
36
|
+
assert_equal [@john_1, @pet_1, @heb_9, @jas_1], sorter.sort([@heb_9, @pet_1, @jas_1, @john_1])
|
|
37
|
+
assert_equal [@john_1_1_18, @john_1_1_3], sorter.sort([@john_1_1_3, @john_1_1_18])
|
|
38
|
+
assert_equal [@john_1, @john_1_1_18, @john_1_1_3, @john_2], sorter.sort([@john_1, @john_1_1_3, @john_2, @john_1_1_18])
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def test_luther_sort_up_up
|
|
42
|
+
sorter = Sorter.new(Bookorder::Luther, Sorter::SortUpUp)
|
|
43
|
+
assert_equal [@john_1, @pet_1, @heb_9, @jas_1], sorter.sort([@heb_9, @pet_1, @jas_1, @john_1])
|
|
44
|
+
assert_equal [@john_1_1_3, @john_1_1_18], sorter.sort([@john_1_1_3, @john_1_1_18])
|
|
45
|
+
assert_equal [@john_1_1_3, @john_1_1_18, @john_1, @john_2], sorter.sort([@john_1, @john_1_1_3, @john_2, @john_1_1_18])
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: scripref
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version:
|
|
4
|
+
version: 2.0.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Jan Friedrich
|
|
@@ -87,6 +87,7 @@ files:
|
|
|
87
87
|
- lib/scripref/passage.rb
|
|
88
88
|
- lib/scripref/pipelining.rb
|
|
89
89
|
- lib/scripref/processor.rb
|
|
90
|
+
- lib/scripref/sorter.rb
|
|
90
91
|
- regtest/formatter.rb
|
|
91
92
|
- regtest/formatter.yml
|
|
92
93
|
- regtest/parser.rb
|
|
@@ -101,9 +102,9 @@ files:
|
|
|
101
102
|
- test/test_helper.rb
|
|
102
103
|
- test/test_integration.rb
|
|
103
104
|
- test/test_parser.rb
|
|
104
|
-
- test/test_passage.rb
|
|
105
105
|
- test/test_pipelining.rb
|
|
106
106
|
- test/test_processor.rb
|
|
107
|
+
- test/test_sorter.rb
|
|
107
108
|
homepage: https://github.com/janfri/scripref
|
|
108
109
|
licenses:
|
|
109
110
|
- MIT
|
data/test/test_passage.rb
DELETED
|
@@ -1,91 +0,0 @@
|
|
|
1
|
-
# encoding: utf-8
|
|
2
|
-
# frozen_string_literal: true
|
|
3
|
-
|
|
4
|
-
require_relative 'test_helper'
|
|
5
|
-
|
|
6
|
-
class TestPassage < Test::Unit::TestCase
|
|
7
|
-
|
|
8
|
-
include Scripref
|
|
9
|
-
include Test::Helper
|
|
10
|
-
|
|
11
|
-
def setup
|
|
12
|
-
@parser = Parser.new(German)
|
|
13
|
-
end
|
|
14
|
-
|
|
15
|
-
def test_to_a
|
|
16
|
-
pass = @parser.parse('Mr 1,2-Luk 3,4').first
|
|
17
|
-
assert_equal [:Mark, 1, 2, :Luke, 3, 4], pass.to_a
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
def test_spaceship_operator
|
|
21
|
-
ast = @parser.parse('Mar 2,3; Joh 1,5')
|
|
22
|
-
p1, p2 = ast[0], ast[2]
|
|
23
|
-
assert_nil p1 <=> :other_value
|
|
24
|
-
assert_nil :other_value <=> p1
|
|
25
|
-
assert_equal (-1), p1 <=> p2
|
|
26
|
-
assert_equal 0, p1 <=> p1
|
|
27
|
-
assert_equal 1, p2 <=> p1
|
|
28
|
-
end
|
|
29
|
-
|
|
30
|
-
def test_comparable_with_sort
|
|
31
|
-
ast = @parser.parse('Joh 8,1-9,11; 8,2-9,12; 8,2-9,11; 8,1-9,12; Joh 8')
|
|
32
|
-
passages = ast.grep(Passage)
|
|
33
|
-
expect = ['Joh 8',
|
|
34
|
-
'Joh 8,1-9,11',
|
|
35
|
-
'8,1-9,12',
|
|
36
|
-
'8,2-9,11',
|
|
37
|
-
'8,2-9,12']
|
|
38
|
-
assert_equal expect, passages.sort.map(&:text)
|
|
39
|
-
|
|
40
|
-
ast = @parser.parse('Mar 1; 1,1; 1,1f; 1,1ff; 1,2; 1,1-2,2; Mar 1-2; Markus; Markus-Lukas; Mar 1-Luk 2; Mar 1,1-Luk 2,2')
|
|
41
|
-
passages = ast.grep(Passage)
|
|
42
|
-
formatter = Formatter.new(German)
|
|
43
|
-
expect = ['Markus 1,1',
|
|
44
|
-
'Markus 1,1f',
|
|
45
|
-
'Markus 1,1ff',
|
|
46
|
-
'Markus 1',
|
|
47
|
-
'Markus 1,1-2,2',
|
|
48
|
-
'Markus 1-2',
|
|
49
|
-
'Markus',
|
|
50
|
-
'Markus 1,1-Lukas 2,2',
|
|
51
|
-
'Markus 1-Lukas 2',
|
|
52
|
-
'Markus-Lukas',
|
|
53
|
-
'Markus 1,2']
|
|
54
|
-
assert_equal expect, passages.sort.map {|e| formatter << e}
|
|
55
|
-
end
|
|
56
|
-
|
|
57
|
-
def test_overlap
|
|
58
|
-
a = @parser.parse('Joh 8,1-9').first
|
|
59
|
-
b = @parser.parse('Joh 8,8-11').first
|
|
60
|
-
c = @parser.parse('Joh 8,12-15').first
|
|
61
|
-
d = @parser.parse('Joh 8,15-18').first
|
|
62
|
-
e = @parser.parse('Joh 8').first
|
|
63
|
-
assert_overlap a, a
|
|
64
|
-
assert_overlap a, b
|
|
65
|
-
assert_not_overlap b, c
|
|
66
|
-
assert_overlap c, d
|
|
67
|
-
assert_overlap d, e
|
|
68
|
-
end
|
|
69
|
-
|
|
70
|
-
def test_start
|
|
71
|
-
p = pass(text: '', b1: :Gen, c1: 2, v1: 3, b2: :Num, c2: 5, v2: 6)
|
|
72
|
-
assert_equal [:Gen, 2, 3], p.start
|
|
73
|
-
end
|
|
74
|
-
|
|
75
|
-
def test_end
|
|
76
|
-
p = pass(text: '', b1: :Gen, c1: 2, v1: 3, b2: :Num, c2: 5, v2: 6)
|
|
77
|
-
assert_equal [:Num, 5, 6], p.end
|
|
78
|
-
end
|
|
79
|
-
|
|
80
|
-
protected
|
|
81
|
-
|
|
82
|
-
def assert_overlap a, b
|
|
83
|
-
assert a.overlap?(b)
|
|
84
|
-
assert b.overlap?(a)
|
|
85
|
-
end
|
|
86
|
-
|
|
87
|
-
def assert_not_overlap a, b
|
|
88
|
-
assert !a.overlap?(b)
|
|
89
|
-
assert !b.overlap?(a)
|
|
90
|
-
end
|
|
91
|
-
end
|