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.
Files changed (31) hide show
  1. checksums.yaml +8 -8
  2. data/default-configuration/assets/javascript/sockjs-0.3.4.js +2379 -0
  3. data/default-configuration/assets/stylesheets/rhet.css.sass +4 -3
  4. data/default-configuration/common/templates/header-javascript.html +1 -1
  5. data/default-configuration/common/templates/presentation.html.erb +1 -1
  6. data/default-configuration/common/templates/presenter-qr.html.erb +1 -1
  7. data/default-configuration/presenter/templates/stylesheets.html.erb +1 -0
  8. data/lib/rhet-butler/command-line.rb +2 -0
  9. data/lib/rhet-butler/filter-resolver.rb +10 -1
  10. data/lib/rhet-butler/messaging.rb +24 -7
  11. data/lib/rhet-butler/resource-localizer.rb +1 -1
  12. data/lib/rhet-butler/slide-contents/embed.rb +39 -0
  13. data/lib/rhet-butler/slide-contents.rb +40 -0
  14. data/lib/rhet-butler/slide-loader.rb +8 -7
  15. data/lib/rhet-butler/slide-rendering.rb +17 -6
  16. data/lib/rhet-butler/slide.rb +9 -78
  17. data/lib/rhet-butler/stasis/rack-loader.rb +3 -1
  18. data/lib/rhet-butler/stasis/transform-queue.rb +23 -13
  19. data/lib/rhet-butler/static-generator.rb +1 -1
  20. data/lib/rhet-butler/web/main-app.rb +12 -12
  21. data/lib/rhet-butler/web/presentation-app.rb +5 -1
  22. data/lib/rhet-butler/yaml-schema.rb +1 -1
  23. data/spec/slide-loader.rb +11 -1
  24. metadata +8 -12
  25. data/lib/rhet-butler/arrangement-finder.rb +0 -71
  26. data/lib/rhet-butler/arrangement.rb +0 -78
  27. data/lib/rhet-butler/layout-rule.rb +0 -61
  28. data/lib/rhet-butler/slide-arranger.rb +0 -39
  29. data/lib/rhet-butler/slide-processor.rb +0 -27
  30. data/spec/arrangements.rb +0 -76
  31. 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.2.1.js"></script>
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>
@@ -2,7 +2,7 @@
2
2
  <html lang="en">
3
3
  <head>
4
4
  <meta charset="utf-8" />
5
- <meta name="viewport" content="width=1024" />
5
+ <meta name="viewport" content="width=100%" />
6
6
  <meta name="apple-mobile-web-app-capable" content="yes" />
7
7
  <title><%= presentation.title %></title>
8
8
 
@@ -19,7 +19,7 @@
19
19
  }
20
20
  </style>
21
21
 
22
- <script type="text/javascript" src="/assets/javascript/sockjs-0.2.1.js"></script>
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
 
@@ -1,3 +1,4 @@
1
1
  <link href="/stylesheets/google-open-sans.css" rel="stylesheet" />
2
2
  <link href="/stylesheets/presenter/rhet.css" rel="stylesheet" />
3
+ <link href="/stylesheets/prez-local.css" rel="stylesheet" />
3
4
  <link href="/stylesheets/highlight/solarized_dark.css" rel="stylesheet" />
@@ -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
- rescue => ex
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 FollowerSession < SockJS::Session
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 < SockJS::Session
22
- def initialize(connection)
23
- super
24
- @queue = connection.options[:queue]
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.delete_key(session)
61
+ @listeners.delete(session)
50
62
  end
51
63
 
52
64
  def enqueue(message)
53
65
  @listeners.keys.each do |session|
54
- session.send(message)
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-processor'
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
- processor = SlideProcessor.new
38
- processor.root_group = root_group
39
- processor.blueprint = @blueprint
40
- processor.process
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.content, slide.content_filters)
13
- slide.notes = filter_text(slide.notes, slide.note_filters)
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(text, filters)
17
- filters.inject(text) do |text, filter|
18
- filter.process(text)
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
@@ -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
- @position = Position.new
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
- warn "Got a sequence for a slide - not sure how to parse that. Skipping"
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
- raise "Slide content needs to be a string, was: #{content.inspect}" unless String === content
90
- @content = content
55
+ @raw_content = content
91
56
  end
92
57
 
93
58
  value_from_config("notes") do |notes|
94
- raise "Slide notes needs to be a string, was: #{notes.inspect}" unless String === notes
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 :content, :html_classes, :html_id, :notes
151
- attr_accessor :position, :rotation, :content_filters, :note_filters
152
- attr_accessor :scale
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