diff options
| -rwxr-xr-x | examples/example.rb | 24 | ||||
| -rw-r--r-- | lib/axlsx/workbook/shared_strings_table.rb | 2 | ||||
| -rw-r--r-- | lib/axlsx/workbook/workbook.rb | 4 | ||||
| -rw-r--r-- | lib/axlsx/workbook/worksheet/cell.rb | 47 | ||||
| -rw-r--r-- | lib/axlsx/workbook/worksheet/cell_serializer.rb | 36 | ||||
| -rw-r--r-- | lib/axlsx/workbook/worksheet/rich_text.rb | 33 | ||||
| -rw-r--r-- | lib/axlsx/workbook/worksheet/rich_text_run.rb | 251 | ||||
| -rw-r--r-- | test/workbook/worksheet/tc_cell.rb | 7 | ||||
| -rw-r--r-- | test/workbook/worksheet/tc_rich_text.rb | 44 | ||||
| -rw-r--r-- | test/workbook/worksheet/tc_rich_text_run.rb | 172 |
10 files changed, 585 insertions, 35 deletions
diff --git a/examples/example.rb b/examples/example.rb index d8519a26..116ce730 100755 --- a/examples/example.rb +++ b/examples/example.rb @@ -49,6 +49,8 @@ examples << :shared_strings examples << :no_autowidth examples << :cached_formula examples << :page_breaks +examples << :rich_text + p = Axlsx::Package.new wb = p.workbook #``` @@ -794,8 +796,7 @@ if examples.include? :no_autowidth end #``` - - +#```ruby if examples.include? :cached_formula p = Axlsx::Package.new p.use_shared_strings = true @@ -805,4 +806,23 @@ if examples.include? :cached_formula end p.serialize 'cached_formula.xlsx' end +#``` +#```ruby +if examples.include? :rich_text + p = Axlsx::Package.new + p.use_shared_strings = true + wb = p.workbook + wrap_text = wb.styles.add_style({:alignment => {:horizontal => :center, :vertical => :center, :wrap_text => true}} ) + rt = Axlsx::RichText.new + rt.add_run('I\'m bold, ', :b => true) + rt.add_run('I\'m italic, ', :i => true) + rt.add_run('I\'m strike' + "\n", :strike => true) + rt.add_run('I\'m bold, italic and strike' + "\n", :b => true, :i => true, :strike => true) + rt.add_run('I\'m style-less :D') + wb.add_worksheet(:name => "RichText") do | sheet | + sheet.add_row [rt], :style => wrap_text + end + p.serialize 'rich_text.xlsx' +end +#```
\ No newline at end of file diff --git a/lib/axlsx/workbook/shared_strings_table.rb b/lib/axlsx/workbook/shared_strings_table.rb index ebec6e67..7e9402b2 100644 --- a/lib/axlsx/workbook/shared_strings_table.rb +++ b/lib/axlsx/workbook/shared_strings_table.rb @@ -38,7 +38,7 @@ module Axlsx @xml_space = xml_space @unique_cells = {} @shared_xml_string = "" - shareable_cells = cells.flatten.select{ |cell| cell.plain_string? } + shareable_cells = cells.flatten.select{ |cell| cell.plain_string? || cell.contains_rich_text? } @count = shareable_cells.size resolve(shareable_cells) end diff --git a/lib/axlsx/workbook/workbook.rb b/lib/axlsx/workbook/workbook.rb index 040628d3..784ee0b4 100644 --- a/lib/axlsx/workbook/workbook.rb +++ b/lib/axlsx/workbook/workbook.rb @@ -5,6 +5,8 @@ require 'axlsx/workbook/worksheet/auto_filter/auto_filter.rb' require 'axlsx/workbook/worksheet/date_time_converter.rb' require 'axlsx/workbook/worksheet/protected_range.rb' require 'axlsx/workbook/worksheet/protected_ranges.rb' +require 'axlsx/workbook/worksheet/rich_text_run' +require 'axlsx/workbook/worksheet/rich_text' require 'axlsx/workbook/worksheet/cell_serializer.rb' require 'axlsx/workbook/worksheet/cell.rb' require 'axlsx/workbook/worksheet/page_margins.rb' @@ -292,7 +294,7 @@ require 'axlsx/workbook/worksheet/selection.rb' end r << Relationship.new(self, STYLES_R, STYLES_PN) if use_shared_strings - r << Relationship.new(self, SHARED_STRINGS_R, SHARED_STRINGS_PN) + r << Relationship.new(self, SHARED_STRINGS_R, SHARED_STRINGS_PN) end r end diff --git a/lib/axlsx/workbook/worksheet/cell.rb b/lib/axlsx/workbook/worksheet/cell.rb index 138efa34..a0607e26 100644 --- a/lib/axlsx/workbook/worksheet/cell.rb +++ b/lib/axlsx/workbook/worksheet/cell.rb @@ -47,6 +47,9 @@ module Axlsx parse_options(options) self.value = value + if value.is_a?(RichText) + value.cell = self + end end # this is the cached value for formula cells. If you want the values to render in iOS/Mac OSX preview @@ -64,7 +67,7 @@ module Axlsx :shadow, :condense, :extend, :u, :vertAlign, :sz, :color, :scheme].freeze - CELL_TYPES = [:date, :time, :float, :integer, + CELL_TYPES = [:date, :time, :float, :integer, :richtext, :string, :boolean, :iso_8601].freeze # The index of the cellXfs item to be applied to this cell. @@ -113,9 +116,13 @@ module Axlsx # Indicates that the cell has one or more of the custom cell styles applied. # @return [Boolean] def is_text_run? - defined?(@is_text_run) && @is_text_run + defined?(@is_text_run) && @is_text_run && !contains_rich_text? + end + + def contains_rich_text? + type == :richtext end - + # Indicates if the cell is good for shared string table def plain_string? type == :string && # String typed @@ -321,13 +328,6 @@ module Axlsx type == :string && @value.to_s.start_with?(?=) end - # This is still not perfect... - # - scaling is not linear as font sizes increase - def autowidth - return if is_formula? || value.nil? - (value.to_s.count(Worksheet::THIN_CHARS) + 3.0) * (font_size/10.0) - end - # returns the absolute or relative string style reference for # this cell. # @param [Boolean] absolute -when false a relative reference will be @@ -345,12 +345,36 @@ module Axlsx # returns the name of the cell attr_reader :name + + def autowidth + return if is_formula? || value.nil? + if contains_rich_text? + string_width('', font_size) + value.autowidth + elsif styles.cellXfs[style].alignment && styles.cellXfs[style].alignment.wrap_text + max_width = 0 + value.to_s.split(/\r?\n/).each do |line| + width = string_width(line, font_size) + max_width = width if width > max_width + end + max_width + else + string_width(value, font_size) + end + end private def styles row.worksheet.styles end + + # Returns the width of a string according to the current style + # This is still not perfect... + # - scaling is not linear as font sizes increase + def string_width(string, font_size) + font_scale = font_size / 10.0 + (string.to_s.count(Worksheet::THIN_CHARS) + 3.0) * (font_size/10.0) + end # we scale the font size if bold style is applied to either the style font or # the cell itself. Yes, it is a bit of a hack, but it is much better than using @@ -396,6 +420,8 @@ module Axlsx :float elsif v.to_s =~ Axlsx::ISO_8601_REGEX :iso_8601 + elsif v.is_a? RichText + :richtext else :string end @@ -407,6 +433,7 @@ module Axlsx # @see Axlsx#date1904 def cast_value(v) return nil if v.nil? + return v if v.is_a? RichText case type when :date self.style = STYLE_DATE if self.style == 0 diff --git a/lib/axlsx/workbook/worksheet/cell_serializer.rb b/lib/axlsx/workbook/worksheet/cell_serializer.rb index 77844ea6..0f66c53e 100644 --- a/lib/axlsx/workbook/worksheet/cell_serializer.rb +++ b/lib/axlsx/workbook/worksheet/cell_serializer.rb @@ -24,20 +24,12 @@ module Axlsx # @return [String] def run_xml_string(cell, str = '') if cell.is_text_run? - data = cell.instance_values.reject{ |key, value| value == nil || key == 'value' || key == 'type' } - keys = data.keys & Cell::INLINE_STYLES - str << '<r><rPr>' - keys.each do |key| - case key - when :font_name - str << ('<rFont val="' << cell.font_name << '"/>') - when :color - str << data[key].to_xml_string - else - str << ('<' << key.to_s << ' val="' << data[key].to_s << '"/>') - end - end - str << ('</rPr><t>' << cell.value.to_s << '</t></r>') + valid = RichTextRun::INLINE_STYLES - [:value, :type] + data = Hash[cell.instance_values.map{ |k, v| [k.to_sym, v] }] + data = data.select { |key, value| valid.include?(key) && !value.nil? } + RichText.new(cell.value.to_s, data).to_xml_string(str) + elsif cell.contains_rich_text? + cell.value.to_xml_string(str) else str << ('<t>' << cell.value.to_s << '</t>') end @@ -121,21 +113,29 @@ module Axlsx if cell.is_formula? formula_serialization cell, str elsif !cell.ssti.nil? - value_serialization 's', cell.ssti.to_s, str + value_serialization 's', cell.ssti, str else inline_string_serialization cell, str end end + + def richtext(cell, str) + if cell.ssti.nil? + inline_string_serialization cell, str + else + value_serialization 's', cell.ssti, str + end + end private def numeric(cell, str = '') - value_serialization 'n', cell.value.to_s, str + value_serialization 'n', cell.value, str end def value_serialization(serialization_type, serialization_value, str = '') - str << ('t="' << serialization_type << '"') if serialization_type - str << ('><v>' << serialization_value << '</v>') + str << ('t="' << serialization_type.to_s << '"') if serialization_type + str << ('><v>' << serialization_value.to_s << '</v>') end diff --git a/lib/axlsx/workbook/worksheet/rich_text.rb b/lib/axlsx/workbook/worksheet/rich_text.rb new file mode 100644 index 00000000..18c8e6b5 --- /dev/null +++ b/lib/axlsx/workbook/worksheet/rich_text.rb @@ -0,0 +1,33 @@ +module Axlsx + class RichText + def initialize(text = nil, options={}) + @runs = SimpleTypedList.new(RichTextRun) + add_run(text, options) unless text.nil? + yield self if block_given? + end + + attr_reader :runs + + attr_reader :cell + + def cell=(cell) + @cell = cell + @runs.each { |run| run.cell = cell } + end + + def autowidth + widtharray = [0] # Are arrays the best way of solving this problem? + @runs.each { |run| run.autowidth(widtharray) } + widtharray.max + end + + def add_run(text, options={}) + @runs << RichTextRun.new(text, options) + end + + def to_xml_string(str='') + runs.each{ |run| run.to_xml_string(str) } + str + end + end +end diff --git a/lib/axlsx/workbook/worksheet/rich_text_run.rb b/lib/axlsx/workbook/worksheet/rich_text_run.rb new file mode 100644 index 00000000..69063135 --- /dev/null +++ b/lib/axlsx/workbook/worksheet/rich_text_run.rb @@ -0,0 +1,251 @@ +module Axlsx + class RichTextRun + + include Axlsx::OptionsParser + + attr_accessor :value + + INLINE_STYLES = [:font_name, :charset, + :family, :b, :i, :strike, :outline, + :shadow, :condense, :extend, :u, + :vertAlign, :sz, :color, :scheme].freeze + + def initialize(value, options={}) + self.value = value + parse_options(options) + end + + attr_accessor :cell + + # The inline font_name property for the cell + # @return [String] + attr_reader :font_name + # @see font_name + def font_name=(v) set_run_style :validate_string, :font_name, v; end + + # The inline charset property for the cell + # As far as I can tell, this is pretty much ignored. However, based on the spec it should be one of the following: + # 0  ANSI_CHARSET + # 1 DEFAULT_CHARSET + # 2 SYMBOL_CHARSET + # 77 MAC_CHARSET + # 128 SHIFTJIS_CHARSET + # 129  HANGUL_CHARSET + # 130  JOHAB_CHARSET + # 134  GB2312_CHARSET + # 136  CHINESEBIG5_CHARSET + # 161  GREEK_CHARSET + # 162  TURKISH_CHARSET + # 163  VIETNAMESE_CHARSET + # 177  HEBREW_CHARSET + # 178  ARABIC_CHARSET + # 186  BALTIC_CHARSET + # 204  RUSSIAN_CHARSET + # 222  THAI_CHARSET + # 238  EASTEUROPE_CHARSET + # 255  OEM_CHARSET + # @return [String] + attr_reader :charset + # @see charset + def charset=(v) set_run_style :validate_unsigned_int, :charset, v; end + + # The inline family property for the cell + # @return [Integer] + # 1 Roman + # 2 Swiss + # 3 Modern + # 4 Script + # 5 Decorative + attr_reader :family + # @see family + def family=(v) + set_run_style :validate_family, :family, v.to_i + end + + # The inline bold property for the cell + # @return [Boolean] + attr_reader :b + # @see b + def b=(v) set_run_style :validate_boolean, :b, v; end + + # The inline italic property for the cell + # @return [Boolean] + attr_reader :i + # @see i + def i=(v) set_run_style :validate_boolean, :i, v; end + + # The inline strike property for the cell + # @return [Boolean] + attr_reader :strike + # @see strike + def strike=(v) set_run_style :validate_boolean, :strike, v; end + + # The inline outline property for the cell + # @return [Boolean] + attr_reader :outline + # @see outline + def outline=(v) set_run_style :validate_boolean, :outline, v; end + + # The inline shadow property for the cell + # @return [Boolean] + attr_reader :shadow + # @see shadow + def shadow=(v) set_run_style :validate_boolean, :shadow, v; end + + # The inline condense property for the cell + # @return [Boolean] + attr_reader :condense + # @see condense + def condense=(v) set_run_style :validate_boolean, :condense, v; end + + # The inline extend property for the cell + # @return [Boolean] + attr_reader :extend + # @see extend + def extend=(v) set_run_style :validate_boolean, :extend, v; end + + # The inline underline property for the cell. + # It must be one of :none, :single, :double, :singleAccounting, :doubleAccounting, true + # @return [Boolean] + # @return [String] + # @note true is for backwards compatability and is reassigned to :single + attr_reader :u + # @see u + def u=(v) + v = :single if (v == true || v == 1 || v == :true || v == 'true') + set_run_style :validate_cell_u, :u, v + end + + # The inline color property for the cell + # @return [Color] + attr_reader :color + # @param [String] v The 8 character representation for an rgb color #FFFFFFFF" + def color=(v) + @color = v.is_a?(Color) ? v : Color.new(:rgb=>v) + @is_text_run = true + end + + # The inline sz property for the cell + # @return [Inteter] + attr_reader :sz + # @see sz + def sz=(v) set_run_style :validate_unsigned_int, :sz, v; end + + # The inline vertical alignment property for the cell + # this must be one of [:baseline, :subscript, :superscript] + # @return [Symbol] + attr_reader :vertAlign + # @see vertAlign + def vertAlign=(v) + RestrictionValidator.validate :cell_vertAlign, [:baseline, :subscript, :superscript], v + set_run_style nil, :vertAlign, v + end + + # The inline scheme property for the cell + # this must be one of [:none, major, minor] + # @return [Symbol] + attr_reader :scheme + # @see scheme + def scheme=(v) + RestrictionValidator.validate :cell_scheme, [:none, :major, :minor], v + set_run_style nil, :scheme, v + end + + # The Shared Strings Table index for this cell + # @return [Integer] + attr_reader :ssti + + # @return [Integer] The cellXfs item index applied to this cell. + # @raise [ArgumentError] Invalid cellXfs id if the value provided is not within cellXfs items range. + def style=(v) + Axlsx::validate_unsigned_int(v) + count = styles.cellXfs.size + raise ArgumentError, "Invalid cellXfs id" unless v < count + @style = v + end + + def autowidth(widtharray) + return if value.nil? + if styles.cellXfs[style].alignment && styles.cellXfs[style].alignment.wrap_text + first = true + value.to_s.split(/\r?\n/, -1).each do |line| + if first + first = false + else + widtharray << 0 + end + widtharray[-1] += string_width(line, font_size) + end + else + widtharray[-1] += string_width(value.to_s, font_size) + end + widtharray + end + + # Utility method for setting inline style attributes + def set_run_style(validator, attr, value) + return unless INLINE_STYLES.include?(attr.to_sym) + Axlsx.send(validator, value) unless validator.nil? + self.instance_variable_set :"@#{attr.to_s}", value + @is_text_run = true + end + + def to_xml_string(str = '') + valid = RichTextRun::INLINE_STYLES + data = Hash[self.instance_values.map{ |k, v| [k.to_sym, v] }] + data = data.select { |key, value| valid.include?(key) && !value.nil? } + + str << '<r><rPr>' + data.keys.each do |key| + case key + when :font_name + str << ('<rFont val="' << font_name << '"/>') + when :color + str << data[key].to_xml_string + else + str << ('<' << key.to_s << ' val="' << xml_value(data[key]) << '"/>') + end + end + str << ('</rPr><t>' << @value.to_s << '</t></r>') + end + + private + + # Returns the width of a string according to the current style + # This is still not perfect... + # - scaling is not linear as font sizes increase + def string_width(string, font_size) + font_scale = font_size / 10.0 + string.count(Worksheet::THIN_CHARS) * font_scale + end + + # we scale the font size if bold style is applied to either the style font or + # the cell itself. Yes, it is a bit of a hack, but it is much better than using + # imagemagick and loading metrics for every character. + def font_size + return sz if sz + font = styles.fonts[styles.cellXfs[style].fontId] || styles.fonts[0] + (font.b || (defined?(@b) && @b)) ? (font.sz * 1.5) : font.sz + end + + def style + cell.style + end + + def styles + cell.row.worksheet.styles + end + + # Converts the value to the correct XML representation (fixes issues with + # Numbers) + def xml_value value + if value == true + 1 + elsif value == false + 0 + else + value + end.to_s + end + end +end diff --git a/test/workbook/worksheet/tc_cell.rb b/test/workbook/worksheet/tc_cell.rb index e42cf09f..ec39bba0 100644 --- a/test/workbook/worksheet/tc_cell.rb +++ b/test/workbook/worksheet/tc_cell.rb @@ -95,6 +95,7 @@ class TestCell < Test::Unit::TestCase assert_equal(@c.send(:cell_type_from_value, true), :boolean) assert_equal(@c.send(:cell_type_from_value, false), :boolean) assert_equal(@c.send(:cell_type_from_value, 1.0/10**6), :float) + assert_equal(@c.send(:cell_type_from_value, Axlsx::RichText.new), :richtext) assert_equal(:iso_8601, @c.send(:cell_type_from_value, '2008-08-30T01:45:36.123+09:00')) end @@ -107,6 +108,8 @@ class TestCell < Test::Unit::TestCase assert_equal(@c.send(:cast_value, "1.0"), 1.0) @c.type = :string assert_equal(@c.send(:cast_value, nil), nil) + @c.type = :richtext + assert_equal(@c.send(:cast_value, nil), nil) @c.type = :float assert_equal(@c.send(:cast_value, nil), nil) @c.type = :boolean @@ -301,11 +304,11 @@ class TestCell < Test::Unit::TestCase assert_equal(sz, 52) end - def test_cell_with_sz @c.sz = 25 assert_equal(25, @c.send(:font_size)) end + def test_to_xml # TODO This could use some much more stringent testing related to the xml content generated! @ws.add_row [Time.now, Date.today, true, 1, 1.0, "text", "=sum(A1:A2)", "2013-01-13T13:31:25.123"] @@ -319,7 +322,5 @@ class TestCell < Test::Unit::TestCase puts error.message end assert(errors.empty?, "error free validation") - end - end diff --git a/test/workbook/worksheet/tc_rich_text.rb b/test/workbook/worksheet/tc_rich_text.rb new file mode 100644 index 00000000..d79d3021 --- /dev/null +++ b/test/workbook/worksheet/tc_rich_text.rb @@ -0,0 +1,44 @@ +require 'tc_helper.rb' + +class RichText < Test::Unit::TestCase + def setup + p = Axlsx::Package.new + @ws = p.workbook.add_worksheet :name => "hmmmz" + p.workbook.styles.add_style :sz => 20 + @rt = Axlsx::RichText.new + b = true + (0..26).each do |r| + @rt.add_run "run #{r}, ", :b => (b=!b), :i => !b + end + @row = @ws.add_row [@rt] + @c = @row.first + end + + def test_initialize + assert_equal(@c.value, @rt) + rt_direct = Axlsx::RichText.new('hi', :i => true) + rt_indirect = Axlsx::RichText.new() + rt_indirect.add_run('hi', :i => true) + assert_equal(rt_direct.runs.length, 1) + assert_equal(rt_indirect.runs.length, 1) + row = @ws.add_row [rt_direct, rt_indirect] + assert_equal(row[0].to_xml_string(0,0), row[1].to_xml_string(0,0)) + end + + def test_textruns + runs = @rt.runs + assert_equal(runs.length, 27) + assert_equal(runs.first.b, false) + assert_equal(runs.first.i, true) + assert_equal(runs[1].b, true) + assert_equal(runs[1].i, false) + end + + def test_implicit_richtext + rt = Axlsx::RichText.new('a', :b => true) + row_rt = @ws.add_row [rt] + row_imp = @ws.add_row ['a'] + row_imp[0].b = true + assert_equal(row_rt[0].to_xml_string(0,0), row_imp[0].to_xml_string(0,0)) + end +end diff --git a/test/workbook/worksheet/tc_rich_text_run.rb b/test/workbook/worksheet/tc_rich_text_run.rb new file mode 100644 index 00000000..f8b11f6c --- /dev/null +++ b/test/workbook/worksheet/tc_rich_text_run.rb @@ -0,0 +1,172 @@ +require 'tc_helper.rb' + +class RichTextRun < Test::Unit::TestCase + def setup + @p = Axlsx::Package.new + @ws = @p.workbook.add_worksheet :name => "hmmmz" + @p.workbook.styles.add_style :sz => 20 + @rtr = Axlsx::RichTextRun.new('hihihi', b: true, i: false) + @rtr2 = Axlsx::RichTextRun.new('hihi2hi2', b: false, i: true) + @rt = Axlsx::RichText.new + @rt.runs << @rtr + @rt.runs << @rtr2 + @row = @ws.add_row [@rt] + @c = @row.first + end + + def test_initialize + assert_equal(@rtr.value, 'hihihi') + assert_equal(@rtr.b, true) + assert_equal(@rtr.i, false) + end + + def test_font_size_with_custom_style_and_no_sz + @c.style = @c.row.worksheet.workbook.styles.add_style :bg_color => 'FF00FF' + sz = @rtr.send(:font_size) + assert_equal(sz, @c.row.worksheet.workbook.styles.fonts.first.sz * 1.5) + sz = @rtr2.send(:font_size) + assert_equal(sz, @c.row.worksheet.workbook.styles.fonts.first.sz) + end + + def test_font_size_with_bolding + @c.style = @c.row.worksheet.workbook.styles.add_style :b => true + assert_equal(@c.row.worksheet.workbook.styles.fonts.first.sz * 1.5, @rtr.send(:font_size)) + assert_equal(@c.row.worksheet.workbook.styles.fonts.first.sz * 1.5, @rtr2.send(:font_size)) # is this the correct behaviour? + end + + def test_font_size_with_custom_sz + @c.style = @c.row.worksheet.workbook.styles.add_style :sz => 52 + sz = @rtr.send(:font_size) + assert_equal(sz, 52 * 1.5) + sz2 = @rtr2.send(:font_size) + assert_equal(sz2, 52) + end + + def test_rtr_with_sz + @rtr.sz = 25 + assert_equal(25, @rtr.send(:font_size)) + end + + def test_color + assert_raise(ArgumentError) { @rtr.color = -1.1 } + assert_nothing_raised { @rtr.color = "FF00FF00" } + assert_equal(@rtr.color.rgb, "FF00FF00") + end + + def test_scheme + assert_raise(ArgumentError) { @rtr.scheme = -1.1 } + assert_nothing_raised { @rtr.scheme = :major } + assert_equal(@rtr.scheme, :major) + end + + def test_vertAlign + assert_raise(ArgumentError) { @rtr.vertAlign = -1.1 } + assert_nothing_raised { @rtr.vertAlign = :baseline } + assert_equal(@rtr.vertAlign, :baseline) + end + + def test_sz + assert_raise(ArgumentError) { @rtr.sz = -1.1 } + assert_nothing_raised { @rtr.sz = 12 } + assert_equal(@rtr.sz, 12) + end + + def test_extend + assert_raise(ArgumentError) { @rtr.extend = -1.1 } + assert_nothing_raised { @rtr.extend = false } + assert_equal(@rtr.extend, false) + end + + def test_condense + assert_raise(ArgumentError) { @rtr.condense = -1.1 } + assert_nothing_raised { @rtr.condense = false } + assert_equal(@rtr.condense, false) + end + + def test_shadow + assert_raise(ArgumentError) { @rtr.shadow = -1.1 } + assert_nothing_raised { @rtr.shadow = false } + assert_equal(@rtr.shadow, false) + end + + def test_outline + assert_raise(ArgumentError) { @rtr.outline = -1.1 } + assert_nothing_raised { @rtr.outline = false } + assert_equal(@rtr.outline, false) + end + + def test_strike + assert_raise(ArgumentError) { @rtr.strike = -1.1 } + assert_nothing_raised { @rtr.strike = false } + assert_equal(@rtr.strike, false) + end + + def test_u + @c.type = :string + assert_raise(ArgumentError) { @c.u = -1.1 } + assert_nothing_raised { @c.u = :single } + assert_equal(@c.u, :single) + doc = Nokogiri::XML(@c.to_xml_string(1,1)) + assert(doc.xpath('//u[@val="single"]')) + end + + def test_i + assert_raise(ArgumentError) { @c.i = -1.1 } + assert_nothing_raised { @c.i = false } + assert_equal(@c.i, false) + end + + def test_rFont + assert_raise(ArgumentError) { @c.font_name = -1.1 } + assert_nothing_raised { @c.font_name = "Arial" } + assert_equal(@c.font_name, "Arial") + end + + def test_charset + assert_raise(ArgumentError) { @c.charset = -1.1 } + assert_nothing_raised { @c.charset = 1 } + assert_equal(@c.charset, 1) + end + + def test_family + assert_raise(ArgumentError) { @c.family = -1.1 } + assert_nothing_raised { @c.family = 5 } + assert_equal(@c.family, 5) + end + + def test_b + assert_raise(ArgumentError) { @c.b = -1.1 } + assert_nothing_raised { @c.b = false } + assert_equal(@c.b, false) + end + + def test_multiline_autowidth + wrap = @p.workbook.styles.add_style({:alignment => {:wrap_text => true}}) + awtr = Axlsx::RichTextRun.new('I\'m bold' + "\n", :b => true) + rt = Axlsx::RichText.new + rt.runs << awtr + @ws.add_row [rt], :style => wrap + ar = [0] + awtr.autowidth(ar) + assert_equal(ar.length, 2) + assert_equal(ar.last, 0) + end + + def test_to_xml + schema = Nokogiri::XML::Schema(File.open(Axlsx::SML_XSD)) + doc = Nokogiri::XML(@ws.to_xml_string) + errors = [] + schema.validate(doc).each do |error| + puts error.message + errors.push error + end + assert(errors.empty?, "error free validation") + + assert(doc.xpath('//rPr/b[@val=1]')) + assert(doc.xpath('//rPr/i[@val=0]')) + assert(doc.xpath('//rPr/b[@val=0]')) + assert(doc.xpath('//rPr/i[@val=1]')) + assert(doc.xpath('//is//t[contains(text(), "hihihi")]')) + assert(doc.xpath('//is//t[contains(text(), "hihi2hi2")]')) + end +end |
