asciidoctor-rhrev 1.3.0 → 1.4.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: cdb14bf628d2c8dd088c5f7f9a37012305efc17fd2c6f6717a4e6a08d3e9ac18
4
- data.tar.gz: b8bbabee8370433715fc06a11259fae8ac7eb80e7821965aa2b348fbcd185bcb
3
+ metadata.gz: f3babf6364c6012f042c82924f7d71c29636646744da52849b8d713638d09b8a
4
+ data.tar.gz: 206543f4a07a74b2c4ea3a589037a41605d87d6f066b201fb1280ab9436dd3ef
5
5
  SHA512:
6
- metadata.gz: a253125687474c408d3d89545d2c66d35f944a5330cb7e99213672bafcdcf199083a4528379b801a035726e0badd9ebd321101ebb27a9b2e3f3bd02e4a2be314
7
- data.tar.gz: 8f4e7888fdbf89ba4a70705b97eed4aa4a05bc5b19e0b5ab96bbd4b295db47757b4d73b724b84243c724098ab4578c844cc9ee3564df655d9831c3adb5021e48
6
+ metadata.gz: 05e9e9583c75900e39aec66ac1004990d49e2b3eb9facb797a72d931dd2747cff34a66c5bd79e3d69c7b120ca4267b43d20b9ca1d34d187e34c2c7dcdea15096
7
+ data.tar.gz: ec541680bb201d87151e66923e2c635b8d2b67efb48b46ea8e1789ab7d4cc178e9c0d681c1abcea2491f74f9345383575cabfe217a54151972c0d037212cc8a1
data/CHANGELOG.adoc CHANGED
@@ -1,5 +1,16 @@
1
1
  = Changelog
2
2
 
3
+ == 1.4.0 (2026-08-14)
4
+
5
+ * Add the `recursive` block option for PDF change bars: a section marked `[%recursive,rhrevN-M="..."]` draws one continuous bar over the whole section, nested child sections included, matching the HTML backend's whole-section extent. Without the option a marked section's bar still stops at its first child section. A child section marked in the current revision inside a recursive section draws its own bar, overlapping the parent's. The option affects sections only; other tracked blocks already receive a bar over their whole extent
6
+ * Note: this is a PDF-only release; the npm package skips 1.4.0
7
+
8
+ == 1.3.1 (2026-07-28)
9
+
10
+ * Fix silent content loss in long revision-history tables (PDF backend): the extent dry-run that reserves space for the table now runs after `prescan_document` populates each tracked node's real `title`/`sectnum`/`reftext`/`caption_number`, so a description cross-reference (`[.rhrevdescription]`) that forward-references its own target no longer measures a humanized-anchor placeholder in the dry-run and the resolved text in the final backfill. When the two lengths differed, the accumulated row heights could shift a row across a reserved page boundary and drop its content from the output; measurement and backfill now agree. The metadata pass is gated on nodes carrying their own `rhrevN-M` attribute, so it adds no full-document walk
11
+ * Fix the `rhrev-table-extra-blank-row` trailing blank row overflowing alone onto a continuation page (PDF backend): when the real entries nearly fill a page, the trailing blank row is now dropped rather than paginated to a page of its own. The check is scoped to the revision-history table's own last row and decided once per row, so no other table's pagination is affected and a multi-column blank row is never half-drawn
12
+ * Note: this is a PDF-only release; the npm package skips 1.3.1
13
+
3
14
  == 1.3.0 (2026-07-16)
4
15
 
5
16
  * Add HTML change bars: with `:rhrev-change-bars:` set, tracked blocks (section, floating title, example, listing, table, image) marked with the current revision get the `rhrev-changed` CSS class in the HTML backend and the Antora extension; `rhrev-change-bars-color`, `-width`, and `-offset` are emitted as CSS custom properties (`--rhrev-change-bar-*`). The side is always right in HTML (no recto/verso model), and a marked section's bar spans its nested subsections, unlike the PDF backend. Default styling (red right border) ships in the baiyibai UI bundle
@@ -66,10 +66,13 @@ module Asciidoctor
66
66
  # nested child sections/chapters: as soon as a child section begins
67
67
  # rendering, close out the bar of every still-open ancestor section
68
68
  # right here, at the boundary between the parent's own content and
69
- # its first child section.
69
+ # its first child section. A section carrying the recursive option
70
+ # keeps its bar open across child boundaries; convert_section closes
71
+ # it after the whole section, children included, has rendered.
70
72
  def enter_change_bar_section node
71
73
  return unless @change_bar_attr
72
74
  @change_bar_section_stack.each do |ancestor|
75
+ next if ancestor.option? 'recursive'
73
76
  next unless (start_pos = take_change_bar_start ancestor)
