Module: Asciidoctor::PDF::Rhrev::ChangeBars
- Included in:
- Converter
- Defined in:
- lib/asciidoctor/rhrev/change_bars.rb
Overview
Inks a vertical change bar in the page margin next to blocks marked with the current revision (revnumber 1.2 => attribute rhrev1-2). Enabled by the rhrev-change-bars document attribute.
Styling comes from the PDF theme by default (rhrev_change_bars category: color, width, offset, side), overridable per document via the rhrev-change-bars-color/-width/-offset/-side attributes.
Instance Method Summary collapse
-
#arrange_block(node, &block) ⇒ Object
Examples and listings are arranged blocks: the extent yielded here is exact across page breaks.
- #change_bar?(node) ⇒ Boolean
-
#change_bar_settings ⇒ Object
Resolved lazily on first ink: the theme (and @media/@folio_placement) are not loaded yet when init_change_bars runs; upstream convert_document sets them up after rhrev's pre-super initialization.
-
#change_bar_x(pgnum, settings) ⇒ Object
The offset measures the gap between the text edge and the near edge of the bar.
- #init_change_bars(doc) ⇒ Object
-
#ink_change_bar(from, to) ⇒ Object
Paints the bar page by page; from/to are { page:, cursor: }.
- #ink_change_bar_for_extent(extent) ⇒ Object
- #ink_chapter_title(node, title, opts = {}) ⇒ Object
-
#ink_general_heading(node, title, opts = {}) ⇒ Object
The heading ink methods run after arrange_heading / start_new_chapter have settled the page, so this is the first accurate start position.
-
#ink_part_title(node, title, opts = {}) ⇒ Object
Upstream defines ink_part_title as an alias copy of ink_chapter_title, so it must be overridden separately.
- #record_change_bar_start(node) ⇒ Object
- #take_change_bar_start(node) ⇒ Object
Instance Method Details
#arrange_block(node, &block) ⇒ Object
Examples and listings are arranged blocks: the extent yielded here is exact across page breaks. Tables and images never reach this hook with their own node, so they are handled in the converter overrides instead.
108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 |
# File 'lib/asciidoctor/rhrev/change_bars.rb', line 108 def arrange_block node, &block if @change_bar_attr && !scratch? && (node.context == :example || node.context == :listing) && ( node) super node do |extent| if scratch? # measurement pass: upstream instance_execs this wrapper on the scratch # document, so re-bind the original block to it the same way instance_exec(&block) else block.call extent extent end end else super end end |
#change_bar?(node) ⇒ Boolean
51 52 53 54 |
# File 'lib/asciidoctor/rhrev/change_bars.rb', line 51 def node @change_bar_attr && node.respond_to?(:attributes) && node.attributes && (node.attributes.key? @change_bar_attr) end |
#change_bar_settings ⇒ Object
Resolved lazily on first ink: the theme (and @media/@folio_placement) are not loaded yet when init_change_bars runs; upstream convert_document sets them up after rhrev's pre-super initialization. Precedence: document attribute > theme key > built-in default.
36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
# File 'lib/asciidoctor/rhrev/change_bars.rb', line 36 def @change_bar_settings ||= begin overrides = @change_bar_overrides || {} theme = @theme side = overrides[:side] || theme&. || (@media == 'prepress' ? 'outer' : 'right') { color: (overrides[:color] || theme&. || 'FF0000').to_s.delete_prefix('#').upcase, width: (overrides[:width] || theme&. || 2).to_f, offset: (overrides[:offset] || theme&. || 16).to_f, side: side.to_s, } end end |
#change_bar_x(pgnum, settings) ⇒ Object
The offset measures the gap between the text edge and the near edge of the bar. Sides recto/verso are determined by the physical page number (honoring pdf-folio-placement inversion), matching prepress physical folio placement.
68 69 70 71 72 73 74 75 76 77 |
# File 'lib/asciidoctor/rhrev/change_bars.rb', line 68 def pgnum, settings case settings[:side] when 'right' on_right = true when 'outer', 'inner' recto = (page_side pgnum, @folio_placement && @folio_placement[:inverted]) == :recto on_right = settings[:side] == 'outer' ? recto : !recto end on_right ? bounds.right + settings[:offset] : bounds.left - settings[:offset] - settings[:width] end |
#init_change_bars(doc) ⇒ Object
14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
# File 'lib/asciidoctor/rhrev/change_bars.rb', line 14 def doc @change_bar_attr = nil @change_bar_settings = nil return unless doc.attr? 'rhrev-change-bars' # Without a revnumber there is no "current" revision to match return unless (revnumber = doc.attr 'revnumber') @change_bar_attr = %(#{@revision_prefix}#{revnumber.to_s.tr '.', '-'}) # Capture attribute values only; holding the Document in an ivar here # would leak it into the scratch prototype, which must stay marshalable @change_bar_overrides = { color: (doc.attr 'rhrev-change-bars-color'), width: (doc.attr 'rhrev-change-bars-width'), offset: (doc.attr 'rhrev-change-bars-offset'), side: (doc.attr 'rhrev-change-bars-side'), } @change_bar_starts = {} end |
#ink_change_bar(from, to) ⇒ Object
Paints the bar page by page; from/to are { page:, cursor: }. Called immediately after the block is rendered, so all spanned pages exist.
81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 |
# File 'lib/asciidoctor/rhrev/change_bars.rb', line 81 def from, to return if scratch? || from.nil? || to.nil? return if to[:page] < from[:page] return if to[:page] == from[:page] && to[:cursor] >= from[:cursor] settings = float do (from[:page]..to[:page]).each do |pgnum| go_to_page pgnum unless page_number == pgnum top = pgnum == from[:page] ? from[:cursor] : bounds.top bottom = pgnum == to[:page] ? to[:cursor] : 0 next if (height = top - bottom) <= 0 bounding_box [( pgnum, settings), top], width: settings[:width], height: height do fill_bounds settings[:color] end end end end |
#ink_change_bar_for_extent(extent) ⇒ Object
99 100 101 102 103 |
# File 'lib/asciidoctor/rhrev/change_bars.rb', line 99 def extent return unless extent ({ page: extent.from.page, cursor: extent.from.cursor }, { page: extent.to.page, cursor: extent.to.cursor }) end |
#ink_chapter_title(node, title, opts = {}) ⇒ Object
133 134 135 136 |
# File 'lib/asciidoctor/rhrev/change_bars.rb', line 133 def ink_chapter_title node, title, opts = {} node if @change_bar_attr && !scratch? && ( node) super end |
#ink_general_heading(node, title, opts = {}) ⇒ Object
The heading ink methods run after arrange_heading / start_new_chapter have settled the page, so this is the first accurate start position.
128 129 130 131 |
# File 'lib/asciidoctor/rhrev/change_bars.rb', line 128 def ink_general_heading node, title, opts = {} node if @change_bar_attr && !scratch? && ( node) super end |
#ink_part_title(node, title, opts = {}) ⇒ Object
Upstream defines ink_part_title as an alias copy of ink_chapter_title, so it must be overridden separately
140 141 142 143 |
# File 'lib/asciidoctor/rhrev/change_bars.rb', line 140 def ink_part_title node, title, opts = {} node if @change_bar_attr && !scratch? && ( node) super end |
#record_change_bar_start(node) ⇒ Object
56 57 58 |
# File 'lib/asciidoctor/rhrev/change_bars.rb', line 56 def node @change_bar_starts[node] = { page: page_number, cursor: cursor } end |
#take_change_bar_start(node) ⇒ Object
60 61 62 |
# File 'lib/asciidoctor/rhrev/change_bars.rb', line 60 def node @change_bar_starts&.delete node end |