From 1246cb86de4eac687ed36b31e3a3c3901af3b595 Mon Sep 17 00:00:00 2001 From: Dan Allen Date: Sun, 15 Sep 2024 00:44:53 -0600 Subject: [PATCH] backport fix for support horizontal alignment on AsciiDoc table cell that only contains paragraphs --- CHANGELOG.adoc | 4 ++ lib/asciidoctor/pdf/converter.rb | 3 +- .../pdf/ext/prawn-table/cell/asciidoc.rb | 7 +++ spec/table_spec.rb | 49 +++++++++++++++++++ 4 files changed, 62 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.adoc b/CHANGELOG.adoc index 55781c0f3..811578e89 100644 --- a/CHANGELOG.adoc +++ b/CHANGELOG.adoc @@ -11,6 +11,10 @@ Improvements:: * replace OpenStruct with internal ThemeData class for storing theme data (#2535) +Bug Fixes:: + +* support horizontal alignment on AsciiDoc table cell that only contains paragraphs (#2358) + == 2.3.18 (2024-07-27) - @mojavelinux Bug Fixes:: diff --git a/lib/asciidoctor/pdf/converter.rb b/lib/asciidoctor/pdf/converter.rb index 37cff99e4..c7be0d1b4 100644 --- a/lib/asciidoctor/pdf/converter.rb +++ b/lib/asciidoctor/pdf/converter.rb @@ -4745,7 +4745,8 @@ def admonition_icon_data key end def allocate_space_for_list_item line_metrics - advance_page if !at_page_top? && cursor < line_metrics.height + line_metrics.leading + line_metrics.padding_top + # need to check ancestors for table_cell as well; perhaps helper in_table_cell? + advance_page if !(bounds.instance_variable_get :@table_cell) && !at_page_top? && cursor < line_metrics.height + line_metrics.leading + line_metrics.padding_top end def apply_text_decoration styles, category, level = nil diff --git a/lib/asciidoctor/pdf/ext/prawn-table/cell/asciidoc.rb b/lib/asciidoctor/pdf/ext/prawn-table/cell/asciidoc.rb index cfd4405bd..9c45148f3 100644 --- a/lib/asciidoctor/pdf/ext/prawn-table/cell/asciidoc.rb +++ b/lib/asciidoctor/pdf/ext/prawn-table/cell/asciidoc.rb @@ -76,6 +76,7 @@ def draw_content padding_adjustment = content.context == :document ? padding_bottom : 0 # NOTE: we've already reserved the space, so just let the box stretch to bottom of the content area pdf.bounds.instance_variable_set :@height, (pdf.y - pdf.page.margins[:bottom] - padding_adjustment) + pdf.bounds.instance_variable_set :@table_cell, true if @valign != :top && (excess_y = spanned_content_height - natural_content_height) > 0 # QUESTION: could this cause a unexpected page overrun? pdf.move_down(@valign == :center ? (excess_y.fdiv 2) : excess_y) @@ -92,6 +93,7 @@ def draw_content doc.catalog[:footnotes] = parent_doc.catalog[:footnotes] # TODO: apply horizontal alignment; currently it is necessary to specify alignment on content blocks apply_font_properties { pdf.traverse content } + pdf.bounds.remove_instance_variable :@table_cell if (extra_pages = pdf.page_number - start_page) > 0 unless extra_pages == 1 && pdf.page.empty? logger.error message_with_context %(the table cell on page #{start_page} has been truncated; Asciidoctor PDF does not support table cell content that exceeds the height of a single page), source_location: @source_location @@ -116,11 +118,16 @@ def apply_font_properties font_size = font_info[:size] end font_style ||= font_info[:style] + if (@align == :center || @align == :right) && content.blocks.map(&:context).uniq == [:paragraph] + prev_text_align = pdf.instance_variable_get :@base_text_align + pdf.instance_variable_set :@base_text_align, @align + end pdf.font font_family, size: font_size, style: font_style do yield ensure pdf.font_color = prev_font_color if prev_font_color pdf.font_scale = prev_font_scale if prev_font_scale + pdf.instance_variable_set :@base_text_align, prev_text_align if prev_text_align end end end diff --git a/spec/table_spec.rb b/spec/table_spec.rb index dfd2e2e9d..15b4497d3 100644 --- a/spec/table_spec.rb +++ b/spec/table_spec.rb @@ -1960,6 +1960,55 @@ def add_header(*) (expect pdf.lines).to eql ['10. ten', '11. eleven', '12. twelve', 'buckle', 'my', 'shoe'] end + it 'should honor horizontal alignment on AsciiDoc table cell' do + pdf = to_pdf <<~'EOS', analyze: true + [cols=1a] + |=== + |left + |=== + + [cols=^1a] + |=== + |center + |=== + + [cols=>1a] + |=== + |right + |=== + EOS + + page_width = pdf.pages[0][:size][0] + midpoint = page_width * 0.5 + left_text = pdf.find_unique_text 'left' + center_text = pdf.find_unique_text 'center' + right_text = pdf.find_unique_text 'right' + (expect left_text[:x]).to be < midpoint + (expect center_text[:x]).to be < midpoint + (expect center_text[:x] + center_text[:width]).to be > midpoint + (expect right_text[:x]).to be > midpoint + end + + it 'should not honor horizontal alignment on AsciiDoc table cell that contains non-paragraph blocks' do + pdf = to_pdf <<~'EOS', analyze: true + [cols=>1a] + |=== + | + left + + ''' + + left + |=== + EOS + + page_width = pdf.pages[0][:size][0] + midpoint = page_width * 0.5 + left_texts = pdf.find_text 'left' + (expect left_texts[0][:x]).to be < midpoint + (expect left_texts[1][:x]).to be < midpoint + end + it 'should convert nested table' do pdf = to_pdf <<~'EOS', analyze: true [cols="1,2a"]