diff --git a/docs/modules/theme/pages/add-running-content.adoc b/docs/modules/theme/pages/add-running-content.adoc index f94c82b54..c010d0f44 100644 --- a/docs/modules/theme/pages/add-running-content.adoc +++ b/docs/modules/theme/pages/add-running-content.adoc @@ -34,21 +34,26 @@ running-content: The `start-at` key accepts the following keywords or an integer: -after-toc:: The running content starts after the TOC, no matter where the TOC is placed in the document. -The `after-toc` value is only recognized if the title page is implicitly or explicitly enabled. -If `media=prepress`, this keyword refers to the first recto page after the last page of the TOC (it will skip an empty verso page). +after-toc:: The running content starts after the last page of the TOC, no matter where the TOC is placed in the document. +If `media=prepress`, this keyword refers to the next recto page after the last page of the TOC. +The `after-toc` value is primarily intended to be used with the book doctype, though it can be used with the article doctype if the title page is enabled. +If the TOC is not enabled, or the title page for an article is not enabled, this value reverts to `body`. + body:: This is the default value. -The running content starts on the first page of the document body, which is typically the first page after the TOC if the TOC is in its default location. -If `media=prepress`, this keyword refers to the first recto page after the last page of the TOC (it will skip an empty verso page). +The running content starts on the first page of the document body. +If the TOC is enabled in its default location, the first page of the document body is the next recto page after the TOC when `media=prepress` or the page that immediately follows the TOC otherwise. + title:: The running content starts on the title page. The `title` value is only recognized if the title page is implicitly or explicitly enabled. -toc:: The running content starts on the first page of the TOC. -The `toc` value only applies if the TOC is in the default location (before the first page of the body). -If the value is `toc`, and the toc macro is used to position the TOC, the `start-at` behavior is the same as if the TOC is not enabled. -The `toc` value is only recognized if the title page is implicitly or explicitly enabled. + +toc:: The running content starts on the first page of the TOC, no matter where the TOC is placed in the document. +The `toc` value is primarily intended to be used with the book doctype, though it can be used with the article doctype if the title page is enabled. +If the TOC is not enabled, or the title page for an article is not enabled, this value reverts to `body`. + [[page]]Integer:: The running content starts on the page that matches the number assigned to `start-at` (i.e., 1 is the first body page, 2 is the second body page). +Refer to the `body` value for an explanation of where the body starts. For a prepress book (`doctype=book` and `media=prepress`), the running content starts on the empty verso page before the body if the value is `0`. -When an integer is assigned to `start-at`, the title page doesn't need to be enabled. +An integer value is recognized by all doctypes and the title page doesn't need to be enabled. TIP: To turn off the running content on TOC pages inserted by the toc macro, set the `noheader` or `nofooter` options on the macro (e.g., `toc::[opts=nofooter]`). diff --git a/docs/modules/theme/pages/page-numbers.adoc b/docs/modules/theme/pages/page-numbers.adoc index 2c91657da..997b97dcb 100644 --- a/docs/modules/theme/pages/page-numbers.adoc +++ b/docs/modules/theme/pages/page-numbers.adoc @@ -74,21 +74,27 @@ page: The `start-at` key accepts the following keywords or an integer: after-toc:: The integer page numbering starts after the last page of the TOC, no matter where the TOC is placed in the document. -The `after-toc` value is only recognized if the title page is implicitly or explicitly enabled. -If `media=prepress`, this keyword refers to the first recto page after the last page of the TOC (it will skip an empty verso page). +If `media=prepress`, this keyword refers to the next recto page after the last page of the TOC. +The `after-toc` value is primarily intended to be used with the book doctype, though it can be used with the article doctype if the title page is enabled. +If the TOC is not enabled, or the title page for an article is not enabled, this value reverts to `body`. + body:: This is the default value. -The integer page numbering starts on the first page of the document body, which is typically the first page after the TOC if the TOC is in its default location. -If `media=prepress`, this keyword refers to the first recto page after the last page of the TOC (it will skip an empty verso page). +The integer page numbering starts on the first page of the document body. +If the TOC is enabled in its default location, the first page of the document body is the next recto page after the TOC when `media=prepress` or the page that immediately follows the TOC otherwise. + cover:: The integer page numbering starts on the front cover page of the document. The `cover` value is only recognized if the document has a front cover page (i.e., `front-cover-image`). + title:: The integer page numbering starts on the title page. The `title` value is only recognized if the title page is implicitly or explicitly enabled. -toc:: The integer page numbering starts on the first page of the TOC. -The `toc` value only applies if the TOC is in the default location (before the first page of the body). -If the value is `toc`, and the toc macro is used to position the TOC, the `start-at` behavior is the same as if the TOC is not enabled. -The `toc` value is only recognized if the title page is implicitly or explicitly enabled. + +toc:: The integer page numbering starts on the first page of the TOC, no matter where the TOC is placed in the document. +The `toc` value is primarily intended to be used with the book doctype, though it can be used with the article doctype if the title page is enabled. +If the TOC is not enabled, or the title page for an article is not enabled, this value reverts to `body`. + Integer:: The page numbering starts at the specified page of the body (i.e., 1 is the first body page, 2 is the second body page). -For a prepress book (`doctype=book` and `media=prepress`), the page numbering starts on the empty verso page before the body if the value is `0`. +Refer to the `body` value for an explanation of where the body starts. +For a prepress book (`doctype=book` and `media=prepress`), the page numbering starts on the verso page before the body if the value is `0`. An integer value is recognized by all doctypes and the title page doesn't need to be enabled. Let's start the integer page number on the title page of a document. diff --git a/lib/asciidoctor/pdf/converter.rb b/lib/asciidoctor/pdf/converter.rb index f29fd3e18..a11a69106 100644 --- a/lib/asciidoctor/pdf/converter.rb +++ b/lib/asciidoctor/pdf/converter.rb @@ -169,7 +169,7 @@ def convert_document doc ink_cover_page doc, :front has_front_cover = page_number > marked_page_number doctype = doc.doctype - if (has_title_page = (title_page_on = doctype == 'book' || (doc.attr? 'title-page')) && (start_title_page doc)) + if (has_title_page = (title_as_page = doctype == 'book' || (doc.attr? 'title-page')) && (start_title_page doc)) # NOTE: the base font must be set before any content is written to the main or scratch document font @theme.base_font_family, size: @root_font_size, style: @theme.base_font_style if perform_on_single_page { ink_title_page doc } @@ -184,7 +184,7 @@ def convert_document doc font @theme.base_font_family, size: @root_font_size, style: @theme.base_font_style end - unless title_page_on + unless title_as_page body_start_page_number = page_number theme_font :heading, level: 1 do ink_general_heading doc, doc.doctitle, align: (@theme.heading_h1_text_align&.to_sym || :center), level: 1, role: :doctitle @@ -195,10 +195,10 @@ def convert_document doc indent_section do toc_num_levels = (doc.attr 'toclevels', 2).to_i - if (insert_toc = (doc.attr? 'toc') && !((toc_placement = doc.attr 'toc-placement') == 'macro' || toc_placement == 'preamble') && !(get_entries_for_toc doc).empty?) + if (toc_at_top = (doc.attr? 'toc') && !((toc_placement = doc.attr 'toc-placement') == 'macro' || toc_placement == 'preamble') && !(get_entries_for_toc doc).empty?) start_new_page if @ppbook && verso_page? add_dest_for_block doc, id: 'toc', y: (at_page_top? ? page_height : nil) - @toc_extent = allocate_toc doc, toc_num_levels, cursor, (title_page_on && theme.toc_break_after != 'auto') + @toc_extent = allocate_toc doc, toc_num_levels, cursor, (title_as_page && theme.toc_break_after != 'auto') else @toc_extent = nil end @@ -210,7 +210,7 @@ def convert_document doc min_start_at = 1 end - if title_page_on + if title_as_page zero_page_offset = has_front_cover ? 1 : 0 first_page_offset = has_title_page ? zero_page_offset.next : zero_page_offset body_offset = (body_start_page_number = page_number) - 1 @@ -223,8 +223,10 @@ def convert_document doc when 'title' running_content_start_at = 'toc' unless has_title_page when 'toc' - running_content_start_at = 'body' unless insert_toc + uses_start_at_toc = true + running_content_start_at = 'body' unless toc_at_top when 'after-toc' + uses_start_at_after_toc = true running_content_start_at = 'body' end end @@ -243,8 +245,10 @@ def convert_document doc when 'title' page_numbering_start_at = 'toc' unless has_title_page when 'toc' - page_numbering_start_at = 'body' unless insert_toc + uses_start_at_toc = true + page_numbering_start_at = 'body' unless toc_at_top when 'after-toc' + uses_start_at_after_toc = true page_numbering_start_at = 'body' end end @@ -298,12 +302,17 @@ def convert_document doc end if (toc_extent = @toc_extent) - if title_page_on && !insert_toc - if @theme.running_content_start_at == 'after-toc' || @theme.page_numbering_start_at == 'after-toc' # rubocop:disable Style/SoleNestedConditional - last_toc_page = toc_extent.to.page - last_toc_page += 1 if @ppbook && (recto_page? last_toc_page) - num_front_matter_pages[0] = last_toc_page if @theme.running_content_start_at == 'after-toc' - num_front_matter_pages[1] = last_toc_page if @theme.page_numbering_start_at == 'after-toc' + if title_as_page && !toc_at_top && (uses_start_at_toc || uses_start_at_after_toc) + if uses_start_at_toc + toc_offset = toc_extent.from.page - 1 + num_front_matter_pages[0] = toc_offset if @theme.running_content_start_at == 'toc' + num_front_matter_pages[1] = toc_offset if @theme.page_numbering_start_at == 'toc' + end + if uses_start_at_after_toc + after_toc_offset = toc_extent.to.page + after_toc_offset += 1 if @ppbook && (recto_page? after_toc_offset) + num_front_matter_pages[0] = after_toc_offset if @theme.running_content_start_at == 'after-toc' + num_front_matter_pages[1] = after_toc_offset if @theme.page_numbering_start_at == 'after-toc' end end toc_page_nums = ink_toc doc, toc_num_levels, toc_extent.from.page, toc_extent.from.cursor, num_front_matter_pages[1] @@ -2384,11 +2393,15 @@ def convert_toc node, opts = {} if ((doc = node.document).attr? 'toc-placement', placement) && (doc.attr? 'toc') && !(get_entries_for_toc doc).empty? start_toc_page node, placement if (is_book = doc.doctype == 'book') add_dest_for_block node, id: (node.id || 'toc') if is_macro - toc_extent = @toc_extent = allocate_toc doc, (doc.attr 'toclevels', 2).to_i, cursor, (title_page_on = is_book || (doc.attr? 'title-page')) - if title_page_on && @theme.page_numbering_start_at == 'after-toc' - new_start_page_number = toc_extent.to.page + 1 - new_start_page_number += 1 if @ppbook && (verso_page? new_start_page_number) - @index.start_page_number = new_start_page_number + toc_extent = @toc_extent = allocate_toc doc, (doc.attr 'toclevels', 2).to_i, cursor, (title_as_page = is_book || (doc.attr? 'title-page')) + if title_as_page + if @theme.page_numbering_start_at == 'toc' + @index.start_page_number = toc_extent.from.page + elsif @theme.page_numbering_start_at == 'after-toc' + new_start_page_number = toc_extent.to.page + 1 + new_start_page_number += 1 if @ppbook && (verso_page? new_start_page_number) + @index.start_page_number = new_start_page_number + end end if is_macro @disable_running_content[:header] += toc_extent.page_range if node.option? 'noheader' diff --git a/spec/index_spec.rb b/spec/index_spec.rb index e3889a311..88479fc41 100644 --- a/spec/index_spec.rb +++ b/spec/index_spec.rb @@ -525,6 +525,38 @@ (expect terms).to eql %w(anchor AsciiDoc Asciidoctor authoring) end + it 'should adjust start page number for prepress book when page numbering starts at toc and toc macro is used' do + pdf = to_pdf <<~'END', pdf_theme: { page_numbering_start_at: 'toc' }, analyze: true + = Book Title + :doctype: book + :media: prepress + :toc: macro + + [dedication] + = Dedication + + Credit where credit is due. + + toc::[] + + == First Chapter + + ((apples)) + + == Second Chapter + + ((bananas)) + + [index] + == Index + END + + index_title_text = (pdf.find_text 'Index')[-1] + (expect index_title_text[:page_number]).to be 11 + index_lines = pdf.lines pdf.find_text page_number: 11 + (expect index_lines).to eql ['Index', 'A', 'apples, 3', 'B', 'bananas, 5'] + end + it 'should adjust start page number for prepress book when page numbering starts after-toc and toc macro is used' do pdf = to_pdf <<~'END', pdf_theme: { page_numbering_start_at: 'after-toc' }, analyze: true = Book Title diff --git a/spec/running_content_spec.rb b/spec/running_content_spec.rb index 205a9df8d..9b34f6aaa 100644 --- a/spec/running_content_spec.rb +++ b/spec/running_content_spec.rb @@ -403,6 +403,27 @@ (expect pgnum_labels).to eql [nil, nil, '1', '2', '3'] end + it 'should start running content at toc in body of book when start at is toc and macro toc is used' do + pdf = to_pdf <<~END, pdf_theme: { running_content_start_at: 'toc' }, enable_footer: true, analyze: true + = Document Title + :doctype: book + :toc: macro + + == First Chapter + + toc::[] + + == Second Chapter + + == Third Chapter + END + + pgnum_labels = (1.upto pdf.pages.size).each_with_object [] do |page_number, accum| + accum << ((pdf.find_text page_number: page_number, y: 14.263)[-1] || {})[:string] + end + (expect pgnum_labels.slice 0, 5).to eql [nil, nil, '2', '3', '4'] + end + it 'should start running content after toc in body of book when start at is after-toc and macro toc is used' do filler = (1..20).map {|it| %(== #{['Filler'] * 20 * ' '} #{it}\n\ncontent) }.join %(\n\n) pdf = to_pdf <<~END, pdf_theme: { running_content_start_at: 'after-toc' }, enable_footer: true, analyze: true @@ -786,6 +807,33 @@ (expect pgnum_labels).to eql [nil, '1', '2', '3'] end + it 'should start page numbering at toc in body of book when start at is toc and toc macro is used' do + pdf = to_pdf <<~END, enable_footer: true, pdf_theme: { page_numbering_start_at: 'toc' }, analyze: true + = Book Title + :doctype: book + :toc: macro + + == Dedication + + To the only person who gets me. + + toc::[] + + == Acknowledgements + + Thanks all to all who made this possible! + + == Chapter One + + content + END + + pgnum_labels = (1.upto pdf.pages.size).each_with_object [] do |page_number, accum| + accum << ((pdf.find_text page_number: page_number, y: 14.263)[-1] || {})[:string] + end + (expect pgnum_labels.slice 0, 5).to eql [nil, 'ii', '1', '2', '3'] + end + it 'should start page numbering after toc in body of book when start at is after-toc and toc macro is used' do filler = (1..20).map {|it| %(== #{['Filler'] * 20 * ' '} #{it}\n\ncontent) }.join %(\n\n) pdf = to_pdf <<~END, enable_footer: true, pdf_theme: { page_numbering_start_at: 'after-toc' }, analyze: true