LilyPond-Ruby 0.0.2.1 → 0.1.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a5c247479c72432681e120f021e8f7bc478fd98d1307e0258bd083f2f04fd604
4
- data.tar.gz: 39f4325ab9da401e2856c68577ce5acc7159189ae3dc6ea8e4097779bd096d44
3
+ metadata.gz: dd7caa18b5b13373b5d316f0b09ad3575131816a2a5c3190c4b4564cf5ebd3da
4
+ data.tar.gz: fe45f4258930993b960751c9c25157f695aa822ba651fd66c331dbf03faae8a8
5
5
  SHA512:
6
- metadata.gz: dae1def60d5a8d81ef598625f3067b644a58aadff548bea017ad8e90b02c589033739b687add9f0f26ecb5e0650fa38ff8350815efdde2409367c69543f90da7
7
- data.tar.gz: 8cdf10c843a017db7f9b0d87cda082af7a329501f16f9b47250a8c5df473350667bdd19f2c1ba669af98051c0e97d03f4bd02df8e4f67a6c8bf5ebcab4ea48be
6
+ metadata.gz: 2430168be722d01a3a1cb3d6e79d146a86a8e2790d0a1b875e2fc1a23b2778c7b0a6c4cddd2dd2ca4912b9996c05168b1252a80131513a2e55d627172031fb08
7
+ data.tar.gz: cdf33ac9fd098add59a5050d0fe95f13ef09b0f3e2bf1d957e71bcc175d9741e76900a1f4f17e36555d261dc467d7a47fcee5d5333c897e5a0006eee0750eff1
data/lib/guile.rb ADDED
@@ -0,0 +1,19 @@
1
+ require 'ffi'
2
+
3
+ module Guile
4
+ extend FFI::Library
5
+
6
+ # Load the Guile shared library
7
+ ffi_lib 'libguile-2.2.so.1'
8
+
9
+ # Define the Guile functions we want to call
10
+ attach_function :scm_init_guile, [:int], :void
11
+ attach_function :scm_c_eval_string, [:string], :void
12
+ end
13
+
14
+ # Initialize Guile
15
+ Guile.scm_init_guile(0)
16
+
17
+ # Evaluate a Guile script
18
+ Guile.scm_c_eval_string('(display "Hello, Guile!")')
19
+ puts "\n"
@@ -0,0 +1,161 @@
1
+ require_relative "../lilypond-ruby.rb"
2
+
3
+ # The LilyPond class provides an interface for generating LilyPond notation.
4
+ class LilyPond
5
+ # The Builder class is responsible for building LilyPond notation.
6
+ class Builder
7
+ # Creates a new LilyPond Builder object.
8
+ def initialize
9
+ @buffer = "\\version \"#{LilyPond.version_number}\"\n"
10
+ @indent_level = 0
11
+ end
12
+
13
+ # Returns the current indentation level.
14
+ #
15
+ # @return [String] the current indentation level in spaces
16
+ def indent
17
+ " " * @indent_level * 2
18
+ end
19
+
20
+ # Generates a block of LilyPond notation.
21
+ #
22
+ # @param name [String] the name of the block
23
+ # @param parallel [Boolean] whether the block should be parallel
24
+ # @param options [Hash] the options for the block
25
+ # @yield the block content
26
+ def block(name = nil, parallel = false, options = {})
27
+ @buffer << "#{indent}"
28
+ @buffer << "\\#{name} " unless name == nil
29
+ if options.any?
30
+ @buffer << "\\with { \n"
31
+ @indent_level +=1
32
+ options.each do |key, value|
33
+ @buffer << "#{indent}#{key.to_s.camelize_lower} = #"
34
+ @buffer << (value.class.name == "String" ? "\"#{value}\"" : "#{value}")
35
+ @buffer << "\n"
36
+ end
37
+ @indent_level -=1
38
+ @buffer << "#{indent}} "
39
+ end
40
+ @buffer << "#{parallel ? "<<" : "{" }"
41
+ if block_given?
42
+ @buffer << "\n"
43
+ @indent_level += 1
44
+ yield
45
+ @indent_level -= 1
46
+ @buffer << "#{indent}#{parallel ? ">>" : "}" }\n"
47
+ else
48
+ @buffer << "#{parallel ? ">>" : "}" }\n"
49
+ end
50
+ end
51
+
52
+ # Defines the content for a LilyPond variable.
53
+ #
54
+ # @param variable_name [String] the name of the variable
55
+ # @param lyricmode [Boolean] whether the variable should be in lyric mode
56
+ # @yield the variable content
57
+ def define_content(variable_name = nil, lyricmode = false)
58
+ @buffer << "#{indent}"
59
+ @buffer << "#{variable_name} = " unless variable_name.nil?
60
+ @buffer << "\\lyricmode " if lyricmode
61
+ @buffer << "{\n"
62
+ @indent_level += 1
63
+ yield
64
+ @indent_level -= 1
65
+ @buffer << "}\n"
66
+ end
67
+
68
+ # Uses the content of a LilyPond variable.
69
+ #
70
+ # @param variable_name [String] the name of the variable to use
71
+ def use_content(variable_name)
72
+ @buffer << "#{indent}\\#{variable_name}\n"
73
+ end
74
+
75
+ # Appends a string of LilyPond notation to the buffer.
76
+ #
77
+ # @param string [String] the LilyPond notation to append
78
+ def append(string)
79
+ @buffer << "#{indent}#{string}\n"
80
+ end
81
+
82
+ # Returns the current buffer as a string of LilyPond notation.
83
+ #
84
+ # @return [String] the LilyPond notation buffer
85
+ def to_s
86
+ @buffer
87
+ end
88
+
89
+ class << self
90
+ # Generates a sample LilyPond notation.
91
+ #
92
+ # @return [LilyPond::Builder] the LilyPond notation builder
93
+ def sample
94
+ parallel = true
95
+ options = {
96
+ :midi_maximum_volume => 0.4,
97
+ :instrument_name => "Piano"
98
+ }
99
+ ly = LilyPond::Builder.new
100
+
101
+ ly.append "%% MUSIC %%"
102
+ ly.define_content("global") do |global|
103
+ ly.append "\\numericTimeSignature"
104
+ ly.append "\\time 4/4"
105
+ ly.append "s1 * 4 |"
106
+ ly.append "\\bar \"|.\""
107
+ end #global
108
+ ly.define_content("sopranoMusic") do |sopranoMusic|
109
+ ly.append "c'4 d'4 e'4 f'4 |"
110
+ ly.append "c'4 d'4 e'4 f'4 |"
111
+ ly.append "c'4 d'4 e'4 f'4 |"
112
+ ly.append "c'4 d'4 e'4 f'4 |"
113
+ end #sopranoMusic
114
+ ly.append "%% LYRICS %%"
115
+ ly.define_content("sopranoLyrics", true) do |sopranoLyrics|
116
+ ly.append "do re me fa"
117
+ ly.append "do re me fa"
118
+ ly.append "do re me fa"
119
+ ly.append "do re me fa"
120
+ end #sopranoLyrics
121
+ ly.append "%% BOOKS %%"
122
+ ly.block("book") do |book|
123
+ ly.block("score") do |score|
124
+ ly.block(nil, parallel) do |score_content|
125
+ ly.block("new Staff", parallel, options) do |staff|
126
+ ly.block("new Voice", parallel) do |voice|
127
+ ly.use_content("global")
128
+ ly.use_content("sopranoMusic")
129
+ end #voice
130
+ ly.block("new Lyrics") do |lyrics|
131
+ ly.use_content("sopranoLyrics")
132
+ end #lyrics
133
+ end #staff
134
+ end #score_content
135
+ ly.block("midi")
136
+ ly.block("layout")
137
+ end #score
138
+ end #book
139
+
140
+ return ly
141
+ end #sample()
142
+
143
+ end #self
144
+ end #Builder
145
+ end #LilyPond
146
+
147
+ # Adds a `camelize_lower` method to the String class.
148
+ class String
149
+ # Converts an underscored string to camel case, except the first word remains downcase.
150
+ #
151
+ # Examples
152
+ #
153
+ # "my_foo".camelize_lower #=> "myFoo"
154
+ #
155
+ # @return [String] the camelized string
156
+ def camelize_lower
157
+ self.split('_').map.with_index do |word, i|
158
+ i == 0 ? word.downcase : word.capitalize
159
+ end.join('')
160
+ end
161
+ end
data/lib/lilypond-ruby.rb CHANGED
@@ -1,11 +1,13 @@
1
1
  require "open3"
