diff options
| author | Dan Allen <dan.j.allen@gmail.com> | 2022-05-20 02:19:39 -0600 |
|---|---|---|
| committer | Dan Allen <dan.j.allen@gmail.com> | 2022-05-20 14:47:43 -0600 |
| commit | 734b06c39f12f77f51952a2eee47eff5ca28087c (patch) | |
| tree | 75e9815ba74526da70622c1a8c6d019ae93df8f5 | |
| parent | 281f2b940b6a426241c1ae577f0fab08d35c985e (diff) | |
short-circuit formatted_text routine and log error if fragments in first line cannot fit on a new page
| -rw-r--r-- | CHANGELOG.adoc | 6 | ||||
| -rw-r--r-- | lib/asciidoctor/pdf/ext/prawn/extensions.rb | 20 | ||||
| -rw-r--r-- | spec/converter_spec.rb | 17 |
3 files changed, 38 insertions, 5 deletions
diff --git a/CHANGELOG.adoc b/CHANGELOG.adoc index 717332b0..3d9d39c2 100644 --- a/CHANGELOG.adoc +++ b/CHANGELOG.adoc @@ -5,6 +5,12 @@ This document provides a high-level view of the changes to the {project-name} by release. For a detailed view of what has changed, refer to the {url-repo}/commits/main[commit history] on GitHub. +== Unreleased + +Bug Fixes:: + +* short-circuit formatted_text routine and log error if fragments in first line cannot fit on a new page + == 2.0.0 (2022-05-18) - @mojavelinux Improvements:: diff --git a/lib/asciidoctor/pdf/ext/prawn/extensions.rb b/lib/asciidoctor/pdf/ext/prawn/extensions.rb index 141dc5aa..3ec04c5f 100644 --- a/lib/asciidoctor/pdf/ext/prawn/extensions.rb +++ b/lib/asciidoctor/pdf/ext/prawn/extensions.rb @@ -431,15 +431,19 @@ module Asciidoctor # NOTE: override built-in fill_formatted_text_box to insert leading before second line when :first_line is true def fill_formatted_text_box text, options - if (initial_gap = options[:initial_gap]) && (first_text = text[0]) && first_text[:from_page] != page_number + if (initial_gap = options[:initial_gap]) && !text.empty? && text[0][:from_page] != page_number self.y -= initial_gap end merge_text_box_positioning_options options box = ::Prawn::Text::Formatted::Box.new text, options - remaining_text = box.render + remaining_fragments = box.render @no_text_printed = box.nothing_printed? @all_text_printed = box.everything_printed? - remaining_text[0][:from_page] = page_number unless remaining_text.empty? + unless remaining_fragments.empty? || (remaining_fragments[0][:from_page] ||= page_number) == page_number + log :error, %(cannot fit formatted text on page: #{remaining_fragments.map {|it| it[:image_path] || it[:text] }.join}) + page.tare_content_stream + remaining_fragments = {} + end if @final_gap || (options[:first_line] && !(@no_text_printed || @all_text_printed)) self.y -= box.height + box.line_gap + box.leading @@ -447,7 +451,7 @@ module Asciidoctor self.y -= box.height end - remaining_text + remaining_fragments end # NOTE: override built-in draw_indented_formatted_line to set first_line flag @@ -483,7 +487,13 @@ module Asciidoctor else remaining_fragments = box.render dry_run: true end - remaining_fragments.empty? ? (remaining_fragments = nil) : (remaining_fragments[0][:from_page] = page_number) + if remaining_fragments.empty? + remaining_fragments = nil + elsif (remaining_fragments[0][:from_page] ||= page_number) != page_number + log :error, %(cannot fit formatted text on page: #{remaining_fragments.map {|it| it[:image_path] || it[:text] }.join}) + page.tare_content_stream + remaining_fragments = nil + end if first_line_text_transform # NOTE: applying text transform here could alter the wrapping, so isolate first line and shrink it to fit first_line_text = (box.instance_variable_get :@printed_lines)[0] diff --git a/spec/converter_spec.rb b/spec/converter_spec.rb index 563181df..58c111e8 100644 --- a/spec/converter_spec.rb +++ b/spec/converter_spec.rb @@ -500,6 +500,23 @@ describe Asciidoctor::PDF::Converter do (expect actual_column).to eql 0 (expect last_visited_column).to eql 1 end + + it 'should short-circuit formatted_text and log error if text cannot not fit on new page' do + doc = Asciidoctor.load 'text', backend: :pdf + last_page = last_page_number = nil + (expect do + doc.converter.instance_exec do + init_pdf doc + start_new_page + ink_prose 'before' + formatted_text [{ text: 'x', ascender: bounds.height, descender: font.descender }] + last_page = page + last_page_number = page_number + end + end).to log_message severity: :ERROR, message: 'cannot fit formatted text on page: x' + (expect last_page).to be_empty + (expect last_page_number).to eql 2 + end end describe '#next_enclosed_block' do |
