fretboards 0.0.5 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2f74b94171d59d8205ea78288d485e0456c0cec05235384b1467031d55f8e16e
4
- data.tar.gz: 77b288c138152851fb1c9ec3b3d888f78ce9a1cd81b9361e2128031f74b03b6d
3
+ metadata.gz: 2709f5ecdfcb4e12f5befb04ed0e9a69d5538c2500f395ef8dff2617ace3d5d7
4
+ data.tar.gz: 493db44900e76c4a7f92c20aaeff8d5824faa39a31824e7ae6b30f24a0ed81a3
5
5
  SHA512:
6
- metadata.gz: 2b193399564a8ed351a954ee6198b493846cd89f3671da04fa84d992934b9f65fc767f3e0b0cab0a818f14c4eaf02accbcd1e317b1ac8c9cb82620677680f433
7
- data.tar.gz: a64774090babf06d96e2811f33600488a0d61739bc868645a3ef2a145aae18ce4145198c3e160cdb29b6c45bb210822db35abe700dd22611ae1015101b63de0c
6
+ metadata.gz: abf0ddda617a1d3ddba69a8a45eb48d7596552fa2b73a6a1f870516435bcb74ffc0ef2d0429cca8c57d1746b959d5bcb577c6eead32048bb9d621129cd79fcc8
7
+ data.tar.gz: 4057730a7f52ebb0ca18771036fb8bd4d2a623254857297d752c88d0e2e4f084b7c3c4f4e2a71773ad8815a2cb46abdb71f828e535848170f52d5dc50de3102a
@@ -2,12 +2,95 @@
2
2
 
3
3
  require "fretboards"
4
4
  require "fretboards/renderer/svg"
5
+ require "docopt"
5
6
 
6
- # TODO make something useful
7
- terse = ARGV
8
- # puts terse.inspect
7
+ doc = <<DOCOPT
8
+ Output a SVG fretboard.
9
9
 