74
77
  ink_change_bar start_pos, { page: page_number, cursor: cursor }
75
78
  end
@@ -91,7 +91,9 @@ module Asciidoctor
91
91
  end
92
92
 
93
93
  # Entering a section closes out any still-open ancestor change bars,
94
- # so a marked section's bar never bleeds into its child sections
94
+ # so a marked section's bar never bleeds into its child sections.
95
+ # Ancestors carrying the recursive option are exempt; their bar is
96
+ # inked below, after super has rendered every nested child.
95
97
  enter_change_bar_section node
96
98
  result = super
97
99
  exit_change_bar_section node
@@ -279,6 +281,17 @@ module Asciidoctor
279
281
  end
280
282
  end
281
283
 
284
+ # True when the node carries its own rhrev* attribute in its raw (non-inherited)
285
+ # attribute set -- the same check collect_revision_entries makes, hoisted out so
286
+ # prescan_document can gate update_revision_entry_metadata on it.
287
+ def node_carries_own_rhrev? node
288
+ return false unless node.respond_to?(:attributes)
289
+ raw = (node.instance_variable_get(:@attributes) rescue nil)
290
+ return false if raw.nil? || raw.empty?
291
+ prefix = @revision_prefix || 'rhrev'
292
+ raw.keys.any? { |k| k.to_s.start_with?(prefix) }
293
+ end
294
+
282
295
  def update_revision_entry_metadata node
283
296
  return unless node.id
284
297
  return unless node.respond_to?(:attributes)
@@ -459,6 +472,13 @@ module Asciidoctor
459
472
  [:section, :floating_title, :example, :listing, :table, :image].each do |ctx|
460
473
  doc.find_by(context: ctx).each do |node|
461
474
  collect_revision_entries node
475
+ # Populate the *real* title/sectnum/reftext/caption_number now, from
476
+ # the parsed AST, so the extent dry-run measures the same content the
477
+ # deferred backfill will later ink. Gated on the node carrying its own
478
+ # rhrevN-M attribute: reusing node.attributes here (inherited config keys
479
+ # like rhrev-table-caption match the prefix) would turn this into a full
480
+ # per-node document walk.
481
+ update_revision_entry_metadata node if node_carries_own_rhrev? node
462
482
  end
463
483
  end
464
484
 
@@ -329,15 +329,24 @@ module Asciidoctor
329
329
 
330
330
  def create_revision_table_properly doc
331
331
  asciidoc_table = build_table_via_parsing doc
332
-
332
+
333
333
  disable_caption = doc.attr? 'rhrev-disable-caption'
334
334
  if disable_caption
335
335
  saved_caption = doc.attr 'table-caption'
336
336
  doc.set_attr 'table-caption', ''
337
337
  end
338
-
339
- convert_table asciidoc_table
340
-
338
+
339
+ # Scope the lonely-trailing-blank-row skip (PrawnTableDrawPatch) to just
340
+ # this table. Both the extent dry-run and the real ink flow through here,
341
+ # so the skip is applied identically in measurement and draw.
342
+ had_skip_flag = @_rhrev_skip_lonely_blank_row
343
+ @_rhrev_skip_lonely_blank_row = true if doc.attr? 'rhrev-table-extra-blank-row'
344
+ begin
345
+ convert_table asciidoc_table
346
+ ensure
347
+ @_rhrev_skip_lonely_blank_row = had_skip_flag
348
+ end
349
+
341
350
  if disable_caption
342
351
  if saved_caption
343
352
  doc.set_attr 'table-caption', saved_caption
@@ -5,3 +5,4 @@ require 'asciidoctor/pdf' unless defined? Asciidoctor::PDF
5
5
  require_relative 'converter'
6
6
  require_relative 'renderer'
7
7
  require_relative 'exporter'