2
+ require "lilypond/builder"
3
+ require "guile"
2
4
 
3
5
  class LilyPond
4
- LYPATH = File.expand_path("../../bin/lilypond", __FILE__)
6
+ LILYPOND_PATH = File.expand_path("../../bin/lilypond", __FILE__)
5
7
  class << self
6
8
 
7
9
  def version
8
- output, error, status = Open3.capture3(LYPATH, "--version")
10
+ output, error, status = Open3.capture3(LILYPOND_PATH, "--version")
9
11
  if status.success?
10
12
  puts output
11
13
  else
@@ -13,8 +15,20 @@ class LilyPond
13
15
  end
14
16
  end
15
17
 
18
+ def version_number
19
+ output, error, status = Open3.capture3(LILYPOND_PATH, "--version")
20
+ if status.success?
21
+ return output.match(/GNU LilyPond (\d+\.\d+\.\d+)/)[1]
22
+ else
23
+ return "#{error}"
24
+ end
25
+ end
26
+
16
27
  def generate_pdf_with_lilypond(file_name, lilypond_code)
17
- Open3.popen3(LYPATH, '--pdf', file_name) do |stdin, stdout, stderr, wait_thr|
28
+ tempfile = Tempfile.new(file_name)
29
+ tempfile.write(lilypond_code)
30
+ tempfile.close
31
+ Open3.popen3(LILYPOND_PATH, "--pdf", tempfile.path) do |stdin, stdout, stderr, wait_thr|
18
32
  # Write the Lilypond code to stdin
