chords 0.4.1 → 0.4.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -108,24 +108,36 @@ module Chords
108
108
  tuning_part = fid.sub(fingering_part, '')
109
109
 
110
110
  fretboard = Fretboard.new_by_string(tuning_part, 50, formatter_class)
111
- over_tens = fingering_part.size - fretboard.open_notes.size
112
111
 
113
- i=0
114
- positions = []
112
+ max_fret_distance, positions = parse_positions(fingering_part,
113
+ fretboard.open_notes.size)
114
+
115
+ fretboard.formatter.print('', [Fingering.new(fretboard, positions)],
116
+ opts.merge(:max_fret_distance => max_fret_distance))
117
+ end
118
+
119
+ # parse positions from a string, for example '022100'
120
+ # returns [max_fret_distance, positions], where max_fret_distance has
121
+ # a minimum of 2
122
+ def self.parse_positions(position_str, no_of_strings)
123
+ position_str.downcase!
124
+ positions = position_str.scan(/./).map{|pos| pos == 'x' ? nil : pos.to_i}
125
+ over_tens = positions.size - no_of_strings
115
126
 
116
- while i < fingering_part.size
117
- fp = fingering_part[i,1]
118
- fp == 'x' ? pos = nil : pos = fp.to_i
119
- if over_tens > 0 and pos and pos < 4
120
- over_tens -= 1
121
- i += 2
122
- pos = "#{pos}#{fingering_part[i+1,1]}".to_i
123
- else
124
- i += 1
127
+ while over_tens > 0
128
+ idx = positions.index{|p| !p.nil? and p > 0 and p < 3}
129
+ if idx
130
+ positions[idx] = "#{positions[idx]}#{positions[idx+1]}".to_i
131
+ positions.delete_at(idx+1)
125
132
  end
126
- positions << pos
133
+ over_tens -= 1
127
134
  end
128
- fretboard.formatter.print('', [Fingering.new(fretboard, positions)], opts)
135
+ max_fret_distance = 2
136
+ tmp = positions.select{|pos| !pos.nil? and pos > 0}
137
+ max_fret_distance = tmp.max - tmp.min unless tmp.empty?
138
+ max_fret_distance = 2 if max_fret_distance < 2
139
+
140
+ [max_fret_distance, positions]
129
141
  end
130
142
 
131
143
  end
@@ -1,7 +1,4 @@
1
- require 'rvg/rvg' # rmagick's RVG (Ruby Vector Graphics)
2
- require 'base64'
3
-
4
- Magick::RVG::dpi = 72
1
+ require 'chords/png_formatter'
5
2
 
6
3
  module Chords
7
4
 
@@ -16,15 +13,15 @@ module Chords
16
13
  def initialize(fretboard, cache=NonCache.new)
17
14
  @fretboard = fretboard
18
15
  @cache = cache
16
+ @png_formatter = PNGFormatter.new(@fretboard)
19
17
  end
20
18
 
21
19
  # TODO: accept a separator element in opts
22
20
  def print(title, fingerings, opts={})
23
- @max_dist = opts[:max_fret_distance] || Fingering::DEFAULT_MAX_FRET_DISTANCE
24
21
  html = "<h2>#{title}</h2>\n"
25
22
 
26
23
  fingerings.each do |fingering|
27
- html += get_element(fingering)
24
+ html += get_element(fingering, opts)
28
25
  end
29
26
 
30
27
  if opts[:inline]
@@ -39,46 +36,10 @@ module Chords
39
36
 
40
37
  private
41
38
 
42
- def get_element(fingering)
43
-
39
+ def get_element(fingering, opts)
44
40
  @cache.fetch(fingering.fid) do
