flutterby 0.0.1 → 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 20cc78c87b60aef744ffbc565db9bee17d25733f
4
- data.tar.gz: '09966bb3f860d28727e6569e73b105679ac39045'
3
+ metadata.gz: 8e74e653d62257035937eb6cec35fafae4ae6272
4
+ data.tar.gz: b0b8918a534bad69247b60e209e5431d31f08731
5
5
  SHA512:
6
- metadata.gz: 94a9745b04134116f517348ebf0dc3569827226d67ee04fcfd59928781b15c12cf47ac58e4eb1d99b1f3eee4df020caf0857b53a8577f26881d755d2c7886fdf
7
- data.tar.gz: d46433b7fd0c1ec835032739bd39afaf320e16f60d8f43248dbfc6b54a35711e76373a13f817cceadc3adc492506b47471ef7de2da974643a212a12b79d28cad
6
+ metadata.gz: d3a8ac8a2eb8e1c53bdbec7b07742cd82461d8255ffe612ef630eaa7b925c6f657e18769854c559463bbc80f08497e5268d31a29d05adaf0ec4c3c910c1a5054
7
+ data.tar.gz: 1189422cf9ed293b66e6295ff3c0eb0a8b7eeba09d7efe1ffda75ab0de592197e5c97f75a86211f3dd5d6d6cf1503ecdb3577190a0f6941184fa2b22cfd9bb9c
data/flutterby.gemspec CHANGED
@@ -25,6 +25,7 @@ Gem::Specification.new do |spec|
25
25
  spec.add_development_dependency "rake", "~> 10.0"
26
26
  spec.add_development_dependency "rspec", "~> 3.0"
27
27
  spec.add_development_dependency 'awesome_print'
28
+ spec.add_development_dependency 'gem-release'
28
29
 
29
30
  spec.add_dependency 'commander'
30
31
  spec.add_dependency 'slodown'
@@ -33,4 +34,6 @@ Gem::Specification.new do |spec|
33
34
  spec.add_dependency 'slim'
34
35
  spec.add_dependency 'toml-rb'
35
36
  spec.add_dependency 'rack'
37
+ spec.add_dependency 'listen'
38
+ spec.add_dependency 'mime-types'
36
39
  end
data/lib/flutterby/cli.rb CHANGED
@@ -21,6 +21,22 @@ Commander.configure do
21
21
  end
22
22
  end
23
23
 
24
+ command :serve do |c|
25
+ c.syntax = 'flutterby serve [options]'
26
+ c.description = "Serve your website for development."
27
+
28
+ c.option '--in DIR', String, "Directory containing your source files"
29
+
30
+ c.action do |args, options|
31
+ options.default in: "./site/"
32
+
33
+ root = Flutterby.from(options.in, name: "/")
34
+ server = Flutterby::Server.new(root)
35
+ server.run!
36
+ end
37
+ end
38
+
39
+
24
40
  command :test do |c|
25
41
  c.syntax = 'flutterby test'
26
42
  c.description = 'TEST. Yo.'
@@ -1,15 +1,16 @@
1
1
  module Flutterby
2
2
  class Entity
3
- attr_reader :name, :ext, :filters, :parent, :fs_path, :path
3
+ attr_reader :name, :ext, :filters, :parent, :fs_path, :path, :data
4
4
 
5
5
  def initialize(name, parent: nil, fs_path: nil)
6
6
  @parent = parent
7
+ @data = {}
7
8
 
8
9
  # Extract name, extension, and filters from given name
9
10
  parts = name.split(".")
10
11
  @name = parts.shift
11
12
  @ext = parts.shift
12
- @filters = parts
13
+ @filters = parts.reverse
13
14
 
14
15
  # Calculate full path
15
16
  @path = parent ? ::File.join(parent.path, full_name) : full_name
@@ -21,6 +22,10 @@ module Flutterby
21
22
  end
22
23
  end
23
24
 
25
+ def reload!
26
+ read
27
+ end
28
+
24
29
  def list(indent: 0)
25
30
  puts "#{" " * indent}[#{self.class}] #{path}"
26
31
  end
@@ -33,7 +38,8 @@ module Flutterby
33
38
  end
34
39
  end
35
40
 
36
- def process
41
+ def process_filters(input)
42
+ input
37
43
  end
