lydown 0.7.2 → 0.9.0

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.
Files changed (43) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +25 -14
  3. data/bin/lydown +1 -122
  4. data/lib/lydown.rb +3 -3
  5. data/lib/lydown/cli.rb +4 -0
  6. data/lib/lydown/cli/commands.rb +98 -0
  7. data/lib/lydown/cli/compiler.rb +11 -14
  8. data/lib/lydown/cli/diff.rb +3 -3
  9. data/lib/lydown/cli/output.rb +18 -0
  10. data/lib/lydown/cli/proofing.rb +8 -6
  11. data/lib/lydown/cli/support.rb +34 -0
  12. data/lib/lydown/cli/translation.rb +73 -0
  13. data/lib/lydown/core_ext.rb +1 -1
  14. data/lib/lydown/lilypond.rb +49 -11
  15. data/lib/lydown/parsing.rb +37 -6
  16. data/lib/lydown/parsing/nodes.rb +57 -56
  17. data/lib/lydown/rendering.rb +0 -9
  18. data/lib/lydown/rendering/base.rb +2 -2
  19. data/lib/lydown/rendering/command.rb +2 -2
  20. data/lib/lydown/rendering/comments.rb +1 -1
  21. data/lib/lydown/rendering/figures.rb +14 -14
  22. data/lib/lydown/rendering/lib.ly +22 -0
  23. data/lib/lydown/rendering/lyrics.rb +2 -2
  24. data/lib/lydown/rendering/movement.rb +2 -2
  25. data/lib/lydown/rendering/music.rb +46 -46
  26. data/lib/lydown/rendering/notes.rb +149 -70
  27. data/lib/lydown/rendering/settings.rb +21 -16
  28. data/lib/lydown/rendering/skipping.rb +1 -1
  29. data/lib/lydown/rendering/source_ref.rb +4 -4
  30. data/lib/lydown/rendering/staff.rb +8 -4
  31. data/lib/lydown/rendering/voices.rb +9 -9
  32. data/lib/lydown/templates.rb +9 -0
  33. data/lib/lydown/templates/lilypond_doc.erb +1 -1
  34. data/lib/lydown/templates/movement.erb +9 -1
  35. data/lib/lydown/templates/part.erb +12 -3
  36. data/lib/lydown/translation.rb +17 -0
  37. data/lib/lydown/translation/ripple.rb +30 -0
  38. data/lib/lydown/translation/ripple/nodes.rb +191 -0
  39. data/lib/lydown/translation/ripple/ripple.treetop +100 -0
  40. data/lib/lydown/version.rb +1 -1
  41. data/lib/lydown/work.rb +144 -198
  42. data/lib/lydown/work_context.rb +152 -0
  43. metadata +11 -2
