cskit 1.0.1 → 1.1.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.
Files changed (50) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +7 -4
  3. data/History.txt +5 -0
  4. data/cskit.gemspec +5 -8
  5. data/lib/cskit.rb +15 -66
  6. data/lib/cskit/annotated_string.rb +1 -1
  7. data/lib/cskit/annotator.rb +1 -3
  8. data/lib/cskit/formatters.rb +3 -4
  9. data/lib/cskit/formatters/bible.rb +4 -5
  10. data/lib/cskit/formatters/bible/bible_html_formatter.rb +2 -2
  11. data/lib/cskit/formatters/bible/bible_json_formatter.rb +17 -0
  12. data/lib/cskit/formatters/bible/bible_plain_text_formatter.rb +3 -3
  13. data/lib/cskit/formatters/science_health.rb +3 -5
  14. data/lib/cskit/formatters/science_health/science_health_html_formatter.rb +3 -4
  15. data/lib/cskit/formatters/science_health/science_health_plain_text_formatter.rb +5 -4
  16. data/lib/cskit/lesson.rb +3 -5
  17. data/lib/cskit/lesson/lesson.rb +3 -3
  18. data/lib/cskit/lesson/section.rb +1 -1
  19. data/lib/cskit/parsers.rb +6 -3
  20. data/lib/cskit/parsers/bible.rb +10 -0
  21. data/lib/cskit/parsers/bible/bible_parser.rb +192 -0
  22. data/lib/cskit/parsers/bible/bible_tokenizer.rb +32 -0
  23. data/lib/cskit/parsers/parser.rb +68 -0
  24. data/lib/cskit/parsers/science_health.rb +10 -0
  25. data/lib/cskit/parsers/science_health/science_health_parser.rb +201 -0
  26. data/lib/cskit/parsers/science_health/science_health_tokenizer.rb +33 -0
  27. data/lib/cskit/parsers/token.rb +17 -0
  28. data/lib/cskit/parsers/tokenizer.rb +43 -0
  29. data/lib/cskit/readers.rb +4 -4
  30. data/lib/cskit/readers/bible_reader.rb +2 -2
  31. data/lib/cskit/readers/reading.rb +8 -1
  32. data/lib/cskit/readers/science_health_reader.rb +8 -8
  33. data/lib/cskit/registry.rb +65 -0
  34. data/lib/cskit/resources/volumes.rb +3 -3
  35. data/lib/cskit/resources/volumes/bible.rb +11 -9
  36. data/lib/cskit/resources/volumes/science_health.rb +10 -9
  37. data/lib/cskit/version.rb +1 -1
  38. data/lib/cskit/volume.rb +1 -1
  39. data/spec/parsers/bible/bible_parser_spec.rb +205 -0
  40. data/spec/parsers/science_health/science_health_parser_spec.rb +153 -0
  41. data/spec/spec_helper.rb +8 -0
  42. metadata +16 -38
  43. data/lib/cskit/parsers/bible/bible.rb +0 -1005
  44. data/lib/cskit/parsers/bible/bible.treetop +0 -64
  45. data/lib/cskit/parsers/bible/nodes.rb +0 -153
  46. data/lib/cskit/parsers/bible/objects.rb +0 -81
  47. data/lib/cskit/parsers/science_health/nodes.rb +0 -82
  48. data/lib/cskit/parsers/science_health/objects.rb +0 -47
  49. data/lib/cskit/parsers/science_health/science_health.rb +0 -607
  50. data/lib/cskit/parsers/science_health/science_health.treetop +0 -44
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: b63a117f2cc1e418414654ab99412b9a70355c05
4
- data.tar.gz: 59293273440f24aea1a23c80c6b96d845d601a12
3
+ metadata.gz: fc2a9550e46d7df48af95443aa4bd70b8a6d9f51
4
+ data.tar.gz: 2c74a6f0feefde08a17af8ba7e7113e9bb97e5fa
5
5
  SHA512:
