roo-calamine 0.0.1
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 +7 -0
- data/CHANGELOG.md +8 -0
- data/Cargo.lock +292 -0
- data/Cargo.toml +7 -0
- data/LICENSE +21 -0
- data/README.md +330 -0
- data/ext/roo_calamine/Cargo.toml +18 -0
- data/ext/roo_calamine/extconf.rb +14 -0
- data/ext/roo_calamine/src/convert.rs +365 -0
- data/ext/roo_calamine/src/lib.rs +254 -0
- data/ext/roo_calamine/src/reader.rs +1182 -0
- data/lib/roo/calamine/context.rb +57 -0
- data/lib/roo/calamine/sheet_doc.rb +66 -0
- data/lib/roo/calamine/version.rb +7 -0
- data/lib/roo/calamine.rb +47 -0
- metadata +90 -0
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Roo
|
|
4
|
+
module Calamine
|
|
5
|
+
# The answers the native reader needs from roo while it builds cells. Each
|
|
6
|
+
# one comes from the roo object or method that SheetDoc#cell_from_xml uses,
|
|
7
|
+
# so formats, shared strings, and errors are roo's own.
|
|
8
|
+
class Context
|
|
9
|
+
attr_reader :hyperlinks, :empty_cell
|
|
10
|
+
|
|
11
|
+
def initialize(shared, hyperlinks, empty_cell)
|
|
12
|
+
@shared = shared
|
|
13
|
+
@hyperlinks = hyperlinks
|
|
14
|
+
@empty_cell = empty_cell
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def base_date
|
|
18
|
+
@shared.base_date
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def base_timestamp
|
|
22
|
+
@shared.base_timestamp
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def style(index)
|
|
26
|
+
format = @shared.styles.style_format(index)
|
|
27
|
+
[format.to_s, Roo::Excelx::Format.to_type(format)]
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def style_index(text)
|
|
31
|
+
text.to_i
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def coordinate(reference)
|
|
35
|
+
Roo::Utils.extract_coordinate(reference)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# roo's own memoized shared-string arrays: plain text, and the HTML that
|
|
39
|
+
# SharedStrings#use_html? tests (nil when the HTML wrapper is disabled).
|
|
40
|
+
def shared_strings
|
|
41
|
+
strings = @shared.shared_strings
|
|
42
|
+
html_disabled = strings.instance_variable_get(:@options)[:disable_html_wrapper]
|
|
43
|
+
[strings.to_a, (strings.to_html unless html_disabled)]
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def shared_string(text)
|
|
47
|
+
shared_string_at(@shared.shared_strings, text.to_i)
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
private
|
|
51
|
+
|
|
52
|
+
def shared_string_at(strings, index)
|
|
53
|
+
strings.use_html?(index) ? strings.to_html[index] : strings[index]
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Roo
|
|
4
|
+
module Calamine
|
|
5
|
+
# Prepended to Roo::Excelx::SheetDoc, where every worksheet read in roo
|
|
6
|
+
# starts: Sheet#cells (and with it #cell, #row, #each, #parse) and
|
|
7
|
+
# Sheet#each_row (#each_row_streaming). Everything else, including roo's
|
|
8
|
+
# padding, offset, and row limits, stays roo's code.
|
|
9
|
+
module SheetDoc
|
|
10
|
+
# Cells the native reader parses ahead of Ruby, per batch.
|
|
11
|
+
BATCH_CELLS = 16_384
|
|
12
|
+
|
|
13
|
+
def cells(relationships)
|
|
14
|
+
return super if @cells || !native?
|
|
15
|
+
|
|
16
|
+
cells = {}
|
|
17
|
+
reader = Native::Reader.new(@path, false, BATCH_CELLS)
|
|
18
|
+
converter = Native::Converter.new(Context.new(@shared, hyperlinks(relationships), @options[:empty_cell]), false)
|
|
19
|
+
nil while reader.fill_cells(cells, converter)
|
|
20
|
+
expand_merged_ranges(cells) if @options[:expand_merged_ranges]
|
|
21
|
+
@cells = cells
|
|
22
|
+
rescue UnsupportedError
|
|
23
|
+
super
|
|
24
|
+
ensure
|
|
25
|
+
reader&.close
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# Yields Native::Row objects; #each_cell turns one into cells when roo
|
|
29
|
+
# asks for it, so rows roo skips are never converted, as in roo.
|
|
30
|
+
def each_row_streaming(&)
|
|
31
|
+
return super unless native?
|
|
32
|
+
|
|
33
|
+
yielded = 0
|
|
34
|
+
reader = Native::Reader.new(@path, true, BATCH_CELLS)
|
|
35
|
+
while (rows = reader.next_rows)
|
|
36
|
+
rows.each do |row|
|
|
37
|
+
yield row
|
|
38
|
+
yielded += 1
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
nil
|
|
42
|
+
rescue UnsupportedError
|
|
43
|
+
# roo reads the sheet again; skip the rows already yielded.
|
|
44
|
+
skip = yielded
|
|
45
|
+
super { |row| skip.zero? ? yield(row) : skip -= 1 }
|
|
46
|
+
ensure
|
|
47
|
+
# Also when the caller stops early, as roo does for max_rows.
|
|
48
|
+
reader&.close
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def each_cell(row_xml, &)
|
|
52
|
+
return super unless row_xml.is_a?(Native::Row)
|
|
53
|
+
|
|
54
|
+
@calamine_stream_converter ||= Native::Converter.new(Context.new(@shared, hyperlinks(@relationships), true),
|
|
55
|
+
true)
|
|
56
|
+
@calamine_stream_converter.row_cells(row_xml).each(&)
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
private
|
|
60
|
+
|
|
61
|
+
def native?
|
|
62
|
+
@path && Calamine.enabled?
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
end
|
data/lib/roo/calamine.rb
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "roo"
|
|
4
|
+
require "roo/excelx"
|
|
5
|
+
require_relative "calamine/version"
|
|
6
|
+
|
|
7
|
+
module Roo
|
|
8
|
+
# Reads `.xlsx` and `.xlsm` worksheets for Roo::Excelx with a native
|
|
9
|
+
# extension. Loading this file is all it takes; `Roo::Calamine.enabled =
|
|
10
|
+
# false` or `ROO_CALAMINE=0` switches back to roo's own reader at runtime.
|
|
11
|
+
module Calamine
|
|
12
|
+
# Raised by the native reader for XML it does not reproduce exactly the
|
|
13
|
+
# way roo reads it. Roo::Calamine rescues it and lets roo read the sheet.
|
|
14
|
+
class UnsupportedError < StandardError; end
|
|
15
|
+
|
|
16
|
+
DISABLING_ENV_VALUES = %w[0 false off].freeze
|
|
17
|
+
private_constant :DISABLING_ENV_VALUES
|
|
18
|
+
|
|
19
|
+
@enabled = true
|
|
20
|
+
|
|
21
|
+
class << self
|
|
22
|
+
attr_writer :enabled
|
|
23
|
+
|
|
24
|
+
# Whether the native extension is loaded. It is `false` on Ruby
|
|
25
|
+
# implementations other than CRuby, such as JRuby.
|
|
26
|
+
def available?
|
|
27
|
+
defined?(Native::Reader) ? true : false
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
# Whether the next worksheet read goes through the native reader.
|
|
31
|
+
def enabled?
|
|
32
|
+
@enabled && available? && !DISABLING_ENV_VALUES.include?(ENV.fetch("ROO_CALAMINE", "").downcase)
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
if RUBY_ENGINE == "ruby"
|
|
39
|
+
begin
|
|
40
|
+
require "roo/calamine/#{RUBY_VERSION[/\d+\.\d+/]}/roo_calamine"
|
|
41
|
+
rescue LoadError
|
|
42
|
+
require "roo/calamine/roo_calamine"
|
|
43
|
+
end
|
|
44
|
+
require_relative "calamine/context"
|
|
45
|
+
require_relative "calamine/sheet_doc"
|
|
46
|
+
Roo::Excelx::SheetDoc.prepend(Roo::Calamine::SheetDoc)
|
|
47
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: roo-calamine
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.0.1
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Sebastian Sala
|
|
8
|
+
bindir: bin
|
|
9
|
+
cert_chain: []
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
11
|
+
dependencies:
|
|
12
|
+
- !ruby/object:Gem::Dependency
|
|
13
|
+
name: rb_sys
|
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
|
15
|
+
requirements:
|
|
16
|
+
- - "~>"
|
|
17
|
+
- !ruby/object:Gem::Version
|
|
18
|
+
version: 0.9.130
|
|
19
|
+
type: :runtime
|
|
20
|
+
prerelease: false
|
|
21
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
22
|
+
requirements:
|
|
23
|
+
- - "~>"
|
|
24
|
+
- !ruby/object:Gem::Version
|
|
25
|
+
version: 0.9.130
|
|
26
|
+
- !ruby/object:Gem::Dependency
|
|
27
|
+
name: roo
|
|
28
|
+
requirement: !ruby/object:Gem::Requirement
|
|
29
|
+
requirements:
|
|
30
|
+
- - "~>"
|
|
31
|
+
- !ruby/object:Gem::Version
|
|
32
|
+
version: '4.0'
|
|
33
|
+
type: :runtime
|
|
34
|
+
prerelease: false
|
|
35
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
36
|
+
requirements:
|
|
37
|
+
- - "~>"
|
|
38
|
+
- !ruby/object:Gem::Version
|
|
39
|
+
version: '4.0'
|
|
40
|
+
description: Unofficial plugin for roo. Add it to the Gemfile and Roo::Excelx reads
|
|
41
|
+
worksheets through a Rust extension instead of Nokogiri, building the same Roo::Excelx::Cell
|
|
42
|
+
objects. Anything the native reader does not reproduce exactly goes to roo's own
|
|
43
|
+
code. Not affiliated with roo-rb.
|
|
44
|
+
executables: []
|
|
45
|
+
extensions:
|
|
46
|
+
- ext/roo_calamine/extconf.rb
|
|
47
|
+
extra_rdoc_files: []
|
|
48
|
+
files:
|
|
49
|
+
- CHANGELOG.md
|
|
50
|
+
- Cargo.lock
|
|
51
|
+
- Cargo.toml
|
|
52
|
+
- LICENSE
|
|
53
|
+
- README.md
|
|
54
|
+
- ext/roo_calamine/Cargo.toml
|
|
55
|
+
- ext/roo_calamine/extconf.rb
|
|
56
|
+
- ext/roo_calamine/src/convert.rs
|
|
57
|
+
- ext/roo_calamine/src/lib.rs
|
|
58
|
+
- ext/roo_calamine/src/reader.rs
|
|
59
|
+
- lib/roo/calamine.rb
|
|
60
|
+
- lib/roo/calamine/context.rb
|
|
61
|
+
- lib/roo/calamine/sheet_doc.rb
|
|
62
|
+
- lib/roo/calamine/version.rb
|
|
63
|
+
homepage: https://github.com/salasebas/roo-calamine
|
|
64
|
+
licenses:
|
|
65
|
+
- MIT
|
|
66
|
+
metadata:
|
|
67
|
+
homepage_uri: https://github.com/salasebas/roo-calamine
|
|
68
|
+
source_code_uri: https://github.com/salasebas/roo-calamine/tree/v0.0.1
|
|
69
|
+
changelog_uri: https://github.com/salasebas/roo-calamine/blob/v0.0.1/CHANGELOG.md
|
|
70
|
+
bug_tracker_uri: https://github.com/salasebas/roo-calamine/issues
|
|
71
|
+
rubygems_mfa_required: 'true'
|
|
72
|
+
rdoc_options: []
|
|
73
|
+
require_paths:
|
|
74
|
+
- lib
|
|
75
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
76
|
+
requirements:
|
|
77
|
+
- - ">="
|
|
78
|
+
- !ruby/object:Gem::Version
|
|
79
|
+
version: '3.3'
|
|
80
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
81
|
+
requirements:
|
|
82
|
+
- - ">="
|
|
83
|
+
- !ruby/object:Gem::Version
|
|
84
|
+
version: 3.3.11
|
|
85
|
+
requirements: []
|
|
86
|
+
rubygems_version: 3.6.9
|
|
87
|
+
specification_version: 4
|
|
88
|
+
summary: A native reader that makes roo read .xlsx and .xlsm files faster, with the
|
|
89
|
+
same results.
|
|
90
|
+
test_files: []
|