Module: Lydown::Lilypond
- Defined in:
- lib/lydown/lilypond.rb
Constant Summary collapse
- MINIMAL_LILYPOND_VERSION =
Gem::Version.new('2.18')
- RESET_ENV =
In order to be able to run the lyp lilypond wrapper (if present), we need to reset the environment variables set by bundler when running lydown.
{ "_ORIGINAL_GEM_PATH" => "", "BUNDLE_GEMFILE" => "", "BUNDLE_BIN_PATH" => "", "RUBYOPT" => "", "RUBYLIB" => "" }
- LILYPOND_STATUS_LINES =
%w{ Processing Parsing Interpreting Preprocessing Finding Fitting Drawing Layout Converting Success: }
- STATUS_TOTAL =
LILYPOND_STATUS_LINES.size
Class Method Summary collapse
- .compile(source, opts = {}) ⇒ Object
- .copy_pages(source, target, ext) ⇒ Object
-
.detect_lilypond_version(exit_on_error) ⇒ Object
detect the lilypond version.
- .display_lilypond_version_error_msg(version) ⇒ Object
- .exec(wait_thr, input, output, opts) ⇒ Object
- .format_cmd(opts, source_path) ⇒ Object
-
.invoke(source, opts = {}) ⇒ Object
Run lilypond, pipe source into its STDIN, and capture its STDERR.
-
.invoke_with_tempfile(source, opts) ⇒ Object
Compile into a tempfile.
- .lilypond_path ⇒ Object
- .read_lilypond_progress(f, opts) ⇒ Object
- .tmpdir ⇒ Object
Class Method Details
.compile(source, opts = {}) ⇒ Object
59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 |
# File 'lib/lydown/lilypond.rb', line 59 def compile(source, opts = {}) opts[:output_target] ||= 'lydown' if opts[:temp] opts[:output_filename] = opts[:output_target] invoke(source, opts) else invoke_with_tempfile(source, opts) end rescue CompilationAbortError => e raise e rescue => e $stderr.puts e. $stderr.puts e.backtrace.join("\n") unless e.is_a?(LydownError) raise e end |
.copy_pages(source, target, ext) ⇒ Object
101 102 103 104 105 106 107 108 109 110 111 112 |
# File 'lib/lydown/lilypond.rb', line 101 def copy_pages(source, target, ext) page = 1 loop do source_fn = source + "-page#{page}" + ext break unless File.file?(source_fn) target_fn = target.dup.insert(target.index(/\.[^\.]+$/), "-page#{page}") FileUtils.cp(source_fn, target_fn) page += 1 end end |
.detect_lilypond_version(exit_on_error) ⇒ Object
detect the lilypond version. If lilypond is not found, or the version is less than the minimal supported version, display an error message.
27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
# File 'lib/lydown/lilypond.rb', line 27 def detect_lilypond_version(exit_on_error) version = nil if path = lilypond_path msg = `#{lilypond_path} --version` if msg.lines.first =~ /LilyPond ([\d\.]+)/ version = $1 end end unless version && Gem::Version.new(version) >= MINIMAL_LILYPOND_VERSION display_lilypond_version_error_msg(version) exit!(1) if exit_on_error version = nil end version rescue => e display_lilypond_version_error_msg(nil) exit!(1) if exit_on_error end |
.display_lilypond_version_error_msg(version) ⇒ Object
47 48 49 50 51 52 53 |
# File 'lib/lydown/lilypond.rb', line 47 def display_lilypond_version_error_msg(version) if version STDERR.puts "ERROR: The installed lilypond (version #{version}) is too old." else STDERR.puts "ERROR: No copy of lilypond found." end end |
.exec(wait_thr, input, output, opts) ⇒ Object
165 166 167 168 169 170 171 172 173 |
# File 'lib/lydown/lilypond.rb', line 165 def exec(wait_thr, input, output, opts) Lydown::CLI.register_abortable_process(wait_thr.pid) input.close_write err_info = read_lilypond_progress(output, opts) output.close err_info ensure Lydown::CLI.unregister_abortable_process(wait_thr.pid) end |
.format_cmd(opts, source_path) ⇒ Object
150 151 152 153 154 155 156 157 158 159 160 161 162 163 |
# File 'lib/lydown/lilypond.rb', line 150 def format_cmd(opts, source_path) format = opts[:format] format = nil if (format == :midi) || (format == :mp3) cmd = "#{lilypond_path} " # cmd << "-dbackend=eps " if opts[:mode] == :proof cmd << "-o #{opts[:output_filename]} " cmd << "-dno-point-and-click " cmd << "--#{opts[:format]} " if format cmd << "-V " if opts[:verbose] cmd << source_path cmd end |
.invoke(source, opts = {}) ⇒ Object
Run lilypond, pipe source into its STDIN, and capture its STDERR
126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 |
# File 'lib/lydown/lilypond.rb', line 126 def invoke(source, opts = {}) tmp_source_path = Tempfile.new('lydown').path File.open(tmp_source_path, 'w') {|f| f << source} cmd = format_cmd(opts, tmp_source_path) puts cmd if opts[:verbose] err_info = '' exit_value = nil Open3.popen2e(RESET_ENV, cmd) do |input, output, wait_thr| err_info = exec(wait_thr, input, output, opts) exit_value = wait_thr.value end if exit_value != 0 if exit_value.termsig raise CompilationAbortError else # err_info = err_info.lines[0, 3].join raise LydownError, "Lilypond compilation failed:\n#{err_info}" end end end |
.invoke_with_tempfile(source, opts) ⇒ Object
Compile into a tempfile. We do this because lilypond’s behavior when supplied with target filenames is broken. If it is given a target path which corresponds to an existing directory name, it does not use the specified path plus extension, but instead creates a file inside the directory.
82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 |
# File 'lib/lydown/lilypond.rb', line 82 def invoke_with_tempfile(source, opts) target = opts[:output_target].dup ext = ".#{opts[:format] || :pdf}" if target !~ /#{ext}$/ target << ext end tmp_target = Tempfile.new('lydown').path opts[:output_filename] = tmp_target invoke(source, opts) # Copy tempfile to target if File.file?(tmp_target + ext) FileUtils.cp(tmp_target + ext, target) else copy_pages(tmp_target, target, ext) end end |
.lilypond_path ⇒ Object
14 15 16 17 18 19 20 21 22 23 |
# File 'lib/lydown/lilypond.rb', line 14 def lilypond_path # detect lyp-installed lilypond # path = `lyp which lilypond`.lines.last rescue nil # return path.chomp if path # # path = `which lilypond` rescue nil # return path.chomp if path && !path.empty? return 'lilypond' end |
.read_lilypond_progress(f, opts) ⇒ Object
189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 |
# File 'lib/lydown/lilypond.rb', line 189 def read_lilypond_progress(f, opts) info = '' if !opts[:verbose] && !opts[:no_progress_bar] Lydown::CLI::show_progress('Compile', STATUS_TOTAL) do || while !f.eof? line = f.gets info += line if line =~ /^([^\s]+)/ idx = LILYPOND_STATUS_LINES.index($1) .progress = idx + 1 if idx end end .progress = STATUS_TOTAL end elsif opts[:verbose] while !f.eof? line = f.gets STDERR.puts line info += line end else info = f.read end info end |
.tmpdir ⇒ Object
55 56 57 |
# File 'lib/lydown/lilypond.rb', line 55 def tmpdir @tmpdir ||= Dir.mktmpdir end |