diff options
| author | Dan Allen <dan.j.allen@gmail.com> | 2016-01-02 23:55:23 -0700 |
|---|---|---|
| committer | Dan Allen <dan.j.allen@gmail.com> | 2016-01-03 03:24:17 -0700 |
| commit | 13732ec8bea6221fe9fac4501920fffae80098a9 (patch) | |
| tree | 96d315e37511eb22eb45c8ca6fe47b79a03bc273 /lib | |
| parent | 1cb29348614cff1ca18c2d9ae35a8a2d772084b9 (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.rb | 12 | ||||
| -rw-r--r-- | lib/asciidoctor/table.rb | 61 |
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 |
