head_music 8.1.1 → 8.2.1

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.
Files changed (40) hide show
  1. checksums.yaml +4 -4
  2. data/.github/ISSUE_TEMPLATE/bug_report.md +31 -0
  3. data/.github/ISSUE_TEMPLATE/feature_request.md +25 -0
  4. data/.github/dependabot.yml +59 -0
  5. data/.github/pull_request_template.md +26 -0
  6. data/.github/workflows/ci.yml +68 -0
  7. data/.github/workflows/release.yml +49 -0
  8. data/.github/workflows/security.yml +32 -0
  9. data/.gitignore +16 -1
  10. data/.rubocop.yml +4 -1
  11. data/.yardopts +16 -0
  12. data/CHANGELOG.md +212 -0
  13. data/CODE_OF_CONDUCT.md +2 -0
  14. data/CONTRIBUTING.md +143 -0
  15. data/Gemfile +7 -2
  16. data/Gemfile.lock +147 -0
  17. data/README.md +100 -11
  18. data/Rakefile +30 -0
  19. data/head_music.gemspec +13 -2
  20. data/lib/head_music/analysis/diatonic_interval.rb +1 -1
  21. data/lib/head_music/analysis/sonority.rb +1 -1
  22. data/lib/head_music/content/staff.rb +13 -3
  23. data/lib/head_music/content/voice.rb +8 -0
  24. data/lib/head_music/instruments/instrument.rb +1 -3
  25. data/lib/head_music/instruments/instrument_families.yml +36 -2
  26. data/lib/head_music/instruments/instruments.yml +3 -0
  27. data/lib/head_music/instruments/variant.rb +1 -1
  28. data/lib/head_music/locales/de.yml +20 -0
  29. data/lib/head_music/locales/es.yml +19 -0
  30. data/lib/head_music/locales/fr.yml +19 -0
  31. data/lib/head_music/locales/it.yml +20 -0
  32. data/lib/head_music/locales/ru.yml +21 -2
  33. data/lib/head_music/rudiment/solmization.rb +1 -1
  34. data/lib/head_music/style/annotation.rb +4 -4
  35. data/lib/head_music/style/guidelines/consonant_climax.rb +2 -2
  36. data/lib/head_music/version.rb +1 -1
  37. metadata +50 -8
  38. data/.circleci/config.yml +0 -22
  39. data/.circleci/setup-rubygems.sh +0 -3
  40. data/.travis.yml +0 -5
