summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorDan Allen <dan.j.allen@gmail.com>2016-01-02 23:55:23 -0700
committerDan Allen <dan.j.allen@gmail.com>2016-01-03 03:24:17 -0700
commit13732ec8bea6221fe9fac4501920fffae80098a9 (patch)
tree96d315e37511eb22eb45c8ca6fe47b79a03bc273 /lib
parent1cb29348614cff1ca18c2d9ae35a8a2d772084b9 (diff)
resolves #1647 ensure colpcwidth values add up to 100%
- refactor code to consolidate logic for calculating colpcwidth values - increase precision of colpcwidth values to 4 decimal places - donate balance of rounding to final column - ignore blank cols attribute on table
Diffstat (limited to 'lib')
-rw-r--r--lib/asciidoctor/parser.rb12
-rw-r--r--lib/asciidoctor/table.rb61
2 files changed, 46 insertions, 27 deletions
diff --git a/lib/asciidoctor/parser.rb b/lib/asciidoctor/parser.rb
index e7755fb1..1dae26fa 100644
--- a/lib/asciidoctor/parser.rb
+++ b/lib/asciidoctor/parser.rb
@@ -2272,10 +2272,10 @@ class Parser
table.assign_caption attributes.delete('caption')
end
- if attributes['cols'].nil_or_empty?
+ if (cols = attributes['cols']).nil_or_empty? || (cols = cols.rstrip).empty?
explicit_col_specs = false
else
- table.create_columns(parse_col_specs(attributes['cols']))
+ table.create_columns(parse_col_specs cols)
explicit_col_specs = true
end
@@ -2372,12 +2372,8 @@ class Parser
end
end
- table.attributes['colcount'] ||= parser_ctx.col_count
-
- if !explicit_col_specs
- # TODO further encapsulate this logic (into table perhaps?)
- even_width = (100.0 / parser_ctx.col_count).floor
- table.columns.each {|c| c.assign_width(0, even_width) }
+ unless (table.attributes['colcount'] ||= table.columns.size) == 0 || explicit_col_specs
+ table.assign_col_widths
end
table.partition_header_footer attributes
diff --git a/lib/asciidoctor/table.rb b/lib/asciidoctor/table.rb
index bd900ede..95873887 100644
--- a/lib/asciidoctor/table.rb
+++ b/lib/asciidoctor/table.rb
@@ -99,21 +99,45 @@ class Table < AbstractBlock
# Internal: Creates the Column objects from the column spec
#
# returns nothing
- def create_columns(col_specs)
- total_width = 0
+ def create_columns col_specs
cols = []
+ width_base = 0
col_specs.each do |col_spec|
- total_width += col_spec['width']
- cols << Column.new(self, cols.size, col_spec)
+ width_base += col_spec['width']
+ cols << (Column.new self, cols.size, col_spec)
end
-
- unless cols.empty?
+ unless (@columns = cols).empty?
@attributes['colcount'] = cols.size
- even_width = (100.0 / cols.size).floor
- cols.each {|c| c.assign_width(total_width, even_width) }
+ assign_col_widths(width_base == 0 ? nil : width_base)
end
+ nil
+ end
+
+ # Internal: Assign column widths to columns
+ #
+ # This method rounds the percentage width values to 4 decimal places and
+ # donates the balance to the final column.
+ #
+ # This method assumes there's at least one column in the columns array.
+ #
+ # width_base - the total of the relative column values used for calculating percentage widths (default: nil)
+ #
+ # returns nothing
+ def assign_col_widths width_base = nil
+ pf = 10.0 ** 4 # precision factor (multipler / divisor) for managing precision of calculated result
+ total_width = col_pcwidth = 0
+
+ if width_base
+ @columns.each {|col| total_width += (col_pcwidth = col.assign_width nil, width_base, pf) }
+ else
+ col_pcwidth = ((100 * pf / @columns.size).to_i) / pf
+ col_pcwidth = col_pcwidth.to_i if col_pcwidth.to_i == col_pcwidth
+ @columns.each {|col| total_width += col.assign_width col_pcwidth }
+ end
+
+ # donate balance, if any, to final column
+ @columns[-1].assign_width(((100 - total_width + col_pcwidth) * pf).round / pf) unless total_width == 100
- @columns = cols
nil
end
@@ -167,19 +191,18 @@ class Table::Column < AbstractNode
#
# This method assigns the colpcwidth and colabswidth attributes.
#
- # returns nothing
- def assign_width(total_width, even_width)
- if total_width > 0
- width = ((@attributes['width'].to_f / total_width) * 100).floor
- else
- width = even_width
+ # returns the resolved colpcwidth value
+ def assign_width col_pcwidth, width_base = nil, pf = 10000.0
+ if width_base
+ col_pcwidth = ((@attributes['width'].to_f / width_base) * 100 * pf).to_i / pf
+ col_pcwidth = col_pcwidth.to_i if col_pcwidth.to_i == col_pcwidth
end
- @attributes['colpcwidth'] = width
+ @attributes['colpcwidth'] = col_pcwidth
if parent.attributes.key? 'tableabswidth'
- @attributes['colabswidth'] = ((width.to_f / 100) * parent.attributes['tableabswidth']).round
+ # FIXME calculate more accurately (only used in DocBook output)
+ @attributes['colabswidth'] = ((col_pcwidth / 100.0) * parent.attributes['tableabswidth']).round
end
-
- nil
+ col_pcwidth
end
end