musicxml 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +6 -0
- data/.rubocop.yml +25 -0
- data/.travis.yml +6 -0
- data/Gemfile +3 -0
- data/LICENSE.txt +21 -0
- data/README.md +42 -0
- data/Rakefile +10 -0
- data/bin/console +10 -0
- data/lib/musicxml.rb +12 -0
- data/lib/musicxml/key_signature.rb +16 -0
- data/lib/musicxml/node.rb +129 -0
- data/lib/musicxml/node/base.rb +30 -0
- data/lib/musicxml/node/config.rb +48 -0
- data/lib/musicxml/node/json_export.rb +54 -0
- data/lib/musicxml/node/parser.rb +66 -0
- data/lib/musicxml/parser.rb +22 -0
- data/lib/musicxml/version.rb +3 -0
- data/musicxml.gemspec +25 -0
- data/samples/ActorPreludeSample.mxl +0 -0
- data/samples/ActorPreludeSample.pdf +0 -0
- data/samples/ActorPreludeSample.xml +44672 -0
- data/samples/BeetAnGeSample.mxl +0 -0
- data/samples/BeetAnGeSample.pdf +0 -0
- data/samples/BeetAnGeSample.xml +4274 -0
- data/samples/Binchois.mxl +0 -0
- data/samples/Binchois.png +0 -0
- data/samples/Binchois.xml +2547 -0
- data/samples/BrahWiMeSample.mxl +0 -0
- data/samples/BrahWiMeSample.pdf +0 -0
- data/samples/BrahWiMeSample.xml +3023 -0
- data/samples/BrookeWestSample.mxl +0 -0
- data/samples/BrookeWestSample.pdf +0 -0
- data/samples/BrookeWestSample.xml +5940 -0
- data/samples/Chant.mxl +0 -0
- data/samples/Chant.png +0 -0
- data/samples/Chant.xml +482 -0
- data/samples/DebuMandSample.mxl +0 -0
- data/samples/DebuMandSample.pdf +0 -0
- data/samples/DebuMandSample.xml +4201 -0
- data/samples/Dichterliebe01.mxl +0 -0
- data/samples/Dichterliebe01.pdf +0 -0
- data/samples/Dichterliebe01.xml +7607 -0
- data/samples/Echigo-Jishi.mxl +0 -0
- data/samples/Echigo-Jishi.pdf +0 -0
- data/samples/Echigo-Jishi.xml +2559 -0
- data/samples/FaurReveSample.mxl +0 -0
- data/samples/FaurReveSample.pdf +0 -0
- data/samples/FaurReveSample.xml +5667 -0
- data/samples/MahlFaGe4Sample.mxl +0 -0
- data/samples/MahlFaGe4Sample.pdf +0 -0
- data/samples/MahlFaGe4Sample.xml +4876 -0
- data/samples/MozaChloSample.mxl +0 -0
- data/samples/MozaChloSample.pdf +0 -0
- data/samples/MozaChloSample.xml +0 -0
- data/samples/MozaVeilSample.mxl +0 -0
- data/samples/MozaVeilSample.pdf +0 -0
- data/samples/MozaVeilSample.xml +0 -0
- data/samples/MozartPianoSonata.mxl +0 -0
- data/samples/MozartPianoSonata.png +0 -0
- data/samples/MozartPianoSonata.xml +1136 -0
- data/samples/MozartTrio.mxl +0 -0
- data/samples/MozartTrio.png +0 -0
- data/samples/MozartTrio.xml +3498 -0
- data/samples/Saltarello.ly +7 -0
- data/samples/Saltarello.mxl +0 -0
- data/samples/Saltarello.png +0 -0
- data/samples/Saltarello.xml +1551 -0
- data/samples/SchbAvMaSample.mxl +0 -0
- data/samples/SchbAvMaSample.pdf +0 -0
- data/samples/SchbAvMaSample.xml +8787 -0
- data/samples/Telemann.mxl +0 -0
- data/samples/Telemann.png +0 -0
- data/samples/Telemann.xml +5498 -0
- metadata +187 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: e6ee424ff81a6fc3e48e995744f296e7a8796778
|
4
|
+
data.tar.gz: ec5671b612320f2cc717dde7f98bcffce3996078
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 705281df74f15b612922ab47af95f052221fed252805e06231a65a736310158f5f081045000100d46ea7ce4790ef8bcde20d0f55c5a8bef5dd35df9f7e19cb3e
|
7
|
+
data.tar.gz: 20973e13ddcbc7fc6d1bb8b79c951eace6fc58fb8586bf2a50ba62c227b94e472311ed36ba913d5080c3108d9718b2eff5b8e2813c35e3658c3f2c305a6cc641
|
data/.gitignore
ADDED
data/.rubocop.yml
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
AllCops:
|
2
|
+
DisplayCopNames: true
|
3
|
+
DisplayStyleGuide: true
|
4
|
+
Exclude:
|
5
|
+
- vendor/**/*
|
6
|
+
|
7
|
+
Metrics/LineLength:
|
8
|
+
Max: 100
|
9
|
+
|
10
|
+
Style/Documentation:
|
11
|
+
Enabled: false
|
12
|
+
|
13
|
+
Style/EmptyLinesAroundClassBody:
|
14
|
+
Enabled: false
|
15
|
+
|
16
|
+
Style/EmptyLinesAroundModuleBody:
|
17
|
+
Enabled: false
|
18
|
+
|
19
|
+
Style/PercentLiteralDelimiters:
|
20
|
+
PreferredDelimiters:
|
21
|
+
'%i': '[]'
|
22
|
+
'%w': '[]'
|
23
|
+
|
24
|
+
Style/PerlBackrefs:
|
25
|
+
Enabled: false
|
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2016 Kevin Deisz
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
# MusicXML
|
2
|
+
|
3
|
+
[![Build Status](https://travis-ci.org/kddeisz/musicxml.svg?branch=master)](https://travis-ci.org/kddeisz/musicxml)
|
4
|
+
|
5
|
+
Ruby bindings for MusicXML.
|
6
|
+
|
7
|
+
## Installation
|
8
|
+
|
9
|
+
Add this line to your application's Gemfile:
|
10
|
+
|
11
|
+
```ruby
|
12
|
+
gem 'musicxml'
|
13
|
+
```
|
14
|
+
|
15
|
+
And then execute:
|
16
|
+
|
17
|
+
$ bundle
|
18
|
+
|
19
|
+
Or install it yourself as:
|
20
|
+
|
21
|
+
$ gem install musicxml
|
22
|
+
|
23
|
+
## Usage
|
24
|
+
|
25
|
+
```ruby
|
26
|
+
filepath = 'my-piece.xml'
|
27
|
+
score = MusicXML::Parser.new(filepath)
|
28
|
+
```
|
29
|
+
|
30
|
+
## Development
|
31
|
+
|
32
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
33
|
+
|
34
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
35
|
+
|
36
|
+
## Contributing
|
37
|
+
|
38
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/kddeisz/musicxml.
|
39
|
+
|
40
|
+
## License
|
41
|
+
|
42
|
+
The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
|
data/Rakefile
ADDED
data/bin/console
ADDED
data/lib/musicxml.rb
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
require 'forwardable'
|
2
|
+
require 'json'
|
3
|
+
require 'nokogiri'
|
4
|
+
|
5
|
+
require 'musicxml/node/config'
|
6
|
+
require 'musicxml/node/json_export'
|
7
|
+
require 'musicxml/node/base'
|
8
|
+
require 'musicxml/node/parser'
|
9
|
+
require 'musicxml/node'
|
10
|
+
|
11
|
+
require 'musicxml/key_signature'
|
12
|
+
require 'musicxml/parser'
|
@@ -0,0 +1,129 @@
|
|
1
|
+
module MusicXML
|
2
|
+
# Namespace for all nodes defined by the system. Nodes are used
|
3
|
+
# to represent the various segments of the XML describing different
|
4
|
+
# musical concepts.
|
5
|
+
module Node
|
6
|
+
|
7
|
+
class << self
|
8
|
+
attr_accessor :registry
|
9
|
+
end
|
10
|
+
self.registry = {}
|
11
|
+
|
12
|
+
def self.register(name, &block)
|
13
|
+
class_name = name.to_s.capitalize.gsub(/\_([a-z])/) { $1.to_s.upcase }
|
14
|
+
clazz = Class.new(Base, &block)
|
15
|
+
|
16
|
+
registry[name] = clazz
|
17
|
+
const_set(class_name.to_sym, clazz)
|
18
|
+
end
|
19
|
+
|
20
|
+
register :articulations do
|
21
|
+
sattrs :accent, :breath_mark, :staccato, :tenuto
|
22
|
+
end
|
23
|
+
|
24
|
+
register :attributes do
|
25
|
+
pattrs :divisions, :staves
|
26
|
+
snodes :clef, :key, :transpose
|
27
|
+
end
|
28
|
+
|
29
|
+
register :barline do
|
30
|
+
snodes :repeat
|
31
|
+
end
|
32
|
+
|
33
|
+
register :chord
|
34
|
+
|
35
|
+
register :clef do
|
36
|
+
sattrs :line, :sign
|
37
|
+
end
|
38
|
+
|
39
|
+
register :defaults do
|
40
|
+
sattrs :music_font, :word_font
|
41
|
+
end
|
42
|
+
|
43
|
+
register :direction do
|
44
|
+
snodes :direction_type
|
45
|
+
end
|
46
|
+
|
47
|
+
register :direction_type do
|
48
|
+
pattrs :words, :dynamics
|
49
|
+
end
|
50
|
+
|
51
|
+
register :dot
|
52
|
+
|
53
|
+
register :encoding do
|
54
|
+
pattrs :supports
|
55
|
+
sattrs :encoding_data, :software
|
56
|
+
end
|
57
|
+
|
58
|
+
register :identification do
|
59
|
+
sattrs :creator, :rights
|
60
|
+
snodes :encoding
|
61
|
+
end
|
62
|
+
|
63
|
+
register :key do
|
64
|
+
sattrs :fifths, :mode
|
65
|
+
|
66
|
+
def humanize
|
67
|
+
(@key_signature ||= KeySignature.new(fifths.to_i)).humanize
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
register :measure do
|
72
|
+
sattrs :sound
|
73
|
+
snodes :clef, :direction, :key, :time, :barline, :transpose
|
74
|
+
pnodes :note
|
75
|
+
end
|
76
|
+
|
77
|
+
register :notations do
|
78
|
+
pnodes :articulations
|
79
|
+
sattrs :arpeggiate, :slur
|
80
|
+
end
|
81
|
+
|
82
|
+
register :note do
|
83
|
+
sattrs :duration, :staff, :stem, :type, :voice, :accidental
|
84
|
+
|
85
|
+
pnodes :notations, :dot
|
86
|
+
snodes :pitch, :chord
|
87
|
+
end
|
88
|
+
|
89
|
+
register :part do
|
90
|
+
pnodes :measure
|
91
|
+
end
|
92
|
+
|
93
|
+
register :part_list do
|
94
|
+
pnodes :score_part
|
95
|
+
end
|
96
|
+
|
97
|
+
register :pitch do
|
98
|
+
sattrs :step, :alter, :octave
|
99
|
+
end
|
100
|
+
|
101
|
+
register :repeat do
|
102
|
+
props :direction, :times
|
103
|
+
end
|
104
|
+
|
105
|
+
register :score_instrument do
|
106
|
+
sattrs :instrument_name
|
107
|
+
end
|
108
|
+
|
109
|
+
register :score_part do
|
110
|
+
sattrs :part_name
|
111
|
+
snodes :score_instrument
|
112
|
+
end
|
113
|
+
|
114
|
+
register :score_partwise do
|
115
|
+
sattrs :movement_title
|
116
|
+
|
117
|
+
pnodes :defaults, :part
|
118
|
+
snodes :identification, :part_list
|
119
|
+
end
|
120
|
+
|
121
|
+
register :time do
|
122
|
+
sattrs :beats, :beat_type
|
123
|
+
end
|
124
|
+
|
125
|
+
register :transpose do
|
126
|
+
sattrs :diatonic, :chromatic, :octave
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module MusicXML
|
2
|
+
module Node
|
3
|
+
|
4
|
+
# Superclass for all node types
|
5
|
+
class Base
|
6
|
+
|
7
|
+
include JsonExport
|
8
|
+
|
9
|
+
# Build a Parser to parse the node based on this class' config
|
10
|
+
def initialize(node)
|
11
|
+
Parser.new(node: node, config: self.class.config).parse.each do |key, value|
|
12
|
+
instance_variable_set(key, value)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
class << self
|
17
|
+
# forward class methods to the config to store the configuration
|
18
|
+
extend Forwardable
|
19
|
+
def_delegators :config, :pattrs, :pnodes, :props, :sattrs, :snodes
|
20
|
+
|
21
|
+
attr_accessor :config
|
22
|
+
|
23
|
+
# when this class is subclassed build a new config
|
24
|
+
def inherited(subclass)
|
25
|
+
subclass.config = ::MusicXML::Node::Config.new(subclass)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module MusicXML
|
2
|
+
module Node
|
3
|
+
class Config
|
4
|
+
|
5
|
+
attr_accessor :clazz, :properties
|
6
|
+
attr_accessor :plural_attrs, :singular_attrs
|
7
|
+
attr_accessor :plural_nodes, :singular_nodes
|
8
|
+
|
9
|
+
def initialize(clazz)
|
10
|
+
self.clazz = clazz
|
11
|
+
%w[plural_attrs plural_nodes singular_attrs singular_nodes properties].each do |name|
|
12
|
+
send("#{name}=", [])
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def pattrs(*names)
|
17
|
+
self.plural_attrs += names
|
18
|
+
add_accessors(*names)
|
19
|
+
end
|
20
|
+
|
21
|
+
def pnodes(*names)
|
22
|
+
self.plural_nodes += names
|
23
|
+
add_accessors(*names)
|
24
|
+
end
|
25
|
+
|
26
|
+
def props(*names)
|
27
|
+
self.properties += names
|
28
|
+
add_accessors(*names)
|
29
|
+
end
|
30
|
+
|
31
|
+
def sattrs(*names)
|
32
|
+
self.singular_attrs += names
|
33
|
+
add_accessors(*names)
|
34
|
+
end
|
35
|
+
|
36
|
+
def snodes(*names)
|
37
|
+
self.singular_nodes += names
|
38
|
+
add_accessors(*names)
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
def add_accessors(*names)
|
44
|
+
clazz.class_eval { attr_accessor(*names) }
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
module MusicXML
|
2
|
+
module Node
|
3
|
+
module JsonExport
|
4
|
+
def to_json
|
5
|
+
{ json_key => json_values }.to_json
|
6
|
+
end
|
7
|
+
|
8
|
+
def json_key
|
9
|
+
self.class.name.split('::').last.gsub(/^([A-Z])/) { $1.downcase }
|
10
|
+
end
|
11
|
+
|
12
|
+
def json_values
|
13
|
+
output = {}
|
14
|
+
load_plural_attrs(output)
|
15
|
+
load_singular_attrs(output)
|
16
|
+
load_plural_nodes(output)
|
17
|
+
load_singular_nodes(output)
|
18
|
+
output
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def jsify(name)
|
24
|
+
name.to_s.gsub(/(_[a-z])/) { $1.upcase[1..-1] }
|
25
|
+
end
|
26
|
+
|
27
|
+
def load_plural_attrs(output)
|
28
|
+
self.class.config.plural_attrs.each do |name|
|
29
|
+
output[jsify(name)] = send(name) || []
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def load_plural_nodes(output)
|
34
|
+
self.class.config.plural_nodes.each do |name|
|
35
|
+
nodes = send(name)
|
36
|
+
output[jsify(name)] = nodes ? nodes.map(&:json_values) : []
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def load_singular_attrs(output)
|
41
|
+
(self.class.config.properties + self.class.config.singular_attrs).each do |name|
|
42
|
+
output[jsify(name)] = send(name)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def load_singular_nodes(output)
|
47
|
+
self.class.config.singular_nodes.each do |name|
|
48
|
+
node = send(name)
|
49
|
+
output[jsify(name)] = node ? node.json_values : nil
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|