data/CONTRIBUTING.md ADDED
@@ -0,0 +1,143 @@
1
+ # Contributing to HeadMusic
2
+
3
+ Thank you for considering contributing to HeadMusic!
4
+
5
+ Following these guidelines helps to communicate that you respect the team managing and developing this open source project. In return, we should reciprocate that respect in addressing your issue, assessing changes, and facilitating your pull requests.
6
+
7
+ ## Code of Conduct
8
+
9
+ This project and everyone participating in it is governed by our [Code of Conduct](CODE_OF_CONDUCT.md). By participating, you are expected to uphold this code. Please report unacceptable behavior to [robert.head@gmail.com](mailto:robert.head@gmail.com).
10
+
11
+ ## What we are looking for
12
+
13
+ HeadMusic is an open source project and we love to receive contributions from our community. There are many ways to contribute, from writing tutorials or blog posts, improving the documentation, submitting bug reports and feature requests or writing code which can be incorporated into HeadMusic itself.
14
+
15
+ ## How to contribute
16
+
17
+ ### Reporting Bugs
18
+
19
+ Before creating bug reports, please check the existing issues as you might find out that you don't need to create one. When you are creating a bug report, please include as many details as possible. Fill out [the required template](.github/ISSUE_TEMPLATE/bug_report.md), the information it asks for helps us resolve issues faster.
20
+
21
+ **Great Bug Reports** tend to have:
22
+
23
+ - A quick summary and/or background
24
+ - Steps to reproduce
25
+ - Be specific!
26
+ - Give sample code if you can
27
+ - What you expected would happen
28
+ - What actually happens
29
+ - Notes (possibly including why you think this might be happening, or stuff you tried that didn't work)
30
+
31
+ ### Suggesting Enhancements
32
+
33
+ Before creating enhancement suggestions, please check the existing issues as you might find out that you don't need to create one. When you are creating an enhancement suggestion, please include as many details as possible. Fill in [the template](.github/ISSUE_TEMPLATE/feature_request.md), including the steps that you imagine you would take if the feature you're requesting existed.
34
+
35
+ ### Pull Requests
36
+
37
+ The process described here has several goals:
38
+
39
+ - Maintain HeadMusic's quality
40
+ - Fix problems that are important to users
41
+ - Engage the community in working toward the best possible HeadMusic
42
+ - Enable a sustainable system for HeadMusic's maintainers to review contributions
43
+
44
+ Please follow these steps to have your contribution considered by the maintainers:
45
+
46
+ 1. Fork the repo and create your branch from `main`.
47
+ 2. If you've added code that should be tested, add tests.
48
+ 3. If you've changed APIs, update the documentation.
49
+ 4. Ensure the test suite passes (`bundle exec rspec`).
50
+ 5. Make sure your code lints (`bundle exec rubocop`).
51
+ 6. Follow the [pull request template](.github/pull_request_template.md) when creating your PR.
52
+
53
+ ## Development Process
54
+
55
+ Here's how to get started with development:
56
+
57
+ 1. Fork and clone the repository
58
+ 2. Run `bin/setup` to install dependencies
59
+ 3. Run `bundle exec rspec` to run the tests
60
+ 4. Run `bundle exec rubocop` to check code style
61
+ 5. Create a new branch for your feature or bug fix
62
+ 6. Make your changes and add tests
63
+ 7. Run the tests and linter to ensure everything passes
64
+ 8. Commit your changes with a clear commit message
65
+ 9. Push to your fork and submit a pull request
66
+
67
+ ### Setting up your development environment
68
+
69
+ ```bash
70
+ git clone https://github.com/your-username/head_music.git
71
+ cd head_music
72
+ bin/setup
73
+ ```
74
+
75
+ ### Running tests
76
+
77
+ ```bash
78
+ # Run all tests
79
+ bundle exec rspec
80
+
81
+ # Run a specific test file
82
+ bundle exec rspec spec/head_music/rudiment/pitch_spec.rb
83
+
84
+ # Run tests matching a pattern
85
+ bundle exec rspec -e "Pitch"
86
+ ```
87
+
88
+ ### Code style
89
+
90
+ We use RuboCop with the Standard Ruby style guide. Before submitting a PR, please run:
91
+
92
+ ```bash
93
+ bundle exec rubocop
94
+ ```
95
+
96
+ To automatically fix many issues:
97
+
98
+ ```bash
99
+ bundle exec rubocop --autocorrect
100
+ ```
101
+
102
+ ## Styleguides
103
+
104
+ ### Git Commit Messages
105
+
106
+ - Use the present tense ("Add feature" not "Added feature")
107
+ - Use the imperative mood ("Move cursor to..." not "Moves cursor to...")
108
+ - Limit the first line to 72 characters or less
109
+ - Reference issues and pull requests liberally after the first line
110
+ - Consider starting the commit message with an applicable emoji:
111
+ - 🎨 `:art:` when improving the format/structure of the code
112
+ - 🐎 `:racehorse:` when improving performance
113
+ - 📝 `:memo:` when writing docs
114
+ - 🐛 `:bug:` when fixing a bug
115
+ - 🔥 `:fire:` when removing code or files
116
+ - ✅ `:white_check_mark:` when adding tests
117
+ - 🔒 `:lock:` when dealing with security
118
+ - ⬆️ `:arrow_up:` when upgrading dependencies
119
+ - ⬇️ `:arrow_down:` when downgrading dependencies
120
+
121
+ ### Ruby Styleguide
122
+
123
+ All Ruby code must adhere to [Standard Ruby](https://github.com/testdouble/standard).
124
+
125
+ ### Documentation Styleguide
126
+
127
+ - Use [YARD](https://yardoc.org/) for API documentation.
128
+ - Include examples in your documentation when possible.
129
+
130
+ ## Community
131
+
132
+ - Join our discussions in [GitHub Discussions](https://github.com/roberthead/head_music/discussions)
133
+ - Ask questions in the [Issues](https://github.com/roberthead/head_music/issues)
134
+
135
+ ## Recognition
136
+
137
+ Contributors who submit a pull request that gets merged will be added to our [Contributors list](https://github.com/roberthead/head_music/graphs/contributors).
138
+
139
+ ## Questions?
140
+
141
+ Feel free to contact the project maintainer at [robert.head@gmail.com](mailto:robert.head@gmail.com) if you have any questions or concerns.
142
+
143
+ Thank you for contributing to HeadMusic! 🎵
data/Gemfile CHANGED
@@ -8,9 +8,14 @@ gemspec
8
8
  gem "standard", require: false
9
9
 
10
10
  group :test do
11
- gem "codeclimate-test-reporter", "~> 1.0.0"
12
11
  gem "rubocop", require: false
13
12
  gem "rubocop-rspec", require: false
14
13
  gem "rubocop-rake", require: false
15
- gem "simplecov"
14
+ gem "simplecov", require: false
15
+ end
16
+
17
+ group :development do
18
+ gem "bundler-audit", require: false
19
+ gem "yard", require: false
20
+ gem "kramdown", require: false
16
21
  end
data/Gemfile.lock ADDED
@@ -0,0 +1,147 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ head_music (8.2.0)
5
+ activesupport (~> 7.0)
6
+ humanize (~> 2.0)
7
+ i18n (~> 1.8)
8
+
9
+ GEM
10
+ remote: https://rubygems.org/
11
+ specs:
12
+ activesupport (7.2.2.1)
13
+ base64
14
+ benchmark (>= 0.3)
15
+ bigdecimal
16
+ concurrent-ruby (~> 1.0, >= 1.3.1)
17
+ connection_pool (>= 2.2.5)
18
+ drb
19
+ i18n (>= 1.6, < 2)
20
+ logger (>= 1.4.2)
21
+ minitest (>= 5.1)
22
+ securerandom (>= 0.3)
23
+ tzinfo (~> 2.0, >= 2.0.5)
24
+ ast (2.4.3)
25
+ base64 (0.2.0)
26
+ benchmark (0.4.0)
27
+ bigdecimal (3.1.9)
28
+ bundler-audit (0.9.2)
29
+ bundler (>= 1.2.0, < 3)
30
+ thor (~> 1.0)
31
+ concurrent-ruby (1.3.5)
32
+ connection_pool (2.5.3)
33
+ diff-lcs (1.6.1)
34
+ docile (1.4.1)
35
+ drb (2.2.1)
36
+ humanize (2.5.1)
37
+ i18n (1.14.7)
38
+ concurrent-ruby (~> 1.0)
39
+ json (2.11.3)
40
+ kramdown (2.5.1)
41
+ rexml (>= 3.3.9)
42
+ language_server-protocol (3.17.0.4)
43
+ lint_roller (1.1.0)
44
+ logger (1.7.0)
45
+ minitest (5.25.5)
46
+ parallel (1.27.0)
47
+ parser (3.3.8.0)
48
+ ast (~> 2.4.1)
49
+ racc
50
+ prism (1.4.0)
51
+ racc (1.8.1)
52
+ rainbow (3.1.1)
53
+ rake (13.2.1)
54
+ regexp_parser (2.10.0)
55
+ rexml (3.4.1)
56
+ rspec (3.13.0)
57
+ rspec-core (~> 3.13.0)
58
+ rspec-expectations (~> 3.13.0)
59
+ rspec-mocks (~> 3.13.0)
60
+ rspec-core (3.13.3)
61
+ rspec-support (~> 3.13.0)
62
+ rspec-expectations (3.13.4)
63
+ diff-lcs (>= 1.2.0, < 2.0)
64
+ rspec-support (~> 3.13.0)
65
+ rspec-its (1.3.1)
66
+ rspec-core (>= 3.0.0)
67
+ rspec-expectations (>= 3.0.0)
68
+ rspec-mocks (3.13.3)
69
+ diff-lcs (>= 1.2.0, < 2.0)
70
+ rspec-support (~> 3.13.0)
71
+ rspec-support (3.13.3)
72
+ rubocop (1.75.4)
73
+ json (~> 2.3)
74
+ language_server-protocol (~> 3.17.0.2)
75
+ lint_roller (~> 1.1.0)
76
+ parallel (~> 1.10)
77
+ parser (>= 3.3.0.2)
78
+ rainbow (>= 2.2.2, < 4.0)
79
+ regexp_parser (>= 2.9.3, < 3.0)
80
+ rubocop-ast (>= 1.44.0, < 2.0)
81
+ ruby-progressbar (~> 1.7)
82
+ unicode-display_width (>= 2.4.0, < 4.0)
83
+ rubocop-ast (1.44.1)
84
+ parser (>= 3.3.7.2)
85
+ prism (~> 1.4)
86
+ rubocop-performance (1.25.0)
87
+ lint_roller (~> 1.1)
88
+ rubocop (>= 1.75.0, < 2.0)
89
+ rubocop-ast (>= 1.38.0, < 2.0)
90
+ rubocop-rake (0.7.1)
91
+ lint_roller (~> 1.1)
92
+ rubocop (>= 1.72.1)
93
+ rubocop-rspec (3.6.0)
94
+ lint_roller (~> 1.1)
95
+ rubocop (~> 1.72, >= 1.72.1)
96
+ ruby-progressbar (1.13.0)
97
+ securerandom (0.4.1)
98
+ simplecov (0.22.0)
99
+ docile (~> 1.1)
100
+ simplecov-html (~> 0.11)
101
+ simplecov_json_formatter (~> 0.1)
102
+ simplecov-html (0.13.1)
103
+ simplecov_json_formatter (0.1.4)
104
+ standard (1.49.0)
105
+ language_server-protocol (~> 3.17.0.2)
106
+ lint_roller (~> 1.0)
107
+ rubocop (~> 1.75.2)
108
+ standard-custom (~> 1.0.0)
109
+ standard-performance (~> 1.8)
110
+ standard-custom (1.0.2)
111
+ lint_roller (~> 1.0)
112
+ rubocop (~> 1.50)
113
+ standard-performance (1.8.0)
114
+ lint_roller (~> 1.1)
115
+ rubocop-performance (~> 1.25.0)
116
+ thor (1.3.2)
117
+ tzinfo (2.0.6)
118
+ concurrent-ruby (~> 1.0)
119
+ unicode-display_width (3.1.4)
120
+ unicode-emoji (~> 4.0, >= 4.0.4)
121
+ unicode-emoji (4.0.4)
122
+ yard (0.9.37)
123
+
124
+ PLATFORMS
125
+ arm64-darwin-22
126
+ arm64-darwin-23
127
+ x86_64-linux
128
+
129
+ DEPENDENCIES
130
+ bundler-audit
131
+ head_music!
132
+ kramdown
133
+ rake (~> 13.0)
134
+ rspec (~> 3.0)
135
+ rspec-its (~> 1.2)
136
+ rubocop
137
+ rubocop-rake
138
+ rubocop-rspec
139
+ simplecov
140
+ standard
141
+ yard
142
+
143
+ RUBY VERSION
144
+ ruby 3.3.0p0
145
+
146
+ BUNDLED WITH
147
+ 2.4.12
data/README.md CHANGED
@@ -1,10 +1,19 @@
1
1
  # HeadMusic
2
2
 
3
- ![Build status](https://circleci.com/gh/roberthead/head_music.svg?style=shield&circle-token=8b39a6f5e809e9baa321e0f13aa06c70c6511794)
4
- [![Code Climate](https://codeclimate.com/github/roberthead/head_music/badges/gpa.svg)](https://codeclimate.com/github/roberthead/head_music)
5
- [![Test Coverage](https://codeclimate.com/github/roberthead/head_music/badges/coverage.svg)](https://codeclimate.com/github/roberthead/head_music/coverage)
3
+ [![CI](https://github.com/roberthead/head_music/workflows/CI/badge.svg)](https://github.com/roberthead/head_music/actions)
4
+ [![Security](https://github.com/roberthead/head_music/workflows/Security/badge.svg)](https://github.com/roberthead/head_music/actions)
5
+ [![Gem Version](https://badge.fury.io/rb/head_music.svg)](https://badge.fury.io/rb/head_music)
6
+ [![Documentation](https://img.shields.io/badge/docs-yard-blue.svg)](https://rubydoc.info/gems/head_music)
6
7
 
7
- The *head_music* ruby gem models the elements of western music theory, such as note names, scales, key signatures, intervals, and chords.
8
+ The **head_music** Ruby gem provides a toolkit for working with Western music theory. Model and manipulate the fundamental elements of music including pitches, scales, key signatures, intervals, and chords.
9
+
10
+ ## Features
11
+
12
+ - **Western Music Theory Fundamentals**: Work with pitches, scales, intervals, chords, and key signatures
13
+ - **Musical Analysis**: Analyze harmonic progressions, voice leading, and counterpoint
14
+ - **Style Analysis**: Rules for species counterpoint and voice leading
15
+ - **Internationalization**: Support for multiple languages (English, French, German, Italian, Russian, Spanish)
16
+ - **Instrument Modeling**: Extensive database of musical instruments with ranges and properties
8
17
 
9
18
  ## Installation
10
19
 
@@ -16,27 +25,107 @@ gem 'head_music'
16
25
 
17
26
  And then execute:
18
27
 
19
- $ bundle
28
+ $ bundle install
20
29
 
21
30
  Or install it yourself as:
22
31
 
23
32
  $ gem install head_music
24
33
 
25
- ## Usage
34
+ ## Quick Start
35
+
36
+ ```ruby
37
+ require 'head_music'
38
+
39
+ # Work with pitches and intervals
40
+ pitch = HeadMusic::Rudiment::Pitch.get('C4')
41
+ higher_pitch = HeadMusic::Rudiment::Pitch.get('E4')
42
+ interval = HeadMusic::Analysis::DiatonicInterval.new(pitch, higher_pitch)
43
+ puts interval.name # => "major third"
44
+
45
+ # Create scales
46
+ scale = HeadMusic::Rudiment::Scale.get('C', :major)
47
+ puts scale.pitches.map(&:to_s) # => ["C4", "D4", "E4", "F4", "G4", "A4", "B4"]
48
+
49
+ # Analyze chords
50
+ pitches = %w[C4 E4 G4].map { |p| HeadMusic::Rudiment::Pitch.get(p) }
51
+ chord = HeadMusic::Analysis::PitchSet.new(pitches)
52
+ puts chord.major_triad? # => true
53
+ ```
54
+
55
+ ## Documentation
56
+
57
+ - **API Documentation**: [rubydoc.info/gems/head_music](https://rubydoc.info/gems/head_music)
58
+ - **Contributing Guide**: [CONTRIBUTING.md](CONTRIBUTING.md)
59
+ - **Changelog**: [CHANGELOG.md](CHANGELOG.md)
26
60
 
27
- HeadMusic can be used as a foundation to build larger applications that notate, analyze, play, or generate music in the language of music theory.
61
+ ## Requirements
62
+
63
+ - Ruby 3.3.0 or higher
64
+ - ActiveSupport 7.0+
28
65
 
29
66
  ## Development
30
67
 
31
- After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
68
+ After checking out the repo, run `bin/setup` to install dependencies.
69
+
70
+ ### Running Tests
71
+
72
+ ```bash
73
+ # Run all tests
74
+ bundle exec rspec
75
+
76
+ # Run tests with coverage
77
+ bundle exec rake
78
+
79
+ # Run quality checks (tests + linting + security)
80
+ bundle exec rake quality
81
+ ```
82
+
83
+ ### Code Quality
84
+
85
+ ```bash
86
+ # Run linting
87
+ bundle exec rubocop
32
88
 
33
- 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).
89
+ # Run security audit
90
+ bundle exec rake bundle:audit:check
91
+
92
+ # Generate documentation
93
+ bundle exec rake doc
94
+ ```
95
+
96
+ ### Available Rake Tasks
97
+
98
+ - `rake spec` - Run tests
99
+ - `rake quality` - Run tests, linting, and security audit
100
+ - `rake doc` - Generate YARD documentation
101
+ - `rake doc_stats` - Show documentation coverage statistics
102
+ - `rake coverage` - Open coverage report in browser
34
103
 
35
104
  ## Contributing
36
105
 
37
- Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/head_music. 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.
106
+ We welcome contributions! Please see our [Contributing Guide](CONTRIBUTING.md) for details.
38
107
 
108
+ ## Project Structure
109
+
110
+ ```
111
+ lib/head_music/
112
+ ├── analysis/ # Musical analysis tools (intervals, chords, etc.)
113
+ ├── content/ # Musical content (compositions, voices, notes)
114
+ ├── instruments/ # Instrument definitions and properties
115
+ ├── rudiment/ # Basic music theory elements (pitches, scales, etc.)
116
+ └── style/ # Style analysis and composition rules
117
+ ```
118
+
119
+ ## Code of Conduct
120
+
121
+ This project is intended to be a safe, welcoming space for collaboration. Contributors are expected to adhere to our [Code of Conduct](CODE_OF_CONDUCT.md).
39
122
 
40
123
  ## License
41
124
 
42
- The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
125
+ The gem is available as open source under the terms of the [MIT License](LICENSE.txt).
126
+
127
+ ## Support
128
+
129
+ - **Issues**: [GitHub Issues](https://github.com/roberthead/head_music/issues)
130
+ - **Discussions**: [GitHub Discussions](https://github.com/roberthead/head_music/discussions)
131
+ - **Security**: For security issues, please email [robert.head@gmail.com](mailto:robert.head@gmail.com)
data/Rakefile CHANGED
@@ -4,9 +4,39 @@ require "standard/rake"
4
4
 
5
5
  RSpec::Core::RakeTask.new(:spec)
6
6
 
7
+ begin
8
+ require "yard"
9
+ YARD::Rake::YardocTask.new(:doc) do |t|
10
+ t.files = ["lib/**/*.rb"]
11
+ t.options = %w[--protected --private]
12
+ end
13
+
14
+ desc "Generate documentation and show stats"
15
+ task :doc_stats => :doc do
16
+ sh "yard stats --list-undoc"
17
+ end
18
+ rescue LoadError
19
+ # YARD not available
20
+ end
21
+
22
+ begin
23
+ require "bundler/audit/task"
24
+ Bundler::Audit::Task.new
25
+ rescue LoadError
26
+ # bundler-audit not available
27
+ end
28
+
7
29
  task default: :spec
8
30
 
31
+ desc "Run all quality checks (tests, linting, security audit)"
32
+ task :quality => [:spec, :standard, "bundle:audit:check"]
33
+
9
34
  desc "Open an irb session preloaded with this library"
10
35
  task :console do
11
36
  sh "irb -I lib -r head_music.rb"
12
37
  end
38
+
39
+ desc "Open coverage report in browser"
40
+ task :coverage do
41
+ sh "open coverage/index.html" if File.exist?("coverage/index.html")
42
+ end
data/head_music.gemspec CHANGED
@@ -8,11 +8,20 @@ Gem::Specification.new do |spec|
8
8
  spec.authors = ["Rob Head"]
9
9
  spec.email = ["robert.head@gmail.com"]
10
10
 
11
- spec.summary = "The rudiments of western music theory."
11
+ spec.summary = "The rudiments of western music theory and analysis."
12
12
  spec.description = "Work with the elements of western music theory, such as pitches, scales, intervals, and chords."
13
13
  spec.homepage = "https://github.com/roberthead/head_music"
14
14
  spec.license = "MIT"
15
15
 
16
+ spec.metadata = {
17
+ "homepage_uri" => spec.homepage,
18
+ "source_code_uri" => "https://github.com/roberthead/head_music",
19
+ "changelog_uri" => "https://github.com/roberthead/head_music/blob/main/CHANGELOG.md",
20
+ "documentation_uri" => "https://rubydoc.info/gems/head_music",
21
+ "bug_tracker_uri" => "https://github.com/roberthead/head_music/issues",
22
+ "rubygems_mfa_required" => "true"
23
+ }
24
+
16
25
  spec.files = `git ls-files -z`.split("\x0").reject do |f|
17
26
  f.match(%r{^(test|spec|features)/}) || f.match(/\.gem$/)
18
27
  end
@@ -21,7 +30,7 @@ Gem::Specification.new do |spec|
21
30
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
22
31
  spec.require_paths = ["lib"]
23
32
 
24
- spec.required_ruby_version = ">= 3.0"
33
+ spec.required_ruby_version = ">= 3.3.0"
25
34
 
26
35
  spec.add_runtime_dependency "activesupport", "~> 7.0"
27
36
  spec.add_runtime_dependency "humanize", "~> 2.0"
@@ -30,4 +39,6 @@ Gem::Specification.new do |spec|
30
39
  spec.add_development_dependency "rake", "~> 13.0"
31
40
  spec.add_development_dependency "rspec", "~> 3.0"
32
41
  spec.add_development_dependency "rspec-its", "~> 1.2"
42
+ spec.add_development_dependency "bundler-audit", "~> 0.9"
43
+ spec.add_development_dependency "yard", "~> 0.9"
33
44
  end
@@ -73,7 +73,7 @@ class HeadMusic::Analysis::DiatonicInterval
73
73
  end
74
74
 
75
75
  def spans?(pitch)
76
- pitch >= lower_pitch && pitch <= higher_pitch
76
+ pitch.between?(lower_pitch, higher_pitch)
77
77
  end
78
78
 
79
79
  def quality
@@ -110,7 +110,7 @@ class HeadMusic::Analysis::Sonority
110
110
  alias_method :quintal?, :quartal?
111
111
 
112
112
  def diatonic_intervals_above_bass_pitch
113
- return nil unless identifier
113
+ return [] unless identifier
114
114
 
115
115
  @diatonic_intervals_above_bass_pitch ||=
116
116
  SONORITIES[identifier].map { |shorthand| HeadMusic::Analysis::DiatonicInterval.get(shorthand) }
@@ -8,12 +8,22 @@ class HeadMusic::Content::Staff
8
8
  attr_reader :default_clef, :line_count, :instrument
9
9
 
10
10
  def initialize(default_clef_key, instrument: nil, line_count: nil)
11
- @default_clef = HeadMusic::Rudiment::Clef.get(default_clef_key)
12
- @line_count = line_count || DEFAULT_LINE_COUNT
13
11
  @instrument = HeadMusic::Instruments::Instrument.get(instrument) if instrument
12
+ begin
13
+ @default_clef = HeadMusic::Rudiment::Clef.get(default_clef_key)
14
+ rescue KeyError, NoMethodError
15
+ puts("Warning: Clef '#{default_clef_key}' not found.")
16
+ if @instrument
17
+ puts("Using instrument clef.")
18
+ @default_clef = @instrument.default_staves.first.clef
19
+ else
20
+ @default_clef = HeadMusic::Rudiment::Clef.get(:treble_clef)
21
+ end
22
+ end
23
+ @line_count = line_count || DEFAULT_LINE_COUNT
14
24
  end
15
25
 
16
26
  def clef
17
- default_clef || instrument&.default_staves&.first&.clef
27
+ default_clef
18
28
  end
19
29
  end
@@ -110,6 +110,14 @@ class HeadMusic::Content::Voice
110
110
  placements.last.position.bar_number
111
111
  end
112
112
 
113
+ def last_placement
114
+ placements.last
115
+ end
116
+
117
+ def next_position
118
+ last_placement ? last_placement.next_position : HeadMusic::Content::Position.new(composition, 1, 1, 0)
119
+ end
120
+
113
121
  def to_s
114
122
  return pitches_string if role.to_s.strip == ""
115
123
 
@@ -82,9 +82,7 @@ class HeadMusic::Instruments::Instrument
82
82
  variants.find(&:default?) || variants.first
83
83
  end
84
84
 
85
- def default_staff_scheme
86
- default_variant&.default_staff_scheme
87
- end
85
+ delegate :default_staff_scheme, to: :default_variant
88
86
 
89
87
  def default_staves
90
88
  default_staff_scheme&.staves || []