10
- fb = Fretboards::Fretboard.new(:tuning => %w{g' c' e' a'})
11
- fb.terse(ARGV)
12
- renderer = Fretboards::Renderer::Svg.new()
13
- puts renderer.render(fb)
10
+ Usage:
11
+ #{__FILE__} [options] [<dots>...]
12
+ #{__FILE__} (--tuning=<tuning> | --guitar | --ukulele) [options] [<dots>...]
13
+ #{__FILE__} -h | --help
14
+ #{__FILE__} --version
15
+
16
+ Options:
17
+ --tuning=<tuning> Tuning of the instrument [default: g' c' e' a'].
18
+ --width=<width> Width of the fretboard [default: 108].
19
+ --height=<height> Height of the fretboard [default: 180].
20
+ --fret-count=<fret-count> Number of frets [default: 4].
21
+ --offset=<offset> Offset of the fretboard [default: 0].
22
+ --title=<title> Title of the fretboard [default: ].
23
+ -h --help Show this screen.
24
+ --version Show version.
25
+
26
+ Arguments:
27
+ <dots> Dots to be drawn on the fretboard. Defaults to 4 strings and ukulele tuning. Actual tuning pitches are only considered when passing the dot marks as pitches.
28
+
29
+ Dots are specified as a sequence of numbers, one per string, starting from 0. Use x for a muted string.
30
+
31
+ #{__FILE__} 0 2 1 2
32
+
33
+ You can also specify dots as pitches, a to g.
34
+
35
+ - Use `is` suffix for sharp, `es` for flat.
36
+ - Use `'` or `,` for octaves up or down. `c'` is middle C.
37
+
38
+ #{__FILE__} aes\\' d\\' f\\' b\\'
39
+
40
+ Draw guitar fretboard passing `--guitar` or `--guitar-7`:
41
+
42
+ #{__FILE__} --guitar x 3 2 0 1 0
43
+
44
+ Use `[` and `]` to indicate barres:
45
+
46
+ #{__FILE__} --guitar 1\\[ 3 3 2 1 1\\]
47
+
48
+ Mark a dot as root with `!`:
49
+
50
+ #{__FILE__} --guitar 3! 2 0 0 3 3
51
+
52
+ Annotate fingerings with `-`:
53
+
54
+ #{__FILE__} --guitar 3-2 2-1 0 0 3-3 3-4
55
+
56
+ To place multiple dots on the same string, use `/`:
57
+
58
+ #{__FILE__} --guitar 5/6 8/6 5/5 7/5 5/4 7/4 5/3 7/3 5/2 8/2 5/1 8/1
59
+
60
+ Report bugs at https://github.com/choan/fretboards/issues
61
+ DOCOPT
62
+
63
+ begin
64
+ arguments = Docopt::docopt(doc, version: ::Fretboards::VERSION)
65
+ rescue Docopt::Exit => e
66
+ puts e.message
67
+ exit
68
+ end
69
+
70
+ if arguments['--guitar']
71
+ arguments['--tuning'] = "e, a, d g b e'"
72
+ elsif arguments['--guitar-7']
73
+ arguments['--tuning'] = "b,, e, a, d g b e'"
74
+ elsif arguments['--ukulele']
75
+ arguments['--tuning'] = "g' c' e' a'"
76
+ end
77
+
78
+ terse = arguments['<dots>']
79
+ tuning = arguments['--tuning'].split(' ')
80
+ title = arguments['--title']
81
+ width = arguments['--width'].to_i
82
+ height = arguments['--height'].to_i
83
+ fret_count = arguments['--fret-count'].to_i
84
+
85
+ fb = Fretboards::Fretboard.new(:tuning => tuning)
86
+ fb.title = title unless title.empty?
87
+ fb.terse(terse)
88
+
89
+ if arguments['--offset']
90
+ fb.set_offset(arguments['--offset'].to_i)
91
+ end
92
+
93
+
94
+ renderer = Fretboards::Renderer::Svg.new(width: width, height: height, fret_count: fret_count)
95
+
96
+ puts renderer.render(fb)
data/fretboards.gemspec CHANGED
@@ -22,4 +22,5 @@ Gem::Specification.new do |s|
22
22
  # specify any dependencies here; for example:
23
23
  # s.add_development_dependency "rspec"
24
24
  s.add_runtime_dependency "builder"
25
+ s.add_runtime_dependency "docopt", "~> 0.6.0"
25
26
  end
@@ -75,12 +75,12 @@ module Fretboards
75
75
  @offset = n
76
76
  self
77
77
  end
78
-
78
+
79
79
  def set_label_offset(n)
80
80
  @label_offset = n
81
81
  self
82
82
  end
83
-
83
+
84
84
 
85
85
  def mark(s, f = nil, settings = {})
86
86
  if !s.is_a? Hash
@@ -196,15 +196,17 @@ module Fretboards
196
196
  if marks.empty?
197
197
  [1, size]
198
198
  else
199
- min = marks.inject { |sum, i| i[:fret] < sum[:fret] ? i : sum }[:fret]
199
+ min = marks.inject { |sum, i| (i[:fret] < sum[:fret]) ? i : sum }[:fret]
200
200
  max = marks.inject { |sum, i| i[:fret] > sum[:fret] ? i : sum }[:fret]
201
201
  if size >= max
202
202
  [1, size]
203
203
  else
204
- # puts "#{self.title} pasa por el segundo hilo"
205
- min = 1 if min == 0
206
- max = (min + size) if (size > (max - min) )
207
- [min + offset, max + offset]
204
+ if offset > 0
205
+ [ offset, offset + size - 1 ]
206
+ else
207
+ min = 1 if min == 0
208
+ [min, max]
209
+ end
208
210
  end
209
211
  end
210
212
  end
@@ -213,4 +215,4 @@ module Fretboards
213
215
 
214
216
 
215
217
  end
216
- end
218
+ end
@@ -10,7 +10,7 @@ module Fretboards
10
10
  @tuning = %w{ g' c' e' a' }
