lydown 0.7.1 → 0.7.2

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: 8f9e00d9938576429da9646dc782f2451c66afa9
4
- data.tar.gz: 3fe22010c7e1928c74a5278eb659dc78922a53a8
3
+ metadata.gz: 2945708b90bba8a47e9c037ed6b58feee552c411
4
+ data.tar.gz: 3fab488b2070abaa55eccd5a2d1ee2af496419af
5
5
  SHA512:
6
- metadata.gz: f18283718262a5404cb6e78ba0c155c3c0f750eaf3ddf47b3f5e6b460836980fb9019e2146bb093aa662e1da25625880fb935479e9766a47f565dd4107300516
7
- data.tar.gz: 86b12d5d519691dc54f18fcfd061eb2d26a1d403780b3e8b5d800e32278bb78250841c818f1a76d7353fd5deffc99642d2eecf960c756205b06c7389a2e72650
6
+ metadata.gz: c9a16ab91b2118d2ceed5791caa10319fac63e38bd09da38e19fb57ba52ab5ad6b3db857c811211a0e8f5d167d0f0e5b841aee06f0bb607df4cdba0cbd794b97
7
+ data.tar.gz: 25df40e9a348873a1da26969c8f8275e7f806ff4f5386657c3a1eba4acdbd7d84f4c687eb5653867973dd656acf4b9eeb59a4ce9e9da9d73894d09a609ae7123
@@ -72,7 +72,8 @@ module Lydown::CLI::Compiler
72
72
  unless File.file?(filename)
73
73
  filename = "#{opts[:output_target]}-page1.#{opts[:format]}"
74
74
  end
75
-
75
+
76
+ # Mac OSX specific probably
76
77
  system("open #{filename}")
77
78
  end
78
79
  end
@@ -42,6 +42,9 @@ module Lydown::CLI::Diff
42
42
 
43
43
  set_cached_content(path, new_version)
44
44
 
45
+ first += 1 if first
46
+ last += 1 if last
47
+
45
48
  first..last
46
49
  rescue => e
47
50
  STDERR << e.message
@@ -20,16 +20,18 @@ module Lydown::CLI::Proofing
20
20
 
21
21
  dw.reset(true)
22
22
  dw.add_observer do |*args|
23
- t = Time.now.strftime("%Y-%m-%d %H:%M:%S")
24
23
  args.each do |e|
25
24
  if e.type = :modified
26
25
  path = File.expand_path(e.path)
27
26
  if path =~ /^#{File.expand_path(source)}\/(.+)/
28
27
  path = $1
29
28
  end
30
- puts "[#{t}] Changed: #{path}"
31
29
  last_proof_path = e.path unless File.basename(e.path) == 'movement.ld'
32
- process(opts.deep_merge opts_for_path(last_proof_path, opts)) if last_proof_path
30
+ if last_proof_path
31
+ file_opts = opts.deep_merge opts_for_path(last_proof_path, opts)
32
+ file_opts[:base_path] = path
33
+ process(file_opts)
34
+ end
33
35
  end
34
36
  end
35
37
  end
@@ -44,12 +46,6 @@ module Lydown::CLI::Proofing
44
46
  def globs(path)
45
47
  Dir.chdir(path) do
46
48
  dirs = Dir['*'].select { |x| File.directory?(x) }
47
- # exclude _ly, _pdf, _midi dirs
48
- # ['ly_dir', 'pdf_dir', 'midi_dir'].map {|d| $config[d]}.each do |d|
49
- # if d =~ /^\.\/(.*)/
50
- # dirs -= [$1]
51
- # end
52
- # end
53
49
  end
54
50
 
55
51
  dirs = dirs.map { |x| "#{x}/**/*" }
@@ -87,9 +83,9 @@ module Lydown::CLI::Proofing
87
83
  end
88
84
 
89
85
  def process(opts)
90
- if opts[:line_range] == (nil..nil)
91
- puts "No change detected"
92
- else
86
+ if opts[:line_range] != (nil..nil)
87
+ t = Time.now.strftime("%H:%M:%S")
88
+ puts "[#{t}] Changed: #{opts[:base_path]} (lines #{opts[:line_range].inspect})"
93
89
  Lydown::CLI::Compiler.process(opts)
