mint 0.2.2 → 0.2.5

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