Class: HeadMusic::Notation::ABC::RepeatTagger

Inherits:
Object
  • Object
show all
Defined in:
lib/head_music/notation/abc/repeat_tagger.rb

Overview

Records repeat and volta structure on the composition’s bars.

ABC spells this structure on bar lines and volta brackets, but the composition carries it on the bars themselves, so the marks are applied as each bar is completed rather than as each token arrives.

Constant Summary collapse

REPEAT_ENDING_STYLES =

Bar styles that end a repeated section, terminating any volta.

[":|", "::"].freeze
REPEAT_STARTING_STYLES =
["|:", "::"].freeze
SECTION_ENDING_STYLES =
["||", "|]", "[|"].freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(composition) ⇒ RepeatTagger

Returns a new instance of RepeatTagger.



14
15
16
# File 'lib/head_music/notation/abc/repeat_tagger.rb', line 14

def initialize(composition)
  @composition = composition
end

Instance Attribute Details

#compositionObject (readonly, private)

Returns the value of attribute composition.



44
45
46
# File 'lib/head_music/notation/abc/repeat_tagger.rb', line 44

def composition
  @composition
end

Instance Method Details

#apply_repeat_flags(state, style) ⇒ Object (private)



46
47
48
49
50
51
52
53
54
# File 'lib/head_music/notation/abc/repeat_tagger.rb', line 46

def apply_repeat_flags(state, style)
  if REPEAT_ENDING_STYLES.include?(style)
    completed = state.completed_bar_number
    bar(completed).ends_repeat_after_num_plays = 2 if completed
  end
  return unless REPEAT_STARTING_STYLES.include?(style)

  bar(state.entered_bar_number).starts_repeat = true
end

#bar(bar_number) ⇒ Object (private)



63
64
65
# File 'lib/head_music/notation/abc/repeat_tagger.rb', line 63

def bar(bar_number)
  composition.bars(bar_number).last
end

#bar_line(state, style) ⇒ Object

A bar line closes the bar before it and may open or close a repeat.



19
20
21
22
23
# File 'lib/head_music/notation/abc/repeat_tagger.rb', line 19

def bar_line(state, style)
  tag_completed_bar(state)
  apply_repeat_flags(state, style)
  clear_passes_if_over(state, style)
end

#clear_passes_if_over(state, style) ⇒ Object (private)



56
57
58
59
60
61
# File 'lib/head_music/notation/abc/repeat_tagger.rb', line 56

def clear_passes_if_over(state, style)
  return unless REPEAT_ENDING_STYLES.include?(style) || SECTION_ENDING_STYLES.include?(style)

  state.active_passes = nil
  state.volta_start_bar = nil
end

#open_volta(state, passes) ⇒ Object



37
38
39
40
# File 'lib/head_music/notation/abc/repeat_tagger.rb', line 37

def open_volta(state, passes)
  state.active_passes = passes
  state.volta_start_bar = state.entered_bar_number
end

#tag_completed_bar(state) ⇒ Object

A volta covers every bar from its opening bracket through the bar line that ends it, so each completed bar in that span gets tagged.



27
28
29
30
31
32
33
34
35
# File 'lib/head_music/notation/abc/repeat_tagger.rb', line 27

def tag_completed_bar(state)
  passes = state.active_passes
  return unless passes

  completed = state.completed_bar_number
  return unless completed && completed >= state.volta_start_bar

  bar(completed).plays_on_passes = passes
end