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 +4 -4
- data/lib/lydown/cli/compiler.rb +2 -1
- data/lib/lydown/cli/diff.rb +3 -0
- data/lib/lydown/cli/proofing.rb +8 -12
- data/lib/lydown/core_ext.rb +29 -0
- data/lib/lydown/lilypond.rb +1 -1
- data/lib/lydown/parsing.rb +4 -1
- data/lib/lydown/parsing/lydown.treetop +18 -7
- data/lib/lydown/parsing/nodes.rb +130 -58
- data/lib/lydown/rendering.rb +2 -0
- data/lib/lydown/rendering/command.rb +10 -1
- data/lib/lydown/rendering/notes.rb +27 -2
- data/lib/lydown/rendering/skipping.rb +49 -0
- data/lib/lydown/rendering/source_ref.rb +15 -0
- data/lib/lydown/version.rb +1 -1
- data/lib/lydown/work.rb +7 -33
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2945708b90bba8a47e9c037ed6b58feee552c411
|
4
|
+
data.tar.gz: 3fab488b2070abaa55eccd5a2d1ee2af496419af
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c9a16ab91b2118d2ceed5791caa10319fac63e38bd09da38e19fb57ba52ab5ad6b3db857c811211a0e8f5d167d0f0e5b841aee06f0bb607df4cdba0cbd794b97
|
7
|
+
data.tar.gz: 25df40e9a348873a1da26969c8f8275e7f806ff4f5386657c3a1eba4acdbd7d84f4c687eb5653867973dd656acf4b9eeb59a4ce9e9da9d73894d09a609ae7123
|
data/lib/lydown/cli/compiler.rb
CHANGED
data/lib/lydown/cli/diff.rb
CHANGED
data/lib/lydown/cli/proofing.rb
CHANGED
@@ -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
|
-
|
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]
|
91
|
-
|
92
|
-
|
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
|
data/lib/lydown/core_ext.rb
CHANGED
@@ -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
|
data/lib/lydown/lilypond.rb
CHANGED
@@ -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|
|
data/lib/lydown/parsing.rb
CHANGED
@@ -15,7 +15,10 @@ class LydownParser
|
|
15
15
|
STDERR.puts error_msg
|
16
16
|
raise LydownError, error_msg
|
17
17
|
else
|
18
|
-
|
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
|
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
|
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 /
|
48
|
-
|
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 /
|
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
|
data/lib/lydown/parsing/nodes.rb
CHANGED
@@ -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) ?
|
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 =
|
30
|
-
|
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
|
-
|
57
|
-
|
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
|
-
|
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 <<
|
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 =
|
99
|
-
|
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 =
|
137
|
-
|
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 =
|
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
|
-
|
214
|
-
|
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
|
-
|
220
|
-
|
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
|
-
|
278
|
-
|
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
|
data/lib/lydown/rendering.rb
CHANGED
@@ -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
|
data/lib/lydown/version.rb
CHANGED
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
|
-
|
259
|
+
Lydown::Rendering.insert_skip_markers(stream, opts[:line_range])
|
286
260
|
end
|
287
261
|
|
288
|
-
process(prefix +
|
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.
|
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-
|
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
|