asciidoctor-lists-extended 1.1.3 → 1.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0f7291c0cf61e02d8b708696ff9f0ef2ef2a0375ede9c43967ef5871b0d2f57a
4
- data.tar.gz: 4ce851476223d5e3c532420f7849476edae9096ab0699deb8e120d4bc137a936
3
+ metadata.gz: 2695e2cdf6dd6a40fcffa22e128746ddb7486187aa38c850b50db829f8843a6a
4
+ data.tar.gz: ad50e9b6ac7434b98a8c04ffe7351847ffbedf9cb5161274c30c618289e29a26
5
5
  SHA512:
6
- metadata.gz: 8f940f72d95a2e4ba1450467c3276e02f6bb0e915bee689b48e7dceebf6c6a88a3318a436b529a2235bf60e26100a61c4a5215e11ece017d8bce8e957571a510
7
- data.tar.gz: ff8c701fb655fdffb3aee51eebc49a98cb9aaf5a892c6f434d0cda02a0a6822f397ef905820b9bd6921014b037dc68282543ad6eae931498e1b715eac163aaed
6
+ metadata.gz: 47279a6a39951b24054144ee43e0aa803290d77a2258bc165107d47142df24ff390ed9700aaf6eef6f18fecf5ba459f021674750a724b1dcd698daf56d90529e
7
+ data.tar.gz: e8f12e04b08cac32b2420177fef005668fba67e4ead2afddac82199c10b98eb74b7b9560faf579b3e42145d8acf28c9c5884d3ba5828c0429cf85f909abe1763
data/README.adoc CHANGED
@@ -222,8 +222,11 @@ In PDF mode the extension hooks into `asciidoctor-pdf`'s ToC allocation/renderin
222
222
  Document-wide lists (macros inside a top-level `== …` section) are placed in the *front matter* (directly after the ToC) regardless of where in the source the `list-of::` macros appear.
223
223
  The macro order in the source determines the order of the lists in the front matter.
224
224
 
225
- When the top-level section that contains a `list-of::` macro also has other content admonitions, paragraphs, or other blocks — those blocks are moved to the front matter too and rendered between the list heading and the first entry.
226
- The enclosing section is then removed from the body so it does not appear twice.
225
+ Blocks placed *before* the `list-of::` macro in the same section (admonitions, notes, paragraphs) are moved to the front matter and rendered between the list heading and the first entry.
226
+
227
+ Blocks placed *after* the macro in the same section — for example a sidebar or admonition following a `<<<` page break — are re-inserted into the document body at the section's former position and rendered there, not in the front matter.
228
+
229
+ The enclosing section is removed from the body so it does not appear twice.
227
230
 
228
231
  You can place `list-of::` macros inside any subsection to generate *section-scoped* lists.
229
232
  The scope is determined automatically from where the macro appears in the document hierarchy:
@@ -86,6 +86,7 @@ module Asciidoctor
86
86
  toc_entry_title = doc.attr('toc-title') || 'Table of Contents'
87
87
  insert_list_into_toc_section doc, toc_entry_title, @toc_extent.page_range,
88
88
  '_toc_in_toc', @list_toc_insert_idx,
89
+ pdf_dest: dest_top(@toc_extent.page_range.first),
89
90
  exclude_from_outline: true
90
91
  @list_toc_insert_idx += 1
91
92
  end
@@ -103,6 +104,7 @@ module Asciidoctor
103
104
  # meaningful label for the ToC or outline — skip the virtual section.
104
105
  unless list_title.nil_or_empty?
105
106
  insert_list_into_toc_section doc, list_title, list_page_nums, list_id, @list_toc_insert_idx,
107
+ pdf_dest: @last_list_dest || dest_top(list_page_nums.first),
106
108
  exclude_from_toc: resolve_exclude_from_toc(config),
107
109
  exclude_from_outline: resolve_exclude_from_outline(config)
108
110
  @list_toc_insert_idx += 1
@@ -317,16 +319,39 @@ module Asciidoctor
317
319
  # rendered in the front matter alongside the list rather than left
318
320
  # as orphaned content in the body.
319
321
  section_title = (parent.context == :section) ? parent.title : nil
320
- section_body = parent.context == :section ?
321
- parent.blocks.reject { |b| b.object_id == block.object_id } : []
322
- # Page-break blocks (<<<) must be deleted from the section but must NOT
323
- # be rendered in front matter they only existed to separate list sections
324
- # from body chapters.
325
- extra_blocks = section_body.reject { |b| b.context == :page_break }
322
+
323
+ # Split sibling blocks around the macro position:
324
+ # pre_body — before the macro rendered in front matter (notes, admonitions)
325
+ # post_body after the macro → re-inserted into the document body so they
326
+ # are not lost (e.g. a sidebar or admonition the author placed
327
+ # after the list-of:: call, possibly preceded by a <<<)
328
+ if parent.context == :section
329
+ macro_idx = parent.blocks.index(block)
330
+ pre_body = macro_idx > 0 ? parent.blocks[0, macro_idx] : []
331
+ post_body = parent.blocks[(macro_idx + 1)..] || []
332
+ # Page-break blocks in pre_body are deleted but not rendered in front matter.
333
+ extra_blocks = pre_body.reject { |b| b.context == :page_break }
334
+ else
335
+ pre_body = post_body = extra_blocks = []
336
+ end
326
337
 
