rhet-butler 0.5.0 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (134) hide show
  1. checksums.yaml +15 -0
  2. data/default-configuration/assets/javascript/keyboard-nav.js +91 -0
  3. data/default-configuration/assets/javascript/rhet-present.js +855 -0
  4. data/default-configuration/assets/javascript/rhet-present.min.js +55 -0
  5. data/default-configuration/assets/stylesheets/_animate-helpers.scss +41 -0
  6. data/default-configuration/assets/stylesheets/animate/_attention.scss +36 -0
  7. data/default-configuration/assets/stylesheets/animate/_bounce.scss +71 -0
  8. data/default-configuration/assets/stylesheets/animate/_fade.scss +56 -0
  9. data/default-configuration/assets/stylesheets/animate/_flip.scss +98 -0
  10. data/default-configuration/assets/stylesheets/animate/_lightSpeed.scss +20 -0
  11. data/default-configuration/assets/stylesheets/animate/_roll.scss +20 -0
  12. data/default-configuration/assets/stylesheets/animate/_rotate.scss +40 -0
  13. data/default-configuration/assets/stylesheets/animate/_special.scss +17 -0
  14. data/default-configuration/assets/stylesheets/animate/_windblown.sass +17 -0
  15. data/default-configuration/assets/stylesheets/animate/attention/._pulse.scss.swp +0 -0
  16. data/default-configuration/assets/stylesheets/animate/attention/_flash.scss +34 -0
  17. data/default-configuration/assets/stylesheets/animate/attention/_pulse.scss +28 -0
  18. data/default-configuration/assets/stylesheets/animate/attention/_shake.scss +53 -0
  19. data/default-configuration/assets/stylesheets/animate/attention/_swing.scss +40 -0
  20. data/default-configuration/assets/stylesheets/animate/attention/_tada.scss +51 -0
  21. data/default-configuration/assets/stylesheets/animate/attention/_wiggle.scss +52 -0
  22. data/default-configuration/assets/stylesheets/animate/attention/_wobble.scss +41 -0
  23. data/default-configuration/assets/stylesheets/animate/bounce/_bounceIn.scss +151 -0
  24. data/default-configuration/assets/stylesheets/animate/bounce/_bounceOut.scss +139 -0
  25. data/default-configuration/assets/stylesheets/animate/fade/_fadeIn.sass +139 -0
  26. data/default-configuration/assets/stylesheets/animate/fade/_fadeOut.sass +139 -0
  27. data/default-configuration/assets/stylesheets/animate/flip/_flipIn.scss +78 -0
  28. data/default-configuration/assets/stylesheets/animate/flip/_flipOut.scss +66 -0
  29. data/default-configuration/assets/stylesheets/animate/lightSpeed/_lightSpeedIn.scss +37 -0
  30. data/default-configuration/assets/stylesheets/animate/lightSpeed/_lightSpeedOut.scss +29 -0
  31. data/default-configuration/assets/stylesheets/animate/roll/_rollIn.scss +29 -0
  32. data/default-configuration/assets/stylesheets/animate/roll/_rollOut.scss +28 -0
  33. data/default-configuration/assets/stylesheets/animate/rotate/_rotateIn.scss +208 -0
  34. data/default-configuration/assets/stylesheets/animate/rotate/_rotateOut.scss +208 -0
  35. data/default-configuration/assets/stylesheets/animate/special/_hinge.scss +49 -0
  36. data/default-configuration/assets/stylesheets/animate/windblown/_windblownIn.sass +28 -0
  37. data/default-configuration/assets/stylesheets/animate/windblown/_windblownOut.sass +24 -0
  38. data/default-configuration/assets/stylesheets/font.css +30 -0
  39. data/default-configuration/assets/stylesheets/highlight/arta.css +158 -0
  40. data/default-configuration/assets/stylesheets/highlight/ascetic.css +50 -0
  41. data/default-configuration/assets/stylesheets/highlight/brown_paper.css +104 -0
  42. data/default-configuration/assets/stylesheets/highlight/brown_papersq.png +0 -0
  43. data/default-configuration/assets/stylesheets/highlight/dark.css +103 -0
  44. data/default-configuration/assets/stylesheets/highlight/default.css +135 -0
  45. data/default-configuration/assets/stylesheets/highlight/far.css +111 -0
  46. data/default-configuration/assets/stylesheets/highlight/github.css +127 -0
  47. data/default-configuration/assets/stylesheets/highlight/googlecode.css +144 -0
  48. data/default-configuration/assets/stylesheets/highlight/idea.css +121 -0
  49. data/default-configuration/assets/stylesheets/highlight/ir_black.css +104 -0
  50. data/default-configuration/assets/stylesheets/highlight/magula.css +120 -0
  51. data/default-configuration/assets/stylesheets/highlight/monokai.css +114 -0
  52. data/default-configuration/assets/stylesheets/highlight/pojoaque.css +104 -0
  53. data/default-configuration/assets/stylesheets/highlight/pojoaque.jpg +0 -0
  54. data/default-configuration/assets/stylesheets/highlight/rainbow.css +114 -0
  55. data/default-configuration/assets/stylesheets/highlight/school_book.css +111 -0
  56. data/default-configuration/assets/stylesheets/highlight/school_book.png +0 -0
  57. data/default-configuration/assets/stylesheets/highlight/solarized_light.css +88 -0
  58. data/default-configuration/assets/stylesheets/highlight/sunburst.css +158 -0
  59. data/default-configuration/assets/stylesheets/highlight/tomorrow-night-blue.css +52 -0
  60. data/default-configuration/assets/stylesheets/highlight/tomorrow-night-bright.css +51 -0
  61. data/default-configuration/assets/stylesheets/highlight/tomorrow-night-eighties.css +51 -0
  62. data/default-configuration/assets/stylesheets/highlight/tomorrow-night.css +52 -0
  63. data/default-configuration/assets/stylesheets/highlight/tomorrow.css +49 -0
  64. data/default-configuration/assets/stylesheets/highlight/vs.css +86 -0
  65. data/default-configuration/assets/stylesheets/highlight/xcode.css +154 -0
  66. data/default-configuration/assets/stylesheets/highlight/zenburn.css +114 -0
  67. data/default-configuration/assets/stylesheets/presenter/rhet.css.sass +160 -0
  68. data/default-configuration/assets/stylesheets/rhet.css.sass +142 -0
  69. data/default-configuration/assets/themes.googleusercontent.com/static/fonts/arimo/v5/K-bXE71xZHgbUS_UdQjugvesZW2xOQ-xsNqO47m55DA.ttf +0 -0
  70. data/default-configuration/assets/themes.googleusercontent.com/static/fonts/cinzeldecorative/v1/pXhIVnhFtL_B9Vb1wq2F9wIh9oxuYcmvOvyh_107lQs.ttf +0 -0
  71. data/default-configuration/assets/themes.googleusercontent.com/static/fonts/cinzeldecorative/v1/pXhIVnhFtL_B9Vb1wq2F9zCUrkmwPfdnoTjOU_kXqBI.ttf +0 -0
  72. data/default-configuration/assets/themes.googleusercontent.com/static/fonts/droidsansmono/v4/ns-m2xQYezAtqh7ai59hJYW_AySPyikQrZReizgrnuw.ttf +0 -0
  73. data/default-configuration/assets/themes.googleusercontent.com/static/fonts/slackey/v3/bJZDrYrGx8atJRHR9DVdqg.ttf +0 -0
  74. data/default-configuration/common/config.yaml +17 -0
  75. data/default-configuration/common/templates/group.html.erb +5 -0
  76. data/default-configuration/common/templates/presentation.html.erb +11 -17
  77. data/default-configuration/common/templates/presenter-qr.html.erb +3 -3
  78. data/default-configuration/common/templates/slide.html.erb +3 -0
  79. data/default-configuration/common/templates/stylesheets.html.erb +1 -1
  80. data/default-configuration/presenter/templates/live-javascript.html.erb +4 -3
  81. data/default-configuration/presenter/templates/slide.html.erb +6 -0
  82. data/default-configuration/presenter/templates/stylesheets.html.erb +1 -1
  83. data/default-configuration/skels/config.yaml +15 -0
  84. data/default-configuration/skels/slides.yaml +6 -0
  85. data/default-configuration/viewer/templates/live-javascript.html.erb +1 -1
  86. data/lib/rhet-butler/arrangement-finder.rb +71 -0
  87. data/lib/rhet-butler/command-line.rb +69 -1
  88. data/lib/rhet-butler/configuration.rb +20 -5
  89. data/lib/rhet-butler/file-loading.rb +28 -0
  90. data/lib/rhet-butler/file-manager.rb +42 -22
  91. data/lib/rhet-butler/filter-resolver.rb +45 -0
  92. data/lib/rhet-butler/html-generator.rb +24 -4
  93. data/lib/rhet-butler/include-processor.rb +55 -0
  94. data/lib/rhet-butler/layout-rule.rb +17 -13
  95. data/lib/rhet-butler/resource-localizer.rb +22 -0
  96. data/lib/rhet-butler/sass-functions.rb +40 -0
  97. data/lib/rhet-butler/slide-arranger.rb +39 -0
  98. data/lib/rhet-butler/slide-group.rb +56 -21
  99. data/lib/rhet-butler/slide-includer.rb +5 -2
  100. data/lib/rhet-butler/slide-loader.rb +16 -332
  101. data/lib/rhet-butler/slide-processor.rb +27 -0
  102. data/lib/rhet-butler/slide-renderer.rb +42 -0
  103. data/lib/rhet-butler/slide-renderers/code.rb +19 -0
  104. data/lib/rhet-butler/slide-renderers/cues.rb +27 -0
  105. data/lib/rhet-butler/slide-renderers/textile.rb +14 -0
  106. data/lib/rhet-butler/slide-rendering.rb +22 -0
  107. data/lib/rhet-butler/slide-traverser.rb +45 -0
  108. data/lib/rhet-butler/slide.rb +40 -30
  109. data/lib/rhet-butler/stasis/css-transform.rb +55 -0
  110. data/lib/rhet-butler/stasis/document-transform.rb +32 -0
  111. data/lib/rhet-butler/stasis/html-transform.rb +51 -0
  112. data/lib/rhet-butler/stasis/http-loader.rb +19 -0
  113. data/lib/rhet-butler/stasis/identity-transform.rb +18 -0
  114. data/lib/rhet-butler/stasis/rack-loader.rb +57 -0
  115. data/lib/rhet-butler/stasis/resource-mapping.rb +55 -0
  116. data/lib/rhet-butler/stasis/transform-queue.rb +87 -0
  117. data/lib/rhet-butler/stasis/writer.rb +35 -0
  118. data/lib/rhet-butler/stasis.rb +18 -0
  119. data/lib/rhet-butler/static-generator.rb +21 -29
  120. data/lib/rhet-butler/web/assets-app.rb +24 -8
  121. data/lib/rhet-butler/web/main-app.rb +17 -8
  122. data/lib/rhet-butler/web/presentation-app.rb +22 -14
  123. data/lib/rhet-butler/web/qr-display-app.rb +4 -1
  124. data/lib/rhet-butler/yaml-schema.rb +5 -4
  125. data/lib/rhet-butler/yaml-type.rb +24 -1
  126. data/spec/html-generation.rb +7 -1
  127. data/spec/presentation-view.rb +33 -8
  128. data/spec/rhet-butler.rb +0 -13
  129. data/spec/slide-loader.rb +3 -3
  130. data/spec/slide-processing.rb +6 -3
  131. metadata +209 -119
  132. data/default-configuration/assets/javascript/impress.js +0 -800
  133. data/default-configuration/assets/stylesheets/presenter/presentation.css +0 -477
  134. data/lib/rhet-butler.rb +0 -2
