summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Allen <dan.j.allen@gmail.com>2022-05-20 02:19:39 -0600
committerDan Allen <dan.j.allen@gmail.com>2022-05-20 14:47:43 -0600
commit734b06c39f12f77f51952a2eee47eff5ca28087c (patch)
tree75e9815ba74526da70622c1a8c6d019ae93df8f5
parent281f2b940b6a426241c1ae577f0fab08d35c985e (diff)
short-circuit formatted_text routine and log error if fragments in first line cannot fit on a new page
-rw-r--r--CHANGELOG.adoc6
-rw-r--r--lib/asciidoctor/pdf/ext/prawn/extensions.rb20
-rw-r--r--spec/converter_spec.rb17
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