pith 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- data/README.markdown +29 -0
- data/Rakefile +16 -0
- data/bin/pith +60 -0
- data/cucumber.yml +7 -0
- data/features/content_for.feature +29 -0
- data/features/content_for.feature~ +29 -0
- data/features/haml.feature +24 -0
- data/features/haml.feature~ +24 -0
- data/features/helpers.feature +23 -0
- data/features/ignorance.feature +26 -0
- data/features/ignorance.feature~ +26 -0
- data/features/include.feature +84 -0
- data/features/include.feature~ +84 -0
- data/features/incremental_rebuild.feature +24 -0
- data/features/layouts.feature +43 -0
- data/features/layouts.feature~ +43 -0
- data/features/linking.feature +79 -0
- data/features/linking.feature~ +79 -0
- data/features/metadata.feature +20 -0
- data/features/metadata.feature~ +20 -0
- data/features/step_definitions/build_steps.rb +46 -0
- data/features/step_definitions/build_steps.rb~ +29 -0
- data/features/support/env.rb +75 -0
- data/features/support/env.rb~ +43 -0
- data/features/support/rspec_matchers.rb +5 -0
- data/features/textile.feature +29 -0
- data/features/textile.feature~ +29 -0
- data/features/verbatim.feature +32 -0
- data/features/verbatim.feature~ +32 -0
- data/lib/pith.rb +1 -0
- data/lib/pith.rb~ +2 -0
- data/lib/pith/console_logger.rb +20 -0
- data/lib/pith/console_logger.rb~ +20 -0
- data/lib/pith/input.rb +189 -0
- data/lib/pith/input.rb~ +95 -0
- data/lib/pith/metadata.rb +26 -0
- data/lib/pith/metadata.rb~ +26 -0
- data/lib/pith/project.rb +68 -0
- data/lib/pith/project.rb~ +50 -0
- data/lib/pith/render_context.rb +77 -0
- data/lib/pith/render_context.rb~ +66 -0
- data/lib/pith/server.rb +42 -0
- data/lib/pith/server.rb~ +45 -0
- data/lib/pith/version.rb +3 -0
- data/lib/pith/version.rb~ +3 -0
- data/sample/_layouts/standard.haml +7 -0
- data/sample/index.html.haml +8 -0
- data/sample/stylesheets/app.css.sass +44 -0
- data/spec/pith/metadata_spec.rb +46 -0
- data/spec/pith/metadata_spec.rb~ +46 -0
- data/spec/pith/project_spec.rb +61 -0
- data/spec/spec_helper.rb +27 -0
- data/spec/spec_helper.rb~ +0 -0
- 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
|
data/lib/pith/project.rb
ADDED
@@ -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
|
data/lib/pith/server.rb
ADDED
@@ -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
|
data/lib/pith/server.rb~
ADDED
@@ -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
|
data/lib/pith/version.rb
ADDED
@@ -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
|