Module: SongPro

Defined in:
lib/song_pro.rb,
lib/song_pro/version.rb

Constant Summary collapse

SECTION_REGEX =
/#\s*([^$]*)/
ATTRIBUTE_REGEX =
/@(\w*)=([^%]*)/
CUSTOM_ATTRIBUTE_REGEX =
/!(\w*)=([^%]*)/
CHORDS_AND_LYRICS_REGEX =
/(\[[\w#b\/]+\])?([\w\s',.!\(\)_\-"]*)/i
VERSION =
'0.1.2'.freeze

Class Method Summary collapse

Class Method Details

.parse(lines) ⇒ Object



15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# File 'lib/song_pro.rb', line 15

def self.parse(lines)
  song = Song.new
  current_section = nil

  lines.split("\n").each do |text|
    if text.start_with?('@')
      process_attribute(song, text)
    elsif text.start_with?('!')
      process_custom_attribute(song, text)
    elsif text.start_with?('#')
      current_section = process_section(song, text)
    else
      process_lyrics_and_chords(song, current_section, text)
    end
  end

  song
end

.process_attribute(song, text) ⇒ Object



43
44
45
46
47
48
49
50
51
52
53
# File 'lib/song_pro.rb', line 43

def self.process_attribute(song, text)
  matches = ATTRIBUTE_REGEX.match(text)
  key = matches[1]
  value = matches[2].strip

  if song.respond_to?("#{key}=".to_sym)
    song.send("#{key}=", value)
  else
    puts "WARNING: Unknown attribute '#{key}'"
  end
end

.process_custom_attribute(song, text) ⇒ Object



55
56
57
58
59
60
61
# File 'lib/song_pro.rb', line 55

def self.process_custom_attribute(song, text)
  matches = CUSTOM_ATTRIBUTE_REGEX.match(text)
  key = matches[1]
  value = matches[2].strip

  song.set_custom(key, value)
end

.process_lyrics_and_chords(song, current_section, text) ⇒ Object



64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
# File 'lib/song_pro.rb', line 64

def self.process_lyrics_and_chords(song, current_section, text)
  return if text == ''

  if current_section.nil?
    current_section = Section.new(name: '')
    song.sections << current_section
  end

  line = Line.new

  if text.start_with?('|')
    line.tablature = text
  else
    captures = text.scan(CHORDS_AND_LYRICS_REGEX).flatten

  captures.each_slice(2) do |pair|
    part = Part.new
    chord = pair[0]&.strip || ''
    part.chord = chord.delete('[').delete(']')
    part.lyric = pair[1]&.strip || ''

      line.parts << part unless (part.chord == '') && (part.lyric == '')
    end
  end

  current_section.lines << line
end

.process_section(song, text) ⇒ Object



34
35
36
37
38
39
40
41
# File 'lib/song_pro.rb', line 34

def self.process_section(song, text)
  matches = SECTION_REGEX.match(text)
  name = matches[1].strip
  current_section = Section.new(name: name)
  song.sections << current_section

  current_section
end