From 36dc014fea3586ff75b5c16213a73d3f8edd8109 Mon Sep 17 00:00:00 2001 From: Dan Allen Date: Sat, 1 Feb 2020 23:52:59 -0700 Subject: [PATCH] resolves #1533 place dots on correct page when section title in TOC wraps across a page boundary (PR #1534) --- CHANGELOG.adoc | 1 + lib/asciidoctor/pdf/converter.rb | 6 +++++- .../fragment_position_renderer.rb | 3 ++- spec/toc_spec.rb | 20 +++++++++++++++++++ 4 files changed, 28 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.adoc b/CHANGELOG.adoc index b6f78a7e9..ea1a7cebc 100644 --- a/CHANGELOG.adoc +++ b/CHANGELOG.adoc @@ -12,6 +12,7 @@ For a detailed view of what has changed, refer to the {uri-repo}/commits/master[ * allow font path to be declared once for all font styles (#1507) * continue border, background, and column rule of admonition block on subsequent pages when block gets split (#1287) * allow max-width on caption be specified as a percentage (of the container width) (#1484) +* place dots on correct page when section title in TOC wraps across a page boundary (#1533) * add destination to top of imported PDF if ID is specified on image block * log reason if theme file cannot be parsed or compiled (#1491) * bundle emoji font and use as fallback in default-with-fallback-font theme (#1129) diff --git a/lib/asciidoctor/pdf/converter.rb b/lib/asciidoctor/pdf/converter.rb index 7e4342cdc..1712c63c1 100644 --- a/lib/asciidoctor/pdf/converter.rb +++ b/lib/asciidoctor/pdf/converter.rb @@ -3027,7 +3027,11 @@ def layout_toc_level sections, num_levels, line_metrics, dot_leader, num_front_m start_dots = last_fragment_pos.right + hanging_indent last_fragment_cursor = last_fragment_pos.top + line_metrics.padding_top # NOTE this will be incorrect if wrapped line is all monospace - start_cursor = last_fragment_cursor if start_cursor - last_fragment_cursor > line_metrics.height + if (last_fragment_page_number = last_fragment_pos.page_number) > start_page_number || + (start_cursor - last_fragment_cursor) > line_metrics.height + start_page_number = last_fragment_page_number + start_cursor = last_fragment_cursor + end end end_page_number = page_number end_cursor = cursor diff --git a/lib/asciidoctor/pdf/formatted_text/fragment_position_renderer.rb b/lib/asciidoctor/pdf/formatted_text/fragment_position_renderer.rb index 10a579847..e99e5035b 100644 --- a/lib/asciidoctor/pdf/formatted_text/fragment_position_renderer.rb +++ b/lib/asciidoctor/pdf/formatted_text/fragment_position_renderer.rb @@ -2,12 +2,13 @@ module Asciidoctor::PDF::FormattedText class FragmentPositionRenderer - attr_reader :top, :right, :bottom, :left + attr_reader :top, :right, :bottom, :left, :page_number def render_behind fragment @top = fragment.top @right = (@left = fragment.left) + fragment.width @bottom = fragment.bottom + @page_number = fragment.document.page_number end end end diff --git a/spec/toc_spec.rb b/spec/toc_spec.rb index 9a57d99ec..7ea8a1401 100644 --- a/spec/toc_spec.rb +++ b/spec/toc_spec.rb @@ -311,6 +311,26 @@ (expect page_number_text).to have_size 1 end + it 'should line up dots and page number with wrapped line when section title gets split across a page boundary' do + sections = (1..37).map {|num| %(\n\n== Section #{num}) }.join + pdf = to_pdf <<~EOS, doctype: :book, analyze: true + = Document Title + :toc: + #{sections} + + == This is a unbelievably long section title that probably shouldn't be a section title at all but here we are + + content + EOS + + page_2_lines = pdf.lines pdf.find_text page_number: 2 + (expect page_2_lines).to include 'Table of Contents' + (expect page_2_lines[-1]).to end_with 'but here' + page_3_lines = pdf.lines pdf.find_text page_number: 3 + (expect page_3_lines).to have_size 1 + (expect page_3_lines[0]).to match %r/we are(\. )+.*38$/ + end + it 'should allow hanging indent to be applied to lines that wrap' do pdf = to_pdf <<~'EOS', doctype: :book, pdf_theme: { toc_hanging_indent: 36 }, analyze: true = Document Title