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