diff options
| -rw-r--r-- | docs/modules/extend/examples/pdf-converter-chapter-toc.rb | 2 | ||||
| -rw-r--r-- | lib/asciidoctor/pdf/converter.rb | 22 | ||||
| -rw-r--r-- | spec/spec_helper.rb | 8 | ||||
| -rw-r--r-- | spec/toc_spec.rb | 61 |
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 |