11
11
  @table = "default"
12
12
  end
13
-
13
+
14
14
  def set_tuning(a)
15
15
  @tuning = a
16
16
  end
@@ -20,14 +20,14 @@ module Fretboards
20
20
  @col << fb
21
21
  fb
22
22
  end
23
-
23
+
24
24
  def define(title, a, attrs = {})
25
25
  form_add(title, a, { :title => title }.merge(attrs))
26
26
  end
27
27
 
28
28
  def use(title)
29
29
  raise "#{title} form not available" unless @forms[title]
30
- @forms[title]
30
+ @forms[title]
31
31
  end
32
32
 
33
33
 
@@ -45,6 +45,9 @@ module Fretboards
45
45
  fb = Fretboard.new(:tuning => @tuning)
46
46
  fb.terse(dots, attrs)
47
47
  end
48
+ if attrs[:offset]
49
+ fb.set_offset(attrs[:offset])
50
+ end
48
51
  fb
49
52
  end
50
53
 
@@ -71,4 +74,4 @@ module Fretboards
71
74
 
72
75
  end
73
76
 
74
- end
77
+ end
@@ -4,7 +4,7 @@ require "fretboards/ext/hash"
4
4
  module Fretboards
5
5
  module Renderer
6
6
  class Svg < Base
7
-
7
+
8
8
  def initialize(opts = {})
9
9
  # TODO configuration should merge recursively
10
10
  @opts = {
@@ -48,7 +48,7 @@ module Fretboards
48
48
  :open_margin_bottom => 4,
49
49
  }.deep_merge(opts)
50
50
  end
51
-
51
+
52
52
  def render(fb)
53
53
  @fb = fb
54
54
  require "builder"
@@ -75,7 +75,7 @@ module Fretboards
75
75
  # @svg
76
76
  # xml
77
77
  end
78
-
78
+
79
79
  def landscape_attributes
80
80
  if @opts[:landscape]