19
33
  stdin.write(lilypond_code)
20
34
  stdin.close
@@ -42,6 +56,7 @@ class LilyPond
42
56
  break
43
57
  end
44
58
  end
59
+ File.delete(tempfile.path)
45
60
  end
46
61
 
47
62
  end # end self
metadata CHANGED
@@ -1,16 +1,38 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: LilyPond-Ruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2.1
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Lee Whittaker
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-03-03 00:00:00.000000000 Z
12
- dependencies: []
13
- description: This gem provides a library to access and control Lilypond from Ruby
11
+ date: 2023-03-08 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: ffi
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.15'
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: 1.15.5
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - "~>"
28
+ - !ruby/object:Gem::Version
29
+ version: '1.15'
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: 1.15.5
33
+ description: "This gem provides a library to access and control Lilypond within Ruby.\nIt
34
+ contains the libraries and binary files for LilyPond 2.24.1 and\nGuile 2.2.3. \n\n\nIt
35
+ also provides a builder tool for generating LilyPond files dynamically\nwith Ruby.\n"
14
36
  email: whittakerlee81@gmail.com
15
37
  executables:
16
38
  - lilypond
@@ -27,7 +49,9 @@ files:
27
49
  - bin/lilysong
28
50
  - bin/midi2ly
29
51
  - bin/musicxml2ly
52
+ - lib/guile.rb
30
53
  - lib/lilypond-ruby.rb
54
+ - lib/lilypond/builder.rb
31
55
  homepage: https://github.com/Okomikeruko/LilyPond-Ruby
32
56
  licenses:
33
57
  - MIT