roo 2.3.2 → 2.4.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: a2e51de2c40930cef415563182257a853b10978e
4
- data.tar.gz: 3b17c8cfb99d1a16778e20289fea7ae9b1ed88a5
3
+ metadata.gz: 5d2a5a56902bf60eef9028eddb5617ae403b866f
4
+ data.tar.gz: 3fad0f4206fd3058b3a420b63da7393b530f5f59
5
5
  SHA512:
6
- metadata.gz: a8f57baddedd100e461fb350814c39dfe765a89a911f2cda0579281612cf37ca95fd9d0459f0572a2241d2e99871045dd5f4573d20364827f756b875a01484b4
7
- data.tar.gz: 87012bc658fbc668b7e655de16b339034cf5887f3e0b3ceb468626e9203c22fd0d05e7d1bbea243525cb7c27e61e2af296f1804bc58def990dc4bf1f95463cd5
6
+ metadata.gz: 91ca5af7282631e668e104e407fb6affd40bc56792809b7129e46de4dd9e4af8133aa6c1eb18f2a9ac8fc7d9470ae51bfb304bff9d920893f1b391b40f6dd162
7
+ data.tar.gz: 9efee7d9ae6fec31bd965a7ce49fcd57452b0b61bb8ad0eb89a21640e4d3f0bbd5cfbb018f6f567b8475050550eb684dd6800aa80716876e2c0b747ae8adecd2
@@ -0,0 +1,10 @@
1
+ Thanks for filing an issue. Following these instructions will help us solve your problem sooner.
2
+
3
+ 1. Describe the issue.
4
+ 2. Create a gist for this issue (Sample gist: https://gist.github.com/stevendaniels/98a05849036e99bb8b3c)?
5
+
6
+ Here are some instructions for creating such a gist.
7
+
8
+ 1. Create a gist (https://gist.github.com) with code that creates the error.
9
+ 2. Clone the gist repo locally, add a stripped down version of the offending spreadsheet to the gist repo, and push the gist's changes master.
10
+ 3. Paste the gist url here.
data/.gitignore CHANGED
@@ -5,3 +5,7 @@
5
5
  .project
6
6
  *.lock
7
7
  .idea
8
+ .buildpath
9
+ *~
10
+ .bundle/
11
+ lbin/
@@ -1,3 +1,13 @@
1
+ ## [2.4.0] 2016-05-14
2
+ ### Fixed
3
+ - Fixed opening spreadsheets with charts [315](https://github.com/roo-rb/roo/pull/315)
4
+ - Fixed memory issues for Roo::Utils.number_to_letter [308](https://github.com/roo-rb/roo/pull/308)
5
+ - Fixed Roo::Excelx::Cell::Number to recognize floating point numbers [306](https://github.com/roo-rb/roo/pull/306)
6
+ - Fixed version number in Readme.md [304](https://github.com/roo-rb/roo/pull/304)
7
+
8
+ ### Added
9
+ - Added initial support for HTML formatting [278](https://github.com/roo-rb/roo/pull/278)
10
+
1
11
  ## [2.3.2] 2016-02-18
2
12
  ### Fixed
3
13
  - Handle url with long query params (ex. S3 secure url) [302](https://github.com/roo-rb/roo/pull/302)
data/Gemfile CHANGED
File without changes
data/README.md CHANGED
@@ -18,7 +18,7 @@ Install as a gem
18
18
  Or add it to your Gemfile
19
19
 
20
20
  ```ruby
21
- gem 'roo', '~> 2.1.0'
21
+ gem 'roo', '~> 2.4.0'
22
22
  ```
23
23
  ## Usage
24
24
 
@@ -354,8 +354,10 @@ module Roo
354
354
  end
355
355
  end
356
356
 
357
+ # Extracts the sheets in order, but it will ignore sheets that are not
358
+ # worksheets.
357
359
  def extract_sheets_in_order(entries, sheet_ids, sheets, tmpdir)
358
- sheet_ids.each_with_index do |id, i|
360
+ (sheet_ids & sheets.keys).each_with_index do |id, i|
359
361
  name = sheets[id]
360
362
  entry = entries.find { |e| e.name =~ /#{name}$/ }
361
363
  path = "#{tmpdir}/roo_sheet#{i + 1}"
@@ -414,6 +416,10 @@ module Roo
414
416
  # ECMA-376 12.3.3 in "Ecma Office Open XML Part 1".
415
417
  nr = Regexp.last_match[1].to_i
416
418
  comments_files[nr - 1] = "#{@tmpdir}/roo_comments#{nr}"
419
+ when %r{chartsheets/_rels/sheet([0-9]+).xml.rels$}
420
+ # NOTE: Chart sheet relationship files were interfering with
421
+ # worksheets.
422
+ nil
417
423
  when /sheet([0-9]+).xml.rels$/
418
424
  # FIXME: Roo seems to use sheet[\d].xml.rels for hyperlinks only, but
419
425
  # it also stores the location for sharedStrings, comments,
@@ -21,7 +21,7 @@ module Roo
21
21
  when /\.0/
22
22
  Float(number)
23
23
  else
24
- (number.include?('.') || (/\A\d+E[-+]\d+\z/i =~ number)) ? Float(number) : Integer(number)
24
+ (number.include?('.') || (/\A[-+]?\d+E[-+]\d+\z/i =~ number)) ? Float(number) : Integer(number)
25
25
  end
26
26
  end
27
27
 
@@ -11,6 +11,16 @@ module Roo
11
11
  @array ||= extract_shared_strings
12
12
  end
13
13
 
14
+ def to_html
15
+ @html ||= extract_html
16
+ end
17
+
18
+ # Use to_html or to_a for html returns
19
+ # See what is happening with commit???
20
+ def use_html?(index)
21
+ to_html[index][/<([biu]|sup|sub)>/]
22
+ end
23
+
14
24
  private
15
25
 
16
26
  def fix_invalid_shared_strings(doc)
@@ -42,6 +52,99 @@ module Roo
42
52
  shared_string
43
53
  end
44
54
  end
45
- end
46
- end
47
- end
55
+
56
+ def extract_html
57
+ return [] unless doc_exists?
58
+ fix_invalid_shared_strings(doc)
59
+ # read the shared strings xml document
60
+ doc.xpath('/sst/si').map do |si|
61
+ html_string = '<html>'
62
+ si.children.each do |elem|
63
+ case elem.name
64
+ when 'r'
65
+ html_string << extract_html_r(elem)
66
+ when 't'
67
+ html_string << elem.content
68
+ end # case elem.name
69
+ end # si.children.each do |elem|
70
+ html_string << '</html>'
71
+ end # doc.xpath('/sst/si').map do |si|
72
+ end # def extract_html
73
+
74
+ # The goal of this function is to take the following XML code snippet and create a html tag
75
+ # r_elem ::: XML Element that is in sharedStrings.xml of excel_book.xlsx
76
+ # {code:xml}
77
+ # <r>
78
+ # <rPr>
79
+ # <i/>
80
+ # <b/>
81
+ # <u/>
82
+ # <vertAlign val="subscript"/>
83
+ # <vertAlign val="superscript"/>
84
+ # </rPr>
85
+ # <t>TEXT</t>
86
+ # </r>
87
+ # {code}
88
+ #
89
+ # Expected Output ::: "<html><sub|sup><b><i><u>TEXT</u></i></b></sub|/sup></html>"
90
+ def extract_html_r(r_elem)
91
+ str = ''
92
+ xml_elems = {
93
+ sub: false,
94
+ sup: false,
95
+ b: false,
96
+ i: false,
97
+ u: false
98
+ }
99
+ b, i, u, sub, sup = false, false, false, false, false
100
+ r_elem.children.each do |elem|
101
+ case elem.name
102
+ when 'rPr'
103
+ elem.children.each do |rPr_elem|
104
+ case rPr_elem.name
105
+ when 'b'
106
+ # set formatting for Bold to true
107
+ xml_elems[:b] = true
108
+ when 'i'
109
+ # set formatting for Italics to true
110
+ xml_elems[:i] = true
111
+ when 'u'
112
+ # set formatting for Underline to true
113
+ xml_elems[:u] = true
114
+ when 'vertAlign'
115
+ # See if the Vertical Alignment is subscript or superscript
116
+ case rPr_elem.xpath('@val').first.value
117
+ when 'subscript'
118
+ # set formatting for Subscript to true and Superscript to false ... Can't have both
119
+ xml_elems[:sub] = true
120
+ xml_elems[:sup] = false
121
+ when 'superscript'
122
+ # set formatting for Superscript to true and Subscript to false ... Can't have both
123
+ xml_elems[:sup] = true
124
+ xml_elems[:sub] = false
125
+ end
126
+ end
127
+ end
128
+ when 't'
129
+ str << create_html(elem.content, xml_elems)
130
+ end
131
+ end
132
+ str
133
+ end # extract_html_r
134
+
135
+ # This will return an html string
136
+ def create_html(text, formatting)
137
+ tmp_str = ''
138
+ formatting.each do |elem, val|
139
+ tmp_str << "<#{elem}>" if val
140
+ end
141
+ tmp_str << text
142
+ reverse_format = Hash[formatting.to_a.reverse]
143
+ reverse_format.each do |elem, val|
144
+ tmp_str << "</#{elem}>" if val
145
+ end
146
+ tmp_str
147
+ end
148
+ end # class SharedStrings < Excelx::Extractor
149
+ end # class Excelx
150
+ end # module Roo
@@ -119,7 +119,7 @@ module Roo
119
119
  # 3. formula
120
120
  case value_type
121
121
  when :shared
122
- value = shared_strings[cell.content.to_i]
122
+ value = shared_strings.use_html?(cell.content.to_i) ? shared_strings.to_html[cell.content.to_i] : shared_strings[cell.content.to_i]
123
123
  Excelx::Cell.create_cell(:string, value, formula, style, hyperlink, coordinate)
124
124
  when :boolean, :string
125
125
  value = cell.content
@@ -2,6 +2,8 @@ module Roo
2
2
  module Utils
3
3
  extend self
4
4
 
5
+ LETTERS = ('A'..'Z').to_a
6
+
5
7
  def split_coordinate(str)
6
8
  @split_coordinate ||= {}
7
9
 
@@ -27,16 +29,14 @@ module Roo
27
29
 
28
30
  # convert a number to something like 'AB' (1 => 'A', 2 => 'B', ...)
29
31
  def number_to_letter(num)
30
- results = []
31
- num = num.to_i
32
+ result = ""
32
33
 
33
- while (num > 0)
34
- mod = (num - 1) % 26
35
- results = [(65 + mod).chr] + results
36
- num = ((num - mod) / 26)
34
+ until num.zero?
35
+ num, index = (num - 1).divmod(26)
36
+ result.prepend(LETTERS[index])
37
37
  end
38
38
 
39
- results.join
39
+ result
40
40
  end
41
41
 
42
42
  def letter_to_number(letters)
@@ -1,3 +1,3 @@
1
1
  module Roo
2
- VERSION = '2.3.2'
2
+ VERSION = '2.4.0'
3
3
  end
@@ -56,7 +56,6 @@ describe Roo::Excelx do
56
56
  expect(subject).to be_a(Roo::Excelx)
57
57
  end
58
58
  end
59
-
60
59
  end
61
60
 
62
61
  describe '#cell' do
@@ -480,10 +479,49 @@ describe Roo::Excelx do
480
479
  end
481
480
  end
482
481
 
482
+ describe '#html_strings' do
483
+ let(:path) { 'test/files/html_strings_formatting.xlsx' }
484
+
485
+ it 'returns the expected result' do
486
+ expect(subject.excelx_value(1, 1, "Sheet1")).to eq "This has no formatting."
487
+ expect(subject.excelx_value(2, 1, "Sheet1")).to eq "<html>This has<b> bold </b>formatting.</html>"
488
+ expect(subject.excelx_value(2, 2, "Sheet1")).to eq "<html>This has <i>italics</i> formatting.</html>"
489
+ expect(subject.excelx_value(2, 3, "Sheet1")).to eq "<html>This has <u>underline</u> format.</html>"
490
+ expect(subject.excelx_value(2, 4, "Sheet1")).to eq "<html>Superscript. x<sup>123</sup></html>"
491
+ expect(subject.excelx_value(2, 5, "Sheet1")).to eq "<html>SubScript. T<sub>j</sub></html>"
492
+
493
+ expect(subject.excelx_value(3, 1, "Sheet1")).to eq "<html>Bold, italics <b><i>together</i></b>.</html>"
494
+ expect(subject.excelx_value(3, 2, "Sheet1")).to eq "<html>Bold, Underline <b><u>together</u></b>.</html>"
495
+ expect(subject.excelx_value(3, 3, "Sheet1")).to eq "<html>Bold, Superscript. <b>x</b><sup><b>N</b></sup></html>"
496
+ expect(subject.excelx_value(3, 4, "Sheet1")).to eq "<html>Bold, Subscript. <b>T</b><sub><b>abc</b></sub></html>"
497
+ expect(subject.excelx_value(3, 5, "Sheet1")).to eq "<html>Italics, Underline <i><u>together</u></i>.</html>"
498
+ expect(subject.excelx_value(3, 6, "Sheet1")).to eq "<html>Italics, Superscript. <i>X</i><sup><i>abc</i></sup></html>"
499
+ expect(subject.excelx_value(3, 7, "Sheet1")).to eq "<html>Italics, Subscript. <i>B</i><sub><i>efg</i></sub></html>"
500
+ expect(subject.excelx_value(4, 1, "Sheet1")).to eq "<html>Bold, italics underline,<b><i><u> together</u></i></b>.</html>"
501
+ expect(subject.excelx_value(4, 2, "Sheet1")).to eq "<html>Bold, italics, superscript. <b>X</b><sup><b><i>abc</i></b></sup><b><i>123</i></b></html>"
502
+ expect(subject.excelx_value(4, 3, "Sheet1")).to eq "<html>Bold, Italics, subscript. <b><i>Mg</i></b><sub><b><i>ha</i></b></sub><b><i>2</i></b></html>"
503
+ expect(subject.excelx_value(4, 4, "Sheet1")).to eq "<html>Bold, Underline, superscript. <b><u>AB</u></b><sup><b><u>C12</u></b></sup><b><u>3</u></b></html>"
504
+ expect(subject.excelx_value(4, 5, "Sheet1")).to eq "<html>Bold, Underline, subscript. <b><u>Good</u></b><sub><b><u>XYZ</u></b></sub></html>"
505
+ expect(subject.excelx_value(4, 6, "Sheet1")).to eq "<html>Italics, Underline, superscript. <i><u>Up</u></i><sup><i><u>swing</u></i></sup></html>"
506
+ expect(subject.excelx_value(4, 7, "Sheet1")).to eq "<html>Italics, Underline, subscript. <i><u>T</u></i><sub><i><u>swing</u></i></sub></html>"
507
+ expect(subject.excelx_value(5, 1, "Sheet1")).to eq "<html>Bold, italics, underline, superscript. <b><i><u>GHJK</u></i></b><sup><b><i><u>190</u></i></b></sup><b><i><u>4</u></i></b></html>"
508
+ expect(subject.excelx_value(5, 2, "Sheet1")).to eq "<html>Bold, italics, underline, subscript. <b><i><u>Mike</u></i></b><sub><b><i><u>drop</u></i></b></sub></html>"
509
+ expect(subject.excelx_value(6, 1, "Sheet1")).to eq "See that regular html tags do not create html tags.\n<ol>\n <li> Denver Broncos </li>\n <li> Carolina Panthers </li>\n <li> New England Patriots</li>\n <li>Arizona Panthers</li>\n</ol>"
510
+ expect(subject.excelx_value(7, 1, "Sheet1")).to eq "<html>Does create html tags when formatting is used..\n<ol>\n <li> <b>Denver Broncos</b> </li>\n <li> <i>Carolina Panthers </i></li>\n <li> <u>New England Patriots</u></li>\n <li>Arizona Panthers</li>\n</ol></html>"
511
+ end
512
+ end
513
+
483
514
  describe '_x000D_' do
484
515
  let(:path) { 'test/files/x000D.xlsx' }
485
516
  it 'does not contain _x000D_' do
486
517
  expect(subject.cell(2, 9)).not_to include('_x000D_')
487
518
  end
488
519
  end
520
+
521
+ describe 'opening a file with a chart sheet' do
522
+ let(:path) { 'test/files/chart_sheet.xlsx' }
523
+ it 'should not raise' do
524
+ expect{ subject }.to_not raise_error
525
+ end
526
+ end
489
527
  end
@@ -4,7 +4,7 @@ RSpec.describe ::Roo::Utils do
4
4
  subject { described_class }
5
5
 
6
6
  context '#number_to_letter' do
7
- ('A'..'Z').to_a.each_with_index do |letter, index|
7
+ described_class::LETTERS.each_with_index do |letter, index|
8
8
  it "should return '#{ letter }' when passed #{ index + 1 }" do
9
9
  expect(described_class.number_to_letter(index + 1)).to eq(letter)
10
10
  end
@@ -1,7 +1,6 @@
1
1
  require 'simplecov'
2
2
  require 'roo'
3
3
  require 'vcr'
4
-
5
4
  require 'helpers'
6
5
 
7
6
  RSpec.configure do |c|
@@ -1,4 +1,7 @@
1
1
  require 'test_helper'
2
+ # require 'pry'
3
+ # require 'active_support'
4
+ # require 'active_support/time'
2
5
 
3
6
  class TestRooExcelxCellDateTime < Minitest::Test
4
7
  def test_cell_value_is_datetime
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: roo
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.3.2
4
+ version: 2.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Thomas Preymesser
@@ -12,7 +12,7 @@ authors:
12
12
  autorequire:
13
13
  bindir: bin
14
14
  cert_chain: []
15
- date: 2016-02-19 00:00:00.000000000 Z
15
+ date: 2016-05-14 00:00:00.000000000 Z
16
16
  dependencies:
17
17
  - !ruby/object:Gem::Dependency
18
18
  name: nokogiri
@@ -95,6 +95,7 @@ executables: []
95
95
  extensions: []
96
96
  extra_rdoc_files: []
97
97
  files:
98
+ - ".github/ISSUE_TEMPLATE"
98
99
  - ".gitignore"
99
100
  - ".simplecov"
100
101
  - ".travis.yml"
@@ -185,8 +186,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
185
186
  version: '0'
186
187
  requirements: []
187
188
  rubyforge_project:
188
- rubygems_version: 2.4.5.1
189
+ rubygems_version: 2.4.5
189
190
  signing_key:
190
191
  specification_version: 4
191
192
  summary: Roo can access the contents of various spreadsheet files.
192
193
  test_files: []
194
+ has_rdoc: