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