Class: Przn::Renderer
- Inherits:
-
Object
- Object
- Przn::Renderer
- Defined in:
- lib/przn/renderer.rb
Direct Known Subclasses
Constant Summary collapse
- ANSI =
{ bold: "\e[1m", italic: "\e[3m", reverse: "\e[7m", strikethrough: "\e[9m", dim: "\e[2m", cyan: "\e[36m", gray_bg: "\e[48;5;236m", reset: "\e[0m" }.freeze
- DEFAULT_SCALE =
2- DEFAULT_IMAGE_RELATIVE_HEIGHT_PERCENT =
Default ‘relative_height` (as a percent of terminal height) applied to image blocks that don’t carry an explicit one. Caps how much of the screen a single image can occupy; the rest leaves predictable margin for the slide footer and avoids placement-clearing edge cases in some terminals when an image lands right against the bottom row.
70
Instance Method Summary collapse
-
#initialize(terminal, base_dir: '.', theme: nil, mode: :solo) ⇒ Renderer
constructor
‘mode:` controls whether `note` / `<note>` segments are rendered: :solo — dim-inline (today’s behavior), default for stand-alone runs.
-
#preload(slide) ⇒ Object
Warm caches for a slide we expect to navigate to soon.
- #render(slide, current:, total:, started_at: nil) ⇒ Object
Constructor Details
#initialize(terminal, base_dir: '.', theme: nil, mode: :solo) ⇒ Renderer
‘mode:` controls whether `note` / `<note>` segments are rendered:
:solo — dim-inline (today's behavior), default for stand-alone runs.
:audience — stripped from output; the projector view never shows notes.
:presenter — dim-inline (so the presenter sees them in context) and
ALSO aggregated separately for the side panel via
Slide#notes; this renderer just keeps the inline copy.
31 32 33 34 35 36 37 38 39 |
# File 'lib/przn/renderer.rb', line 31 def initialize(terminal, base_dir: '.', theme: nil, mode: :solo) @terminal = terminal @base_dir = base_dir @theme = theme || Theme.default @mode = mode @image_cache = {} @kitty_uploads = {} @mutex = Mutex.new end |
Instance Method Details
#preload(slide) ⇒ Object
Warm caches for a slide we expect to navigate to soon. Uploads any PNG images on the Kitty Graphics Protocol so the next render only needs a placement command. Safe to call from a background thread; serialized against ‘render` via the renderer’s mutex so terminal writes don’t interleave.
83 84 85 86 87 88 89 90 91 92 93 94 95 |
# File 'lib/przn/renderer.rb', line 83 def preload() return unless ImageUtil.kitty_terminal? @mutex.synchronize do .blocks.each do |block| next unless block[:type] == :image path = resolve_image_path(block[:path]) next unless File.exist?(path) && ImageUtil.png?(path) ensure_kitty_uploaded(path) end @terminal.flush end end |
#render(slide, current:, total:, started_at: nil) ⇒ Object
41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 |
# File 'lib/przn/renderer.rb', line 41 def render(, current:, total:, started_at: nil) @mutex.synchronize do @terminal.clear () w = @terminal.width h = @terminal.height row = if current == 0 content_height = calculate_height(.blocks, w) usable_height = h - 1 [(usable_height - content_height) / 2 + 1, 1].max else 2 end pending_align = nil .blocks.each do |block| if block[:type] == :align pending_align = block[:align] else row = render_block(block, w, row, align: pending_align) pending_align = nil end end if @theme.rabbit (h, w, current, total, started_at) else status = " #{current + 1} / #{total} " @terminal.move_to(h, w - status.size) @terminal.write "#{ANSI[:dim]}#{status}#{ANSI[:reset]}" end @terminal.flush end end |