pith 0.0.6 → 0.0.7
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 +28 -6
- data/bin/pith +35 -9
- data/features/metadata.feature +2 -2
- data/features/relative_linking.feature +67 -0
- data/features/{verbatim.feature → resources.feature} +18 -4
- data/features/step_definitions/build_steps.rb +8 -0
- data/lib/pith/console_logger.rb +0 -4
- data/lib/pith/input/abstract.rb +5 -5
- data/lib/pith/input/{verbatim.rb → resource.rb} +1 -1
- data/lib/pith/input/template.rb +4 -0
- data/lib/pith/input/template.rb~ +3 -7
- data/lib/pith/input.rb +2 -2
- data/lib/pith/pathname_ext.rb +14 -0
- data/lib/pith/project.rb +23 -7
- data/lib/pith/reference_error.rb +5 -0
- data/lib/pith/render_context.rb +29 -23
- data/lib/pith/render_context.rb~ +7 -6
- data/lib/pith/server.rb +17 -12
- data/lib/pith/version.rb +1 -1
- data/lib/pith/version.rb~ +1 -1
- data/spec/pith/input/template_spec.rb +48 -0
- data/spec/pith/project_spec.rb +28 -6
- data/spec/spec_helper.rb +0 -10
- metadata +11 -9
- data/spec/pith/input/abstract_spec.rb +0 -31
data/README.markdown
CHANGED
@@ -6,15 +6,10 @@ Pith is a static website generator, written in Ruby.
|
|
6
6
|
Using Pith, you can:
|
7
7
|
|
8
8
|
* Lay-out your page designs in [Haml][haml], ERb, or Liquid.
|
9
|
-
|
10
9
|
* Style things up using [Sass][sass].
|
11
|
-
|
12
10
|
* Succintly add content using Markdown or Textile.
|
13
|
-
|
14
11
|
* Encapsulate common markup in "layout" and "partial" templates.
|
15
|
-
|
16
12
|
* Easily link pages (and resources) using relative links.
|
17
|
-
|
18
13
|
* Test changes quickly using the built-in web-server.
|
19
14
|
|
20
15
|
Install it
|
@@ -35,7 +30,7 @@ Create an input directory for your site (wherever you want), and pop some files
|
|
35
30
|
logo.png
|
36
31
|
index.html.haml
|
37
32
|
|
38
|
-
The only requirement is the existance of a sub-directory called "`_pith`". Pith checks that it's present, to prevent you accidently treating
|
33
|
+
The only requirement is the existance of a sub-directory called "`_pith`". Pith checks that it's present, to prevent you accidently treating your entire home-directory as website input.
|
39
34
|
|
40
35
|
Next, use the `pith build` command to convert your inputs into a functioning website.
|
41
36
|
|
@@ -55,6 +50,25 @@ Any input file with an extension recognised by [Tilt][tilt] is considered to be
|
|
55
50
|
|
56
51
|
Anything else is just copied verbatim into the generated site.
|
57
52
|
|
53
|
+
Page metadata
|
54
|
+
-------------
|
55
|
+
|
56
|
+
A YAML header can be provided at the top of any template, defining page metadata. The header is introduced by a first line containing three dashes, and terminated by a line containing three dots.
|
57
|
+
|
58
|
+
---
|
59
|
+
title: "All about fish"
|
60
|
+
...
|
61
|
+
|
62
|
+
Metadata provided in the header can be referenced by template content, via the "`page`" object:
|
63
|
+
|
64
|
+
%html
|
65
|
+
%head
|
66
|
+
%title= page.title
|
67
|
+
%body
|
68
|
+
%h1= page.title
|
69
|
+
|
70
|
+
This is especially useful in "layout" templates (see below).
|
71
|
+
|
58
72
|
Partials
|
59
73
|
--------
|
60
74
|
|
@@ -92,6 +106,14 @@ Use "`yield`" to embed the block's content within the layout:
|
|
92
106
|
.main
|
93
107
|
= yield
|
94
108
|
|
109
|
+
Layouts can also be specified using a "`layout`" entry in the page header, e.g.
|
110
|
+
|
111
|
+
---
|
112
|
+
layout: "/_mylayout.haml"
|
113
|
+
...
|
114
|
+
|
115
|
+
Some content
|
116
|
+
|
95
117
|
Relative links
|
96
118
|
--------------
|
97
119
|
|
data/bin/pith
CHANGED
@@ -8,15 +8,17 @@ require "pathname"
|
|
8
8
|
require "pith/version"
|
9
9
|
|
10
10
|
$input_dir = Pathname(".")
|
11
|
+
$interval = 2
|
12
|
+
$port = 4321
|
11
13
|
|
12
14
|
BANNER = <<EOF
|
13
15
|
usage: pith [OPTIONS] [COMMAND]
|
14
16
|
|
15
17
|
Commands: (default: "build")
|
16
18
|
|
17
|
-
build Generate the website into OUTPUT_DIR
|
18
|
-
|
19
|
-
serve Serve the website
|
19
|
+
build Generate the website (into OUTPUT_DIR)
|
20
|
+
watch Monitor INPUT_DIR, and incrementally rebuild OUTPUT_DIR
|
21
|
+
serve Serve the generated website at "http://localhost:#{$port}"
|
20
22
|
|
21
23
|
EOF
|
22
24
|
|
@@ -24,12 +26,18 @@ OptionParser.new do |opts|
|
|
24
26
|
opts.banner = BANNER
|
25
27
|
opts.version = Pith::VERSION
|
26
28
|
opts.separator " Options:"
|
27
|
-
opts.on("-i", "--input INPUT_DIR",
|
29
|
+
opts.on("-i", "--input INPUT_DIR", %[Input directory (default: ".")]) do |dir|
|
28
30
|
$input_dir = Pathname(dir)
|
29
31
|
end
|
30
|
-
opts.on("-o", "--output OUTPUT_DIR",
|
32
|
+
opts.on("-o", "--output OUTPUT_DIR", %[Output directory (default: "INPUT_DIR/_out")]) do |dir|
|
31
33
|
$output_dir = Pathname(dir)
|
32
34
|
end
|
35
|
+
opts.on("-n", "--interval N", Integer, %[Rebuild interval (default: #{$interval})]) do |n|
|
36
|
+
$interval = n
|
37
|
+
end
|
38
|
+
opts.on("-p", "--port N", Integer, %[Web-server port (default: #{$port})]) do |port|
|
39
|
+
$port = port
|
40
|
+
end
|
33
41
|
opts.on_tail("-h", "--help", "Show this message") do
|
34
42
|
puts opts
|
35
43
|
exit
|
@@ -46,6 +54,8 @@ unless $output_dir
|
|
46
54
|
$output_dir = $input_dir + "_out"
|
47
55
|
end
|
48
56
|
|
57
|
+
puts %{Generating to "#{$output_dir}"}
|
58
|
+
|
49
59
|
require "pith/project"
|
50
60
|
require "pith/console_logger"
|
51
61
|
|
@@ -53,16 +63,32 @@ require "pith/console_logger"
|
|
53
63
|
@project.logger = Pith::ConsoleLogger.new
|
54
64
|
|
55
65
|
def build
|
56
|
-
puts %{Generating to "#{$output_dir}"}
|
57
66
|
@project.build
|
58
67
|
end
|
59
68
|
|
69
|
+
def watch
|
70
|
+
loop do
|
71
|
+
begin
|
72
|
+
build
|
73
|
+
rescue Exception => e
|
74
|
+
$stderr.puts "ERROR: #{e}"
|
75
|
+
e.backtrace.each { |line| $stderr.puts line }
|
76
|
+
end
|
77
|
+
sleep($interval)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
60
81
|
def serve
|
82
|
+
|
61
83
|
require "pith/server"
|
62
|
-
|
84
|
+
server = Pith::Server.new(@project)
|
85
|
+
|
63
86
|
build
|
64
|
-
|
65
|
-
|
87
|
+
Thread.new { watch }
|
88
|
+
|
89
|
+
puts %{>>> Now taking the Pith at "http://localhost:#{$port}"}
|
90
|
+
Rack::Handler.default.run(server, :Port => $port)
|
91
|
+
|
66
92
|
end
|
67
93
|
|
68
94
|
action = ARGV.shift || "build"
|
data/features/metadata.feature
CHANGED
@@ -10,7 +10,7 @@ Scenario: use meta-data from YAML comment
|
|
10
10
|
---
|
11
11
|
title: PAGE TITLE
|
12
12
|
---
|
13
|
-
%h1= meta["title"]
|
13
|
+
%h1= page.meta["title"]
|
14
14
|
"""
|
15
15
|
|
16
16
|
When I build the site
|
@@ -24,7 +24,7 @@ Scenario: corrupt meta-data
|
|
24
24
|
Given input file "page.html.haml" contains
|
25
25
|
"""
|
26
26
|
---
|
27
|
-
title: "This" is
|
27
|
+
title: "This" is not well-formed YAML
|
28
28
|
...
|
29
29
|
%p PAGE BODY
|
30
30
|
"""
|
@@ -3,6 +3,11 @@ Feature: linking between files
|
|
3
3
|
I want to be able to generate relative reference to other pages
|
4
4
|
So that the generated site is re-locateable
|
5
5
|
|
6
|
+
Background:
|
7
|
+
|
8
|
+
Given the "assume_content_negotiation" flag is disabled
|
9
|
+
And the "assume_directory_index" flag is disabled
|
10
|
+
|
6
11
|
Scenario: link from one top-level page to another
|
7
12
|
|
8
13
|
Given input file "index.html.haml" contains
|
@@ -107,3 +112,65 @@ Scenario: use "title" meta-data attribute in link
|
|
107
112
|
"""
|
108
113
|
<a href="page.html">Title from meta-data</a>
|
109
114
|
"""
|
115
|
+
|
116
|
+
Scenario: link to an Input object
|
117
|
+
|
118
|
+
Given input file "subdir/page.html.haml" contains
|
119
|
+
"""
|
120
|
+
= link(project.input("help.html"))
|
121
|
+
"""
|
122
|
+
|
123
|
+
And input file "help.html.haml" contains
|
124
|
+
"""
|
125
|
+
---
|
126
|
+
title: "Help!"
|
127
|
+
...
|
128
|
+
"""
|
129
|
+
|
130
|
+
When I build the site
|
131
|
+
Then output file "subdir/page.html" should contain
|
132
|
+
"""
|
133
|
+
<a href="../help.html">Help!</a>
|
134
|
+
"""
|
135
|
+
|
136
|
+
Scenario: link to a missing resource
|
137
|
+
|
138
|
+
Given input file "index.html.haml" contains
|
139
|
+
"""
|
140
|
+
= link("missing_page.html")
|
141
|
+
"""
|
142
|
+
|
143
|
+
When I build the site
|
144
|
+
Then output file "index.html" should contain
|
145
|
+
"""
|
146
|
+
<a href="missing_page.html">???</a>
|
147
|
+
"""
|
148
|
+
|
149
|
+
Scenario: assume content negotiation
|
150
|
+
|
151
|
+
Given the "assume_content_negotiation" flag is enabled
|
152
|
+
And input file "index.html.haml" contains
|
153
|
+
"""
|
154
|
+
= link("page.html", "Page")
|
155
|
+
"""
|
156
|
+
|
157
|
+
When I build the site
|
158
|
+
Then output file "index.html" should contain
|
159
|
+
"""
|
160
|
+
<a href="page">Page</a>
|
161
|
+
"""
|
162
|
+
|
163
|
+
Scenario: link to an index page
|
164
|
+
|
165
|
+
Given the "assume_directory_index" flag is enabled
|
166
|
+
|
167
|
+
And input file "page.html.haml" contains
|
168
|
+
"""
|
169
|
+
= link("stuff/index.html", "Stuff")
|
170
|
+
"""
|
171
|
+
|
172
|
+
When I build the site
|
173
|
+
Then output file "page.html" should contain
|
174
|
+
"""
|
175
|
+
<a href="stuff/">Stuff</a>
|
176
|
+
"""
|
@@ -5,28 +5,42 @@ Feature: unrecognised input files are copied into output intact
|
|
5
5
|
|
6
6
|
Scenario: text file
|
7
7
|
|
8
|
-
Given input file "
|
8
|
+
Given input file "resource.txt" contains
|
9
9
|
"""
|
10
10
|
Blah de blah
|
11
11
|
"""
|
12
12
|
|
13
13
|
When I build the site
|
14
14
|
|
15
|
-
Then output file "
|
15
|
+
Then output file "resource.txt" should contain
|
16
16
|
"""
|
17
17
|
Blah de blah
|
18
18
|
"""
|
19
19
|
|
20
20
|
Scenario: file in subdirectory
|
21
21
|
|
22
|
-
Given input file "blah/
|
22
|
+
Given input file "blah/resource.txt" contains
|
23
23
|
"""
|
24
24
|
Blah de blah
|
25
25
|
"""
|
26
26
|
|
27
27
|
When I build the site
|
28
28
|
|
29
|
-
Then output file "blah/
|
29
|
+
Then output file "blah/resource.txt" should contain
|
30
30
|
"""
|
31
31
|
Blah de blah
|
32
32
|
"""
|
33
|
+
|
34
|
+
Scenario: dot-file
|
35
|
+
|
36
|
+
Given input file ".htaccess" contains
|
37
|
+
"""
|
38
|
+
DirectoryIndex index.html
|
39
|
+
"""
|
40
|
+
|
41
|
+
When I build the site
|
42
|
+
|
43
|
+
Then output file ".htaccess" should contain
|
44
|
+
"""
|
45
|
+
DirectoryIndex index.html
|
46
|
+
"""
|
@@ -14,6 +14,14 @@ Given "the site is up-to-date" do
|
|
14
14
|
When "I build the site"
|
15
15
|
end
|
16
16
|
|
17
|
+
Given /^the "([^\"]*)" flag is enabled$/ do |flag|
|
18
|
+
@project.send("#{flag}=", true)
|
19
|
+
end
|
20
|
+
|
21
|
+
Given /^the "([^\"]*)" flag is disabled$/ do |flag|
|
22
|
+
@project.send("#{flag}=", false)
|
23
|
+
end
|
24
|
+
|
17
25
|
When /^I change input file "([^\"]*)" to contain "([^\"]*)"$/ do |path, content|
|
18
26
|
@inputs[path] = content
|
19
27
|
end
|
data/lib/pith/console_logger.rb
CHANGED
data/lib/pith/input/abstract.rb
CHANGED
@@ -20,11 +20,15 @@ module Pith
|
|
20
20
|
project.input_dir + path
|
21
21
|
end
|
22
22
|
|
23
|
+
# Public: Get the file-system location of the corresponding output file.
|
24
|
+
#
|
25
|
+
# Returns a fully-qualified Pathname.
|
26
|
+
#
|
23
27
|
def output_file
|
24
28
|
project.output_dir + output_path
|
25
29
|
end
|
26
30
|
|
27
|
-
# Public: Generate
|
31
|
+
# Public: Generate an output file.
|
28
32
|
#
|
29
33
|
def build
|
30
34
|
return false if ignorable? || uptodate?
|
@@ -59,10 +63,6 @@ module Pith
|
|
59
63
|
end
|
60
64
|
|
61
65
|
protected
|
62
|
-
|
63
|
-
def default_title
|
64
|
-
path.to_s.sub(/\..*/, '').tr('_-', ' ').capitalize
|
65
|
-
end
|
66
66
|
|
67
67
|
def logger
|
68
68
|
project.logger
|
data/lib/pith/input/template.rb
CHANGED
data/lib/pith/input/template.rb~
CHANGED
@@ -28,7 +28,7 @@ module Pith
|
|
28
28
|
# Return true unless output needs to be re-generated.
|
29
29
|
#
|
30
30
|
def uptodate?
|
31
|
-
|
31
|
+
dependencies && FileUtils.uptodate?(output_file, dependencies)
|
32
32
|
end
|
33
33
|
|
34
34
|
# Generate output for this template
|
@@ -39,7 +39,7 @@ module Pith
|
|
39
39
|
output_file.open("w") do |out|
|
40
40
|
out.puts(render_context.render(self))
|
41
41
|
end
|
42
|
-
|
42
|
+
@dependencies = render_context.dependencies
|
43
43
|
end
|
44
44
|
|
45
45
|
# Render this input using Tilt
|
@@ -112,11 +112,7 @@ module Pith
|
|
112
112
|
end
|
113
113
|
end
|
114
114
|
|
115
|
-
|
116
|
-
@all_input_files = referenced_inputs.map { |input| input.file }
|
117
|
-
end
|
118
|
-
|
119
|
-
attr_accessor :all_input_files
|
115
|
+
attr_accessor :dependencies
|
120
116
|
|
121
117
|
end
|
122
118
|
|
data/lib/pith/input.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
require "pith/input/template"
|
2
|
-
require "pith/input/
|
2
|
+
require "pith/input/resource"
|
3
3
|
|
4
4
|
module Pith
|
5
5
|
module Input
|
@@ -9,7 +9,7 @@ module Pith
|
|
9
9
|
def new(project, path)
|
10
10
|
Template.new(project, path)
|
11
11
|
rescue Template::UnrecognisedType
|
12
|
-
|
12
|
+
Resource.new(project, path)
|
13
13
|
end
|
14
14
|
|
15
15
|
end
|
data/lib/pith/project.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
|
-
require "pathname"
|
2
1
|
require "logger"
|
3
2
|
require "pith/input"
|
3
|
+
require "pith/pathname_ext"
|
4
|
+
require "pith/reference_error"
|
4
5
|
require "tilt"
|
5
6
|
|
6
7
|
module Pith
|
@@ -13,8 +14,20 @@ module Pith
|
|
13
14
|
end
|
14
15
|
end
|
15
16
|
|
16
|
-
|
17
|
+
attr_reader :input_dir
|
17
18
|
|
19
|
+
attr_accessor :output_dir
|
20
|
+
attr_accessor :assume_content_negotiation
|
21
|
+
attr_accessor :assume_directory_index
|
22
|
+
|
23
|
+
def input_dir=(dir)
|
24
|
+
@input_dir = Pathname(dir)
|
25
|
+
end
|
26
|
+
|
27
|
+
def output_dir=(dir)
|
28
|
+
@output_dir = Pathname(dir)
|
29
|
+
end
|
30
|
+
|
18
31
|
# Public: get inputs
|
19
32
|
#
|
20
33
|
# Returns Pith::Input objects representing the files in the input_dir.
|
@@ -23,7 +36,7 @@ module Pith
|
|
23
36
|
# call #refresh to discard the cached data.
|
24
37
|
#
|
25
38
|
def inputs
|
26
|
-
@inputs ||=
|
39
|
+
@inputs ||= input_dir.glob_all("**/*").map do |input_file|
|
27
40
|
next if input_file.directory?
|
28
41
|
path = input_file.relative_path_from(input_dir)
|
29
42
|
find_or_create_input(path)
|
@@ -42,7 +55,7 @@ module Pith
|
|
42
55
|
inputs.each do |input|
|
43
56
|
return input if input.path == path || input.output_path == path
|
44
57
|
end
|
45
|
-
|
58
|
+
nil
|
46
59
|
end
|
47
60
|
|
48
61
|
# Public: build the project, generating output files.
|
@@ -53,6 +66,7 @@ module Pith
|
|
53
66
|
inputs.each do |input|
|
54
67
|
input.build
|
55
68
|
end
|
69
|
+
output_dir.touch
|
56
70
|
end
|
57
71
|
|
58
72
|
# Public: discard cached data that is out-of-sync with the file-system.
|
@@ -62,6 +76,10 @@ module Pith
|
|
62
76
|
@config_files = nil
|
63
77
|
end
|
64
78
|
|
79
|
+
def last_built_at
|
80
|
+
output_dir.mtime
|
81
|
+
end
|
82
|
+
|
65
83
|
def logger
|
66
84
|
@logger ||= Logger.new(nil)
|
67
85
|
end
|
@@ -78,7 +96,7 @@ module Pith
|
|
78
96
|
|
79
97
|
def config_files
|
80
98
|
@config_files ||= begin
|
81
|
-
|
99
|
+
input_dir.glob_all("_pith/**")
|
82
100
|
end.to_set
|
83
101
|
end
|
84
102
|
|
@@ -105,7 +123,5 @@ module Pith
|
|
105
123
|
end
|
106
124
|
|
107
125
|
end
|
108
|
-
|
109
|
-
class ReferenceError < StandardError; end
|
110
126
|
|
111
127
|
end
|
data/lib/pith/render_context.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
|
-
require "
|
1
|
+
require "ostruct"
|
2
2
|
require "pathname"
|
3
|
+
require "pith/reference_error"
|
4
|
+
require "set"
|
3
5
|
require "tilt"
|
4
6
|
|
5
7
|
module Pith
|
@@ -17,7 +19,7 @@ module Pith
|
|
17
19
|
|
18
20
|
attr_reader :project
|
19
21
|
|
20
|
-
def
|
22
|
+
def page
|
21
23
|
@input_stack.first
|
22
24
|
end
|
23
25
|
|
@@ -28,7 +30,7 @@ module Pith
|
|
28
30
|
def render(input, locals = {}, &block)
|
29
31
|
with_input(input) do
|
30
32
|
result = input.render(self, locals, &block)
|
31
|
-
layout_ref =
|
33
|
+
layout_ref = input.meta["layout"]
|
32
34
|
result = render_ref(layout_ref) { result } if layout_ref
|
33
35
|
result
|
34
36
|
end
|
@@ -50,37 +52,42 @@ module Pith
|
|
50
52
|
@content_for_hash ||= Hash.new { "" }
|
51
53
|
end
|
52
54
|
|
53
|
-
def
|
54
|
-
|
55
|
+
def relative_url_to(target_path)
|
56
|
+
url = target_path.relative_path_from(page.path.parent)
|
57
|
+
url = url.sub(/index\.html$/, "") if project.assume_directory_index
|
58
|
+
url = url.sub(/\.html$/, "") if project.assume_content_negotiation
|
59
|
+
url
|
55
60
|
end
|
56
61
|
|
57
62
|
def href(target_ref)
|
58
|
-
|
63
|
+
relative_url_to(resolve_reference(target_ref))
|
59
64
|
end
|
60
65
|
|
61
66
|
def link(target_ref, label = nil)
|
62
|
-
target_path =
|
63
|
-
label ||= begin
|
64
|
-
|
65
|
-
rescue
|
66
|
-
"???"
|
67
|
+
target_path = resolve_reference(target_ref)
|
68
|
+
label ||= begin
|
69
|
+
input(target_path).title
|
70
|
+
rescue ReferenceError
|
71
|
+
"???"
|
67
72
|
end
|
68
|
-
|
73
|
+
url = relative_url_to(target_path)
|
74
|
+
%{<a href="#{url}">#{label}</a>}
|
69
75
|
end
|
70
76
|
|
71
77
|
private
|
72
78
|
|
73
|
-
def
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
+
def resolve_reference(ref)
|
80
|
+
if ref.respond_to?(:output_path)
|
81
|
+
ref.output_path
|
82
|
+
else
|
83
|
+
current_input.resolve_path(ref)
|
84
|
+
end
|
79
85
|
end
|
80
86
|
|
81
|
-
def
|
87
|
+
def input(path)
|
82
88
|
input = project.input(path)
|
83
|
-
|
89
|
+
raise(ReferenceError, %{Can't find "#{path}"}) if input.nil?
|
90
|
+
@dependencies << input.file
|
84
91
|
input
|
85
92
|
end
|
86
93
|
|
@@ -95,9 +102,8 @@ module Pith
|
|
95
102
|
end
|
96
103
|
|
97
104
|
def render_ref(template_ref, locals = {}, &block)
|
98
|
-
|
99
|
-
|
100
|
-
render(template, locals, &block)
|
105
|
+
template_input = input(resolve_reference(template_ref))
|
106
|
+
render(template_input, locals, &block)
|
101
107
|
end
|
102
108
|
|
103
109
|
end
|
data/lib/pith/render_context.rb~
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
require "set"
|
2
2
|
require "pathname"
|
3
|
+
require "ostruct"
|
3
4
|
require "tilt"
|
4
5
|
|
5
6
|
module Pith
|
@@ -11,7 +12,7 @@ module Pith
|
|
11
12
|
def initialize(project)
|
12
13
|
@project = project
|
13
14
|
@input_stack = []
|
14
|
-
@
|
15
|
+
@dependencies = project.config_files.dup
|
15
16
|
self.extend(project.helper_module)
|
16
17
|
end
|
17
18
|
|
@@ -34,7 +35,7 @@ module Pith
|
|
34
35
|
end
|
35
36
|
end
|
36
37
|
|
37
|
-
attr_reader :
|
38
|
+
attr_reader :dependencies
|
38
39
|
|
39
40
|
def include(template_ref, locals = {}, &block)
|
40
41
|
content_block = if block_given?
|
@@ -50,8 +51,8 @@ module Pith
|
|
50
51
|
@content_for_hash ||= Hash.new { "" }
|
51
52
|
end
|
52
53
|
|
53
|
-
def
|
54
|
-
initial_input.meta
|
54
|
+
def page
|
55
|
+
@page ||= OpenStruct.new(initial_input.meta)
|
55
56
|
end
|
56
57
|
|
57
58
|
def href(target_ref)
|
@@ -80,12 +81,12 @@ module Pith
|
|
80
81
|
|
81
82
|
def find_input(path)
|
82
83
|
input = project.input(path)
|
83
|
-
@
|
84
|
+
@dependencies << input.file if input
|
84
85
|
input
|
85
86
|
end
|
86
87
|
|
87
88
|
def with_input(input)
|
88
|
-
@
|
89
|
+
@dependencies << input.file
|
89
90
|
@input_stack.push(input)
|
90
91
|
begin
|
91
92
|
yield
|
data/lib/pith/server.rb
CHANGED
@@ -7,31 +7,36 @@ module Pith
|
|
7
7
|
|
8
8
|
def new(project)
|
9
9
|
Rack::Builder.new do
|
10
|
-
use Rack::CommonLogger
|
10
|
+
use Rack::CommonLogger
|
11
11
|
use Rack::ShowExceptions
|
12
12
|
use Rack::Lint
|
13
|
-
use Pith::Server::AutoBuild, project
|
14
13
|
use Adsf::Rack::IndexFileFinder, :root => project.output_dir
|
14
|
+
use Pith::Server::DefaultToHtml, project.output_dir
|
15
15
|
run Rack::Directory.new(project.output_dir)
|
16
16
|
end
|
17
17
|
end
|
18
18
|
|
19
|
-
def run(project, options = {})
|
20
|
-
Rack::Handler.get("thin").run(new(project), options)
|
21
|
-
end
|
22
|
-
|
23
19
|
extend self
|
24
|
-
|
25
|
-
class AutoBuild
|
26
20
|
|
27
|
-
|
28
|
-
|
29
|
-
|
21
|
+
class DefaultToHtml
|
22
|
+
|
23
|
+
def initialize(app, root)
|
24
|
+
@app = app
|
25
|
+
@root = root
|
30
26
|
end
|
31
27
|
|
32
28
|
def call(env)
|
33
|
-
|
29
|
+
|
30
|
+
path_info = ::Rack::Utils.unescape(env["PATH_INFO"])
|
31
|
+
file = "#{@root}#{path_info}"
|
32
|
+
unless File.exist?(file)
|
33
|
+
if File.exist?("#{file}.html")
|
34
|
+
env["PATH_INFO"] += ".html"
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
34
38
|
@app.call(env)
|
39
|
+
|
35
40
|
end
|
36
41
|
|
37
42
|
end
|
data/lib/pith/version.rb
CHANGED
data/lib/pith/version.rb~
CHANGED
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require "pith/input/abstract"
|
3
|
+
require "pith/project"
|
4
|
+
|
5
|
+
describe Pith::Input::Template do
|
6
|
+
|
7
|
+
before do
|
8
|
+
$input_dir.mkpath
|
9
|
+
@project = Pith::Project.new(:input_dir => $input_dir)
|
10
|
+
end
|
11
|
+
|
12
|
+
def make_input(path)
|
13
|
+
input_file = $input_dir + path
|
14
|
+
input_file.parent.mkpath
|
15
|
+
input_file.open("w") do |io|
|
16
|
+
yield io if block_given?
|
17
|
+
end
|
18
|
+
@project.input(path)
|
19
|
+
end
|
20
|
+
|
21
|
+
describe "#title" do
|
22
|
+
|
23
|
+
it "is based on last component of filename" do
|
24
|
+
@input = make_input("dir/some_page.html.haml")
|
25
|
+
@input.title.should == "Some page"
|
26
|
+
end
|
27
|
+
|
28
|
+
it "can be over-ridden in metadata" do
|
29
|
+
@input = make_input("dir/some_page.html.haml") do |i|
|
30
|
+
i.puts "---"
|
31
|
+
i.puts "title: Blah blah"
|
32
|
+
i.puts "..."
|
33
|
+
end
|
34
|
+
@input.title.should == "Blah blah"
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
|
39
|
+
describe "#output_path" do
|
40
|
+
|
41
|
+
it "excludes the template-type extension" do
|
42
|
+
@input = make_input("dir/some_page.html.haml")
|
43
|
+
@input.output_path.should == Pathname("dir/some_page.html")
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
data/spec/pith/project_spec.rb
CHANGED
@@ -17,9 +17,9 @@ describe Pith::Project do
|
|
17
17
|
@input_file.touch
|
18
18
|
end
|
19
19
|
|
20
|
-
it "constructs an
|
20
|
+
it "constructs an Resource object" do
|
21
21
|
@input = @project.input("input.txt")
|
22
|
-
@input.should be_kind_of(Pith::Input::
|
22
|
+
@input.should be_kind_of(Pith::Input::Resource)
|
23
23
|
@input.file.should == @input_file
|
24
24
|
end
|
25
25
|
|
@@ -55,10 +55,8 @@ describe Pith::Project do
|
|
55
55
|
|
56
56
|
describe "(with an invalid input path)" do
|
57
57
|
|
58
|
-
it "
|
59
|
-
|
60
|
-
@project.input("bogus.path")
|
61
|
-
end.should raise_error(Pith::ReferenceError)
|
58
|
+
it "returns nil" do
|
59
|
+
@project.input("bogus.path").should be_nil
|
62
60
|
end
|
63
61
|
|
64
62
|
end
|
@@ -112,4 +110,28 @@ describe Pith::Project do
|
|
112
110
|
|
113
111
|
end
|
114
112
|
|
113
|
+
describe "when an input file is removed" do
|
114
|
+
|
115
|
+
before do
|
116
|
+
@input_file = $input_dir + "input.html.haml"
|
117
|
+
@input_file.touch(Time.now - 10)
|
118
|
+
end
|
119
|
+
|
120
|
+
describe "a second call to #input" do
|
121
|
+
it "returns nil" do
|
122
|
+
|
123
|
+
first_time = @project.input("input.html.haml")
|
124
|
+
first_time.should_not be_nil
|
125
|
+
|
126
|
+
FileUtils.rm(@input_file)
|
127
|
+
|
128
|
+
@project.refresh
|
129
|
+
second_time = @project.input("input.html.haml")
|
130
|
+
second_time.should be_nil
|
131
|
+
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
end
|
136
|
+
|
115
137
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,16 +1,6 @@
|
|
1
1
|
require "rubygems"
|
2
2
|
|
3
3
|
require "fileutils"
|
4
|
-
require "pathname"
|
5
|
-
|
6
|
-
class Pathname
|
7
|
-
|
8
|
-
def touch(mtime = nil)
|
9
|
-
FileUtils.touch(self.to_s)
|
10
|
-
utime(mtime, mtime) if mtime
|
11
|
-
end
|
12
|
-
|
13
|
-
end
|
14
4
|
|
15
5
|
$project_dir = Pathname(__FILE__).expand_path.parent.parent
|
16
6
|
$tmp_dir = $project_dir + "tmp"
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pith
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 17
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 0
|
9
|
-
-
|
10
|
-
version: 0.0.
|
9
|
+
- 7
|
10
|
+
version: 0.0.7
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Mike Williams
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2010-09-
|
18
|
+
date: 2010-09-09 00:00:00 +10:00
|
19
19
|
default_executable: pith
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
@@ -96,15 +96,17 @@ files:
|
|
96
96
|
- lib/pith/console_logger.rb~
|
97
97
|
- lib/pith/input/abstract.rb
|
98
98
|
- lib/pith/input/abstract.rb~
|
99
|
+
- lib/pith/input/resource.rb
|
99
100
|
- lib/pith/input/template.rb
|
100
101
|
- lib/pith/input/template.rb~
|
101
|
-
- lib/pith/input/verbatim.rb
|
102
102
|
- lib/pith/input/verbatim.rb~
|
103
103
|
- lib/pith/input.rb
|
104
104
|
- lib/pith/input.rb~
|
105
105
|
- lib/pith/metadata.rb~
|
106
|
+
- lib/pith/pathname_ext.rb
|
106
107
|
- lib/pith/project.rb
|
107
108
|
- lib/pith/project.rb~
|
109
|
+
- lib/pith/reference_error.rb
|
108
110
|
- lib/pith/render_context.rb
|
109
111
|
- lib/pith/render_context.rb~
|
110
112
|
- lib/pith/server.rb
|
@@ -122,8 +124,8 @@ files:
|
|
122
124
|
- sample/stylesheets/app.css.sass
|
123
125
|
- README.markdown
|
124
126
|
- Rakefile
|
125
|
-
- spec/pith/input/abstract_spec.rb
|
126
127
|
- spec/pith/input/abstract_spec.rb~
|
128
|
+
- spec/pith/input/template_spec.rb
|
127
129
|
- spec/pith/metadata_spec.rb~
|
128
130
|
- spec/pith/project_spec.rb
|
129
131
|
- spec/pith/project_spec.rb~
|
@@ -148,6 +150,7 @@ files:
|
|
148
150
|
- features/metadata.feature~
|
149
151
|
- features/relative_linking.feature
|
150
152
|
- features/relative_linking.feature~
|
153
|
+
- features/resources.feature
|
151
154
|
- features/step_definitions/build_steps.rb
|
152
155
|
- features/step_definitions/build_steps.rb~
|
153
156
|
- features/support/env.rb
|
@@ -156,7 +159,6 @@ files:
|
|
156
159
|
- features/support/rspec_matchers.rb~
|
157
160
|
- features/textile.feature
|
158
161
|
- features/textile.feature~
|
159
|
-
- features/verbatim.feature
|
160
162
|
- features/verbatim.feature~
|
161
163
|
- cucumber.yml
|
162
164
|
- bin/pith
|
@@ -196,8 +198,8 @@ specification_version: 3
|
|
196
198
|
summary: A static website generator
|
197
199
|
test_files:
|
198
200
|
- Rakefile
|
199
|
-
- spec/pith/input/abstract_spec.rb
|
200
201
|
- spec/pith/input/abstract_spec.rb~
|
202
|
+
- spec/pith/input/template_spec.rb
|
201
203
|
- spec/pith/metadata_spec.rb~
|
202
204
|
- spec/pith/project_spec.rb
|
203
205
|
- spec/pith/project_spec.rb~
|
@@ -222,6 +224,7 @@ test_files:
|
|
222
224
|
- features/metadata.feature~
|
223
225
|
- features/relative_linking.feature
|
224
226
|
- features/relative_linking.feature~
|
227
|
+
- features/resources.feature
|
225
228
|
- features/step_definitions/build_steps.rb
|
226
229
|
- features/step_definitions/build_steps.rb~
|
227
230
|
- features/support/env.rb
|
@@ -230,6 +233,5 @@ test_files:
|
|
230
233
|
- features/support/rspec_matchers.rb~
|
231
234
|
- features/textile.feature
|
232
235
|
- features/textile.feature~
|
233
|
-
- features/verbatim.feature
|
234
236
|
- features/verbatim.feature~
|
235
237
|
- cucumber.yml
|
@@ -1,31 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
require "pith/input/abstract"
|
3
|
-
require "pith/project"
|
4
|
-
|
5
|
-
describe Pith::Input::Abstract do
|
6
|
-
|
7
|
-
before do
|
8
|
-
$input_dir.mkpath
|
9
|
-
@project = Pith::Project.new(:input_dir => $input_dir)
|
10
|
-
@input_file = $input_dir + "some_page.html.haml"
|
11
|
-
@input_file.touch
|
12
|
-
end
|
13
|
-
|
14
|
-
describe "#title" do
|
15
|
-
|
16
|
-
it "is based on last component of filename" do
|
17
|
-
@project.input("some_page.html").title.should == "Some page"
|
18
|
-
end
|
19
|
-
|
20
|
-
it "can be over-ridden in metadata" do
|
21
|
-
@input_file.open("w") do |i|
|
22
|
-
i.puts "---"
|
23
|
-
i.puts "title: Blah blah"
|
24
|
-
i.puts "..."
|
25
|
-
end
|
26
|
-
@project.input("some_page.html").title.should == "Blah blah"
|
27
|
-
end
|
28
|
-
|
29
|
-
end
|
30
|
-
|
31
|
-
end
|