rhet-butler 0.11.1 → 0.12.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +8 -8
- data/default-configuration/assets/javascript/sockjs-0.3.4.js +2379 -0
- data/default-configuration/assets/stylesheets/rhet.css.sass +4 -3
- data/default-configuration/common/templates/header-javascript.html +1 -1
- data/default-configuration/common/templates/presentation.html.erb +1 -1
- data/default-configuration/common/templates/presenter-qr.html.erb +1 -1
- data/default-configuration/presenter/templates/stylesheets.html.erb +1 -0
- data/lib/rhet-butler/command-line.rb +2 -0
- data/lib/rhet-butler/filter-resolver.rb +10 -1
- data/lib/rhet-butler/messaging.rb +24 -7
- data/lib/rhet-butler/resource-localizer.rb +1 -1
- data/lib/rhet-butler/slide-contents/embed.rb +39 -0
- data/lib/rhet-butler/slide-contents.rb +40 -0
- data/lib/rhet-butler/slide-loader.rb +8 -7
- data/lib/rhet-butler/slide-rendering.rb +17 -6
- data/lib/rhet-butler/slide.rb +9 -78
- data/lib/rhet-butler/stasis/rack-loader.rb +3 -1
- data/lib/rhet-butler/stasis/transform-queue.rb +23 -13
- data/lib/rhet-butler/static-generator.rb +1 -1
- data/lib/rhet-butler/web/main-app.rb +12 -12
- data/lib/rhet-butler/web/presentation-app.rb +5 -1
- data/lib/rhet-butler/yaml-schema.rb +1 -1
- data/spec/slide-loader.rb +11 -1
- metadata +8 -12
- data/lib/rhet-butler/arrangement-finder.rb +0 -71
- data/lib/rhet-butler/arrangement.rb +0 -78
- data/lib/rhet-butler/layout-rule.rb +0 -61
- data/lib/rhet-butler/slide-arranger.rb +0 -39
- data/lib/rhet-butler/slide-processor.rb +0 -27
- data/spec/arrangements.rb +0 -76
- data/spec/slide-processing.rb +0 -76
@@ -134,19 +134,20 @@ body
|
|
134
134
|
vertical-align: middle
|
135
135
|
|
136
136
|
@for $i from 1 through 10
|
137
|
-
li.cue-#{$i}
|
137
|
+
li.cue-#{$i}, svg .cue-#{$i}
|
138
138
|
opacity: 0
|
139
139
|
|
140
|
+
|
140
141
|
&.current-cue-#{$i}
|
141
142
|
code span.cue-#{$i}
|
142
143
|
border-radius: 5px
|
143
144
|
+box-shadow(-1px -1px 0px 1px rgba(140,140,140,0.5) inset, 1px 1px 0px 1px rgba(40, 40, 40, 0.5) inset)
|
144
145
|
background-color: rgba(255,255,255,0.1)
|
145
146
|
|
146
|
-
li.cue-#{$i}
|
147
|
+
li.cue-#{$i}, svg .cue-#{$i}
|
147
148
|
+animation(fadeIn .6s ease both)
|
148
149
|
@for $j from 1 through $i
|
149
|
-
li.cue-#{$j}
|
150
|
+
li.cue-#{$j}, svg .cue-#{$j}
|
150
151
|
opacity: 1
|
151
152
|
|
152
153
|
p
|
@@ -1,3 +1,3 @@
|
|
1
|
-
<script type="text/javascript" src="assets/javascript/sockjs-0.
|
1
|
+
<script type="text/javascript" src="assets/javascript/sockjs-0.3.4.js"></script>
|
2
2
|
<script src="assets/javascript/highlight.pack.js"></script>
|
3
3
|
<script>hljs.initHighlightingOnLoad();</script>
|
@@ -19,7 +19,7 @@
|
|
19
19
|
}
|
20
20
|
</style>
|
21
21
|
|
22
|
-
<script type="text/javascript" src="/assets/javascript/sockjs-0.
|
22
|
+
<script type="text/javascript" src="/assets/javascript/sockjs-0.3.4.js"></script>
|
23
23
|
<script type="text/javascript">
|
24
24
|
var sock = new SockJS("/live/follower");
|
25
25
|
|
@@ -10,6 +10,7 @@ module RhetButler
|
|
10
10
|
method_option :root_slide, :type => :string
|
11
11
|
end
|
12
12
|
|
13
|
+
#:nocov:
|
13
14
|
desc "init", "Create example skeleton files to get started with"
|
14
15
|
def init
|
15
16
|
require 'fileutils'
|
@@ -113,5 +114,6 @@ module RhetButler
|
|
113
114
|
app.check
|
114
115
|
app.start
|
115
116
|
end
|
117
|
+
#:nocov:
|
116
118
|
end
|
117
119
|
end
|
@@ -36,11 +36,20 @@ module RhetButler
|
|
36
36
|
slide.html_classes += slide.content_filters.map do |filter|
|
37
37
|
filter.html_class
|
38
38
|
end
|
39
|
+
|
39
40
|
slide.note_filters = get_filters(slide.note_filters || default_note_filters)
|
40
41
|
slide.html_classes += slide.content_filters.map do |filter|
|
41
42
|
"note-" + filter.html_class unless filter.html_class.nil?
|
42
43
|
end
|
43
|
-
|
44
|
+
|
45
|
+
[ *slide.raw_content ].each do |content| #XXX This is how all content filtering should work
|
46
|
+
case content
|
47
|
+
when SlideContents
|
48
|
+
content.filters = get_filters(content.filters || default_content_filters)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
rescue
|
44
53
|
puts "While processing #{slide}:"
|
45
54
|
raise
|
46
55
|
end
|
@@ -2,35 +2,47 @@ require 'thin'
|
|
2
2
|
require 'rack/sockjs'
|
3
3
|
|
4
4
|
module RhetButler
|
5
|
-
class
|
5
|
+
class QueueSession < SockJS::Session
|
6
|
+
include Thin::Logging
|
7
|
+
|
6
8
|
def initialize(connection)
|
7
9
|
super
|
8
10
|
@queue = connection.options[:queue]
|
9
11
|
end
|
12
|
+
end
|
10
13
|
|
14
|
+
class FollowerSession < QueueSession
|
11
15
|
def opened
|
16
|
+
log_info("Follower opened socket")
|
12
17
|
@queue.subscribe(self)
|
13
18
|
end
|
14
19
|
|
15
20
|
def close(*args)
|
21
|
+
log_info("Follower closed socket")
|
16
22
|
@queue.unsubscribe(self)
|
17
23
|
super
|
18
24
|
end
|
19
25
|
end
|
20
26
|
|
21
|
-
class LeaderSession <
|
22
|
-
def
|
23
|
-
|
24
|
-
|
27
|
+
class LeaderSession < QueueSession
|
28
|
+
def opened
|
29
|
+
log_info("Leader opened socket")
|
30
|
+
end
|
31
|
+
|
32
|
+
def close(*args)
|
33
|
+
log_info("Leader closed socket")
|
25
34
|
end
|
26
35
|
|
27
36
|
def process_message(message)
|
37
|
+
log_info("Leader moved to slide #{message}")
|
28
38
|
@queue.current_slide = message
|
29
39
|
@queue.enqueue(message)
|
30
40
|
end
|
31
41
|
end
|
32
42
|
|
33
43
|
class SlideMessageQueue
|
44
|
+
include Thin::Logging
|
45
|
+
|
34
46
|
attr_accessor :current_slide
|
35
47
|
def initialize
|
36
48
|
@listeners = {}
|
@@ -46,12 +58,17 @@ module RhetButler
|
|
46
58
|
end
|
47
59
|
|
48
60
|
def unsubscribe(session)
|
49
|
-
@listeners.
|
61
|
+
@listeners.delete(session)
|
50
62
|
end
|
51
63
|
|
52
64
|
def enqueue(message)
|
53
65
|
@listeners.keys.each do |session|
|
54
|
-
|
66
|
+
begin
|
67
|
+
session.send(message)
|
68
|
+
rescue MetaState::WrongStateError => wse
|
69
|
+
log_info("Follower in wrong state: #{wse.inspect}")
|
70
|
+
@listeners.delete(session)
|
71
|
+
end
|
55
72
|
end
|
56
73
|
end
|
57
74
|
end
|
@@ -15,7 +15,7 @@ module RhetButler
|
|
15
15
|
transform_queue.writer.store_log = store_log
|
16
16
|
|
17
17
|
target_uri = transform_queue.mapping.target_link_for(source_uri)
|
18
|
-
transform_queue.add_mapping(source_uri, target_uri, target_path)
|
18
|
+
transform_queue.add_mapping(nil, source_uri, target_uri, target_path)
|
19
19
|
transform_queue.go
|
20
20
|
end
|
21
21
|
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'nokogiri'
|
2
|
+
|
3
|
+
module RhetButler
|
4
|
+
class SlideContents
|
5
|
+
class Embed < SlideContents
|
6
|
+
register "embed"
|
7
|
+
register "embedded"
|
8
|
+
|
9
|
+
def self.required_config
|
10
|
+
%w{source}
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.optional_config
|
14
|
+
%w{filters}
|
15
|
+
end
|
16
|
+
|
17
|
+
def positional_options
|
18
|
+
%w{source}
|
19
|
+
end
|
20
|
+
|
21
|
+
attr_reader :source
|
22
|
+
attr_accessor :filters
|
23
|
+
|
24
|
+
def configure
|
25
|
+
value_from_config("source") do |source|
|
26
|
+
@source = source
|
27
|
+
end
|
28
|
+
|
29
|
+
value_from_config("filters") do |value|
|
30
|
+
@filters = value
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def content(file_set)
|
35
|
+
"\n" + file_set.contents(source) + "\n"
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'rhet-butler/yaml-type'
|
2
|
+
|
3
|
+
module RhetButler
|
4
|
+
class SlideContents < YamlType
|
5
|
+
def self.required_config
|
6
|
+
[]
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.optional_config
|
10
|
+
[]
|
11
|
+
end
|
12
|
+
|
13
|
+
def setup_defaults
|
14
|
+
end
|
15
|
+
|
16
|
+
def positional_options
|
17
|
+
[]
|
18
|
+
end
|
19
|
+
|
20
|
+
def normalize_config(coder)
|
21
|
+
case coder.type
|
22
|
+
when :seq
|
23
|
+
Hash[positional_options.zip(coder.seq)]
|
24
|
+
when :map
|
25
|
+
coder.map
|
26
|
+
else
|
27
|
+
Hash[positional_options.zip([coder.scalar])]
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def configure
|
32
|
+
end
|
33
|
+
|
34
|
+
def html_class
|
35
|
+
nil
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
require 'rhet-butler/slide-contents/embed'
|
@@ -1,13 +1,14 @@
|
|
1
1
|
require 'rhet-butler/yaml-schema'
|
2
2
|
require 'rhet-butler/file-loading'
|
3
3
|
require 'rhet-butler/include-processor'
|
4
|
-
require 'rhet-butler/slide-
|
4
|
+
require 'rhet-butler/slide-rendering'
|
5
5
|
require 'rhet-butler/filter-resolver'
|
6
6
|
|
7
7
|
module RhetButler
|
8
8
|
class SlideLoader
|
9
|
-
def initialize(slide_files, configuration)
|
9
|
+
def initialize(slide_files, asset_files, configuration)
|
10
10
|
@file_set = slide_files
|
11
|
+
@asset_set = asset_files
|
11
12
|
@named_filter_lists = configuration.named_filter_lists
|
12
13
|
@default_content_filters = configuration.default_content_filters
|
13
14
|
@default_note_filters = configuration.default_note_filters
|
@@ -21,8 +22,8 @@ module RhetButler
|
|
21
22
|
includer = Includer.new
|
22
23
|
includer.path = @root_slide
|
23
24
|
root_group.slides = [includer]
|
24
|
-
|
25
25
|
loading = FileLoading.new(@file_set)
|
26
|
+
|
26
27
|
including = IncludeProcessor.new(loading)
|
27
28
|
including.root_group = root_group
|
28
29
|
including.traverse
|
@@ -34,10 +35,10 @@ module RhetButler
|
|
34
35
|
filter_resolver.default_note_filters = @default_note_filters
|
35
36
|
filter_resolver.traverse
|
36
37
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
38
|
+
renderer = SlideRendering.new
|
39
|
+
renderer.root_group = root_group
|
40
|
+
renderer.file_set = @asset_set
|
41
|
+
renderer.traverse
|
41
42
|
|
42
43
|
return root_group
|
43
44
|
end
|
@@ -2,20 +2,31 @@ require 'rhet-butler/slide-renderer'
|
|
2
2
|
require 'rhet-butler/slide-traverser'
|
3
3
|
module RhetButler
|
4
4
|
class SlideRendering < SlideTraverser
|
5
|
-
attr_accessor :root_group
|
5
|
+
attr_accessor :root_group, :file_set
|
6
6
|
|
7
7
|
def setup
|
8
8
|
descend(@root_group, @root_group)
|
9
9
|
end
|
10
10
|
|
11
11
|
def on_slide(slide)
|
12
|
-
slide.content = filter_text(slide.
|
13
|
-
slide.notes = filter_text(slide.
|
12
|
+
slide.content = filter_text(slide.raw_content, slide.content_filters)
|
13
|
+
slide.notes = filter_text(slide.raw_notes, slide.note_filters)
|
14
|
+
raise "Slide content needs to be a string, was: #{slide.content.inspect}" unless String === slide.content
|
15
|
+
raise "Slide notes needs to be a string, was: #{slide.notes.inspect}" unless String === slide.notes
|
14
16
|
end
|
15
17
|
|
16
|
-
def filter_text(
|
17
|
-
|
18
|
-
|
18
|
+
def filter_text(content, filters)
|
19
|
+
case content
|
20
|
+
when String
|
21
|
+
filters.inject(content) do |text, filter|
|
22
|
+
filter.process(text)
|
23
|
+
end
|
24
|
+
when Array
|
25
|
+
content.map{|item| filter_text(item, filters)}.join("")
|
26
|
+
when SlideContents
|
27
|
+
filter_text(content.content(file_set), content.filters)
|
28
|
+
else
|
29
|
+
raise "Don't know how to filter slide content like #{content.inspect}"
|
19
30
|
end
|
20
31
|
end
|
21
32
|
end
|
data/lib/rhet-butler/slide.rb
CHANGED
@@ -8,7 +8,6 @@ module RhetButler
|
|
8
8
|
def optional_config
|
9
9
|
%w[
|
10
10
|
title html_id html_classes html_class
|
11
|
-
pos_x pos_y pos_z rot_x rot_y rot_z scale
|
12
11
|
notes filters note_filters
|
13
12
|
]
|
14
13
|
end
|
@@ -18,42 +17,11 @@ module RhetButler
|
|
18
17
|
end
|
19
18
|
end
|
20
19
|
|
21
|
-
class Position
|
22
|
-
def initialize
|
23
|
-
@x = 0
|
24
|
-
@y = 0
|
25
|
-
@z = 0
|
26
|
-
end
|
27
|
-
|
28
|
-
attr_accessor :x, :y, :z
|
29
|
-
|
30
|
-
def to_attrs
|
31
|
-
"data-x='#@x' data-y='#@y' data-z='#@z'"
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
|
-
class Rotation
|
36
|
-
def initialize
|
37
|
-
@x = 0
|
38
|
-
@y = 0
|
39
|
-
@z = 0
|
40
|
-
end
|
41
|
-
|
42
|
-
attr_accessor :x, :y, :z
|
43
|
-
|
44
|
-
def to_attrs
|
45
|
-
"data-rotate-x='#@x' data-rotate-y='#@y' data-rotate-z='#@z'"
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
20
|
def setup_defaults
|
50
21
|
@template_name = "slide.html"
|
51
22
|
@html_classes = ["slide"]
|
52
23
|
@html_id = nil
|
53
|
-
@
|
54
|
-
@rotation = Rotation.new
|
55
|
-
@scale = 1.0
|
56
|
-
@notes = ""
|
24
|
+
@raw_notes = ""
|
57
25
|
@type = nil
|
58
26
|
end
|
59
27
|
|
@@ -63,8 +31,6 @@ module RhetButler
|
|
63
31
|
@content = source.content.dup unless source.content.nil?
|
64
32
|
@notes = source.notes.dup unless source.notes.nil?
|
65
33
|
@html_id = source.html_id.dup unless source.html_id.nil?
|
66
|
-
@position = source.position.dup unless source.position.nil?
|
67
|
-
@rotation = source.rotation.dup unless source.rotation.nil?
|
68
34
|
@html_classes = source.html_classes.dup unless source.html_classes.nil?
|
69
35
|
end
|
70
36
|
|
@@ -76,7 +42,7 @@ module RhetButler
|
|
76
42
|
when :scalar
|
77
43
|
{ 'content' => coder.scalar.to_s }
|
78
44
|
when :seq
|
79
|
-
|
45
|
+
{ 'content' => coder.seq.to_a }
|
80
46
|
end
|
81
47
|
end
|
82
48
|
|
@@ -86,13 +52,11 @@ module RhetButler
|
|
86
52
|
end
|
87
53
|
|
88
54
|
value_from_config("content") do |content|
|
89
|
-
|
90
|
-
@content = content
|
55
|
+
@raw_content = content
|
91
56
|
end
|
92
57
|
|
93
58
|
value_from_config("notes") do |notes|
|
94
|
-
|
95
|
-
@notes = notes
|
59
|
+
@raw_notes = notes
|
96
60
|
end
|
97
61
|
|
98
62
|
value_from_config("html_id") do |value|
|
@@ -107,30 +71,6 @@ module RhetButler
|
|
107
71
|
@html_classes << value
|
108
72
|
end
|
109
73
|
|
110
|
-
value_from_config("pos_x") do |value|
|
111
|
-
@position.x = value
|
112
|
-
end
|
113
|
-
value_from_config("pos_y") do |value|
|
114
|
-
@position.y = value
|
115
|
-
end
|
116
|
-
value_from_config("pos_z") do |value|
|
117
|
-
@position.z = value
|
118
|
-
end
|
119
|
-
|
120
|
-
value_from_config("rot_x") do |value|
|
121
|
-
@rotation.x = value
|
122
|
-
end
|
123
|
-
value_from_config("rot_y") do |value|
|
124
|
-
@rotation.y = value
|
125
|
-
end
|
126
|
-
value_from_config("rot_z") do |value|
|
127
|
-
@rotation.z = value
|
128
|
-
end
|
129
|
-
|
130
|
-
value_from_config("scale") do |value|
|
131
|
-
@scale = value
|
132
|
-
end
|
133
|
-
|
134
74
|
value_from_config("filters") do |value|
|
135
75
|
@content_filters = value
|
136
76
|
@html_classes += [*value].map do |filter|
|
@@ -147,13 +87,14 @@ module RhetButler
|
|
147
87
|
end
|
148
88
|
|
149
89
|
attr_reader :config_hash
|
150
|
-
attr_accessor :
|
151
|
-
attr_accessor :
|
152
|
-
attr_accessor :
|
90
|
+
attr_accessor :raw_content, :raw_notes
|
91
|
+
attr_accessor :content, :notes
|
92
|
+
attr_accessor :html_classes, :html_id
|
93
|
+
attr_accessor :content_filters, :note_filters
|
153
94
|
attr_reader :template_name
|
154
95
|
|
155
96
|
def to_s
|
156
|
-
"Slide: #{content[0..20]}"
|
97
|
+
"Slide: #{content.nil? ? "R:#{raw_content[0..20]}" : content[0..20]}"
|
157
98
|
end
|
158
99
|
|
159
100
|
def id_attr
|
@@ -167,15 +108,5 @@ module RhetButler
|
|
167
108
|
def classes
|
168
109
|
@html_classes.join(" ")
|
169
110
|
end
|
170
|
-
|
171
|
-
def impress_attrs
|
172
|
-
attrs = []
|
173
|
-
|
174
|
-
attrs << @position.to_attrs
|
175
|
-
attrs << @rotation.to_attrs
|
176
|
-
attrs << "data-scale='#{"%0.2f" % scale}'"
|
177
|
-
|
178
|
-
attrs.join(" ")
|
179
|
-
end
|
180
111
|
end
|
181
112
|
end
|