webern 0.2.0 → 0.3.0

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.
data/.gitignore CHANGED
@@ -1,2 +1,20 @@
1
- *.ly
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
2
18
  *.pdf
19
+ *.ly
20
+ *.txt
data/Gemfile CHANGED
@@ -1,4 +1,4 @@
1
- source "http://rubygems.org"
1
+ source 'https://rubygems.org'
2
2
 
3
- gem "spec"
4
- gem "yard"
3
+ # Specify your gem's dependencies in webern.gemspec
4
+ gemspec
data/Guardfile ADDED
@@ -0,0 +1,8 @@
1
+ # A sample Guardfile
2
+ # More info at https://github.com/guard/guard#readme
3
+
4
+ guard 'rspec' do
5
+ watch(%r{^lib/(.+)\.rb$}) { "spec" }
6
+ watch(%r{^spec/(.+)\.rb$}) { "spec" }
7
+ watch('spec/spec_helper.rb') { "spec" }
8
+ end
data/README.md CHANGED
@@ -1,50 +1,51 @@
1
- # webern
1
+ # Webern
2
2
 
3
- ### current version: 0.2.0
3
+ Transforms user input into a complete 12-tone row and computes all 48 (at most) possible rows that result from the matrix of that row.
4
4
 
5
- [http://github.com/mikowitz/webern][webern]
5
+ Possible outputs:
6
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.
7
+ * text
8
+ * pdf
9
+ * lilypond
12
10
 
13
11
  ## Installation
14
12
 
15
- Install the gemcutter gem
16
-
17
- ~$ gem install gemcutter
13
+ Add this line to your application's Gemfile:
18
14
 
19
- Add gemcutter.org to your gem remote sources
15
+ gem 'webern'
20
16
 
21
- ~$ gem tumble
17
+ And then execute:
22
18
 
23
- Download and install this gem
19
+ $ bundle
24
20
 
25
- ~$ gem install crayon
21
+ Or install it yourself as:
26
22
 
27
- ## Requirements
28
-
29
- No other gems are required, but you do need [LilyPond][lilypond] to generate the .pdf file.
23
+ $ gem install webern
30
24
 
31
25
  ## Usage
32
26
 
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:
27
+ Create a row of the numbers 0 - 11
28
+
29
+ row = Webern::Row.new(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11)
34
30
 
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
31
+ You do not need to provide a full row. `Webern` will fill out the missing
32
+ numbers by adding them in ascending order to the end of the provided row.
38
33
 
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:
34
+ row = Webern::Row.new(5, 4, 8, 7, 10, 11, 3, 2) #=> [5, 4, 8, 7, 10, 11, 3, 2, 0, 1, 6, 9]
40
35
 
41
- [0 6 10 9 4 7] #=> [0 6 10 9 4 7 1 2 3 5 8 11]
36
+ Then choose a format in which to output either the matrix (text or pdf) or all
37
+ possible rows resulting from that matrix (lilypond).
42
38
 
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.
39
+ Webern::Formatters.Text.new(row).print_to_file('filename.txt)
40
+ Webern::Formatters.Pdf.new(row).print_to_file('filename.pdf)
41
+ Webern::Formatters.Lilypond.new(row).print_to_file('filename.ly')
44
42
 
45
- ## Copyright
43
+ The `lilypond` executable is required in order to convert the resulting `filename.ly` file to PDF.
46
44
 
47
- Copyright (c) 2010 Michael Berkowitz. See LICENSE for details.
45
+ ## Contributing
48
46
 
49
- [webern]: http://github.com/mikowitz/webern "Webern repository"
50
- [lilypond]: http://lilypond.org "LilyPond"
47
+ 1. Fork it
48
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
49
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
50
+ 4. Push to the branch (`git push origin my-new-feature`)
51
+ 5. Create new Pull Request
data/Rakefile CHANGED
@@ -1,85 +1,6 @@
1
- require 'rubygems'
2
- require 'rake'
1
+ require "bundler/gem_tasks"
2
+ require 'rspec/core/rake_task'
3
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
4
+ RSpec::Core::RakeTask.new('spec')
19
5
 
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
6
+ task default: :spec
data/lib/webern.rb CHANGED
@@ -1,19 +1,5 @@
1
- $:.unshift File.dirname(__FILE__)
2
- $:.unshift File.dirname(__FILE__) + "/webern"
3
-
4
- %w{ core_ext lilypond_builder matrix row }.each {|file| require file }
1
+ require "webern/version"
2
+ Dir[File.dirname(__FILE__) + '/**/*.rb'].each {|file| require file}
5
3
 
6
4
  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
5
  end
@@ -0,0 +1,15 @@
1
+ module Webern
2
+ module Formatters
3
+ class Base
4
+ PITCH_CLASSES = %w{ C C# D Eb E F F# G Ab A Bb B }
5
+ def initialize(prime_row, show_pitch_classes=true)
6
+ @prime_row = prime_row
7
+ @show_pitch_classes = show_pitch_classes
8
+ end
9
+
10
+ def pitch_value(n)
11
+ @show_pitch_classes ? PITCH_CLASSES[n] : n.to_s
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,43 @@
1
+ module Webern
2
+ module Formatters
3
+ class Lilypond < Base
4
+ def write_to_file(filename)
5
+ File.open(filename, 'w') do |f|
6
+ f << LILYPOND_HEADER
7
+ f << "rows = {\n"
8
+ f << "\\time 12/4\n"
9
+ f << "\\override Staff.Stem #'transparent = ##t\n"
10
+ {p: :prime, i: :inversion, r: :retrograde, ri: :retrograde_inversion}.each do |key, transformation|
11
+ (0..11).each do |transposition|
12
+ f << "\\mark \"#{key}#{transposition}\" "
13
+ f << @prime_row.send(transformation).zero.transpose(transposition).map{|n| lilypond_pitch(n) }.join(' ') + "\n"
14
+ end
15
+ f << "\\bar \"||\"\n"
16
+ end
17
+ f << "}\n"
18
+ f << LILYPOND_SCORE_BLOCK
19
+ end
20
+ end
21
+
22
+ def lilypond_pitch(n)
23
+ %w{ c'' cs'' d'' ef'' e'' f' fs' g' af' a' bf' b' }[n]
24
+ end
25
+ end
26
+ end
27
+ end
28
+
29
+ LILYPOND_HEADER = <<-pond
30
+ \\version "2.16.2"
31
+ \\include "english.ly"
32
+
33
+ #(set-global-staff-size 13)
34
+
35
+ pond
36
+
37
+ LILYPOND_SCORE_BLOCK = <<-pond
38
+ \\score {
39
+ <<
40
+ \\new Staff \\rows
41
+ >>
42
+ }
43
+ pond
@@ -0,0 +1,18 @@
1
+ require 'prawn'
2
+
3
+ module Webern
4
+ module Formatters
5
+ class Pdf < Base
6
+ def write_to_file(filename)
7
+ data = @prime_row.inversion.map do |i|
8
+ @prime_row.transpose(i).map do |n|
9
+ pitch_value(n)
10
+ end
11
+ end
12
+ Prawn::Document.generate(filename) do |pdf|
13
+ pdf.table data, cell_style: { width: 42, height: 42, align: :center, padding: 10}
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,34 @@
1
+ module Webern
2
+ module Formatters
3
+ class Text < Base
4
+ def draw
5
+ output($stdout)
6
+ end
7
+
8
+
9
+ def write_to_file(filename)
10
+ File.open(filename, 'w') do |f|
11
+ output(f)
12
+ end
13
+ end
14
+
15
+ private
16
+
17
+ def output(target)
18
+ @prime_row.inversion.each do |i|
19
+ target << border_row
20
+ target << empty_row
21
+ target << @prime_row.transpose(i).map{|n| pitch_cell(n) }.join + "|\n"
22
+ target << empty_row
23
+ end
24
+ target << border_row
25
+ end
26
+
27
+ def border_row; ('|---------' * 12) + "|\n"; end
28
+ def empty_row; ('| ' * 12) + "|\n"; end
29
+ def pitch_cell(n)
30
+ '| %s ' % (pitch_value(n)).rjust(2)
31
+ end
32
+ end
33
+ end
34
+ end
data/lib/webern/row.rb CHANGED
@@ -1,53 +1,43 @@
1
1
  module Webern
2
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
3
+ def initialize(*row)
4
+ @row = row
5
+ replace complete_row
9
6
  end
10
7
 
11
- def retrograde; Row.new *reverse; end
12
-
13
- def inversion
14
- Row.new *map{|note| (12 - note) % 12 }
8
+ def zero!
9
+ replace zero
15
10
  end
16
11
 
17
- def retrograde_inversion
18
- Row.new *inversion.retrograde
12
+ def prime
13
+ Row.new *self
19
14
  end
20
15
 
21
- def transpose(interval)
22
- Row.new *map{|note| (note + interval) % 12 }
16
+ def inversion
17
+ Row.new *self.map{|i| (12 - i) % 12}
23
18
  end
24
19
 
25
- def complete_row
26
- return @row if @row.size == 12
27
- _remainder = Array(0..11) - @row
28
- [@row, _remainder].flatten
20
+ def retrograde
21
+ Row.new *self.reverse
29
22
  end
30
23
 
31
- def process_strings
32
- full_string = @row.join("").split("")
33
- _letters = full_string.uniq[0..11]
34
- _letters.generate_row_from_letters
24
+ def retrograde_inversion
25
+ Row.new *self.retrograde.inversion
35
26
  end
36
27
 
37
- def check_for_valid_row(elements)
38
- raise InvalidRow unless row_is_valid_numbers? or row_is_strings?
28
+ def transpose(distance)
29
+ Row.new *self.map{|i| (i + distance) % 12 }
39
30
  end
40
31
 
41
- def row_is_valid_numbers?
42
- @row.all?{|element| element.is_a?(Fixnum) } and (@row - Array(0..11)).empty?
32
+ def zero
33
+ Row.new *self.map{|i| (i + 12 - self[0]) % 12}
43
34
  end
44
35
 
45
- def row_is_strings?
46
- @row.all?{|element| element.is_a?(String) }
47
- end
36
+ private
48
37
 
49
- def zero_row
50
- transpose(12-self[0])
38
+ def complete_row
39
+ missing = Array(0..11) - @row
40
+ @row + missing
51
41
  end
52
42
  end
53
43
  end
@@ -0,0 +1,3 @@
1
+ module Webern
2
+ VERSION = "0.3.0"
3
+ end
@@ -0,0 +1,3 @@
1
+ require 'rubygems'
2
+ require 'bundler/setup'
3
+ require 'webern'
@@ -0,0 +1,73 @@
1
+ require 'spec_helper'
2
+
3
+ describe Webern::Row do
4
+ describe 'complete integer row' do
5
+ # Concerto for Nine Instruments, Op. 24
6
+ let(:row) { create_row(11, 10, 2, 3, 7, 6, 8, 4, 5, 0, 1, 9) }
7
+
8
+ describe '#zero' do
9
+ it 'should return the row normalized to start on 0' do
10
+ expect(row.zero).to eq [0, 11, 3, 4, 8, 7, 9, 5, 6, 1, 2, 10]
11
+ end
12
+ end
13
+
14
+ describe 'transformations' do
15
+ before { row.zero! }
16
+ it 'should invert correctly' do
17
+ expect(row.inversion).to eq [0, 1, 9, 8, 4, 5, 3, 7, 6, 11, 10, 2]
18
+ end
19
+
20
+ it 'should retrograde correctly' do
21
+ expect(row.retrograde).to eq [10, 2, 1, 6, 5, 9, 7, 8, 4, 3, 11, 0]
22
+ end
23
+
24
+ it 'should retrograde-inversion correctly' do
25
+ expect(row.retrograde_inversion).to eq [2, 10, 11, 6, 7, 3, 5, 4, 8, 9, 1, 0]
26
+ end
27
+
28
+ it 'should transpose correctly' do
29
+ expect(row.transpose(2)).to eq [2, 1, 5, 6, 10, 9, 11, 7, 8, 3, 4, 0]
30
+ end
31
+ end
32
+ end
33
+
34
+ describe 'incomplete integer row' do
35
+ # String Quartet, Op. 28
36
+ let(:row) { create_row(10, 9, 0, 11, 3, 4, 1, 2) } # actual ending: 6, 5, 8, 7
37
+
38
+ describe 'row completion' do
39
+ it 'should complete the row in ascending order of remaining pitches' do
40
+ expect(row).to eq [10, 9, 0, 11, 3, 4, 1, 2, 5, 6, 7, 8]
41
+ end
42
+ end
43
+
44
+ describe '#zero' do
45
+ it 'should return the row normalized to start on 0' do
46
+ expect(row.zero).to eq [0, 11, 2, 1, 5, 6, 3, 4, 7, 8, 9, 10]
47
+ end
48
+ end
49
+
50
+ describe 'transformations' do
51
+ before { row.zero! }
52
+ it 'should invert correctly' do
53
+ expect(row.inversion).to eq [0, 1, 10, 11, 7, 6, 9, 8, 5, 4, 3, 2]
54
+ end
55
+
56
+ it 'should retrograde correctly' do
57
+ expect(row.retrograde).to eq [10, 9, 8, 7, 4, 3 ,6, 5, 1, 2, 11, 0]
58
+ end
59
+
60
+ it 'should retrograde-inversion correctly' do
61
+ expect(row.retrograde_inversion).to eq [2, 3, 4, 5, 8, 9, 6, 7, 11, 10, 1, 0]
62
+ end
63
+
64
+ it 'should transpose correctly' do
65
+ expect(row.transpose(2)).to eq [2, 1, 4, 3, 7, 8, 5, 6, 9, 10, 11, 0]
66
+ end
67
+ end
68
+ end
69
+
70
+ def create_row(*args)
71
+ Webern::Row.new(*args)
72
+ end
73
+ end
data/spec/webern_spec.rb CHANGED
@@ -1,55 +1,10 @@
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])
1
+ require 'spec_helper'
2
+
3
+ describe Webern do
4
+ it 'should output correctly' do
5
+ row = Webern::Row.new(11, 10, 2, 3, 7, 6, 8, 4, 5, 0, 1, 9)
6
+ Webern::Formatters::Text.new(row, false).write_to_file('row.txt')
7
+ Webern::Formatters::Pdf.new(row).write_to_file('row.pdf')
8
+ Webern::Formatters::Lilypond.new(row).write_to_file('lilypond-row.ly')
54
9
  end
55
10
  end
data/webern.gemspec ADDED
@@ -0,0 +1,30 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'webern/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "webern"
8
+ spec.version = Webern::VERSION
9
+ spec.authors = ["Michael Berkowitz"]
10
+ spec.email = ["michael.berkowitz@gmail.com"]
11
+ spec.description = %q{Transforms user input into a complete 12-tone row and computes all 48 (at most) possible rows that result from the matrix of that row.}
12
+ spec.summary = %q{Calculates all 48 possible 12-tone rows from the given input}
13
+ spec.homepage = ""
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_dependency 'prawn'
22
+
23
+ spec.add_development_dependency "bundler", "~> 1.3"
24
+ spec.add_development_dependency "rake"
25
+ spec.add_development_dependency "rspec"
26
+ spec.add_development_dependency "guard"
27
+ spec.add_development_dependency "guard-rspec"
28
+ spec.add_development_dependency "terminal-notifier-guard"
29
+ spec.add_development_dependency "rb-fsevent"
30
+ end
metadata CHANGED
@@ -1,87 +1,195 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
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
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.3.0
5
+ prerelease:
10
6
  platform: ruby
11
- authors:
7
+ authors:
12
8
  - Michael Berkowitz
13
9
  autorequire:
14
10
  bindir: bin
15
11
  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
12
+ date: 2013-04-21 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: prawn
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: bundler
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ~>
36
+ - !ruby/object:Gem::Version
37
+ version: '1.3'
38
+ type: :development
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ~>
44
+ - !ruby/object:Gem::Version
45
+ version: '1.3'
46
+ - !ruby/object:Gem::Dependency
47
+ name: rake
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ - !ruby/object:Gem::Dependency
63
+ name: rspec
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ! '>='
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ type: :development
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ - !ruby/object:Gem::Dependency
79
+ name: guard
80
+ requirement: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ! '>='
84
+ - !ruby/object:Gem::Version
85
+ version: '0'
86
+ type: :development
87
+ prerelease: false
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ! '>='
92
+ - !ruby/object:Gem::Version
93
+ version: '0'
94
+ - !ruby/object:Gem::Dependency
95
+ name: guard-rspec
96
+ requirement: !ruby/object:Gem::Requirement
97
+ none: false
98
+ requirements:
99
+ - - ! '>='
100
+ - !ruby/object:Gem::Version
101
+ version: '0'
102
+ type: :development
103
+ prerelease: false
104
+ version_requirements: !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ! '>='
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
110
+ - !ruby/object:Gem::Dependency
111
+ name: terminal-notifier-guard
112
+ requirement: !ruby/object:Gem::Requirement
113
+ none: false
114
+ requirements:
115
+ - - ! '>='
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ none: false
122
+ requirements:
123
+ - - ! '>='
124
+ - !ruby/object:Gem::Version
125
+ version: '0'
126
+ - !ruby/object:Gem::Dependency
127
+ name: rb-fsevent
128
+ requirement: !ruby/object:Gem::Requirement
129
+ none: false
130
+ requirements:
131
+ - - ! '>='
132
+ - !ruby/object:Gem::Version
133
+ version: '0'
134
+ type: :development
135
+ prerelease: false
136
+ version_requirements: !ruby/object:Gem::Requirement
137
+ none: false
138
+ requirements:
139
+ - - ! '>='
140
+ - !ruby/object:Gem::Version
141
+ version: '0'
142
+ description: Transforms user input into a complete 12-tone row and computes all 48
143
+ (at most) possible rows that result from the matrix of that row.
144
+ email:
145
+ - michael.berkowitz@gmail.com
146
+ executables: []
25
147
  extensions: []
26
-
27
- extra_rdoc_files:
28
- - LICENSE
29
- - README.md
30
- files:
31
- - .document
148
+ extra_rdoc_files: []
149
+ files:
32
150
  - .gitignore
33
- - CHANGELOG.md
34
151
  - Gemfile
35
- - LICENSE
152
+ - Guardfile
153
+ - LICENSE.txt
36
154
  - README.md
37
155
  - Rakefile
38
- - VERSION
39
- - bin/webern
40
- - lib/core_ext.rb
41
156
  - lib/webern.rb
42
- - lib/webern/lilypond_builder.rb
43
- - lib/webern/matrix.rb
157
+ - lib/webern/formatters/base.rb
158
+ - lib/webern/formatters/lilypond.rb
159
+ - lib/webern/formatters/pdf.rb
160
+ - lib/webern/formatters/text.rb
44
161
  - 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
162
+ - lib/webern/version.rb
163
+ - spec/spec_helper.rb
164
+ - spec/webern/row_spec.rb
50
165
  - spec/webern_spec.rb
51
- has_rdoc: true
52
- homepage: http://github.com/mikowitz/webern
53
- licenses: []
54
-
166
+ - webern.gemspec
167
+ homepage: ''
168
+ licenses:
169
+ - MIT
55
170
  post_install_message:
56
- rdoc_options:
57
- - --charset=UTF-8
58
- require_paths:
171
+ rdoc_options: []
172
+ require_paths:
59
173
  - 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"
174
+ required_ruby_version: !ruby/object:Gem::Requirement
175
+ none: false
176
+ requirements:
177
+ - - ! '>='
178
+ - !ruby/object:Gem::Version
179
+ version: '0'
180
+ required_rubygems_version: !ruby/object:Gem::Requirement
181
+ none: false
182
+ requirements:
183
+ - - ! '>='
184
+ - !ruby/object:Gem::Version
185
+ version: '0'
74
186
  requirements: []
75
-
76
187
  rubyforge_project:
77
- rubygems_version: 1.3.6
188
+ rubygems_version: 1.8.23
78
189
  signing_key:
79
190
  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
191
+ summary: Calculates all 48 possible 12-tone rows from the given input
192
+ test_files:
193
+ - spec/spec_helper.rb
194
+ - spec/webern/row_spec.rb
87
195
  - spec/webern_spec.rb
data/.document DELETED
@@ -1,4 +0,0 @@
1
- lib/**/*.rb
2
- -
3
- CHANGELOG.md
4
- LICENSE
data/CHANGELOG.md DELETED
@@ -1,3 +0,0 @@
1
- ### 0.2.0 : 04/22/10
2
-
3
- * Reimplementation of code.
data/LICENSE DELETED
@@ -1,20 +0,0 @@
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/VERSION DELETED
@@ -1 +0,0 @@
1
- 0.2.0
data/bin/webern DELETED
@@ -1,10 +0,0 @@
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 DELETED
@@ -1,11 +0,0 @@
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
@@ -1,62 +0,0 @@
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
data/lib/webern/matrix.rb DELETED
@@ -1,26 +0,0 @@
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/spec/array_spec.rb DELETED
@@ -1,22 +0,0 @@
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 DELETED
@@ -1,5 +0,0 @@
1
- require 'spec'
2
-
3
- $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
4
- $LOAD_PATH.unshift(File.dirname(__FILE__))
5
- require 'webern'
@@ -1,40 +0,0 @@
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
data/spec/matrix_spec.rb DELETED
@@ -1,22 +0,0 @@
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 DELETED
@@ -1,29 +0,0 @@
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