lydown 0.7.1 → 0.7.2
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 +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
|