327
338
  parent.blocks.delete(block)
328
- section_body.each { |b| parent.blocks.delete(b) }
329
- parent.parent&.blocks&.delete(parent) if parent.context == :section && parent.blocks.empty?
339
+ pre_body.each { |b| parent.blocks.delete(b) }
340
+ post_body.each { |b| parent.blocks.delete(b) }
341
+
342
+ if parent.context == :section && parent.blocks.empty?
343
+ grandparent = parent.parent
344
+ if grandparent
345
+ section_idx = grandparent.blocks.index(parent)
346
+ grandparent.blocks.delete(parent)
347
+ # Re-insert post-macro blocks into the grandparent at the section's
348
+ # former position so they survive in the document body.
349
+ post_body.each_with_index do |b, i|
350
+ b.parent = grandparent
351
+ grandparent.blocks.insert(section_idx + i, b)
352
+ end
353
+ end
354
+ end
330
355
 
331
356
  next if entries.empty?
332
357
 
@@ -344,11 +369,15 @@ module Asciidoctor
344
369
  end
345
370
  end
346
371
 
347
- # Strip leading page-break blocks left over after list sections were
348
- # removed. A `<<<` placed between the last list section and the first
349
- # chapter now sits orphaned at the document level; without this cleanup
350
- # it renders as a blank page before Chapter 1.
351
- doc.blocks.shift while doc.blocks.first&.context == :page_break
372
+ # Strip leading page-break blocks left orphaned at the document level
373
+ # after list section removal but only when the immediately following
374
+ # block is a section (chapter heading). A page-break before non-section
375
+ # body content (sidebar, admonition, etc.) was re-inserted intentionally
376
+ # from a post-macro position and must be preserved.
377
+ while doc.blocks.first&.context == :page_break &&
378
+ doc.blocks[1]&.context == :section
379
+ doc.blocks.shift
380
+ end
352
381
  end
353
382
 
354
383
  # -----------------------------------------------------------------------
@@ -42,6 +42,7 @@ module Asciidoctor
42
42
  outdent: true,
43
43
  role: theme_key_sym
44
44
  add_dest_for_block doc, id: dest_id, y: (at_page_top? ? page_height : nil)
45
+ @last_list_dest = doc.attr('pdf-destination') unless scratch?
45
46
  end
46
47
  end
47
48
 
@@ -91,7 +92,13 @@ module Asciidoctor
91
92
  #
92
93
  # insert_idx is the 0-based position among sibling list sections being inserted,
93
94
  # which preserves document order in the ToC.
94
- def insert_list_into_toc_section(doc, list_title, list_page_nums, list_id, insert_idx, exclude_from_toc: false, exclude_from_outline: false)
95
+ # pdf_dest: when nil (the default for regular lists), the outline falls back to
96
+ # get_dest(dest_name_for_id(list_id)) which resolves to the exact heading Y
97
+ # position registered by add_dest_for_block in ink_list_content.
98
+ # Pass an explicit dest_top value only for entries that have no add_dest_for_block
99
+ # call (e.g. toc-in-toc).
100
+ def insert_list_into_toc_section(doc, list_title, list_page_nums, list_id, insert_idx,
101
+ pdf_dest: nil, exclude_from_toc: false, exclude_from_outline: false)
95
102
  if (doc.attr? 'toc-placement', 'macro') && (toc_node = (doc.find_by context: :toc)[0])
96
103
  if (parent_section = toc_node.parent).context == :section
97
104
  grandparent_section = parent_section.parent
@@ -102,19 +109,14 @@ module Asciidoctor
102
109
  toc_level = doc.sections[0]&.level || 1
103
110
  base_idx = 0
104
111
  end
105
- # NOTE: do NOT use toc_node.attr('pdf-destination') — that is the ToC
106
- # page's own destination, which would make every list bookmark navigate
107
- # back to the ToC page instead of the actual list page.
108
- toc_dest = dest_top list_page_nums.first
109
112
  else
110
113
  grandparent_section = doc
111
114
  toc_level = doc.sections[0]&.level || 1
112
115
  base_idx = 0
113
- toc_dest = dest_top list_page_nums.first
114
116
  end
115
117
 
116
- list_section = Asciidoctor::Section.new grandparent_section, toc_level, false,
117
- attributes: { 'pdf-destination' => toc_dest }
118
+ list_section = Asciidoctor::Section.new grandparent_section, toc_level, false
119
+ list_section.set_attr 'pdf-destination', pdf_dest if pdf_dest
118
120
  list_section.title = list_title
119
121
  list_section.id = list_id
120
122
  list_section.set_attr 'pdf-page-start', list_page_nums.first
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: asciidoctor-lists-extended
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.3
4
+ version: 1.1.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - 白一百 baiyibai