pith 0.0.6 → 0.0.7

Sign up to get free protection for your applications and to get access to all the features.
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 you entire home-directory as website input.
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 via HTTP, re-generating as required.
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", 'Input directory', ' (default: ".")') do |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", 'Output directory', ' (default: "INPUT_DIR/_out")') do |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
- port = 4321
84
+ server = Pith::Server.new(@project)
85
+
63
86
  build
64
- puts %{Taking the Pith at "http://localhost:#{port}"}
65
- Pith::Server.run(@project, :Port => port)
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"
@@ -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 no well-formed YAML
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 "verbatim.txt" contains
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 "verbatim.txt" should contain
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/verbatim.txt" contains
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/verbatim.txt" should contain
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
@@ -11,10 +11,6 @@ module Pith
11
11
  @io.puts(message)
12
12
  end
13
13
 
14
- def write(message)
15
- @io.puts(message)
16
- end
17
-
18
14
  end
19
15
 
20
16
  end
@@ -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 a corresponding output file.
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
@@ -4,7 +4,7 @@ require "pith/input/abstract"
4
4
  module Pith
5
5
  module Input
6
6
 
7
- class Verbatim < Abstract
7
+ class Resource < Abstract
8
8
 
9
9
  def output_path
10
10
  path
@@ -88,6 +88,10 @@ module Pith
88
88
  end
89
89
 
90
90
  private
91
+
92
+ def default_title
93
+ path.basename.to_s.sub(/\..*/, '').tr('_-', ' ').capitalize
94
+ end
91
95
 
92
96
  # Read input file, extracting YAML meta-data header, and template content.
93
97
  #
@@ -28,7 +28,7 @@ module Pith
28
28
  # Return true unless output needs to be re-generated.
29
29
  #
30
30
  def uptodate?
31
- all_input_files && FileUtils.uptodate?(output_file, all_input_files)
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
- remember_dependencies(render_context.referenced_inputs)
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
- def remember_dependencies(referenced_inputs)
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/verbatim"
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
- Verbatim.new(project, path)
12
+ Resource.new(project, path)
13
13
  end
14
14
 
15
15
  end
@@ -0,0 +1,14 @@
1
+ require "pathname"
2
+
3
+ class Pathname
4
+
5
+ def touch(mtime = nil)
6
+ FileUtils.touch(self.to_s)
7
+ utime(mtime, mtime) if mtime
8
+ end
9
+
10
+ def glob_all(pattern)
11
+ Pathname.glob(self + pattern, File::FNM_DOTMATCH)
12
+ end
13
+
14
+ 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
- attr_accessor :input_dir, :output_dir
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 ||= Pathname.glob(input_dir + "**/*").map do |input_file|
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
- raise ReferenceError, "Can't find #{path.inspect}"
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
- Pathname.glob("#{input_dir}/_pith/**")
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
@@ -0,0 +1,5 @@
1
+ module Pith
2
+
3
+ class ReferenceError < StandardError; end
4
+
5
+ end
@@ -1,5 +1,7 @@
1
- require "set"
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 initial_input
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 = current_input.meta["layout"]
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 meta
54
- initial_input.meta || {}
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
- relative_path_to(resolve_path(target_ref))
63
+ relative_url_to(resolve_reference(target_ref))
59
64
  end
60
65
 
61
66
  def link(target_ref, label = nil)
62
- target_path = resolve_path(target_ref)
63
- label ||= begin
64
- find_input(target_path).title
65
- rescue Pith::ReferenceError
66
- "???"
67
+ target_path = resolve_reference(target_ref)
68
+ label ||= begin
69
+ input(target_path).title
70
+ rescue ReferenceError
71
+ "???"
67
72
  end
68
- %{<a href="#{relative_path_to(target_path)}">#{label}</a>}
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 relative_path_to(target_path)
74
- target_path.relative_path_from(initial_input.path.parent)
75
- end
76
-
77
- def resolve_path(ref)
78
- current_input.resolve_path(ref)
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 find_input(path)
87
+ def input(path)
82
88
  input = project.input(path)
83
- @dependencies << input.file if input
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
- template_path = resolve_path(template_ref)
99
- template = find_input(template_path)
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
@@ -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
- @referenced_inputs = project.config_files.dup
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 :referenced_inputs
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 meta
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
- @referenced_inputs << input if input
84
+ @dependencies << input.file if input
84
85
  input
85
86
  end
86
87
 
87
88
  def with_input(input)
88
- @referenced_inputs << input
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, project.logger
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
- def initialize(app, project)
28
- @app = app
29
- @project = project
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
- @project.build
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
@@ -1,3 +1,3 @@
1
1
  module Pith
2
- VERSION = "0.0.6".freeze
2
+ VERSION = "0.0.7".freeze
3
3
  end
data/lib/pith/version.rb~ CHANGED
@@ -1,3 +1,3 @@
1
1
  module Pith
2
- VERSION = "0.0.5".freeze
2
+ VERSION = "0.0.6".freeze
3
3
  end
@@ -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
@@ -17,9 +17,9 @@ describe Pith::Project do
17
17
  @input_file.touch
18
18
  end
19
19
 
20
- it "constructs an Verbatim object" do
20
+ it "constructs an Resource object" do
21
21
  @input = @project.input("input.txt")
22
- @input.should be_kind_of(Pith::Input::Verbatim)
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 "complains" do
59
- lambda do
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: 19
4
+ hash: 17
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
8
  - 0
9
- - 6
10
- version: 0.0.6
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-02 00:00:00 +10:00
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