mint 0.2.2 → 0.2.5

Sign up to get free protection for your applications and to get access to all the features.
data/lib/mint/mint.rb CHANGED
@@ -8,22 +8,23 @@ require 'mint/exceptions'
8
8
  module Mint
9
9
  # Assume that someone using an Html template has formatted it
10
10
  # in Erb and that a Css stylesheet will pass untouched through
11
- # a Less parser.
12
- Tilt.register 'html', Tilt::ERBTemplate
13
- Tilt.register 'css', Tilt::LessTemplate
11
+ # a Scss parser.
12
+ Tilt.register Tilt::ERBTemplate, :html
13
+ Tilt.register Tilt::ScssTemplate, :css
14
14
 
15
15
  def self.root
16
- Pathname.new(__FILE__).realpath.dirname + '../..'
16
+ (Pathname.new(__FILE__).realpath.dirname + '../..').to_s
17
17
  end
18
18
 
19
19
  # Return the an array with the Mint template path. Will first look
20
20
  # for MINT_PATH environment variable. Otherwise will use smart defaults.
21
21
  # Either way, earlier/higher paths take precedence. And is considered to
22
22
  # be the directory for "local" config options, templates, etc.
23
- def self.path
23
+ def self.path(as_path=false)
24
24
  mint_path = ENV['MINT_PATH'] ||
25
25
  "#{Dir.getwd}/.mint:~/.mint:#{Mint.root}"
26
- mint_path.split(':').map {|p| Pathname.new(p).expand_path }
26
+ paths = mint_path.split(':')
27
+ as_path ? paths.map {|p| Pathname.new(p).expand_path } : paths
27
28
  end
28
29
 
29
30
  # I want to refactor this so that Mint.path is always a Hash...
@@ -31,13 +32,13 @@ module Mint
31
32
  # Right now, this is a hack. It assumes a sane MINT_PATH, where the
32
33
  # first entry is most local, the second is user-level,
33
34
  # and the last entry is most global.
34
- def self.path_for_scope(scope=:local)
35
+ def self.path_for_scope(scope=:local, as_path=false)
35
36
  case Mint.path
36
37
  when Array
37
38
  index = { local: 0, user: 1, global: 2 }[scope]
38
- Mint.path[index]
39
+ Mint.path(as_path)[index]
39
40
  when Hash
40
- Mint.path[scope]
41
+ Mint.path(as_path)[scope]
41
42
  else
42
43
  nil
43
44
  end
@@ -45,12 +46,18 @@ module Mint
45
46
 
46
47
  # Returns a hash with key Mint directories
47
48
  def self.directories
48
- { templates: 'templates' }
49
+ {
50
+ templates: 'templates',
51
+ config: 'config'
52
+ }
49
53
  end
50
54
 
51
55
  # Returns a hash with key Mint files
52
56
  def self.files
53
- { config: 'config.yaml' }
57
+ {
58
+ syntax: directories[:config] + '/syntax.yaml',
59
+ config: directories[:config] + '/config.yaml'
60
+ }
54
61
  end
55
62
 
56
63
  def self.default_options
@@ -75,6 +82,18 @@ module Mint
75
82
  css_formats = ['css', 'sass', 'scss', 'less']
76
83
  end
77
84
 
85
+ # Lists the full path for each known template in the
86
+ # Mint path
87
+ def self.templates
88
+ templates_dir = Mint.directories[:templates]
89
+
90
+ Mint.path(true).
91
+ map {|p| p + directories[:templates] }.
92
+ select(&:exist?).
93
+ map {|p| p.children.select(&:directory?).map(&:to_s) }.
94
+ flatten
95
+ end
96
+
78
97
  # Decides whether the template specified by `name_or_file` is a real
79
98
  # file or the name of a template. If it is a real file, Mint will
80
99
  # return a that file. Otherwise, Mint will look for a file with that
@@ -87,7 +106,7 @@ module Mint
87
106
  # ~/.mint/templates/normal/style.css.
