kadryll 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
5
+ drills
6
+ .approvals
7
+ *.received.txt
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in kadryll.gemspec
4
+ gemspec
@@ -0,0 +1,33 @@
1
+ # Kadryll
2
+
3
+ Drill notation generator for drums, with particular relevance to independence drills.
4
+
5
+ ## Input
6
+
7
+ The drill generator takes a block of text on 5 lines.
8
+
9
+ The first line consists of the exercise name and the time signature, and the four subsequent lines define the drill for the right hand, left hand, right foot, and left foot respectively. E.g.
10
+
11
+ ex1 4/4
12
+ tt4 r4 tt4 r4
13
+ r4 tt4 r4 tt4
14
+ r1
15
+ r1
16
+
17
+ This will create a lilypond file named `ex1.ly`, and a score called `ex1.png`.
18
+
19
+ ## Configuration
20
+
21
+ You can configure the location of the input directory (where the `*.ly` files go -- default is `drills/data/`) and the output directory (where the `*.png` files go - default is `drills/scores/`).
22
+
23
+
24
+ Kadryll.configure do |c|
25
+ c.output_dir = 'my/images/'
26
+ c.input_dir = 'my/lilypond/files/'
27
+ end
28
+
29
+ In addition, you should set the copyright text which will be listed at the bottom of the score.
30
+
31
+ Kadryll.configure do |c|
32
+ c.copyright = 'Copyright 2012 - Chet'
33
+ end
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
data/TODO ADDED
@@ -0,0 +1 @@
1
+ [ ] executable to generate a collection of exercises from a file
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'rubygems'
4
+ require 'thor'
5
+ require "kadryll"
6
+ require "kadryll/cli"
7
+
8
+ Kadryll::CLI.start
@@ -0,0 +1,25 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+
4
+ Gem::Specification.new do |s|
5
+ s.name = "kadryll"
6
+ s.version = "0.0.1"
7
+ s.authors = ["Katrina Owen"]
8
+ s.email = ["katrina.owen@gmail.com"]
9
+ s.homepage = ""
10
+ s.summary = %q{Score generator for drum independence drills.}
11
+ s.description = %q{Score generator for drum independence drills.}
12
+
13
+ s.rubyforge_project = "kadryll"
14
+
15
+ s.files = `git ls-files`.split("\n")
16
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
17
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
18
+ s.require_paths = ["lib"]
19
+
20
+ # specify any dependencies here; for example:
21
+ s.add_development_dependency "rspec"
22
+ s.add_development_dependency "approvals"
23
+ s.add_development_dependency "timecop"
24
+ # s.add_runtime_dependency "rest-client"
25
+ end
@@ -0,0 +1,68 @@
1
+ require 'fileutils'
2
+ require 'singleton'
3
+ require 'date'
4
+ require 'kadryll/drill'
5
+ require 'kadryll/shorthand_reader'
6
+
7
+ module Kadryll
8
+ class << self
9
+
10
+ def initialize
11
+ FileUtils.mkdir_p(output_dir) unless File.exists?(output_dir)
12
+ FileUtils.mkdir_p(input_dir) unless File.exists?(input_dir)
13
+ end
14
+
15
+ def output_dir
16
+ config.output_dir
17
+ end
18
+
19
+ def input_dir
20
+ config.input_dir
21
+ end
22
+
23
+ def copyright
24
+ config.copyright
25
+ end
26
+
27
+ def configure(&block)
28
+ block.call Kadryll::Configuration.instance
29
+ end
30
+
31
+ def config
32
+ Kadryll::Configuration.instance
33
+ end
34
+ end
35
+
36
+ class Configuration
37
+ include Singleton
38
+
39
+ def output_dir=(dir = '')
40
+ @output_dir = sanitize(dir)
41
+ end
42
+
43
+ def output_dir
44
+ @output_dir ||= 'drills/scores/'
45
+ end
46
+
47
+ def input_dir=(dir = '')
48
+ @input_dir = sanitize(dir)
49
+ end
50
+
51
+ def input_dir
52
+ @input_dir ||= 'drills/data/'
53
+ end
54
+
55
+ def copyright
56
+ @copyright ||= "Copyright #{Date.today.year} YourName"
57
+ end
58
+
59
+ def copyright=(copyright)
60
+ @copyright = copyright
61
+ end
62
+
63
+ private
64
+ def sanitize(directory)
65
+ directory.nil? ? directory : directory.chomp('/') + '/'
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,21 @@
1
+ module Kadryll
2
+
3
+ class CLI < Thor
4
+
5
+ desc "generate", "Generate drills from a file with score shorthand"
6
+ method_option :input, :type => :string, :aliases => "-i", :required => true, :desc => "path to template file"
7
+ method_option :output, :type => :string, :default => './', :aliases => "-o", :desc => "path to output directory"
8
+ method_option :prefix, :type => :string, :default => nil, :aliases => "-p", :desc => "file prefix for the .png output"
9
+ def generate
10
+ Kadryll.configure do |c|
11
+ c.output_dir = options[:output]
12
+ end
13
+ exercises = Kadryll::ShorthandReader.read(options[:input])
14
+ exercises.each do |exercise|
15
+ drill = Kadryll::Drill.from_string(exercise, :prefix => options[:prefix])
16
+ drill.generate_png
17
+ end
18
+ end
19
+ end
20
+ end
21
+
@@ -0,0 +1,135 @@
1
+ module Kadryll
2
+ class Drill
3
+
4
+ class << self
5
+ def lilypond_file(name)
6
+ "#{Kadryll.input_dir}#{name}.ly"
7
+ end
8
+
9
+ def from_string(template, options = {})
10
+ drill = parse template, options
11
+ drill.write
12
+ drill
13
+ end
14
+
15
+ def parse(template, options = {})
16
+ data, *measures = template.split("\n").map(&:strip)
17
+ name, time = data.split(" ")
18
+ new(name, time, measures, options)
19
+ end
20
+ end
21
+
22
+ attr_accessor :name, :time, :right_hand, :left_hand, :right_foot, :left_foot
23
+ def initialize(name, time, measures, options = {})
24
+ self.name = build_name(name, options[:prefix])
25
+ self.time = time
26
+ self.right_hand, self.left_hand, self.right_foot, self.left_foot = measures
27
+ end
28
+
29
+ def command
30
+ "lilypond --png --output=#{output_to} #{lilypond_file}"
31
+ end
32
+
33
+ def generate_png
34
+ system(command)
35
+ "#{output_to}.png"
36
+ end
37
+
38
+ def output_to
39
+ "#{Kadryll.output_dir}#{name}"
40
+ end
41
+
42
+ def write
43
+ Kadryll.initialize
44
+ File.open(lilypond_file, 'w') do |file|
45
+ file.write template
46
+ end
47
+ end
48
+
49
+ def lilypond_file
50
+ Drill.lilypond_file(name)
51
+ end
52
+
53
+ def template
54
+ <<-DRILL.gsub(/^\ {6}/, '')
55
+ \\version "2.14.2"
56
+
57
+ \\header {
58
+ tagline = \\markup {
59
+ \\fill-line {
60
+ \\line { \\null }
61
+ \\line { \\null }
62
+ \\line { \\tiny \\with-color #(x11-color 'gray80) { #{Kadryll.copyright} \\char ##x00A9 } }
63
+
64
+ }
65
+ }
66
+ }
67
+
68
+ #(set! paper-alist (cons '("drill" . (cons (* 190 mm) (* 80 mm))) paper-alist))
69
+ \\paper {
70
+ #(set-paper-size "drill")
71
+ #(define top-margin (* 7 mm))
72
+ #(define line-width (* 140 mm))
73
+ }
74
+
75
+ signature = \\time #{time}
76
+
77
+ rh = \\drummode { #{right_hand} }
78
+ lh = \\drummode { #{left_hand} }
79
+ rf = \\drummode { #{right_foot} }
80
+ lf = \\drummode { #{left_foot} }
81
+
82
+ #(define quake '((tamtam default #t 0)))
83
+ quakestaff = {
84
+ \\override DrumStaff.StaffSymbol #'line-positions = #'( 0 )
85
+ \\override DrumStaff.BarLine #'bar-extent = #'(-1 . 1.5)
86
+ \\override DrumStaff.InstrumentName #'self-alignment-X = #LEFT
87
+ \\set DrumStaff.drumStyleTable = #(alist->hash-table quake)
88
+ \\set fontSize = #-2
89
+ \\signature
90
+ \\override DrumStaff.Rest #'staff-position = #0
91
+ }
92
+
93
+ <<
94
+ \\new DrumStaff {
95
+ \\quakestaff
96
+ \\set DrumStaff.instrumentName = "Right Hand "
97
+ \\override Stem #'direction = #UP
98
+ \\rh | \\rh | \\rh | \\rh |
99
+ }
100
+ \\new DrumStaff {
101
+ \\quakestaff
102
+ \\set DrumStaff.instrumentName = \\markup \\left-column {
103
+ "Left Hand "
104
+ }
105
+ \\override Stem #'direction = #DOWN
106
+ \\lh | \\lh | \\lh | \\lh |
107
+ }
108
+ \\new DrumStaff {
109
+ \\quakestaff
110
+ \\set DrumStaff.instrumentName = \\markup \\left-column {
111
+ "Right Foot "
112
+ }
113
+ \\override Stem #'direction = #UP
114
+ \\rf | \\rf | \\rf | \\rf |
115
+ }
116
+ \\new DrumStaff {
117
+ \\quakestaff
118
+ \\set DrumStaff.instrumentName = \\markup \\left-column {
119
+ "Left Foot "
120
+ }
121
+ \\override Stem #'direction = #DOWN
122
+ \\lf | \\lf | \\lf | \\lf |
123
+ }
124
+ >>
125
+
126
+ DRILL
127
+ end
128
+
129
+ private
130
+ def build_name(name, prefix)
131
+ [prefix, name].compact.join('_').gsub(/[^\w\.\-]/, '')
132
+ end
133
+
134
+ end
135
+ end
@@ -0,0 +1,19 @@
1
+ module Kadryll
2
+ class ShorthandReader
3
+ def self.read(file)
4
+ exercises = []
5
+ current_exercise = []
6
+ lines = File.readlines(file)
7
+ lines.each do |line|
8
+ if line.gsub(/\W/, '').empty?
9
+ exercises << current_exercise.join
10
+ current_exercise = []
11
+ else
12
+ current_exercise << line
13
+ end
14
+ end
15
+ exercises << current_exercise.join
16
+ exercises.compact.reject {|e| e.empty?}
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,51 @@
1
+ require 'approvals'
2
+ require 'kadryll'
3
+
4
+ def default_template
5
+ <<-DRILL
6
+ e42 4/4
7
+ tt4 r4 tt4-> r4
8
+ r4 tt4 r4 tt4
9
+ tt4 r4 r4 tt4
10
+ r1
11
+ DRILL
12
+ end
13
+
14
+ describe Kadryll::Drill do
15
+ before(:all) do
16
+ Approvals.configure do |c|
17
+ c.approvals_path = 'spec/fixtures/approvals/'
18
+ end
19
+ end
20
+
21
+ describe "the name" do
22
+ it "it defaults to the name passed in" do
23
+ Kadryll::Drill.new("whatever", nil, nil).name.should eq("whatever")
24
+ end
25
+
26
+ it "adds a prefix if there is one" do
27
+ Kadryll::Drill.new("whatever", nil, nil, :prefix => 'level1').name.should eq("level1_whatever")
28
+ end
29
+
30
+ it "sanitizes the name" do
31
+ Kadryll::Drill.new("w_^h%$a&t.ev-er !", nil, nil).name.should eq("w_hat.ev-er")
32
+ end
33
+ end
34
+
35
+ it "creates the correct lilypond command" do
36
+ drill = Kadryll::Drill.from_string(default_template)
37
+ executable = Approvals::Executable.new(drill.command) do |command|
38
+ Approvals::Reporters::FilelauncherReporter.report(drill.generate_png)
39
+ end
40
+ Approvals.verify(executable, :name => 'drill uses the correct command')
41
+ end
42
+
43
+
44
+ it "generates a png" do
45
+ drill = Kadryll::Drill.from_string(default_template)
46
+ executable = Approvals::Executable.new(drill.template) do |command|
47
+ Approvals::Reporters::FilelauncherReporter.report(drill.generate_png)
48
+ end
49
+ Approvals.verify(executable, :name => 'drill generates the template')
50
+ end
51
+ end
@@ -0,0 +1,71 @@
1
+ \version "2.14.2"
2
+
3
+ \header {
4
+ tagline = \markup {
5
+ \fill-line {
6
+ \line { \null }
7
+ \line { \null }
8
+ \line { \tiny \with-color #(x11-color 'gray80) { Copyright 2012 YourName \char ##x00A9 } }
9
+
10
+ }
11
+ }
12
+ }
13
+
14
+ #(set! paper-alist (cons '("drill" . (cons (* 190 mm) (* 80 mm))) paper-alist))
15
+ \paper {
16
+ #(set-paper-size "drill")
17
+ #(define top-margin (* 7 mm))
18
+ #(define line-width (* 140 mm))
19
+ }
20
+
21
+ signature = \time 4/4
22
+
23
+ rh = \drummode { tt4 r4 tt4-> r4 }
24
+ lh = \drummode { r4 tt4 r4 tt4 }
25
+ rf = \drummode { tt4 r4 r4 tt4 }
26
+ lf = \drummode { r1 }
27
+
28
+ #(define quake '((tamtam default #t 0)))
29
+ quakestaff = {
30
+ \override DrumStaff.StaffSymbol #'line-positions = #'( 0 )
31
+ \override DrumStaff.BarLine #'bar-extent = #'(-1 . 1.5)
32
+ \override DrumStaff.InstrumentName #'self-alignment-X = #LEFT
33
+ \set DrumStaff.drumStyleTable = #(alist->hash-table quake)
34
+ \set fontSize = #-2
35
+ \signature
36
+ \override DrumStaff.Rest #'staff-position = #0
37
+ }
38
+
39
+ <<
40
+ \new DrumStaff {
41
+ \quakestaff
42
+ \set DrumStaff.instrumentName = "Right Hand "
43
+ \override Stem #'direction = #UP
44
+ \rh | \rh | \rh | \rh |
45
+ }
46
+ \new DrumStaff {
47
+ \quakestaff
48
+ \set DrumStaff.instrumentName = \markup \left-column {
49
+ "Left Hand "
50
+ }
51
+ \override Stem #'direction = #DOWN
52
+ \lh | \lh | \lh | \lh |
53
+ }
54
+ \new DrumStaff {
55
+ \quakestaff
56
+ \set DrumStaff.instrumentName = \markup \left-column {
57
+ "Right Foot "
58
+ }
59
+ \override Stem #'direction = #UP
60
+ \rf | \rf | \rf | \rf |
61
+ }
62
+ \new DrumStaff {
63
+ \quakestaff
64
+ \set DrumStaff.instrumentName = \markup \left-column {
65
+ "Left Foot "
66
+ }
67
+ \override Stem #'direction = #DOWN
68
+ \lf | \lf | \lf | \lf |
69
+ }
70
+ >>
71
+
@@ -0,0 +1 @@
1
+ lilypond --png --output=drills/scores/e42 drills/data/e42.ly
@@ -0,0 +1,2 @@
1
+ [0] "exercise1 4/4\r\nr1\r\nr4 tt4 r4 4\r\nr1\r\nr1\r\n"
2
+ [1] "exercise2 4/4\r\nr2 tt4 r4\r\nr4 tt4 r4 tt4\r\ntt4 r4 tt4 r4\r\nr1\r\n"
@@ -0,0 +1,2 @@
1
+ [0] "exercise1 4/4\r\nr1\r\nr4 tt4 r4 4\r\nr1\r\nr1\r\n"
2
+ [1] "exercise2 4/4\r\nr2 tt4 r4\r\nr4 tt4 r4 tt4\r\ntt4 r4 tt4 r4\r\nr1\r\n"
@@ -0,0 +1,11 @@
1
+ exercise1 4/4
2
+ r1
3
+ r4 tt4 r4 4
4
+ r1
5
+ r1
6
+
7
+ exercise2 4/4
8
+ r2 tt4 r4
9
+ r4 tt4 r4 tt4
10
+ tt4 r4 tt4 r4
11
+ r1
@@ -0,0 +1,13 @@
1
+ exercise1 4/4
2
+ r1
3
+ r4 tt4 r4 4
4
+ r1
5
+ r1
6
+
7
+
8
+ exercise2 4/4
9
+ r2 tt4 r4
10
+ r4 tt4 r4 tt4
11
+ tt4 r4 tt4 r4
12
+ r1
13
+
@@ -0,0 +1,71 @@
1
+ require 'kadryll'
2
+ require 'timecop'
3
+
4
+ describe Kadryll do
5
+
6
+ describe "output dir" do
7
+ after(:each) do
8
+ Kadryll.configure do |c|
9
+ c.output_dir = nil
10
+ end
11
+ end
12
+
13
+ it "is drills/ by default" do
14
+ Kadryll.output_dir.should eq('drills/scores/')
15
+ end
16
+
17
+ it "handles trailing slashes" do
18
+ Kadryll.configure do |c|
19
+ c.output_dir = 'other/dir'
20
+ end
21
+
22
+ Kadryll.output_dir.should eq('other/dir/')
23
+ end
24
+ end
25
+
26
+ describe "input dir" do
27
+ after(:each) do
28
+ Kadryll.configure do |c|
29
+ c.input_dir = nil
30
+ end
31
+ end
32
+
33
+ it "is drills/data/ by default" do
34
+ Kadryll.input_dir.should eq('drills/data/')
35
+ end
36
+
37
+ it "can be overridden" do
38
+ Kadryll.configure do |c|
39
+ c.input_dir = 'other/dir'
40
+ end
41
+
42
+ Kadryll.input_dir.should eq('other/dir/')
43
+ end
44
+ end
45
+
46
+ describe "copyright" do
47
+ before(:each) do
48
+ Timecop.travel(Time.utc(2012, 2, 7, 18, 28, 18))
49
+ end
50
+
51
+ after(:each) do
52
+ Kadryll.configure do |c|
53
+ c.copyright = nil
54
+ end
55
+ Timecop.return
56
+ end
57
+
58
+ it "defaults to kadryll" do
59
+ Kadryll.copyright.should eq('Copyright 2012 YourName')
60
+ end
61
+
62
+ it "can be overridden" do
63
+ Kadryll.configure do |c|
64
+ c.copyright = 'ALL NOTES ARE BELONG TO ME'
65
+ end
66
+ Kadryll.copyright.should eq('ALL NOTES ARE BELONG TO ME')
67
+ end
68
+
69
+ end
70
+
71
+ end
@@ -0,0 +1,20 @@
1
+ require 'approvals'
2
+ require 'kadryll/shorthand_reader'
3
+ describe Kadryll::ShorthandReader do
4
+ before(:all) do
5
+ Approvals.configure do |c|
6
+ c.approvals_path = 'spec/fixtures/approvals/'
7
+ end
8
+ end
9
+
10
+ it "breaks an input file into exercise templates" do
11
+ exercises = Kadryll::ShorthandReader.read("spec/fixtures/exercises.txt")
12
+ Approvals.verify(exercises, :name => 'exercises from file')
13
+ end
14
+
15
+ it "ignores double blank lines" do
16
+ exercises = Kadryll::ShorthandReader.read("spec/fixtures/exercises_with_blank_lines.txt")
17
+ Approvals.verify(exercises, :name => 'exercises with blanks from file')
18
+ end
19
+
20
+ end
metadata ADDED
@@ -0,0 +1,110 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: kadryll
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Katrina Owen
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-02-25 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rspec
16
+ requirement: &70323596785480 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: *70323596785480
25
+ - !ruby/object:Gem::Dependency
26
+ name: approvals
27
+ requirement: &70323596784080 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ! '>='
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
33
+ type: :development
34
+ prerelease: false
35
+ version_requirements: *70323596784080
36
+ - !ruby/object:Gem::Dependency
37
+ name: timecop
38
+ requirement: &70323596782100 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ! '>='
42
+ - !ruby/object:Gem::Version
43
+ version: '0'
44
+ type: :development
45
+ prerelease: false
46
+ version_requirements: *70323596782100
47
+ description: Score generator for drum independence drills.
48
+ email:
49
+ - katrina.owen@gmail.com
50
+ executables:
51
+ - kadryll
52
+ extensions: []
53
+ extra_rdoc_files: []
54
+ files:
55
+ - .gitignore
56
+ - Gemfile
57
+ - README.md
58
+ - Rakefile
59
+ - TODO
60
+ - bin/kadryll
61
+ - kadryll.gemspec
62
+ - lib/kadryll.rb
63
+ - lib/kadryll/cli.rb
64
+ - lib/kadryll/drill.rb
65
+ - lib/kadryll/shorthand_reader.rb
66
+ - spec/drill_spec.rb
67
+ - spec/fixtures/approvals/drill_generates_a_png.approved.txt
68
+ - spec/fixtures/approvals/drill_generates_the_template.approved.txt
69
+ - spec/fixtures/approvals/drill_uses_the_correct_command.approved.txt
70
+ - spec/fixtures/approvals/exercises_from_file.approved.txt
71
+ - spec/fixtures/approvals/exercises_with_blanks_from_file.approved.txt
72
+ - spec/fixtures/exercises.txt
73
+ - spec/fixtures/exercises_with_blank_lines.txt
74
+ - spec/kadryll_spec.rb
75
+ - spec/shorthand_reader_spec.rb
76
+ homepage: ''
77
+ licenses: []
78
+ post_install_message:
79
+ rdoc_options: []
80
+ require_paths:
81
+ - lib
82
+ required_ruby_version: !ruby/object:Gem::Requirement
83
+ none: false
84
+ requirements:
85
+ - - ! '>='
86
+ - !ruby/object:Gem::Version
87
+ version: '0'
88
+ required_rubygems_version: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ! '>='
92
+ - !ruby/object:Gem::Version
93
+ version: '0'
94
+ requirements: []
95
+ rubyforge_project: kadryll
96
+ rubygems_version: 1.8.15
97
+ signing_key:
98
+ specification_version: 3
99
+ summary: Score generator for drum independence drills.
100
+ test_files:
101
+ - spec/drill_spec.rb
102
+ - spec/fixtures/approvals/drill_generates_a_png.approved.txt
103
+ - spec/fixtures/approvals/drill_generates_the_template.approved.txt
104
+ - spec/fixtures/approvals/drill_uses_the_correct_command.approved.txt
105
+ - spec/fixtures/approvals/exercises_from_file.approved.txt
106
+ - spec/fixtures/approvals/exercises_with_blanks_from_file.approved.txt
107
+ - spec/fixtures/exercises.txt
108
+ - spec/fixtures/exercises_with_blank_lines.txt
109
+ - spec/kadryll_spec.rb
110
+ - spec/shorthand_reader_spec.rb