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,14 +1,15 @@
1
1
  require 'rhet-butler/yaml-type'
2
2
 
3
3
  module RhetButler
4
- class Slide
5
- include YamlType
4
+ class Slide < YamlType
5
+ register "slide"
6
+
6
7
  class << self
7
8
  def optional_config
8
9
  %w[
9
10
  title html_id html_classes html_class
10
11
  pos_x pos_y pos_z rot_x rot_y rot_z scale
11
- notes type
12
+ notes filters note_filters
12
13
  ]
13
14
  end
14
15
 
@@ -46,7 +47,8 @@ module RhetButler
46
47
  end
47
48
 
48
49
  def setup_defaults
49
- @html_classes = ["step"]
50
+ @template_name = "slide.html"
51
+ @html_classes = ["slide"]
50
52
  @html_id = nil
51
53
  @position = Position.new
52
54
  @rotation = Rotation.new
@@ -55,10 +57,6 @@ module RhetButler
55
57
  @type = nil
56
58
  end
57
59
 
58
- def initialize
59
- setup_defaults
60
- end
61
-
62
60
  def initialize_copy(source)
63
61
  super
64
62
  @config_hash = source.config_hash.dup unless source.config_hash.nil?
@@ -67,25 +65,22 @@ module RhetButler
67
65
  @html_id = source.html_id.dup unless source.html_id.nil?
68
66
  @position = source.position.dup unless source.position.nil?
69
67
  @rotation = source.rotation.dup unless source.rotation.nil?
70
- @type = source.type.dup unless source.type.nil?
71
68
  @html_classes = source.html_classes.dup unless source.html_classes.nil?
72
69
  end
73
70
 
74
- def init_with(coder)
75
- setup_defaults
76
-
77
- @config_hash =
78
- case coder.type
79
- when :map
80
- coder.map
81
- when :scalar
82
- { 'content' => coder.scalar.to_s }
83
- when :seq
84
- warn "Got a sequence for a slide - not sure how to parse that. Skipping"
85
- end
86
71
 
87
- check_config_hash(@config_hash)
72
+ def normalize_config(coder)
73
+ case coder.type
74
+ when :map
75
+ coder.map
76
+ when :scalar
77
+ { 'content' => coder.scalar.to_s }
78
+ when :seq
79
+ warn "Got a sequence for a slide - not sure how to parse that. Skipping"
80
+ end
81
+ end
88
82
 
83
+ def configure
89
84
  value_from_config("title") do |title|
90
85
  @html_id = title.downcase.split(/\s/).join("-")
91
86
  end
@@ -136,24 +131,39 @@ module RhetButler
136
131
  @scale = value
137
132
  end
138
133
 
139
- value_from_config("type") do |value|
140
- @type = value
141
- @html_classes << value
134
+ value_from_config("filters") do |value|
135
+ @content_filters = value
136
+ end
137
+
138
+ value_from_config("note-filters") do |value|
139
+ @note_filters = value
140
+ @html_classes += value.map do |filter|
141
+ "notes-" + filter.html_class unless filter.html_class.nil?
142
+ end
142
143
  end
143
144
  end
144
145
 
145
146
  attr_reader :config_hash
146
147
  attr_accessor :content, :html_classes, :html_id, :notes
147
- attr_reader :position, :rotation, :type
148
+ attr_accessor :position, :rotation, :content_filters, :note_filters
148
149
  attr_accessor :scale
150
+ attr_reader :template_name
151
+
152
+ def id_attr
153
+ if @html_id.nil?
154
+ return ""
155
+ else
156
+ "id='#@html_id'"
157
+ end
158
+ end
159
+
160
+ def classes
161
+ @html_classes.join(" ")
162
+ end
149
163
 
150
164
  def impress_attrs
151
165
  attrs = []
152
- unless @html_id.nil?
153
- attrs << "id='#@html_id'"
154
- end
155
166
 
156
- attrs << "class='#{@html_classes.join(" ")}'"
157
167
  attrs << @position.to_attrs
158
168
  attrs << @rotation.to_attrs
159
169
  attrs << "data-scale='#{"%0.2f" % scale}'"
