musical_score 0.1.0 → 0.1.1

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
  SHA1:
3
- metadata.gz: 8b09d9932a8034a704c30a63a3bf1f2c656788e9
4
- data.tar.gz: db84bae2d9473dfda8d6ab146ad0effd966de5d5
3
+ metadata.gz: f4fe9ce7d2dc51b7136d205eef2d8401b67c1e0b
4
+ data.tar.gz: 339ccef7ae5b6bf7492a5e8e3d9d4a5c830b3579
5
5
  SHA512:
6
- metadata.gz: e16f49f188756a8738f2a2b533f9b1d9bbe6b8fc19d5aa507432ed23b2dff3ccd73bae9125bb021832a349d29d5f0cdb04f1982261985ad6f74cf6ed9e347474
7
- data.tar.gz: ee2052aa91df90bd32184c2e83c8e50dada2928dd6b88fbce9eda6c128ae3822fcddc9158f5f8924703ccd767cc670c061ffd584f4f54388a2703377efd4e641
6
+ metadata.gz: 07b419d4fd50b20fb505954537794fec98b24eddb2c3bddcad8fb16dd0f015f53ca9f386e9766de725590a716a41c0294a8485a88e4f4689f2a4fd0278fd75e6
7
+ data.tar.gz: cf3d0a5a58b34be0364668b29ef635cd11c64741bacca005ba33f15b32bec295665ae987c48e1c8fedd9208714c75d9f563909e73ec19c0a44b3db3a3e5b536c
data/.rspec CHANGED
@@ -1,2 +1,2 @@
1
- --format Fuubar
1
+ --format documentation
2
2
  --color
data/README.md CHANGED
@@ -2,6 +2,7 @@
2
2
 