8
+ require_relative 'table_draw_patch'
@@ -0,0 +1,107 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Scoped override of prawn-table's Table#draw.
4
+ #
5
+ # When the rhrev revision-history table is drawn with rhrev-table-extra-blank-row
6
+ # set, build_table_via_parsing appends a trailing blank (NBSP) row. prawn-table
7
+ # treats that row like any other: if the real entries nearly fill a page, the blank
8
+ # row alone overflows onto a fresh continuation page whose only content is the
9
+ # "(continued)" caption and an invisible row.
10
+ #
11
+ # This patch is INERT for every table except the rhrev revision-history one: draw
12
+ # returns super unless the converter has set @_rhrev_skip_lonely_blank_row on the
13
+ # document around that table's conversion. Only then do we reimplement the 0.2.2 draw
14
+ # loop (verified against prawn-table 0.2.2) with a single added rule: if the table's
15
+ # last row would land alone at the top of a fresh page, drop it instead of paginating
16
+ # to it. The decision is made once, from the row's first cell, and applied to every
17
+ # cell of the row -- prawn-table evaluates pagination per cell, so re-deciding per cell
18
+ # could ink one cell of the row and drop the other, leaving a half-drawn blank row.
19
+
20
+ begin
21
+ require 'prawn/table' unless defined? ::Prawn::Table
22
+ rescue LoadError
23
+ # prawn-table not present; nothing to patch
24
+ end
25
+
26
+ if defined? ::Prawn::Table
27
+ module Asciidoctor
28
+ module PDF
29
+ module Rhrev
30
+ module PrawnTableDrawPatch
31
+ def draw
32
+ unless @pdf.respond_to?(:instance_variable_get) &&
33
+ @pdf.instance_variable_get(:@_rhrev_skip_lonely_blank_row)
34
+ return super
35
+ end
36
+
37
+ # Defensive: only take the reimplemented path when the prawn-table
38
+ # internals we rely on are exactly the shape we reimplement against
39
+ # (0.2.2). On any drift, fall back to stock behavior.
40
+ internals = %i[initial_row_on_initial_page start_new_page?
41
+ ink_and_draw_cells_and_start_new_page set_background_color
42
+ ink_and_draw_cells header_rows with_position]
43
+ unless internals.all? { |m| respond_to?(m, true) } &&
44
+ @pdf.respond_to?(:reference_bounds)
45
+ return super
46
+ end
47
+
48
+ with_position do
49
+ ref_bounds = @pdf.reference_bounds
50
+ started_new_page_at_row = initial_row_on_initial_page
51
+ offset = @pdf.y
52
+ @header_row = header_rows if @header
53
+
54
+ cells_this_page = []
55
+ last_drawn_cell = nil
56
+
57
+ last_row_index = @cells.map(&:row).max
58
+ blank_row_decided = false
59
+ skip_blank_row = false
60
+
61
+ @cells.each do |cell|
62
+ if cell.row == last_row_index && rhrev_blank_cell?(cell)
63
+ # Decide once, from the first (column 0) cell of the last row, and
64
+ # apply the same answer to every cell of that row.
65
+ unless blank_row_decided
66
+ skip_blank_row = start_new_page?(cell, offset, ref_bounds)
67
+ blank_row_decided = true
68
+ end
69
+ next if skip_blank_row
70
+ end
71
+
72
+ if start_new_page?(cell, offset, ref_bounds)
73
+ cells_this_page, offset = ink_and_draw_cells_and_start_new_page(cells_this_page, cell)
74
+ started_new_page_at_row = cell.row
75
+ end
76
+
77
+ cell = set_background_color(cell, started_new_page_at_row)
78
+ cells_this_page << [cell, [cell.relative_x, cell.relative_y(offset)]]
79
+ last_drawn_cell = cell
80
+ end
81
+
82
+ ink_and_draw_cells(cells_this_page)
83
+
84
+ # @cells.last may now be a dropped blank cell; anchor the final cursor
85
+ # to the last cell we actually inked.
86
+ if last_drawn_cell
87
+ @pdf.move_cursor_to(last_drawn_cell.relative_y(offset) - last_drawn_cell.height)
88
+ end
89
+ end
90
+ end
91
+
92
+ # The trailing row appended for rhrev-table-extra-blank-row is a pair of
93
+ # non-breaking-space cells. Treat a last-row cell as blank when its content
94
+ # is empty once NBSP/whitespace is stripped; when the content can't be read,
95
+ # rely on the caller's flag + last-row guarantee and treat it as blank.
96
+ def rhrev_blank_cell? cell
97
+ content = (cell.content.to_s rescue nil)
98
+ return true if content.nil?
99
+ content.gsub(/[ \s]|&#160;|&nbsp;/, '').empty?
100
+ end
101
+ end
102
+
103
+ ::Prawn::Table.prepend PrawnTableDrawPatch
104
+ end
105
+ end
106
+ end
107
+ end
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.3.0
4
+ version: 1.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - 白一百 baiyibai
@@ -46,6 +46,7 @@ files:
46
46
  - lib/asciidoctor/rhrev/renderer.rb
47
47
  - lib/asciidoctor/rhrev/rhrev_html.rb
48
48
  - lib/asciidoctor/rhrev/rhrev_pdf.rb
49
+ - lib/asciidoctor/rhrev/table_draw_patch.rb
49
50
  homepage: https://gitlab.com/baiyibai/rhrev-asciidoctor-automatic-revision-history
50
51
  licenses:
51
52
  - CC0-1.0