6
- metadata.gz: cd54044d09b723ccfd504dd87d9a44283df32ddd56905a40df1b0e36314368b04388c343e2d9190b175f2f786ecf0e89e2e824488fb72ff11bf808f2238d9b3f
7
- data.tar.gz: 204c2eec966c773dfabb68a3e70a2778ef7811691238dbc26a01ce66f0bbf55651b943e6eebf4c1fd39ddda6f883027ad1889d980526a2fed6570e2ce3616ee0
6
+ metadata.gz: fa92477f03276a97d9e77964b5eb2b9ea295870d810c97037166e31a091d2fbd808227325949febebdd4efef5894344d127bb3639fbb6fd237f806fec49cba73
7
+ data.tar.gz: eaad5970540813c5a6f489fa60668b15476bed1ae281d092d46898bb8a29e22766d687c400d5b2b67d0b55bbd27d4886d6b199105a98cd455319df83b8fb486e
data/Gemfile CHANGED
@@ -1,8 +1,11 @@
1
- source "http://rubygems.org"
1
+ source 'http://rubygems.org'
2
2
 
3
3
  gemspec
4
4
 
5
- group :development do
6
- gem "pry"
7
- gem "pry-nav"
5
+ group :test do
6
+ gem 'rspec'
7
+ end
8
+
9
+ group :development, :test do
10
+ gem 'pry-byebug'
8
11
  end
data/History.txt CHANGED
@@ -6,3 +6,8 @@
6
6
 
7
7
  * Fix preface regex to detect pages starting at vii instead of vi for Science and Health.
8
8
 
9
+ == 1.1.0
10
+
11
+ * Parser rewrite.
12
+ * Add parser tests.
13
+ * General cleanup.
data/cskit.gemspec CHANGED
@@ -6,20 +6,17 @@ require 'cskit/version'
6
6
  Gem::Specification.new do |s|
7
7
  s.name = "cskit"
8
8
  s.version = ::CSKit::VERSION
9
- s.authors = ["Cameron Dutro"]
10
- s.email = ["camertron@gmail.com"]
11
- s.homepage = "http://github.com/camertron"
9
+ s.authors = ['Cameron Dutro']
10
+ s.email = ['camertron@gmail.com']
11
+ s.homepage = 'http://github.com/camertron'
12
12
 
13
- s.description = s.summary = "Christian Science citation library for Ruby."
13
+ s.description = s.summary = 'Christian Science citation library for Ruby.'
14
14
 
15
15
  s.platform = Gem::Platform::RUBY
16
16
  s.has_rdoc = true
17
17
 
18
18
  s.add_dependency 'json'
19
- s.add_dependency 'treetop'
20
-
21
- s.add_development_dependency 'rake'
22
19
 
23
20
  s.require_path = 'lib'
24
- s.files = Dir["{lib,spec,resources}/**/*", "Gemfile", "History.txt", "LICENSE", "README.md", "Rakefile", "cskit.gemspec"]
21
+ s.files = Dir['{lib,spec,resources}/**/*', 'Gemfile', 'History.txt', 'LICENSE', 'README.md', 'Rakefile', 'cskit.gemspec']
25
22
  end
data/lib/cskit.rb CHANGED
@@ -1,73 +1,22 @@
1
1
  # encoding: UTF-8
2
2
 
3
- require 'cskit/formatters'
4
- require 'cskit/lesson'
5
- require 'cskit/parsers'
6
- require 'cskit/readers'
7
- require 'cskit/volume'
8
- require 'cskit/resources/volumes'
9
-
10
- require 'treetop'
11
- require 'json'
12
-
13
3
  module CSKit
14
4
 
