summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rwxr-xr-xexamples/example.rb24
-rw-r--r--lib/axlsx/workbook/shared_strings_table.rb2
-rw-r--r--lib/axlsx/workbook/workbook.rb4
-rw-r--r--lib/axlsx/workbook/worksheet/cell.rb47
-rw-r--r--lib/axlsx/workbook/worksheet/cell_serializer.rb36
-rw-r--r--lib/axlsx/workbook/worksheet/rich_text.rb33
-rw-r--r--lib/axlsx/workbook/worksheet/rich_text_run.rb251
-rw-r--r--test/workbook/worksheet/tc_cell.rb7
-rw-r--r--test/workbook/worksheet/tc_rich_text.rb44
-rw-r--r--test/workbook/worksheet/tc_rich_text_run.rb172
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