pith 0.2.0 → 0.2.1
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/bin/pith +6 -5
- data/features/error_handling.feature +5 -4
- data/features/step_definitions/build_steps.rb +4 -0
- data/lib/pith/input.rb +215 -11
- data/lib/pith/plugins/publication/input.rb +2 -14
- data/lib/pith/project.rb +26 -19
- data/lib/pith/version.rb +1 -1
- data/spec/pith/{input/template_spec.rb~ → input_spec.rb} +15 -28
- data/spec/pith/project_spec.rb +14 -29
- metadata +28 -41
- data/lib/pith/exception_ext.rb +0 -9
- data/lib/pith/input/abstract.rb +0 -78
- data/lib/pith/input/abstract.rb~ +0 -74
- data/lib/pith/input/base.rb~ +0 -74
- data/lib/pith/input/resource.rb +0 -39
- data/lib/pith/input/resource.rb~ +0 -41
- data/lib/pith/input/template.rb +0 -159
- data/lib/pith/input/template.rb~ +0 -126
- data/lib/pith/input/verbatim.rb~ +0 -31
- data/spec/pith/input/abstract_spec.rb~ +0 -31
- data/spec/pith/input/template_spec.rb +0 -70
data/lib/pith/input/abstract.rb~
DELETED
@@ -1,74 +0,0 @@
|
|
1
|
-
require "pathname"
|
2
|
-
|
3
|
-
module Pith
|
4
|
-
module Input
|
5
|
-
|
6
|
-
class Abstract
|
7
|
-
|
8
|
-
def initialize(project, path)
|
9
|
-
@project = project
|
10
|
-
@path = path
|
11
|
-
end
|
12
|
-
|
13
|
-
attr_reader :project, :path
|
14
|
-
|
15
|
-
# Public: Get the file-system location of this input.
|
16
|
-
#
|
17
|
-
# Returns a fully-qualified Pathname.
|
18
|
-
#
|
19
|
-
def file
|
20
|
-
project.input_dir + path
|
21
|
-
end
|
22
|
-
|
23
|
-
def output_file
|
24
|
-
project.output_dir + output_path
|
25
|
-
end
|
26
|
-
|
27
|
-
# Public: Generate a corresponding output file.
|
28
|
-
#
|
29
|
-
def build
|
30
|
-
return false if ignorable? || uptodate?
|
31
|
-
logger.info("%-14s%s" % ["--(#{type})-->", output_path])
|
32
|
-
generate_output
|
33
|
-
end
|
34
|
-
|
35
|
-
# Public: Resolve a reference relative to this input.
|
36
|
-
#
|
37
|
-
# ref - a String referencing another asset
|
38
|
-
#
|
39
|
-
# A ref starting with "/" is resolved relative to the project root;
|
40
|
-
# anything else is resolved relative to this input.
|
41
|
-
#
|
42
|
-
# Returns a fully-qualified Pathname of the asset.
|
43
|
-
#
|
44
|
-
def resolve_path(ref)
|
45
|
-
ref = ref.to_str
|
46
|
-
if ref[0,1] == "/"
|
47
|
-
Pathname(ref[1..-1])
|
48
|
-
else
|
49
|
-
path.parent + ref
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|
53
|
-
# Consider whether this input can be ignored.
|
54
|
-
#
|
55
|
-
# Returns true if it can.
|
56
|
-
#
|
57
|
-
def ignorable?
|
58
|
-
path.to_s.split("/").any? { |component| component.to_s[0,1] == "_" }
|
59
|
-
end
|
60
|
-
|
61
|
-
protected
|
62
|
-
|
63
|
-
def default_title
|
64
|
-
path.to_s.sub(/\..*/, '').tr('_-', ' ').capitalize
|
65
|
-
end
|
66
|
-
|
67
|
-
def logger
|
68
|
-
project.logger
|
69
|
-
end
|
70
|
-
|
71
|
-
end
|
72
|
-
|
73
|
-
end
|
74
|
-
end
|
data/lib/pith/input/base.rb~
DELETED
@@ -1,74 +0,0 @@
|
|
1
|
-
require "pathname"
|
2
|
-
|
3
|
-
module Pith
|
4
|
-
module Input
|
5
|
-
|
6
|
-
class Abstract
|
7
|
-
|
8
|
-
def initialize(project, path)
|
9
|
-
@project = project
|
10
|
-
@path = path
|
11
|
-
end
|
12
|
-
|
13
|
-
attr_reader :project, :path
|
14
|
-
|
15
|
-
# Public: Get the file-system location of this input.
|
16
|
-
#
|
17
|
-
# Returns a fully-qualified Pathname.
|
18
|
-
#
|
19
|
-
def file
|
20
|
-
project.input_dir + path
|
21
|
-
end
|
22
|
-
|
23
|
-
# Public: Get the file-system location of the corresponding output file.
|
24
|
-
#
|
25
|
-
# Returns a fully-qualified Pathname.
|
26
|
-
#
|
27
|
-
def output_file
|
28
|
-
project.output_dir + output_path
|
29
|
-
end
|
30
|
-
|
31
|
-
# Public: Generate an output file.
|
32
|
-
#
|
33
|
-
def build
|
34
|
-
return false if ignorable? || uptodate?
|
35
|
-
logger.info("%-16s%s" % ["--(#{type})-->", output_path])
|
36
|
-
generate_output
|
37
|
-
end
|
38
|
-
|
39
|
-
# Public: Resolve a reference relative to this input.
|
40
|
-
#
|
41
|
-
# ref - a String referencing another asset
|
42
|
-
#
|
43
|
-
# A ref starting with "/" is resolved relative to the project root;
|
44
|
-
# anything else is resolved relative to this input.
|
45
|
-
#
|
46
|
-
# Returns a fully-qualified Pathname of the asset.
|
47
|
-
#
|
48
|
-
def resolve_path(ref)
|
49
|
-
ref = ref.to_str
|
50
|
-
if ref[0,1] == "/"
|
51
|
-
Pathname(ref[1..-1])
|
52
|
-
else
|
53
|
-
path.parent + ref
|
54
|
-
end
|
55
|
-
end
|
56
|
-
|
57
|
-
# Consider whether this input can be ignored.
|
58
|
-
#
|
59
|
-
# Returns true if it can.
|
60
|
-
#
|
61
|
-
def ignorable?
|
62
|
-
path.to_s.split("/").any? { |component| component.to_s[0,1] == "_" }
|
63
|
-
end
|
64
|
-
|
65
|
-
protected
|
66
|
-
|
67
|
-
def logger
|
68
|
-
project.logger
|
69
|
-
end
|
70
|
-
|
71
|
-
end
|
72
|
-
|
73
|
-
end
|
74
|
-
end
|
data/lib/pith/input/resource.rb
DELETED
@@ -1,39 +0,0 @@
|
|
1
|
-
require "fileutils"
|
2
|
-
require "pith/input/abstract"
|
3
|
-
|
4
|
-
module Pith
|
5
|
-
module Input
|
6
|
-
|
7
|
-
# Represents a non-template input.
|
8
|
-
#
|
9
|
-
class Resource < Abstract
|
10
|
-
|
11
|
-
def output_path
|
12
|
-
path
|
13
|
-
end
|
14
|
-
|
15
|
-
def uptodate?
|
16
|
-
FileUtils.uptodate?(output_file, [file])
|
17
|
-
end
|
18
|
-
|
19
|
-
# Copy this input verbatim into the output directory
|
20
|
-
#
|
21
|
-
def generate_output
|
22
|
-
output_file.parent.mkpath
|
23
|
-
FileUtils.copy(file, output_file)
|
24
|
-
end
|
25
|
-
|
26
|
-
# Render this input, for inclusion within templates
|
27
|
-
#
|
28
|
-
def render(context, locals = {})
|
29
|
-
file.read
|
30
|
-
end
|
31
|
-
|
32
|
-
def meta
|
33
|
-
{}
|
34
|
-
end
|
35
|
-
|
36
|
-
end
|
37
|
-
|
38
|
-
end
|
39
|
-
end
|
data/lib/pith/input/resource.rb~
DELETED
@@ -1,41 +0,0 @@
|
|
1
|
-
require "fileutils"
|
2
|
-
require "pith/input/abstract"
|
3
|
-
|
4
|
-
module Pith
|
5
|
-
module Input
|
6
|
-
|
7
|
-
class Resource < Abstract
|
8
|
-
|
9
|
-
def output_path
|
10
|
-
path
|
11
|
-
end
|
12
|
-
|
13
|
-
def type
|
14
|
-
"copy"
|
15
|
-
end
|
16
|
-
|
17
|
-
def uptodate?
|
18
|
-
FileUtils.uptodate?(output_file, [file])
|
19
|
-
end
|
20
|
-
|
21
|
-
# Copy this input verbatim into the output directory
|
22
|
-
#
|
23
|
-
def generate_output
|
24
|
-
output_file.parent.mkpath
|
25
|
-
FileUtils.copy(file, output_file)
|
26
|
-
end
|
27
|
-
|
28
|
-
# Render this input, for inclusion within templates
|
29
|
-
#
|
30
|
-
def render(context, locals = {})
|
31
|
-
file.read
|
32
|
-
end
|
33
|
-
|
34
|
-
def meta
|
35
|
-
{}
|
36
|
-
end
|
37
|
-
|
38
|
-
end
|
39
|
-
|
40
|
-
end
|
41
|
-
end
|
data/lib/pith/input/template.rb
DELETED
@@ -1,159 +0,0 @@
|
|
1
|
-
require "fileutils"
|
2
|
-
require "pathname"
|
3
|
-
require "pith/exception_ext"
|
4
|
-
require "pith/input/abstract"
|
5
|
-
require "pith/render_context"
|
6
|
-
require "tilt"
|
7
|
-
require "yaml"
|
8
|
-
|
9
|
-
module Pith
|
10
|
-
module Input
|
11
|
-
|
12
|
-
# Represents an input that should be evaluated as a template.
|
13
|
-
#
|
14
|
-
class Template < Abstract
|
15
|
-
|
16
|
-
def self.can_handle?(path)
|
17
|
-
!!Tilt[path.to_s]
|
18
|
-
end
|
19
|
-
|
20
|
-
def initialize(project, path)
|
21
|
-
raise(ArgumentError, "#{path} is not a template") unless Template.can_handle?(path)
|
22
|
-
super(project, path)
|
23
|
-
determine_pipeline
|
24
|
-
load
|
25
|
-
end
|
26
|
-
|
27
|
-
attr_reader :output_path
|
28
|
-
|
29
|
-
# Check whether output is up-to-date.
|
30
|
-
#
|
31
|
-
# Return true unless output needs to be re-generated.
|
32
|
-
#
|
33
|
-
def uptodate?
|
34
|
-
dependencies && FileUtils.uptodate?(output_file, dependencies)
|
35
|
-
end
|
36
|
-
|
37
|
-
# Generate output for this template
|
38
|
-
#
|
39
|
-
def generate_output
|
40
|
-
output_file.parent.mkpath
|
41
|
-
render_context = RenderContext.new(project)
|
42
|
-
output_file.open("w") do |out|
|
43
|
-
begin
|
44
|
-
out.puts(render_context.render(self))
|
45
|
-
rescue StandardError, SyntaxError => e
|
46
|
-
logger.warn e.summary(:max_backtrace => 5)
|
47
|
-
out.puts "<pre>"
|
48
|
-
out.puts e.summary
|
49
|
-
end
|
50
|
-
end
|
51
|
-
@dependencies = render_context.dependencies
|
52
|
-
end
|
53
|
-
|
54
|
-
# Render this input using Tilt
|
55
|
-
#
|
56
|
-
def 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
|
61
|
-
end
|
62
|
-
|
63
|
-
# Public: Get YAML metadata declared in the header of of a template.
|
64
|
-
#
|
65
|
-
# If the first line of the template starts with "---" it is considered to be
|
66
|
-
# the start of a YAML 'document', which is loaded and returned.
|
67
|
-
#
|
68
|
-
# Examples
|
69
|
-
#
|
70
|
-
# Given input starting with:
|
71
|
-
#
|
72
|
-
# ---
|
73
|
-
# published: 2008-09-15
|
74
|
-
# ...
|
75
|
-
# OTHER STUFF
|
76
|
-
#
|
77
|
-
# input.meta
|
78
|
-
# #=> { "published" => "2008-09-15" }
|
79
|
-
#
|
80
|
-
# Returns a Hash.
|
81
|
-
#
|
82
|
-
def meta
|
83
|
-
@meta
|
84
|
-
end
|
85
|
-
|
86
|
-
# Public: Get page title.
|
87
|
-
#
|
88
|
-
# The default title is based on the input file-name, sans-extension, capitalised,
|
89
|
-
# but can be overridden by providing a "title" in the metadata block.
|
90
|
-
#
|
91
|
-
# Examples
|
92
|
-
#
|
93
|
-
# input.path.to_s
|
94
|
-
# #=> "some_page.html.haml"
|
95
|
-
# input.title
|
96
|
-
# #=> "Some page"
|
97
|
-
#
|
98
|
-
def title
|
99
|
-
meta["title"] || default_title
|
100
|
-
end
|
101
|
-
|
102
|
-
private
|
103
|
-
|
104
|
-
def default_title
|
105
|
-
path.basename.to_s.sub(/\..*/, '').tr('_-', ' ').capitalize
|
106
|
-
end
|
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
|
-
|
122
|
-
# Read input file, extracting YAML meta-data header, and template content.
|
123
|
-
#
|
124
|
-
def load
|
125
|
-
file.open do |input|
|
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"
|
143
|
-
end
|
144
|
-
else
|
145
|
-
input.rewind
|
146
|
-
end
|
147
|
-
end
|
148
|
-
|
149
|
-
def load_template(input)
|
150
|
-
@template_start_line = input.lineno + 1
|
151
|
-
@template_text = input.read
|
152
|
-
end
|
153
|
-
|
154
|
-
attr_accessor :dependencies
|
155
|
-
|
156
|
-
end
|
157
|
-
|
158
|
-
end
|
159
|
-
end
|
data/lib/pith/input/template.rb~
DELETED
@@ -1,126 +0,0 @@
|
|
1
|
-
require "fileutils"
|
2
|
-
require "pathname"
|
3
|
-
require "pith/input/abstract"
|
4
|
-
require "pith/render_context"
|
5
|
-
require "tilt"
|
6
|
-
require "yaml"
|
7
|
-
|
8
|
-
module Pith
|
9
|
-
module Input
|
10
|
-
|
11
|
-
class Template < Abstract
|
12
|
-
|
13
|
-
def self.can_handle?(path)
|
14
|
-
path.to_str =~ /\.([^.]+)$/ && Tilt.registered?($1)
|
15
|
-
end
|
16
|
-
|
17
|
-
def initialize(project, path)
|
18
|
-
raise(ArgumentError, "#{path} is not a template") unless Template.can_handle?(path)
|
19
|
-
super(project, path)
|
20
|
-
path.to_str =~ /^(.+)\.(.+)$/ || raise("huh?")
|
21
|
-
@output_path = Pathname($1)
|
22
|
-
@type = $2
|
23
|
-
load
|
24
|
-
end
|
25
|
-
|
26
|
-
attr_reader :output_path, :type
|
27
|
-
|
28
|
-
# Check whether output is up-to-date.
|
29
|
-
#
|
30
|
-
# Return true unless output needs to be re-generated.
|
31
|
-
#
|
32
|
-
def uptodate?
|
33
|
-
dependencies && FileUtils.uptodate?(output_file, dependencies)
|
34
|
-
end
|
35
|
-
|
36
|
-
# Generate output for this template
|
37
|
-
#
|
38
|
-
def generate_output
|
39
|
-
output_file.parent.mkpath
|
40
|
-
render_context = RenderContext.new(project)
|
41
|
-
output_file.open("w") do |out|
|
42
|
-
out.puts(render_context.render(self))
|
43
|
-
end
|
44
|
-
@dependencies = render_context.dependencies
|
45
|
-
end
|
46
|
-
|
47
|
-
# Render this input using Tilt
|
48
|
-
#
|
49
|
-
def render(context, locals = {}, &block)
|
50
|
-
@tilt_template.render(context, locals, &block)
|
51
|
-
end
|
52
|
-
|
53
|
-
# Public: Get YAML metadata declared in the header of of a template.
|
54
|
-
#
|
55
|
-
# If the first line of the template starts with "---" it is considered to be
|
56
|
-
# the start of a YAML 'document', which is loaded and returned.
|
57
|
-
#
|
58
|
-
# Examples
|
59
|
-
#
|
60
|
-
# Given input starting with:
|
61
|
-
#
|
62
|
-
# ---
|
63
|
-
# published: 2008-09-15
|
64
|
-
# ...
|
65
|
-
# OTHER STUFF
|
66
|
-
#
|
67
|
-
# input.meta
|
68
|
-
# #=> { "published" => "2008-09-15" }
|
69
|
-
#
|
70
|
-
# Returns a Hash.
|
71
|
-
#
|
72
|
-
def meta
|
73
|
-
@meta
|
74
|
-
end
|
75
|
-
|
76
|
-
# Public: Get page title.
|
77
|
-
#
|
78
|
-
# The default title is based on the input file-name, sans-extension, capitalised,
|
79
|
-
# but can be overridden by providing a "title" in the metadata block.
|
80
|
-
#
|
81
|
-
# Examples
|
82
|
-
#
|
83
|
-
# input.path.to_s
|
84
|
-
# #=> "some_page.html.haml"
|
85
|
-
# input.title
|
86
|
-
# #=> "Some page"
|
87
|
-
#
|
88
|
-
def title
|
89
|
-
meta["title"] || default_title
|
90
|
-
end
|
91
|
-
|
92
|
-
private
|
93
|
-
|
94
|
-
def default_title
|
95
|
-
path.basename.to_s.sub(/\..*/, '').tr('_-', ' ').capitalize
|
96
|
-
end
|
97
|
-
|
98
|
-
# Read input file, extracting YAML meta-data header, and template content.
|
99
|
-
#
|
100
|
-
def load
|
101
|
-
@meta = {}
|
102
|
-
file.open do |input|
|
103
|
-
header = input.gets
|
104
|
-
if header =~ /^---/
|
105
|
-
while line = input.gets
|
106
|
-
break if line =~ /^(---|\.\.\.)/
|
107
|
-
header << line
|
108
|
-
end
|
109
|
-
begin
|
110
|
-
@meta = YAML.load(header)
|
111
|
-
rescue
|
112
|
-
logger.warn "#{file}:1: badly-formed YAML header"
|
113
|
-
end
|
114
|
-
else
|
115
|
-
input.rewind
|
116
|
-
end
|
117
|
-
@tilt_template = Tilt.new(file, input.lineno + 1) { input.read }
|
118
|
-
end
|
119
|
-
end
|
120
|
-
|
121
|
-
attr_accessor :dependencies
|
122
|
-
|
123
|
-
end
|
124
|
-
|
125
|
-
end
|
126
|
-
end
|