@@ -0,0 +1,152 @@
1
+ module Lydown
2
+ # A WorkContext instance holds the entire state of a work being processed.
3
+ # This includes both the document settings and processing state, and the
4
+ # resulting lilypond streams and associated data.
5
+ class WorkContext
6
+ attr_reader :context
7
+
8
+ include TemplateBinding
9
+
10
+ def initialize(opts = {}, context = nil)
11
+ if context
12
+ @context = context
13
+ else
14
+ @context = {}.deep!
15
+ reset(:work)
16
+ @context[:options] = opts.deep_clone
17
+ end
18
+ end
19
+
20
+ # process lydown stream by translating into self
21
+ def translate(stream, opts = {})
22
+ stream.each_with_index do |e, idx|
23
+ if e[:type]
24
+ Lydown::Rendering.translate(self, e, stream, idx)
25
+ else
26
+ raise LydownError, "Invalid lydown stream event: #{e.inspect}"
27
+ end
28
+ end
29
+ reset(:part) unless opts[:macro_group]
30
+ end
31
+
32
+ def reset(mode)
33
+ case mode
34
+ when :work
35
+ @context[:time] = '4/4'
36
+ @context[:tempo] = nil
37
+ @context[:cadenza_mode] = nil
38
+ @context[:key] = 'c major'
39
+ @context[:pickup] = nil
40
+ @context[:beaming] = nil
41
+ @context[:end_barline] = nil
42
+ @context[:part] = nil
43
+ when :movement
44
+ @context[:part] = nil
45
+ end
46
+ if @context['process/tuplet_mode']
47
+ Lydown::Rendering::TupletDuration.emit_tuplet_end(self)
48
+ end
49
+ if @context['process/grace_mode']
50
+ Lydown::Rendering::Grace.emit_grace_end(self)
51
+ end
52
+
53
+ if @context['process/voice_selector']
54
+ Lydown::Rendering::VoiceSelect.render_voices(self)
55
+ end
56
+
57
+ Lydown::Rendering::Notes.cleanup_duration_macro(self)
58
+
59
+ # reset processing variables
60
+ @context['process'] = {
61
+ 'duration_values' => ['4'],
62
+ 'running_values' => []
63
+ }
64
+ end
65
+
66
+ def clone_for_translation
67
+ new_context = @context.deep_merge({'movements' => nil})
68
+ WorkContext.new(nil, new_context)
69
+ end
70
+
71
+ def merge_movements(ctx)
72
+ return unless ctx['movements']
73
+ if @context['movements']
74
+ @context['movements'].deep_merge! ctx['movements']
75
+ else
76
+ @context['movements'] = ctx['movements']
77
+ end
78
+ end
79
+
80
+ def filter(opts = {})
81
+ filtered = @context.deep_clone
82
+
83
+ if filtered[:movements].nil? || filtered[:movements].size == 0
84
+ # no movements found, so no music
85
+ raise LydownError, "No music found"
86
+ elsif filtered[:movements].size > 1
87
+ # delete default movement if other movements are present
88
+ filtered[:movements].delete('')
89
+ end
90
+
91
+ if filter = opts[:movements]
92
+ filter = [filter] unless filter.is_a?(Array)
93
+ filtered[:movements].select! {|name, m| filter.include?(name.to_s)}
94
+ end
95
+
96
+ if filter = opts[:parts]
97
+ filter = [filter] unless filter.is_a?(Array)
98
+ end
99
+ filtered[:movements].each do |name, m|
100
+ # delete default part if other parts are present
101
+ if m[:parts].size > 1
102
+ m[:parts].delete('')
103
+ end
104
+
105
+ if filter
106
+ m[:parts].select! do |pname, p|
107
+ filter.include?(pname.to_s)
108
+ end
109
+ end
110
+ end
111
+
112
+ filtered
113
+ end
114
+
115
+ def [](key)
116
+ @context[key]
117
+ end
118
+
119
+ def []=(key, value)
120
+ @context[key] = value
121
+ end
122
+
123
+ def emit(path, *content)
124
+ stream = current_stream(path)
125
+
126
+ content.each {|c| stream << c}
127
+ end
128
+
129
+ def current_stream(subpath)
130
+ if @context['process/voice_selector']
131
+ path = "process/voices/#{@context['process/voice_selector']}/#{subpath}"
132
+ else
133
+ movement = @context[:movement]
134
+ part = @context[:part]
135
+ path = "movements/#{movement}/parts/#{part}/#{subpath}"
136
+ end
137
+ @context[path] ||= (subpath == :settings) ? {} : ''
138
+ end
139
+
140
+ def set_part_context(part)
141
+ movement = @context[:movement]
142
+ path = "movements/#{movement}/parts/#{part}/settings"
143
+
144
+ settings = {}.deep!
145
+ settings[:pickup] = @context[:pickup]
146
+ settings[:key] = @context[:key]
147
+ settings[:tempo] = @context[:tempo]
148
+
149
+ @context[path] = settings
150
+ end
151
+ end
152
+ 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.2
4
+ version: 0.9.0
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-15 00:00:00.000000000 Z
11
+ date: 2015-08-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: treetop
@@ -36,9 +36,13 @@ files:
36
36
  - bin/lydown
37
37
  - lib/lydown.rb
38
38
  - lib/lydown/cli.rb
39
+ - lib/lydown/cli/commands.rb
39
40
  - lib/lydown/cli/compiler.rb
40
41
  - lib/lydown/cli/diff.rb
42
+ - lib/lydown/cli/output.rb
41
43
  - lib/lydown/cli/proofing.rb
44
+ - lib/lydown/cli/support.rb
45
+ - lib/lydown/cli/translation.rb
42
46
  - lib/lydown/core_ext.rb
43
47
  - lib/lydown/errors.rb
44
48
  - lib/lydown/lilypond.rb
@@ -66,8 +70,13 @@ files:
66
70
  - lib/lydown/templates/movement.erb
67
71
  - lib/lydown/templates/multi_voice.erb
68
72
  - lib/lydown/templates/part.erb
73
+ - lib/lydown/translation.rb
74
+ - lib/lydown/translation/ripple.rb
75
+ - lib/lydown/translation/ripple/nodes.rb
76
+ - lib/lydown/translation/ripple/ripple.treetop
69
77
  - lib/lydown/version.rb
70
78
  - lib/lydown/work.rb
79
+ - lib/lydown/work_context.rb
71
80
  homepage: http://github.com/ciconia/lydown
72
81
  licenses:
73
82
  - MIT