asciidoctor-rhrev 1.5.2 → 1.6.0
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 +4 -4
- data/CHANGELOG.adoc +10 -0
- data/lib/asciidoctor/rhrev/converter.rb +109 -2
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: d50d58f6581222d194cf031114bf6aeb82525b1662e6765c4e24c5c4f0e530cd
|
|
4
|
+
data.tar.gz: b45e1e49cc09002e1267c1e31221658ec9aa26a5ca49d4ef9dc8ea3ba857e0d4
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 0cf35ff6b4b52a1b9851b8eb103efd5eafc0922f59045d4830b5a390a2a62607060ff79442d5c26e129512efaf06cbd0c4dfc06808f992b14fe3203f94a2e3cf
|
|
7
|
+
data.tar.gz: 39ac612cba2f168c9cf4b26eddaea213246d18a90a3b25283b38f82c035756ae78597b01090466ae97ffe644f53f813e8f6b907a7957f5bd4f470d8ecc607e73
|
data/CHANGELOG.adoc
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
= Changelog
|
|
2
2
|
|
|
3
|
+
== 1.6.0 (2026-09-02)
|
|
4
|
+
|
|
5
|
+
* Add per-item change bars and revision-history roll-up for individual items in an unordered or ordered list (PDF backend), previously only possible for a whole marked list. `Converter#convert_list_item` brackets asciidoctor-pdf's own per-item render call (`convert_list` calls it once per item directly, a real granular hook, unlike table rows) the same way the existing paragraph/ulist/olist/dlist overrides already bracket their own whole-block calls. No AsciiDoc syntax attaches a block attribute list directly to a list item's own bullet line, confirmed directly against a real parse: the attribute list is silently dropped, not attached to the item, the list, or anywhere else. The working construct, the same shape as an `a|` table cell's own workaround, is a block attribute list on content the item already legitimately attaches via a `+` continuation. `Converter#propagate_list_item_content_marks` copies a marked carrier block's rhrev attribute onto the enclosing item and strips it from the carrier, at prescan time, before real rendering: the strip matters because `convert_list_item`'s own `traverse_list_item` call renders an item's attached blocks through this same converter, so a left-marked carrier would independently trigger its own bar-inking hook too, a second bad bar. `list_item` is now one of the roll-up contexts, resolved via the same nearest-enclosing-section walk every other roll-up context already uses, reusing that mechanism unchanged. A marked sub-list attached to an item keeps its own independent mark; the new marker-carrier context set deliberately excludes ulist/olist/dlist/list_item so a compound item's own nested sub-list is never swallowed into the parent item's mark. A `dlist` using the `unordered`, `ordered`, or `qanda` style gets the same per-item support, since asciidoctor-pdf itself renders those through synthesized list items routed through the same hook; the default and `horizontal` `dlist` styles render each term and description pair inline with no per-item method call to override, the same category of structural gap table-row-level marking has, not attempted here. Verified directly: a real fixture rendered to PNG shows exactly one bar, spanning only the marked item, not the whole list and not bleeding into neighboring items; the revision-history table shows exactly one bullet for the marked item, nothing from its unmarked siblings. New regression file, `tests/regression/list-item-change-bars.rb`, confirmed to fail (a raised `NoMethodError`) without the fix and pass with it
|
|
6
|
+
* Note: gem-only; the Antora extension (HTML output, no page-margin bar geometry the same way) is unaffected, npm still bumps concurrently per the standing 1.5.1 policy
|
|
7
|
+
|
|
8
|
+
== 1.5.3 (2026-09-01)
|
|
9
|
+
|
|
10
|
+
* Fix `page_numbering_start_at: cover` still reporting the revision-history table and `pagerhref:` one page low when the theme has no real `front-cover-image`/`cover_front_image` of its own, for example a theme that draws its own cover through some other means. `Converter#compute_rhrev_page_numbering_start_page`'s `cover` branch fell back to plain `body_start` whenever `resolve_background_image` found nothing, matching 1.5.2's own `body`-shaped formula rather than the real one: asciidoctor-pdf itself falls back from `cover` to `title` in that case, not to `body`, and `title`'s own offset is 0 whenever the document has a title page at all (`doctype: book`, or the `title-page` attribute), regardless of whether a real front cover ever rendered. `body_start` only remains correct for the narrow remaining case of no front cover and no title page either. Reported directly against a real document: the table was one page low throughout. New regression case, `cover-no-image`, in `tests/regression/rhrev-page-numbering-start-at.rb`, confirmed to fail without the fix and pass with it
|
|
11
|
+
* Note: gem-only, matching 1.5.2; npm still bumps concurrently per the standing 1.5.1 policy
|
|
12
|
+
|
|
3
13
|
== 1.5.2 (2026-09-01)
|
|
4
14
|
|
|
5
15
|
* Fix revision-history and `pagerhref` page numbers being off by a fixed, per-document offset for every `page_numbering_start_at` mode other than `body` (PDF backend). `Converter#record_rhrev_body_start_page` always assumed a `body`-mode restart (wherever structural body content first renders), the only mode where that assumption holds; reported directly with real page numbers from a real document under `after-toc` (an 11-page discrepancy, exactly the front matter preceding the real restart point) and `cover` (a consistent 1-page discrepancy, exactly the cover page numbering there is contiguous with, not reset after). `Converter#compute_rhrev_page_numbering_start_page` now reads the document's own resolved mode directly, matching asciidoctor-pdf's own logic (`converter.rb`'s own `page_numbering_start_at` branches), and `Converter#correct_rhrev_page_numbering` (called once, after the whole document, table of contents included, has rendered) corrects every number `record_rhrev_body_start_page`'s own eager, body-mode-only capture recorded during traversal: `toc`/`after-toc`'s real restart point is not knowable any earlier, confirmed directly against asciidoctor-pdf's own source, since it only finalizes the table of contents' real page extent after inking it. `Catalog#recompute_display_pages` applies the correction from each entry's own already-stored real physical page number (`page_sortable`), never re-derived. An explicit integer `page_numbering_start_at` remains a known, undocumented-no-longer limitation: that mode's own formula is a genuinely different shape (the body's own first page is labeled the given integer, not necessarily displayed page "1"), not confirmed against a real build, so left unhandled rather than risk a second, differently-wrong number. Verified directly against real `asciidoctor-pdf` builds for `after-toc` and `cover` (not assumed from source reading alone): the revision-history table's own reported page cross-checked against the number actually printed in the footer of the real page a marked entry lands on, confirmed wrong before the fix and correct after, for both modes independently; `body` mode and the two existing pagination regression fixtures produce byte-identical rendered text before and after. New regression fixture, `tests/regression/rhrev-page-numbering-start-at.rb`
|
|
@@ -108,8 +108,19 @@ module Asciidoctor
|
|
|
108
108
|
body_start = @rhrev_body_start_page || 1
|
|
109
109
|
case (mode = @theme.page_numbering_start_at || 'body')
|
|
110
110
|
when 'cover'
|
|
111
|
+
# asciidoctor-pdf itself only honors page-numbering-start-at:
|
|
112
|
+
# cover when a real front cover exists (front-cover-image or the
|
|
113
|
+
# theme's own cover_front_image); otherwise it falls back to
|
|
114
|
+
# title, not body, silently (converter.rb's own page_numbering_
|
|
115
|
+
# start_at cascade), and title's offset is 0 whenever the
|
|
116
|
+
# document has a title page at all (doctype book, or the
|
|
117
|
+
# title-page attribute), regardless of whether that title page
|
|
118
|
+
# itself renders. body_start only survives as the real answer
|
|
119
|
+
# for the narrow remaining case: no front cover AND no title
|
|
120
|
+
# page either.
|
|
111
121
|
front_cover_path, = resolve_background_image node.document, @theme, 'front-cover-image', theme_key: :cover_front_image
|
|
112
|
-
|
|
122
|
+
has_title_page = node.document.doctype == 'book' || (node.document.attr? 'title-page')
|
|
123
|
+
(front_cover_path || has_title_page) ? 1 : body_start
|
|
113
124
|
when 'toc'
|
|
114
125
|
(extent = @toc_extent) ? extent.from.page : body_start
|
|
115
126
|
when 'after-toc'
|
|
@@ -400,6 +411,30 @@ module Asciidoctor
|
|
|
400
411
|
bracket_change_bar(node) { super }
|
|
401
412
|
end
|
|
402
413
|
|
|
414
|
+
# A single item within a ulist/olist (and a dlist using the
|
|
415
|
+
# unordered/ordered/qanda styles, which asciidoctor-pdf itself
|
|
416
|
+
# synthesizes into real ListItem objects routed through here the
|
|
417
|
+
# same way), rather than the whole list. asciidoctor-pdf's own
|
|
418
|
+
# convert_list calls this once per item directly (not through the
|
|
419
|
+
# normal node.convert dispatch), a real granular hook, so the same
|
|
420
|
+
# bracket_change_bar shape as the nine block types above applies
|
|
421
|
+
# unchanged: bare super forwards list/opts along with node
|
|
422
|
+
# automatically. The bracket spans traverse_list_item's own call at
|
|
423
|
+
# the end of the real convert_list_item, which covers the item's
|
|
424
|
+
# marker, its principal text, and any attached continuation content
|
|
425
|
+
# together, correct even for a compound, multi-block item.
|
|
426
|
+
#
|
|
427
|
+
# A dlist using its default or horizontal style is NOT covered:
|
|
428
|
+
# asciidoctor-pdf renders those two styles' term/description pairs
|
|
429
|
+
# entirely inline inside convert_dlist itself, with no per-entry
|
|
430
|
+
# method call to override, the same category of structural gap
|
|
431
|
+
# table-row-level marking has (see LIST_ITEM_MARKER_CARRIER_
|
|
432
|
+
# CONTEXTS's own docblock and the project's declined-features
|
|
433
|
+
# notes); a bigger, riskier lift, not attempted here.
|
|
434
|
+
def convert_list_item node, list, opts = {}
|
|
435
|
+
bracket_change_bar(node) { super }
|
|
436
|
+
end
|
|
437
|
+
|
|
403
438
|
def convert_rhrev node
|
|
404
439
|
# The HtmlTreeprocessor (misleadingly named; it has no backend guard,
|
|
405
440
|
# unlike ChangeBarsHtmlTreeprocessor) unshifts a synthetic :rhrev
|
|
@@ -517,7 +552,24 @@ module Asciidoctor
|
|
|
517
552
|
# none yet for the matching revision), rather than needing its own
|
|
518
553
|
# id, its own destination, or a generated label. See
|
|
519
554
|
# rollup_child_revision_entries.
|
|
520
|
-
|
|
555
|
+
#
|
|
556
|
+
# list_item is included: enclosing_section's own node.parent walk
|
|
557
|
+
# already skips past a marked item's containing ulist/olist/dlist to
|
|
558
|
+
# the nearest section correctly, no special-casing needed there. Its
|
|
559
|
+
# own mark, however, never arrives via the item's own attributes
|
|
560
|
+
# directly, see propagate_list_item_content_marks below.
|
|
561
|
+
ROLLUP_CONTEXTS = [:paragraph, :ulist, :olist, :dlist, :list_item, :admonition, :open, :quote, :verse, :sidebar].freeze
|
|
562
|
+
|
|
563
|
+
# Contexts propagate_list_item_content_marks accepts as a list
|
|
564
|
+
# item's own marker carrier: everything ROLLUP_CONTEXTS covers
|
|
565
|
+
# except list_item itself (the item is the propagation target, not
|
|
566
|
+
# a valid source) and ulist/olist/dlist (a nested sub-list attached
|
|
567
|
+
# to an item already has its own independent, correct mark-and-
|
|
568
|
+
# roll-up path via convert_ulist/convert_olist/convert_dlist and
|
|
569
|
+
# this same ROLLUP_CONTEXTS walk; swallowing its mark into the
|
|
570
|
+
# parent item here would both steal it from the sub-list and give
|
|
571
|
+
# the item a mark it never earned).
|
|
572
|
+
LIST_ITEM_MARKER_CARRIER_CONTEXTS = (ROLLUP_CONTEXTS - [:list_item, :ulist, :olist, :dlist]).freeze
|
|
521
573
|
|
|
522
574
|
# Walks up from node to its nearest enclosing :section, or nil if
|
|
523
575
|
# none exists, i.e. node sits in the document preamble. Shared by
|
|
@@ -721,6 +773,60 @@ module Asciidoctor
|
|
|
721
773
|
end
|
|
722
774
|
end
|
|
723
775
|
|
|
776
|
+
# No canonical AsciiDoc syntax attaches a block attribute list
|
|
777
|
+
# directly to one list item's own bullet line; confirmed directly
|
|
778
|
+
# (Asciidoctor.load, a real fixture): the attribute list is silently
|
|
779
|
+
# dropped, not attached to the item, the list, or anywhere else. The
|
|
780
|
+
# working construct, the same shape as an a| table cell's own
|
|
781
|
+
# workaround, is a block attribute list on content the item already
|
|
782
|
+
# legitimately attaches via a `+` continuation:
|
|
783
|
+
#
|
|
784
|
+
# * Item two
|
|
785
|
+
# +
|
|
786
|
+
# [rhrev1-2="Added item two"]
|
|
787
|
+
# --
|
|
788
|
+
# --
|
|
789
|
+
#
|
|
790
|
+
# or with real visible continuation text instead of an empty open
|
|
791
|
+
# block. Copies any rhrev-prefixed attribute from the item's own
|
|
792
|
+
# directly-attached marker block onto the item itself, then strips
|
|
793
|
+
# it from that block, the same two reasons propagate_cell_content_
|
|
794
|
+
# marks strips its own source: convert_list_item's traverse_list_
|
|
795
|
+
# item call renders an item's attached blocks through this same
|
|
796
|
+
# converter, so a left-marked carrier would independently trigger
|
|
797
|
+
# its own bar-inking hook too, and the strip keeps
|
|
798
|
+
# node_carries_own_rhrev?/rollup_child_revision_entries from later
|
|
799
|
+
# finding and rolling up the same mark a second time from the
|
|
800
|
+
# carrier's own now-redundant position in the tree.
|
|
801
|
+
#
|
|
802
|
+
# Deliberately only the item's own direct children (item.blocks),
|
|
803
|
+
# not a recursive descent: a compound item nesting a sub-list of
|
|
804
|
+
# its own must not have that sub-list's independent marks stolen
|
|
805
|
+
# and reattributed to the outer item, LIST_ITEM_MARKER_CARRIER_
|
|
806
|
+
# CONTEXTS excludes ulist/olist/dlist/list_item for exactly this
|
|
807
|
+
# reason, restricting a valid carrier to paragraph/admonition/open/
|
|
808
|
+
# quote/verse/sidebar.
|
|
809
|
+
#
|
|
810
|
+
# Must run before rollup_child_revision_entries and before real
|
|
811
|
+
# rendering, so the item's own attributes are already in place by
|
|
812
|
+
# the time either reads them.
|
|
813
|
+
def propagate_list_item_content_marks doc
|
|
814
|
+
doc.find_by(context: :list_item).each do |item|
|
|
815
|
+
item.blocks.each do |node|
|
|
816
|
+
next unless LIST_ITEM_MARKER_CARRIER_CONTEXTS.include? node.context
|
|
817
|
+
attr_entries = (node.instance_variable_get(:@attributes) rescue nil)
|
|
818
|
+
next if attr_entries.nil? || attr_entries.empty?
|
|
819
|
+
|
|
820
|
+
attr_entries.keys.each do |key|
|
|
821
|
+
key_str = key.to_s
|
|
822
|
+
next unless key_str.start_with?(@revision_prefix)
|
|
823
|
+
item.set_attr key_str, attr_entries[key]
|
|
824
|
+
node.remove_attr key_str
|
|
825
|
+
end
|
|
826
|
+
end
|
|
827
|
+
end
|
|
828
|
+
end
|
|
829
|
+
|
|
724
830
|
def rollup_table_cell_revision_entries doc
|
|
725
831
|
doc.find_by(context: :table).each do |table|
|
|
726
832
|
cells = (table.rows[:head] + table.rows[:body]).flatten
|
|
@@ -953,6 +1059,7 @@ module Asciidoctor
|
|
|
953
1059
|
end
|
|
954
1060
|
|
|
955
1061
|
propagate_cell_content_marks doc
|
|
1062
|
+
propagate_list_item_content_marks doc
|
|
956
1063
|
rollup_child_revision_entries doc
|
|
957
1064
|
rollup_table_cell_revision_entries doc
|
|
958
1065
|
|