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.
- checksums.yaml +15 -0
- data/default-configuration/assets/javascript/keyboard-nav.js +91 -0
- data/default-configuration/assets/javascript/rhet-present.js +855 -0
- data/default-configuration/assets/javascript/rhet-present.min.js +55 -0
- data/default-configuration/assets/stylesheets/_animate-helpers.scss +41 -0
- data/default-configuration/assets/stylesheets/animate/_attention.scss +36 -0
- data/default-configuration/assets/stylesheets/animate/_bounce.scss +71 -0
- data/default-configuration/assets/stylesheets/animate/_fade.scss +56 -0
- data/default-configuration/assets/stylesheets/animate/_flip.scss +98 -0
- data/default-configuration/assets/stylesheets/animate/_lightSpeed.scss +20 -0
- data/default-configuration/assets/stylesheets/animate/_roll.scss +20 -0
- data/default-configuration/assets/stylesheets/animate/_rotate.scss +40 -0
- data/default-configuration/assets/stylesheets/animate/_special.scss +17 -0
- data/default-configuration/assets/stylesheets/animate/_windblown.sass +17 -0
- data/default-configuration/assets/stylesheets/animate/attention/._pulse.scss.swp +0 -0
- data/default-configuration/assets/stylesheets/animate/attention/_flash.scss +34 -0
- data/default-configuration/assets/stylesheets/animate/attention/_pulse.scss +28 -0
- data/default-configuration/assets/stylesheets/animate/attention/_shake.scss +53 -0
- data/default-configuration/assets/stylesheets/animate/attention/_swing.scss +40 -0
- data/default-configuration/assets/stylesheets/animate/attention/_tada.scss +51 -0
- data/default-configuration/assets/stylesheets/animate/attention/_wiggle.scss +52 -0
- data/default-configuration/assets/stylesheets/animate/attention/_wobble.scss +41 -0
- data/default-configuration/assets/stylesheets/animate/bounce/_bounceIn.scss +151 -0
- data/default-configuration/assets/stylesheets/animate/bounce/_bounceOut.scss +139 -0
- data/default-configuration/assets/stylesheets/animate/fade/_fadeIn.sass +139 -0
- data/default-configuration/assets/stylesheets/animate/fade/_fadeOut.sass +139 -0
- data/default-configuration/assets/stylesheets/animate/flip/_flipIn.scss +78 -0
- data/default-configuration/assets/stylesheets/animate/flip/_flipOut.scss +66 -0
- data/default-configuration/assets/stylesheets/animate/lightSpeed/_lightSpeedIn.scss +37 -0
- data/default-configuration/assets/stylesheets/animate/lightSpeed/_lightSpeedOut.scss +29 -0
- data/default-configuration/assets/stylesheets/animate/roll/_rollIn.scss +29 -0
- data/default-configuration/assets/stylesheets/animate/roll/_rollOut.scss +28 -0
- data/default-configuration/assets/stylesheets/animate/rotate/_rotateIn.scss +208 -0
- data/default-configuration/assets/stylesheets/animate/rotate/_rotateOut.scss +208 -0
- data/default-configuration/assets/stylesheets/animate/special/_hinge.scss +49 -0
- data/default-configuration/assets/stylesheets/animate/windblown/_windblownIn.sass +28 -0
- data/default-configuration/assets/stylesheets/animate/windblown/_windblownOut.sass +24 -0
- data/default-configuration/assets/stylesheets/font.css +30 -0
- data/default-configuration/assets/stylesheets/highlight/arta.css +158 -0
- data/default-configuration/assets/stylesheets/highlight/ascetic.css +50 -0
- data/default-configuration/assets/stylesheets/highlight/brown_paper.css +104 -0
- data/default-configuration/assets/stylesheets/highlight/brown_papersq.png +0 -0
- data/default-configuration/assets/stylesheets/highlight/dark.css +103 -0
- data/default-configuration/assets/stylesheets/highlight/default.css +135 -0
- data/default-configuration/assets/stylesheets/highlight/far.css +111 -0
- data/default-configuration/assets/stylesheets/highlight/github.css +127 -0
- data/default-configuration/assets/stylesheets/highlight/googlecode.css +144 -0
- data/default-configuration/assets/stylesheets/highlight/idea.css +121 -0
- data/default-configuration/assets/stylesheets/highlight/ir_black.css +104 -0
- data/default-configuration/assets/stylesheets/highlight/magula.css +120 -0
- data/default-configuration/assets/stylesheets/highlight/monokai.css +114 -0
- data/default-configuration/assets/stylesheets/highlight/pojoaque.css +104 -0
- data/default-configuration/assets/stylesheets/highlight/pojoaque.jpg +0 -0
- data/default-configuration/assets/stylesheets/highlight/rainbow.css +114 -0
- data/default-configuration/assets/stylesheets/highlight/school_book.css +111 -0
- data/default-configuration/assets/stylesheets/highlight/school_book.png +0 -0
- data/default-configuration/assets/stylesheets/highlight/solarized_light.css +88 -0
- data/default-configuration/assets/stylesheets/highlight/sunburst.css +158 -0
- data/default-configuration/assets/stylesheets/highlight/tomorrow-night-blue.css +52 -0
- data/default-configuration/assets/stylesheets/highlight/tomorrow-night-bright.css +51 -0
- data/default-configuration/assets/stylesheets/highlight/tomorrow-night-eighties.css +51 -0
- data/default-configuration/assets/stylesheets/highlight/tomorrow-night.css +52 -0
- data/default-configuration/assets/stylesheets/highlight/tomorrow.css +49 -0
- data/default-configuration/assets/stylesheets/highlight/vs.css +86 -0
- data/default-configuration/assets/stylesheets/highlight/xcode.css +154 -0
- data/default-configuration/assets/stylesheets/highlight/zenburn.css +114 -0
- data/default-configuration/assets/stylesheets/presenter/rhet.css.sass +160 -0
- data/default-configuration/assets/stylesheets/rhet.css.sass +142 -0
- data/default-configuration/assets/themes.googleusercontent.com/static/fonts/arimo/v5/K-bXE71xZHgbUS_UdQjugvesZW2xOQ-xsNqO47m55DA.ttf +0 -0
- data/default-configuration/assets/themes.googleusercontent.com/static/fonts/cinzeldecorative/v1/pXhIVnhFtL_B9Vb1wq2F9wIh9oxuYcmvOvyh_107lQs.ttf +0 -0
- data/default-configuration/assets/themes.googleusercontent.com/static/fonts/cinzeldecorative/v1/pXhIVnhFtL_B9Vb1wq2F9zCUrkmwPfdnoTjOU_kXqBI.ttf +0 -0
- data/default-configuration/assets/themes.googleusercontent.com/static/fonts/droidsansmono/v4/ns-m2xQYezAtqh7ai59hJYW_AySPyikQrZReizgrnuw.ttf +0 -0
- data/default-configuration/assets/themes.googleusercontent.com/static/fonts/slackey/v3/bJZDrYrGx8atJRHR9DVdqg.ttf +0 -0
- data/default-configuration/common/config.yaml +17 -0
- data/default-configuration/common/templates/group.html.erb +5 -0
- data/default-configuration/common/templates/presentation.html.erb +11 -17
- data/default-configuration/common/templates/presenter-qr.html.erb +3 -3
- data/default-configuration/common/templates/slide.html.erb +3 -0
- data/default-configuration/common/templates/stylesheets.html.erb +1 -1
- data/default-configuration/presenter/templates/live-javascript.html.erb +4 -3
- data/default-configuration/presenter/templates/slide.html.erb +6 -0
- data/default-configuration/presenter/templates/stylesheets.html.erb +1 -1
- data/default-configuration/skels/config.yaml +15 -0
- data/default-configuration/skels/slides.yaml +6 -0
- data/default-configuration/viewer/templates/live-javascript.html.erb +1 -1
- data/lib/rhet-butler/arrangement-finder.rb +71 -0
- data/lib/rhet-butler/command-line.rb +69 -1
- data/lib/rhet-butler/configuration.rb +20 -5
- data/lib/rhet-butler/file-loading.rb +28 -0
- data/lib/rhet-butler/file-manager.rb +42 -22
- data/lib/rhet-butler/filter-resolver.rb +45 -0
- data/lib/rhet-butler/html-generator.rb +24 -4
- data/lib/rhet-butler/include-processor.rb +55 -0
- data/lib/rhet-butler/layout-rule.rb +17 -13
- data/lib/rhet-butler/resource-localizer.rb +22 -0
- data/lib/rhet-butler/sass-functions.rb +40 -0
- data/lib/rhet-butler/slide-arranger.rb +39 -0
- data/lib/rhet-butler/slide-group.rb +56 -21
- data/lib/rhet-butler/slide-includer.rb +5 -2
- data/lib/rhet-butler/slide-loader.rb +16 -332
- data/lib/rhet-butler/slide-processor.rb +27 -0
- data/lib/rhet-butler/slide-renderer.rb +42 -0
- data/lib/rhet-butler/slide-renderers/code.rb +19 -0
- data/lib/rhet-butler/slide-renderers/cues.rb +27 -0
- data/lib/rhet-butler/slide-renderers/textile.rb +14 -0
- data/lib/rhet-butler/slide-rendering.rb +22 -0
- data/lib/rhet-butler/slide-traverser.rb +45 -0
- data/lib/rhet-butler/slide.rb +40 -30
- data/lib/rhet-butler/stasis/css-transform.rb +55 -0
- data/lib/rhet-butler/stasis/document-transform.rb +32 -0
- data/lib/rhet-butler/stasis/html-transform.rb +51 -0
- data/lib/rhet-butler/stasis/http-loader.rb +19 -0
- data/lib/rhet-butler/stasis/identity-transform.rb +18 -0
- data/lib/rhet-butler/stasis/rack-loader.rb +57 -0
- data/lib/rhet-butler/stasis/resource-mapping.rb +55 -0
- data/lib/rhet-butler/stasis/transform-queue.rb +87 -0
- data/lib/rhet-butler/stasis/writer.rb +35 -0
- data/lib/rhet-butler/stasis.rb +18 -0
- data/lib/rhet-butler/static-generator.rb +21 -29
- data/lib/rhet-butler/web/assets-app.rb +24 -8
- data/lib/rhet-butler/web/main-app.rb +17 -8
- data/lib/rhet-butler/web/presentation-app.rb +22 -14
- data/lib/rhet-butler/web/qr-display-app.rb +4 -1
- data/lib/rhet-butler/yaml-schema.rb +5 -4
- data/lib/rhet-butler/yaml-type.rb +24 -1
- data/spec/html-generation.rb +7 -1
- data/spec/presentation-view.rb +33 -8
- data/spec/rhet-butler.rb +0 -13
- data/spec/slide-loader.rb +3 -3
- data/spec/slide-processing.rb +6 -3
- metadata +209 -119
- data/default-configuration/assets/javascript/impress.js +0 -800
- data/default-configuration/assets/stylesheets/presenter/presentation.css +0 -477
- data/lib/rhet-butler.rb +0 -2
data/lib/rhet-butler/slide.rb
CHANGED
@@ -1,14 +1,15 @@
|
|
1
1
|
require 'rhet-butler/yaml-type'
|
2
2
|
|
3
3
|
module RhetButler
|
4
|
-
class Slide
|
5
|
-
|
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
|
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
|
-
@
|
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
|
-
|
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("
|
140
|
-
@
|
141
|
-
|
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
|
-
|
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 '
|
2
|
-
require 'rhet-butler/
|
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
|
-
@
|
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
|
-
|
19
|
-
|
11
|
+
attr_reader :target_valise
|
12
|
+
attr_accessor :store_log
|
20
13
|
|
21
|
-
def
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
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
|
-
|
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
|
-
|
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
|
-
@
|
5
|
+
@file_manager = file_manager
|
6
6
|
end
|
7
7
|
|
8
|
-
attr_reader :
|
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
|
-
|
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
|