94
90
  end
95
91
  end
@@ -1,3 +1,5 @@
1
+ require 'escape_utils'
2
+
1
3
  class Hash
2
4
  # Merges self with another hash, recursively.
3
5
  #
@@ -137,6 +139,33 @@ class String
137
139
  end
138
140
  }
139
141
  end
142
+
143
+ def calculate_line_indexes
144
+ i = -1
145
+ indexes = {0 => 0}
146
+ line = 1
147
+ while i = index("\n", i + 1)
148
+ indexes[line] = i + 1 # first character after line break
149
+ line += 1
150
+ end
151
+ indexes
152
+ end
153
+
154
+ def find_line_and_column(index)
155
+ @line_indexes ||= calculate_line_indexes
156
+ line = @line_indexes.reverse_each {|l, i| break l if i <= index}
157
+
158
+ # return line and column
159
+ if line.nil?
160
+ [nil, nil]
161
+ else
162
+ [(line + 1), (index - @line_indexes[line] + 1)]
163
+ end
164
+ end
165
+
166
+ def uri_escape
167
+ EscapeUtils.escape_uri(self)
168
+ end
140
169
  end
141
170
 
142
171
  class Fixnum
@@ -49,9 +49,9 @@ module Lydown
49
49
  # Run lilypond, pipe source into its STDIN, and capture its STDERR
50
50
  cmd = 'lilypond -lERROR '
51
51
  cmd << "-o #{opts[:output_filename]} "
52
+ cmd << "-dno-point-and-click "
52
53
  cmd << "--#{opts[:format]} " if opts[:format]
53
54
  cmd << '-s - 2>&1'
54
- # cmd << "-s #{ly_path} 2>&1"
55
55
 
56
56
  err_info = ''
57
57
  IO.popen(cmd, 'r+') do |f|
@@ -15,7 +15,10 @@ class LydownParser
15
15
  STDERR.puts error_msg
16
16
  raise LydownError, error_msg
17
17
  else
18
- ast.to_stream
18
+ stream = []
19
+ # insert source ref event into stream if we have a filename ref
20
+ stream << {type: :source_ref}.merge(opts) if opts[:filename]
21
+ ast.to_stream(stream, opts)
19
22
  end
20
23
  end
21
24
 
@@ -11,7 +11,8 @@ grammar Lydown
11
11
  '=music' white_space? [\n] music ([\n] !stream_breaker music)*
12
12
  end
13
13
  rule lyrics_stream
14
- '=lyrics' stream_idx? white_space? [\n] lyrics_content ([\n] !stream_breaker lyrics_content)* <Lyrics>
14
+ '=lyrics' stream_idx? white_space? [\n] lyrics_content
15
+ ([\n] !stream_breaker lyrics_content)* <Lyrics>
15
16
  end
16
17
  rule stream_breaker
17
18
  stream_switch / stream_breaking_setting
@@ -29,7 +30,8 @@ grammar Lydown
29
30
  [^\n]* <CommentContent>
30
31
  end
31
32
  rule setting
32
- white_space? '-' white_space* setting_key ':' setting_value comment? <Setting>
33
+ white_space? '-' white_space* setting_key ':' setting_value
34
+ comment? <Setting>
33
35
  end
34
36
  rule setting_key
35
37
  [a-z0-9_]+ <Setting::Key>
@@ -44,13 +46,12 @@ grammar Lydown
44
46
  [ \t]+
45
47
  end
46
48
  rule event
47
- (inline_command / inline_lyrics / voice_selector / barline / grace_duration / duration /
48
- chord / note / standalone_figures / rest / silence / phrasing / tie) white_space*
49
+ (inline_command / inline_lyrics / voice_selector / barline / source_ref /
50
+ grace_duration / duration / chord / note / standalone_figures / rest /
51
+ silence / phrasing / tie) white_space*
49
52
  end
50
53
  rule barline
51
54
  ('?|' / ':|][|:' / '[|:' / ':|]' / [\|\.\:]+) <Barline>
