summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Allen <dan.j.allen@gmail.com>2022-05-03 11:53:39 -0600
committerGitHub <noreply@github.com>2022-05-03 11:53:39 -0600
commit0dd5466a1b8e153b30e6143b0bb2a8ddab28a579 (patch)
tree5011b314add1a8105895ed8bc428926dd3e6908a
parent843e7effa1725c8067ffe9adfb568ba54e8d2450 (diff)
resolves #2128 make allocate_toc method reusable (PR #2129)
-rw-r--r--docs/modules/extend/examples/pdf-converter-chapter-toc.rb2
-rw-r--r--lib/asciidoctor/pdf/converter.rb22
-rw-r--r--spec/spec_helper.rb8
-rw-r--r--spec/toc_spec.rb61
4 files changed, 78 insertions, 15 deletions
diff --git a/docs/modules/extend/examples/pdf-converter-chapter-toc.rb b/docs/modules/extend/examples/pdf-converter-chapter-toc.rb
index 7bdc75ad..bfbc1712 100644
--- a/docs/modules/extend/examples/pdf-converter-chapter-toc.rb
+++ b/docs/modules/extend/examples/pdf-converter-chapter-toc.rb
@@ -16,11 +16,9 @@ class PDFConverterChapterTOC < (Asciidoctor::Converter.for 'pdf')
def ink_chapter_title sect, title, opts
super
if ((doc = sect.document).attr? 'chapter-toc') && (levels = (doc.attr 'chapter-toclevels', 1).to_i + 1) > 1
- old_toc_extent = @toc_extent
theme_font :base do
sect.set_attr 'pdf-toc-extent', (allocate_toc sect, levels, cursor, false)
end
- @toc_extent = old_toc_extent
end
end
end
diff --git a/lib/asciidoctor/pdf/converter.rb b/lib/asciidoctor/pdf/converter.rb
index 702e21d5..f6869b31 100644
--- a/lib/asciidoctor/pdf/converter.rb
+++ b/lib/asciidoctor/pdf/converter.rb
@@ -218,7 +218,7 @@ module Asciidoctor
if (insert_toc = (doc.attr? 'toc') && !((toc_placement = doc.attr 'toc-placement') == 'macro' || toc_placement == 'preamble') && doc.sections?)
start_new_page if @ppbook && verso_page?
add_dest_for_block doc, id: 'toc', y: (at_page_top? ? page_height : nil)
- allocate_toc doc, toc_num_levels, cursor, title_page_on
+ @toc_extent = allocate_toc doc, toc_num_levels, cursor, title_page_on
else
@toc_extent = nil
end
@@ -305,12 +305,12 @@ module Asciidoctor
# NOTE: for a book, these are leftover footnotes; for an article this is everything
outdent_section { ink_footnotes doc }
- if @toc_extent
+ if (toc_extent = @toc_extent)
if title_page_on && !insert_toc
- num_front_matter_pages[0] = @toc_extent.to.page if @theme.running_content_start_at == 'after-toc'
- num_front_matter_pages[1] = @toc_extent.to.page if @theme.page_numbering_start_at == 'after-toc'
+ num_front_matter_pages[0] = toc_extent.to.page if @theme.running_content_start_at == 'after-toc'
+ num_front_matter_pages[1] = toc_extent.to.page if @theme.page_numbering_start_at == 'after-toc'
end
- toc_page_nums = ink_toc doc, toc_num_levels, @toc_extent.from.page, @toc_extent.from.cursor, num_front_matter_pages[1]
+ toc_page_nums = ink_toc doc, toc_num_levels, toc_extent.from.page, toc_extent.from.cursor, num_front_matter_pages[1]
else
toc_page_nums = []
end
@@ -2359,7 +2359,7 @@ module Asciidoctor
end
def convert_toc node, opts = {}
- # NOTE: only allow document to have a single toc
+ # NOTE: only allow document to have a single managed toc
return if @toc_extent
is_macro = (placement = opts[:placement] || 'macro') == 'macro'
if ((doc = node.document).attr? 'toc-placement', placement) && (doc.attr? 'toc') && doc.sections?
@@ -2368,11 +2368,11 @@ module Asciidoctor
start_new_page if @ppbook && verso_page? && !(is_macro && (node.option? 'nonfacing'))
end
add_dest_for_block node, id: (node.id || 'toc') if is_macro
- allocate_toc doc, (doc.attr 'toclevels', 2).to_i, cursor, (title_page_on = is_book || (doc.attr? 'title-page'))
- @index.start_page_number = @toc_extent.to.page + 1 if title_page_on && @theme.page_numbering_start_at == 'after-toc'
+ toc_extent = @toc_extent = allocate_toc doc, (doc.attr 'toclevels', 2).to_i, cursor, (title_page_on = is_book || (doc.attr? 'title-page'))
+ @index.start_page_number = toc_extent.to.page + 1 if title_page_on && @theme.page_numbering_start_at == 'after-toc'
if is_macro
- @disable_running_content[:header] += @toc_extent.page_range if node.option? 'noheader'
- @disable_running_content[:footer] += @toc_extent.page_range if node.option? 'nofooter'
+ @disable_running_content[:header] += toc_extent.page_range if node.option? 'noheader'
+ @disable_running_content[:footer] += toc_extent.page_range if node.option? 'nofooter'
end
end
nil
@@ -3168,7 +3168,7 @@ module Asciidoctor
extent.each_page {|first_page| start_new_page unless first_page }
move_cursor_to extent.to.cursor
end
- @toc_extent = extent
+ extent
end
def get_entries_for_toc node
diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb
index e5483717..205b8efb 100644
--- a/spec/spec_helper.rb
+++ b/spec/spec_helper.rb
@@ -352,6 +352,14 @@ RSpec.configure do |config|
end
end
+ def docs_dir
+ File.join __dir__, '..', 'docs'
+ end
+
+ def doc_file path
+ File.absolute_path path, docs_dir
+ end
+
def examples_dir
File.join __dir__, '..', 'examples'
end
diff --git a/spec/toc_spec.rb b/spec/toc_spec.rb
index 6966ed5f..7433304e 100644
--- a/spec/toc_spec.rb
+++ b/spec/toc_spec.rb
@@ -1398,7 +1398,7 @@ describe 'Asciidoctor::PDF::Converter - TOC' do
(expect images[0][:width]).to eql images[1][:width]
end
- it 'should allow extnded converter to insert extra page before toc' do
+ it 'should allow extended converter to insert extra page before toc' do
backend = nil
create_class (Asciidoctor::Converter.for 'pdf') do
register_for (backend = %(pdf#{object_id}).to_sym)
@@ -1436,7 +1436,7 @@ describe 'Asciidoctor::PDF::Converter - TOC' do
(expect (pdf.find_text 'Chapter B')[0][:page_number]).to eql 3
end
- it 'should allow extnded converter to insert extra entries into TOC' do
+ it 'should allow extended converter to insert extra entries into TOC' do
backend = nil
create_class (Asciidoctor::Converter.for 'pdf') do
register_for (backend = %(pdf#{object_id}).to_sym)
@@ -1486,4 +1486,61 @@ describe 'Asciidoctor::PDF::Converter - TOC' do
(expect annots.select {|it| it[:Dest] == 'check-for-ruby' }).to have_size 2
(expect annots.select {|it| it[:Dest] == 'screenshot' }).to have_size 2
end
+
+ it 'should allow extended converter to insert chapter per TOC' do
+ source_file = doc_file 'modules/extend/examples/pdf-converter-chapter-toc.rb'
+ source_lines = (File.readlines source_file).select {|l| l == ?\n || (l.start_with? ' ') }
+ ext_class = create_class Asciidoctor::Converter.for 'pdf'
+ backend = %(pdf#{ext_class.object_id})
+ source_lines[0] = %(register_for '#{backend}')
+ ext_class.class_eval source_lines.join, source_file
+ pdf = to_pdf <<~'EOS', backend: backend, analyze: true
+ = Document Title
+ :doctype: book
+ :toc:
+ :toclevels: 1
+ :chapter-toc:
+ :chapter-toclevels: 2
+
+ == Chapter Title
+
+ === First Section
+
+ ==== Subsection
+
+ <<<
+
+ === Last Section
+
+ == Another Chapter
+ EOS
+
+ toc_text = pdf.find_text page_number: 2
+ toc_lines = toc_text
+ .sort_by {|it| -it[:y] }
+ .group_by {|it| it[:y] }
+ .map {|_, it| it.sort_by {|fragment| fragment[:order] }.map {|fragment| fragment[:string] }.join }
+ (expect toc_lines).to have_size 3
+ (expect toc_lines[0]).to eql 'Table of Contents'
+ (expect toc_lines[1]).to start_with 'Chapter Title'
+ (expect toc_lines[1]).to end_with '1'
+ (expect toc_lines[2]).to start_with 'Another Chapter'
+ (expect toc_lines[2]).to end_with '3'
+
+ ch1_text = pdf.find_text page_number: 3
+ ch1_lines = ch1_text
+ .sort_by {|it| -it[:y] }
+ .group_by {|it| it[:y] }
+ .map {|_, it| it.sort_by {|fragment| fragment[:order] }.map {|fragment| fragment[:string] }.join }
+ (expect ch1_lines).to have_size 6
+ (expect ch1_lines[0]).to eql 'Chapter Title'
+ (expect ch1_lines[1]).to start_with 'First Section'
+ (expect ch1_lines[1]).to end_with '1'
+ (expect ch1_lines[2]).to start_with 'Subsection'
+ (expect ch1_lines[2]).to end_with '1'
+ (expect ch1_lines[3]).to start_with 'Last Section'
+ (expect ch1_lines[3]).to end_with '2'
+ (expect ch1_lines[4]).to eql 'First Section'
+ (expect ch1_lines[5]).to eql 'Subsection'
+ end
end