45
- rvg = Magick::RVG.new(5.cm, 5.cm).viewbox(0,0,270,250) do |canvas|
46
- canvas.background_fill = 'white'
47
- x_div = @fretboard.open_notes.size - 1
48
-
49
- y_diff = 215 / (@max_dist + 1)
50
-
51
- (@max_dist+2).times do |n|
52
- canvas.line(20, n*y_diff+20, 250, n*y_diff+20)
53
- end
54
-
55
- @fretboard.open_notes.each_with_index do |note, i|
56
- canvas.line(i*(230/x_div)+20, 20, i*(230/x_div)+20, 230)
57
-
58
- unless [0,nil].include?(fingering[i])
59
- canvas.circle(15, i*(230/x_div)+20,
60
- fingering.relative(@max_dist)[i]*y_diff - 5)
61
- end
62
-
63
- canvas.text(i*(230/x_div)+20, 15) do |txt|
64
- txt.tspan((fingering[i] || 'x').to_s).styles(
65
- :text_anchor => 'middle',
66
- :font_size => 20,
67
- :font_family => 'helvetica',
68
- :fill => 'black')
69
- end
70
- canvas.text(i*(230/x_div)+20, 249) do |txt|
71
- txt.tspan(note.title).styles(:text_anchor => 'middle',
72
- :font_size => 18,
73
- :font_family => 'helvetica',
74
- :fill => 'black')
75
- end
76
- end
77
-
78
- end
79
- img = rvg.draw
80
- img.format = 'PNG'
81
- "<img src=\"data:image/png;base64,#{Base64.encode64(img.to_blob)}\" />\n"
41
+ png_data = @png_formatter.print(nil, [fingering], opts)
42
+ "<img src=\"data:image/png;base64,#{Base64.encode64(png_data)}\" />\n"
82
43
  end
83
44
  end
84
45
 
@@ -0,0 +1,68 @@
1
+ require 'rvg/rvg' # rmagick's RVG (Ruby Vector Graphics)
2
+
3
+ Magick::RVG::dpi = 72
4
+
5
+ module Chords
6
+
7
+ # Formats a single fingering as png data
8
+ class PNGFormatter
9
+
10
+ def initialize(fretboard)
11
+ @fretboard = fretboard
12
+ end
13
+
14
+ def print(title, fingerings, opts={})
15
+ # title omitted
16
+ raise "Please provide only one fingering" if fingerings.size != 1
17
+
18
+ @max_dist = opts[:max_fret_distance] || Fingering::DEFAULT_MAX_FRET_DISTANCE
19
+
20
+ get_png_data(fingerings.first)
21
+ end
22
+
23
+ private
24
+
25
+ def get_png_data(fingering)
26
+ rvg = Magick::RVG.new(5.cm, 5.cm).viewbox(0,0,270,250) do |canvas|
27
+ canvas.background_fill = 'white'
28
+ x_div = @fretboard.open_notes.size - 1
29
+
30
+ y_diff = 215 / (@max_dist + 1)
31
+
32
+ (@max_dist+2).times do |n|
33
+ canvas.line(20, n*y_diff+20, 250, n*y_diff+20)
34
+ end
35
+
36
+ @fretboard.open_notes.each_with_index do |note, i|
37
+ canvas.line(i*(230/x_div)+20, 20, i*(230/x_div)+20, 230)
38
+
39
+ unless [0,nil].include?(fingering[i])
40
+ canvas.circle(15, i*(230/x_div)+20,
41
+ fingering.relative(@max_dist)[i]*y_diff - 5)
42
+ end
43
+
44
+ canvas.text(i*(230/x_div)+20, 15) do |txt|
45
+ txt.tspan((fingering[i] || 'x').to_s).styles(
46
+ :text_anchor => 'middle',
47
+ :font_size => 20,
48
+ :font_family => 'helvetica',
49
+ :fill => 'black')
50
+ end
51
+ canvas.text(i*(230/x_div)+20, 249) do |txt|
52
+ txt.tspan(note.title).styles(:text_anchor => 'middle',
53
+ :font_size => 18,
54
+ :font_family => 'helvetica',
55
+ :fill => 'black')
56
+ end
57
+ end
58
+
59
+ end
60
+ img = rvg.draw
61
+ img.format = 'PNG'
62
+ img.to_blob
63
+ end
64
+ end
65
+
66
+ end
67
+
68
+ # TODO: change pdf and png formatter to be
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: chords
3
3
  version: !ruby/object:Gem::Version
4
- hash: 13
4
+ hash: 11
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
8
  - 4
9
- - 1
10
- version: 0.4.1
9
+ - 2
10
+ version: 0.4.2
11
11
  platform: ruby
12
12
  authors:
13
13
  - Antti Hakala
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2010-08-10 00:00:00 +03:00
18
+ date: 2010-08-11 00:00:00 +03:00
19
19
  default_executable:
20
20
  dependencies: []
21
21
 
@@ -39,6 +39,7 @@ files:
39
39
  - lib/chords/html_formatter.rb
40
40
  - lib/chords/note.rb
41
41
  - lib/chords/pdf_formatter.rb
42
+ - lib/chords/png_formatter.rb
42
43
  - lib/chords/text_formatter.rb
43
44
  - lib/chords.rb
44
45
  has_rdoc: true