@@ -1,3 +1,3 @@
1
1
  <link href="/stylesheets/google-open-sans.css" rel="stylesheet" />
2
- <link href="/stylesheets/presenter/presentation.css" rel="stylesheet" />
2
+ <link href="/stylesheets/presenter/rhet.css" rel="stylesheet" />
3
3
  <link href="/stylesheets/highlight/solarized_dark.css" rel="stylesheet" />
@@ -0,0 +1,15 @@
1
+ ---
2
+ named-filters:
3
+ normal:
4
+ - !textile
5
+ - !cues
6
+ code:
7
+ - !code
8
+ - !textile
9
+ - !cues
10
+
11
+ default-content-filters:
12
+ normal
13
+
14
+ default-note-filters:
15
+ normal
@@ -0,0 +1,6 @@
1
+ !slide An awesome presentation
2
+ !group
3
+ !include whoami.yaml
4
+ !group
5
+ !slide |
6
+ contents: It'll knock your socks off!
@@ -7,7 +7,7 @@
7
7
 
8
8
  sock.onmessage = function(e) {
9
9
  console.log("message", e.data);
10
- impress().goto(e.data);
10
+ presenter.moveTo(e.data);
11
11
  };
12
12
 
13
13
  sock.onclose = function() {
@@ -0,0 +1,71 @@
1
+ require 'rhet-butler/arrangement'
2
+ require 'rhet-butler/slide-traverser'
3
+ module RhetButler
4
+ class ArrangementFinder < SlideTraverser
5
+ attr_accessor :root_arrangement, :root_group, :blueprint
6
+
7
+ def initialize
8
+ super
9
+ end
10
+
11
+ def setup
12
+ if @blueprint.empty?
13
+ raise "Empty blueprint - can't layout slides"
14
+ end
15
+
16
+ @blueprint.combination(2) do |first, second|
17
+ if first.match == second.match
18
+ if first.match == {}
19
+ raise "Two default rules (default or match: {}) - please fix"
20
+ end
21
+ warn "Blueprint rules with duplicate rules: will ignore the later one:"
22
+ warn second.inspect
23
+ end
24
+ end
25
+
26
+ unless @blueprint.last.match == {}
27
+ warn "Last blueprint rule not a default - fixing..."
28
+ defaults, rules = @blueprint.partition{|rule| rule.match == {}}
29
+ raise "Multiple default blueprint rules" unless defaults.length < 2
30
+ raise "No default blueprint rule" unless defaults.length > 0
31
+ @blueprint = rules + defaults
32
+ end
33
+
34
+ default_rule = @blueprint.last
35
+ @active_match = default_rule
36
+ @root_arrangement = default_rule.layout
37
+ descend(@root_group, @root_arrangement)
38
+ end
39
+
40
+ def on_slide(slide)
41
+ target_stack.last.slides << slide
42
+ end
43
+
44
+ def on_group(group)
45
+ arrangement = find_arrangement(group)
46
+ if arrangement != target_stack.last
47
+ target_stack.last.slides << arrangement
48
+ end
49
+ descend(group, arrangement)
50
+ end
51
+
52
+ def match?(filter, value)
53
+ return filter === value
54
+ end
55
+
56
+ def find_arrangement(group)
57
+ match = {}
58
+ template = nil
59
+ match = blueprint.find do |rule|
60
+ rule.match?(group)
61
+ end
62
+
63
+ if !match.nil? and match != @active_match
64
+ @active_match = match
65
+ return match.layout
66
+ else
67
+ return target_stack.last
68
+ end
69
+ end
70
+ end
71
+ end
@@ -10,18 +10,65 @@ module RhetButler
10
10
  method_option :root_slide, :type => :string
11
11
  end
12
12
 
13
+ desc "init", "Create example skeleton files to get started with"
14
+ def init
15
+ require 'fileutils'
16
+
17
+ file_manager = FileManager.new(options)
18
+
19
+ FileUtils.mkdir_p "assets"
20
+ FileUtils.mkdir_p "presenter/assets"
21
+ FileUtils.mkdir_p "viewer/assets"
22
+
23
+ skels = file_manager.all_files.sub_set("skels")
24
+
25
+ %w{slides.yaml}.each do |path|
26
+ unless Dir.glob(path).empty?
27
+ puts "Refusing to clobber existing: #{path}"
28
+ next
29
+ end
30
+
31
+ File::open(path, "w") do |file|
32
+ file.write skels.contents(path)
33
+ end
34
+ end
35
+ end
36
+
13
37
  desc "static", "Builds a static version of the presentation"
14
38
  method_option :target, :type => :string
39
+ method_option :quiet, :type => :boolean, :aliases => "-q", :desc => "Suppress listing of files as their written"
15
40
  shared_options
16
41
  def static
17
42
  require 'rhet-butler/static-generator'
18
43
 
19
44
  file_manager = FileManager.new(options)
20
45
  generator = StaticGenerator.new(file_manager)
46
+ generator.store_log = $stderr unless options[:quiet]
21
47
 
22
48
  generator.go!
23
49
  end
24
50
 
51
+ desc "import URL TARGET", "Pulls presentation assets from the web and removes remote dependencies"
52
+ method_option :role, :type => :string, :desc => "The presentation role for to localize to", :enum => %w{presenter viewer common}
53
+ method_option :quiet, :type => :boolean, :aliases => "-q", :desc => "Suppress listing of files as their written"
54
+ def import(url, target)
55
+ require 'rhet-butler/resource-localizer'
56
+ file_manager = FileManager.new(options)
57
+ localizer = ResourceLocalizer.new
58
+
59
+ case options[:role]
60
+ when "presenter", "viewer"
61
+ localizer.files = file_manager.aspect_search_path(options[:role])
62
+ else
63
+ localizer.files = file_manager.all_files
64
+ end
65
+ localizer.source_uri = url
66
+ localizer.target_path = target
67
+ localizer.store_log = $stderr unless options[:quiet]
68
+
69
+ localizer.go!
70
+ end
71
+
25
72
  desc "check", "Load slide set to check syntax"
26
73
  shared_options
27
74
  def check
@@ -29,12 +76,31 @@ module RhetButler
29
76
 
30
77
  file_manager = FileManager.new(options)
31
78
  app = Web::MainApp.new(file_manager)
79
+ app.presentation_app_class = Web::MemoizedPresentationApp
80
+ app.assets_app_class = Web::MemoizedAssetsApp
81
+ app.check
32
82
 
83
+ slide_count = app.viewer_app.root_step.each_slide.inject(0) do |count, slide|
84
+ count + 1
85
+ end
33
86
  say "Slides loaded and parsed"
34
- say " #{app.viewer_app.slides.length} slides loaded"
87
+ say " #{slide_count} slides loaded"
35
88
  say " Serving slides and assets found in: #{app.slides}"
36
89
  end
37
90
 
91
+ desc "author", "Run the presentation in authoring mode"
92
+ shared_options
93
+ def author
94
+ require 'rhet-butler/web/main-app'
95
+
96
+ file_manager = FileManager.new(options)
97
+ app = Web::MainApp.new(file_manager)
98
+ app.presentation_app_class = Web::PresentationApp
99
+ app.assets_app_class = Web::AssetsApp
100
+ app.check
101
+ app.start
102
+ end
103
+
38
104
  desc "serve", "Run the presentation server"
39
105
  shared_options
40
106
  def serve
@@ -42,6 +108,8 @@ module RhetButler
42
108
 
43
109
  file_manager = FileManager.new(options)
44
110
  app = Web::MainApp.new(file_manager)
111
+ app.presentation_app_class = Web::MemoizedPresentationApp
112
+ app.assets_app_class = Web::MemoizedAssetsApp
45
113
  app.check
46
114
  app.start
47
115
  end
@@ -1,3 +1,5 @@
1
+ require 'rhet-butler/yaml-schema'
2
+
1
3
  module RhetButler
2
4
  #This class is used to manage application config throughout. Basically it
3
5
  #wraps a hash loaded from the base fileset. Since the file search path can be
@@ -10,8 +12,9 @@ module RhetButler
10
12
  def initialize(files, overrides=nil)
11
13
  @base_hash =
12
14
  begin
13
- files.find("config.yaml").contents rescue {}
14
- rescue Object
15
+ files.find("config.yaml").contents
16
+ rescue Valise::Errors::NotFound
17
+ warn "No config.yaml found in #{files.inspect} - using defaults"
15
18
  {}
16
19
  end
17
20
  @base_hash.merge!(overrides) unless overrides.nil?
@@ -45,6 +48,10 @@ module RhetButler
45
48
  @base_hash["sources"] || []
46
49
  end
47
50
 
51
+ def template_cache
52
+ @base_hash["template-cache"] || ".template-cache"
53
+ end
54
+
48
55
  def static_target
49
56
  @base_hash["static_target"] || "static"
50
57
  end
@@ -58,7 +65,7 @@ module RhetButler
58
65
  end
59
66
 
60
67
  def arrangement_blueprint
61
- @base_hash["blueprint"] || {}
68
+ @base_hash["blueprint"] || []
62
69
  end
63
70
 
64
71
  def serve_port
@@ -69,8 +76,16 @@ module RhetButler
69
76
  @base_hash["root_slide"] || "slides.yaml"
70
77
  end
71
78
 
72
- def default_slide_type
73
- @base_hash["default_slide_type"] || "textile"
79
+ def named_filter_lists
80
+ @base_hash["named-filters"] || {"textile" => [SlideRenderers::Textile.new]}
81
+ end
82
+
83
+ def default_content_filters
84
+ @default_content_filters ||= @base_hash["default-content-filters"] || "textile"
85
+ end
86
+
87
+ def default_note_filters
88
+ @default_note_filters ||= @base_hash["default-note-filters"] || "textile"
74
89
  end
75
90
  end
76
91
  end
@@ -0,0 +1,28 @@
1
+ require 'rhet-butler/yaml-schema'
2
+
3
+ module RhetButler
4
+ class FileLoading
5
+ def initialize(file_set)
6
+ @file_set = file_set
7
+ @loaded_paths = {}
8
+ end
9
+ attr_reader :loaded_paths, :file_set
10
+
11
+ def initialize_copy(other)
12
+ @file_set = other.file_set
13
+ @loaded_paths = other.loaded_paths.dup
14
+ end
15
+
16
+ def load_file(rel_path)
17
+ file = @file_set.find(rel_path)
18
+
19
+ if @loaded_paths.has_key?(file.full_path)
20
+ raise "Circular inclusion of slides: >> #{file.full_path} << #{@loaded_paths.keys.inspect}"
21
+ else
22
+ @loaded_paths[file.full_path] = true
23
+ end
24
+
25
+ return YAML.load_stream(file.contents).flatten
26
+ end
27
+ end
28
+ end
@@ -1,5 +1,9 @@
1
1
  require 'valise'
2
2
  require 'rhet-butler/configuration'
3
+ require 'compass/import-once'
4
+ require 'compass/core'
5
+ require 'rhet-butler/sass-functions'
6
+ require 'fileutils'
3
7
 
4
8
  module RhetButler
5
9
  #All file handling is routed through this class.
@@ -50,18 +54,51 @@ module RhetButler
50
54
  all_files.sub_set("slides") + all_files
51
55
  end
52
56
 
53
- def base_assets
54
- all_files.templates("assets")
57
+ def all_files
58
+ current_directory + configured_search_path + base_config_set
59
+ end
60
+
61
+ def base_config_search_path
62
+ set = current_directory + base_config_set
63
+ set + set.sub_set("common")
64
+ end
65
+
66
+ def template_config(type)
67
+ case type
68
+ when "sass", "scss"
69
+ load_paths = all_files.sub_set("assets/stylesheets").map(&:to_s)
70
+ load_paths << Compass::Core.base_directory("stylesheets")
71
+ FileUtils::mkdir_p base_config.template_cache
72
+ {:template_options =>
73
+ { :load_paths => load_paths, :cache_location => base_config.template_cache }}
74
+ else
75
+ nil
76
+ end
55
77
  end
56
78
 
57
79
  def aspect_config(aspect_name)
58
- @cached_configs[aspect_name] ||= load_config(aspect_search_path(aspect_name))
80
+ load_config(aspect_search_path(aspect_name))
59
81
  end
60
82
 
61
- def aspect_templates(aspect)
62
- @cached_templates[aspect] ||= aspect_search_path(aspect).templates
83
+ def base_assets(template_cache)
84
+ all_files.templates("assets") do |mapping|
85
+ (template_config(mapping) || {}).merge(:template_cache => template_cache)
86
+ end
63
87
  end
64
88
 
89
+ def aspect_templates(aspect, template_cache = nil)
90
+ aspect_search_path(aspect).templates do |mapping|
91
+ (template_config(mapping) || {}).merge(:template_cache => template_cache)
92
+ end
93
+ end
94
+
95
+ def aspect_search_path(aspect)
96
+ aspect = aspect.to_s
97
+ set = all_files.sub_set(aspect)
98
+ set += all_files.sub_set("common")
99
+ set += all_files
100
+ return set
101
+ end
65
102
 
66
103
  def load_config(files)
67
104
  Configuration.new(files, @overrides)
@@ -105,22 +142,5 @@ module RhetButler
105
142
  end
106
143
  end
107
144
  end
108
-
109
- def all_files
110
- current_directory + configured_search_path + base_config_set
111
- end
112
-
113
- def base_config_search_path
114
- set = current_directory + base_config_set
115
- set + set.sub_set("common")
116
- end
117
-
118
- def aspect_search_path(aspect)
119
- aspect = aspect.to_s
120
- set = all_files.sub_set(aspect)
121
- set += all_files.sub_set("common")
122
- set += all_files
123
- return set
124
- end
125
145
  end
126
146
  end
@@ -0,0 +1,45 @@
1
+ require 'rhet-butler/slide-renderer'
2
+ require 'rhet-butler/slide-traverser'
3
+ require 'pp'
4
+
5
+ module RhetButler
6
+ class FilterResolver < SlideTraverser
7
+ attr_accessor :root_group, :named_filter_lists, :default_content_filters, :default_note_filters
8
+
9
+ def setup
10
+ named_filter_lists.each_key do |name|
11
+ named_filter_lists[name] = get_filters(named_filter_lists[name])
12
+ end
13
+ self.default_content_filters = get_filters(default_content_filters)
14
+ self.default_note_filters = get_filters(default_note_filters)
15
+ descend(@root_group, @root_group)
16
+ end
17
+
18
+ def get_filters(filter, used_names=nil)
19
+ case filter
20
+ when String
21
+ if !used_names.nil? and used_names.include?(filter)
22
+ raise "Recursive filter list definitions: #{filter} already referenced in #{used_names}"
23
+ end
24
+ get_filters(named_filter_lists.fetch(filter), (used_names||[])+[filter]) do
25
+ raise "No filter named #{filter}"
26
+ end
27
+ when Array
28
+ filter.map{|item| get_filters(item)}.flatten
29
+ else
30
+ filter
31
+ end
32
+ end
33
+
34
+ def on_slide(slide)
35
+ slide.content_filters = get_filters(slide.content_filters || default_content_filters)
36
+ slide.html_classes += slide.content_filters.map do |filter|
37
+ filter.html_class
38
+ end
39
+ slide.note_filters = get_filters(slide.note_filters || default_note_filters)
40
+ slide.html_classes += slide.content_filters.map do |filter|
41
+ "note-" + filter.html_class unless filter.html_class.nil?
42
+ end
43
+ end
44
+ end
45
+ end
@@ -13,17 +13,37 @@ module RhetButler
13
13
  attr_accessor :author_name, :title, :description
14
14
  end
15
15
 
16
+ class RenderFacade
17
+ def initialize(templates, item)
18
+ @templates = templates
19
+ @item = item
20
+ end
21
+
22
+ def method_missing(name, *args, &block)
23
+ @item.__send__(name, *args, &block)
24
+ end
25
+
26
+ def render(path, item=nil, locals=nil)
27
+ scope = if(item.nil?)
28
+ self
29
+ else
30
+ self.class.new(@templates, item)
31
+ end
32
+ @templates.find(path).contents.render(scope || self, locals || {})
33
+ end
34
+ end
35
+
16
36
  def initialize(configuration, templates)
17
37
  @impress_config = configuration.impress_config
18
38
  @templates = templates
19
- @slides = []
39
+ @root_step
20
40
  @presentation = Presentation.new(configuration)
21
41
  end
22
42
 
23
- attr_accessor :slides, :presentation, :impress_config
43
+ attr_accessor :root_step, :presentation, :impress_config
24
44
 
25
- def render(path, scope=nil, locals=nil)
26
- @templates.find(path).contents.render(scope || self, locals || {})
45
+ def render(template, item=nil)
46
+ RenderFacade.new(@templates, item || self).render(template)
27
47
  end
28
48
  end
29
49
  end
@@ -0,0 +1,55 @@
1
+ require 'rhet-butler/slide-traverser'
2
+ module RhetButler
3
+ class IncludeProcessor < SlideTraverser
4
+ Collector = Struct.new(:group, :slides, :loader)
5
+ attr_accessor :root_group
6
+
7
+ def initialize(loader)
8
+ @loader = loader
9
+ super()
10
+ end
11
+
12
+ def current_loader
13
+ if target_stack.empty?
14
+ return @loader
15
+ else
16
+ return target_stack.last.loader
17
+ end
18
+ end
19
+
20
+ def setup
21
+ descend(@root_group, @root_group)
22
+ end
23
+
24
+ def descend(source, dest)
25
+ unless Collector === dest
26
+ dest = Collector.new(dest, [], current_loader)
27
+ end
28
+ super(source, dest)
29
+ end
30
+
31
+ def ascend
32
+ target = target_stack.pop
33
+ unless target == target_stack.last
34
+ target.group.slides = target.slides
35
+ end
36
+ iter_stack.pop
37
+ end
38
+
39
+ def on_include(includer)
40
+ loader = includer.load(current_loader)
41
+ collector = target_stack.last.dup
42
+ collector.loader = loader
43
+ descend(includer, collector)
44
+ end
45
+
46
+ def on_slide(slide)
47
+ target_stack.last.slides << slide
48
+ end
49
+
50
+ def on_group(group)
51
+ target_stack.last.slides << group
52
+ super
53
+ end
54
+ end
55
+ end
@@ -1,8 +1,9 @@
1
1
  require 'rhet-butler/yaml-type'
2
2
 
3
3
  module RhetButler
4
- class LayoutRule
5
- include YamlType
4
+ class LayoutRule < YamlType
5
+ register "layout-rule"
6
+
6
7
  def initialize
7
8
  @match = {}
8
9
  @layout_args = nil
@@ -17,19 +18,22 @@ module RhetButler
17
18
  %w[layout]
18
19
  end
19
20
 
20
- def init_with(coder)
21
- @config_hash =
22
- case coder.type
23
- when :seq
24
- { 'match' => coder.seq[0], 'layout' => coder.seq[1] }
25
- when :map
26
- coder.map
27
- else
28
- raise "Tried to configure a layout rule with non-sequence: #{coder.inspect}"
29
- end
21
+ def setup_defaults
30
22
 
31
- check_config_hash(@config_hash)
23
+ end
24
+
25
+ def normalize_config(coder)
26
+ case coder.type
27
+ when :seq
28
+ { 'match' => coder.seq[0], 'layout' => coder.seq[1] }
29
+ when :map
30
+ coder.map
31
+ else
32
+ raise "Tried to configure a layout rule with non-sequence: #{coder.inspect}"
33
+ end
34
+ end
32
35
 
36
+ def configure
33
37
  value_from_config("match") do |value|
34
38
  if value == 'default'
35
39
  @match = {}
@@ -0,0 +1,22 @@
1
+ require 'rhet-butler/web/main-app'
2
+ require 'rhet-butler/stasis'
3
+
4
+ module RhetButler
5
+ class ResourceLocalizer
6
+ attr_accessor :files, :source_uri, :target_path, :store_log
7
+
8
+ def go!
9
+ app_url = "http://example.com/"
10
+ transform_queue = Stasis::TransformQueue.new
11
+ transform_queue.loader = Stasis::HTTPLoader.new
12
+ transform_queue.mapping = Stasis::ResourceMapping.new
13
+ transform_queue.mapping.default_uri = app_url
14
+ transform_queue.writer = Stasis::ValiseWriter.new(@files)
15
+ transform_queue.writer.store_log = store_log
16
+
17
+ target_uri = transform_queue.mapping.target_link_for(source_uri)
18
+ transform_queue.add_mapping(source_uri, target_uri, target_path)
19
+ transform_queue.go
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,40 @@
1
+ require 'sass'
2
+ require 'sass/script/functions'
3
+
4
+ module Sass::Script
5
+ module Functions
6
+ def exp(modulus, exponent)
7
+ assert_type modulus, :Number
8
+ assert_type exponent, :Number
9
+
10
+ Number.new(modulus.value ** exponent.value, modulus.numerator_units, modulus.denominator_units)
11
+ end
12
+ declare :exp, :args => [:modulus, :exponent]
13
+
14
+ def tween(initial, final, ratio)
15
+ assert_type initial, :Number
16
+ assert_type final, :Number
17
+ assert_type ratio, :Number
18
+
19
+ initial_units = [initial.numerator_units, initial.denominator_units]
20
+ final_units = [final.numerator_units, final.denominator_units]
21
+ unless initial_units == final_units
22
+ raise ArgumentError, "Mismatched units: initial: #{initial_units.inspect} != final: #{final_units.inspect}"
23
+ end
24
+
25
+ ratio_units = ratio.numerator_units - ratio.denominator_units
26
+ ratio_value = case ratio_units
27
+ when %w{%}
28
+ ratio.value / 100.0
29
+ when []
30
+ ratio.value
31
+ else
32
+ raise ArgumentError, "Bad units for ratio: #{ratio_units.inspect}"
33
+ end
34
+
35
+ Number.new(initial.value + ((final.value - initial.value) * ratio_value), *initial_units)
36
+ end
37
+
38
+ declare :tween, :args => [:initial, :final, :ratio]
39
+ end
40
+ end
@@ -0,0 +1,39 @@
1
+ require 'rhet-butler/slide-traverser'
2
+ module RhetButler
3
+ class SlideArranger < SlideTraverser
4
+ attr_reader :slides, :current_slide
5
+ attr_accessor :root_arrangement
6
+
7
+ def setup
8
+ @slides = []
9
+ on_group(@root_arrangement)
10
+ end
11
+
12
+ def null_slide
13
+ @null_slide ||= Slide.new
14
+ end
15
+
16
+ def previous_slide
17
+ case @previous_slide
18
+ when Slide
19
+ @previous_slide
20
+ when nil
21
+ null_slide
22
+ else
23
+ @previous_slide.previous_slide
24
+ end
25
+ end
26
+
27
+ def on_slide(slide)
28
+ @current_slide = slide.dup
29
+ target_stack.last.arrange(self)
30
+ @slides.push @current_slide
31
+ @previous_slide = @current_slide
32
+ end
33
+
34
+ def ascend
35
+ @previous_slide = target_stack.last
36
+ super
37
+ end
38
+ end
39
+ end