diff options
| author | Dan Allen <dan.j.allen@gmail.com> | 2020-02-10 02:45:06 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-02-10 02:45:06 -0700 |
| commit | 4decb8e79d8e382ec72ba42b76de59be09584701 (patch) | |
| tree | b2023f51ce2579a369fc3e3901caa2d8993f5722 | |
| parent | 74a5ebb28d6cac5bbf5f1f42e1b448448dc5bd50 (diff) | |
resolves #1539 support table head with multiple rows & decorate accordingly (PR #1544)
| -rw-r--r-- | CHANGELOG.adoc | 1 | ||||
| -rw-r--r-- | lib/asciidoctor/pdf/converter.rb | 36 | ||||
| -rw-r--r-- | spec/spec_helper.rb | 2 | ||||
| -rw-r--r-- | spec/table_spec.rb | 64 |
4 files changed, 87 insertions, 16 deletions
diff --git a/CHANGELOG.adoc b/CHANGELOG.adoc index 56835fbb..a311ec81 100644 --- a/CHANGELOG.adoc +++ b/CHANGELOG.adoc @@ -7,6 +7,7 @@ For a detailed view of what has changed, refer to the {uri-repo}/commits/master[ == Unreleased +* support table with multiple head rows & decorate accordingly (#1539) * draw background and border around entire delimited block with wrapped text that appears inside an AsciiDoc table cell (#820) * fix crash when document has PDF cover page and SVG background (#1546) * allow page mode to be fully configured using pdf-page-mode attribute or page_mode theme key (#840) diff --git a/lib/asciidoctor/pdf/converter.rb b/lib/asciidoctor/pdf/converter.rb index fd4dcd35..cab585d6 100644 --- a/lib/asciidoctor/pdf/converter.rb +++ b/lib/asciidoctor/pdf/converter.rb @@ -1882,7 +1882,7 @@ module Asciidoctor # TODO: we could skip a lot of the logic below when num_rows == 0 num_rows = node.attr 'rowcount' num_cols = node.columns.size - table_header = false + table_header_size = false theme = @theme tbl_bg_color = resolve_theme_color :table_background_color @@ -1905,8 +1905,14 @@ module Asciidoctor table_data = [] theme_font :table do head_rows = node.rows[:head] + body_rows = node.rows[:body] + #if (hrows = node.attr 'hrows', false, nil) && (shift_rows = hrows.to_i - head_rows.size) > 0 + # head_rows = head_rows.dup + # body_rows = body_rows.dup + # shift_rows.times { head_rows << body_rows.shift unless body_rows.empty? } + #end theme_font :table_head do - table_header = true + table_header_size = head_rows.size head_font_info = font_info head_line_metrics = calc_line_metrics theme.base_line_height head_cell_padding = theme.table_head_cell_padding || theme.table_cell_padding @@ -1949,7 +1955,7 @@ module Asciidoctor text_color: @font_color, } body_cell_line_metrics = calc_line_metrics theme.base_line_height - (node.rows[:body] + node.rows[:foot]).each do |row| + (body_rows + node.rows[:foot]).each do |row| table_data << (row.map do |cell| cell_data = base_cell_data.merge \ colspan: cell.colspan || 1, @@ -2065,7 +2071,7 @@ module Asciidoctor table_border_color = theme.table_border_color || theme.table_grid_color || theme.base_border_color table_border_style = (theme.table_border_style || :solid).to_sym table_border_width = theme.table_border_width - if table_header + if table_header_size head_border_bottom_color = theme.table_head_border_bottom_color || table_border_color head_border_bottom_style = (theme.table_head_border_bottom_style || table_border_style).to_sym head_border_bottom_width = theme.table_head_border_bottom_width || table_border_width @@ -2122,7 +2128,7 @@ module Asciidoctor caption_max_width = theme.table_caption_max_width || 'fit-content' table_settings = { - header: table_header, + header: table_header_size, # NOTE: position is handled by this method position: :left, cell_style: { @@ -2168,28 +2174,26 @@ module Asciidoctor end end if grid == 'none' && frame == 'none' - if table_header - rows(0).tap do |r| - r.border_bottom_color = head_border_bottom_color - r.border_bottom_line = head_border_bottom_style - r.border_bottom_width = head_border_bottom_width - end - end + rows(table_header_size).tap do |r| + r.border_bottom_color = head_border_bottom_color + r.border_bottom_line = head_border_bottom_style + r.border_bottom_width = head_border_bottom_width + end if table_header_size else # apply the grid setting first across all cells cells.border_width = [border_width[:rows], border_width[:cols], border_width[:rows], border_width[:cols]] - if table_header - rows(0).tap do |r| + if table_header_size + rows(table_header_size - 1).tap do |r| r.border_bottom_color = head_border_bottom_color r.border_bottom_line = head_border_bottom_style r.border_bottom_width = head_border_bottom_width end - rows(1).tap do |r| + rows(table_header_size).tap do |r| r.border_top_color = head_border_bottom_color r.border_top_line = head_border_bottom_style r.border_top_width = head_border_bottom_width - end if num_rows > 1 + end if num_rows > table_header_size end # top edge of table diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index ea00ecb0..f57a1697 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -25,6 +25,8 @@ require 'pathname' unless defined? Pathname require 'pdf/inspector' require 'socket' +Asciidoctor.autoload :Extensions, 'asciidoctor/extensions' unless defined? Asciidoctor::LoggerManager + # NOTE fix invalid bits for PNG in Gmagick Gmagick.prepend (Module.new do def initialize image_blob diff --git a/spec/table_spec.rb b/spec/table_spec.rb index 10928aeb..78e91a06 100644 --- a/spec/table_spec.rb +++ b/spec/table_spec.rb @@ -141,6 +141,39 @@ describe 'Asciidoctor::PDF::Converter - Table' do (expect lines[3][:width]).to eql 0.5 end + it 'should apply thicker bottom border to last table head row when table has multiple head rows' do + tree_processor_impl = proc do + process do |doc| + table = doc.blocks[0] + table.rows[:head] << table.rows[:body].shift + end + end + if asciidoctor_1_5_7_or_better? + opts = { extension_registry: Asciidoctor::Extensions.create { tree_processor(&tree_processor_impl) } } + else + opts = { extensions_registry: Asciidoctor::Extensions.build_registry { treeprocessor(&tree_processor_impl) } } + end + pdf = to_pdf <<~'EOS', (opts.merge analyze: :line) + [%header,frame=none,grid=rows] + |=== + | Columns + | Col A + + | A1 + + | A2 + |=== + EOS + + lines = pdf.lines.uniq + ys = lines.map {|l| l[:from][:y] }.sort.reverse.uniq + (expect ys).to have_size 3 + head_dividing_lines = lines.select {|l| l[:width] == 1.25 } + (expect head_dividing_lines).to have_size 1 + (expect head_dividing_lines[0][:from][:y]).to eql head_dividing_lines[0][:to][:y] + (expect head_dividing_lines[0][:from][:y]).to eql ys[1] + end + it 'should allow theme to customize bottom border of table head row', visual: true do theme_overrides = { table_head_border_bottom_width: 0.5, @@ -163,6 +196,37 @@ describe 'Asciidoctor::PDF::Converter - Table' do (expect to_file).to visually_match 'table-head-border-bottom.pdf' end + it 'should repeat multiple head rows on subsequent pages' do + tree_processor_impl = proc do + process do |doc| + table = doc.blocks[0] + table.rows[:head] << table.rows[:body].shift + end + end + if asciidoctor_1_5_7_or_better? + opts = { extension_registry: Asciidoctor::Extensions.create { tree_processor(&tree_processor_impl) } } + else + opts = { extensions_registry: Asciidoctor::Extensions.build_registry { treeprocessor(&tree_processor_impl) } } + end + pdf = to_pdf <<~EOS, (opts.merge analyze: true) + [%header] + |=== + 2+^| Columns + ^| Column A ^| Column B + #{['| cell | cell'] * 40 * ?\n} + |=== + EOS + + [1, 2].each do |page_number| + col_a_text = (pdf.find_text page_number: page_number, string: 'Column A')[0] + col_b_text = (pdf.find_text page_number: page_number, string: 'Column B')[0] + (expect col_a_text).not_to be_nil + (expect col_a_text[:font_name]).to eql 'NotoSerif-Bold' + (expect col_b_text).not_to be_nil + (expect col_b_text[:font_name]).to eql 'NotoSerif-Bold' + end + end + it 'should allow theme to set table border color to transparent' do theme_overrides = { table_border_color: 'transparent', |
