webern 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/.document ADDED
@@ -0,0 +1,4 @@
1
+ lib/**/*.rb
2
+ -
3
+ CHANGELOG.md
4
+ LICENSE
data/.gitignore ADDED
@@ -0,0 +1,2 @@
1
+ *.ly
2
+ *.pdf
data/CHANGELOG.md ADDED
@@ -0,0 +1,3 @@
1
+ ### 0.2.0 : 04/22/10
2
+
3
+ * Reimplementation of code.
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ gem "spec"
4
+ gem "yard"
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2010 Michael Berkowitz
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,50 @@
1
+ # webern
2
+
3
+ ### current version: 0.2.0
4
+
5
+ [http://github.com/mikowitz/webern][webern]
6
+
7
+ ## Description
8
+
9
+ Taking a 12-tone row generated from user input Webern will create the full matrix based upon this
10
+ row, and then output all 48 possible rows created by that matrix to a .pdf file using the LilyPond notational
11
+ language.
12
+
13
+ ## Installation
14
+
15
+ Install the gemcutter gem
16
+
17
+ ~$ gem install gemcutter
18
+
19
+ Add gemcutter.org to your gem remote sources
20
+
21
+ ~$ gem tumble
22
+
23
+ Download and install this gem
24
+
25
+ ~$ gem install crayon
26
+
27
+ ## Requirements
28
+
29
+ No other gems are required, but you do need [LilyPond][lilypond] to generate the .pdf file.
30
+
31
+ ## Usage
32
+
33
+ `Webern` can accept a full 12-tone row, a partial 12-tone row, or a list of strings which will be parsed into a numeric row:
34
+
35
+ ~$ webern 9 1 4 7 8 2 0 10 5 6 11 3
36
+ ~$ webern 0 6 10 9 4 7
37
+ ~$ webern michael berkowitz
38
+
39
+ In the instance where a partial row is given, or the strings given do not provide 12 distinct letters, `Webern` will complete the row with the missing numbers in ascending order. In the example above, `Webern` would complete the row like this:
40
+
41
+ [0 6 10 9 4 7] #=> [0 6 10 9 4 7 1 2 3 5 8 11]
42
+
43
+ `Webern` will take the completed row and create the full 12-tone matrix, then generate a LilyPond file containing all 48 possible rows contained in the matrix, and output them to a .pdf file.
44
+
45
+ ## Copyright
46
+
47
+ Copyright (c) 2010 Michael Berkowitz. See LICENSE for details.
48
+
49
+ [webern]: http://github.com/mikowitz/webern "Webern repository"
50
+ [lilypond]: http://lilypond.org "LilyPond"
data/Rakefile ADDED
@@ -0,0 +1,85 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "webern"
8
+ gem.summary = %Q{Creates a .pdf reference sheet for all 12-tone rows generated from a given prime row's matrix.}
9
+ gem.description = %Q{Taking a 12-tone row generated from user input Webern will create the full matrix based upon this row, and then output all 48 possible rows created by that matrix to a .pdf file using the LilyPond notational language.}
10
+ gem.email = "michael.berkowitz@gmail.com"
11
+ gem.homepage = "http://github.com/mikowitz/webern"
12
+ gem.authors = ["Michael Berkowitz"]
13
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
14
+ end
15
+ Jeweler::GemcutterTasks.new
16
+ rescue LoadError
17
+ puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
18
+ end
19
+
20
+ require 'spec/rake/spectask'
21
+ Spec::Rake::SpecTask.new(:spec) do |spec|
22
+ spec.libs << "lib" << "spec"
23
+ spec.spec_opts = ["-cfs"]
24
+ spec.spec_files = FileList["spec/**/*_spec.rb"]
25
+ end
26
+
27
+ Spec::Rake::SpecTask.new(:rcov) do |spec|
28
+ spec.libs << "lib" << "spec"
29
+ spec.pattern = "spec/**/*_spec.rb"
30
+ spec.rcov = true
31
+ end
32
+
33
+ task :test => :check_dependencies
34
+
35
+ begin
36
+ require 'reek/adapters/rake_task'
37
+ Reek::RakeTask.new do |t|
38
+ t.fail_on_error = true
39
+ t.verbose = false
40
+ t.source_files = 'lib/**/*.rb'
41
+ end
42
+ rescue LoadError
43
+ task :reek do
44
+ abort "Reek is not available. In order to run reek, you must: sudo gem install reek"
45
+ end
46
+ end
47
+
48
+ begin
49
+ require 'roodi'
50
+ require 'roodi_task'
51
+ RoodiTask.new do |t|
52
+ t.verbose = false
53
+ end
54
+ rescue LoadError
55
+ task :roodi do
56
+ abort "Roodi is not available. In order to run roodi, you must: sudo gem install roodi"
57
+ end
58
+ end
59
+
60
+ task :default => :spec
61
+
62
+ begin
63
+ require 'yard'
64
+ YARD::Rake::YardocTask.new do |t|
65
+ t.options = %w{--no-private -mmarkdown}
66
+ end
67
+ rescue LoadError
68
+ task :yardoc do
69
+ abort "YARD is not available. In order to run yardoc, you must: sudo gem install yard"
70
+ end
71
+ end
72
+
73
+ begin
74
+ require 'hanna/rdoctask'
75
+ desc "generate hanna documentation"
76
+ Rake::RDocTask.new(:hanna) do |t|
77
+ t.rdoc_files.include("README.md", "License", "lib/**/*.rb")
78
+ t.main = "README.md"
79
+ t.rdoc_dir = "hanna"
80
+ end
81
+ rescue LoadError
82
+ task :hanna do
83
+ abort "hanna is not available. In order to run this task, you must: sudo gem install hanna"
84
+ end
85
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.2.0
data/bin/webern ADDED
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require File.dirname(__FILE__) + '/../lib/webern'
4
+ require 'optparse'
5
+
6
+ if ARGV.is_all_integers?
7
+ Webern.new(*ARGV.map(&:to_i))
8
+ else
9
+ Webern.new(*ARGV)
10
+ end
data/lib/core_ext.rb ADDED
@@ -0,0 +1,11 @@
1
+ class Array
2
+ def is_all_integers?
3
+ self.all?{|element| element.to_i.to_s == element }
4
+ rescue Exception
5
+ false
6
+ end
7
+
8
+ def generate_row_from_letters
9
+ self.map{|element| self.sort.index(element) }
10
+ end
11
+ end
@@ -0,0 +1,62 @@
1
+ module Webern
2
+ module LilypondBuilder
3
+ NOTES = %w{c cs d ef e f fs g af a bf b}
4
+
5
+ class << self
6
+ attr_writer :zero_note
7
+ end
8
+
9
+ def self.current_lilypond_version
10
+ `lilypond --version`.match(/\d+\.\d+\.\d+/)[0]
11
+ end
12
+
13
+ def self.zero_note
14
+ @zero_note ||= "c"
15
+ end
16
+
17
+ def self.convert_row(row)
18
+ row.map{|note| NOTES[(note + NOTES.index(self.zero_note)) % 12] }.join(" ")
19
+ end
20
+
21
+ def self.generate_file(matrix)
22
+ file = [PREAMBLE_BLOCK, "\n"]
23
+ file << STAFF_BLOCK
24
+ [:primes, :retrogrades, :inversions, :retrograde_inversions].each do |method|
25
+ abbrev = method.to_s.scan(/^\w|_\w/).join("").gsub(/_/, "").upcase
26
+ matrix.send(method).each do |row|
27
+ first = row[0]
28
+ row = self.convert_row(row)
29
+ row = row.sub(" ", "^\\markup{#{abbrev}#{first}} ")
30
+ file << " #{row}"
31
+ end
32
+ end
33
+ file << "\}" << "\n" << SCORE_BLOCK
34
+ File.open("matrix.ly", "w") do |f|
35
+ f << file.join("\n")
36
+ end
37
+ # TODO: This unless seems a bit messy
38
+ system("lilypond matrix.ly") unless $0 =~ /spec|rcov/
39
+ end
40
+
41
+ PREAMBLE_BLOCK = <<-STR
42
+ \\version \"#{self.current_lilypond_version}\"
43
+ \\include \"english.ly\"
44
+ #(set-global-staff-size 13)
45
+ STR
46
+
47
+ STAFF_BLOCK = <<-STR
48
+ rows = {
49
+ \\override Score.TimeSignature #'stencil = ##f
50
+ \\clef bass
51
+ \\time 12/4
52
+ STR
53
+
54
+ SCORE_BLOCK = <<-STR
55
+ \\score {
56
+ <<
57
+ \\new Staff \\rows
58
+ >>
59
+ }
60
+ STR
61
+ end
62
+ end
@@ -0,0 +1,26 @@
1
+ module Webern
2
+ class Matrix
3
+ attr_accessor :prime_row
4
+ BASIC_ROW = Array(0..11)
5
+
6
+ def initialize(row)
7
+ @prime_row = row
8
+ end
9
+
10
+ def primes
11
+ BASIC_ROW.map{|note| @prime_row.transpose(note) }
12
+ end
13
+
14
+ def inversions
15
+ BASIC_ROW.map{|note| @prime_row.transpose(note).inversion }
16
+ end
17
+
18
+ def retrogrades
19
+ BASIC_ROW.map{|note| @prime_row.transpose(note).retrograde }
20
+ end
21
+
22
+ def retrograde_inversions
23
+ BASIC_ROW.map{|note| @prime_row.transpose(note).retrograde_inversion }
24
+ end
25
+ end
26
+ end
data/lib/webern/row.rb ADDED
@@ -0,0 +1,53 @@
1
+ module Webern
2
+ class Row < Array
3
+ def initialize(*_row)
4
+ @row = _row
5
+ check_for_valid_row(@row)
6
+ @row = process_strings if @row.any?{|element| element.is_a?(String) }
7
+ @row = complete_row[0..11]
8
+ replace @row
9
+ end
10
+
11
+ def retrograde; Row.new *reverse; end
12
+
13
+ def inversion
14
+ Row.new *map{|note| (12 - note) % 12 }
15
+ end
16
+
17
+ def retrograde_inversion
18
+ Row.new *inversion.retrograde
19
+ end
20
+
21
+ def transpose(interval)
22
+ Row.new *map{|note| (note + interval) % 12 }
23
+ end
24
+
25
+ def complete_row
26
+ return @row if @row.size == 12
27
+ _remainder = Array(0..11) - @row
28
+ [@row, _remainder].flatten
29
+ end
30
+
31
+ def process_strings
32
+ full_string = @row.join("").split("")
33
+ _letters = full_string.uniq[0..11]
34
+ _letters.generate_row_from_letters
35
+ end
36
+
37
+ def check_for_valid_row(elements)
38
+ raise InvalidRow unless row_is_valid_numbers? or row_is_strings?
39
+ end
40
+
41
+ def row_is_valid_numbers?
42
+ @row.all?{|element| element.is_a?(Fixnum) } and (@row - Array(0..11)).empty?
43
+ end
44
+
45
+ def row_is_strings?
46
+ @row.all?{|element| element.is_a?(String) }
47
+ end
48
+
49
+ def zero_row
50
+ transpose(12-self[0])
51
+ end
52
+ end
53
+ end
data/lib/webern.rb ADDED
@@ -0,0 +1,19 @@
1
+ $:.unshift File.dirname(__FILE__)
2
+ $:.unshift File.dirname(__FILE__) + "/webern"
3
+
4
+ %w{ core_ext lilypond_builder matrix row }.each {|file| require file }
5
+
6
+ module Webern
7
+ class << self
8
+ attr_accessor :prime_row
9
+ end
10
+
11
+ def Webern.new(*row_elements)
12
+ @prime_row = Row.new(*row_elements).zero_row
13
+ @m = Matrix.new(@prime_row)
14
+ LilypondBuilder.generate_file(@m)
15
+ self
16
+ end
17
+
18
+ InvalidRow = Class.new(Exception)
19
+ end
@@ -0,0 +1,22 @@
1
+ describe "Array" do
2
+ describe "is_all_integers?" do
3
+ before do
4
+ @all_ints = %w{0 1 2 3 4 5 6 7 8 9 10 11}
5
+ @no_ints = %w{a b c d e f g h i j k}
6
+ @mixed = %w{a 1 b 2 c 3 d 4 5 6 7}
7
+ @bad_input = [{1 => 2}, [1,2,3], :"45"]
8
+ end
9
+ it "should return true when all elements are strings of integers" do
10
+ @all_ints.is_all_integers?.should be_true
11
+ end
12
+ it "should return false when no elements are strings of integers" do
13
+ @no_ints.is_all_integers?.should_not be_true
14
+ end
15
+ it "should return false when only some elements are strings of integers" do
16
+ @mixed.is_all_integers?.should_not be_true
17
+ end
18
+ it "should return false when some elements do not have a :to_i method" do
19
+ @bad_input.is_all_integers?.should_not be_true
20
+ end
21
+ end
22
+ end
data/spec/helper.rb ADDED
@@ -0,0 +1,5 @@
1
+ require 'spec'
2
+
3
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
4
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
5
+ require 'webern'
@@ -0,0 +1,40 @@
1
+ if system("lilypond --version")
2
+ describe "LilypondBuilder" do
3
+ it "should find the current lilypond version" do
4
+ Webern::LilypondBuilder.current_lilypond_version.should =~ /\d+\.\d+\.\d+/
5
+ end
6
+ it "should, by default, have 0 == c" do
7
+ Webern::LilypondBuilder.zero_note = "c"
8
+ end
9
+ describe "converting rows into lilypond" do
10
+ before { @row = Webern::Row.new(0,1,2,3,4,5,6,7,8,9,10,11) }
11
+ it "should be correctly converted by default to 'c cs d ef e f fs g af a bf b'" do
12
+ Webern::LilypondBuilder.convert_row(@row).should == "c cs d ef e f fs g af a bf b"
13
+ end
14
+ describe "when the zero_note is shifted" do
15
+ before { Webern::LilypondBuilder.zero_note = "d" }
16
+ it "should correct convert the chromatic scale to 'd ef e f fs g af a bf b c cs'" do
17
+ Webern::LilypondBuilder.convert_row(@row).should == "d ef e f fs g af a bf b c cs"
18
+ end
19
+ end
20
+ end
21
+ describe "generating lilypond file" do
22
+ before do
23
+ @row = Webern::Row.new(*Array(0..11))
24
+ @matrix = Webern::Matrix.new(@row)
25
+ @file_path = File.join(File.dirname(__FILE__), "..", "matrix.ly")
26
+ puts Webern::LilypondBuilder.generate_file(@matrix)
27
+ end
28
+ after do
29
+ File.delete(@file_path) if File.exists?(@file_path)
30
+ end
31
+ it "should create the file" do
32
+ File.exists?(@file_path).should be_true
33
+ end
34
+ end
35
+ end
36
+ else
37
+ describe "LilypondBuilder" do
38
+ it "needs Lilypond to be installed. Check out http://www.lilypond.org"
39
+ end
40
+ end
@@ -0,0 +1,22 @@
1
+ describe "Matrix" do
2
+ before { @m = Webern::Matrix.new(Webern::Row.new(0,1,2,3,4,5,6,7,8,9,10,11)) }
3
+ it "should have the correct prime row" do
4
+ @m.prime_row.should == Webern::Row.new(*Array(0..11))
5
+ end
6
+ it "should have the correct primes" do
7
+ @m.primes[0].should == @m.prime_row
8
+ @m.primes[3].should == @m.prime_row.transpose(3)
9
+ end
10
+ it "should have the correct inversions" do
11
+ @m.inversions[0].should == @m.prime_row.inversion
12
+ @m.inversions[6].should == @m.prime_row.inversion.transpose(6)
13
+ end
14
+ it "should have the correct retrogrades" do
15
+ @m.retrogrades[0].should == @m.prime_row.retrograde
16
+ @m.retrogrades[8].should == @m.prime_row.retrograde.transpose(8)
17
+ end
18
+ it "should have the correct retrograde inversions" do
19
+ @m.retrograde_inversions[0].should == @m.prime_row.retrograde_inversion
20
+ @m.retrograde_inversions[1].should == @m.prime_row.retrograde_inversion.transpose(11)
21
+ end
22
+ end
data/spec/row_spec.rb ADDED
@@ -0,0 +1,29 @@
1
+ describe "Row" do
2
+ describe "a basic row" do
3
+ before { @row = Webern::Row.new(*Array(0..11)) }
4
+ it "should create the correct retrograde: [11,10,9,8,7,6,5,4,3,2,1,0]" do
5
+ @row.retrograde.should == Array(0..11).reverse
6
+ end
7
+ it "should create the correct inversion: [0,11,10,9,8,7,6,5,4,3,2,1]" do
8
+ @row.inversion.should == [0,11,10,9,8,7,6,5,4,3,2,1]
9
+ end
10
+ it "should create the correct retrograde inversion: [1,2,3,4,5,6,7,8,9,10,11,0]" do
11
+ @row.retrograde_inversion.should == [1,2,3,4,5,6,7,8,9,10,11,0]
12
+ end
13
+ it "should transpose correctly" do
14
+ @row.transpose(2).should == [2,3,4,5,6,7,8,9,10,11,0,1]
15
+ end
16
+ end
17
+ describe "a more complex row" do
18
+ before { @row = Webern::Row.new(0,11,8,2,4,1,3,10,7,5,9,6) }
19
+ it "should create the correct retrograde: [6,9,5,7,10,3,1,4,2,8,11,0]" do
20
+ @row.retrograde.should == [6,9,5,7,10,3,1,4,2,8,11,0]
21
+ end
22
+ it "should create the correct inversion: [0,1,4,10,8,11,9,2,5,7,3,6]" do
23
+ @row.inversion.should == [0,1,4,10,8,11,9,2,5,7,3,6]
24
+ end
25
+ it "should create the correct retrograde inversion: [7,3,7,5,2,9,11,8,10,4,1,0]" do
26
+ @row.retrograde_inversion.should == [6,3,7,5,2,9,11,8,10,4,1,0]
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,55 @@
1
+ require 'helper'
2
+
3
+ def test_with_full_row(row, expected_result)
4
+ it "should return #{expected_result.inspect} for #{row.inspect}" do
5
+ Webern.new(*row).prime_row.should == expected_result
6
+ end
7
+ end
8
+
9
+ alias :test_with_incomplete_row :test_with_full_row
10
+ alias :test_with_complete_string :test_with_full_row
11
+ alias :test_with_incomplete_string :test_with_full_row
12
+
13
+ describe "Webern" do
14
+ describe "parsing complete rows" do
15
+ # beginning with 0
16
+ test_with_full_row(Array(0..11), Array(0..11))
17
+ test_with_full_row([0,11,10,9,8,7,6,5,4,3,2,1], [0,11,10,9,8,7,6,5,4,3,2,1])
18
+
19
+ # not beginning with 0
20
+ test_with_full_row([1,2,3,9,7,8,6,4,5,0,11,10], [0,1,2,8,6,7,5,3,4,11,10,9])
21
+ test_with_full_row(Array(0..11).reverse, [0,11,10,9,8,7,6,5,4,3,2,1])
22
+ end
23
+
24
+ describe "parsing incomplete rows" do
25
+ # beginning with 0
26
+ test_with_incomplete_row(Array(0..6), Array(0..11))
27
+ test_with_incomplete_row([0,11,10,9,8,7], [0,11,10,9,8,7,1,2,3,4,5,6])
28
+
29
+ # not beginning with 0
30
+ test_with_incomplete_row([1,2,3,9,7,8,6], [0,1,2,8,6,7,5,11,3,4,9,10])
31
+ test_with_incomplete_row([11,10,9,8,7,6], [0,11,10,9,8,7,1,2,3,4,5,6])
32
+ end
33
+
34
+ describe "parsing invalid rows" do
35
+ it "should raise an error for [1,2,3,4,5,6,7,8,9,10,11,12]" do
36
+ lambda { Webern.new(*Array(1..12)) }.should raise_error Webern::InvalidRow
37
+ end
38
+ it "should raise an error for [-1,0,1,2,3]" do
39
+ lambda { Webern.new(*Array(-1..3)) }.should raise_error Webern::InvalidRow
40
+ end
41
+ it "should raise an error for [0,1,2,3,4.5]" do
42
+ lambda { Webern.new(0,1,2,3,4.5) }.should raise_error Webern::InvalidRow
43
+ end
44
+ end
45
+
46
+ describe "parsing strings that provide a full row" do
47
+ test_with_complete_string(%w{a b c d e f g h i j k l}, Array(0..11))
48
+ test_with_complete_string(%w{michael rowe berkowitz}, [0,9,6,8,4,7,11,2,1,3,5,10])
49
+ end
50
+
51
+ describe "parsing strings that do not provide a full row" do
52
+ test_with_incomplete_string(%w{a b c d e f g}, Array(0..11))
53
+ test_with_incomplete_string(%w{michael rowe}, [0,10,7,9,6,8,11,2,1,3,4,5])
54
+ end
55
+ end
metadata ADDED
@@ -0,0 +1,87 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: webern
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 2
8
+ - 0
9
+ version: 0.2.0
10
+ platform: ruby
11
+ authors:
12
+ - Michael Berkowitz
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2010-04-22 00:00:00 -04:00
18
+ default_executable: webern
19
+ dependencies: []
20
+
21
+ description: Taking a 12-tone row generated from user input Webern will create the full matrix based upon this row, and then output all 48 possible rows created by that matrix to a .pdf file using the LilyPond notational language.
22
+ email: michael.berkowitz@gmail.com
23
+ executables:
24
+ - webern
25
+ extensions: []
26
+
27
+ extra_rdoc_files:
28
+ - LICENSE
29
+ - README.md
30
+ files:
31
+ - .document
32
+ - .gitignore
33
+ - CHANGELOG.md
34
+ - Gemfile
35
+ - LICENSE
36
+ - README.md
37
+ - Rakefile
38
+ - VERSION
39
+ - bin/webern
40
+ - lib/core_ext.rb
41
+ - lib/webern.rb
42
+ - lib/webern/lilypond_builder.rb
43
+ - lib/webern/matrix.rb
44
+ - lib/webern/row.rb
45
+ - spec/array_spec.rb
46
+ - spec/helper.rb
47
+ - spec/lilypond_builder_spec.rb
48
+ - spec/matrix_spec.rb
49
+ - spec/row_spec.rb
50
+ - spec/webern_spec.rb
51
+ has_rdoc: true
52
+ homepage: http://github.com/mikowitz/webern
53
+ licenses: []
54
+
55
+ post_install_message:
56
+ rdoc_options:
57
+ - --charset=UTF-8
58
+ require_paths:
59
+ - lib
60
+ required_ruby_version: !ruby/object:Gem::Requirement
61
+ requirements:
62
+ - - ">="
63
+ - !ruby/object:Gem::Version
64
+ segments:
65
+ - 0
66
+ version: "0"
67
+ required_rubygems_version: !ruby/object:Gem::Requirement
68
+ requirements:
69
+ - - ">="
70
+ - !ruby/object:Gem::Version
71
+ segments:
72
+ - 0
73
+ version: "0"
74
+ requirements: []
75
+
76
+ rubyforge_project:
77
+ rubygems_version: 1.3.6
78
+ signing_key:
79
+ specification_version: 3
80
+ summary: Creates a .pdf reference sheet for all 12-tone rows generated from a given prime row's matrix.
81
+ test_files:
82
+ - spec/array_spec.rb
83
+ - spec/helper.rb
84
+ - spec/lilypond_builder_spec.rb
85
+ - spec/matrix_spec.rb
86
+ - spec/row_spec.rb
87
+ - spec/webern_spec.rb