38
44
 
39
45
  def url
@@ -44,15 +50,27 @@ module Flutterby
44
50
  ::File.expand_path(::File.join(base, full_name))
45
51
  end
46
52
 
47
- def call(env)
48
- ['200', {"Content-Type" => "text/html"}, [name]]
49
- end
50
-
51
53
  def root
52
54
  parent ? parent.root : self
53
55
  end
54
56
 
55
- private
57
+
58
+ #
59
+ # Serving
60
+ #
61
+
62
+ def call(env)
63
+ env['rack.request'] ||= Rack::Request.new(env)
64
+ env['rack.response'] ||= Rack::Response.new([], 200, {})
65
+ parts = env['rack.request'].path.split("/").reject(&:empty?)
66
+
67
+ serve(parts, env['rack.request'], env['rack.response'])
68
+
69
+ env['rack.response']
70
+ end
71
+
72
+ def serve(parts, req, res)
73
+ end
56
74
 
57
75
  def sibling(name)
58
76
  parent && parent.find(name)
@@ -3,14 +3,23 @@ require 'sass'
3
3
  require 'tilt'
4
4
  require 'slim'
5
5
  require 'toml'
6
+ require 'mime-types'
6
7
 
7
8
  module Flutterby
8
9
  class File < Entity
9
- attr_reader :contents, :data
10
+ attr_reader :contents
10
11
 
11
12
  def read
12
13
  @contents = ::File.read(fs_path)
13
- @data = parse_frontmatter
14
+
15
+ # Extract date from name
16
+ if name =~ %r{^(\d\d\d\d\-\d\d?\-\d\d?)\-}
17
+ @data['date'] = Time.parse($1)
18
+ end
19
+
20
+ # Read remaining data from frontmatter. Data in frontmatter
21
+ # will always have precedence!
22
+ @data.merge! parse_frontmatter
14
23
  end
15
24
 
16
25
  def parse_frontmatter
@@ -28,16 +37,18 @@ module Flutterby
28
37
  data
29
38
  end
30
39
 
31
- def process!
32
- # Apply processors
33
- while filter = filters.pop do
40
+ def process_filters(input)
41
+ # Apply all filters
42
+ filters.each do |filter|
34
43
  meth = "process_#{filter}"
35
44
  if respond_to?(meth)
36
- send(meth)
45
+ input = send(meth, input)
37
46
  else
38
47
  puts "Woops, no #{meth} available :("
39
48
  end
40
49
  end
50
+
51
+ input
41
52
  end
42
53
 
43
54
  def page?
@@ -48,27 +59,27 @@ module Flutterby
48
59
  @view ||= View.new(self)
49
60
  end
50
61
 
51
- def process_erb
52
- tilt = Tilt["erb"].new { @contents }
53
- @contents = tilt.render(view)
62
+ def process_erb(input)
63
+ tilt = Tilt["erb"].new { input }
64
+ tilt.render(view)
54
65
  end
55
66
 
56
- def process_slim
57
- tilt = Tilt["slim"].new { @contents }
58
- @contents = tilt.render(view)
67
+ def process_slim(input)
68
+ tilt = Tilt["slim"].new { input }
69
+ tilt.render(view)
59
70
  end
60
71
 
61
- def process_md
62
- @contents = Slodown::Formatter.new(@contents).complete.to_s
72
+ def process_md(input)
73
+ Slodown::Formatter.new(input).complete.to_s
63
74
  end
64
75
 
65
- def process_scss
66
- engine = Sass::Engine.new(@contents, syntax: :scss)
67
- @contents = engine.render
76
+ def process_scss(input)
77
+ engine = Sass::Engine.new(input, syntax: :scss)
78
+ engine.render
68
79
  end
69
80
 
70
- def apply_layout
71
- output = @contents
81
+ def apply_layout(input)
82
+ output = input
72
83
 
73
84
  # collect layouts to apply
74
85
  layouts = []
@@ -93,10 +104,23 @@ module Flutterby
93
104
  end
94
105
 
95
106
  def write_static(path)
96
- process!
97
- output = apply_layout? ? apply_layout : @contents
107
+ rendered = process_filters(@contents)
108
+ output = apply_layout? ? apply_layout(rendered) : rendered
98
109
 