@@ -0,0 +1,55 @@
1
+ require 'rhet-butler/stasis/document-transform'
2
+ module RhetButler
3
+ module Stasis
4
+ require 'crass'
5
+ class CSSTransform < DocumentTransform
6
+ register "text/css"
7
+
8
+ def parse_document
9
+ @parsed = Crass::parse(document.body)
10
+ end
11
+
12
+ def url_nodes(node_list)
13
+ return [] if node_list.nil?
14
+
15
+ list = []
16
+
17
+ node_list.each do |node|
18
+ case node[:node]
19
+ when :url
20
+ list << node
21
+ when :at_rule
22
+ if node[:name] == "import"
23
+ list += node[:prelude].find_all do |node|
24
+ node[:node] == :url or node[:node] == :string
25
+ end
26
+ else
27
+ children = node
28
+ [:block, :value].each do |key|
29
+ children = children[key]
30
+ break if children.nil?
31
+ end
32
+ list += url_nodes(children)
33
+ end
34
+ else
35
+ list += url_nodes(node[:children])
36
+ end
37
+ end
38
+ return list
39
+ end
40
+
41
+ def translate_links
42
+ url_nodes(@parsed).uniq.each do |node|
43
+ node[:value] = get_link_translation(node[:value]).to_s
44
+ if node[:node] == :url
45
+ node[:raw] = "url(#{node[:value]})"
46
+ end
47
+ end
48
+ end
49
+
50
+ def render_document
51
+ Crass::Parser.stringify(@parsed)
52
+ end
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,32 @@
1
+ require 'rhet-butler/stasis'
2
+ module RhetButler
3
+ module Stasis
4
+ class DocumentTransform
5
+ def self.register(type)
6
+ TransformQueue.register(type, self)
7
+ end
8
+
9
+ attr_accessor :document, :queue, :target_path
10
+
11
+ def document_source
12
+ @document.source_uri
13
+ end
14
+
15
+ def save_document
16
+ @queue.write_document(target_path, render_document)
17
+ end
18
+
19
+ def process
20
+ parse_document
21
+
22
+ translate_links
23
+
24
+ save_document
25
+ end
26
+
27
+ def get_link_translation(link)
28
+ queue.target_for(document, document_source).route_to(queue.target_for(document, link))
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,51 @@
1
+ require 'rhet-butler/stasis/document-transform'
2
+ module RhetButler
3
+ module Stasis
4
+ require 'nokogiri'
5
+ class HTMLTransform < DocumentTransform
6
+ register "text/html"
7
+
8
+ NAV_AND_EMBED = %w[
9
+ //a/@href
10
+ //applet/@codebase
11
+ //area/@href
12
+ //base/@href
13
+ //body/@background
14
+ //frame/@longdesc
15
+ //frame/@src
16
+ //iframe/@longdesc
17
+ //iframe/@src
18
+ //img/@longdesc
19
+ //img/@src
20
+ //input/@src
21
+ //link/@href
22
+ //object/@codebase
23
+ //object/@data
24
+ //script/@src
25
+ //audio/@src
26
+ //command/@icon
27
+ //embed/@src
28
+ //html/@manifest
29
+ //source/@src
30
+ //video/@poster
31
+ //video/@src
32
+ ]
33
+
34
+ def parse_document
35
+ @parsed = Nokogiri::HTML(document.body)
36
+ end
37
+
38
+ def translate_links
39
+ NAV_AND_EMBED.each do |xpath|
40
+ @parsed.xpath(xpath).each do |attr|
41
+ attr.value = get_link_translation(attr.value)
42
+ end
43
+ end
44
+ end
45
+
46
+ def render_document
47
+ @parsed.to_html
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,19 @@
1
+ require 'rhet-butler/stasis'
2
+ module RhetButler
3
+ module Stasis
4
+ class HTTPLoader
5
+ def initialize
6
+ require 'net/http'
7
+ end
8
+
9
+ def load(source_uri)
10
+ response = Net::HTTP.get_response(URI(source_uri.to_s))
11
+ Document.new.tap do |doc|
12
+ doc.body = response.body
13
+ doc.source_uri = source_uri
14
+ doc.type = response["Content-Type"]
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,18 @@
1
+ require 'rhet-butler/stasis/document-transform'
2
+ module RhetButler
3
+ module Stasis
4
+ class IdentityTransform < DocumentTransform
5
+ register nil
6
+
7
+ def parse_document
8
+ end
9
+
10
+ def translate_links
11
+ end
12
+
13
+ def render_document
14
+ document.body
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,57 @@
1
+ require 'rhet-butler/stasis'
2
+ module RhetButler
3
+ module Stasis
4
+ class RackLoader
5
+ def initialize(url, app)
6
+ require 'stringio'
7
+ @url = url
8
+ @app = app
9
+ end
10
+
11
+ def root_uri
12
+ @root_uri ||= Addressable::URI.parse(@url).tap do |root_url|
13
+ root_url.path = ""
14
+ end
15
+ end
16
+
17
+ def server_name
18
+ root_uri.host
19
+ end
20
+
21
+ def load(source_uri)
22
+ doc = Document.new
23
+ doc.source_uri = source_uri
24
+
25
+ source_uri = root_uri.join(source_uri).route_from(root_uri).to_s
26
+ source_uri = "/" if source_uri == "#"
27
+
28
+ env = {
29
+ "REQUEST_METHOD" => "GET",
30
+ "SCRIPT_NAME" => "",
31
+ "PATH_INFO" => source_uri,
32
+ "QUERY_STRING" => "",
33
+ "SERVER_NAME" => server_name,
34
+ "rack.errors" => StringIO.new,
35
+ "rack.input" => StringIO.new,
36
+ "rack.url_scheme" => "http",
37
+ "rack.version" => Rack::VERSION,
38
+ "rack.multithread" => false,
39
+ "rack.multiprocess" => false,
40
+ "rack.runonce" => false,
41
+ "rack.hijack?" => false,
42
+ }
43
+
44
+ response = @app.call(env)
45
+
46
+ code, headers, body = *response
47
+
48
+ unless code == 200
49
+ raise "Bad response from local server: #{response[0..1].inspect} body: #{response[2].to_a.join.length}"
50
+ end
51
+ doc.type = headers["Content-Type"]
52
+ doc.body = body.to_a.join("")
53
+ return doc
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,55 @@
1
+ require 'rhet-butler/stasis'
2
+ module RhetButler
3
+ module Stasis
4
+ class ResourceMapping
5
+ def initalize(queue)
6
+ @queue = queue
7
+ end
8
+
9
+ attr_writer :default_uri
10
+
11
+ def default_uri
12
+ Addressable::URI.parse(@default_uri)
13
+ end
14
+
15
+ def absolute_uri(uri)
16
+ uri = default_uri.join(uri)
17
+ if uri == default_uri
18
+ uri = uri.join("index.html")
19
+ end
20
+ return uri
21
+ end
22
+
23
+ def relative_uri(uri)
24
+ default_uri.route_to(absolute_uri(uri))
25
+ end
26
+
27
+ def localized(uri)
28
+ return "/index.html" if uri == "/"
29
+
30
+ uri = relative_uri(uri)
31
+
32
+ if uri.relative?
33
+ return uri.to_s
34
+ end
35
+
36
+ query_values = uri.query_values(Array)
37
+ [
38
+ [uri.host, uri.port, uri.user, uri.scheme == 'http' ? nil : uri.scheme].compact.join("-"),
39
+ uri.path,
40
+ (query_values ? query_values.map{|pair| pair.join("=")}.join(",") : nil)
41
+ ].compact.map do |part|
42
+ part.sub(%r{\A/},'').sub(%r{/\Z},'')
43
+ end.join("/")
44
+ end
45
+
46
+ def storage_for(uri)
47
+ localized(uri).sub(%r{^/},'')
48
+ end
49
+
50
+ def target_link_for(uri)
51
+ default_uri.join(storage_for(uri))
52
+ end
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,87 @@
1
+ require 'rhet-butler/stasis'
2
+ module RhetButler
3
+ module Stasis
4
+ class TranformationOrder
5
+ attr_accessor :source_link, :target_link, :storage_target
6
+
7
+ def initialize(source_link, target_link, storage_target)
8
+ @source_link, @target_link, @storage_target =
9
+ source_link, target_link, storage_target
10
+ end
11
+ end
12
+
13
+ class TransformQueue
14
+ class << self
15
+ def transformers
16
+ @transformers ||= {}
17
+ end
18
+
19
+ def register(type, klass)
20
+ transformers[type] = klass
21
+ end
22
+
23
+ def lookup(type)
24
+ transformers.fetch(type) do
25
+ transformers.fetch(nil)
26
+ end
27
+ end
28
+ end
29
+
30
+ def initialize
31
+ @list = []
32
+ @hash = {}
33
+ end
34
+ attr_accessor :loader, :writer, :mapping
35
+
36
+ def add(source)
37
+ store_to = mapping.storage_for(source)
38
+ link_target = mapping.target_link_for(source)
39
+ add_mapping(source, link_target, store_to)
40
+ return link_target
41
+ end
42
+
43
+ def add_mapping(source_uri, target_uri, target_path)
44
+ @hash[source_uri] = target_uri
45
+ @list << TranformationOrder.new(source_uri, target_uri, target_path)
46
+ end
47
+
48
+ def transform_class(type)
49
+ self.class.lookup(type)
50
+ end
51
+
52
+ def target_for(document, link)
53
+ link = canonicalize_uri(mapping.absolute_uri(document.source_uri).join(link))
54
+ @hash.fetch(link) do
55
+ add(link)
56
+ end
57
+ end
58
+
59
+ def canonicalize_uri(string)
60
+ uri = Addressable::URI.parse(string).normalize
61
+ uri.fragment = nil
62
+ uri
63
+ end
64
+
65
+ def load_document(source_path)
66
+ loader.load(canonicalize_uri(source_path))
67
+ end
68
+
69
+ def write_document(target_path, document_body)
70
+ writer.write(target_path, document_body)
71
+ end
72
+
73
+ def go
74
+ until @list.empty?
75
+ order = @list.pop
76
+
77
+ doc = load_document(order.source_link)
78
+ transformer = transform_class(doc.type).new
79
+ transformer.queue = self
80
+ transformer.document = doc
81
+ transformer.target_path = order.storage_target
82
+ transformer.process
83
+ end
84
+ end
85
+ end
86
+ end
87
+ end
@@ -0,0 +1,35 @@
1
+ require 'rhet-butler/stasis'
2
+ module RhetButler
3
+ module Stasis
4
+ class Writer
5
+ def initialize(root)
6
+ @root = root
7
+ end
8
+ attr_accessor :store_log
9
+
10
+ def write(path, content)
11
+ store_log.puts "Writing: #{path}" if store_log.respond_to? :puts
12
+ store(path, content)
13
+ end
14
+
15
+ def store(path, content)
16
+ File::open(File::join(@root, path), "w") do |file|
17
+ file.write(content)
18
+ end
19
+ end
20
+ end
21
+
22
+ class ValiseWriter < Writer
23
+ def initialize(valise)
24
+ @target_valise = valise
25
+ end
26
+
27
+ attr_reader :target_valise
28
+
29
+ def store(path, content)
30
+ target = target_valise.get(path).writable.first
31
+ target.contents = content
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,18 @@
1
+ require 'addressable/uri'
2
+ module RhetButler
3
+ module Stasis
4
+ class Document
5
+ attr_accessor :type, :body, :source_uri
6
+ end
7
+ end
8
+ end
9
+
10
+ require 'rhet-butler/stasis/rack-loader'
11
+ require 'rhet-butler/stasis/http-loader'
12
+ require 'rhet-butler/stasis/writer'
13
+ require 'rhet-butler/stasis/resource-mapping'
14
+ require 'rhet-butler/stasis/transform-queue'
15
+ require 'rhet-butler/stasis/document-transform'
16
+ require 'rhet-butler/stasis/identity-transform'
17
+ require 'rhet-butler/stasis/html-transform'
18
+ require 'rhet-butler/stasis/css-transform'
@@ -1,44 +1,36 @@
1
- require 'valise'
2
- require 'rhet-butler/html-generator'
3
- require 'rhet-butler/arrangement'
4
- require 'rhet-butler/file-manager'
5
- require 'rhet-butler/slide-loader'
1
+ require 'rhet-butler/web/main-app'
2
+ require 'rhet-butler/stasis'
6
3
 
