asciidoctor-rhrev 1.8.2 → 1.8.3

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: 155f025dbf45d15c912cbb3f624bc9214344472bd3d33e21c8cfb8dcca21f54a
4
- data.tar.gz: b6ceffec703149d7b45f2c3007ff32099421532cf9e73f9cff763200706f6b00
3
+ metadata.gz: d6b54dc5e03efdf90006626cb974c4c4197b27ed97d960e5e0d2ce22231e7010
4
+ data.tar.gz: a0458dd0638281b54db276cdc03c0a0e3e543f4da8cf8fcae08a2a89a124bd15
5
5
  SHA512:
6
- metadata.gz: eb676e02167dad226f2ef494bf8de843df79497d8f6fd419d44d815c727e635ea6d62ca9767283540630a515ae27c201695d67875b57d6684158cb1dc15f26e2
7
- data.tar.gz: 4369e143e5614067d6f0f28039788e5004a5f772bc5383beacfd56c6f20c3dd7970808515bbcf9b459337d4d7b726e79f3b1d20bbdaa46a689cc26bb639fa6f4
6
+ metadata.gz: 06edfa5079b4b995ebf98fd709af51396fe4c31aea40f2a55af14ab75112c7eae5f11ffcf9dc3195b0ff1dee2c077f134524a0f89d53c7ce43db2d9205879fee
7
+ data.tar.gz: 2624c3f6c4d7951def744ec358eec91f49718f6bf96376d9afda2de9e8e8dc59c5298da3997b7d1c79217e1d519582b1d689fb3fc9867149f185b1db5f2cc3e3
data/CHANGELOG.adoc CHANGED
@@ -1,5 +1,10 @@
1
1
  = Changelog
2
2
 
3
+ == 1.8.3 (2026-10-22)
4
+
5
+ * Fix per-item list change bars landing on another revision's items when marks for several revisions stack one per attribute line (PDF backend). Asciidoctor numbers positional entries per attribute line and merges the lines into one hash, so a later line's targets overwrote an earlier line's: `[rhrev1-2="...",2]` followed by `[rhrev1-3="..."]` barred item 2 for revision 1.3 instead of the whole list, and a current mark on the first line took the targets of the line below it. The new `mark_targets.rb` hooks `AttributeList#parse_into`, reads each block attribute line's own memoized parse result, and records which positional entries follow which mark on that line; `Converter#list_item_change_bar_targets` reads the current mark's own record and falls back to every positional entry only for a list built without one. Reported against a real document. Stacked-line checks in `tests/regression/list-item-target-change-bars.rb` cover a current mark with no targets, a current mark on the first line, a later line with fewer targets, a custom `revhistoryprefix`, and a style before the mark, plus a render spy that fails (bars on the wrong items) without the fix
6
+ * Note: gem-only; the Antora extension has no per-item list targets, npm still bumps concurrently per the standing 1.5.1 policy
7
+
3
8
  == 1.8.2 (2026-10-06)
4
9
 
5
10
  * Change the initial-release table's default text from `Initial Release` to `Initial release` and render it bold (PDF backend), matching the bold `Page` cell beside it; `rhrev-customization-initial-release-text` still overrides the text and is rendered bold too
@@ -481,14 +481,24 @@ module Asciidoctor
481
481
  # Reuses change_bar? for the marked/not-marked check, the same
482
482
  # predicate every other bar-inking decision in this file already
483
483
  # uses, so this only ever answers for the current revnumber.
484
+ #
485
+ # Only the current mark's own positional attributes count. With
486
+ # stacked attribute lines the merged hash mixes every line's
487
+ # positional entries, so the per-line record MarkTargets keeps at
488
+ # parse time decides; a list built without one (through the
489
+ # extension API, for instance) falls back to every positional entry.
484
490
  def list_item_change_bar_targets node
485
491
  return nil unless change_bar? node
486
492
  raw = node.instance_variable_get(:@attributes)
487
- positional_keys = raw.keys.select {|k| ::Integer === k }.sort
488
- return :all if positional_keys.empty?
493
+ tokens = if (by_mark = raw[::Asciidoctor::Rhrev::MarkTargets::KEY]) && (by_mark.key? @change_bar_attr)
494
+ by_mark[@change_bar_attr]
495
+ else
496
+ raw.keys.select {|k| ::Integer === k }.sort.map {|k| raw[k] }
497
+ end
498
+ return :all if tokens.empty?
489
499
  targets = ::Set.new
