pith 0.1.1 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -140,10 +140,48 @@ There's also a "`link`" function, for even easier hyper-linking:
140
140
 
141
141
  link("other.html", "Other page")
142
142
 
143
+ Configuring Pith
144
+ ----------------
145
+
146
+ The behaviour of Pith can be customised somewhat, by dropping a "`config.rb`" file into the "`_pith`" directory.
147
+
148
+ There are a couple of flags that can be set to modify generation of links using "`href`" and "`link`":
149
+
150
+ project.assume_content_negotiation = true
151
+ project.assume_directory_index = true
152
+
153
+ Both flags default to false. When `assume_content_negotiation` is enabled, Pith omits the ".html" suffix from links. When `assume_directory_index` is enabled, Pith abbreviates links to "index.html" files. Both of these assumptions work nicely when the generated files are served using a web-server such as Apache httpd, but aren't appropriate if you wish to navigate them as static files on the filesystem.
154
+
155
+ It's also possible to mix behaviour into Pith, using the config file, e.g.
156
+
157
+ project.helpers do
158
+
159
+ def handy_method
160
+ # ...
161
+ end
162
+
163
+ end
164
+
165
+ Any methods defined in a `project.helpers` block are available for use in templates.
166
+
167
+ For a more extensive example of a config file, look [over here](https://github.com/mdub/dogbiscuit.org/blob/master/src/_pith/config.rb).
168
+
169
+ Incremental rebuild
170
+ -------------------
171
+
172
+ For quick prototyping, use the "`watch`" command, rather than "`build`". After building your site, Pith will stay running, and regenerate output files (as necessary) as you edit the inputs. We keep track of which input files are involved in the production of each output, so only the affected outputs are re-generated.
173
+
174
+ $ pith -i SITE watch
175
+ Generating to "SITE/_out"
176
+ --(copy)--> images/logo.png
177
+ --(haml)--> index.html
178
+ # ... edit "index.html.haml" ...
179
+ --(haml)--> index.html
180
+
143
181
  Built-in web-server
144
182
  -------------------
145
183
 
146
- For quick prototyping, pith includes a simple HTTP server. Start it by using the "`serve`" command, rather than "`build`"
184
+ For even quicker prototyping, Pith includes a simple HTTP server. Start it by using the "`serve`" command, rather than "`build`"
147
185
 
148
186
  $ pith -i SITE serve
149
187
  Generating to "SITE/_out"
@@ -0,0 +1,24 @@
1
+ Feature: apply multiple template processors
2
+
3
+ I want to apply multiple template processors
4
+ So that I can take advantage of the best features of each
5
+
6
+ Scenario: Markdown page with embedded ERB
7
+
8
+ Given input file "article.html.md.erb" contains
9
+ """
10
+ <% %w(one two three).each do |n| %>
11
+ - <%= n %>
12
+ <% end %>
13
+ """
14
+
15
+ When I build the site
16
+
17
+ Then output file "article.html" should contain
18
+ """
19
+ <ul>
20
+ <li>one</li>
21
+ <li>two</li>
22
+ <li>three</li>
23
+ </ul>
24
+ """
@@ -32,8 +32,8 @@ module Pith
32
32
  #
33
33
  def build
34
34
  return false if ignorable? || uptodate?
35
- logger.info("%-16s%s" % ["--(#{type})-->", output_path])
36
- generate_output
35
+ logger.info("--> #{output_path}")
36
+ generate_output
37
37
  end
38
38
 
39
39
  # Public: Resolve a reference relative to this input.
@@ -11,15 +11,11 @@ module Pith
11
11
  def output_path
12
12
  path
13
13
  end
14
-
15
- def type
16
- "copy"
17
- end
18
-
14
+
19
15
  def uptodate?
20
16
  FileUtils.uptodate?(output_file, [file])
21
17
  end
22
-
18
+
23
19
  # Copy this input verbatim into the output directory
24
20
  #
25
21
  def generate_output
@@ -36,7 +32,7 @@ module Pith
36
32
  def meta
37
33
  {}
38
34
  end
39
-
35
+
40
36
  end
41
37
 
42
38
  end
@@ -14,18 +14,17 @@ module Pith
14
14
  class Template < Abstract
15
15
 
16
16
  def self.can_handle?(path)
17
- path.to_s =~ /\.([^.]+)$/ && Tilt.registered?($1)
17
+ !!Tilt[path.to_s]
18
18
  end
19
-
19
+
20
20
  def initialize(project, path)
21
21
  raise(ArgumentError, "#{path} is not a template") unless Template.can_handle?(path)
22
22
  super(project, path)
23
- path.to_s =~ /^(.+)\.(.+)$/ || raise("huh?")
24
- @output_path = Pathname($1)
25
- @type = $2
23
+ determine_pipeline
24
+ load
26
25
  end
27
26
 
28
- attr_reader :output_path, :type
27
+ attr_reader :output_path
29
28
 
30
29
  # Check whether output is up-to-date.
31
30
  #
@@ -43,7 +42,7 @@ module Pith
43
42
  output_file.open("w") do |out|
44
43
  begin
45
44
  out.puts(render_context.render(self))
46
- rescue Exception => e
45
+ rescue StandardError, SyntaxError => e
47
46
  logger.warn e.summary(:max_backtrace => 5)
48
47
  out.puts "<pre>"
49
48
  out.puts e.summary
@@ -55,12 +54,14 @@ module Pith
55
54
  # Render this input using Tilt
56
55
  #
57
56
  def render(context, locals = {}, &block)
58
- load
59
- @tilt_template.render(context, locals, &block)
57
+ @pipeline.inject(@template_text) do |text, processor|
58
+ template = processor.new(file.to_s, @template_start_line) { text }
59
+ template.render(context, locals, &block)
60
+ end
60
61
  end
61
-
62
+
62
63
  # Public: Get YAML metadata declared in the header of of a template.
63
- #
64
+ #
64
65
  # If the first line of the template starts with "---" it is considered to be
65
66
  # the start of a YAML 'document', which is loaded and returned.
66
67
  #
@@ -75,11 +76,10 @@ module Pith
75
76
  #
76
77
  # input.meta
77
78
  # #=> { "published" => "2008-09-15" }
78
- #
79
+ #
79
80
  # Returns a Hash.
80
81
  #
81
82
  def meta
82
- load
83
83
  @meta
84
84
  end
85
85
 
@@ -94,41 +94,63 @@ module Pith
94
94
  # #=> "some_page.html.haml"
95
95
  # input.title
96
96
  # #=> "Some page"
97
- #
97
+ #
98
98
  def title
99
99
  meta["title"] || default_title
100
100
  end
101
101
 
102
102
  private
103
-
103
+
104
104
  def default_title
105
105
  path.basename.to_s.sub(/\..*/, '').tr('_-', ' ').capitalize
106
106
  end
107
107
 
108
+ def determine_pipeline
109
+ @pipeline = []
110
+ remaining_path = path.to_s
111
+ while remaining_path =~ /^(.+)\.(.+)$/
112
+ if Tilt[$2]
113
+ remaining_path = $1
114
+ @pipeline << Tilt[$2]
115
+ else
116
+ break
117
+ end
118
+ end
119
+ @output_path = Pathname(remaining_path)
120
+ end
121
+
108
122
  # Read input file, extracting YAML meta-data header, and template content.
109
123
  #
110
124
  def load
111
- return false if @tilt_template
112
- @meta = {}
113
125
  file.open do |input|
114
- header = input.gets
115
- if header =~ /^---/
116
- while line = input.gets
117
- break if line =~ /^(---|\.\.\.)/
118
- header << line
119
- end
120
- begin
121
- @meta = YAML.load(header)
122
- rescue
123
- logger.warn "#{file}:1: badly-formed YAML header"
124
- end
125
- else
126
- input.rewind
126
+ load_meta(input)
127
+ load_template(input)
128
+ end
129
+ end
130
+
131
+ def load_meta(input)
132
+ @meta = {}
133
+ header = input.gets
134
+ if header =~ /^---/
135
+ while line = input.gets
136
+ break if line =~ /^(---|\.\.\.)/
137
+ header << line
138
+ end
139
+ begin
140
+ @meta = YAML.load(header)
141
+ rescue ArgumentError, SyntaxError
142
+ logger.warn "#{file}:1: badly-formed YAML header"
127
143
  end
128
- @tilt_template = Tilt.new(file.to_s, input.lineno + 1) { input.read }
144
+ else
145
+ input.rewind
129
146
  end
130
147
  end
131
-
148
+
149
+ def load_template(input)
150
+ @template_start_line = input.lineno + 1
151
+ @template_text = input.read
152
+ end
153
+
132
154
  attr_accessor :dependencies
133
155
 
134
156
  end
@@ -1,3 +1,3 @@
1
1
  module Pith
2
- VERSION = "0.1.1".freeze
2
+ VERSION = "0.2.0".freeze
3
3
  end
@@ -1,9 +1,9 @@
1
1
  module Pith
2
-
2
+
3
3
  class Watcher
4
4
 
5
5
  DEFAULT_INTERVAL = 2
6
-
6
+
7
7
  def initialize(project, options = {})
8
8
  @project = project
9
9
  @interval = DEFAULT_INTERVAL
@@ -11,7 +11,7 @@ module Pith
11
11
  send("#{k}=", v)
12
12
  end
13
13
  end
14
-
14
+
15
15
  attr_accessor :project
16
16
  attr_accessor :interval
17
17
 
@@ -19,11 +19,13 @@ module Pith
19
19
  loop do
20
20
  begin
21
21
  project.build
22
+ sleep(interval)
23
+ rescue Interrupt
24
+ break
22
25
  end
23
- sleep(interval)
24
26
  end
25
27
  end
26
28
 
27
29
  end
28
-
30
+
29
31
  end
metadata CHANGED
@@ -1,149 +1,147 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: pith
3
- version: !ruby/object:Gem::Version
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.0
4
5
  prerelease:
5
- version: 0.1.1
6
6
  platform: ruby
7
- authors:
7
+ authors:
8
8
  - Mike Williams
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
-
13
- date: 2011-05-08 00:00:00 Z
14
- dependencies:
15
- - !ruby/object:Gem::Dependency
12
+ date: 2011-10-06 00:00:00.000000000Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
16
15
  name: tilt
17
- prerelease: false
18
- requirement: &id001 !ruby/object:Gem::Requirement
16
+ requirement: &70100992669820 !ruby/object:Gem::Requirement
19
17
  none: false
20
- requirements:
18
+ requirements:
21
19
  - - ~>
22
- - !ruby/object:Gem::Version
23
- version: "1.1"
20
+ - !ruby/object:Gem::Version
21
+ version: '1.1'
24
22
  type: :runtime
25
- version_requirements: *id001
26
- - !ruby/object:Gem::Dependency
27
- name: adsf
28
23
  prerelease: false
29
- requirement: &id002 !ruby/object:Gem::Requirement
24
+ version_requirements: *70100992669820
25
+ - !ruby/object:Gem::Dependency
26
+ name: adsf
27
+ requirement: &70100992665860 !ruby/object:Gem::Requirement
30
28
  none: false
31
- requirements:
29
+ requirements:
32
30
  - - ~>
33
- - !ruby/object:Gem::Version
31
+ - !ruby/object:Gem::Version
34
32
  version: 1.0.1
35
33
  type: :runtime
36
- version_requirements: *id002
37
- - !ruby/object:Gem::Dependency
38
- name: rack
39
34
  prerelease: false
40
- requirement: &id003 !ruby/object:Gem::Requirement
35
+ version_requirements: *70100992665860
36
+ - !ruby/object:Gem::Dependency
37
+ name: rack
38
+ requirement: &70100992659140 !ruby/object:Gem::Requirement
41
39
  none: false
42
- requirements:
40
+ requirements:
43
41
  - - ~>
44
- - !ruby/object:Gem::Version
42
+ - !ruby/object:Gem::Version
45
43
  version: 1.2.1
46
44
  type: :runtime
47
- version_requirements: *id003
48
- - !ruby/object:Gem::Dependency
49
- name: thin
50
45
  prerelease: false
51
- requirement: &id004 !ruby/object:Gem::Requirement
46
+ version_requirements: *70100992659140
47
+ - !ruby/object:Gem::Dependency
48
+ name: thin
49
+ requirement: &70100992656080 !ruby/object:Gem::Requirement
52
50
  none: false
53
- requirements:
51
+ requirements:
54
52
  - - ~>
55
- - !ruby/object:Gem::Version
53
+ - !ruby/object:Gem::Version
56
54
  version: 1.2.7
57
55
  type: :runtime
58
- version_requirements: *id004
59
- - !ruby/object:Gem::Dependency
60
- name: clamp
61
56
  prerelease: false
62
- requirement: &id005 !ruby/object:Gem::Requirement
57
+ version_requirements: *70100992656080
58
+ - !ruby/object:Gem::Dependency
59
+ name: clamp
60
+ requirement: &70100992634020 !ruby/object:Gem::Requirement
63
61
  none: false
64
- requirements:
62
+ requirements:
65
63
  - - ~>
66
- - !ruby/object:Gem::Version
64
+ - !ruby/object:Gem::Version
67
65
  version: 0.1.7
68
66
  type: :runtime
69
- version_requirements: *id005
70
- - !ruby/object:Gem::Dependency
71
- name: rake
72
67
  prerelease: false
73
- requirement: &id006 !ruby/object:Gem::Requirement
68
+ version_requirements: *70100992634020
69
+ - !ruby/object:Gem::Dependency
70
+ name: rake
71
+ requirement: &70100992621940 !ruby/object:Gem::Requirement
74
72
  none: false
75
- requirements:
76
- - - ">="
77
- - !ruby/object:Gem::Version
78
- version: "0"
73
+ requirements:
74
+ - - ! '>='
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
79
77
  type: :development
80
- version_requirements: *id006
81
- - !ruby/object:Gem::Dependency
82
- name: rspec
83
78
  prerelease: false
84
- requirement: &id007 !ruby/object:Gem::Requirement
79
+ version_requirements: *70100992621940
80
+ - !ruby/object:Gem::Dependency
81
+ name: rspec
82
+ requirement: &70100992611420 !ruby/object:Gem::Requirement
85
83
  none: false
86
- requirements:
84
+ requirements:
87
85
  - - ~>
88
- - !ruby/object:Gem::Version
86
+ - !ruby/object:Gem::Version
89
87
  version: 1.2.9
90
88
  type: :development
91
- version_requirements: *id007
92
- - !ruby/object:Gem::Dependency
93
- name: cucumber
94
89
  prerelease: false
95
- requirement: &id008 !ruby/object:Gem::Requirement
90
+ version_requirements: *70100992611420
91
+ - !ruby/object:Gem::Dependency
92
+ name: cucumber
93
+ requirement: &70100992606220 !ruby/object:Gem::Requirement
96
94
  none: false
97
- requirements:
95
+ requirements:
98
96
  - - ~>
99
- - !ruby/object:Gem::Version
97
+ - !ruby/object:Gem::Version
100
98
  version: 0.8.3
101
99
  type: :development
102
- version_requirements: *id008
103
- - !ruby/object:Gem::Dependency
104
- name: haml
105
100
  prerelease: false
106
- requirement: &id009 !ruby/object:Gem::Requirement
101
+ version_requirements: *70100992606220
102
+ - !ruby/object:Gem::Dependency
103
+ name: haml
104
+ requirement: &70100992599740 !ruby/object:Gem::Requirement
107
105
  none: false
108
- requirements:
109
- - - ">="
110
- - !ruby/object:Gem::Version
111
- version: "0"
106
+ requirements:
107
+ - - ! '>='
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
112
110
  type: :development
113
- version_requirements: *id009
114
- - !ruby/object:Gem::Dependency
115
- name: RedCloth
116
111
  prerelease: false
117
- requirement: &id010 !ruby/object:Gem::Requirement
112
+ version_requirements: *70100992599740
113
+ - !ruby/object:Gem::Dependency
114
+ name: RedCloth
115
+ requirement: &70100992582600 !ruby/object:Gem::Requirement
118
116
  none: false
119
- requirements:
120
- - - ">="
121
- - !ruby/object:Gem::Version
122
- version: "0"
117
+ requirements:
118
+ - - ! '>='
119
+ - !ruby/object:Gem::Version
120
+ version: '0'
123
121
  type: :development
124
- version_requirements: *id010
125
- - !ruby/object:Gem::Dependency
126
- name: rdiscount
127
122
  prerelease: false
128
- requirement: &id011 !ruby/object:Gem::Requirement
123
+ version_requirements: *70100992582600
124
+ - !ruby/object:Gem::Dependency
125
+ name: rdiscount
126
+ requirement: &70100992575120 !ruby/object:Gem::Requirement
129
127
  none: false
130
- requirements:
131
- - - ">="
132
- - !ruby/object:Gem::Version
133
- version: "0"
128
+ requirements:
129
+ - - ! '>='
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
134
132
  type: :development
135
- version_requirements: *id011
136
- description: |
137
- Pith builds static websites, using markup/template languages including Haml, Sass, ERb, Liquid, Markdown and Textile.
133
+ prerelease: false
134
+ version_requirements: *70100992575120
135
+ description: ! 'Pith builds static websites, using markup/template languages including
136
+ Haml, Sass, ERb, Liquid, Markdown and Textile.
138
137
 
138
+ '
139
139
  email: mdub@dogbiscuit.org
140
- executables:
140
+ executables:
141
141
  - pith
142
142
  extensions: []
143
-
144
143
  extra_rdoc_files: []
145
-
146
- files:
144
+ files:
147
145
  - lib/pith/console_logger.rb
148
146
  - lib/pith/console_logger.rb~
149
147
  - lib/pith/exception_ext.rb
@@ -217,6 +215,7 @@ files:
217
215
  - features/markdown.feature
218
216
  - features/metadata.feature
219
217
  - features/metadata.feature~
218
+ - features/pipeline.feature
220
219
  - features/relative_linking.feature
221
220
  - features/relative_linking.feature~
222
221
  - features/resources.feature
@@ -233,32 +232,35 @@ files:
233
232
  - bin/pith
234
233
  homepage: http://github.com/mdub/pith
235
234
  licenses: []
236
-
237
235
  post_install_message:
238
236
  rdoc_options: []
239
-
240
- require_paths:
237
+ require_paths:
241
238
  - lib
242
- required_ruby_version: !ruby/object:Gem::Requirement
239
+ required_ruby_version: !ruby/object:Gem::Requirement
243
240
  none: false
244
- requirements:
245
- - - ">="
246
- - !ruby/object:Gem::Version
247
- version: "0"
248
- required_rubygems_version: !ruby/object:Gem::Requirement
241
+ requirements:
242
+ - - ! '>='
243
+ - !ruby/object:Gem::Version
244
+ version: '0'
245
+ segments:
246
+ - 0
247
+ hash: -2050158771651431666
248
+ required_rubygems_version: !ruby/object:Gem::Requirement
249
249
  none: false
250
- requirements:
251
- - - ">="
252
- - !ruby/object:Gem::Version
253
- version: "0"
250
+ requirements:
251
+ - - ! '>='
252
+ - !ruby/object:Gem::Version
253
+ version: '0'
254
+ segments:
255
+ - 0
256
+ hash: -2050158771651431666
254
257
  requirements: []
255
-
256
258
  rubyforge_project:
257
- rubygems_version: 1.7.2
259
+ rubygems_version: 1.8.10
258
260
  signing_key:
259
261
  specification_version: 3
260
262
  summary: A static website generator
261
- test_files:
263
+ test_files:
262
264
  - Rakefile
263
265
  - spec/pith/input/abstract_spec.rb~
264
266
  - spec/pith/input/template_spec.rb
@@ -290,6 +292,7 @@ test_files:
290
292
  - features/markdown.feature
291
293
  - features/metadata.feature
292
294
  - features/metadata.feature~
295
+ - features/pipeline.feature
293
296
  - features/relative_linking.feature
294
297
  - features/relative_linking.feature~
295
298
  - features/resources.feature
@@ -303,4 +306,3 @@ test_files:
303
306
  - features/textile.feature~
304
307
  - features/verbatim.feature~
305
308
  - cucumber.yml
306
- has_rdoc: