pith 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.
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