7
4
  module RhetButler
8
5
  class StaticGenerator
9
6
  def initialize(file_manager)
10
- @configuration = file_manager.base_config
11
- @base_valise = file_manager.slide_files
7
+ @file_manager = file_manager
12
8
  @target_valise = file_manager.target_valise
13
- @root_slide = configuration.root_slide
14
- @root_slide_template = configuration.root_slide_template
15
- @template_handler = file_manager.aspect_templates(:viewer)
16
9
  end
17
10
 
18
- attr_accessor :target_directory, :root_slides
19
- attr_reader :configuration, :template_handler, :target_valise
11
+ attr_reader :target_valise
12
+ attr_accessor :store_log
20
13
 
21
- def html_document
22
- html_generator = HTMLGenerator.new(configuration, template_handler)
23
- html_generator.slides = SlideLoader.new(@base_valise, configuration).load_slides
24
-
25
- return html_generator.render(@root_slide_template)
26
- end
27
-
28
- def populate_assets
29
- @base_valise.sub_set("templates").glob("assets/**").map do |stack|
30
- stack.segments[1..-2] +
31
- [stack.segments.last.sub(/(.*(?:\..*)?).*/){|| $1}]
32
- end.uniq.each do |target_file|
33
- target_valise.get(target_file).writable.first.contents =
34
- template_handler.render(target_file, nil)
35
- end
14
+ def app
15
+ web_app = Web::MainApp.new(@file_manager)
16
+ web_app.presentation_app_class = Web::MemoizedPresentationApp
17
+ web_app.assets_app_class = Web::MemoizedAssetsApp
18
+ web_app.capture_exceptions = false
19
+ web_app.check
20
+ web_app.builder.to_app
36
21
  end