490
- positional_keys.each do |key|
491
- token = raw[key].to_s
500
+ tokens.each do |token|
501
+ token = token.to_s
492
502
  if (m = /\A(\d+)-(\d+)\z/.match token)
493
503
  (m[1].to_i..m[2].to_i).each {|i| targets << i }
494
504
  elsif /\A\d+\z/.match? token
@@ -0,0 +1,57 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Asciidoctor
4
+ module Rhrev
5
+ # Records which positional list-item targets belong to which rhrev mark,
6
+ # one block attribute line at a time.
7
+ #
8
+ # Stacked attribute lines merge into one attribute hash, and Asciidoctor
9
+ # numbers positional entries per line, so a later line's positional
10
+ # entries overwrite an earlier line's at the same index:
11
+ #
12
+ # [rhrev1-2="old",2]
13
+ # [rhrev1-3="new"]
14
+ #
15
+ # leaves {"rhrev1-2"=>"old", 2=>"2", "rhrev1-3"=>"new"}, and the merged
16
+ # hash no longer says whether target 2 belongs to rhrev1-2 or rhrev1-3.
17
+ # Each line is still parsed on its own, through AttributeList#parse_into,
18
+ # whose per-line result is memoized, so reading it here costs no second
19
+ # parse. Every positional entry on a line belongs to the nearest mark
20
+ # before it on that same line; a mark with no positional entry after it
21
+ # targets the whole list.
22
+ #
23
+ # The record is stored on the block's own attribute hash under KEY, as a
24
+ # Hash of mark name => Array of raw target tokens. KEY never starts with
25
+ # an attribute name character, so it collides with no AsciiDoc attribute
26
+ # and is never mistaken for an rhrev mark by any prefix scan.
27
+ module MarkTargets
28
+ KEY = '@rhrev-mark-targets'
29
+
30
+ def self.record attributes, line, prefix
31
+ by_mark = current = nil
32
+ line.each do |key, value|
33
+ if ::String === key
34
+ next unless key.start_with? prefix
35
+ (by_mark ||= (attributes[KEY] ||= {}))[current = key] = []
36
+ elsif current && ::Integer === key
37
+ by_mark[current] << value
38
+ end
39
+ end
40
+ end
41
+
42
+ # Only a block attribute line passes the document itself as the block
43
+ # (Parser.parse_block_metadata_line, sub_result: true); every other
44
+ # caller, such as a block macro's attribute list, passes none.
45
+ module AttributeListHook
46
+ def parse_into attributes, positional_attrs = []
47
+ if ::Asciidoctor::Document === @block
48
+ MarkTargets.record attributes, (parse positional_attrs), (@block.attr 'revhistoryprefix', 'rhrev')
49
+ end
50
+ super
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end
56
+
57
+ ::Asciidoctor::AttributeList.prepend ::Asciidoctor::Rhrev::MarkTargets::AttributeListHook
@@ -7,6 +7,7 @@ require 'asciidoctor' unless defined? Asciidoctor
7
7
  require_relative 'rhrev/processors'
8
8
  require_relative 'rhrev/helpers'
9
9
  require_relative 'rhrev/cell_text_marks'
10
+ require_relative 'rhrev/mark_targets'
10
11
  require_relative 'rhrev/catalog'
11
12
 
12
13
  # Try to load the PDF converter support if asciidoctor-pdf is available
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: asciidoctor-rhrev
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.8.2
4
+ version: 1.8.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - 白一百 baiyibai
@@ -43,6 +43,7 @@ files:
43
43
  - lib/asciidoctor/rhrev/converter.rb
44
44
  - lib/asciidoctor/rhrev/exporter.rb
45
45
  - lib/asciidoctor/rhrev/helpers.rb
46
+ - lib/asciidoctor/rhrev/mark_targets.rb
46
47
  - lib/asciidoctor/rhrev/processors.rb
47
48
  - lib/asciidoctor/rhrev/renderer.rb
48
49
  - lib/asciidoctor/rhrev/rhrev_html.rb