81
81
  {
@@ -85,23 +85,23 @@ module Fretboards
85
85
  {}
86
86
  end
87
87
  end
88
-
88
+
89
89
  def string_attrs
90
90
  @opts[:string_attrs]
91
91
  end
92
-
92
+
93
93
  def fret_attrs
94
94
  @opts[:fret_attrs]
95
95
  end
96
-
96
+
97
97
  def nut_attrs
98
98
  @opts[:nut_attrs]
99
99
  end
100
-
100
+
101
101
  def string_spacing
102
102
  (@opts[:width] - @opts[:padding_left] - @opts[:padding_right]) / ((@fb.string_count - 1).to_f)
103
103
  end
104
-
104
+
105
105
  def draw_strings(svg)
106
106
  (0..@fb.string_count-1).each do |sn|
107
107
  # x = @opts[:padding_left] + sn * string_spacing(fb)
@@ -109,24 +109,24 @@ module Fretboards
109
109
  y1 = @opts[:padding_top]
110
110
  y2 = @opts[:height] - @opts[:padding_bottom]
111
111
  attrs = string_attrs.merge(:x1 => x, :x2 => x, :y1 => y1, :y2 => y2, :class => 'string')
112
- if (!@opts[:string_widths].empty?)
112
+ if (!@opts[:string_widths].empty?)
113
113
  attrs = attrs.merge({ :"stroke-width" => @opts[:string_widths][sn] })
114
114
  end
115
115
  svg.line(attrs)
116
116
  end
117
117
  end
118
-
118
+
119
119
  def draw_title(svg)
120
120
  # TODO calculate ideal gap
121
- gap = @opts[:title_attrs][:"font-size"]
121
+ gap = @opts[:title_attrs][:"font-size"]
122
122
  svg.text(@fb.title, { :x => @opts[:width] * 0.5 + ((@opts[:padding_left] - @opts[:padding_right])*0.5), :y => @opts[:padding_top] - gap, :class => 'title' }.merge(@opts[:title_attrs]))
123
123
  end
124
-
124
+
125
125
  def get_string_x(sn)
126
126
  sn = @fb.string_number_to_index(sn)
127
127
  @opts[:padding_left] + sn * string_spacing
128
128
  end
129
-
129
+
130
130
  def draw_frets(svg)
131
131
  fret_range = @fb.fret_range(@opts[:fret_count])
132
132
  total_frets = fret_range.last - fret_range.first + 1
@@ -141,7 +141,7 @@ module Fretboards
141
141
  draw_fret(svg, n+1)
142
142
  end
143
143
  end
144
-
144
+
145
145
  def draw_labels(svg)
146
146
  fret_range = @fb.fret_range(@opts[:fret_count])
147
147
  if fret_range.first > 1
@@ -151,7 +151,7 @@ module Fretboards
151
151
  svg.text(fret_range.first + @fb.label_offset, { :y => y, :x => x, :class => 'label' }.merge(@opts[:label_attrs]))
152
152
  end
153
153
  end
154
-
154
+
155
155
  def draw_fret(svg, n)
156
156
  y = get_fret_y(n)
157
157
  if @opts[:rectangular_frets]
@@ -160,14 +160,14 @@ module Fretboards
160
160
  svg.line(fret_attrs.merge(:x1 => @opts[:padding_left], :x2 => @opts[:width] - @opts[:padding_right], :y1 => y, :y2 => y, :class => 'fret'))
161
161
  end
162
162
  end
163
-
163
+
164
164
  def draw_nut(svg)
165
165
  y = @opts[:padding_top] - @opts[:nut_attrs][:"stroke-width"] * 0.5
166
166
  extra_first = 0 # @opts[:string_widths][0] * 0.5
167
167
  extra_last = 0 # @opts[:string_widths].last * 0.5
168
168
  svg.line(nut_attrs.merge(:x1 => @opts[:padding_left] - extra_first, :x2 => @opts[:width] - @opts[:padding_right] + extra_last, :y1 => y, :y2 => y, :class => 'nut'))
169
169
  end
170
-
170
+
171
171
  def get_fret_y(fret_number)
172
172
  fret_range = @fb.fret_range(@opts[:fret_count])
173
173
  avail = @opts[:height] - @opts[:padding_top] - @opts[:padding_bottom] - @opts[:string_ext_bottom]
@@ -184,7 +184,7 @@ module Fretboards
184
184
  end
185
185
  y
186
186
  end
187
-
187
+
188
188
  def get_first_fret_size(gaps, factor, avail)
189
189
  sum = 0
190
190
  (0..gaps-1).each do |t|
@@ -192,8 +192,8 @@ module Fretboards
192
192
  end
193
193
  avail.to_f/sum.to_f
194
194
  end
195
-
196
-
195
+
196
+
197
197
  def draw_marks(svg)
198
198
  @fb.marks.each do |m|
199
199
  if m[:fret] == 0
@@ -209,13 +209,13 @@ module Fretboards
209
209
  end
210
210
  end
211
211
  end
212
-
212
+
213
213
  def draw_blue_note_symbol(svg, x, y, m)
214
214
  svg.rect(:x => x - 4, :y => y - 4, :width => 8, :height => 8, :fill => "#000", :stroke => "", :transform => "rotate(-45 #{x} #{y})")
215
215
  # svg.circle(:cx => x, :cy => y, :r => 3, :fill => "blue")
216
216
  end
217
-
218
-
217
+
218
+
219
219
  def draw_dot(svg, x, y, m)
220
220
  cnames = %w[dot]
221
221
  cnames << "dot-#{m[:symbol]}" if m[:symbol]
@@ -223,7 +223,7 @@ module Fretboards
223
223
  attrs = attrs.merge(@opts[(m[:symbol].to_s + "_symbol_attrs").to_sym]) if (m[:symbol] && @opts[(m[:symbol].to_s + "_symbol_attrs").to_sym])
224
224
  svg.circle(attrs)
225
225
  end
226
-
226
+
227
227
  def get_dot_position(string, fret)
228
228
  fret_range = @fb.fret_range(@opts[:fret_count])
229
229
  diff = fret_range.first == 1 ? 0 : fret_range.first - 1
@@ -232,7 +232,7 @@ module Fretboards
232
232
  y = 0.5 * (get_fret_y(fret - 1) + get_fret_y(fret))
233
233
  [x, y]
234
234
  end
235
-
235
+
236
236
  def draw_in_dots(svg, name)
237
237
  # TODO allow rotating dot text on rotated fretboards
238
238
  sym = name.to_sym
@@ -250,7 +250,7 @@ module Fretboards
250
250
  end
251
251
  end
252
252
  end
253
-
253
+
254
254
  def draw_in_bottom(svg, name)
255
255
  # TODO allow rotating bottom text on rotated fretboards
256
256
  sym = name.to_sym
@@ -264,7 +264,7 @@ module Fretboards
264
264
  end
265
265
  end
266
266
  end
267
-
267
+
268
268
  def draw_open(svg, m)
269
269
  margin_bottom = @opts[:open_margin_bottom]
270
270
  y = @opts[:padding_top] - @opts[:open_attrs][:r] - @opts[:nut_attrs][:"stroke-width"] - margin_bottom
@@ -274,7 +274,7 @@ module Fretboards
274
274
  attrs = attrs.merge(@opts[symbol_attrs]) if (m[:symbol] && @opts[symbol_attrs])
275
275
  svg.circle(attrs)
276
276
  end
277
-
277
+
278
278
  def draw_mutes(svg)
279
279
  margin_bottom = @opts[:open_margin_bottom]
280
280
  cy = @opts[:padding_top] - @opts[:open_attrs][:r] - @opts[:nut_attrs][:"stroke-width"] - margin_bottom
@@ -286,7 +286,7 @@ module Fretboards
286
286
  # svg.text("x", { :x => cx, :y => cy })
287
287
  end
288
288
  end
289
-
289
+
290
290
  def draw_barres(svg)
291
291
  barre_attrs = @opts[:barre_attrs]
292
292
  @fb.barres.each do |b|
@@ -297,8 +297,8 @@ module Fretboards
297
297
  svg.rect({:y => y, :x => x, :width => w, :class => :barre}.merge(barre_attrs))
298
298
  end
299
299
  end
300
-
301
-
300
+
301
+
302
302
  end
303
303
  end
304
- end
304
+ end
@@ -1,3 +1,3 @@
1
1
  module Fretboards
2
- VERSION = "0.0.5"
2
+ VERSION = "0.2.0"
3
3
  end
@@ -1,11 +1,11 @@
1
1
  require 'test/unit'
2
+ $:<< File.dirname(__FILE__) + '/../lib'
2
3
  require 'fretboards'
3
-
4
4
  include Fretboards
5
5
 
6
6
  # TODO write useful tests
7
7
  class FretboardTest < Test::Unit::TestCase
8
-
8
+
9
9
  def test_string_count
10
10
  uke = Fretboard.new()
11
11
  assert_equal(4, uke.string_count)
@@ -13,71 +13,71 @@ class FretboardTest < Test::Unit::TestCase
13
13
  guit = Fretboard.new(:tuning => Fretboards::Tuning::GUITAR)
14
14
  assert_equal(6, guit.string_count)
15
15
  end
16
-
16
+
17
17
  def test_mark
18
18
  fb = Fretboard.new
19
19
  fb.mark :string => 1, :fret => 5
20
20
  assert_equal([{:string => 1, :fret => 5}], fb.marks)
21
21
  end
22
-
22
+
23
23
  def test_barre
24
24
  fb = Fretboard.new(:tuning => %w{ g' c' e' a' })
25
25
  fb.barre 1
26
26
  assert_equal([{:fret => 1, :from => 4, :to => 1 }], fb.barres)
27
27
  end
28
-
28
+
29
29
  def test_mute
30
30
  fb = Fretboard.new
31
31
  fb.mute(1)
32
32
  assert_equal([1], fb.mutes)
33
33
  end
34
-
34
+
35
35
  def test_open
36
36
  fb = Fretboard.new
37
37
  fb.open(1)
38
38
  assert_equal([{:string => 1, :fret => 0}], fb.marks)
39
39
  end
40
-
40
+
41
41
  def test_terse_full
42
42
  fb = Fretboard.new
43
43
  fb.terse %w{ 1/4-3(5) }
44
44
  assert_equal([{:string => 4, :finger => 3, :function => "5", :fret => 1}], fb.marks)
45
45
  end
46
-
46
+
47
47
  def test_terse_minimal
48
48
  fb = Fretboard.new
49
49
  fb.terse %w{ 1 }
50
50
  assert_equal([{ :string => 4, :fret => 1 } ], fb.marks)
51
51
  end
52
-
52
+
53
53
  def test_terse_barre
54
54
  fb = Fretboard.new
55
55
  fb.terse %w{ 3 1[ 1] 0 }
56
56
  assert_equal([{:fret => 1, :from => 3, :to => 2 }], fb.barres)
57
57
  end
58
-
58
+
59
59
  def test_terse_unfinished_barre
60
60
  fb = Fretboard.new
61
61
  fb.terse %w{ 3 1[ 1 1 }
62
62
  assert_equal([{:fret => 1, :from => 3, :to => 1 }], fb.barres)
63
63
  end
64
-
64
+
65
65
  def test_terse_symbols
66
66
  # puts "symbols"
67
67
  fb = Fretboard.new
68
68
  fb.terse %w{ 3! }
69
69
  assert_equal(:root, fb.marks.first[:symbol])
70
-
70
+
71
71
  fb = Fretboard.new
72
72
  fb.terse %w{ 3? }
73
73
  assert_equal(:phantom, fb.marks.first[:symbol])
74
-
74
+
75
75
  fb = Fretboard.new
76
76
  fb.terse %w{ 3!? }
77
77
  assert_equal(:phantom_root, fb.marks.first[:symbol])
78
-
78
+
79
79
  end
80
-
80
+
81
81
  def test_fret_range
82
82
  fb = Fretboard.new
83
83
  fb.terse %w{ 0 0 0 3 }
@@ -89,5 +89,12 @@ class FretboardTest < Test::Unit::TestCase
89
89
  fb.terse %w{ 7 6 5 9 }
90
90
  assert_equal([5, 9], fb.fret_range)
91
91
  end
92
-
93
- end
92
+
93
+ def test_fret_range_with_offset
94
+ fb = Fretboard.new
95
+ fb.terse %w{ 0 5 7 7 }
96
+ fb.set_offset 5
97
+ assert_equal([5, 8], fb.fret_range)
98
+ end
99
+
100
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fretboards
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.5
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Choan Galvez
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-07-18 00:00:00.000000000 Z
11
+ date: 2023-10-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: builder
@@ -24,6 +24,20 @@ dependencies:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: docopt
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: 0.6.0
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: 0.6.0
27
41
  description: Allows defining instrument fretboard structures and representing them
28
42
  as highly customizable SVG graphics.
29
43
  email:
@@ -57,7 +71,7 @@ homepage: ''
57
71
  licenses:
58
72
  - MIT
59
73
  metadata: {}
60
- post_install_message:
74
+ post_install_message:
61
75
  rdoc_options: []
62
76
  require_paths:
63
77
  - lib
@@ -72,8 +86,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
72
86
  - !ruby/object:Gem::Version
73
87
  version: '0'
74
88
  requirements: []
75
- rubygems_version: 3.0.4
76
- signing_key:
89
+ rubygems_version: 3.2.3
90
+ signing_key:
77
91
  specification_version: 4
78
92
  summary: Define and draw fretboards
79
93
  test_files: