cskit 1.0.1 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
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