pith 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (54) hide show
  1. data/README.markdown +29 -0
  2. data/Rakefile +16 -0
  3. data/bin/pith +60 -0
  4. data/cucumber.yml +7 -0
  5. data/features/content_for.feature +29 -0
  6. data/features/content_for.feature~ +29 -0
  7. data/features/haml.feature +24 -0
  8. data/features/haml.feature~ +24 -0
  9. data/features/helpers.feature +23 -0
  10. data/features/ignorance.feature +26 -0
  11. data/features/ignorance.feature~ +26 -0
  12. data/features/include.feature +84 -0
  13. data/features/include.feature~ +84 -0
  14. data/features/incremental_rebuild.feature +24 -0
  15. data/features/layouts.feature +43 -0
  16. data/features/layouts.feature~ +43 -0
  17. data/features/linking.feature +79 -0
  18. data/features/linking.feature~ +79 -0
  19. data/features/metadata.feature +20 -0
  20. data/features/metadata.feature~ +20 -0
  21. data/features/step_definitions/build_steps.rb +46 -0
  22. data/features/step_definitions/build_steps.rb~ +29 -0
  23. data/features/support/env.rb +75 -0
  24. data/features/support/env.rb~ +43 -0
  25. data/features/support/rspec_matchers.rb +5 -0
  26. data/features/textile.feature +29 -0
  27. data/features/textile.feature~ +29 -0
  28. data/features/verbatim.feature +32 -0
  29. data/features/verbatim.feature~ +32 -0
  30. data/lib/pith.rb +1 -0
  31. data/lib/pith.rb~ +2 -0
  32. data/lib/pith/console_logger.rb +20 -0
  33. data/lib/pith/console_logger.rb~ +20 -0
  34. data/lib/pith/input.rb +189 -0
  35. data/lib/pith/input.rb~ +95 -0
  36. data/lib/pith/metadata.rb +26 -0
  37. data/lib/pith/metadata.rb~ +26 -0
  38. data/lib/pith/project.rb +68 -0
  39. data/lib/pith/project.rb~ +50 -0
  40. data/lib/pith/render_context.rb +77 -0
  41. data/lib/pith/render_context.rb~ +66 -0
  42. data/lib/pith/server.rb +42 -0
  43. data/lib/pith/server.rb~ +45 -0
  44. data/lib/pith/version.rb +3 -0
  45. data/lib/pith/version.rb~ +3 -0
  46. data/sample/_layouts/standard.haml +7 -0
  47. data/sample/index.html.haml +8 -0
  48. data/sample/stylesheets/app.css.sass +44 -0
  49. data/spec/pith/metadata_spec.rb +46 -0
  50. data/spec/pith/metadata_spec.rb~ +46 -0
  51. data/spec/pith/project_spec.rb +61 -0
  52. data/spec/spec_helper.rb +27 -0
  53. data/spec/spec_helper.rb~ +0 -0
  54. metadata +166 -0