15
- autoload :Annotator, "cskit/annotator"
16
- autoload :Annotation, "cskit/annotator"
17
- autoload :AnnotatedString, "cskit/annotated_string"
18
-
19
- class << self
20
-
21
- def register_volume(config)
22
- register(:volume, config[:id], config[:volume].new(config))
23
- end
24
-
25
- def register_annotator(config)
26
- register(:annotator, config[:id], config[:annotator].new(config))
27
- end
28
-
29
- def get_volume(volume_id)
30
- get(:volume, volume_id)
31
- end
32
-
33
- def get_annotator(annotator_id)
34
- get(:annotator, annotator_id)
35
- end
36
-
37
- def volume_available?(volume_id)
38
- available?(:volume, volume_id)
39
- end
40
-
41
- def annotator_available?(annotator_id)
42
- available?(:annotator, annotator_id)
43
- end
44
-
45
- private
46
-
47
- def register(family, key, obj)
48
- (registry[family.to_sym] ||= {})[key.to_sym] = obj
49
- end
50
-
51
- def get(family, key)
52
- registry[family.to_sym][key.to_sym] || get_for_type(family, key)
53
- end
54
-
55
- def get_for_type(family, type)
56
- found = registry[family.to_sym].find do |key, obj|
57
- obj.config[:type] == type
58
- end
59
-
60
- found.last if found
61
- end
62
-
63
- def available?(family, key)
64
- !!registry[family.to_sym][key.to_sym] rescue false
65
- end
5
+ autoload :Annotator, 'cskit/annotator'
6
+ autoload :Annotation, 'cskit/annotator'
7
+ autoload :AnnotatedString, 'cskit/annotated_string'
8
+ autoload :Formatters, 'cskit/formatters'
9
+ autoload :Lesson, 'cskit/lesson'
10
+ autoload :Parsers, 'cskit/parsers'
11
+ autoload :Readers, 'cskit/readers'
12
+ autoload :Registry, 'cskit/registry'
13
+ autoload :RegistryFactory, 'cskit/registry'
14
+ autoload :Volume, 'cskit/volume'
15
+ autoload :Volumes, 'cskit/resources/volumes'
66
16
 
67
- def registry
68
- @registry ||= {}
69
- end
17
+ extend Registry
70
18
 
71
- end
19
+ family :volume, :volumes
20
+ family :annotator, :annotators
72
21
 
73
- end
22
+ end
@@ -70,4 +70,4 @@ module CSKit
70
70
  end
71
71
 
72
72
  end
73
- end
73
+ end
@@ -2,15 +2,13 @@
2
2
 
3
3
  module CSKit
4
4
  class Annotator
5
-
6
5
  attr_reader :config
7
6
 
8
7
  def initialize(config)
9
8
  @config = config
10
9
  end
11
-
12
10
  end
13
11
 
14
12
  Annotation = Struct.new(:start, :finish, :data)
15
13
 
16
- end
14
+ end
@@ -3,9 +3,8 @@
3
3
  module CSKit
4
4
  module Formatters
5
5
 
6
- autoload :Bible, "cskit/formatters/bible"
7
- autoload :ScienceHealth, "cskit/formatters/science_health"
8
-
6
+ autoload :Bible, 'cskit/formatters/bible'
7
+ autoload :ScienceHealth, 'cskit/formatters/science_health'
9
8
 
10
9
  class Formatter
11
10
  attr_reader :options
@@ -16,4 +15,4 @@ module CSKit
16
15
  end
17
16
 
18
17
  end
19
- end
18
+ end
@@ -3,10 +3,9 @@
3
3
  module CSKit
4
4
  module Formatters
5
5
  module Bible
6
-
7
- autoload :BiblePlainTextFormatter, "cskit/formatters/bible/bible_plain_text_formatter"
8
- autoload :BibleHtmlFormatter, "cskit/formatters/bible/bible_html_formatter"
9
-
6
+ autoload :BibleHtmlFormatter, 'cskit/formatters/bible/bible_html_formatter'
7
+ autoload :BibleJsonFormatter, 'cskit/formatters/bible/bible_json_formatter'
8
+ autoload :BiblePlainTextFormatter, 'cskit/formatters/bible/bible_plain_text_formatter'
10
9
  end
11
10
  end