37
22
 
38
23
  def go!
39
- target_valise.get("presentation.html").writable.first.contents = html_document
24
+ app_url = "http://example.com/"
25
+ transform_queue = Stasis::TransformQueue.new
26
+ transform_queue.loader = Stasis::RackLoader.new(app_url, app)
27
+ transform_queue.mapping = Stasis::ResourceMapping.new
28
+ transform_queue.mapping.default_uri = app_url
29
+ transform_queue.writer = Stasis::ValiseWriter.new(@target_valise)
30
+ transform_queue.writer.store_log = store_log
40
31
 
41
- populate_assets
32
+ transform_queue.add("/")
33
+ transform_queue.go
42
34
  end
43
35
  end
44
36
  end
@@ -2,12 +2,16 @@ module RhetButler
2
2
  module Web
3
3
  class AssetsApp
4
4
  def initialize(file_manager)
5
- @template_handler = file_manager.base_assets
5
+ @file_manager = file_manager
6
6
  end
7
7
 
8
- attr_reader :template_handler
8
+ attr_reader :file_manager
9
9
 
10
10
  class AssetsContext
11
+ def initialize(template_handler)
12
+ @template_handler = template_handler
13
+ end
14
+
11
15
  def render(path, locals = nil)
12
16
  template = @template_handler.find(path).contents
13
17
  if template.respond_to? :render
@@ -18,13 +22,12 @@ module RhetButler
18
22
  end
19
23
  end
20
24
 
25
+ def template_handler
26
+ file_manager.base_assets(::Tilt::Cache.new)
27
+ end
28
+
21
29
  def assets_context
22
- @context ||=
23
- begin
24
- context = AssetsContext.new
25
- context.instance_variable_set("@template_handler", template_handler)
26
- context
27
- end
30
+ AssetsContext.new(template_handler)
28
31
  end
29
32
 
30
33
  def call(env)
@@ -34,6 +37,19 @@ module RhetButler
34
37
 
35
38
  mime_type = Rack::Mime.mime_type(extension, "text/plain")
36
39
  [200, {'Content-Type' => mime_type}, [assets_context.render(asset_path)]]
40
+ rescue Object => ex
41
+ puts ex
42
+ raise
43
+ end
44
+ end
45
+
46
+ class MemoizedAssetsApp < AssetsApp
47
+ def template_handler
48
+ @template_handler ||= super
49
+ end
50
+
51
+ def assets_context
52
+ @assets_contenxt ||= super
37
53
  end
38
54
  end
39
55
  end