52
- # ('|' / '.' / '||' / '.|' / '..' / '|.|' / '|.' /
53
- # '.|') <Barline>
54
55
  end
55
56
  rule duration
56
57
  tuplet_value / duration_value / duration_macro
@@ -83,7 +84,8 @@ grammar Lydown
83
84
  (macro_name / macro_event*) <DurationMacroExpression>
84
85
  end
85
86
  rule macro_event
86
- (duration / note_placeholder / rest / silence / phrasing / tie) white_space*
87
+ (duration / note_placeholder / rest / silence /
88
+ phrasing / tie) white_space*
87
89
  end
88
90
  rule macro_name
89
91
  [a-zA-Z_] [a-zA-Z0-9_]*
@@ -191,4 +193,13 @@ grammar Lydown
191
193
  rule voice_selector
192
194
  [1234u] ':' <VoiceSelector>
193
195
  end
196
+ rule source_ref
197
+ '{' source_line ':' source_column '}' <SourceRef>
198
+ end
199
+ rule source_line
200
+ [\d]+ <SourceRef::Line>
201
+ end
202
+ rule source_column
203
+ [\d]+ <SourceRef::Column>
204
+ end
194
205
  end
@@ -1,22 +1,44 @@
1
1
  module Lydown::Parsing
2
2
  module Root
3
- def _to_stream(element, stream)
3
+ def _to_stream(element, stream, opts)
4
4
  if element.elements
5
5
  element.elements.each do |e|
6
- e.respond_to?(:to_stream) ? e.to_stream(stream) : _to_stream(e, stream)
6
+ e.respond_to?(:to_stream) ?
7
+ e.to_stream(stream, opts) :
8
+ _to_stream(e, stream, opts)
7
9
  end
8
10
  end
9
11
  stream
10
12
  end
11
-
12
- def to_stream(stream = [])
13
- _to_stream(self, stream)
13
+
14
+ def to_stream(stream = [], opts = {})
15
+ _to_stream(self, stream, opts)
14
16
  stream
15
17
  end
18
+
19
+ def event_hash(stream, opts, hash = {})
20
+ if source = opts[:source]
21
+ last = stream.last
22
+ if last && last[:type] == :source_ref && last[:line]
23
+ line, column = last[:line], last[:column]
24
+ else
25
+ line, column = source.find_line_and_column(interval.first)
26
+ end
27
+
28
+ hash.merge({
29
+ filename: opts[:filename],
30
+ source: source,
31
+ line: line,
32
+ column: column
33
+ })
34
+ else
35
+ hash
36
+ end
37
+ end
16
38
  end
17
39
 
18
40
  module CommentContent
19
- def to_stream(stream)
41
+ def to_stream(stream, opts)
20
42
  stream << {type: :comment, content: text_value.strip}
21
43
  end
22
44
  end
@@ -24,28 +46,30 @@ module Lydown::Parsing
24
46
  module Setting
25
47
  include Root
26
48
 
27
- def to_stream(stream)
49
+ def to_stream(stream, opts)
28
50
  level = (text_value =~ /^([\s]+)/) ? ($1.length / 2) : 0
29
- @setting = {type: :setting, level: level}
30
- _to_stream(self, stream)
51
+ @setting = event_hash(stream, opts, {
52
+ type: :setting, level: level
53
+ })
54
+ _to_stream(self, stream, opts)
31
55
  end
32
-
56
+
33
57
  def setting
34
58
  @setting
35
59
  end
36
-
60
+
37
61
  def emit_setting(stream)
38
62
  stream << @setting
39
63
  end
40
64
 
41
65
  module Key
42
- def to_stream(stream)
66
+ def to_stream(stream, opts)
43
67
  parent.setting[:key] = text_value
44
68
  end
45
69
  end
46
70
 
47
71
  module Value
48
- def to_stream(stream)
72
+ def to_stream(stream, opts)
49
73
  parent.setting[:value] = text_value.strip
50
74
  parent.emit_setting(stream)
51
75
  end
@@ -53,13 +77,19 @@ module Lydown::Parsing
53
77
  end
54
78
 
55
79
  module DurationValue
