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/README.md +37 -32
- data/bin/mint +15 -52
- data/config/{options.yaml → syntax.yaml} +10 -11
- data/lib/mint/commandline.rb +63 -15
- data/lib/mint/document.rb +48 -28
- data/lib/mint/exceptions.rb +3 -0
- data/lib/mint/helpers.rb +21 -10
- data/lib/mint/layout.rb +2 -1
- data/lib/mint/mint.rb +47 -15
- data/lib/mint/resource.rb +58 -20
- data/lib/mint/style.rb +23 -4
- data/lib/mint/version.rb +1 -1
- data/spec/document_spec.rb +124 -162
- data/spec/spec_helper.rb +90 -2
- data/templates/default/style.sass +18 -96
- metadata +131 -162
data/README.md
CHANGED
@@ -1,10 +1,12 @@
|
|
1
|
-
*The following is a **rough
|
1
|
+
*The following is a **rough description** of the current Mint design, along with my future plans for the library and tool. When I have time, I'll extract the juciest parts into a README and move the rest into official documentation. The templates are not finished, and I haven't completed the plugin system. That said, I'm excited about where this library is going to go.*
|
2
2
|
|
3
|
-
**Mint requires Ruby 1.9.**
|
3
|
+
> **Mint requires Ruby 1.9.**
|
4
4
|
|
5
5
|
If I believed in slogans...
|
6
6
|
---------------------------
|
7
7
|
|
8
|
+
Mint is a publishing platform for people who want to store their documents as plain text without giving up proper layout or the ability to share with friends.
|
9
|
+
|
8
10
|
I don't actually believe in tag lines, but if Mint were to have one, it might be one of these:
|
9
11
|
|
10
12
|
- Value your words. Leave the formatting up to us.
|
@@ -20,7 +22,7 @@ Mint manages your documents in a decentralized but consistent way. It frees you
|
|
20
22
|
|
21
23
|
In a few more: *Mint processes words so you don't have to.*
|
22
24
|
|
23
|
-
|
25
|
+
Use cases
|
24
26
|
------------
|
25
27
|
|
26
28
|
1. Jake has text files formatted as Markdown-style text. He has traditionally published these as blog entries, which works well because his webserver takes care of processing the Markdown, generating HTML, and styling it with his static CSS. Jake has no way of visualizing his documents without a webserver running. He likes the convenience of centralized CSS styles that he can update once and cascade everywhere. He does not like depending on a webserver for static pages, i.e., his local documents. Jake wants a document management system where source files are written in Markdown but are "printed" into HTML and styled with centralized sheets he creates himself. In some cases, he merely wants to tweak the typography settings of a solid existing style. Above all, he wants simplicity: he does not want to have to put his documents into a certain structure in order for them to be rendered. And he wants default styles so that he doesn't have to create them on his own.
|
@@ -31,7 +33,7 @@ I. Use cases
|
|
31
33
|
|
32
34
|
4. Santosh stores his blog entries in Markdown and wants to see how they look using his blog engine's stylesheet. He doesn't want to upload his entry until he's finished with it, but he wants to preview it with that stylesheet along the way.
|
33
35
|
|
34
|
-
|
36
|
+
The Mint library
|
35
37
|
--------------------
|
36
38
|
|
37
39
|
This section discusses the Mint library API. This library encapsulates the idea of a styled document, which is composed of a stylesheet, a layout and content. Mint makes combining those seemless. See **The `mint` command** for more information on an easy-to-use binary.
|
@@ -41,9 +43,9 @@ This section discusses the Mint library API. This library encapsulates the idea
|
|
41
43
|
Mint is loaded with smart defaults, so if you don't want to configure something--say, the basic HTML skeleton of your document or the output directory--you don't have to. You'll probably be surprised at how easy it is to use out of the box, and how configurable it is.
|
42
44
|
|
43
45
|
document = Document.new 'Minimalism.md'
|
44
|
-
document.
|
46
|
+
document.publish!
|
45
47
|
|
46
|
-
And voil
|
48
|
+
And voilà, Minimalism.html will show up next to Minimalism.md.
|
47
49
|
|
48
50
|
Opening Minimalism.html with your favorite web browser--[Firefox is best for typography][Firefox typography], but Webkit-based browsers (Chrome, Safari) work, too--will show what looks like a word-processed document, complete with big bold headers, italic emphasis, automatically indented and numbered lists, and bullets. If you're in a modern browser, you'll even see ligatures and proper kerning. The page will be on a white canvas that looks like a page, even though you are in a browser.
|
49
51
|
|
@@ -57,35 +59,39 @@ If you want to customize your document, though--and that's why I built this libr
|
|
57
59
|
|
58
60
|
To understand how the library works, with and without configuration, it is helpful to look at the options you can pass to the library and what their defaults are.
|
59
61
|
|
60
|
-
You can
|
62
|
+
You can change a document by passing it one of several options.
|
63
|
+
|
64
|
+
#### Layout and style ####
|
65
|
+
|
66
|
+
`:layout` and `:style` are names of templates or file names. They can be overridden by `:template`, which sets both to the same name.
|
61
67
|
|
62
|
-
|
68
|
+
Defaults:
|
63
69
|
|
64
|
-
|
70
|
+
:template => 'default'
|
65
71
|
|
66
|
-
|
72
|
+
Notes:
|
67
73
|
|
68
|
-
|
74
|
+
1. If you specify a template name here, Mint will search its paths in order (see **The Mint Path** for more details) for a template with that name. A template file looks like the following:
|
69
75
|
|
70
|
-
|
76
|
+
${MINT_PATH}/templates/template_name/style.css
|
77
|
+
${MINT_PATH}/templates/template_name/layout.haml
|
71
78
|
|
72
|
-
|
73
|
-
${MINT_PATH}/templates/template_name/layout.haml
|
79
|
+
2. If you specify a template name that is also the name of an existing file in your working directory, Mint will use the file and not look for a template. (It is unlikely you'll have an extension-less file named 'normal' or 'default' in your working directory, so don't worry about this edge case.) If you do specify an existing file, the path/file will be resolved from the directory where you're calling Mint (the 'working directory'). To use Mint this way (and I don't see this as more than a temporary solution) you'll probably want to call Mint from within your source's directory. Alternatively, you can use [`Dir.chdir`][Dir::chdir method] for the same effect.
|
74
80
|
|
75
|
-
|
81
|
+
#### Destination ####
|
76
82
|
|
77
|
-
|
83
|
+
`:destination` lets you organize your output. It directs Mint to write the template or document to one of root's subdirectories. There is an option to specify a separate `:style_destination`, which is resolved relative to `:destination`.
|
78
84
|
|
79
|
-
|
85
|
+
Defaults:
|
80
86
|
|
81
|
-
|
82
|
-
|
87
|
+
:destination => nil
|
88
|
+
:style_destination => nil
|
83
89
|
|
84
|
-
|
90
|
+
Notes:
|
85
91
|
|
86
|
-
|
92
|
+
1. `:destination` *must* refer to a directory (existing or not) and not a file.
|
87
93
|
|
88
|
-
|
94
|
+
2. `:style_destination` is resolved relative to `:destination` so that packaging styles inside document directories is easy. (This supports the common case where you will want a subdirectory called 'styles' to hold your style files.) When `:style_destination` is nil (default), the stylesheet will not be copied anywhere. Instead, your document will link to the rendered stylesheet in place. If it needs to be rendered, it will be rendered into a subdirectory called 'css' so that the rendered document isn't picked up the next time you specify the same style.
|
89
95
|
|
90
96
|
### Examples ###
|
91
97
|
|
@@ -120,7 +126,7 @@ Block-style indentation passes the block to you *after* initializing the documen
|
|
120
126
|
|
121
127
|
[Dir::chdir method]: http://ruby-doc.org/core/classes/Dir.html#M002314 "You can change the current directory context with Dir::chdir(path)"
|
122
128
|
|
123
|
-
|
129
|
+
Designing a template
|
124
130
|
-------------------------
|
125
131
|
|
126
132
|
Templates can be written in any format accepted by the Tilt template interface library. (See [the Tilt TEMPLATES file][Tilt templates] for more information.)
|
@@ -176,20 +182,19 @@ destination.
|
|
176
182
|
Mint comes preloaded with several styles and layouts.
|
177
183
|
|
178
184
|
1. Default
|
179
|
-
2.
|
180
|
-
3.
|
185
|
+
2. Pro
|
186
|
+
3. Resume\*
|
181
187
|
4. Protocol
|
182
|
-
5. Protocol Flow - requires Javascript and jQuery
|
183
|
-
6. Resume
|
188
|
+
5. Protocol Flow\* - requires Javascript and jQuery
|
184
189
|
|
185
|
-
> Note:
|
190
|
+
> Note: Starred entries are not yet implemente. If you have a killer
|
186
191
|
> template you think should be included, send it my way. I'll check
|
187
192
|
> it out and see if it should be part of the standard template library.
|
188
193
|
> (Of course, you'll get all the credit.)
|
189
194
|
|
190
|
-
I'
|
195
|
+
I've included a base stylesheet that is useful for setting sensible typographic defaults.
|
191
196
|
|
192
|
-
|
197
|
+
The Mint path
|
193
198
|
-----------------
|
194
199
|
|
195
200
|
Mint's path tells the library where to search for named templates. It can be useful for other things, too, especially for extensions and tools that use the library (for example, for storing config files for the `mint` command). The Mint path is flexible and something that you can modify, even from the command line. (Just export `MINT_PATH`=`your:colon-separated-paths:here`. Just make sure to specify higher-priority paths before lower-priority ones.)
|
@@ -212,7 +217,7 @@ Templates should be in a directory named templates. Inside this directory, there
|
|
212
217
|
|
213
218
|
Normally a style will go best with its layout complement. However, layouts and styles can be mixed and matched at your discretion. This is especially true where you are primarily customizing DOM elements with your stylesheet instead of targeting specific IDs or classes you're expecting to find. (In other words, this works best when your stylesheet focuses on modifying typography and not page layout.)
|
214
219
|
|
215
|
-
|
220
|
+
The `mint` command
|
216
221
|
---------------------
|
217
222
|
|
218
223
|
*The `mint` command is almost functional. Testing is in development.*
|
@@ -327,7 +332,7 @@ Mint will open the appropriate file in the editor specified by EDITOR. The same
|
|
327
332
|
mint edit -l normal
|
328
333
|
mint edit -s normal
|
329
334
|
|
330
|
-
|
335
|
+
The future of Mint
|
331
336
|
----------------------
|
332
337
|
|
333
338
|
This section documents features that do not yet exist, but that I would like to have in future versions of Mint.
|
data/bin/mint
CHANGED
@@ -1,72 +1,35 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
-
|
3
2
|
# A script for harnessing Mint at the commandline
|
4
3
|
# Usage: mint [options] files
|
5
4
|
|
6
|
-
require 'optparse'
|
7
5
|
require 'mint'
|
8
6
|
|
9
7
|
# Parse options from the commandline
|
10
8
|
commandline_options = {}
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
Mint::CommandLine.options.each do |k,v|
|
15
|
-
has_param = v['parameter']
|
9
|
+
process_opts = lambda {|k,v| commandline_options[k] = v }
|
10
|
+
parser = Mint::CommandLine.parser(&process_opts)
|
11
|
+
parser.parse!
|
16
12
|
|
17
|
-
|
18
|
-
|
13
|
+
# Minimalist implementation that I want to move to, but
|
14
|
+
# will have to refactor commandline.rb code and tests
|
15
|
+
#
|
16
|
+
# first = ARGV.first.downcase.to_sym
|
17
|
+
# commands = [ :install, :edit, :set, :config ]
|
18
|
+
# command = commands.include?(first) ? command : :mint
|
19
19
|
|
20
|
-
|
21
|
-
v['long'] << " PARAM"
|
22
|
-
opts.on v['short'], v['long'], v['description'] do |p|
|
23
|
-
commandline_options[k.to_sym] = p
|
24
|
-
end
|
25
|
-
else
|
26
|
-
opts.on v['short'], v['long'], v['description'] do
|
27
|
-
commandline_options[k] = true
|
28
|
-
end
|
29
|
-
end
|
30
|
-
end
|
31
|
-
end
|
32
|
-
optparse.parse!
|
20
|
+
# Mint::CommandLine.send(command, commandline_options)
|
33
21
|
|
34
22
|
case ARGV.first.downcase.to_sym
|
35
23
|
when :help
|
36
|
-
Mint::CommandLine.help(
|
37
|
-
|
24
|
+
Mint::CommandLine.help(parser.help)
|
38
25
|
when :install
|
39
|
-
commandline_options
|
40
|
-
scope = [:global, :user, :local].
|
41
|
-
select {|e| commandline_options[e] }.
|
42
|
-
first
|
43
|
-
|
44
|
-
Mint::CommandLine.install ARGV.shift, scope
|
45
|
-
|
26
|
+
Mint::CommandLine.install(ARGV.shift, commandline_options)
|
46
27
|
when :edit
|
47
|
-
|
48
|
-
style = commandline_options[:style]
|
49
|
-
|
50
|
-
if layout and not style
|
51
|
-
Mint::CommandLine.edit layout, :layout
|
52
|
-
elsif style
|
53
|
-
Mint::CommandLine.edit style, :style
|
54
|
-
else
|
55
|
-
puts optparse.help
|
56
|
-
end
|
57
|
-
|
28
|
+
Mint::CommandLine.edit(ARGV.shift, commandline_options)
|
58
29
|
when :set
|
59
|
-
|
60
|
-
commandline_options[:local] = true
|
61
|
-
scope = [:global, :user, :local].
|
62
|
-
select {|e| commandline_options[e] }.
|
63
|
-
first
|
64
|
-
|
65
|
-
Mint::CommandLine.set ARGV.shift, ARGV.shift, scope
|
66
|
-
|
30
|
+
Mint::CommandLine.set(ARGV.shift, ARGV.shift, commandline_options)
|
67
31
|
when :config
|
68
32
|
Mint::CommandLine.config
|
69
|
-
|
70
33
|
else
|
71
34
|
# If no commands were found, search the PATH for commands prefixed
|
72
35
|
# with mint-. If no matching executables are found, we know we've
|
@@ -82,6 +45,6 @@ else
|
|
82
45
|
commandline_options.delete :verbose
|
83
46
|
commandline_options.delete :simulation
|
84
47
|
|
85
|
-
Mint::CommandLine.mint
|
48
|
+
Mint::CommandLine.mint(ARGV, commandline_options)
|
86
49
|
# end
|
87
50
|
end
|
@@ -2,7 +2,7 @@ template:
|
|
2
2
|
short: t
|
3
3
|
long: template
|
4
4
|
parameter: true
|
5
|
-
description: 'Specify the template (layout + style)
|
5
|
+
description: 'Specify the template (layout + style)'
|
6
6
|
|
7
7
|
layout:
|
8
8
|
short: l
|
@@ -14,19 +14,19 @@ style:
|
|
14
14
|
short: s
|
15
15
|
long: style
|
16
16
|
parameter: true
|
17
|
-
description: 'Specify only the style
|
17
|
+
description: 'Specify only the style'
|
18
18
|
|
19
19
|
root:
|
20
20
|
short: w
|
21
21
|
long: r
|
22
22
|
parameter: true
|
23
|
-
description: 'Specify a root outside the current directory
|
23
|
+
description: 'Specify a root outside the current directory'
|
24
24
|
|
25
25
|
destination:
|
26
26
|
short: d
|
27
27
|
long: destination
|
28
28
|
parameter: true
|
29
|
-
description: 'Specify a destination directory, relative to the root
|
29
|
+
description: 'Specify a destination directory, relative to the root'
|
30
30
|
|
31
31
|
style_destination:
|
32
32
|
short: n
|
@@ -38,35 +38,34 @@ global:
|
|
38
38
|
short: G
|
39
39
|
long: global
|
40
40
|
parameter: false
|
41
|
-
description: 'Specify config changes on a global level
|
41
|
+
description: 'Specify config changes on a global level'
|
42
42
|
|
43
43
|
user:
|
44
44
|
short: U
|
45
45
|
long: user
|
46
46
|
parameter: false
|
47
|
-
description: 'Specify config changes on a user-wide level
|
48
|
-
|
47
|
+
description: 'Specify config changes on a user-wide level'
|
49
48
|
|
50
49
|
local:
|
51
50
|
short: L
|
52
51
|
long: local
|
53
52
|
parameter: false
|
54
|
-
description: 'Specify config changes on a project-specific level
|
53
|
+
description: 'Specify config changes on a project-specific level'
|
55
54
|
|
56
55
|
force:
|
57
56
|
short: f
|
58
57
|
long: force
|
59
58
|
parameter: false
|
60
|
-
description: 'Force file overwrite without prompt
|
59
|
+
description: 'Force file overwrite without prompt'
|
61
60
|
|
62
61
|
verbose:
|
63
62
|
short: v
|
64
63
|
long: verbose
|
65
64
|
parameter: false
|
66
|
-
description: 'Verbose output
|
65
|
+
description: 'Verbose output'
|
67
66
|
|
68
67
|
simulation:
|
69
68
|
short: S
|
70
69
|
long: simulation
|
71
70
|
parameter: false
|
72
|
-
description: 'Simulate transformation without actually creating files
|
71
|
+
description: 'Simulate transformation without actually creating files'
|
data/lib/mint/commandline.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'pathname'
|
2
2
|
require 'yaml'
|
3
|
-
require '
|
3
|
+
require 'optparse'
|
4
4
|
|
5
5
|
module Mint
|
6
6
|
module CommandLine
|
@@ -9,21 +9,48 @@ module Mint
|
|
9
9
|
# the commandline. (All other arguments are taken to be
|
10
10
|
# filenames.)
|
11
11
|
def self.options
|
12
|
-
options_file =
|
12
|
+
options_file = "../../../#{Mint.files[:syntax]}"
|
13
13
|
YAML.load_file File.expand_path(options_file, __FILE__)
|
14
14
|
end
|
15
15
|
|
16
|
-
def self.
|
17
|
-
|
16
|
+
def self.parser(options_metadata=Mint::CommandLine.options)
|
17
|
+
optparse = OptionParser.new do |opts|
|
18
|
+
opts.banner = 'Usage: mint [command] files [options]'
|
19
|
+
|
20
|
+
Helpers.symbolize_keys(options_metadata).each do |k,v|
|
21
|
+
has_param = v[:parameter]
|
22
|
+
|
23
|
+
v[:short] = "-#{v[:short]}"
|
24
|
+
v[:long] = "--#{v[:long]}"
|
25
|
+
|
26
|
+
if has_param
|
27
|
+
v[:long] << " PARAM"
|
28
|
+
opts.on v[:short], v[:long], v[:description] do |p|
|
29
|
+
yield k.to_sym, p
|
30
|
+
end
|
31
|
+
else
|
32
|
+
opts.on v[:short], v[:long], v[:description] do
|
33
|
+
yield k, true
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def self.configuration(file=Mint.files[:config])
|
41
|
+
return nil unless file
|
42
|
+
config_file = Pathname.new file
|
18
43
|
|
19
44
|
# Merge config options from all config files on the Mint path,
|
20
45
|
# where more local options take precedence over more global
|
21
46
|
# options
|
22
|
-
Mint.path.map {|p| p + config_file }.
|
47
|
+
configuration = Mint.path(true).map {|p| p + config_file }.
|
23
48
|
select(&:exist?).
|
24
49
|
map {|p| YAML.load_file p }.
|
25
50
|
reverse.
|
26
51
|
reduce(Mint.default_options) {|r,p| r.merge p }
|
52
|
+
|
53
|
+
Helpers.symbolize_keys configuration
|
27
54
|
end
|
28
55
|
|
29
56
|
def self.configuration_with(opts)
|
@@ -36,23 +63,39 @@ module Mint
|
|
36
63
|
|
37
64
|
# Install the listed file to the scope listed, using
|
38
65
|
# local as the default scope.
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
66
|
+
def self.install(file, commandline_options)
|
67
|
+
commandline_options[:local] = true
|
68
|
+
scope = [:global, :user, :local].
|
69
|
+
select {|e| commandline_options[e] }.
|
70
|
+
first
|
71
|
+
|
72
|
+
directory = path_for_scope(scope)
|
73
|
+
FileUtils.copy file, directory
|
74
|
+
end
|
43
75
|
|
44
76
|
# If we get the edit command, will retrieve appropriate file
|
45
77
|
# (probably a Mint template) and shell out that file to
|
46
78
|
# the user's favorite editor.
|
47
|
-
def self.edit(name,
|
79
|
+
def self.edit(name, commandline_options)
|
80
|
+
layout = commandline_options[:layout]
|
81
|
+
style = commandline_options[:style]
|
82
|
+
|
83
|
+
if layout and not style
|
84
|
+
layout_or_style = :layout
|
85
|
+
elsif style
|
86
|
+
layout_or_style = :style
|
87
|
+
else
|
88
|
+
puts optparse.help
|
89
|
+
end
|
90
|
+
|
48
91
|
file = Mint.lookup_template name, layout_or_style
|
49
92
|
|
50
|
-
editor = ENV['EDITOR'] || '
|
93
|
+
editor = ENV['EDITOR'] || 'vi'
|
51
94
|
system "#{editor} #{file}"
|
52
95
|
end
|
53
96
|
|
54
97
|
def self.configure(opts, scope=:local)
|
55
|
-
config_directory = Mint.path_for_scope
|
98
|
+
config_directory = Mint.path_for_scope(scope, true)
|
56
99
|
config_file = config_directory + Mint.files[:config]
|
57
100
|
Helpers.ensure_directory config_directory
|
58
101
|
Helpers.update_yaml opts, config_file
|
@@ -60,7 +103,12 @@ module Mint
|
|
60
103
|
|
61
104
|
# Try to set a config option (at the specified scope) per
|
62
105
|
# the user's command.
|
63
|
-
def self.set(key, value,
|
106
|
+
def self.set(key, value, commandline_options)
|
107
|
+
commandline_options[:local] = true
|
108
|
+
scope = [:global, :user, :local].
|
109
|
+
select {|e| commandline_options[e] }.
|
110
|
+
first
|
111
|
+
|
64
112
|
configure({ key => value }, scope)
|
65
113
|
end
|
66
114
|
|
@@ -80,13 +128,13 @@ module Mint
|
|
80
128
|
documents = []
|
81
129
|
options = configuration_with commandline_options
|
82
130
|
|
83
|
-
|
131
|
+
options[:root] ||= Dir.getwd
|
84
132
|
|
85
133
|
# Eventually render_style should be replaced with file
|
86
134
|
# change detection
|
87
135
|
render_style = true
|
88
136
|
files.each do |file|
|
89
|
-
Document.new(file, options).mint(
|
137
|
+
Document.new(file, options).mint(render_style)
|
90
138
|
render_style = false
|
91
139
|
end
|
92
140
|
end
|
data/lib/mint/document.rb
CHANGED
@@ -53,8 +53,10 @@ module Mint
|
|
53
53
|
# I'm going to maintain a document's official style_destination
|
54
54
|
# outside of its style object. If a document has no
|
55
55
|
# style_destination defined when it needs one, the document will
|
56
|
-
# use the style's source directory. This
|
57
|
-
#
|
56
|
+
# use the style's source directory. This happens lazily via
|
57
|
+
# virtual attributes like #style_destination_file, etc.
|
58
|
+
# This eliminates edge cases (like styles we don't want to move
|
59
|
+
# anywhere) nicely and lets us maintain document-specific information
|
58
60
|
# separately. (Without this separation, funky things happen when
|
59
61
|
# you assign a new style template to an existing document -- if
|
60
62
|
# you had specified a custom style_destination before changing
|
@@ -65,6 +67,29 @@ module Mint
|
|
65
67
|
@style_destination = style_destination
|
66
68
|
end
|
67
69
|
|
70
|
+
def style_destination_file_path
|
71
|
+
if style_destination
|
72
|
+
path = Pathname.new style_destination
|
73
|
+
dir = path.absolute? ?
|
74
|
+
path : destination_directory_path + path
|
75
|
+
dir + style.name
|
76
|
+
else
|
77
|
+
style.destination_file_path
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
def style_destination_file
|
82
|
+
style_destination_file_path.to_s
|
83
|
+
end
|
84
|
+
|
85
|
+
def style_destination_directory_path
|
86
|
+
style_destination_file_path.dirname
|
87
|
+
end
|
88
|
+
|
89
|
+
def style_destination_directory
|
90
|
+
style_destination_directory_path.to_s
|
91
|
+
end
|
92
|
+
|
68
93
|
def template=(template)
|
69
94
|
if template
|
70
95
|
self.layout = template
|
@@ -74,7 +99,11 @@ module Mint
|
|
74
99
|
|
75
100
|
def initialize(source, opts={})
|
76
101
|
options = Mint.default_options.merge opts
|
77
|
-
|
102
|
+
|
103
|
+
# Loads source and destination, which will be used for
|
104
|
+
# all source_* and destination_* virtual attributes.
|
105
|
+
super(source, options)
|
106
|
+
self.type = :document
|
78
107
|
|
79
108
|
# Each of these should invoke explicitly defined method
|
80
109
|
self.content = source
|
@@ -85,38 +114,32 @@ module Mint
|
|
85
114
|
# The template option will override layout and style choices
|
86
115
|
self.template = options[:template]
|
87
116
|
|
117
|
+
# Yield self to block after all other parameters are loaded,
|
118
|
+
# so we only have to tweak. (We don't have to give up our
|
119
|
+
# defaults or re-test blocks beyond them being tweaked.)
|
88
120
|
yield self if block_given?
|
89
121
|
end
|
90
122
|
|
123
|
+
# Render content in the context of layout
|
91
124
|
def render(args={})
|
92
125
|
layout.render self, args
|
93
126
|
end
|
94
127
|
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
# not raw, browser-parseable CSS).
|
101
|
-
render_style &&= style.need_rendering?
|
102
|
-
|
103
|
-
document_file = root + (self.destination || '') + self.name
|
104
|
-
FileUtils.mkdir_p document_file.dirname
|
105
|
-
document_file.open 'w+' do |f|
|
128
|
+
# Write all rendered content where a) possible, b) required,
|
129
|
+
# and c) specified
|
130
|
+
def publish!(render_style=true)
|
131
|
+
FileUtils.mkdir_p self.destination_directory
|
132
|
+
File.open(self.destination_file, 'w+') do |f|
|
106
133
|
f << self.render
|
107
134
|
end
|
108
135
|
|
136
|
+
# Only render style if a) it's specified by the options path and
|
137
|
+
# b) it actually needs rendering (i.e., it's in template form and
|
138
|
+
# not raw, browser-parseable CSS) or it if it doesn't need
|
139
|
+
# rendering but there is an explicit style_destination.
|
109
140
|
if render_style
|
110
|
-
|
111
|
-
|
112
|
-
root + self.destination + style_destination
|
113
|
-
else
|
114
|
-
self.style.destination
|
115
|
-
end
|
116
|
-
style_file = style_dest + self.style.name
|
117
|
-
FileUtils.mkdir_p style_file.dirname
|
118
|
-
|
119
|
-
style_file.open 'w+' do |f|
|
141
|
+
FileUtils.mkdir_p style_destination_directory
|
142
|
+
File.open(self.style_destination_file, 'w+') do |f|
|
120
143
|
f << self.style.render
|
121
144
|
end
|
122
145
|
end
|
@@ -127,10 +150,7 @@ module Mint
|
|
127
150
|
# Returns a relative path from the document to its stylesheet. Can
|
128
151
|
# be called directly from inside a layout template.
|
129
152
|
def stylesheet
|
130
|
-
|
131
|
-
destination = self.destination || ''
|
132
|
-
Helpers.normalize_path(style_dest, destination) +
|
133
|
-
style.name.to_s
|
153
|
+
self.destination_file_path.relative_path_from(self.style_destination_file_path).to_s
|
134
154
|
end
|
135
155
|
end
|
136
156
|
end
|
data/lib/mint/helpers.rb
CHANGED
@@ -1,5 +1,4 @@
|
|
1
1
|
require 'pathname'
|
2
|
-
require 'fileutils'
|
3
2
|
require 'yaml'
|
4
3
|
|
5
4
|
module Mint
|
@@ -7,9 +6,9 @@ module Mint
|
|
7
6
|
def self.slugize(obj)
|
8
7
|
obj.to_s.downcase.
|
9
8
|
gsub(/&/, 'and').
|
10
|
-
gsub(
|
11
|
-
gsub(
|
12
|
-
gsub(/[
|
9
|
+
gsub(/[\s-]+/, '-').
|
10
|
+
gsub(/[^a-z0-9-]/, '').
|
11
|
+
gsub(/[-]+/, '-')
|
13
12
|
end
|
14
13
|
|
15
14
|
def self.symbolize(obj)
|
@@ -25,14 +24,26 @@ module Mint
|
|
25
24
|
end.expand_path
|
26
25
|
end
|
27
26
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
27
|
+
def self.symbolize_keys(map)
|
28
|
+
map.reduce(Hash.new) do |syms,(k,v)|
|
29
|
+
syms[k.to_sym] =
|
30
|
+
case v
|
31
|
+
when Hash
|
32
|
+
self.symbolize_keys(v)
|
33
|
+
else
|
34
|
+
v
|
35
|
+
end
|
36
|
+
syms
|
37
|
+
end
|
32
38
|
end
|
33
39
|
|
34
|
-
|
35
|
-
|
40
|
+
# Returns the relative path to dir1 from dir2. If dir1 and dir2
|
41
|
+
# have no directories in common besides /, will return the
|
42
|
+
# absolute directory of dir1. Right now, assumes no symlinks
|
43
|
+
def self.normalize_path(dir1, dir2)
|
44
|
+
path1, path2 = [dir1, dir2].map {|d| pathize d }
|
45
|
+
root1, root2 = [path1, path2].map {|p| p.each_filename.first }
|
46
|
+
root1 == root2 ? path1.relative_path_from(path2) : path1
|
36
47
|
end
|
37
48
|
|
38
49
|
def self.update_yaml(new_opts, file)
|
data/lib/mint/layout.rb
CHANGED