mint 0.1.1 → 0.1.3
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.md +175 -228
- data/bin/mint +141 -57
- data/lib/mint.rb +2 -433
- data/lib/mint/helpers.rb +31 -0
- data/lib/mint/mint.rb +309 -0
- metadata +20 -11
- data/templates/default/layout.haml +0 -7
- data/templates/default/style.sass +0 -21
data/bin/mint
CHANGED
@@ -1,80 +1,164 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
# A script for harnessing Mint at the commandline
|
3
3
|
|
4
|
-
|
4
|
+
require 'pathname'
|
5
|
+
|
6
|
+
$:.unshift Pathname.new(__FILE__).realpath.dirname + '..' + 'lib'
|
5
7
|
|
6
|
-
require 'rubygems'
|
7
|
-
require 'mint'
|
8
8
|
require 'optparse'
|
9
|
+
require 'yaml'
|
10
|
+
require 'mint'
|
9
11
|
|
10
|
-
|
11
|
-
|
12
|
-
|
12
|
+
module Mint
|
13
|
+
# A map of all options that OptParse will accept from the commandline.
|
14
|
+
# All other arguments are taken to be filenames.
|
15
|
+
def self.options
|
16
|
+
{
|
17
|
+
# These options take parameters
|
18
|
+
template: ['t', 'template', true, 'Specify the template (layout + style).'],
|
19
|
+
layout: ['l', 'layout', true, 'Specify only the layout.'],
|
20
|
+
style: ['s', 'style', true, 'Specify only the style.'],
|
21
|
+
root: ['w', 'root', true, 'Specify a root outside the current directory.'],
|
22
|
+
destination: ['d', 'destination', true, 'Specify a destination directory, relative to the root.'],
|
23
|
+
style_destination: ['n', 'style-destination', true, 'Specify a destination directory for stylesheets, relative to the document destination directory. If not explicit, will be linked from original location.'],
|
13
24
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
25
|
+
# These options do not take parameters
|
26
|
+
global: ['G', 'global', false, 'Specify config changes on a global level.'],
|
27
|
+
user: ['U', 'user', false, 'Specify config changes on a user-wide level.'],
|
28
|
+
local: ['L', 'local', false, 'Specify config changes on a project-specific level.'],
|
29
|
+
force: ['f', 'force', false, 'Force file overwrite without prompt.'],
|
30
|
+
verbose: ['v', 'verbose', false, 'Verbose output.'],
|
31
|
+
simulation: ['s', 'simulation', false, 'Simulate transformation without actually creating files.']
|
32
|
+
}
|
33
|
+
end
|
18
34
|
|
19
|
-
|
35
|
+
module CommandLine
|
36
|
+
def self.config_options
|
37
|
+
config_filename = Pathname.new(Mint.files[:config])
|
20
38
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
39
|
+
# Merge config options from all config files on the Mint path,
|
40
|
+
# where more local options take precedence over more global
|
41
|
+
# options
|
42
|
+
Mint.path.map {|p| p + config_filename }.
|
43
|
+
select(&:exist?).
|
44
|
+
map {|p| YAML.load_file p }.
|
45
|
+
reverse.
|
46
|
+
reduce({}) {|r,p| r.merge p }
|
47
|
+
end
|
48
|
+
|
49
|
+
def self.full_options_with(commandline_options)
|
50
|
+
config_options.merge commandline_options
|
51
|
+
end
|
52
|
+
|
53
|
+
def self.write_config(opts, scope=:local)
|
54
|
+
Helpers.ensure_directory Mint.path_for_scope(scope)
|
55
|
+
Helpers.update_yaml(opts, Mint.path_for_scope(scope) + Mint.files[:config])
|
56
|
+
end
|
57
|
+
|
58
|
+
def self.edit(name, layout_or_style=:layout)
|
59
|
+
file = Mint.lookup_template name, layout_or_style
|
60
|
+
|
61
|
+
editor = ENV['EDITOR'] || 'vim'
|
62
|
+
system "#{editor} #{file}"
|
63
|
+
end
|
64
|
+
|
65
|
+
def self.set(key, value, scope=:local)
|
66
|
+
write_config({ key => value }, scope)
|
67
|
+
end
|
68
|
+
|
69
|
+
def self.config
|
70
|
+
puts YAML.dump(config_options)
|
27
71
|
end
|
28
|
-
end
|
29
72
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
73
|
+
# Renders and writes to file all resources described by a document.
|
74
|
+
# Specifically: it renders itself (inside of its own layout) and then
|
75
|
+
# renders its style. This method will overwrite any existing content
|
76
|
+
# in a document's destination files. The `render_style` option
|
77
|
+
# provides an easy way to stop Mint from rendering a style, even
|
78
|
+
# if the document's style is not nil.
|
79
|
+
def self.mint(files, commandline_options)
|
80
|
+
puts "minting #{files}"
|
81
|
+
documents = []
|
82
|
+
options = Mint::CommandLine.full_options_with commandline_options
|
83
|
+
|
84
|
+
root = options[:root] || Dir.getwd
|
85
|
+
|
86
|
+
# Eventually render_style should be replaced with file change detection
|
87
|
+
render_style = true
|
88
|
+
files.each do |file|
|
89
|
+
Document.new(file, options).mint(root, render_style)
|
90
|
+
render_style = false
|
37
91
|
end
|
38
92
|
end
|
39
93
|
end
|
40
94
|
end
|
41
95
|
|
42
|
-
#
|
43
|
-
|
44
|
-
# --root, -R
|
45
|
-
# --destination, -D
|
46
|
-
# --name, -N
|
47
|
-
# --style-destination
|
48
|
-
# --style-name
|
49
|
-
|
50
|
-
options_with_parameters = {
|
51
|
-
:template => ['T', 'template'],
|
52
|
-
:layout => ['L', 'layout'],
|
53
|
-
:style => ['S', 'style'],
|
54
|
-
:root => ['R', 'root'],
|
55
|
-
:destination => ['D', 'destination'],
|
56
|
-
:name => ['N', 'name'],
|
57
|
-
:style_destination => ['E', 'style-destination'],
|
58
|
-
:style_name => ['A', 'style-name']
|
59
|
-
}
|
60
|
-
|
61
|
-
options_without_parameters = [ :verbose, :simulation ]
|
62
|
-
|
63
|
-
config = {}
|
64
|
-
|
96
|
+
# Parse options from the commandline
|
97
|
+
commandline_options = {}
|
65
98
|
optparse = OptionParser.new do |opts|
|
66
|
-
opts.banner = 'Usage: mint
|
67
|
-
|
68
|
-
|
99
|
+
opts.banner = 'Usage: mint [command] files [options]'
|
100
|
+
|
101
|
+
Mint.options.each do |k,v|
|
102
|
+
has_param = v[2]
|
103
|
+
|
69
104
|
v[0] = "-#{v[0]}"
|
70
|
-
v[1] = "--#{v[1]}
|
71
|
-
|
72
|
-
|
73
|
-
|
105
|
+
v[1] = "--#{v[1]}"
|
106
|
+
|
107
|
+
if has_param
|
108
|
+
v[1] << " PARAM"
|
109
|
+
opts.on v[0], v[1], v[3] do |p|
|
110
|
+
commandline_options[k] = p
|
111
|
+
end
|
112
|
+
else
|
113
|
+
opts.on v[0], v[1], v[3] do
|
114
|
+
commandline_options[k] = true
|
115
|
+
end
|
74
116
|
end
|
75
117
|
end
|
76
118
|
end
|
119
|
+
optparse.parse!
|
77
120
|
|
78
|
-
|
121
|
+
case ARGV.first.downcase.to_sym
|
79
122
|
|
80
|
-
|
123
|
+
# If we get the edit command, will retrieve appropriate file
|
124
|
+
# (probably a Mint template) and shell out that file to
|
125
|
+
# the user's favorite editor. Otherwise ...
|
126
|
+
when :edit
|
127
|
+
layout = commandline_options[:layout]
|
128
|
+
style = commandline_options[:style]
|
129
|
+
|
130
|
+
if layout and not style
|
131
|
+
Mint::CommandLine.edit layout, :layout
|
132
|
+
elsif style
|
133
|
+
Mint::CommandLine.edit style, :style
|
134
|
+
else
|
135
|
+
puts optparse.help
|
136
|
+
end
|
137
|
+
|
138
|
+
# ... if we get the set command, we will try to set
|
139
|
+
# a config option (at the specified scope) per the user's command. Else ...
|
140
|
+
when :set
|
141
|
+
# Determine scope, using local as the default
|
142
|
+
commandline_options[:local] = true
|
143
|
+
scope = [:global, :user, :local].
|
144
|
+
select {|e| commandline_options[e] }.
|
145
|
+
first
|
146
|
+
|
147
|
+
Mint::CommandLine.set ARGV.shift, ARGV.shift, scope
|
148
|
+
|
149
|
+
# ... if we get the config command, display all active configurations,
|
150
|
+
# where local configurations override global ones
|
151
|
+
when :config
|
152
|
+
Mint::CommandLine.config
|
153
|
+
|
154
|
+
# ... we know we've been passed a set of documents, so parse the
|
155
|
+
# commandline options, merge them with the config options, and
|
156
|
+
# start minting the document list.
|
157
|
+
else
|
158
|
+
# The Mint library can't parse these options
|
159
|
+
commandline_options.delete :verbose
|
160
|
+
commandline_options.delete :simulation
|
161
|
+
|
162
|
+
puts "ARGV = #{ARGV}"
|
163
|
+
Mint::CommandLine.mint ARGV, commandline_options
|
164
|
+
end
|
data/lib/mint.rb
CHANGED
@@ -1,433 +1,2 @@
|
|
1
|
-
require '
|
2
|
-
require '
|
3
|
-
require 'tilt'
|
4
|
-
require 'haml'
|
5
|
-
require 'rdiscount'
|
6
|
-
|
7
|
-
require 'helpers'
|
8
|
-
|
9
|
-
module Mint
|
10
|
-
VERSION = '0.1'
|
11
|
-
|
12
|
-
# Default paths where Mint looks for styles and layouts, in this order
|
13
|
-
$path = [
|
14
|
-
Pathname.new('.mint'), # 1. Project-defined
|
15
|
-
Pathname.new(ENV['HOME']) + '.mint', # 2. User-defined
|
16
|
-
Pathname.new('/usr') + 'share' + 'mint', # 3. System-defined
|
17
|
-
Pathname.new(__FILE__).dirname + '..' # 4. Gemfile-defined
|
18
|
-
].collect! {|p| p.expand_path }
|
19
|
-
|
20
|
-
# Directories within the Mint path
|
21
|
-
$default_directories = {
|
22
|
-
:templates => 'templates'
|
23
|
-
}
|
24
|
-
|
25
|
-
# Files within a Mint Project
|
26
|
-
$default_files = {
|
27
|
-
:config => 'config.yaml'
|
28
|
-
}
|
29
|
-
|
30
|
-
# Registered HTML and CSS formats, for source -> destination
|
31
|
-
# name guessing/conversion
|
32
|
-
$html_formats = ['.haml', '.erb', '.md']
|
33
|
-
$css_formats = ['.sass', '.scss', '.less']
|
34
|
-
$source_formats = $html_formats + $css_formats
|
35
|
-
|
36
|
-
# Default options, where nil acts as described in the specification
|
37
|
-
# Namely, a nil root or destination or style/layout template will
|
38
|
-
# not be used, and a nil name will prompt Mint to guess an appropriate
|
39
|
-
# name based on your source files
|
40
|
-
$default_opts = {
|
41
|
-
:template => 'default', # this is a new feature I need to test
|
42
|
-
# :layout => 'default',
|
43
|
-
# :style => 'default',
|
44
|
-
:root => nil,
|
45
|
-
:destination => nil,
|
46
|
-
:style_destination => nil,
|
47
|
-
:name => nil,
|
48
|
-
:style_name => nil
|
49
|
-
}
|
50
|
-
|
51
|
-
class Resource
|
52
|
-
attr_accessor :type, :source, :destination, :name
|
53
|
-
|
54
|
-
def initialize(source, opts={}, &block)
|
55
|
-
# A nil stylesheet or layout should not be rendered, so
|
56
|
-
# we'll return nil here
|
57
|
-
return nil unless source
|
58
|
-
|
59
|
-
# If there is a source, we initialize it right away as a
|
60
|
-
# Pathname, so we can use methods like @source.basename
|
61
|
-
@source = Pathname.new source
|
62
|
-
|
63
|
-
# Load in opts and change nil values to the assumptions
|
64
|
-
# described in the Mint README.
|
65
|
-
@opts = opts
|
66
|
-
|
67
|
-
# If there is no destination value, ignore it
|
68
|
-
@opts[:destination] ||= String.new
|
69
|
-
|
70
|
-
# For a nil name, guess based on source
|
71
|
-
@opts[:name] ||= Resource.guess_from(@source.basename.to_s)
|
72
|
-
|
73
|
-
# Initialize resource values based on normalized, robust
|
74
|
-
# opts. For raw resources (i.e., not for Documents), the destination
|
75
|
-
# and source are both resolved relative to the current working
|
76
|
-
# directory. This only really matters if you are initializing Layouts
|
77
|
-
# or Styles on your own instead of via a Document. If you're using
|
78
|
-
# a Document, all destination paths are resolved relative to the
|
79
|
-
# Document root, which defaults to the content's source directory.
|
80
|
-
@destination = Pathname.new @opts[:destination]
|
81
|
-
@name = @opts[:name]
|
82
|
-
@template = Resource.template @source
|
83
|
-
|
84
|
-
# You can use a block to instantiate a Resource. Any values you set
|
85
|
-
# in this block will override all other values.
|
86
|
-
if block_given?
|
87
|
-
yield self
|
88
|
-
end
|
89
|
-
end
|
90
|
-
|
91
|
-
def equals?(other)
|
92
|
-
destination + name == other.destination + other.name
|
93
|
-
end
|
94
|
-
|
95
|
-
alias_method :==, :equals?
|
96
|
-
|
97
|
-
# A convenience method for supplying and selecting configuration
|
98
|
-
# options. If supplied with an array of possible values, will return
|
99
|
-
# the first non-nil value. If the first non-nil value responds to
|
100
|
-
# `call`, will call that function and return its value.
|
101
|
-
def config_with(config)
|
102
|
-
(c = config.compact[0]).respond_to?(:call) ? c.call : c
|
103
|
-
end
|
104
|
-
|
105
|
-
# Renders the current resource to a string, returning that string
|
106
|
-
# and not outputting to any file. Can operate within the context of
|
107
|
-
# an Object, whose methods can be called from within the template.
|
108
|
-
# Other arguments can be passed along to the template compiler. (For
|
109
|
-
# example, to output HAML as HTML5, pass the option `:format =>
|
110
|
-
# :html5`. See the Tilt TEMPLATES.md file for more information.)
|
111
|
-
def render(context=Object.new, args={})
|
112
|
-
@template.render context, args
|
113
|
-
end
|
114
|
-
|
115
|
-
# Guesses an appropriate name for the Resource output file based on
|
116
|
-
# its source file's base name. Will convert registered HTML template
|
117
|
-
# extensions to '.html' and CSS template extensions to '.css'.
|
118
|
-
def self.guess_from(name)
|
119
|
-
css, html = $css_formats.join('|'), $html_formats.join('|')
|
120
|
-
name.gsub(/#{css}/, '.css').gsub(/#{html}/, '.html')
|
121
|
-
end
|
122
|
-
|
123
|
-
# Transforms a path into a template that will render the file specified
|
124
|
-
# at that path. Currently uses Tilt, so any valid Tilt source file
|
125
|
-
# is valid here.
|
126
|
-
def self.template(path)
|
127
|
-
Tilt.new path
|
128
|
-
end
|
129
|
-
end
|
130
|
-
|
131
|
-
# Layout describes a resource whose type is `:layout`. Beyond its type,
|
132
|
-
# it is a simple resource. However, its type helps decide which template
|
133
|
-
# file to use when a template name is specified. A Layout is best managed
|
134
|
-
# by a Document.
|
135
|
-
class Layout < Resource
|
136
|
-
def initialize(source, args={})
|
137
|
-
@type = :layout
|
138
|
-
super
|
139
|
-
end
|
140
|
-
end
|
141
|
-
|
142
|
-
# Style describes a resource whose type is `:style`. Beyond its type,
|
143
|
-
# it is a simple resource. However, its type helps decide which template
|
144
|
-
# file to use when a template name is specified. A Style is best managed
|
145
|
-
# by a Document.
|
146
|
-
class Style < Resource
|
147
|
-
def initialize(source, args={})
|
148
|
-
@type = :style
|
149
|
-
super
|
150
|
-
end
|
151
|
-
end
|
152
|
-
|
153
|
-
# Document is a workhorse of the Mint library. It extends Resource
|
154
|
-
# to include helpful variables like `root`, which will be the context
|
155
|
-
# for all the Resources it contains. A Document's source is its content
|
156
|
-
# file, from which it can derive a root directory, an output name, and
|
157
|
-
# destination directories. A Document has one Style and one Layout, which
|
158
|
-
# it initializes on creation. Default and optional Styles and Layouts are
|
159
|
-
# included with Mint. You can add more templates to the Mint path
|
160
|
-
# for even more choices.
|
161
|
-
class Document < Resource
|
162
|
-
attr_accessor :root, :layout, :style, :content
|
163
|
-
|
164
|
-
def initialize(source, opts={}, &block)
|
165
|
-
# Initialize opts to the default opts, replacing them with user-
|
166
|
-
# supplied opts where possible.
|
167
|
-
@opts = $default_opts.merge opts
|
168
|
-
|
169
|
-
# Invoke the parent class initializer, which sets the source,
|
170
|
-
# destination, name, template (content), and basic options.
|
171
|
-
super(source, @opts)
|
172
|
-
|
173
|
-
# Add in Doc-specific opts and change nil values to the
|
174
|
-
# assumptions described in the Mint README.
|
175
|
-
@opts[:root] ||= @source.dirname
|
176
|
-
|
177
|
-
# If a template name is given, it overrides style and layout
|
178
|
-
# names or files, per the Mint README.
|
179
|
-
if templ = @opts[:template]
|
180
|
-
@opts[:layout], @opts[:style] = templ, templ
|
181
|
-
end
|
182
|
-
|
183
|
-
@opts[:style_destination] ||= String.new
|
184
|
-
|
185
|
-
style_opts = {
|
186
|
-
:destination => @destination + @opts[:style_destination],
|
187
|
-
:name => @opts[:style_name]
|
188
|
-
}
|
189
|
-
|
190
|
-
# Initialize resource values based on normalized, robust opts. For
|
191
|
-
# Documents, the destination is resolved relative to the document
|
192
|
-
# root. The root and source paths are both resolved relative to the
|
193
|
-
# current working directory whenever this instantiation method
|
194
|
-
# is called.
|
195
|
-
@type = :document
|
196
|
-
@root = Pathname.new(@opts[:root]).expand_path
|
197
|
-
|
198
|
-
@content = Resource.template(@source).render
|
199
|
-
@layout = choose_template(@opts[:layout], :layout)
|
200
|
-
@style = choose_template(@opts[:style], :style, style_opts)
|
201
|
-
|
202
|
-
# Be careful not to modify this code such that you can change the
|
203
|
-
# current working directory before the source directory is normalized.
|
204
|
-
# expand_path is always called relative to the *current* working
|
205
|
-
# directory, not the initial one.
|
206
|
-
@source = normalize_path(@source) # becomes relative here
|
207
|
-
|
208
|
-
# You can use a block to instantiate a Document. Any values you set
|
209
|
-
# in this block will override all other values.
|
210
|
-
if block_given?
|
211
|
-
yield self
|
212
|
-
mint
|
213
|
-
end
|
214
|
-
end
|
215
|
-
|
216
|
-
# Returns the relative path to dir1 from dir2, which defaults to the
|
217
|
-
# Document root.
|
218
|
-
def normalize_path(dir1, dir2=root)
|
219
|
-
Document.normalize_path(dir1, dir2)
|
220
|
-
end
|
221
|
-
|
222
|
-
# Returns the relative path to dir1 from dir2.
|
223
|
-
def self.normalize_path(dir1, dir2)
|
224
|
-
path = case dir1
|
225
|
-
when String
|
226
|
-
Pathname.new dir1
|
227
|
-
when Pathname
|
228
|
-
dir1
|
229
|
-
end
|
230
|
-
|
231
|
-
path.expand_path.relative_path_from dir2
|
232
|
-
end
|
233
|
-
|
234
|
-
# Decides whether the template specified by `name_or_file` is a real
|
235
|
-
# file or the name of a template. If it is a real file, Mint will
|
236
|
-
# return a template using that file. Otherwise, Mint will look for a
|
237
|
-
# template with that name in the Mint path. The `layout_or_style`
|
238
|
-
# argument indicates whether the template we are looking for is
|
239
|
-
# a layout or a style and will affect which type of template is returned
|
240
|
-
# for a given template name. For example, `choose_template('normal',
|
241
|
-
# :layout)` might return a Layout template referring to the file
|
242
|
-
# ~/.mint/templates/normal/layout.haml. Changing the second argument
|
243
|
-
# to :style would return a Style template whose source file is
|
244
|
-
# ~/.mint/templates/normal/style.sass.
|
245
|
-
def choose_template(name_or_file, layout_or_style=:layout, opts={})
|
246
|
-
template = File.file?(name_or_file) ? Pathname.new(name_or_file) :
|
247
|
-
find_template(name_or_file, layout_or_style)
|
248
|
-
|
249
|
-
Mint.const_get(layout_or_style.to_s.capitalize).new(template, opts)
|
250
|
-
end
|
251
|
-
|
252
|
-
# Finds a template named `name` in the Mint path. If `layout_or_style`
|
253
|
-
# is :layout, will look for `MINT_PATH/templates/layout.*`. If it is
|
254
|
-
# :style, will look for `MINT_PATH/templates/TEMPLATE_NAME/style.*`.
|
255
|
-
# Will reject raw HTML and CSS, which are currently not compatible
|
256
|
-
# with Tilt, the rendering interface that Mint uses. (There are plans
|
257
|
-
# to support these files in the future.) Mint assumes that a named
|
258
|
-
# template will hold only one layout and one style template. It does
|
259
|
-
# not know how to decide between style.sass and style.less, for
|
260
|
-
# example. For predictable results, only include one template file
|
261
|
-
# called `layout.*` in the TEMPLATE_NAME directory. If you do want
|
262
|
-
# several style files in the same template directory, you will want
|
263
|
-
# to refer to the style file by its path and not by its template name.
|
264
|
-
# Will return nil if the named template is not in the Mint path.
|
265
|
-
def find_template(name, layout_or_style)
|
266
|
-
file = nil
|
267
|
-
|
268
|
-
$path.each do |directory|
|
269
|
-
templates_dir = directory + $default_directories[:templates]
|
270
|
-
query = templates_dir + name + layout_or_style.to_s
|
271
|
-
|
272
|
-
if templates_dir.exist?
|
273
|
-
# Mint looks for any
|
274
|
-
results = Pathname.glob "#{query}.*"
|
275
|
-
|
276
|
-
# Will only allow files ending in extensions that Tilt can
|
277
|
-
# handle. They are working to add raw HTML and CSS support, but
|
278
|
-
# it is not yet implemented.
|
279
|
-
results.reject {|r| r.to_s !~ /#{$source_formats.join('|')}/}
|
280
|
-
|
281
|
-
if results.length > 0
|
282
|
-
# Will return the first match found. See the `find_template`
|
283
|
-
# description for a discussion of when you should and should
|
284
|
-
# not rely on this method.
|
285
|
-
file = results[0]
|
286
|
-
break
|
287
|
-
end
|
288
|
-
end
|
289
|
-
end
|
290
|
-
|
291
|
-
file
|
292
|
-
end
|
293
|
-
|
294
|
-
# A Document renders itself (its content) in the context of its layout.
|
295
|
-
# This differs from raw Resources, which render themselves in the
|
296
|
-
# context of `Object.new`
|
297
|
-
def render(args={})
|
298
|
-
layout.render self, args
|
299
|
-
end
|
300
|
-
|
301
|
-
# Renders and writes to file all Resources described by a Document.
|
302
|
-
# Specifically: it renders itself (inside of its own Layout) and then
|
303
|
-
# renders its Style. This method will overwrite any existing content
|
304
|
-
# in a Document's destination files. The `render_style?` option
|
305
|
-
# provides an easy way to stop Mint from rendering a style, even
|
306
|
-
# if the Document's style is not nil. This makes it possible to
|
307
|
-
# associate a style with a Document (a style that can be called
|
308
|
-
# from layouts via `stylesheet`) without regenerating that
|
309
|
-
# stylesheet every time Mint runs.
|
310
|
-
def mint(render_style=true)
|
311
|
-
|
312
|
-
resources = [self]
|
313
|
-
resources << style if render_style
|
314
|
-
|
315
|
-
resources.compact.each do |r|
|
316
|
-
dest = @root + r.destination + r.name
|
317
|
-
|
318
|
-
# Kernel.puts <<-HERE
|
319
|
-
# Source: #{@root + r.source}
|
320
|
-
# Destination: #{dest}
|
321
|
-
# HERE
|
322
|
-
|
323
|
-
# Create any directories in the destination path that don't exist.
|
324
|
-
FileUtils.mkdir_p dest.dirname
|
325
|
-
|
326
|
-
# Render the resource to its destination file, overwriting any
|
327
|
-
# existing content.
|
328
|
-
dest.open 'w+' do |file|
|
329
|
-
file << r.render
|
330
|
-
end
|
331
|
-
end
|
332
|
-
end
|
333
|
-
|
334
|
-
# Convenience methods for views
|
335
|
-
|
336
|
-
# Returns a relative path from the Document to its stylesheet. Can
|
337
|
-
# be called directly from inside a Layout template.
|
338
|
-
def stylesheet
|
339
|
-
normalize_path(@root + style.destination,
|
340
|
-
@root + @destination) +
|
341
|
-
style.name.to_s
|
342
|
-
end
|
343
|
-
end
|
344
|
-
|
345
|
-
$project_default_opts = {}
|
346
|
-
|
347
|
-
class ProjectDocument < Document
|
348
|
-
attr_accessor :changed
|
349
|
-
end
|
350
|
-
|
351
|
-
class Project
|
352
|
-
attr_accessor :root, :documents, :layout, :style, :config
|
353
|
-
|
354
|
-
def initialize(root, opts={})
|
355
|
-
@opts = opts
|
356
|
-
@opts = $project_default_opts.merge opts
|
357
|
-
|
358
|
-
if templ = @opts[:template]
|
359
|
-
@opts[:layout], @opts[:style] = templ, templ
|
360
|
-
end
|
361
|
-
|
362
|
-
@root = root
|
363
|
-
@documents = Array.new
|
364
|
-
@style = @opts[:style]
|
365
|
-
@layout = @opts[:layout]
|
366
|
-
end
|
367
|
-
|
368
|
-
def mint
|
369
|
-
@documents.each_index do |i|
|
370
|
-
render_style = (i == 0)
|
371
|
-
@documents[i].mint(render_style)
|
372
|
-
end
|
373
|
-
end
|
374
|
-
|
375
|
-
def change_status(document, new_status)
|
376
|
-
end
|
377
|
-
|
378
|
-
def status
|
379
|
-
end
|
380
|
-
|
381
|
-
def add(document)
|
382
|
-
doc = Document.new
|
383
|
-
doc.layout = @layout
|
384
|
-
doc.style = @style
|
385
|
-
doc.root = @root
|
386
|
-
|
387
|
-
@documents << doc
|
388
|
-
end
|
389
|
-
|
390
|
-
alias_method :<<, :add
|
391
|
-
|
392
|
-
def remove(document)
|
393
|
-
@documents.delete document
|
394
|
-
end
|
395
|
-
|
396
|
-
def list
|
397
|
-
end
|
398
|
-
|
399
|
-
def edit(file_or_name, type=:layout)
|
400
|
-
|
401
|
-
|
402
|
-
if editor = ENV['EDITOR']
|
403
|
-
`#{editor} `
|
404
|
-
end
|
405
|
-
end
|
406
|
-
|
407
|
-
def watch
|
408
|
-
require 'fssm'
|
409
|
-
|
410
|
-
FSSM.monitor do
|
411
|
-
path root do
|
412
|
-
glob '*'
|
413
|
-
|
414
|
-
update {|base, relative|}
|
415
|
-
delete {|base, relative|}
|
416
|
-
create {|base, relative|}
|
417
|
-
end
|
418
|
-
end
|
419
|
-
|
420
|
-
path 'templates/**/*' do
|
421
|
-
update { |base, relative| update(relative) }
|
422
|
-
delete { |base, relative| update(relative) }
|
423
|
-
create { |base, relative| update(relative) }
|
424
|
-
end
|
425
|
-
end
|
426
|
-
|
427
|
-
def update(relative)
|
428
|
-
puts ">>> Change Detected to: #{relative} <<<"
|
429
|
-
|
430
|
-
puts '>>> Update Complete <<<'
|
431
|
-
end
|
432
|
-
end
|
433
|
-
end
|
1
|
+
require 'mint/mint'
|
2
|
+
require 'mint/version'
|