56
- def to_stream(stream)
57
- stream << {type: :duration, value: text_value}
80
+ include Root
81
+
82
+ def to_stream(stream, opts)
83
+ stream << event_hash(stream, opts, {
84
+ type: :duration, value: text_value
85
+ })
58
86
  end
59
87
  end
60
88
 
61
89
  module TupletValue
62
- def to_stream(stream)
90
+ include Root
91
+
92
+ def to_stream(stream, opts)
63
93
  if text_value =~ /^(\d+)%((\d+)\/(\d+))?$/
64
94
  value, fraction, group_length = $1, $2, $4
65
95
  unless fraction
@@ -67,26 +97,30 @@ module Lydown::Parsing
67
97
  group_length = '2'
68
98
  end
69
99
 
70
- stream << {
100
+ stream << event_hash(stream, opts, {
71
101
  type: :tuplet_duration,
72
102
  value: value,
73
103
  fraction: fraction,
74
104
  group_length: group_length
75
- }
105
+ })
76
106
  end
77
107
  end
78
108
  end
79
109
 
80
110
  module GraceDuration
111
+ include Root
112
+
81
113
  GRACE_KIND = {
82
114
  nil => :grace,
83
115
  '/' => :acciaccatura,
84
116
  '^' => :appoggiatura
85
117
  }
86
118
 
87
- def to_stream(stream)
119
+ def to_stream(stream, opts)
88
120
  if text_value =~ /^\$([\/\^])?(\d+)$/
89
- stream << {type: :grace, value: $2, kind: GRACE_KIND[$1]}
121
+ stream << event_hash(stream, opts, {
122
+ type: :grace, value: $2, kind: GRACE_KIND[$1]
123
+ })
90
124
  end
91
125
  end
92
126
  end
@@ -94,14 +128,16 @@ module Lydown::Parsing
94
128
  module Note
95
129
  include Root
96
130
 
97
- def to_stream(stream)
98
- note = {type: :note, raw: text_value}
99
- _to_stream(self, note)
131
+ def to_stream(stream, opts)
132
+ note = event_hash(stream, opts, {
133
+ type: :note, raw: text_value
134
+ })
135
+ _to_stream(self, note, opts)
100
136
  stream << note
101
137
  end
102
138
 
103
139
  module Head
104
- def to_stream(note)
140
+ def to_stream(note, opts)
105
141
  # remove octave marks from note head (this is only in case the order
106
142
  # accidental-octave was reversed)