12
- end
11
+ end
@@ -5,7 +5,7 @@ module CSKit
5
5
  module Bible
6
6
  class BibleHtmlFormatter < BiblePlainTextFormatter
7
7
 
8
- protected
8
+ private
9
9
 
10
10
  def format_verse_texts(texts, verse)
11
11
  texts.each_with_index.map do |text, index|
@@ -38,4 +38,4 @@ module CSKit
38
38
  end
39
39
  end
40
40
  end
41
- end
41
+ end
@@ -0,0 +1,17 @@
1
+ # encoding: UTF-8
2
+
3
+ module CSKit
4
+ module Formatters
5
+ module Bible
6
+ class BibleJsonFormatter < CSKit::Formatters::Formatter
7
+
8
+ def format_readings(readings)
9
+ readings.map do |reading|
10
+ reading.to_hash
11
+ end
12
+ end
13
+
14
+ end
15
+ end
16
+ end
17
+ end
@@ -21,7 +21,7 @@ module CSKit
21
21
  texts.join(separator)
22
22
  end
23
23
 
24
- protected
24
+ private
25
25
 
26
26
  def join_readings(readings)
27
27
  join(
@@ -78,7 +78,7 @@ module CSKit
78
78
  end
79
79
 
80
80
  def format_starter(text, pos)
81
- pos ? "..." + text : text
81
+ pos ? '...' + text : text
82
82
  end
83
83
 
84
84
  def terminator_position(text, terminator)
@@ -114,4 +114,4 @@ module CSKit
114
114
  end
115
115
  end
116
116
  end
117
- end
117
+ end
@@ -3,10 +3,8 @@
3
3
  module CSKit
4
4
  module Formatters
5
5
  module ScienceHealth
6
-
7
- autoload :ScienceHealthPlainTextFormatter, "cskit/formatters/science_health/science_health_plain_text_formatter"
8
- autoload :ScienceHealthHtmlFormatter, "cskit/formatters/science_health/science_health_html_formatter"
9
-
6
+ autoload :ScienceHealthPlainTextFormatter, 'cskit/formatters/science_health/science_health_plain_text_formatter'
7
+ autoload :ScienceHealthHtmlFormatter, 'cskit/formatters/science_health/science_health_html_formatter'
10
8
  end
11
9
  end
12
- end
10
+ end
@@ -5,10 +5,9 @@ module CSKit
5
5
  module ScienceHealth
6
6
  class ScienceHealthHtmlFormatter < ScienceHealthPlainTextFormatter
7
7
 
8
- # _word_
9
8
  ITALICS_REGEX = /_([a-zA-Z0-9\-\.,\"\'\?]+)_/
10
9
 
11
- protected
10
+ private
12
11
 
13
12
  def format_lines(lines, citation_line)
14
13
  detect_italics(super)
@@ -23,10 +22,10 @@ module CSKit
23
22
  end
24
23
 
25
24
  def separator
26
- options[:separator] || "<br />"
25
+ options[:separator] || '<br />'
27
26
  end
28
27
 
29
28
  end
30
29
  end
31
30
  end
32
- end
31
+ end
@@ -8,7 +8,8 @@ module CSKit
8
8
  # semicolon, question mark, or period
9
9
  SENTENCE_TERMINATOR_REGEX = /[;\?\.]/
10
10
 
11
- # either a period + space, quotes, or start of line followed by the first capital letter or number.
11
+ # either a period + space, quotes, or start of line followed by the
12
+ # first capital letter or number.
12
13
  SENTENCE_START_REGEX = /(\.\s+|\.\"\s+|\.\'\s+|\?\s+|\!\s+|^)[A-Z0-9\"\']/
13
14
 
14
15
  def format_readings(readings)
@@ -23,7 +24,7 @@ module CSKit
23
24
  texts.join(separator)
24
25
  end
25
26
 
26
- protected
27
+ private
27
28
 
28
29
  def format_lines(lines, citation_line)
29
30
  lines.each_with_index.map do |line, line_index|
@@ -37,7 +38,7 @@ module CSKit
37
38
  matches = line_text.match(SENTENCE_START_REGEX)
38
39
  if matches && matches.length == 2
39
40
  offset = matches.offset(1)
40
- spaces = " " * offset.first # indent to match physical position in S&H book
41
+ spaces = ' ' * offset.first # indent to match physical position in S&H book
41
42
  spaces + line_text[matches.offset(1).last..-1]
42
43
  else
43
44
  line_text
@@ -70,4 +71,4 @@ module CSKit
70
71
  end
71
72
  end
72
73
  end
73
- end
74
+ end
data/lib/cskit/lesson.rb CHANGED
@@ -2,9 +2,7 @@
2
2
 
3
3
  module CSKit
4
4
  module Lesson
5
-
6
- autoload :Lesson, "cskit/lesson/lesson"
7
- autoload :Section, "cskit/lesson/section"
8
-
5
+ autoload :Lesson, 'cskit/lesson/lesson'
6
+ autoload :Section, 'cskit/lesson/section'
9
7
  end
10
- end
8
+ end
@@ -17,8 +17,8 @@ module CSKit
17
17
  def from_json(data)
18
18
  sections = JSON.parse(data).map do |section_data|
19
19
  Section.new(
20
- section_data["section"],
21
- section_data["readings"].inject({}) do |ret, (k, v)|
20
+ section_data['section'],
21
+ section_data['readings'].inject({}) do |ret, (k, v)|
22
22
  ret[k.to_sym] = v; ret
23
23
  end
24
24
  )
@@ -69,4 +69,4 @@ module CSKit
69
69
 
70
70
  end
71
71
  end
72
- end
72
+ end
@@ -23,4 +23,4 @@ module CSKit
23
23
 
24
24
  end
25
25
  end
26
- end
26
+ end
data/lib/cskit/parsers.rb CHANGED
@@ -2,7 +2,10 @@
2
2
 
3
3
  module CSKit
4
4
  module Parsers
5
- autoload :ScienceHealthParser, "cskit/parsers/science_health/science_health"
6
- autoload :BibleParser, "cskit/parsers/bible/bible"
5
+ autoload :Bible, 'cskit/parsers/bible'
6
+ autoload :Parser, 'cskit/parsers/parser'
7
+ autoload :ScienceHealth, 'cskit/parsers/science_health'
8
+ autoload :Token, 'cskit/parsers/token'
9
+ autoload :Tokenizer, 'cskit/parsers/tokenizer'
7
10
  end
8
- end
11
+ end
@@ -0,0 +1,10 @@
1
+ # encoding: UTF-8
2
+
3
+ module CSKit
4
+ module Parsers
5
+ module Bible
6
+ autoload :BibleParser, 'cskit/parsers/bible/bible_parser'
7
+ autoload :BibleTokenizer, 'cskit/parsers/bible/bible_tokenizer'
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,192 @@
1
+ # encoding: UTF-8
2
+
3
+ module CSKit
4
+ module Parsers
5
+ module Bible
6
+
7
+ DEFAULT_CARDINALITY = 1
8
+
9
+ Citation = Struct.new(:book, :chapter_list) do
10
+ def to_s
11
+ "#{book} #{chapter_list.map(&:to_s).join('; ')}"
12
+ end
13
+
14
+ def to_hash
15
+ {
16
+ book: book,
17
+ chapters: chapter_list.map(&:to_hash)
18
+ }
19
+ end
20
+ end
21
+
22
+ Chapter = Struct.new(:chapter_number, :verse_list) do
23
+ def to_s
24
+ "#{chapter_number}:#{verse_list.map(&:to_s).join(', ')}"
25
+ end
26
+
27
+ def to_hash
28
+ {
29
+ chapter_number: chapter_number,
30
+ verses: verse_list.map(&:to_hash)
31
+ }
32
+ end
33
+ end
34
+
35
+ Verse = Struct.new(:start, :finish, :starter, :terminator) do
36
+ def to_s
37
+ str = if start == finish
38
+ start.to_s
39
+ else
40
+ "#{start}-#{finish}"
41
+ end
42
+
43
+ str << " #{starter}" if starter
44
+ str << " (to #{terminator})" if terminator
45
+ str
46
+ end
47
+
48
+ def to_hash
49
+ {
50
+ start: start,
51
+ finish: finish,
52
+ starter: starter ? starter.to_hash : nil,
53
+ terminator: terminator ? terminator.to_hash : nil
54
+ }
55
+ end
56
+ end
57
+
58
+ Positional = Struct.new(:cardinality, :fragment) do
59
+ def to_s
60
+ card_s = case cardinality
61
+ when 1 then '1st'
62
+ when 2 then '2nd'
63
+ when 3 then '3rd'
64
+ end
65
+
66
+ if cardinality
67
+ "#{card_s} #{fragment}"
68
+ else
69
+ fragment
70
+ end
71
+ end
72
+
73
+ def to_hash
74
+ {
75
+ cardinality: cardinality,
76
+ fragment: fragment
77
+ }
78
+ end
79
+ end
80
+
81
+
82
+ class BibleParser < CSKit::Parsers::Parser
83
+ def entry_point
84
+ Citation.new(book, chapter_list)
85
+ end
86
+
87
+ private
88
+
89
+ def get_token_stream
90
+ BibleTokenizer.new(citation_text).each_token.lazy
91
+ end
92
+
93
+ def book
94
+ current.value.tap { next_token(:text) }
95
+ end
96
+
97
+ def chapter_list
98
+ [].tap do |list|
99
+ loop do
100
+ list << chapter
101
+
102
+ case current.type
103
+ when :semicolon
104
+ next_token(:semicolon)
105
+ else
106
+ break
107
+ end
108
+
109
+ break if eos?
110
+ end
111
+ end
112
+ end
113
+
114
+ def chapter
115
+ chap_num = chapter_number
116
+ next_token(:colon)
117
+ vlist = verse_list
118
+
119
+ Chapter.new(chap_num, vlist)
120
+ end
121
+
122
+ def chapter_number
123
+ current.value.tap { next_token(:number) }.to_i
124
+ end
125
+
126
+ def verse_list
127
+ [].tap do |list|
128
+ loop do
129
+ list << verse
130
+
131
+ case current.type
132
+ when :comma
133
+ next_token(:comma)
134
+ else
135
+ break
136
+ end
137
+
138
+ break if eos?
139
+ end
140
+ end
141
+ end
142
+
143
+ def verse
144
+ start = current.value.tap { next_token(:number) }.to_i
145
+ finish = start
146
+ starter = nil
147
+
148
+ if current.type == :dash
149
+ next_token(:dash)
150
+ finish = current.value.tap { next_token(:number) }.to_i
151
+ end
152
+
153
+ starter = verse_starter
154
+ terminator = verse_terminator
155
+
156
+ Verse.new(start, finish, starter, terminator)
157
+ end
158
+
159
+ def verse_starter
160
+ case current.type
161
+ when :text, :cardinality
162
+ positional
163
+ end
164
+ end
165
+
166
+ def verse_terminator
167
+ if current.type == :left_paren
168
+ next_token(:left_paren)
169
+ next_token(:to)
170
+ positional.tap { next_token(:right_paren) }
171
+ end
172
+ end
173
+
174
+ def positional
175
+ card = cardinality
176
+ fragment = current.value
177
+ next_token(:text, :semicolon, :colon, :comma)
178
+ Positional.new(card, fragment)
179
+ end
180
+
181
+ def cardinality
182
+ if current.type == :cardinality
183
+ current.value.tap { next_token(:cardinality) }.to_i
184
+ else
185
+ DEFAULT_CARDINALITY
186
+ end
187
+ end
188
+ end
189
+
190
+ end
191
+ end
192
+ end