lib/coltrane/renderers/text_renderer/representation_piano_note_set_drawer.rb
module Coltrane
module Renderers
module TextRenderer
class RepresentationPianoNoteSetDrawer < BaseDrawer
alias note_set model
PIANO_TEMPLATE = <<~ASCII
┌─┬─┬┬─┬─╥─┬─┬┬─┬┬─┬─╥─┬─┬┬─┬─╥─┬─┬┬─┬┬─┬─┐
│ │ ││ │ ║ │ ││ ││ │ ║ │ ││ │ ║ │ ││ ││ │ │
│ │X││X│ ║ │X││X││X│ ║ │X││X│ ║ │X││X││X│ │
│ │X││X│ ║ │X││X││X│ ║ │X││X│ ║ │X││X││X│ │
│ ┕╥┙┕╥┙ ║ ┕╥┙┕╥┙┕╥┙ ║ ┕╥┙┕╥┙ ║ ┕╥┙┕╥┙┕╥┙ │
│ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ │
│XX║XX║XX║XX║XX║XX║XX║XX║XX║XX║XX║XX║XX║XX│
└──╨──╨──╨──╨──╨──╨──╨──╨──╨──╨──╨──╨──╨──┘
ASCII
def render
PIANO_TEMPLATE.each_line.map.each_with_index do |l, ln|
case ln
when 2, 3 then replace_x(l, Representation::Piano.black_notes, 1, ln - 2)
when 6 then replace_x(l, Representation::Piano.white_notes, 2)
else l
end
end.join
end
private
def replace_x(line, notes, size, index = 0)
line.gsub('X' * size).with_index do |_match, i|
note = notes[i % notes.size]
next ' ' * size unless note_set.include?(note)
Paint[replacer(note)[size == 2 ? 0..2 : index], 'red']
end
end
def replacer(note)
case flavor
when :intervals then (note_set.root - note).name
when :marks then '◼ '
when :degrees then note_set.notes.degree(note).to_s.rjust(2, '0')
when :notes then note.pretty_name.to_s.ljust(2, " ")
end
end
end
end
end
end