@@ -0,0 +1,26 @@
1
+ require "yaml"
2
+
3
+ module Pith
4
+
5
+ module Metadata
6
+
7
+ extend self
8
+
9
+ def extract_from(io)
10
+ line = io.gets
11
+ if line =~ /---$/
12
+ metadata_prefix = $`
13
+ yaml = ""
14
+ while line && line.start_with?(metadata_prefix)
15
+ yaml << line[metadata_prefix.size .. -1]
16
+ line = io.gets
17
+ end
18
+ YAML.load(yaml)
19
+ else
20
+ Hash.new
21
+ end
22
+ end
23
+
24
+ end
25
+
26
+ end
@@ -0,0 +1,26 @@
1
+ require "yaml"
2
+
3
+ module Pith
4
+
5
+ module Metadata
6
+
7
+ extend self
8
+
9
+ def extract_from(io)
10
+ line = io.gets
11
+ if line =~ /---$/
12
+ metadata_prefix = $`
13
+ yaml = ""
14
+ while line && line.start_with?(metadata_prefix)
15
+ yaml << line[metadata_prefix.size .. -1]
16
+ line = io.gets
17
+ end
18
+ YAML.load(yaml)
19
+ else
20
+ Hash.new
21
+ end
22
+ end
23
+
24
+ end
25
+
26
+ end
@@ -0,0 +1,68 @@
1
+ require "pathname"
2
+ require "logger"
3
+ require "pith/input"
4
+ require "tilt"
5
+
6
+ module Pith
7
+
8
+ class Project
9
+
10
+ def initialize(attributes = {})
11
+ attributes.each do |k,v|
12
+ send("#{k}=", v)
13
+ end
14
+ end
15
+
16
+ attr_accessor :input_dir, :output_dir
17
+
18
+ def inputs
19
+ Pathname.glob(input_dir + "**/*").map do |input_file|
20
+ next if input_file.directory?
21
+ path = input_file.relative_path_from(input_dir)
22
+ input(path)
23
+ end.compact
24
+ end
25
+
26
+ def input(path)
27
+ @input_cache ||= Hash.new do |h, path|
28
+ h[path] = Input.new(self, path)
29
+ end
30
+ input = @input_cache[path]
31
+ raise %{can't locate "#{path}"} unless input.full_path.file?
32
+ input
33
+ end
34
+
35
+ def build
36
+ load_config
37
+ inputs.each do |input|
38
+ input.build
39
+ end
40
+ end
41
+
42
+ def logger
43
+ @logger ||= Logger.new(nil)
44
+ end
45
+
46
+ attr_writer :logger
47
+
48
+ def helpers(&block)
49
+ helper_module.module_eval(&block)
50
+ end
51
+
52
+ def helper_module
53
+ @helper_module ||= Module.new
54
+ end
55
+
56
+ private
57
+
58
+ def load_config
59
+ config_file = input_dir + "_pith/config.rb"
60
+ project = self
61
+ if config_file.exist?
62
+ eval(config_file.read, binding, config_file)
63
+ end
64
+ end
65
+
66
+ end
67
+
68
+ end
@@ -0,0 +1,50 @@
1
+ require "pathname"
2
+ require "logger"
3
+ require "pith/input"
4
+ require "tilt"
5
+
6
+ module Pith
7
+
8
+ class Project
9
+
10
+ def initialize(attributes = {})
11
+ attributes.each do |k,v|
12
+ send("#{k}=", v)
13
+ end
14
+ end
15
+
16
+ attr_accessor :input_dir, :output_dir
17
+
18
+ def inputs
19
+ Pathname.glob(input_dir + "**/*").map do |input_file|
20
+ unless input_file.directory?
21
+ path = input_file.relative_path_from(input_dir)
22
+ Input.new(self, path)
23
+ end
24
+ end.compact
25
+ end
26
+
27
+ def input(name)
28
+ input_dir + name
29
+ end
30
+
31
+ def build
32
+ inputs.each do |input|
33
+ input.build
34
+ end
35
+ end
36
+
37
+ def serve
38
+ require "pith/server"
39
+ Pith::Server.run(self)
40
+ end
41
+
42
+ def logger
43
+ @logger ||= Logger.new(nil)
44
+ end
45
+
46
+ attr_writer :logger
47
+
48
+ end
49
+
50
+ end
@@ -0,0 +1,77 @@
1
+ require "set"
2
+ require "pathname"
3
+ require "tilt"
4
+
5
+ module Pith
6
+
7
+ class RenderContext
8
+
9
+ include Tilt::CompileSite
10
+
11
+ def self.can_render?(extension)
12
+ Tilt.registered?(extension)
13
+ end
14
+
15
+ def initialize(project)
16
+ @input_stack = []
17
+ @rendered_inputs = Set.new
18
+ self.extend(project.helper_module)
19
+ end
20
+
21
+ def initial_input
22
+ @input_stack.first
23
+ end
24
+
25
+ def current_input
26
+ @input_stack.last
27
+ end
28
+
29
+ def render(input, locals = {}, &block)
30
+ @rendered_inputs << input
31
+ with_input(input) do
32
+ Tilt.new(input.full_path).render(self, locals, &block)
33
+ end
34
+ end
35
+
36
+ attr_reader :rendered_inputs
37
+
38
+ def include(name, locals = {}, &block)
39
+ included_input = current_input.relative_input(name)
40
+ content_block = if block_given?
41
+ content = capture_haml(&block)
42
+ proc { content }
43
+ end
44
+ render(included_input, locals, &content_block)
45
+ end
46
+
47
+ def content_for
48
+ @content_for_hash ||= Hash.new { "" }
49
+ end
50
+
51
+ def meta
52
+ initial_input.meta || {}
53
+ end
54
+
55
+ def href(name)
56
+ target_path = current_input.relative_path(name)
57
+ target_path.relative_path_from(initial_input.path.parent)
58
+ end
59
+
60
+ def link(target, label)
61
+ %{<a href="#{href(target)}">#{label}</a>}
62
+ end
63
+
64
+ private
65
+
66
+ def with_input(input)
67
+ @input_stack.push(input)
68
+ begin
69
+ yield
70
+ ensure
71
+ @input_stack.pop
72
+ end
73
+ end
74
+
75
+ end
76
+
77
+ end
@@ -0,0 +1,66 @@
1
+ require "pathname"
2
+ require "tilt"
3
+
4
+ module Pith
5
+
6
+ class RenderContext
7
+
8
+ include Tilt::CompileSite
9
+
10
+ def initialize(input)
11
+ @input_stack = [input]
12
+ end
13
+
14
+ def initial_input
15
+ @input_stack.first
16
+ end
17
+
18
+ def current_input
19
+ @input_stack.last
20
+ end
21
+
22
+ def include(name, locals = {}, &block)
23
+ including_input = current_input
24
+ included_input = including_input.relative_input(name)
25
+ with_input(included_input) do
26
+ content_block = if block_given?
27
+ content = with_input(including_input) do
28
+ capture_haml(&block)
29
+ end
30
+ proc { content }
31
+ end
32
+ current_input.render(self, locals, &content_block)
33
+ end
34
+ end
35
+
36
+ def content_for
37
+ @content_for_hash ||= Hash.new { "" }
38
+ end
39
+
40
+ def meta
41
+ initial_input.meta || {}
42
+ end
43
+
44
+ def href(name)
45
+ target_path = current_input.relative_path(name)
46
+ target_path.relative_path_from(initial_input.path.parent)
47
+ end
48
+
49
+ def link(target, label)
50
+ %{<a href="#{href(target)}">#{label}</a>}
51
+ end
52
+
53
+ private
54
+
55
+ def with_input(input)
56
+ @input_stack.push(input)
57
+ begin
58
+ yield
59
+ ensure
60
+ @input_stack.pop
61
+ end
62
+ end
63
+
64
+ end
65
+
66
+ end
@@ -0,0 +1,42 @@
1
+ require "rack"
2
+ require "adsf/rack"
3
+ require "logger"
4
+
5
+ module Pith
6
+
7
+ module Server
8
+
9
+ def new(project)
10
+ Rack::Builder.new do
11
+ use Rack::CommonLogger, project.logger
12
+ use Rack::ShowExceptions
13
+ use Rack::Lint
14
+ use Pith::Server::AutoBuild, project
15
+ use Adsf::Rack::IndexFileFinder, :root => project.output_dir
16
+ run Rack::File.new(project.output_dir)
17
+ end
18
+ end
19
+
20
+ def run(project, options = {})
21
+ Rack::Handler.get("thin").run(new(project), options)
22
+ end
23
+
24
+ extend self
25
+
26
+ class AutoBuild
27
+
28
+ def initialize(app, project)
29
+ @app = app
30
+ @project = project
31
+ end
32
+
33
+ def call(env)
34
+ @project.build
35
+ @app.call(env)
36
+ end
37
+
38
+ end
39
+
40
+ end
41
+
42
+ end
@@ -0,0 +1,45 @@
1
+ require "rack"
2
+ require "adsf/rack"
3
+ require "logger"
4
+
5
+ module Pith
6
+
7
+ module Server
8
+
9
+ class << self
10
+
11
+ def new(project)
12
+ Rack::Builder.new do
13
+ use Rack::CommonLogger, project.logger
14
+ use Rack::ShowExceptions
15
+ use Rack::Lint
16
+ use Pith::Server::AutoBuild, project
17
+ use Adsf::Rack::IndexFileFinder, :root => project.output_dir
18
+ run Rack::File.new(project.output_dir)
19
+ end
20
+ end
21
+
22
+ def run(project)
23
+ app = new(project)
24
+ Rack::Handler.get("thin").run(app, :Port => 4321)
25
+ end
26
+
27
+ end
28
+
29
+ class AutoBuild
30
+
31
+ def initialize(app, project)
32
+ @app = app
33
+ @project = project
34
+ end
35
+
36
+ def call(env)
37
+ @project.build
38
+ @app.call(env)
39
+ end
40
+
41
+ end
42
+
43
+ end
44
+
45
+ end
@@ -0,0 +1,3 @@
1
+ module Pith
2
+ VERSION = "0.0.2".freeze
3
+ end
@@ -0,0 +1,3 @@
1
+ module Pith
2
+ VERSION = "0.0.2a".freeze
3
+ end
@@ -0,0 +1,7 @@
1
+ !!!
2
+ %html
3
+ %head
4
+ %link{ :href=>href("/stylesheets/app.css"), :rel=>"stylesheet", :type=>"text/css" }
5
+ %body
6
+
7
+ = yield
@@ -0,0 +1,8 @@
1
+ = include "_layouts/standard.haml" do
2
+
3
+ %ol.tabs
4
+ %li= link "index.html", "Introduction"
5
+
6
+ .box
7
+ %p This is my site. Do you like it?
8
+
@@ -0,0 +1,44 @@
1
+ .sidebar
2
+ width: 19%
3
+ float: right
4
+
5
+ .main
6
+ width: 79%
7
+
8
+ .box
9
+ -moz-border-radius: 0.5em
10
+ -webkit-border-radius: 0.5em
11
+ border: 2px solid grey
12
+ padding: 0.5em
13
+
14
+ .heading
15
+ font-size: 120%
16
+ border-bottom: 1px solid #aaa
17
+ font-weight: bold
18
+ margin-bottom: 0.5em
19
+
20
+ ol.tabs
21
+
22
+ position: relative
23
+ padding: 0
24
+ margin: 0 0 -2px 1em
25
+
26
+ list-style-type: none
27
+
28
+ li
29
+ display: inline-block
30
+ border: 2px solid grey
31
+ -moz-border-radius-topleft: 0.5em
32
+ -webkit-border-top-left-radius: 0.5em
33
+ -moz-border-radius-topright: 0.5em
34
+ -webkit-border-top-right-radius: 0.5em
35
+ background: #ccc
36
+ padding: 0.5em
37
+
38
+ &.current
39
+ border-bottom: 2px solid white
40
+ background: white
41
+
42
+ a
43
+ color: inherit
44
+ text-decoration: none