3
3
  [![Build Status](https://travis-ci.org/yumaito/musical_score.svg?branch=master)](https://travis-ci.org/yumaito/musical_score)
4
4
  [![Code Climate](https://codeclimate.com/github/yumaito/musical_score/badges/gpa.svg)](https://codeclimate.com/github/yumaito/musical_score)
5
+ [![Gem Version](https://badge.fury.io/rb/musical_score.svg)](https://badge.fury.io/rb/musical_score)
5
6
 
6
7
  Library for representing and analysing musical score.
7
8
  This library is implemented along with the definitions of [MusicXML](http://www.musicxml.com/) mainly.
@@ -32,9 +33,15 @@ require 'musical_score'
32
33
 
33
34
  musical_score = MusicalScore::IO.import("path/to/musicxml.xml")
34
35
  ```
35
-
36
36
  Now you can handle the musical score as a ruby class object.
37
37
 
38
+ For example, if you want to know the pitch of the first note information:
39
+ ```ruby
40
+ pitch = musical_score.part[0].measures[0].notes[0].pitch
41
+ puts pitch
42
+ # E3
43
+ ```
44
+
38
45
  ## Contributing
39
46
 
40
47
  Bug reports and pull requests are welcome on GitHub at https://github.com/yumaito/musical_score. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
@@ -50,6 +50,17 @@ module MusicalScore
50
50
  return attributes
51
51
  end
52
52
 
53
+ Contract HashOf[String => Any] => MusicalScore::Attribute::Attribute
54
+ def self.create_by_hash(doc)
55
+ divisions = doc["divisions"][0].to_i
56
+ clef = doc.has_key?("clef") ? MusicalScore::Attribute::Clef.create_by_hash(doc["clef"][0]) : nil
57
+ time = doc.has_key?("time") ? MusicalScore::Attribute::Time.create_by_hash(doc["time"][0]) : nil
58
+ key = doc.has_key?("key") ? MusicalScore::Attribute::Key.create_by_hash(doc["key"][0]) : nil
59
+
60
+ attributes = MusicalScore::Attribute::Attribute.new(divisions: divisions, clef: clef, key: key, time: time)
61
+ return attributes
62
+ end
63
+
53
64
  def export_xml
54
65
  attribute_element = REXML::Element.new('attributes')
55
66
  divisions_element = REXML::Element.new('divisions').add_text(@divisions.to_s)
@@ -27,6 +27,15 @@ module MusicalScore
27
27
  return clef
28
28
  end
29
29
 
30
+ Contract HashOf[String => Any] => MusicalScore::Attribute::Clef
31
+ def self.create_by_hash(doc)
32
+ sign = doc["sign"][0].to_sym
33
+ line = doc.has_key?("line") ? doc["line"][0].to_i : 0
34
+ clef_octave_change = doc.has_key?("clef-octave-change") ? doc["clef-octave-change"][0].to_i : 0
35
+ clef = MusicalScore::Attribute::Clef.new(sign, line, clef_octave_change)
36
+ return clef
37
+ end
38
+
30
39
  def export_xml
31
40
  clef_element = REXML::Element.new('clef')
32
41
  sign_element = REXML::Element.new('sign').add_text(@sign.to_s)
@@ -41,4 +50,4 @@ module MusicalScore
41
50
  end
42
51
  end
43
52
  end
44
- end
53
+ end
@@ -3,7 +3,7 @@ module MusicalScore
3
3
  module Attribute
4
4
  class Key < MusicalScore::ElementBase
5
5
  include Contracts
6
- @@mode = %i(major :minor)
6
+ @@mode = %i(major minor)
7
7
  @@circle_of_fifths = [0, 7, 2, 9, 4, 11, 6, 1, 8, 3, 10, 5]
8
8
 
9
9
  attr_reader :fifths, :mode
@@ -59,6 +59,13 @@ module MusicalScore
59
59
  return MusicalScore::Attribute::Key.new(fifths, mode)
60
60
  end
61
61
 
62
+ Contract HashOf[String => Any] => MusicalScore::Attribute::Key
63
+ def self.create_by_hash(doc)
64
+ fifths = doc["fifths"][0].to_i
65
+ mode = doc["mode"][0].to_sym
66
+ return MusicalScore::Attribute::Key.new(fifths, mode)
67
+ end
68
+
62
69
  def export_xml
63
70
  key_element = REXML::Element.new('key')
64
71
  fifths_element = REXML::Element.new('fifths').add_text(@fifths.to_s)
@@ -71,4 +78,4 @@ module MusicalScore
71
78
  end
72
79
  end
73
80
  end
74
- end
81
+ end
@@ -25,6 +25,13 @@ module MusicalScore
25
25
  return MusicalScore::Attribute::Time.new(beats, beat_type)
26
26
  end
27
27
 
28
+ Contract HashOf[String => Any] => MusicalScore::Attribute::Time
29
+ def self.create_by_hash(doc)
30
+ beats = doc["beats"][0].to_i
31
+ beat_type = doc["beat-type"][0].to_i
32
+ return MusicalScore::Attribute::Time.new(beats, beat_type)
33
+ end
34
+
28
35
  def export_xml
29
36
  time = REXML::Element.new('time')
30
37
  beats = REXML::Element.new('beats')
@@ -10,6 +10,10 @@ module MusicalScore
10
10
  raise "Called abstract method: create_by_xml"
11
11
  end
12
12
 
13
+ def self.create_by_hash(hash)
14
+ raise "Called abstract method: create_by_hash"
15
+ end
16
+
13
17
  def export_xml
14
18
  raise "Called abstract method: export_xml"
15
19
  end
@@ -0,0 +1,16 @@
1
+ require 'musical_score'
2
+ require 'rexml/document'
3
+ require 'rexml/formatters/pretty'
4
+ module MusicalScore
5
+ module IO
6
+ def export_xml(path, score)
7
+ formatter = REXML::Formatters::Pretty.new(4)
8
+ formatter.compact = true
9
+ File.open(path, 'w') do |file|
10
+ formatter.write(score.export_xml, file)
11
+ end
12
+ end
13
+
14
+ module_function :export_xml
15
+ end
16
+ end
@@ -1,12 +1,13 @@
1
1
  require 'musical_score'
2
2
  require 'rexml/document'
3
+ require 'xmlsimple'
3
4
  module MusicalScore
4
5
  module IO
5
6
  def import(file)
6
7
  extname = File.extname(file)
7
8
  case extname
8
9
  when ".xml"
9
- return import_xml(file)
10
+ return import_xml_via_hash(file)
10
11
  else
11
12
  raise MusicalScore::InvalidFileType
12
13
  end
@@ -17,6 +18,12 @@ module MusicalScore
17
18
  return score
18
19
  end
19
20
 
20
- module_function :import, :import_xml
21
+ def import_xml_via_hash(file_path)
22
+ doc = XmlSimple.xml_in(open(file_path))
23
+ score = MusicalScore::Score::Score.create_by_hash(doc, file_path)
24
+ return score
25
+ end
26
+
27
+ module_function :import, :import_xml, :import_xml_via_hash
21
28
  end
22
29
  end
@@ -21,6 +21,10 @@ module MusicalScore
21
21
  end
22
22
  end
23
23
 
24
+ def last
25
+ return @measures[@measures.size-1]
26
+ end
27
+
24
28
  def all_notes
25
29
  result = Array.new
26
30
  @measures.each do |measure|
@@ -25,6 +25,14 @@ module MusicalScore
25
25
  return MusicalScore::Note::Lyric.new(text, syllabic, is_extend)
26
26
  end
27
27
 
28
+ Contract HashOf[String => Any] => MusicalScore::Note::Lyric
29
+ def self.create_by_hash(doc)
30
+ syllabic = doc.has_key?("syllabic") ? doc["syllabic"][0].to_sym : nil
31
+ text = doc["text"][0]
32
+ is_extend = doc.has_key?("extend")
33
+ return MusicalScore::Note::Lyric.new(text, syllabic, is_extend)
34
+ end
35
+
28
36
  def export_xml(number)
29
37
  lyric_element = REXML::Element.new('lyric')
30
38
  lyric_element.add_attribute('number', number.to_s)
@@ -40,4 +48,4 @@ module MusicalScore
40
48
  end
41
49
  end
42
50
  end
43
- end
51
+ end
@@ -80,6 +80,17 @@ module MusicalScore
80
80
  return MusicalScore::Note::Notation::Notation.new(articulation: articulation, dynamics: dynamics, tie: tie, tuplet: tuplet)
81
81
  end
82
82
 
83
+ Contract HashOf[String => Any] => MusicalScore::Note::Notation::Notation
84
+ def self.create_by_hash(doc)
85
+ articulation = doc.has_key?("articulations") ? doc["articulations"][0].keys[0].to_sym : nil
86
+ dynamics = doc.has_key?("dynamics") ? doc["dynamics"][0].keys[0].to_sym : nil
87
+ tie_arg = doc.has_key?("tied") ? doc.dig("tied", 0, "type").to_sym : nil
88
+ tie = tie_arg ? MusicalScore::Note::Notation::Tie.new(tie_arg) : nil
89
+ tuplet_arg = doc.has_key?("tuplet") ? doc.dig("tuplet", 0, "type").to_sym : nil
90
+ tuplet = tuplet_arg ? MusicalScore::Note::Notation::Tuplet.new(tuplet_arg) : nil
91
+ return MusicalScore::Note::Notation::Notation.new(articulation: articulation, dynamics: dynamics, tie: tie, tuplet: tuplet)
92
+ end
93
+
83
94
  def export_xml
84
95
  notations_element = REXML::Element.new('notations')
85
96
  articulation_element = REXML::Element.new('articulations')
@@ -113,6 +113,26 @@ module MusicalScore
113
113
  end
114
114
  end
115
115
 
116
+ Contract HashOf[String => Any] => MusicalScore::Note::Note
117
+ def self.create_by_hash(doc)
118
+ dots = doc.has_key?("dot") ? doc["dot"].size : 0
119
+ duration = doc["duration"][0].to_i
120
+ type = MusicalScore::Note::Type.new(doc["type"][0])
121
+ tie = doc.has_key?("tie") ? doc.dig("tie", 0, "type").to_sym : nil
122
+ notation = doc.has_key?("notations") ? MusicalScore::Note::Notation::Notation.create_by_hash(doc["notations"][0]) : nil
123
+ time_modification = doc.has_key?("time-modification") ? MusicalScore::Note::TimeModification.create_by_hash(doc["time-modification"][0]) : nil
124
+ rest = doc.has_key?("rest")
125
+
126
+ if (rest)
127
+ return MusicalScore::Note::Note.new(duration: duration, tie: tie, dot: dots, rest: rest, type: type, time_modification: time_modification, notation: notation)
128
+ else
129
+ pitch = MusicalScore::Note::Pitch.create_by_hash(doc["pitch"][0])
130
+ lyric = doc.has_key?("lyric") ? MusicalScore::Note::Lyric.create_by_hash(doc["lyric"][0]) : nil
131
+ return MusicalScore::Note::Note.new(duration: duration, tie: tie, dot: dots, type: type, lyric: lyric, pitch: pitch, time_modification: time_modification, notation: notation)
132
+ end
133
+
134
+ end
135
+
116
136
  def export_xml
117
137
  note_element = REXML::Element.new('note')
118
138
  note_element.add_element('rest') if @rest
@@ -100,6 +100,14 @@ module MusicalScore
100
100
  return MusicalScore::Note::Pitch.new(step, alter, octave)
101
101
  end
102
102
 
103
+ Contract HashOf[String => Any] => MusicalScore::Note::Pitch
104
+ def self.create_by_hash(doc)
105
+ step = doc["step"][0].to_sym
106
+ octave = doc["octave"][0].to_i
107
+ alter = doc.has_key?("alter") ? doc["alter"][0].to_i : 0
108
+ return MusicalScore::Note::Pitch.new(step, alter, octave)
109
+ end
110
+
103
111
  def export_xml
104
112
  pitch_element = REXML::Element.new('pitch')
105
113
  step_element = REXML::Element.new('step').add_text(@step.to_s)
@@ -18,6 +18,13 @@ module MusicalScore
18
18
  return MusicalScore::Note::TimeModification.new(actual_notes, normal_notes)
19
19
  end
20
20
 
21
+ Contract HashOf[String => Any] => MusicalScore::Note::TimeModification
22
+ def self.create_by_hash(doc)
23
+ actual_notes = doc["actual-notes"][0].to_i
24
+ normal_notes = doc["normal-notes"][0].to_i
25
+ return MusicalScore::Note::TimeModification.new(actual_notes, normal_notes)
26
+ end
27
+
21
28
  def export_xml
22
29
  time_modification_element = REXML::Element.new('time-modification')
23
30
  actual_notes_element = REXML::Element.new('actual-notes').add_text(@actual_notes.to_s)
@@ -30,4 +37,4 @@ module MusicalScore
30
37
  end
31
38
  end
32
39
  end
33
- end
40
+ end
@@ -29,6 +29,19 @@ module MusicalScore
29
29
  return MusicalScore::Part::Measure.new(notes, number, attributes)
30
30
  end
31
31
 
32
+ Contract HashOf[String => Any] => MusicalScore::Part::Measure
33
+ def self.create_by_hash(doc)
34
+ number = doc["number"].to_i
35
+ attributes = doc.has_key?("attributes") ? MusicalScore::Attribute::Attribute.create_by_hash(doc["attributes"][0]) : nil
36
+ note_array = Array.new
37
+ doc["note"].each do |element|
38
+ note = MusicalScore::Note::Note.create_by_hash(element)
39
+ note_array.push(note)
40
+ end
41
+ notes = MusicalScore::Notes.new(note_array)
42
+ return MusicalScore::Part::Measure.new(notes, number, attributes)
43
+ end
44
+
32
45
  def export_xml
33
46
  measure_element = REXML::Element.new('measure')
34
47
  measure_element.add_attribute('number',@number.to_s)
@@ -26,6 +26,17 @@ module MusicalScore
26
26
  return MusicalScore::Part::Part.new(measures)
27
27
  end
28
28
 
29
+ Contract HashOf[String => Any] => MusicalScore::Part::Part
30
+ def self.create_by_hash(doc)
31
+ measure_array = Array.new
32
+ doc["measure"].each do |element|
33
+ measure = MusicalScore::Part::Measure.create_by_hash(element)
34
+ measure_array.push(measure)
35
+ end
36
+ measures = MusicalScore::Measures.new(measure_array)
37
+ return MusicalScore::Part::Part.new(measures)
38
+ end
39
+
29
40
  def export_xml(number)
30
41
  part = REXML::Element.new('part')
31
42
  part.add_attribute('id', "P" + number.to_s)
@@ -17,6 +17,14 @@ module MusicalScore
17
17
  name = xml_doc.text
18
18
  return MusicalScore::Score::Identification::Creator.new(name, type)
19
19
  end
20
+
21
+ Contract HashOf[String => Any] => MusicalScore::Score::Identification::Creator
22
+ def self.create_by_hash(doc)
23
+ type = doc["type"].to_sym
24
+ name = doc["content"]
25
+ return MusicalScore::Score::Identification::Creator.new(name, type)
26
+ end
27
+
20
28
  def export_xml
21
29
  creator = REXML::Element.new('creator')
22
30
  creator.add_attribute('type', @type)
@@ -36,6 +36,28 @@ module MusicalScore
36
36
  return MusicalScore::Score::Identification::Encoding.new(encoding_date, encoding_description, softwares, supports)
37
37
  end
38
38
 
39
+ Contract HashOf[String => Any] => MusicalScore::Score::Identification::Encoding
40
+ def self.create_by_hash(doc)
41
+ encoding_date = Time.new
42
+ if (doc.has_key?("encoding-date"))
43
+ encoding_date = Time.parse(doc["encoding-date"][0])
44
+ end
45
+ encoding_description = doc.has_key?("encoding_description") ? doc["encoding_date"] : ''
46
+ softwares = Array.new
47
+ if doc.has_key?("software")
48
+ doc["software"].each do |element|
49
+ softwares.push(element)
50
+ end
51
+ end
52
+ supports = Array.new
53
+ doc["supports"].each do |element|
54
+ if (element["type"] == "yes")
55
+ supports.push(element["element"])
56
+ end
57
+ end
58
+ return MusicalScore::Score::Identification::Encoding.new(encoding_date, encoding_description, softwares, supports)
59
+ end
60
+
39
61
  def export_xml
40
62
  encoding = REXML::Element.new('encoding')
41
63
  @softwares.each do |software|
@@ -32,6 +32,18 @@ module MusicalScore
32
32
  return MusicalScore::Score::Identification::Identification.new(creators, encoding)
33
33
  end
34
34
 
35
+ Contract HashOf[String => Any] => MusicalScore::Score::Identification::Identification
36
+ def self.create_by_hash(doc)
37
+ creators = Array.new
38
+ if (doc.has_key?("creator"))
39
+ doc["creator"].each do |element|
40
+ creators.push(MusicalScore::Score::Identification::Creator.create_by_hash(element))
41
+ end
42
+ end
43
+ encoding = doc.has_key?("encoding") ? MusicalScore::Score::Identification::Encoding.create_by_hash(doc["encoding"][0]) : nil
44
+ return MusicalScore::Score::Identification::Identification.new(creators, encoding)
45
+ end
46
+
35
47
  def export_xml
36
48
  identification = REXML::Element.new('identification')
37
49
  @creators.each do |creator|
@@ -72,7 +72,43 @@ module MusicalScore
72
72
  return MusicalScore::Score::Score.new(args)
73
73
  end
74
74
 
75
- def export_xml(path)
75
+ Contract HashOf[String => Any], Maybe[String] => MusicalScore::Score::Score
76
+ def self.create_by_hash(doc, file_path)
77
+ args = {}
78
+ args[:file_path] = file_path
79
+
80
+ if doc.has_key?("identification")
81
+ identification = MusicalScore::Score::Identification::Identification.create_by_hash(doc["identification"][0])
82
+ args[:identification] = identification
83
+ end
84
+
85
+ credits = Array.new
86
+ doc["credit"].each do |element|
87
+ if (element.has_key?("credit-words"))
88
+ credits.push(element.dig("credit-words", 0, "content"))
89
+ end
90
+ end
91
+ args[:credits] = credits
92
+
93
+ part_list = Array.new
94
+ doc.dig("part-list", 0, "score-part").each do |element|
95
+ part_name = element["part-name"][0]
96
+ part_abbreviation = element["part-abbreviation"][0]
97
+ part = MusicalScore::Score::Part::Part.new(part_name, part_abbreviation)
98
+ part_list.push(part)
99
+ end
100
+ args[:part_list] = part_list
101
+
102
+ parts = Array.new
103
+ doc["part"].each do |element|
104
+ part = MusicalScore::Part::Part.create_by_hash(element)
105
+ parts.push(part)
106
+ end
107
+ args[:parts] = parts
108
+ return MusicalScore::Score::Score.new(args)
109
+ end
110
+
111
+ def export_xml()
76
112
  doc = REXML::Document.new
77
113
  doc << REXML::XMLDecl.new('1.0', 'UTF-8')
78
114
  doc << REXML::Document.new(<<-EOS).doctype
@@ -108,12 +144,7 @@ module MusicalScore
108
144
 
109
145
  doc.add_element(score_partwise)
110
146
 
111
- xml = ''
112
- formatter = REXML::Formatters::Pretty.new(4)
113
- formatter.compact = true
114
- formatter.write(doc, xml)
115
-
116
- # puts xml
147
+ return doc
117
148
  end
118
149
 
119
150
  def set_location
@@ -1,4 +1,4 @@
1
1
  module MusicalScore
2
- VERSION = "0.1.0"
2
+ VERSION = "0.1.1"
3
3
  APP_NAME = "MusicalScore"
4
4
  end
@@ -34,9 +34,9 @@ Gem::Specification.new do |spec|
34
34
  spec.add_development_dependency "bundler", "~> 1.13"
35
35
  spec.add_development_dependency "rake", "~> 10.0"
36
36
  spec.add_development_dependency "rspec", "~> 3.1"
37
- spec.add_development_dependency "fuubar"
38
37
  spec.add_development_dependency "yard"
39
38
  spec.add_development_dependency "yard-contracts"
40
39
 
41
40
  spec.add_dependency "contracts"
41
+ spec.add_dependency "xml-simple"
42
42
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: musical_score
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Yuma Ito
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2016-11-19 00:00:00.000000000 Z
11
+ date: 2016-11-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -53,7 +53,7 @@ dependencies:
53
53
  - !ruby/object:Gem::Version
54
54
  version: '3.1'
55
55
  - !ruby/object:Gem::Dependency
56
- name: fuubar
56
+ name: yard
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
59
  - - ">="
@@ -67,7 +67,7 @@ dependencies:
67
67
  - !ruby/object:Gem::Version
68
68
  version: '0'
69
69
  - !ruby/object:Gem::Dependency
70
- name: yard
70
+ name: yard-contracts
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
73
  - - ">="
@@ -81,13 +81,13 @@ dependencies:
81
81
  - !ruby/object:Gem::Version
82
82
  version: '0'
83
83
  - !ruby/object:Gem::Dependency
84
- name: yard-contracts
84
+ name: contracts
85
85
  requirement: !ruby/object:Gem::Requirement
86
86
  requirements:
87
87
  - - ">="
88
88
  - !ruby/object:Gem::Version
89
89
  version: '0'
90
- type: :development
90
+ type: :runtime
91
91
  prerelease: false
92
92
  version_requirements: !ruby/object:Gem::Requirement
93
93
  requirements:
@@ -95,7 +95,7 @@ dependencies:
95
95
  - !ruby/object:Gem::Version
96
96
  version: '0'
97
97
  - !ruby/object:Gem::Dependency
98
- name: contracts
98
+ name: xml-simple
99
99
  requirement: !ruby/object:Gem::Requirement
100
100
  requirements:
101
101
  - - ">="
@@ -136,6 +136,7 @@ files:
136
136
  - lib/musical_score/const.rb
137
137
  - lib/musical_score/element_base.rb
138
138
  - lib/musical_score/errors.rb
139
+ - lib/musical_score/io/exporter.rb
139
140
  - lib/musical_score/io/importer.rb
140
141
  - lib/musical_score/location.rb
141
142
  - lib/musical_score/measures.rb