88
107
  def self.lookup_template(name_or_file, type=:layout)
89
108
  name = name_or_file.to_s
90
- File.exist?(name) ? Pathname.new(name) : find_template(name, type)
109
+ File.exist?(name) ? name : find_template(name, type)
91
110
  end
92
111
 
93
112
  # Finds a template named `name` in the Mint path. If `type` is :layout,
@@ -105,17 +124,26 @@ module Mint
105
124
  find_files = lambda {|x| Pathname.glob "#{x.to_s}.*" }
106
125
  acceptable = lambda {|x| x.to_s =~ /#{Mint.formats.join '|'}/ }
107
126
 
108
- template = Mint.path.map(&file_name).map(&find_files).flatten.
109
- select(&acceptable).select(&:exist?).first
127
+ template = Mint.path(true).map(&file_name).map(&find_files).flatten.
128
+ select(&acceptable).select(&:exist?).first.to_s
110
129
  raise TemplateNotFoundException unless template
111
130
 
112
131
  template
113
132
  end
114
133
 
134
+ # A non-rigourous check to see if the file is somewhere on the
135
+ # MINT_PATH
136
+ def self.template?(file)
137
+ paths = Mint.path.map {|f| File.expand_path f }
138
+ file_path = Pathname.new(file)
139
+ file_path.exist? and
140
+ file_path.dirname.expand_path.to_s =~ /#{paths.join('|')}/
141
+ end
142
+
115
143
  # Guesses an appropriate name for the resource output file based on
116
144
  # its source file's base name
117
145
  def self.guess_name_from(name)
118
- name = name.basename if name.respond_to? :basename
146
+ name = Pathname(name).basename if name
119
147
  css = Mint.css_formats.join '|'
120
148
  name.to_s.
121
149
  gsub(/\.(#{css})$/, '.css').
@@ -127,4 +155,8 @@ module Mint
127
155
  def self.renderer(path)
128
156
  Tilt.new path.to_s, :smart => true, :ugly => true
129
157
  end
158
+
159
+ def self.publish!(document)
160
+ document.publish!
161
+ end
130
162
  end
data/lib/mint/resource.rb CHANGED
@@ -4,44 +4,82 @@ module Mint
4
4
  class Resource
5
5
  attr_accessor :type
6
6
 
7
- attr_reader :source
8
- def source=(source)
9
- @source = Pathname.new(source) if source
10
- end
11
-
12
- # I haven't tested this - moved empty string from
13
- # default options into this method, so that default options
14
- # can be uniform - i.e., style_destination and destination
15
- # can each be nil to indicate that any rendering will be
16
- # done in the same folder the file is already in. I need
17
- # to make sure that adding the empty string here actually
18
- # keeps us in the current working directory
19
- attr_reader :destination
20
- def destination=(destination)
21
- @destination = Pathname.new(destination) if destination
22
- end
23
-
24
7
  attr_reader :name
25
8
  def name=(name)
26
9
  @name = name
27
10
  end
28
11
 
12
+ attr_reader :root
13
+ def root=(root)
14
+ @root = root
15
+ end
16
+
17
+ def root_directory_path
18
+ Pathname.new(root || Dir.getwd).expand_path
19
+ end
20
+
21
+ def root_directory
22
+ root_directory_path.to_s
23
+ end
24
+
25
+ attr_accessor :source
26
+
27
+ def source_file_path
28
+ path = Pathname.new(source)
29
+ path.absolute? ?
30
+ path.expand_path : root_directory_path + path
31
+ end
32
+
33
+ def source_file
34
+ source_file_path.to_s
35
+ end
36
+
37
+ def source_directory_path
38
+ source_file_path.dirname
39
+ end
40
+
41
+ def source_directory
42
+ source_directory_path.to_s
43
+ end
44
+
45
+ attr_accessor :destination
46
+
47
+ def destination_file_path
48
+ root_directory_path + (destination || '') + name
49
+ end
50
+
51
+ def destination_file
52
+ destination_file_path.to_s
53
+ end
54
+
55
+ def destination_directory_path
56
+ destination_file_path.dirname
57
+ end
58
+
59
+ def destination_directory
60
+ destination_directory_path.to_s
61
+ end
62
+
29
63
  def renderer=(renderer)
30
64
  @renderer = renderer
31
65
  end
32
66
 
33
- def initialize(source, type=:resource, options={})
67
+ def initialize(source, options={})
34
68
  return nil unless source
35
69
 
70
+ self.type = :resource
36
71
  self.source = source
37
- self.type = type
72
+ self.root = options[:root] || source_directory
38
73
  self.destination = options[:destination]
74
+
75
+ yield self if block_given?
76
+
39
77
  self.name = Mint.guess_name_from source
40
78
  self.renderer = Mint.renderer source
41
79
  end
42
80
 
43
81
  def equal?(other)
44
- self.destination + self.name == other.destination + other.name
82
+ self.destination_file_path == other.destination_file_path
45
83
  end
46
84
  alias_method :==, :equal?
47
85
 
data/lib/mint/style.rb CHANGED
@@ -6,12 +6,31 @@ module Mint
6
6
  # file to use when a template name is specified.
7
7
  class Style < Resource
8
8
  def initialize(source, opts=Mint.default_options)
9
- super(source, :style, opts)
10
- self.destination ||= source.dirname.expand_path + 'css'
9
+ super(source, opts)
10
+ self.type = :style
11
+
12
+ # We want to render final stylesheet to the /css subdirectory if
13
+ # an output directory is not specified and we are dealing with
14
+ # a named template (not a local file). If we don't do this, the rendered
15
+ # Css file might be picked up next time we look for a named template
16
+ # in this directory, and the (correct) Sass file won't be picked up.
17
+ # However, if a destination directory is already specified, we
18
+ # leave it alone.
19
+ if Mint.template?(self.source_directory) and rendered?
20
+ self.destination ||= 'css'
21
+ end
22
+ end
23
+
24
+ def render
25
+ if rendered?
26
+ super
27
+ else
28
+ File.read source
29
+ end
11
30
  end
12
31
 
13
- def need_rendering?
14
- source.extname !~ /\.css$/
32
+ def rendered?
33
+ source_file_path.extname !~ /\.css$/
15
34
  end
16
35
  end
17
36
  end
data/lib/mint/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Mint
2
- VERSION = '0.2.2'
2
+ VERSION = '0.2.5'
3
3
  end
@@ -2,225 +2,187 @@ require 'spec_helper'
2
2
 
3
3
  module Mint
4
4
  describe Document do
5
- before(:all) do
6
- @old_dir = Dir.getwd
7
- Dir.chdir 'tmp'
8
- end
9
-
10
- before do
11
- @content_file = 'content.md'
12
- @layout_file = 'local.haml'
13
- @style_file = 'local.css'
5
+ before { @tmp_dir = Dir.getwd }
14
6
 
15
- @content = <<-HERE
16
- Header
17
- ------
7
+ # We're not going to re-test derivative methods like source_file_path
8
+ # or root_directory. resource_spec.rb tells us that if the master
9
+ # values hold true, then their derivatives will be what we expect, as well.
10
+ # We do have to test #style_destination derivatives. Those aren't
11
+ # covered by resource_spec.rb.
12
+ shared_examples_for "all documents" do
13
+ # Convenience methods
14
+
15
+ it "#stylesheet" do
16
+ relative_path = document.destination_file_path.
17
+ relative_path_from(document.style_destination_file_path)
18
18
 
19
- This is just a test.
20
- HERE
19
+ document.stylesheet.should == relative_path.to_s
20
+ end
21
21
 
22
- @layout = <<-HERE
23
- !!!
24
- %html
25
- %head
26
- %body= content
27
- HERE
22
+ # style_spec.rb ensures that our style generation goes as planned
23
+ # However, we need to test layout generation because it should now
24
+ # include our content
25
+ its(:content) { should =~ /<p>This is just a test.<\/p>/ }
28
26
 
29
- @style = 'body { font-size: 16px }'
27
+ # Render output
30
28
 
31
- File.open @content_file, 'w' do |f|
32
- f << @content
29
+ it "renders its layout, injecting content inside" do
30
+ document.render.should =~
31
+ /.*<html>.*#{document.content}.*<\/html>.*/m
33
32
  end
34
33
 
35
- File.open @layout_file, 'w' do |f|
36
- f << @layout
34
+ it "links to its stylesheet" do
35
+ document.render.should =~ /#{document.stylesheet}/
37
36
  end
38
37
 
39
- File.open @style_file, 'w' do |f|
40
- f << @style
38
+ # Mint output
39
+
40
+ it "writes its rendered style to #style_destination_file" do
41
+ document.publish!
42
+ document.style_destination_file_path.should exist
41
43
  end
42
- end
43
44
 
44
- after do
45
- File.delete @content_file
46
- File.delete @layout_file
47
- File.delete @style_file
45
+ it "writes its rendered layout and content to #destination_file" do
46
+ document.publish!
47
+ document.destination_file_path.should exist
48
+ content = File.read document.destination_file
49
+ content.should == document.render
50
+ end
48
51
  end
49
52
 
50
- after(:all) do
51
- Dir.chdir @old_dir
52
- end
53
+ context "when it's created with default options" do
54
+ let(:document) { Document.new @content_file }
53
55
 
54
- shared_examples_for "all documents" do
55
- it "loads content as its source" do
56
- document.source.to_s.should == 'content.md'
57
- end
56
+ subject { document }
57
+ its(:root) { should == @tmp_dir }
58
+ its(:destination) { should be_nil }
59
+ its(:source) { should == 'content.md' }
60
+ its(:style_destination) { should be_nil }
58
61
 
59
- it "guesses its name from the source" do
60
- document.name.to_s.should =~ /content/
62
+ its(:style_destination_file) do
63
+ should == Mint.root + '/templates/default/css/style.css'
61
64
  end
62
65
 
63
- it "renders its content" do
64
- document.content.should =~ /<p>This is just a test.<\/p>/
66
+ its(:style_destination_directory) do
67
+ should == Mint.root + '/templates/default/css'
65
68
  end
66
69
 
67
- it "renders its layout, injecting content inside" do
68
- document.render.should =~
69
- /.*<html>.*<p>This is just a test.<\/p>.*<\/html>.*/m
70
+ its(:style_destination_file_path) do
71
+ should == Pathname.new(document.style_destination_file)
70
72
  end
71
73
 
72
- # This test makes me think I want to add document.destination_file and
73
- # change document.destination to document.destination_directory.
74
- it "creates a named output file in its specified destination directory" do
75
- pending
76
- document.mint
77
- document.destination_file.should exist
78
- # file = Pathname.getwd + (document.destination || '') + document.name
79
- # file.should exist
74
+ its(:style_destination_directory_path) do
75
+ should == Pathname.new(document.style_destination_directory)
80
76
  end
81
77
 
82
- it "writes its rendered layout and content to that output file" do
83
- pending
84
- document.mint
85
- content = File.read document.destination_file
86
- content.should =~ /.*<html>.*<p>This is just a test.<\/p>.*<\/html>.*/m
87
- end
88
- end
78
+ its(:layout) { should be_in_directory('default') }
79
+ its(:style) { should be_in_directory('default') }
89
80
 
90
- shared_examples_for "documents with a static stylesheet" do
91
- it "knows not to render its style" do
92
- document.style.need_rendering?.should == false
93
- end
94
-
95
- it "does not render or write its style"
81
+ it_should_behave_like "all documents"
96
82
  end
97
83
 
98
- shared_examples_for "documents with a dynamic stylesheet" do
99
- it "knows to render its style" do
100
- document.style.need_rendering?.should == true
101
- end
84
+ context "when it's created with explicit destination directories" do
85
+ let(:document) { Document.new @content_file,
86
+ :destination => 'destination',
87
+ :style_destination => 'styles' }
102
88
 
103
- it "writes its rendered style into its style_destination"
104
- end
89
+ subject { document }
90
+ its(:root) { should == @tmp_dir }
91
+ its(:destination) { should == 'destination' }
92
+ its(:source) { should == 'content.md' }
93
+ its(:style_destination) { should == 'styles' }
105
94
 
106
- shared_examples_for "documents with the default template" do
107
- it "chooses the default layout" do
108
- document.layout.should be_in_directory('default')
95
+ its(:style_destination_file) do
96
+ should == "#{@tmp_dir}/destination/styles/style.css"
109
97
  end
110
98
 
111
- it "chooses the default style" do
112
- document.style.should be_in_directory('default')
99
+ its(:style_destination_directory) do
100
+ should == "#{@tmp_dir}/destination/styles"
113
101
  end
114
- end
115
102
 
116
- shared_examples_for "documents with the pro template" do
117
- it "chooses the pro layout" do
118
- document.layout.should be_in_directory('pro')
103
+ its(:style_destination_file_path) do
104
+ should == Pathname.new(document.style_destination_file)
119
105
  end
120
106
 
121
- it "chooses the pro style" do
122
- document.style.should be_in_directory('pro')
107
+ its(:style_destination_directory_path) do
108
+ should == Pathname.new(document.style_destination_directory)
123
109
  end
124
- end
125
110
 
126
- shared_examples_for "documents with the local template" do
127
- it "chooses the local layout" do
128
- document.layout.name.to_s.should =~ /local/
129
- document.layout.source.to_s.should == 'local.haml'
130
- end
111
+ its(:layout) { should be_in_directory('default') }
112
+ its(:style) { should be_in_directory('default') }
131
113
 
132
- it "chooses the local style" do
133
- document.style.name.to_s.should =~ /local/
134
- document.style.source.to_s.should == 'local.css'
135
- end
114
+ it_should_behave_like "all documents"
136
115
  end
137
116
 
138
- shared_examples_for "documents without explicit directories" do
139
- it "does not have a nested destination directory" do
140
- document.destination.should be_nil
141
- end
117
+ context "when it's created with an explicit root" do
118
+ let(:document) { Document.new @content_file,
119
+ :root => "#{@tmp_dir}/alternative-root" }
142
120
 
143
- it "sets the style's current directory as its style destination" do
144
- document.style_destination.should be_nil
145
- end
146
- end
121
+ subject { document }
122
+ its(:root) { should == "#{@tmp_dir}/alternative-root" }
123
+ its(:destination) { should be_nil }
124
+ its(:source) { should == 'content.md' }
125
+ its(:style_destination) { should be_nil }
147
126
 
148
- shared_examples_for "documents with explicit directories" do
149
- it "has a nested destination directory" do
150
- document.destination.to_s.should == 'destination'
127
+ its(:style_destination_file) do
128
+ should == Mint.root + '/templates/default/css/style.css'
151
129
  end
152
130
 
153
- it "sets the destination directory as its style destination" do
154
- document.style_destination.to_s.should == 'styles'
131
+ its(:style_destination_directory) do
132
+ should == Mint.root + '/templates/default/css'
155
133
  end
156
- end
157
134
 
158
- context "when it's created without explicit options" do
159
- let(:document) { Document.new @content_file }
135
+ its(:style_destination_file_path) do
136
+ should == Pathname.new(document.style_destination_file)
137
+ end
160
138
 
161
- it_behaves_like "all documents"
162
- it_behaves_like "documents with the default template"
163
- it_behaves_like "documents without explicit directories"
164
- it_behaves_like "documents with a dynamic stylesheet"
165
- end
139
+ its(:style_destination_directory_path) do
140
+ should == Pathname.new(document.style_destination_directory)
141
+ end
166
142
 
167
- context "when it's created inline with named layouts and styles" do
168
- let(:document) { Document.new @content_file,
169
- :layout => 'pro', :style => 'pro' }
143
+ its(:layout) { should be_in_directory('default') }
144
+ its(:style) { should be_in_directory('default') }
170
145
 
171
- it_behaves_like "all documents"
172
- it_behaves_like "documents with the pro template"
173
- it_behaves_like "documents without explicit directories"
174
- it_behaves_like "documents with a dynamic stylesheet"
146
+ it_should_behave_like "all documents"
175
147
  end
176
148
 
177
- context "when it's created inline with local layouts and styles" do
178
- let(:document) { Document.new @content_file,
179
- :layout => 'local.haml', :style => 'local.css' }
180
-
181
- it_behaves_like "all documents"
182
- it_behaves_like "documents with the local template"
183
- it_behaves_like "documents without explicit directories"
184
- it_behaves_like "documents with a static stylesheet"
185
- end
149
+ context "when it is created with a block" do
150
+ let(:document) do
151
+ Document.new @content_file do |doc|
152
+ doc.root = "#{@tmp_dir}/alternative-root"
153
+ doc.destination = 'destination'
154
+ doc.style_destination = 'styles'
155
+ doc.layout = 'pro'
156
+ doc.style = 'pro'
157
+ end
158
+ end
186
159
 
187
- context "when it's created with a template" do
188
- let(:document) { Document.new @content_file, :template => 'pro' }
160
+ subject { document }
161
+ its(:root) { should == "#{@tmp_dir}/alternative-root" }
162
+ its(:destination) { should == 'destination' }
163
+ its(:source) { should == 'content.md' }
164
+ its(:style_destination) { should == 'styles' }
189
165
 
190
- it_behaves_like "all documents"
191
- it_behaves_like "documents with the pro template"
192
- it_behaves_like "documents without explicit directories"
193
- it_behaves_like "documents with a dynamic stylesheet"
194
- end
166
+ its(:style_destination_file) do
167
+ should == "#{@tmp_dir}/alternative-root/destination/styles/style.css"
168
+ end
195
169
 
196
- context "when it's created with a non-default destinations" do
197
- let(:document) { Document.new @content_file,
198
- :root => 'root', :destination => 'destination',
199
- :style_destination => 'styles' }
170
+ its(:style_destination_directory) do
171
+ should == "#{@tmp_dir}/alternative-root/destination/styles"
172
+ end
200
173
 
201
- it_behaves_like "all documents"
202
- it_behaves_like "documents with the default template"
203
- it_behaves_like "documents with explicit directories"
204
- it_behaves_like "documents with a dynamic stylesheet"
205
- end
174
+ its(:style_destination_file_path) do
175
+ should == Pathname.new(document.style_destination_file)
176
+ end
206
177
 
207
- context "when it's created with a block" do
208
- let(:document) do
209
- Document.new @content_file do |document|
210
- document.destination = 'destination'
211
- document.style_destination = 'styles'
212
- document.layout = 'pro'
213
- document.style = 'pro'
214
- end
178
+ its(:style_destination_directory_path) do
179
+ should == Pathname.new(document.style_destination_directory)
215
180
  end
216
181
 
217
- it_behaves_like "all documents"
218
- it_behaves_like "documents with the pro template"
219
- it_behaves_like "documents with explicit directories"
220
- it_behaves_like "documents with a dynamic stylesheet"
221
- end
182
+ its(:layout) { should be_in_directory('pro') }
183
+ its(:style) { should be_in_directory('pro') }
222
184
 
223
- context "when it's created with an existing layout"
224
- context "when it's created with an existnig style"
185
+ it_should_behave_like "all documents"
186
+ end
225
187
  end
226
188
  end