rhet-butler 0.11.1 → 0.12.1
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 +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
|