99
110
  ::File.write(path, output)
100
111
  end
112
+
113
+ def serve(parts, req, res)
114
+ # TODO: DRY this up
115
+ rendered = process_filters(@contents)
116
+ output = apply_layout? ? apply_layout(rendered) : rendered
117
+
118
+ # Determine MIME type
119
+ mime_type = MIME::Types.type_for(ext) || "text/plain"
120
+
121
+ # Build response
122
+ res.headers["Content-Type"] = mime_type
123
+ res.body = [output]
124
+ end
101
125
  end
102
126
  end
@@ -22,6 +22,7 @@ module Flutterby
22
22
  end
23
23
 
24
24
  def find(name)
25
+ name = name.split('.').first
25
26
  @children.find { |c| c.name == name }
26
27
  end
27
28
 
@@ -30,5 +31,18 @@ module Flutterby
30
31
  def pages
31
32
  children.select { |c| c.ext == "html" }
32
33
  end
34
+
35
+
36
+
37
+ def serve(parts, req, res)
38
+ # If no further parts are requested, let's look for an index
39
+ # document and serve that instead.
40
+ if child = find(parts.empty? ? "index" : parts.shift)
41
+ child.serve(parts, req, res)
42
+ else
43
+ res.headers["Content-Type"] = "text/html"
44
+ res.body = ["404"]
45
+ end
46
+ end
33
47
  end
34
48
  end
@@ -1,4 +1,5 @@
1
1
  require 'rack'
2
+ require 'listen'
2
3
 
3
4
  module Flutterby
4
5
  class Server
@@ -7,7 +8,28 @@ module Flutterby
7
8
  end
8
9
 
9
10
  def run!
10
- Rack::Handler::WEBrick.run @root
11
+ # Set up listener
12
+ listener = Listen.to(@root.fs_path) do |modified, added, removed|
13
+ # puts "modified absolute path: #{modified}"
14
+ # puts "added absolute path: #{added}"
15
+ # puts "removed absolute path: #{removed}"
16
+
17
+ puts "Change detected, reloading everything!"
18
+ @root.reload!
19
+ end
20
+
21
+ # Set up server
22
+ server = Rack::Handler::WEBrick
23
+
24
+ # Make sure we handle interrupts correctly
25
+ trap('INT') do
26
+ listener.stop
27
+ server.shutdown
28
+ end
29
+
30
+ # Go!
31
+ listener.start
32
+ server.run @root
11
33
  end
12
34
  end
13
35
  end
@@ -1,3 +1,3 @@
1
1
  module Flutterby
2
- VERSION = "0.0.1"
2
+ VERSION = "0.0.2"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: flutterby
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Hendrik Mans
@@ -66,6 +66,20 @@ dependencies:
66
66
  - - ">="
67
67
  - !ruby/object:Gem::Version
68
68
  version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: gem-release
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
69
83
  - !ruby/object:Gem::Dependency
70
84
  name: commander
71
85
  requirement: !ruby/object:Gem::Requirement
@@ -164,6 +178,34 @@ dependencies:
164
178
  - - ">="
165
179
  - !ruby/object:Gem::Version
166
180
  version: '0'
181
+ - !ruby/object:Gem::Dependency
182
+ name: listen
183
+ requirement: !ruby/object:Gem::Requirement
184
+ requirements:
185
+ - - ">="
186
+ - !ruby/object:Gem::Version
187
+ version: '0'
188
+ type: :runtime
189
+ prerelease: false
190
+ version_requirements: !ruby/object:Gem::Requirement
191
+ requirements:
192
+ - - ">="
193
+ - !ruby/object:Gem::Version
194
+ version: '0'
195
+ - !ruby/object:Gem::Dependency
196
+ name: mime-types
197
+ requirement: !ruby/object:Gem::Requirement
198
+ requirements:
199
+ - - ">="
200
+ - !ruby/object:Gem::Version
201
+ version: '0'
202
+ type: :runtime
203
+ prerelease: false
204
+ version_requirements: !ruby/object:Gem::Requirement
205
+ requirements:
206
+ - - ">="
207
+ - !ruby/object:Gem::Version
208
+ version: '0'
167
209
  description: There are many static site generators. This is mine.
168
210
  email:
169
211
  - hendrik@mans.de