chords 0.4.1 → 0.4.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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