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