Class: MPS::Presenter

Inherits:
Object
  • Object
show all
Defined in:
lib/mps/presenter.rb

Overview

Renders an elements hash to a string. Has no dependency on Thor; receives a colorize proc for terminal output.

Usage (in CLI):

p = Presenter.new(elements, color_fn: method(:set_color), resolver: resolver)
puts p.render_tree

Constant Summary collapse

TYPE_COLORS =
{
  "task"     => :green,
  "note"     => :cyan,
  "reminder" => :magenta,
  "log"      => :yellow
}.freeze
ANSI_CODES =
{
  green: "\e[32m", cyan: "\e[36m", magenta: "\e[35m",
  yellow: "\e[33m", white: "\e[37m", reset: "\e[0m"
}.freeze

Instance Method Summary collapse

Constructor Details

#initialize(elements_hash, color_fn: nil, resolver: nil, with_refs: false) ⇒ Presenter

Returns a new instance of Presenter.

Parameters:

  • elements_hash (Hash)

    ref => element, as returned by Store#parse_date

  • color_fn (Proc, nil) (defaults to: nil)

    set_color(text, color) — nil disables color

  • resolver (RefResolver, nil) (defaults to: nil)
  • with_refs (Boolean) (defaults to: false)

    prefix each line with human ref



27
28
29
30
31
32
# File 'lib/mps/presenter.rb', line 27

def initialize(elements_hash, color_fn: nil, resolver: nil, with_refs: false)
  @elements  = elements_hash
  @color_fn  = color_fn || method(:_ansi_color)
  @resolver  = resolver
  @with_refs = with_refs
end

Instance Method Details

#render_element(el, depth: 0) ⇒ Object

Renders a single element as a terminal line (no indentation).



70
71
72
73
# File 'lib/mps/presenter.rb', line 70

def render_element(el, depth: 0)
  indent = "  " * (depth + 1)
  "#{indent}#{_element_line(el)}"
end

#render_tag_tableObject

Returns a tag-frequency table as a string. elements_hash should already be filtered (MPS containers excluded).



77
78
79
80
81
82
83
84
85
86
87
# File 'lib/mps/presenter.rb', line 77

def render_tag_table
  counts = Hash.new(0)
  @elements.each_value do |el|
    next if el.is_a?(::MPS::Elements::MPS)
    el.tags.each { |t| counts[t] += 1 }
  end
  return _colorize("(no tags found)", :yellow) if counts.empty?
  counts.sort_by { |_, v| -v }
        .map { |tag, n| "  #{_colorize(tag, :white)} (#{n})" }
        .join("\n")
end

#render_treeObject

Renders elements as an indented tree. @mps containers shown as group headers. Returns the number of non-MPS elements printed, or just the rendered string if called for its side-effect-free return value.



37
38
39
40
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
# File 'lib/mps/presenter.rb', line 37

def render_tree
  sorted = @elements.sort_by { |k, _| k.split(".").map(&:to_i) }
  return ["", 0] if sorted.empty?

  root_segs = sorted.first.first.split(".").size
  lines = []
  shown = 0

  sorted.each do |ref_key, el|
    depth = ref_key.split(".").size - root_segs - 1
    next if depth < 0

    if el.is_a?(::MPS::Elements::MPS)
      prefix = "#{ref_key}."
      any_visible = @elements.any? { |k, v| k.start_with?(prefix) && !v.is_a?(::MPS::Elements::MPS) }
      next unless any_visible
      indent    = "  " * (depth + 1)
      human     = @resolver&.to_human(ref_key) || ref_key
      ref_col   = @with_refs ? "#{_colorize(human.ljust(12), :white)}  " : ""
      lines << "#{indent}#{ref_col}#{_colorize("[@mps]", :white)}"
    else
      indent    = "  " * (depth + 1)
      human     = @resolver&.to_human(ref_key) || ref_key
      ref_col   = @with_refs ? "#{_colorize(human.ljust(12), :white)}  " : ""
      lines << "#{indent}#{ref_col}#{_element_line(el)}"
      shown += 1
    end
  end

  [lines.join("\n"), shown]
end