epub-parser 0.3.1 → 0.3.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 655aca49d6761da9e30df396fa811d63aee8c7fb
4
- data.tar.gz: f1aad47cfbe0594fa64fbc1a09075d1ab4b7624d
3
+ metadata.gz: 0061ced06336ffbf3bcdeecdd56d91dd92d7dc01
4
+ data.tar.gz: 0ff0efba6754a25c31550f318f60041591e67729
5
5
  SHA512:
6
- metadata.gz: 4027e8135e0a87bbe18f8947cba9c3a6f6b643aa64745d08a4b89c1a944f96de1e2059dbd099243e6479d02a65e12a4967b8bd80a324dbd8119a6464d019363e
7
- data.tar.gz: 6a4cf144baf144804b27700d4fc404653f1d59ed2e2d31fd380be510b746293b85550f4e362b304b7a6a86a611da894857be4f00387a6b08ebb1a709f46df7ea
6
+ metadata.gz: 6fa942fad606d5722c09abac9caac938c3b364a3c44707940493a3aa7838ec2b6cb740bf696fbfb41c212fce44cb51d16b8ba919d4b1cd2bb72ce77a8b3f47be
7
+ data.tar.gz: ca69eb60e0ce44329c276eb3d33b6e3f564ac8432570fce70a0131dcbc2635a651249c2009d64417857bdd1c7bd4fd1bbb239b800b9574b1dff5329c6e5418db
data/.gitignore CHANGED
@@ -11,4 +11,3 @@ html/*
11
11
  NOTE
12
12
  test/fixtures/book.epub
13
13
  *~
14
- lib/epub/parser/cfi.tab.rb
@@ -1,6 +1,11 @@
1
1
  CHANGELOG
2
2
  =========
3
3
 
4
+ 0.3.2
5
+ -----
6
+
7
+ * Use epub-cfi gem for EPUB CFI
8
+
4
9
  0.3.1
5
10
  -----
6
11
 
@@ -134,7 +134,7 @@ Then documentation will be available in `doc` directory.
134
134
 
135
135
  REQUIREMENTS
136
136
  ------------
137
- * Ruby 2.1.0 or later
137
+ * Ruby 2.2.0 or later
138
138
  * `patch` command to install Nokogiri
139
139
  * C compiler to compile Nokogiri
140
140
 
@@ -145,13 +145,18 @@ Similar Efforts
145
145
  * [ReVIEW](https://github.com/kmuto/review) - ReVIEW is a easy-to-use digital publishing system for books and ebooks.
146
146
  * [epzip](https://github.com/takahashim/epzip) - epzip is EPUB packing tool. It's just only doing 'zip.' :)
147
147
  * [eeepub](https://github.com/jugyo/eeepub) - EeePub is a Ruby ePub generator
148
- * [epub-maker](https://github.com/KitaitiMakoto/epub-maker) - This library supports making and editing EPUB books based on this EPUB Parser library
148
+ * [epub-maker](https://gitlab.com/KitaitiMakoto/epub-maker) - This library supports making and editing EPUB books based on this EPUB Parser library
149
+ * [epub-cfi](https://gitlab.com/KitaitiMakoto/epub-cfi) - EPUB CFI library extracted this EPUB Parser library.
149
150
 
150
151
  If you find other gems, please tell me or request a pull request.
151
152
 
152
153
  RECENT CHANGES
153
154
  --------------
154
155
 
156
+ ### 0.3.2
157
+
158
+ * Use epub-cfi gem for EPUB CFI
159
+
155
160
  ### 0.3.1
156
161
 
157
162
  * Make `CFI` comparable. Now can call `CFI#==`
@@ -166,29 +171,6 @@ RECENT CHANGES
166
171
  * Fix a bug that `Searcher.search_element` returns wrong CFI
167
172
  * Add `Searcher.search_by_cfi`
168
173
 
169
- ### 0.2.8
170
-
171
- * Change Searcher API: #search -> #search_text
172
- * Add Searcher.search_element
173
-
174
- ### 0.2.7
175
-
176
- * Add `EPUB::Metadata#children`
177
- * Allow class including `EPUB` to intialize with extra arguments(Thanks, [skukx][]!)
178
-
179
- [skukx]: https://github.com/skukx
180
-
181
- ### 0.2.6
182
-
183
- * Add `EPUB::Publication::Package::Metadata#package_identifier` as alias of `#release_identifier`
184
- * [BUG FIX]Metadata#modified returns modified with no refiners
185
- * Make second argument for `EPUB::Parser::Publication.new` deprecated
186
- * Add META-INF/metadata.xml support defined in [EPUB Multiple-Rendition Publications 1.0][multi-rendition]
187
- * Add `EPUB::Book::Features#packages` and `#default_rendition`
188
- * [BUG FIX]Don't raise error when using `Zipruby` container adapter
189
-
190
- [multi-rendition]: http://www.idpf.org/epub/renditions/multiple/
191
-
192
174
  See {file:CHANGELOG.markdown} for older changelogs and details.
193
175
 
194
176
  TODOS
data/Rakefile CHANGED
@@ -6,17 +6,9 @@ require 'rdoc/task'
6
6
  require 'epub/parser/version'
7
7
  require 'zipruby'
8
8
 
9
- CFI_TAB = 'lib/epub/parser/cfi.tab.rb'
10
- CFI_Y = 'lib/epub/parser/cfi.y'
11
- CLEAN.include(CFI_TAB)
12
-
13
9
  task :default => :test
14
10
  task :test => 'test:default'
15
11
 
16
- file CFI_TAB do
17
- sh "racc #{CFI_Y}"
18
- end
19
-
20
12
  namespace :test do
21
13
  task :default => [:build, :test]
22
14
 
@@ -24,7 +16,7 @@ namespace :test do
24
16
  task :all => [:build, :test]
25
17
 
26
18
  desc 'Build test fixture EPUB file'
27
- task :build => [:clean, CFI_TAB] do
19
+ task :build => :clean do
28
20
  input_dir = 'test/fixtures/book'
29
21
  sh "epzip #{input_dir}"
30
22
  small_file = File.read("#{input_dir}/OPS/case-sensitive.xhtml")
@@ -57,7 +49,7 @@ end
57
49
  Gem::Tasks.new do |tasks|
58
50
  tasks.console.command = 'pry'
59
51
  end
60
- task :build => [:clean, CFI_TAB]
52
+ task :build => :clean
61
53
 
62
54
  class ForwardableDefDelegatorsHandler < YARD::Handlers::Ruby::Base
63
55
  handles method_call(:def_delegators)
@@ -142,7 +142,8 @@ Then documentation will be available in `doc` directory.
142
142
  Requirements
143
143
  ------------
144
144
 
145
- * Ruby 2.0.0 or later
145
+ * Ruby 2.2.0 or later
146
+ * `patch` command to install Nokogiri
146
147
  * C compiler to compile Zip/Ruby and Nokogiri
147
148
 
148
149
  Note
@@ -14,7 +14,6 @@ Gem::Specification.new do |s|
14
14
  s.required_ruby_version = '> 2'
15
15
 
16
16
  s.files = `git ls-files`.split("\n")
17
- .push('lib/epub/parser/cfi.tab.rb')
18
17
  .push('test/fixtures/book/OPS/ルートファイル.opf')
19
18
  .push('test/fixtures/book/OPS/日本語.xhtml')
20
19
  .push(Dir['docs/*.md'])
@@ -46,4 +45,5 @@ Gem::Specification.new do |s|
46
45
  s.add_runtime_dependency 'nokogiri', '~> 1.6'
47
46
  s.add_runtime_dependency 'addressable', '>= 2.3.5'
48
47
  s.add_runtime_dependency 'rchardet', '>= 1.6.1'
48
+ s.add_runtime_dependency 'epub-cfi'
49
49
  end
@@ -30,7 +30,7 @@
30
30
  # Accessibility is a difficult concept to define.
31
31
 
32
32
  require 'epub/parser'
33
- require 'epub/parser/cfi'
33
+ require 'epub/cfi'
34
34
  require 'nokogiri' # Do gem install nokogiri
35
35
  require 'nokogiri/xml/range' # Do gem install nokogiri-xml-range
36
36
 
@@ -1,6 +1,6 @@
1
1
  require 'English'
2
2
  require 'epub/parser'
3
- require 'epub/parser/cfi'
3
+ require 'epub/cfi'
4
4
  require 'nokogiri'
5
5
 
6
6
  def usage
@@ -1,5 +1,5 @@
1
1
  module EPUB
2
2
  class Parser
3
- VERSION = "0.3.1"
3
+ VERSION = "0.3.2"
4
4
  end
5
5
  end
@@ -1,5 +1,4 @@
1
1
  require 'epub/cfi'
2
- require 'epub/parser/cfi'
3
2
 
4
3
  module EPUB
5
4
  module Searcher
@@ -1,7 +1,7 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  require_relative 'helper'
3
3
  require 'epub/searcher'
4
- require 'epub/parser/cfi'
4
+ require 'epub/cfi'
5
5
 
6
6
  class TestSearcher < Test::Unit::TestCase
7
7
  class TestPublication < self
@@ -40,7 +40,7 @@ class TestSearcher < Test::Unit::TestCase
40
40
  "epubcfi(/6/2!/4/2/2[idid]/4/4/4/6/2)",
41
41
  "epubcfi(/6/2!/4/2/2[idid]/4/4/4/8/2)"
42
42
  ],
43
- EPUB::Searcher::Publication.search_element(@package, xpath: './/xhtml:a').collect {|result| result[:location]}.map(&:to_fragment)
43
+ EPUB::Searcher::Publication.search_element(@package, xpath: './/xhtml:a').collect {|result| result[:location]}.map(&:to_s)
44
44
  )
45
45
  end
46
46
 
@@ -53,7 +53,7 @@ class TestSearcher < Test::Unit::TestCase
53
53
  "epubcfi(/6/2!/4/2/2[idid]/4/4/4/6/2)",
54
54
  "epubcfi(/6/2!/4/2/2[idid]/4/4/4/8/2)"
55
55
  ],
56
- EPUB::Searcher::Publication.search_element(@package, xpath: './/customnamespace:a', namespaces: {'customnamespace' => 'http://www.w3.org/1999/xhtml'}).collect {|result| result[:location]}.map(&:to_fragment)
56
+ EPUB::Searcher::Publication.search_element(@package, xpath: './/customnamespace:a', namespaces: {'customnamespace' => 'http://www.w3.org/1999/xhtml'}).collect {|result| result[:location]}.map(&:to_s)
57
57
  )
58
58
  end
59
59
 
@@ -67,13 +67,13 @@ class TestSearcher < Test::Unit::TestCase
67
67
  "epubcfi(/6/2!/4/2/2[idid]/4/4/4/6)",
68
68
  "epubcfi(/6/2!/4/2/2[idid]/4/4/4/8)"
69
69
  ],
70
- EPUB::Searcher::Publication.search_element(@package, css: 'ol > li').collect {|result| result[:location]}.map(&:to_fragment)
70
+ EPUB::Searcher::Publication.search_element(@package, css: 'ol > li').collect {|result| result[:location]}.map(&:to_s)
71
71
  )
72
72
  end
73
73
 
74
74
  class TesetResult < self
75
75
  def test_to_cfi
76
- assert_equal 'epubcfi(/6/2!/4/2/2[idid]/2/4/1,:9,:16)', EPUB::Searcher::Publication.search_text(@package, 'Content').last.to_cfi.to_fragment
76
+ assert_equal 'epubcfi(/6/2!/4/2/2[idid]/2/4/1,:9,:16)', EPUB::Searcher::Publication.search_text(@package, 'Content').last.to_cfi.to_s
77
77
  end
78
78
  end
79
79
  end
@@ -151,11 +151,11 @@ class TestSearcher < Test::Unit::TestCase
151
151
  end
152
152
 
153
153
  def test_to_cfi
154
- assert_equal 'epubcfi(/4/2/2[idid]/4/4/4/4/2/1,:0,:3)', @result.to_cfi.to_fragment
154
+ assert_equal 'epubcfi(/4/2/2[idid]/4/4/4/4/2/1,:0,:3)', @result.to_cfi.to_s
155
155
  end
156
156
 
157
157
  def test_to_cfi_img
158
- assert_equal 'epubcfi(/4/2/2[idid]/4/4/4/6/2/2)', EPUB::Searcher::XHTML::Restricted.search_text(@doc, '第三節').first.to_cfi.to_fragment
158
+ assert_equal 'epubcfi(/4/2/2[idid]/4/4/4/6/2/2)', EPUB::Searcher::XHTML::Restricted.search_text(@doc, '第三節').first.to_cfi.to_s
159
159
  end
160
160
  end
161
161
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: epub-parser
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.1
4
+ version: 0.3.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - KITAITI Makoto
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-02-12 00:00:00.000000000 Z
11
+ date: 2017-08-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -290,6 +290,20 @@ dependencies:
290
290
  - - ">="
291
291
  - !ruby/object:Gem::Version
292
292
  version: 1.6.1
293
+ - !ruby/object:Gem::Dependency
294
+ name: epub-cfi
295
+ requirement: !ruby/object:Gem::Requirement
296
+ requirements:
297
+ - - ">="
298
+ - !ruby/object:Gem::Version
299
+ version: '0'
300
+ type: :runtime
301
+ prerelease: false
302
+ version_requirements: !ruby/object:Gem::Requirement
303
+ requirements:
304
+ - - ">="
305
+ - !ruby/object:Gem::Version
306
+ version: '0'
293
307
  description: Parse EPUB 3 book loosely
294
308
  email:
295
309
  - KitaitiMakoto@gmail.com
@@ -302,8 +316,6 @@ files:
302
316
  - ".gemtest"
303
317
  - ".gitignore"
304
318
  - ".gitlab-ci.yml"
305
- - ".gitmodules"
306
- - ".travis.yml"
307
319
  - ".yardopts"
308
320
  - CHANGELOG.markdown
309
321
  - Gemfile
@@ -330,7 +342,6 @@ files:
330
342
  - lib/epub.rb
331
343
  - lib/epub/book.rb
332
344
  - lib/epub/book/features.rb
333
- - lib/epub/cfi.rb
334
345
  - lib/epub/constants.rb
335
346
  - lib/epub/content_document.rb
336
347
  - lib/epub/content_document/navigation.rb
@@ -350,9 +361,6 @@ files:
350
361
  - lib/epub/ocf/rights.rb
351
362
  - lib/epub/ocf/signatures.rb
352
363
  - lib/epub/parser.rb
353
- - lib/epub/parser/cfi.rb
354
- - lib/epub/parser/cfi.tab.rb
355
- - lib/epub/parser/cfi.y
356
364
  - lib/epub/parser/content_document.rb
357
365
  - lib/epub/parser/metadata.rb
358
366
  - lib/epub/parser/ocf.rb
@@ -386,14 +394,12 @@ files:
386
394
  - test/fixtures/book/OPS/日本語.xhtml
387
395
  - test/fixtures/book/mimetype
388
396
  - test/helper.rb
389
- - test/test_cfi.rb
390
397
  - test/test_content_document.rb
391
398
  - test/test_epub.rb
392
399
  - test/test_fixed_layout.rb
393
400
  - test/test_inspect.rb
394
401
  - test/test_ocf_physical_container.rb
395
402
  - test/test_parser.rb
396
- - test/test_parser_cfi.rb
397
403
  - test/test_parser_content_document.rb
398
404
  - test/test_parser_fixed_layout.rb
399
405
  - test/test_parser_ocf.rb
@@ -420,20 +426,18 @@ required_rubygems_version: !ruby/object:Gem::Requirement
420
426
  version: '0'
421
427
  requirements: []
422
428
  rubyforge_project:
423
- rubygems_version: 2.6.8
429
+ rubygems_version: 2.6.11
424
430
  signing_key:
425
431
  specification_version: 4
426
432
  summary: EPUB 3 Parser
427
433
  test_files:
428
434
  - test/helper.rb
429
- - test/test_cfi.rb
430
435
  - test/test_content_document.rb
431
436
  - test/test_epub.rb
432
437
  - test/test_fixed_layout.rb
433
438
  - test/test_inspect.rb
434
439
  - test/test_ocf_physical_container.rb
435
440
  - test/test_parser.rb
436
- - test/test_parser_cfi.rb
437
441
  - test/test_parser_content_document.rb
438
442
  - test/test_parser_fixed_layout.rb
439
443
  - test/test_parser_ocf.rb
@@ -1,3 +0,0 @@
1
- [submodule "wiki"]
2
- path = wiki
3
- url = git://github.com/KitaitiMakoto/epub-parser.wiki.git
@@ -1,4 +0,0 @@
1
- rvm:
2
- - "2.2.5"
3
- - "2.3.1"
4
- - "2.4.0"
@@ -1,313 +0,0 @@
1
- module EPUB
2
- module CFI
3
- SPECIAL_CHARS = '^[](),;=' # "5E", "5B", "5D", "28", "29", "2C", "3B", "3D"
4
- RE_ESCAPED_SPECIAL_CHARS = Regexp.escape(SPECIAL_CHARS)
5
-
6
- class << self
7
- def escape(string)
8
- string.gsub(/([#{RE_ESCAPED_SPECIAL_CHARS}])/o, '^\1')
9
- end
10
-
11
- def unescape(string)
12
- string.gsub(/\^([#{RE_ESCAPED_SPECIAL_CHARS}])/o, '\1')
13
- end
14
- end
15
-
16
- class Location
17
- include Comparable
18
-
19
- attr_reader :paths
20
-
21
- def initialize(paths=[])
22
- @paths = paths
23
- end
24
-
25
- def initialize_copy(original)
26
- @paths = original.paths.collect(&:dup)
27
- end
28
-
29
- def type
30
- @paths.last.type
31
- end
32
-
33
- def <=>(other)
34
- index = 0
35
- other_paths = other.paths
36
- cmp = nil
37
- paths.each do |path|
38
- other_path = other_paths[index]
39
- return 1 unless other_path
40
- cmp = path <=> other_path
41
- break unless cmp == 0
42
- index += 1
43
- end
44
-
45
- unless cmp == 0
46
- if cmp == 1 and paths[index].offset and other_paths[index + 1]
47
- return nil
48
- else
49
- return cmp
50
- end
51
- end
52
-
53
- return nil if paths.last.offset && other_paths[index]
54
-
55
- return -1 if other_paths[index]
56
-
57
- 0
58
- end
59
-
60
- def to_s
61
- paths.join('!')
62
- end
63
-
64
- def to_fragment
65
- "epubcfi(#{self})"
66
- end
67
-
68
- def join(*other_paths)
69
- new_paths = paths.dup
70
- other_paths.each do |path|
71
- new_paths << path
72
- end
73
- self.class.new(new_paths)
74
- end
75
- end
76
-
77
- class Path
78
- attr_reader :steps, :offset
79
-
80
- def initialize(steps=[], offset=nil)
81
- @steps, @offset = steps, offset
82
- end
83
-
84
- def initialize_copy(original)
85
- @steps = original.steps.collect(&:dup)
86
- @offset = original.offset.dup if original.offset
87
- end
88
-
89
- def to_s
90
- @string_cache ||= (steps.join + offset.to_s)
91
- end
92
-
93
- def to_fragment
94
- @fragment_cache ||= "epubcfi(#{self})"
95
- end
96
-
97
- def <=>(other)
98
- other_steps = other.steps
99
- index = 0
100
- steps.each do |step|
101
- other_step = other_steps[index]
102
- return 1 unless other_step
103
- cmp = step <=> other_step
104
- return cmp unless cmp == 0
105
- index += 1
106
- end
107
-
108
- return -1 if other_steps[index]
109
-
110
- other_offset = other.offset
111
- if offset
112
- if other_offset
113
- offset <=> other_offset
114
- else
115
- 1
116
- end
117
- else
118
- if other_offset
119
- -1
120
- else
121
- 0
122
- end
123
- end
124
- end
125
-
126
- def each_step_with_instruction
127
- yield [step, nil]
128
- local_path.each_step_with_instruction do |s, instruction|
129
- yield [s, instruction]
130
- end
131
- self
132
- end
133
- end
134
-
135
- class Range < ::Range
136
- attr_accessor :parent, :start, :end
137
-
138
- # @todo consider the case subpaths are redirected path
139
- # @todo FIXME: too dirty
140
- class << self
141
- def from_parent_and_start_and_end(parent_path, start_subpath, end_subpath)
142
- start_str = start_subpath.join
143
- end_str = end_subpath.join
144
-
145
- first_paths = parent_path.collect(&:dup)
146
- if start_subpath
147
- offset_of_first = start_subpath.last.offset
148
- offset_of_first = offset_of_first.dup if offset_of_first
149
- last_of_first_paths = first_paths.pop
150
- first_paths << last_of_first_paths
151
- last_of_first_paths.steps.concat start_subpath.shift.steps
152
- first_paths.concat start_subpath
153
- first_paths.last.instance_variable_set :@offset, offset_of_first
154
- end
155
- offset_of_last = end_subpath.last.offset
156
- offset_of_last = offset_of_last.dup if offset_of_last
157
- last_paths = parent_path.collect(&:dup)
158
- last_of_last_paths = last_paths.pop
159
- last_paths << last_of_last_paths
160
- last_of_last_paths.steps.concat end_subpath.shift.steps
161
- last_paths.concat end_subpath
162
- last_paths.last.instance_variable_set :@offset, offset_of_last
163
-
164
- first = CFI::Location.new(first_paths)
165
- last = CFI::Location.new(last_paths)
166
-
167
- new_range = new(first, last)
168
-
169
- new_range.parent = Location.new(parent_path)
170
- new_range.start = start_str
171
- new_range.end = end_str
172
-
173
- new_range
174
- end
175
- end
176
-
177
- def to_s
178
- @string_cache ||= (first.to_fragment + (exclude_end? ? '...' : '..') + last.to_fragment)
179
- end
180
-
181
- def to_fragment
182
- @fragment_cache ||= "epubcfi(#{@parent},#{@start},#{@end})"
183
- end
184
- end
185
-
186
- class Step
187
- attr_reader :value, :assertion
188
- alias step value
189
-
190
- def initialize(value, assertion=nil)
191
- @value, @assertion = value, assertion
192
- @string_cache = nil
193
- end
194
-
195
- def initialize_copy(original)
196
- @value = original.value
197
- @assertion = original.assertion.dup if original.assertion
198
- end
199
-
200
- def to_s
201
- @string_cache ||= "/#{value}#{assertion}" # need escape?
202
- end
203
-
204
- def <=>(other)
205
- value <=> other.value
206
- end
207
-
208
- def element?
209
- value.even?
210
- end
211
-
212
- def character_data?
213
- value.odd?
214
- end
215
- end
216
-
217
- class IDAssertion
218
- attr_reader :id, :parameters
219
-
220
- def initialize(id, parameters={})
221
- @id, @parameters = id, parameters
222
- @string_cache = nil
223
- end
224
-
225
- def to_s
226
- return @string_cache if @string_cache
227
- string_cache = '['
228
- string_cache << CFI.escape(id) if id
229
- parameters.each_pair do |key, values|
230
- value = values.join(',')
231
- string_cache << ";#{CFI.escape(key)}=#{CFI.escape(value)}"
232
- end
233
- string_cache << ']'
234
- @string_cache = string_cache
235
- end
236
- end
237
-
238
- class TextLocationAssertion
239
- attr_reader :preceded, :followed, :parameters
240
-
241
- def initialize(preceded=nil, followed=nil, parameters={})
242
- @preceded, @followed, @parameters = preceded, followed, parameters
243
- @string_cache = nil
244
- end
245
-
246
- def to_s
247
- return @string_cache if @string_cache
248
- string_cache = '['
249
- string_cache << CFI.escape(preceded) if preceded
250
- string_cache << ',' << CFI.escape(followed) if followed
251
- parameters.each_pair do |key, values|
252
- value = values.join(',')
253
- string_cache << ";#{CFI.escape(key)}=#{CFI.escape(value)}"
254
- end
255
- string_cache << ']'
256
- @string_cache = string_cache
257
- end
258
- end
259
-
260
- class CharacterOffset
261
- attr_reader :value, :assertion
262
- alias offset value
263
-
264
- def initialize(value, assertion=nil)
265
- @value, @assertion = value, assertion
266
- @string_cache = nil
267
- end
268
-
269
- def to_s
270
- @string_cache ||= ":#{value}#{assertion}" # need escape?
271
- end
272
-
273
- def <=>(other)
274
- value <=> other.value
275
- end
276
- end
277
-
278
- class TemporalSpatialOffset
279
- attr_reader :temporal, :x, :y, :assertion
280
-
281
- def initialize(temporal=nil, x=nil, y=nil, assertion=nil)
282
- raise RangeError, "dimension must be in 0..100 but passed #{x}" unless (0.0..100.0).cover?(x) if x
283
- raise RangeError, "dimension must be in 0..100 but passed #{y}" unless (0.0..100.0).cover?(y) if y
284
- warn "Assertion is passed to #{__class__} but cannot know how to handle with it: #{assertion}" if assertion
285
- @temporal, @x, @y, @assertion = temporal, x, y, assertion
286
- @string_cache = nil
287
- end
288
-
289
- def to_s
290
- return @string_cache if @string_cache
291
- string_cache = ''
292
- string_cache << "~#{temporal}" if temporal
293
- string_cache << "@#{x}:#{y}" if x or y
294
- @string_cache = string_cache
295
- end
296
-
297
- # @note should split the class to spatial offset and temporal-spatial offset?
298
- def <=>(other)
299
- return -1 if temporal.nil? and other.temporal
300
- return 1 if temporal and other.temporal.nil?
301
- cmp = temporal <=> other.temporal
302
- return cmp unless cmp == 0
303
- return -1 if y.nil? and other.y
304
- return 1 if y and other.y.nil?
305
- cmp = y <=> other.y
306
- return cmp unless cmp == 0
307
- return -1 if x.nil? and other.x
308
- return 1 if x and other.x.nil?
309
- cmp = x <=> other.x
310
- end
311
- end
312
- end
313
- end
@@ -1,85 +0,0 @@
1
- require 'strscan'
2
- require 'epub/parser'
3
- require 'epub/parser/cfi.tab'
4
- require 'epub/cfi'
5
-
6
- EPUB::Parser::CFI = EPUB::CFIParser
7
-
8
- class EPUB::Parser::CFI
9
- include Comparable
10
-
11
- UNICODE_CHARACTER_EXCLUDING_SPECIAL_CHARS_AND_SPACE_AND_DOT_AND_COLON_AND_TILDE_AND_ATMARK_AND_SOLIDUS_AND_EXCLAMATION_MARK_PATTERN = /\u0009|\u000A|\u000D|[\u0022-\u0027]|[\u002A-\u002B]|\u002D|[\u0030-\u0039]|\u003C|[\u003E-\u0040]|[\u0041-\u005A]|\u005C|[\u005F-\u007D]|[\u007F-\uD7FF]|[\uE000-\uFFFD]|[\u10000-\u10FFFF]/ # excluding special chars and space(\u0020) and dot(\u002E) and colon(\u003A) and tilde(\u007E) and atmark(\u0040) and solidus(\u002F) and exclamation mark(\u0021)
12
- UNICODE_CHARACTER_PATTERN = Regexp.union(UNICODE_CHARACTER_EXCLUDING_SPECIAL_CHARS_AND_SPACE_AND_DOT_AND_COLON_AND_TILDE_AND_ATMARK_AND_SOLIDUS_AND_EXCLAMATION_MARK_PATTERN, Regexp.new(Regexp.escape(EPUB::CFI::SPECIAL_CHARS), / \.:~@!/))
13
-
14
- class << self
15
- def parse(string, debug: false)
16
- new(debug: debug).parse(string)
17
- end
18
- end
19
-
20
- def initialize(debug: false)
21
- @yydebug = debug
22
- super()
23
- end
24
-
25
- def parse(string)
26
- if string.start_with? 'epubcfi('
27
- string = string['epubcfi('.length .. -2]
28
- end
29
- @scanner = StringScanner.new(string, true)
30
- @q = []
31
- until @scanner.eos?
32
- case
33
- when @scanner.scan(/[1-9]/)
34
- @q << [:DIGIT_NON_ZERO, @scanner[0]]
35
- when @scanner.scan(/0/)
36
- @q << [:ZERO, @scanner[0]]
37
- when @scanner.scan(/ /)
38
- @q << [:SPACE, @scanner[0]]
39
- when @scanner.scan(/\^/)
40
- @q << [:CIRCUMFLEX, @scanner[0]]
41
- when @scanner.scan(/\[/)
42
- @q << [:OPENING_SQUARE_BRACKET, @scanner[0]]
43
- when @scanner.scan(/\]/)
44
- @q << [:CLOSING_SQUARE_BRACKET, @scanner[0]]
45
- when @scanner.scan(/\(/)
46
- @q << [:OPENING_PARENTHESIS, @scanner[0]]
47
- when @scanner.scan(/\)/)
48
- @q << [:CLOSING_PARENTHESIS, @scanner[0]]
49
- when @scanner.scan(/,/)
50
- @q << [:COMMA, @scanner[0]]
51
- when @scanner.scan(/;/)
52
- @q << [:SEMICOLON, @scanner[0]]
53
- when @scanner.scan(/=/)
54
- @q << [:EQUAL, @scanner[0]]
55
- when @scanner.scan(/\./)
56
- @q << [:DOT, @scanner[0]]
57
- when @scanner.scan(/:/)
58
- @q << [:COLON, @scanner[0]]
59
- when @scanner.scan(/~/)
60
- @q << [:TILDE, @scanner[0]]
61
- when @scanner.scan(/@/)
62
- @q << [:ATMARK, @scanner[0]]
63
- when @scanner.scan(/\//)
64
- @q << [:SOLIDUS, @scanner[0]]
65
- when @scanner.scan(/!/)
66
- @q << [:EXCLAMATION_MARK, @scanner[0]]
67
- when @scanner.scan(UNICODE_CHARACTER_EXCLUDING_SPECIAL_CHARS_AND_SPACE_AND_DOT_AND_COLON_AND_TILDE_AND_ATMARK_AND_SOLIDUS_AND_EXCLAMATION_MARK_PATTERN)
68
- @q << [:UNICODE_CHARACTER_EXCLUDING_SPECIAL_CHARS_AND_SPACE_AND_DOT_AND_COLON_AND_TILDE_AND_ATMARK_AND_SOLIDUS_AND_EXCLAMATION_MARK, @scanner[0]]
69
- else
70
- raise 'unexpected character'
71
- end
72
- end
73
- @q << [false, false]
74
-
75
- do_parse
76
- end
77
-
78
- def next_token
79
- @q.shift
80
- end
81
- end
82
-
83
- def EPUB::CFI(string)
84
- EPUB::Parser::CFI.parse('epubcfi(' + string + ')')
85
- end
@@ -1,187 +0,0 @@
1
- # EPUB::Parser::CFI is prefered but cannot be used.
2
- # Racc automatically declare module EPUB::Parser
3
- # but EPUB::Parser have been declared as a class.
4
- class EPUB::CFIParser
5
- rule
6
-
7
- fragment : path range_zero_or_one
8
- {
9
- if val[1]
10
- result = CFI::Range.from_parent_and_start_and_end(val[0], *val[1])
11
- else
12
- result = CFI::Location.new(val[0])
13
- end
14
- }
15
-
16
- range_zero_or_one : range
17
- |
18
-
19
- path : step local_path
20
- {
21
- path, redirected_path = *val[1]
22
- path.steps.unshift val[0]
23
- result = val[1]
24
- }
25
-
26
- range : COMMA local_path COMMA local_path
27
- {result = [val[1], val[3]]}
28
-
29
- local_path : step_zero_or_more redirected_path
30
- {result = [CFI::Path.new(val[0])] + val[1]}
31
- | step_zero_or_more offset_zero_or_one
32
- {result = [CFI::Path.new(val[0], val[1])]}
33
-
34
- step_zero_or_more : step_zero_or_more step
35
- {result = val[0] + [val[1]]}
36
- | step
37
- {result = [val[0]]}
38
- |
39
- {result = []}
40
-
41
- redirected_path : EXCLAMATION_MARK offset
42
- {result = [CFI::Path.new([], val[1])]}
43
- | EXCLAMATION_MARK path
44
- {result = val[1]}
45
-
46
- step : SOLIDUS integer assertion_part_zero_or_one
47
- {
48
- assertion = val[2] ? CFI::IDAssertion.new(val[2][0], val[2][2]) : nil
49
- result = CFI::Step.new(val[1].to_i, assertion)
50
- }
51
-
52
- offset_zero_or_one : offset
53
- |
54
-
55
- offset : COLON integer assertion_part_zero_or_one
56
- {
57
- assertion = val[2] ? CFI::TextLocationAssertion.new(*val[2]) : nil
58
- result = CFI::CharacterOffset.new(val[1].to_i, assertion)
59
- }
60
- | spatial_offset assertion_part_zero_or_one
61
- {result = CFI::TemporalSpatialOffset.new(nil, val[0][0].to_f, val[0][1].to_f, val[2])}
62
- | TILDE number spatial_offset_zero_or_one assertion_part_zero_or_one
63
- {
64
- x = val[2] ? val[2][0].to_f : nil
65
- y = val[2] ? val[2][1].to_f : nil
66
- result = CFI::TemporalSpatialOffset.new(val[1].to_f, x, y, val[3])
67
- }
68
-
69
- spatial_offset_zero_or_one : spatial_offset
70
- |
71
-
72
- spatial_offset : ATMARK number COLON number
73
- {result = [val[1], val[3]]}
74
-
75
- assertion_part_zero_or_one : opening_square_bracket assertion closing_square_bracket
76
- {result = val[1]}
77
- |
78
-
79
- number : DIGIT_NON_ZERO digit_zero_or_more fractional_portion_zero_or_one
80
- {result = val.join}
81
- | ZERO fractional_portion_zero_or_one
82
- {result = val.join}
83
-
84
- fractional_portion_zero_or_one : fractional_portion
85
- |
86
-
87
- fractional_portion : DOT digit_zero_or_more DIGIT_NON_ZERO
88
- {result = val.join}
89
- | DOT DIGIT_NON_ZERO
90
- {result = val.join}
91
-
92
- integer : ZERO
93
- | DIGIT_NON_ZERO digit_zero_or_more
94
- {result = val.join}
95
-
96
- digit_zero_or_more : digit_zero_or_more digit
97
- {result = val.join}
98
- | digit
99
- |
100
-
101
- assertion : value_csv_one_or_two parameter_zero_or_more
102
- {result = [val[0][0], val[0][1], val[1]]} # Cannot see id assertion or text location assertion when val[0]'s length is 1. It can be done by context.
103
- | COMMA value parameter_zero_or_more
104
- {result = [nil, val[1], val[2]]}
105
- | parameter parameter_zero_or_more
106
- {result = [nil, nil, val[0].merge(val[1])]} # Cannot see id assertion or text location assertion when val[0]'s length is 1. It can be done by context. In EPUBCFI 3.0.1 spec, only side-bias parameter is defined and we can say it's text location assertion of the assertion has parameters. But when the spec is extended and other parameter definitions added, we might become not able to say so.
107
-
108
- value_csv_one_or_two : value COMMA value
109
- {result = [val[0], val[2]]}
110
- | value
111
- {result = [val[0]]}
112
-
113
- parameter_zero_or_more : parameter_zero_or_more parameter
114
- {result = val[0].merge(val[1])}
115
- | parameter
116
- {result = val[0]}
117
- |
118
- {result = {}}
119
-
120
- parameter : SEMICOLON value_no_space EQUAL csv
121
- {result = {val[1] => val[3]}}
122
-
123
- csv : csv COMMA value
124
- {result = val[0] + [val[2]]}
125
- | value
126
- {result = [val[0]]}
127
-
128
- value : string_escaped_special_chars
129
- {result = val[0]}
130
-
131
- value_no_space: string_escaped_special_chars_excluding_space
132
-
133
- escaped_special_chars : CIRCUMFLEX CIRCUMFLEX
134
- {result = val[1]}
135
- | CIRCUMFLEX square_brackets
136
- {result = val[1]}
137
- | CIRCUMFLEX parentheses
138
- {result = val[1]}
139
- | CIRCUMFLEX COMMA
140
- {result = val[1]}
141
- | CIRCUMFLEX SEMICOLON
142
- {result = val[1]}
143
- | CIRCUMFLEX EQUAL
144
- {result = val[1]}
145
-
146
- character_escaped_special : character_excluding_special_chars
147
- | escaped_special_chars
148
-
149
- string_escaped_special_chars : string_escaped_special_chars character_escaped_special
150
- {result = val.join}
151
- | character_escaped_special
152
- {result = val[0]}
153
-
154
- string_escaped_special_chars_excluding_space : string_escaped_special_chars_excluding_space character_escaped_special_excluding_space
155
- | character_escaped_special_excluding_space
156
-
157
- character_escaped_special_excluding_space : character_excluding_special_chars_and_space
158
- | escaped_special_chars
159
-
160
- digit : ZERO
161
- | DIGIT_NON_ZERO
162
-
163
- square_brackets : opening_square_bracket
164
- | closing_square_bracket
165
-
166
- opening_square_bracket : OPENING_SQUARE_BRACKET
167
-
168
- closing_square_bracket : CLOSING_SQUARE_BRACKET
169
-
170
- parentheses : OPENING_PARENTHESIS
171
- | CLOSING_PARENTHESIS
172
-
173
- character_excluding_special_chars : character_excluding_special_chars_and_space
174
- | SPACE
175
-
176
- character_excluding_special_chars_and_space : character_excluding_special_chars_and_space_and_dot_and_colon_and_tilde_and_atmark_and_solidus_and_exclamation_mark
177
- | DOT
178
- | COLON
179
- | TILDE
180
- | ATMARK
181
- | SOLIDUS
182
- | EXCLAMATION_MARK
183
-
184
- character_excluding_special_chars_and_space_and_dot_and_colon_and_tilde_and_atmark_and_solidus_and_exclamation_mark : UNICODE_CHARACTER_EXCLUDING_SPECIAL_CHARS_AND_SPACE_AND_DOT_AND_COLON_AND_TILDE_AND_ATMARK_AND_SOLIDUS_AND_EXCLAMATION_MARK
185
- | digit
186
-
187
- end
@@ -1,227 +0,0 @@
1
- # coding: utf-8
2
- require_relative 'helper'
3
- require 'epub/cfi'
4
- require 'epub/parser/cfi'
5
- require 'nokogiri/diff'
6
-
7
- class TestCFI < Test::Unit::TestCase
8
- def test_escape
9
- assert_equal '^^^[^]^(^)^,^;^=', EPUB::CFI.escape('^[](),;=')
10
- end
11
-
12
- def test_unescape
13
- assert_equal '^[](),;=', EPUB::CFI.unescape('^^^[^]^(^)^,^;^=')
14
- end
15
-
16
- class TestPath < self
17
- data([
18
- '/6/14[chap05ref]!/4[body01]/10/2/1:3[2^[1^]]',
19
- '/6/4!/4/10/2/1:3[Ф-"spa ce"-99%-aa^[bb^]^^]',
20
- '/6/4!/4/10/2/1:3[Ф-"spa%20ce"-99%25-aa^[bb^]^^]',
21
- '/6/4!/4/10/2/1:3[%d0%a4-"spa%20ce"-99%25-aa^[bb^]^^]',
22
- '/6/4[chap01ref]!/4[body01]/10[para05]/2/1:3[yyy]',
23
- '/6/4[chap01ref]!/4[body01]/10[para05]/1:3[xx,y]',
24
- '/6/4[chap01ref]!/4[body01]/10[para05]/2/1:3[,y]',
25
- '/6/4[chap01ref]!/4[body01]/10[para05]/2/1:3[;s=b]',
26
- '/6/4[chap01ref]!/4[body01]/10[para05]/2/1:3[yyy;s=b]',
27
- '/6/4[chap01ref]!/4[body01]/10[para05]/2[;s=b]',
28
- '/6/4[chap01ref]!/4[body01]/10[para05]/3:10',
29
- '/6/4[chap01ref]!/4[body01]/16[svgimg]',
30
- '/6/4[chap01ref]!/4[body01]/10[para05]/1:0',
31
- '/6/4[chap01ref]!/4[body01]/10[para05]/2/1:0',
32
- '/6/4[chap01ref]!/4[body01]/10[para05]/2/1:3',
33
- ].reduce({}) {|data, cfi|
34
- data[cfi] = cfi
35
- data
36
- })
37
- def test_to_s(cfi)
38
- assert_equal cfi, epubcfi(cfi).to_s
39
- end
40
-
41
- data([
42
- 'epubcfi(/6/14[chap05ref]!/4[body01]/10/2/1:3[2^[1^]])',
43
- 'epubcfi(/6/4!/4/10/2/1:3[Ф-"spa ce"-99%-aa^[bb^]^^])',
44
- 'epubcfi(/6/4!/4/10/2/1:3[Ф-"spa%20ce"-99%25-aa^[bb^]^^])',
45
- 'epubcfi(/6/4!/4/10/2/1:3[%d0%a4-"spa%20ce"-99%25-aa^[bb^]^^])',
46
- 'epubcfi(/6/4[chap01ref]!/4[body01]/10[para05]/2/1:3[yyy])',
47
- 'epubcfi(/6/4[chap01ref]!/4[body01]/10[para05]/1:3[xx,y])',
48
- 'epubcfi(/6/4[chap01ref]!/4[body01]/10[para05]/2/1:3[,y])',
49
- 'epubcfi(/6/4[chap01ref]!/4[body01]/10[para05]/2/1:3[;s=b])',
50
- 'epubcfi(/6/4[chap01ref]!/4[body01]/10[para05]/2/1:3[yyy;s=b])',
51
- 'epubcfi(/6/4[chap01ref]!/4[body01]/10[para05]/2[;s=b])',
52
- 'epubcfi(/6/4[chap01ref]!/4[body01]/10[para05]/3:10)',
53
- 'epubcfi(/6/4[chap01ref]!/4[body01]/16[svgimg])',
54
- 'epubcfi(/6/4[chap01ref]!/4[body01]/10[para05]/1:0)',
55
- 'epubcfi(/6/4[chap01ref]!/4[body01]/10[para05]/2/1:0)',
56
- 'epubcfi(/6/4[chap01ref]!/4[body01]/10[para05]/2/1:3)',
57
- ].reduce({}) {|data, cfi|
58
- data[cfi] = cfi
59
- data
60
- })
61
- def test_to_fragment(cfi)
62
- assert_equal cfi, EPUB::Parser::CFI.parse(cfi).to_fragment
63
- end
64
-
65
- def test_compare
66
- assert_equal -1, epubcfi('/6/4[id]') <=> epubcfi('/6/5')
67
- assert_equal 0, epubcfi('/6/4') <=> epubcfi('/6/4')
68
- assert_equal 1, epubcfi('/6/4') <=> epubcfi('/4/6')
69
- assert_equal 1, epubcfi('/6/4!/4@3:7') <=> epubcfi('/6/4!/4')
70
- assert_equal 1,
71
- epubcfi('/6/4[chap01ref]!/4[body01]/10[para05]/2/1:3[yyy]') <=>
72
- epubcfi('/6/4[chap01ref]!/4[body01]/10[para05]/1:3[xx,y]')
73
- assert_nil epubcfi('/6/4[chap01ref]!/4[body01]/10[para05]/3:10') <=>
74
- epubcfi('/6/4[chap01ref]!/4[body01]/10[para05]/3!:10')
75
- assert_equal 1, epubcfi('/6/4') <=> epubcfi('/6')
76
- end
77
- end
78
-
79
- class TestRange < self
80
- def test_attributes
81
- parent = epubcfi('/6/4[chap01ref]!/4[body01]/10[para05]')
82
- first = epubcfi('/6/4[chap01ref]!/4[body01]/10[para05]/2/1:1')
83
- last = epubcfi('/6/4[chap01ref]!/4[body01]/10[para05]/3:4')
84
- range = epubcfi('/6/4[chap01ref]!/4[body01]/10[para05],/2/1:1,/3:4')
85
- assert_equal 0, first <=> range.first
86
- assert_equal 0, last <=> range.last
87
-
88
- assert_equal 0, parent <=> range.parent
89
- end
90
-
91
- def test_to_s
92
- assert_equal 'epubcfi(/6/4[chap01ref]!/4[body01]/10[para05]/2/1:1)..epubcfi(/6/4[chap01ref]!/4[body01]/10[para05]/3:4)', epubcfi('/6/4[chap01ref]!/4[body01]/10[para05],/2/1:1,/3:4').to_s
93
- assert_equal 'epubcfi(/6/4[chap01ref]!/4[body01]/10[para05]!/2/1:1)..epubcfi(/6/4[chap01ref]!/4[body01]/10[para05]!/3:4)', epubcfi('/6/4[chap01ref]!/4[body01]/10[para05],!/2/1:1,!/3:4').to_s
94
- end
95
-
96
- def test_to_fragment
97
- cfi = '/6/4[chap01ref]!/4[body01]/10[para05],/2/1:1,/3:4'
98
- assert_equal 'epubcfi(' + cfi + ')', epubcfi('/6/4[chap01ref]!/4[body01]/10[para05],/2/1:1,/3:4').to_fragment
99
- end
100
-
101
- def test_cover
102
- assert_true epubcfi('/6/4[chap01ref]!/4[body01]/10[para05],/2/1:1,/3:4').cover? epubcfi('/6/4[chap01ref]!/4[body01]/10[para05]/2/2/4')
103
- end
104
- end
105
-
106
- class TestStep < self
107
- def test_to_s
108
- assert_equal '/6', EPUB::CFI::Step.new(6).to_s
109
- assert_equal '/4[id]', EPUB::CFI::Step.new(4, EPUB::CFI::IDAssertion.new('id')).to_s
110
- end
111
-
112
- def test_compare
113
- assert_equal 0, EPUB::CFI::Step.new(6) <=> EPUB::CFI::Step.new(6, 'assertion')
114
- assert_equal -1, EPUB::CFI::Step.new(6) <=> EPUB::CFI::Step.new(7)
115
- end
116
- end
117
-
118
- class TestIDAssertion < self
119
- def test_to_s
120
- assert_equal '[id]', EPUB::CFI::IDAssertion.new('id').to_s
121
- assert_equal '[id;p=a]', EPUB::CFI::IDAssertion.new('id', {'p' => ['a']}).to_s
122
- end
123
- end
124
-
125
- class TestTextLocationAssertion < self
126
- def test_to_s
127
- assert_equal '[yyy]', EPUB::CFI::TextLocationAssertion.new('yyy').to_s
128
- assert_equal '[xx,y]', EPUB::CFI::TextLocationAssertion.new('xx', 'y').to_s
129
- assert_equal '[,y]', EPUB::CFI::TextLocationAssertion.new(nil, 'y').to_s
130
- assert_equal '[;s=b]', EPUB::CFI::TextLocationAssertion.new(nil, nil, {'s' => ['b']}).to_s
131
- assert_equal '[yyy;s=b]', EPUB::CFI::TextLocationAssertion.new('yyy', nil, {'s' => ['b']}).to_s
132
- end
133
- end
134
-
135
- class TestCharacterOffset < self
136
- def test_to_s
137
- assert_equal ':1', EPUB::CFI::CharacterOffset.new(1).to_s
138
- assert_equal ':2[yyy]', EPUB::CFI::CharacterOffset.new(2, EPUB::CFI::TextLocationAssertion.new('yyy')).to_s
139
- end
140
-
141
- def test_compare
142
- assert_equal 0,
143
- EPUB::CFI::CharacterOffset.new(3) <=>
144
- EPUB::CFI::CharacterOffset.new(3, EPUB::CFI::TextLocationAssertion.new('yyy'))
145
- assert_equal -1,
146
- EPUB::CFI::CharacterOffset.new(4) <=>
147
- EPUB::CFI::CharacterOffset.new(5)
148
- assert_equal 1,
149
- EPUB::CFI::CharacterOffset.new(4, EPUB::CFI::TextLocationAssertion.new(nil, 'xx')) <=>
150
- EPUB::CFI::CharacterOffset.new(2)
151
- end
152
- end
153
-
154
- class TestSpatialOffset < self
155
- def test_to_s
156
- assert_equal '@0.5:30.2', EPUB::CFI::TemporalSpatialOffset.new(nil, 0.5, 30.2).to_s
157
- assert_equal '@0:100', EPUB::CFI::TemporalSpatialOffset.new(nil, 0, 100).to_s
158
- assert_equal '@50:50.0', EPUB::CFI::TemporalSpatialOffset.new(nil, 50, 50.0).to_s
159
- end
160
-
161
- def test_compare
162
- assert_equal 0,
163
- EPUB::CFI::TemporalSpatialOffset.new(nil, 30, 40) <=>
164
- EPUB::CFI::TemporalSpatialOffset.new(nil, 30, 40)
165
- assert_equal 1,
166
- EPUB::CFI::TemporalSpatialOffset.new(nil, 30, 40) <=>
167
- EPUB::CFI::TemporalSpatialOffset.new(nil, 40, 30)
168
- end
169
- end
170
-
171
- class TestTemporalOffset < self
172
- def test_to_s
173
- assert_equal '~23.5', EPUB::CFI::TemporalSpatialOffset.new(23.5).to_s
174
- end
175
-
176
- def test_compare
177
- assert_equal 0,
178
- EPUB::CFI::TemporalSpatialOffset.new(23.5) <=>
179
- EPUB::CFI::TemporalSpatialOffset.new(23.5)
180
- assert_equal -1,
181
- EPUB::CFI::TemporalSpatialOffset.new(23) <=>
182
- EPUB::CFI::TemporalSpatialOffset.new(23.5)
183
- end
184
- end
185
-
186
- class TestTemporalSpatialOffset < self
187
- def test_to_s
188
- assert_equal '~23.5@50:30.0', EPUB::CFI::TemporalSpatialOffset.new(23.5, 50, 30.0).to_s
189
- end
190
-
191
- def test_compare
192
- assert_equal 0,
193
- EPUB::CFI::TemporalSpatialOffset.new(23.5, 30, 40) <=>
194
- EPUB::CFI::TemporalSpatialOffset.new(23.5, 30, 40.0)
195
- assert_equal 1,
196
- EPUB::CFI::TemporalSpatialOffset.new(23.5, 30, 40) <=>
197
- EPUB::CFI::TemporalSpatialOffset.new(23.5)
198
- assert_equal -1,
199
- EPUB::CFI::TemporalSpatialOffset.new(nil, 30, 40) <=>
200
- EPUB::CFI::TemporalSpatialOffset.new(23.5, 30, 40)
201
- assert_equal -1,
202
- EPUB::CFI::TemporalSpatialOffset.new(23.5, 30, 40) <=>
203
- EPUB::CFI::TemporalSpatialOffset.new(23.5, 30, 50)
204
- assert_equal 1,
205
- EPUB::CFI::TemporalSpatialOffset.new(24, 30, 40) <=>
206
- EPUB::CFI::TemporalSpatialOffset.new(23.5, 100, 100)
207
- end
208
- end
209
-
210
- private
211
-
212
- def epubcfi(string)
213
- EPUB::Parser::CFI.new.parse(string)
214
- end
215
-
216
- def assert_equal_node(expected, actual, message='')
217
- diff = AssertionMessage.delayed_diff(expected.to_s, actual.to_s)
218
- message = build_message(message, <<EOT, expected, actual, diff)
219
- <?>
220
- expected but was
221
- <?>.?
222
- EOT
223
- assert_block message do
224
- expected.tdiff_equal actual
225
- end
226
- end
227
- end
@@ -1,53 +0,0 @@
1
- # coding: utf-8
2
- require_relative 'helper'
3
- require 'epub/parser/cfi'
4
-
5
- class TestParserCFI < Test::Unit::TestCase
6
- def setup
7
- @parser = EPUB::Parser::CFI.new(debug: true)
8
- end
9
-
10
- # from http://www.idpf.org/epub/linking/cfi/epub-cfi.html
11
- data([
12
- 'epubcfi(/6/14[chap05ref]!/4[body01]/10/2/1:3[2^[1^]])',
13
- 'epubcfi(/6/4!/4/10/2/1:3[Ф-"spa ce"-99%-aa^[bb^]^^])',
14
- 'epubcfi(/6/4!/4/10/2/1:3[Ф-"spa%20ce"-99%25-aa^[bb^]^^])',
15
- 'epubcfi(/6/4!/4/10/2/1:3[%d0%a4-"spa%20ce"-99%25-aa^[bb^]^^])',
16
- 'epubcfi(/6/4[chap01ref]!/4[body01]/10[para05]/2/1:3[yyy])',
17
- 'epubcfi(/6/4[chap01ref]!/4[body01]/10[para05]/1:3[xx,y])',
18
- 'epubcfi(/6/4[chap01ref]!/4[body01]/10[para05]/2/1:3[,y])',
19
- 'epubcfi(/6/4[chap01ref]!/4[body01]/10[para05]/2/1:3[;s=b])',
20
- 'epubcfi(/6/4[chap01ref]!/4[body01]/10[para05]/2/1:3[yyy;s=b])',
21
- 'epubcfi(/6/4[chap01ref]!/4[body01]/10[para05]/2/1:3[^(;s=b])',
22
- 'epubcfi(/6/4[chap01ref]!/4[body01]/10[para05]/2[;s=b])',
23
- 'epubcfi(/6/4[chap01ref]!/4[body01]/10[para05]/3:10)',
24
- 'epubcfi(/6/4[chap01ref]!/4[body01]/16[svgimg])',
25
- 'epubcfi(/6/4[chap01ref]!/4[body01]/10[para05]/1:0)',
26
- 'epubcfi(/6/4[chap01ref]!/4[body01]/10[para05]/2/1:0)',
27
- 'epubcfi(/6/4[chap01ref]!/4[body01]/10[para05]/2/1:3)',
28
- 'epubcfi(/6/4[chap01ref]!/4[body01]/10[para05],/2/1:1,/3:4)',
29
- 'epubcfi(/6,:1,:3)',
30
- 'epubcfi(/6/4[chap01ref]!/4[body01]/10[mov01]~23.5@5.75:97.6)'
31
- ].reduce({}) {|data, cfi|
32
- data[cfi] = cfi
33
- data
34
- })
35
- def test_raise_no_error_on_parsing_valid_cfi(cfi)
36
- assert_nothing_raised do
37
- @parser.parse(cfi)
38
- end
39
- end
40
-
41
- data([
42
- '/6/4[chap01ref]!/4[body01]/10[para05]/2/1:3[(;s=b]',
43
- '/6/4[chap01ref]!/4[body01]/10[para05]/2/1:3[);s=b]'
44
- ].reduce({}) {|data, cfi|
45
- data[cfi] = cfi
46
- data
47
- })
48
- def test_raise_error_on_parsing_invalid_cfi(cfi)
49
- assert_raise Racc::ParseError do
50
- EPUB::CFI(cfi)
51
- end
52
- end
53
- end