107
143
  head = text_value.gsub(/[',]+/) {|m| note[:octave] = m; ''}
@@ -110,19 +146,19 @@ module Lydown::Parsing
110
146
  end
111
147
 
112
148
  module Octave
113
- def to_stream(note)
149
+ def to_stream(note, opts)
114
150
  note[:octave] = text_value
115
151
  end
116
152
  end
117
153
 
118
154
  module AccidentalFlag
119
- def to_stream(note)
155
+ def to_stream(note, opts)
120
156
  note[:accidental_flag] = text_value
121
157
  end
122
158
  end
123
159
 
124
160
  module Expression
125
- def to_stream(note)
161
+ def to_stream(note, opts)
126
162
  note[:expressions] ||= []
127
163
  note[:expressions] << text_value
128
164
  end
@@ -132,15 +168,17 @@ module Lydown::Parsing
132
168
  module Chord
133
169
  include Root
134
170
 
135
- def to_stream(stream)
136
- chord = {type: :chord, notes: []}
137
- _to_stream(self, chord[:notes])
171
+ def to_stream(stream, opts)
172
+ chord = event_hash(stream, opts, {
173
+ type: :chord, notes: []
174
+ })
175
+ _to_stream(self, chord[:notes], opts)
138
176
  stream << chord
139
177
  end
140
178
  end
141
179
 
142
180
  module FiguresComponent
143
- def to_stream(note)
181
+ def to_stream(note, opts)
144
182
  note[:figures] ||= []
145
183
  note[:figures] << text_value
146
184
  end
@@ -149,47 +187,47 @@ module Lydown::Parsing
149
187
  module StandAloneFigures
150
188
  include Root
151
189
 
152
- def to_stream(stream)
190
+ def to_stream(stream, opts)
153
191
  note = {type: :stand_alone_figures}
154
- _to_stream(self, note)
192
+ _to_stream(self, note, opts)
155
193
  stream << note
156
194
  end
157
195
  end
158
196
 
159
197
  module Phrasing
160
198
  module BeamOpen
161
- def to_stream(stream)
199
+ def to_stream(stream, opts)
162
200
  stream << {type: :beam_open}
163
201
  end
164
202
  end
165
203
 
166
204
  module BeamClose
167
- def to_stream(stream)
205
+ def to_stream(stream, opts)
168
206
  stream << {type: :beam_close}
169
207
  end
170
208
  end
171
209
 
172
210
  module SlurOpen
173
- def to_stream(stream)
211
+ def to_stream(stream, opts)
174
212
  stream << {type: :slur_open}
175
213
  end
176
214
  end
177
215
 
178
216
  module SlurClose
179
- def to_stream(stream)
217
+ def to_stream(stream, opts)
180
218
  stream << {type: :slur_close}
181
219
  end
182
220
  end
183
221
  end
184
222
 
185
223
  module Tie
186
- def to_stream(stream)
224
+ def to_stream(stream, opts)
187
225
  stream << {type: :tie}
188
226
  end
189
227
  end
190
228
 
191
229
  module ShortTie
192
- def to_stream(stream)
230
+ def to_stream(stream, opts)
193
231
  stream << {type: :short_tie}
194
232
  end
195
233
  end
@@ -197,40 +235,50 @@ module Lydown::Parsing
197
235
  module Rest
198
236
  include Root
199
237
 
200
- def to_stream(stream)
201
- rest = {type: :rest, raw: text_value, head: text_value[0]}
238
+ def to_stream(stream, opts)
239
+ rest = event_hash(stream, opts, {
240
+ type: :rest, raw: text_value, head: text_value[0]
241
+ })
202
242
  if text_value =~ /^R(\*([0-9]+))?$/
203
243
  rest[:multiplier] = $2 || '1'
204
244
  end
205
245
 
206
- _to_stream(self, rest)
246
+ _to_stream(self, rest, opts)
207
247
 
208
248
  stream << rest
209
249
  end
210
250
  end
211
251
 
212
252
  module Silence
213
- def to_stream(stream)
214
- stream << {type: :silence, raw: text_value, head: text_value[0]}
253
+ include Root
254
+
255
+ def to_stream(stream, opts)
256
+ stream << event_hash(stream, opts, {
257
+ type: :silence, raw: text_value, head: text_value[0]
258
+ })
215
259
  end
216
260
  end
217
261
 
218
262
  module DurationMacroExpression
219
- def to_stream(stream)
220
- stream << {type: :duration_macro, macro: text_value}
263
+ include Root
264
+
265
+ def to_stream(stream, opts)
266
+ stream << event_hash(stream, opts, {
267
+ type: :duration_macro, macro: text_value
268
+ })
221
269
  end
222
270
  end
223
271
 
224
272
  module Lyrics
225
273
  include Root
226
- def to_stream(stream)
274
+ def to_stream(stream, opts)
227
275
  o = {type: :lyrics}
228
- _to_stream(self, o)
276
+ _to_stream(self, o, opts)
229
277
  stream << o
230
278
  end
231
279
 
232
280
  module Content
233
- def to_stream(o)
281
+ def to_stream(o, opts)
234
282
  if o[:content]
235
283
  o[:content] << ' ' << text_value
236
284
  else
@@ -240,7 +288,7 @@ module Lydown::Parsing
240
288
  end
241
289
 
242
290
  module QuotedContent
243
- def to_stream(o)
291
+ def to_stream(o, opts)
244
292
  if text_value =~ /^"(.+)"$/
245
293
  content = $1
246
294
  else
@@ -257,7 +305,7 @@ module Lydown::Parsing
257
305
  end
258
306
 
259
307
  module StreamIndex
260
- def to_stream(o)
308
+ def to_stream(o, opts)
261
309
  idx = (text_value =~ /\(([\d]+)\)/) && $1.to_i
262
310
  if idx.nil?
263
311
  raise LydownError, "Invalid stream index (#{text_value.inspect})"
@@ -267,24 +315,27 @@ module Lydown::Parsing
267
315
  end
268
316
 
269
317
  module Barline
270
- def to_stream(stream)
318
+ def to_stream(stream, opts)
271
319
  stream << {type: :barline, barline: text_value}
272
320
  end
273
321
  end
274
322
 
275
323
  module Command
276
324
  include Root
277
- def to_stream(stream)
278
- cmd = {type: :command, raw: text_value}
325
+
326
+ def to_stream(stream, opts)
327
+ cmd = event_hash(stream, opts, {
328
+ type: :command, raw: text_value
329
+ })
279
330
  cmd[:once] = true if text_value =~ /^\\\!/
280
- _to_stream(self, cmd)
331
+ _to_stream(self, cmd, opts)
281
332
  stream << cmd
282
333
  end
283
334
 
284
335
  SETTING_KEYS = %w{time key clef}
285
336
 
286
337
  module Key
287
- def to_stream(cmd)
338
+ def to_stream(cmd, opts)
288
339
  cmd[:key] = text_value
289
340
  if SETTING_KEYS.include?(text_value)
290
341
  cmd[:type] = :setting
@@ -293,7 +344,7 @@ module Lydown::Parsing
293
344
  end
294
345
 
295
346
  module Argument
296
- def to_stream(cmd)
347
+ def to_stream(cmd, opts)
297
348
  if text_value =~ /^"(.+)"$/
298
349
  value = $1.unescape
299
350
  else
@@ -311,9 +362,30 @@ module Lydown::Parsing
311
362
  end
312
363
 
313
364
  module VoiceSelector
314
- def to_stream(stream)
365
+ def to_stream(stream, opts)
315
366
  voice = (text_value =~ /^([1234])/) && $1.to_i
316
367
  stream << {type: :voice_select, voice: voice}
317
368
  end
318
369
  end
370
+
371
+ module SourceRef
372
+ include Root
373
+ def to_stream(stream, opts)
374
+ ref = {type: :source_ref, raw: text_value}
375
+ _to_stream(self, ref, opts)
376
+ stream << ref
377
+ end
378
+
379
+ module Line
380
+ def to_stream(ref, opts)
381
+ ref[:line] = text_value.to_i
382
+ end
383
+ end
384
+
385
+ module Column
386
+ def to_stream(ref, opts)
387
+ ref[:column] = text_value.to_i
388
+ end
389
+ end
390
+ end
319
391
  end
@@ -10,6 +10,8 @@ require 'lydown/rendering/staff'
10
10
  require 'lydown/rendering/movement'
11
11
  require 'lydown/rendering/command'
12
12
  require 'lydown/rendering/voices'
13
+ require 'lydown/rendering/source_ref'
14
+ require 'lydown/rendering/skipping'
13
15
 
14
16
  require 'yaml'
15
17
 
@@ -4,12 +4,21 @@ module Lydown::Rendering
4
4
 
5
5
  def translate
6
6
  if @work['process/duration_macro']
7
- add_macro_event(@event[:raw])
7
+ add_macro_event(@event[:raw] || cmd_to_lydown(@event))
8
8
  else
9
9
  once = @event[:once] ? '\once ' : ''
10
10
  cmd = "#{once}\\#{@event[:key]} #{(@event[:arguments] || []).join(' ')} "
11
11
  @work.emit(:music, cmd)
12
12
  end
13
13
  end
14
+
15
+ def cmd_to_lydown(event)
16
+ cmd = "\\#{event[:key]}"
17
+ if event[:arguments]
18
+ cmd << ":"
19
+ cmd << event[:arguments].map {|a| a.inspect}.join(':')
20
+ end
21
+ cmd
22
+ end
14
23
  end
15
24
  end
@@ -106,6 +106,11 @@ module Lydown::Rendering
106
106
  else
107
107
  @work['process/last_value'] = value
108
108
  end
109
+
110
+ if event[:line] && @work['options/proof_mode']
111
+ @work.emit(event[:stream] || :music, note_event_url_link(event))
112
+ # @work.emit(event[:stream] || :music, "%{#{event[:line]}:#{event[:column]}%}")
113
+ end
109
114
 
110
115
  code = lilypond_note(event, options.merge(value: value))
111
116
  @work.emit(event[:stream] || :music, code)
@@ -219,7 +224,9 @@ module Lydown::Rendering
219
224
  @work['process/macro_group'] ||= @work['process/duration_macro'].clone
220
225
  underscore_count = 0
221
226
 
222
- lydown_note = "%s%s%s%s%s%s%s" % [
227
+ lydown_note = "{%d:%d}%s%s%s%s%s%s%s" % [
228
+ event[:line] || 0,
229
+ event[:column] || 0,
223
230
  lydown_phrasing_open(event),
224
231
  event[:head], event[:octave], event[:accidental_flag],
225
232
  lydown_phrasing_close(event),
@@ -240,7 +247,10 @@ module Lydown::Rendering
240
247
 
241
248
  # if group is complete, compile it just like regular code
242
249
  unless @work['process/macro_group'].include?('_')
243
- code = LydownParser.parse(@work['process/macro_group'])
250
+ code = LydownParser.parse(@work['process/macro_group'], {
251
+ filename: event[:filename],
252
+ source: event[:source]
253
+ })
244
254
 
245
255
  # stash macro
246
256
  macro = @work['process/duration_macro']
@@ -312,5 +322,20 @@ module Lydown::Rendering
312
322
  gsub(/__([^_]+)__/) {|m| "\\bold { #{$1} }" }.
313
323
  gsub(/_([^_]+)_/) {|m| "\\italic { #{$1} }" }
314
324
  end
325
+
326
+ TEXTMATE_URL = "txmt://open?url=file://%s&line=%d&column=%d"
327
+
328
+ ADD_LINK_COMMAND = '\once \override NoteHead.after-line-breaking =
329
+ #(add-link "%s") '
330
+
331
+ def note_event_url_link(event)
332
+ url = TEXTMATE_URL % [
333
+ File.expand_path(event[:filename]).uri_escape,
334
+ event[:line],
335
+ event[:column]
336
+ ]
337
+
338
+ ADD_LINK_COMMAND % [url]
339
+ end
315
340
  end
316
341
  end
@@ -0,0 +1,49 @@
1
+ module Lydown::Rendering
2
+ class << self
3
+ SKIP_ON_CMD = {type: :command, key: 'set', arguments: ['Score.skipTypesetting = ##t']}
4
+ SKIP_OFF_CMD = {type: :command, key: 'set', arguments: ['Score.skipTypesetting = ##f']}
5
+
6
+ BARLINE = {type: :barline, barline: '|'}
7
+ BAR_NUMBERS_CMD = {type: :command, key: 'set', arguments: ['Score.barNumberVisibility = #all-bar-numbers-visible']}
8
+
9
+ HIGHLIGHT_NOTES_CMD = {type: :command, key: 'override', arguments: ['NoteHead.color = #red']}
10
+ NORMAL_NOTES_CMD = {type: :command, key: 'override', arguments: ['NoteHead.color = #black']}
11
+
12
+ def insert_skip_markers(stream, line_range)
13
+ # find indexes of first and last changed lines
14
+ changed_first_idx = find_line_idx(stream, line_range.first)
15
+ changed_last_idx = find_line_idx(stream, line_range.last, true)
16
+
17
+ # find index of first line to include
18
+ start_line = line_range.first - 2; start_line = 0 if start_line < 0
19
+ start_idx = find_line_idx(stream, start_line)
20
+
21
+ if changed_last_idx
22
+ stream.insert(changed_last_idx + 1, NORMAL_NOTES_CMD)
23
+ end
24
+
25
+ if changed_first_idx
26
+ stream.insert(changed_first_idx, BARLINE)
27
+ stream.insert(changed_first_idx, BAR_NUMBERS_CMD)
28
+ stream.insert(changed_first_idx, HIGHLIGHT_NOTES_CMD)
29
+ end
30
+
31
+ if start_line > 0 && start_idx
32
+ stream.insert(start_idx, SKIP_OFF_CMD)
33
+ stream.insert(0, SKIP_ON_CMD)
34
+ end
35
+ end
36
+
37
+ # returns index of first event at or after specified line
38
+ def find_line_idx(stream, line, last = false)
39
+ if last
40
+ stream.reverse_each do |e|
41
+ return stream.index(e) if e[:line] && e[:line] <= line
42
+ end
43
+ nil
44
+ else
45
+ stream.index {|e| e[:line] && e[:line] >= line}
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,15 @@
1
+ module Lydown::Rendering
2
+ # SourceRef does nothing, it's only there to provide line, column references
3
+ # for notes in a macro group
4
+ class SourceRef < Base
5
+ def translate
6
+ return # unless @work['options/proof_mode']
7
+
8
+ fn = @event[:filename]
9
+ if fn && fn != @work['process/last_filename']
10
+ @work['process/last_filename'] = fn
11
+ @work.emit(@event[:stream] || :music, "%{::#{File.expand_path(fn)}%} ")
12
+ end
13
+ end
14
+ end
15
+ end
@@ -1,3 +1,3 @@
1
1
  module Lydown
2
- VERSION = "0.7.1"
2
+ VERSION = "0.7.2"
3
3
  end
data/lib/lydown/work.rb CHANGED
@@ -246,46 +246,20 @@ module Lydown
246
246
  end
247
247
  end
248
248
 
249
- SKIP_ON = "\\set:\"Score.skipTypesetting = ##t\""
250
- SHOW_BAR_NUMBERS = "\\set:\"Score.barNumberVisibility = #all-bar-numbers-visible\" |"
251
- SKIP_OFF = "\\set:\"Score.skipTypesetting = ##f\""
252
-
253
- HIGHLIGHT = "\\large \\override:\"NoteHead.color = #red\""
254
- NORMAL = "\\large \\override:\"NoteHead.color = #black\""
255
-
256
- def insert_skip_markers(content, range)
257
- unless range.first.nil?
258
- lines = content.lines
259
- start = range.first - 2; start = 0 if start < 0
260
- stop = range.last + 2; stop = lines.size if stop > lines.size
261
-
262
- lines.insert(stop, "| #{SKIP_ON}")
263
- lines.insert(range.last + 1, NORMAL)
264
- if start > 0
265
- lines.insert(range.first, HIGHLIGHT)
266
- lines.insert(start, SHOW_BAR_NUMBERS)
267
- lines.insert(start, NORMAL)
268
- lines.insert(start, SKIP_OFF)
269
- lines.insert(0, SKIP_ON)
270
- else
271
- lines.insert(0, SHOW_BAR_NUMBERS)
272
- end
273
-
274
- lines.join("\n")
275
- else
276
- content
277
- end
278
- end
279
-
280
249
  def process_lydown_file(path, prefix = [], opts = {})
281
250
  return unless File.file?(path)
282
251
 
283
252
  content = IO.read(path)
253
+ stream = LydownParser.parse(content, {
254
+ filename: File.expand_path(path),
255
+ source: content
256
+ })
257
+
284
258
  if opts[:line_range]
285
- content = insert_skip_markers(content, opts[:line_range])
259
+ Lydown::Rendering.insert_skip_markers(stream, opts[:line_range])
286
260
  end
287
261
 
288
- process(prefix + LydownParser.parse(content))
262
+ process(prefix + stream)
289
263
  end
290
264
  end
291
265
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lydown
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.1
4
+ version: 0.7.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sharon Rosner
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-07-01 00:00:00.000000000 Z
11
+ date: 2015-07-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: treetop
@@ -57,6 +57,8 @@ files:
57
57
  - lib/lydown/rendering/music.rb
58
58
  - lib/lydown/rendering/notes.rb
59
59
  - lib/lydown/rendering/settings.rb
60
+ - lib/lydown/rendering/skipping.rb
61
+ - lib/lydown/rendering/source_ref.rb
60
62
  - lib/lydown/rendering/staff.rb
61
63
  - lib/lydown/rendering/voices.rb
62
64
  - lib/lydown/templates.rb