mint 0.5.1 → 0.7.1
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +18 -0
- data/README.md +3 -3
- data/bin/mint +27 -27
- data/bin/mint-epub +6 -6
- data/config/syntax.yaml +12 -12
- data/{templates → config/templates}/base/style.sass +11 -4
- data/config/templates/default/css/style.css +158 -0
- data/config/templates/default/layout.haml +8 -0
- data/{templates → config/templates}/default/style.sass +0 -0
- data/{templates/default → config/templates/protocol}/layout.haml +0 -0
- data/config/templates/protocol/style.sass +20 -0
- data/config/templates/reset.css +92 -0
- data/config/templates/zen/css/style.css +145 -0
- data/{templates/pro → config/templates/zen}/layout.haml +0 -0
- data/config/templates/zen/style.sass +24 -0
- data/features/config.feature +21 -0
- data/features/publish.feature +3 -3
- data/features/support/env.rb +9 -27
- data/features/templates.feature +79 -0
- data/lib/mint.rb +11 -11
- data/lib/mint/{commandline.rb → command_line.rb} +96 -80
- data/lib/mint/css.rb +43 -34
- data/lib/mint/document.rb +99 -93
- data/lib/mint/helpers.rb +21 -17
- data/lib/mint/layout.rb +1 -1
- data/lib/mint/mint.rb +92 -36
- data/lib/mint/plugin.rb +5 -5
- data/lib/mint/plugins/epub.rb +51 -51
- data/lib/mint/resource.rb +2 -2
- data/lib/mint/style.rb +2 -2
- data/lib/mint/version.rb +1 -1
- data/spec/command_line_spec.rb +87 -0
- data/spec/css_spec.rb +46 -0
- data/spec/document_spec.rb +38 -40
- data/spec/helpers_spec.rb +101 -83
- data/spec/layout_spec.rb +1 -1
- data/spec/mint_spec.rb +184 -60
- data/spec/plugin_spec.rb +61 -67
- data/spec/plugins/epub_spec.rb +47 -47
- data/spec/resource_spec.rb +9 -9
- data/spec/spec_helper.rb +20 -93
- data/spec/style_spec.rb +6 -8
- data/spec/support/fixtures/content.md +16 -0
- data/spec/support/fixtures/dynamic.sass +3 -0
- data/spec/support/fixtures/layout.haml +3 -0
- data/spec/support/fixtures/static.css +3 -0
- data/spec/support/matchers.rb +15 -0
- metadata +160 -70
- data/spec/commandline_spec.rb +0 -91
- data/templates/pro/style.sass +0 -0
data/lib/mint.rb
CHANGED
@@ -1,11 +1,11 @@
|
|
1
|
-
require
|
2
|
-
require
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
6
|
-
require
|
7
|
-
require
|
8
|
-
require
|
9
|
-
require
|
10
|
-
require
|
11
|
-
require
|
1
|
+
require "mint/helpers"
|
2
|
+
require "mint/mint"
|
3
|
+
require "mint/resource"
|
4
|
+
require "mint/layout"
|
5
|
+
require "mint/style"
|
6
|
+
require "mint/document"
|
7
|
+
require "mint/version"
|
8
|
+
require "mint/css"
|
9
|
+
require "mint/command_line"
|
10
|
+
require "mint/exceptions"
|
11
|
+
require "mint/plugin"
|
@@ -1,6 +1,9 @@
|
|
1
|
-
require
|
2
|
-
require
|
3
|
-
require
|
1
|
+
require "pathname"
|
2
|
+
require "yaml"
|
3
|
+
require "optparse"
|
4
|
+
require "fileutils"
|
5
|
+
|
6
|
+
require "active_support/core_ext/object/blank"
|
4
7
|
|
5
8
|
module Mint
|
6
9
|
module CommandLine
|
@@ -14,22 +17,24 @@ module Mint
|
|
14
17
|
# @return [Hash] a structured set of options that the commandline
|
15
18
|
# executable accepts
|
16
19
|
def self.options
|
17
|
-
options_file = "
|
20
|
+
options_file = "../../../config/#{Mint.files[:syntax]}"
|
18
21
|
YAML.load_file File.expand_path(options_file, __FILE__)
|
19
22
|
end
|
20
23
|
|
21
|
-
#
|
22
|
-
# a key/value pair to a block. If the option does not take a param, the value
|
23
|
-
# will be specified as true.
|
24
|
+
# Parses ARGV according to the specified or default commandline syntax
|
24
25
|
#
|
25
|
-
# @param [
|
26
|
-
#
|
27
|
-
# @return [
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
26
|
+
# @param [Array] argv a list of arguments to parse
|
27
|
+
# @param [Hash] opts default parsing options (to specify syntax file)
|
28
|
+
# @return [Hash] an object that contains parsed options, remaining arguments,
|
29
|
+
# and a help message
|
30
|
+
def self.parse(argv, opts={})
|
31
|
+
opts = { syntax: options }.merge(opts)
|
32
|
+
parsed_options = {}
|
33
|
+
|
34
|
+
parser = OptionParser.new do |cli|
|
35
|
+
cli.banner = "Usage: mint [command] files [options]"
|
36
|
+
|
37
|
+
Helpers.symbolize_keys(opts[:syntax]).each do |k,v|
|
33
38
|
has_param = v[:parameter]
|
34
39
|
|
35
40
|
v[:short] = "-#{v[:short]}"
|
@@ -37,49 +42,20 @@ module Mint
|
|
37
42
|
|
38
43
|
if has_param
|
39
44
|
v[:long] << " PARAM"
|
40
|
-
|
41
|
-
|
45
|
+
cli.on v[:short], v[:long], v[:description] do |p|
|
46
|
+
parsed_options[k.to_sym] = p
|
42
47
|
end
|
43
48
|
else
|
44
|
-
|
45
|
-
|
49
|
+
cli.on v[:short], v[:long], v[:description] do
|
50
|
+
parsed_options[k.to_sym] = true
|
46
51
|
end
|
47
52
|
end
|
48
53
|
end
|
49
54
|
end
|
50
|
-
end
|
51
|
-
|
52
|
-
# Returns a hash of all active options specified by file (for all scopes).
|
53
|
-
# That is, if you specify file as 'config.yaml', this will return the aggregate
|
54
|
-
# of all config.yaml-specified options in the Mint path, where more local
|
55
|
-
# members of the path take precedence over more global ones.
|
56
|
-
#
|
57
|
-
# @param [String] file a filename pointing to a Mint configuration file
|
58
|
-
# @return [Hash] a structured set of configuration options
|
59
|
-
def self.configuration(file=Mint.files[:config])
|
60
|
-
return nil unless file
|
61
|
-
config_file = Pathname.new file
|
62
|
-
|
63
|
-
# Merge config options from all config files on the Mint path,
|
64
|
-
# where more local options take precedence over more global
|
65
|
-
# options
|
66
|
-
configuration = Mint.path(true).map {|p| p + config_file }.
|
67
|
-
select(&:exist?).
|
68
|
-
map {|p| YAML.load_file p }.
|
69
|
-
reverse.
|
70
|
-
reduce(Mint.default_options) {|r,p| r.merge p }
|
71
|
-
|
72
|
-
Helpers.symbolize_keys configuration
|
73
|
-
end
|
74
55
|
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
# @param [Hash] additional options to add to the current configuration
|
79
|
-
# @return [Hash] a structured set of configuration options with opts
|
80
|
-
# overriding any options from config files
|
81
|
-
def self.configuration_with(opts)
|
82
|
-
configuration.merge opts
|
56
|
+
transient_argv = argv.dup
|
57
|
+
parser.parse! transient_argv
|
58
|
+
{ argv: transient_argv, options: parsed_options, help: parser.help }
|
83
59
|
end
|
84
60
|
|
85
61
|
# Mint built-in commands
|
@@ -92,19 +68,64 @@ module Mint
|
|
92
68
|
puts message
|
93
69
|
end
|
94
70
|
|
71
|
+
# Install the named file as a template
|
72
|
+
#
|
95
73
|
# @param [File] file the file to install to the appropriate Mint directory
|
96
74
|
# @param [Hash] commandline_options a structured set of options, including
|
97
75
|
# a scope label that the method will use to choose the appropriate
|
98
76
|
# installation directory
|
99
77
|
# @return [void]
|
100
78
|
def self.install(file, commandline_options={})
|
101
|
-
|
102
|
-
scope = [:global, :user
|
79
|
+
opts = { scope: :local }.merge(commandline_options)
|
80
|
+
scope = [:global, :user].
|
103
81
|
select {|e| commandline_options[e] }.
|
104
|
-
first
|
82
|
+
first || :local
|
83
|
+
|
84
|
+
filename, ext = file.split "."
|
85
|
+
|
86
|
+
name = commandline_options[:template] || filename
|
87
|
+
type = Mint.css_formats.include?(ext) ? :style : :layout
|
88
|
+
destination = Mint.template_path(name, type, :scope => opts[:scope], :ext => ext)
|
89
|
+
FileUtils.mkdir_p File.expand_path("#{destination}/..")
|
105
90
|
|
106
|
-
|
107
|
-
|
91
|
+
puts "reading file"
|
92
|
+
puts File.read file
|
93
|
+
|
94
|
+
if File.exist? file
|
95
|
+
FileUtils.cp file, destination
|
96
|
+
else
|
97
|
+
raise "[error] no such file"
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
# Uninstall the named template
|
102
|
+
#
|
103
|
+
# @param [String] name the name of the template to be uninstalled
|
104
|
+
# @param [Hash] commandline_options a structured set of options, including
|
105
|
+
# a scope label that the method will use to choose the appropriate
|
106
|
+
# installation directory
|
107
|
+
# @return [void]
|
108
|
+
def self.uninstall(name, commandline_options={})
|
109
|
+
opts = { scope: :local }.merge(commandline_options)
|
110
|
+
FileUtils.rm_r Mint.template_path(name, :all, :scope => opts[:scope])
|
111
|
+
end
|
112
|
+
|
113
|
+
# List the installed templates
|
114
|
+
#
|
115
|
+
# @return [void]
|
116
|
+
def self.templates(filter=nil, commandline_options={})
|
117
|
+
scopes = Mint::SCOPE_NAMES.select do |s|
|
118
|
+
commandline_options[s]
|
119
|
+
end.presence || Mint::SCOPE_NAMES
|
120
|
+
|
121
|
+
Mint.templates(:scopes => scopes).
|
122
|
+
grep(Regexp.new(filter || "")).
|
123
|
+
sort.
|
124
|
+
each do |template|
|
125
|
+
print File.basename template
|
126
|
+
print " [#{template}]" if commandline_options[:verbose]
|
127
|
+
puts
|
128
|
+
end
|
108
129
|
end
|
109
130
|
|
110
131
|
# Retrieve named template file (probably a built-in or installed
|
@@ -115,21 +136,25 @@ module Mint
|
|
115
136
|
# a layout or style flag that the method will use to choose the appropriate
|
116
137
|
# file to edit
|
117
138
|
# @return [void]
|
118
|
-
def self.edit(name, commandline_options)
|
139
|
+
def self.edit(name, commandline_options={})
|
119
140
|
layout = commandline_options[:layout]
|
120
141
|
style = commandline_options[:style]
|
121
142
|
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
layout_or_style = :style
|
143
|
+
# Allow for convenient editing (edit "default" works just as well
|
144
|
+
# as edit :style => "default")
|
145
|
+
if style
|
146
|
+
name, layout_or_style = style, :style
|
147
|
+
elsif layout
|
148
|
+
name, layout_or_style = layout, :layout
|
126
149
|
else
|
127
|
-
|
150
|
+
layout_or_style = :style
|
128
151
|
end
|
129
152
|
|
153
|
+
abort "[error] no template specified" if name.nil? || name.empty?
|
154
|
+
|
130
155
|
file = Mint.lookup_template name, layout_or_style
|
131
156
|
|
132
|
-
editor = ENV[
|
157
|
+
editor = ENV["EDITOR"] || "vi"
|
133
158
|
system "#{editor} #{file}"
|
134
159
|
end
|
135
160
|
|
@@ -142,9 +167,8 @@ module Mint
|
|
142
167
|
# @return [void]
|
143
168
|
def self.configure(opts, scope=:local)
|
144
169
|
config_directory = Mint.path_for_scope(scope, true)
|
145
|
-
|
146
|
-
Helpers.
|
147
|
-
Helpers.update_yaml! opts, config_file
|
170
|
+
FileUtils.mkdir_p config_directory
|
171
|
+
Helpers.update_yaml! "#{config_directory}/#{Mint.files[:defaults]}", opts
|
148
172
|
end
|
149
173
|
|
150
174
|
# Tries to set a config option (at the specified scope) per
|
@@ -156,7 +180,7 @@ module Mint
|
|
156
180
|
# a scope label that the method will use to choose the appropriate
|
157
181
|
# scope
|
158
182
|
# @return [void]
|
159
|
-
def self.set(key, value, commandline_options)
|
183
|
+
def self.set(key, value, commandline_options={})
|
160
184
|
commandline_options[:local] = true
|
161
185
|
scope = [:global, :user, :local].
|
162
186
|
select {|e| commandline_options[e] }.
|
@@ -170,7 +194,7 @@ module Mint
|
|
170
194
|
#
|
171
195
|
# @return [void]
|
172
196
|
def self.config
|
173
|
-
puts YAML.dump(configuration)
|
197
|
+
puts YAML.dump(Mint.configuration)
|
174
198
|
end
|
175
199
|
|
176
200
|
# Renders and writes to file all resources described by a document.
|
@@ -184,18 +208,10 @@ module Mint
|
|
184
208
|
# @param [Hash, #[]] commandline_options a structured set of configuration options
|
185
209
|
# that will guide Mint.publish!
|
186
210
|
# @return [void]
|
187
|
-
def self.publish!(files, commandline_options)
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
options[:root] ||= Dir.getwd
|
192
|
-
|
193
|
-
# Eventually render_style should be replaced with file
|
194
|
-
# change detection
|
195
|
-
render_style = true
|
196
|
-
files.each do |file|
|
197
|
-
Document.new(file, options).publish! :render_style => render_style
|
198
|
-
render_style = false
|
211
|
+
def self.publish!(files, commandline_options={})
|
212
|
+
options = { root: Dir.getwd }.merge(Mint.configuration_with commandline_options)
|
213
|
+
files.each_with_index do |file, idx|
|
214
|
+
Document.new(file, options).publish!(:render_style => (idx == 0))
|
199
215
|
end
|
200
216
|
end
|
201
217
|
end
|
data/lib/mint/css.rb
CHANGED
@@ -1,61 +1,70 @@
|
|
1
|
+
require "sass"
|
2
|
+
|
1
3
|
module Mint
|
2
4
|
module CSS
|
3
|
-
def container
|
4
|
-
|
5
|
+
def self.container
|
6
|
+
"container"
|
5
7
|
end
|
6
8
|
|
7
|
-
# Maps a "DSL" onto actual CSS.
|
8
|
-
# the plan is to translate this ...
|
9
|
+
# Maps a "DSL" onto actual CSS. Translates this ...
|
9
10
|
#
|
10
11
|
# ---
|
11
12
|
# Font: Helvetica
|
12
|
-
# Margin:
|
13
|
-
#
|
13
|
+
# Margin: 1in
|
14
|
+
# Orientation: Landscape
|
14
15
|
#
|
15
16
|
# ... into something like:
|
16
17
|
#
|
17
18
|
# #container {
|
18
|
-
# font:
|
19
|
-
# padding-left:
|
20
|
-
#
|
21
|
-
# p { line-height: (value specified and cleaned up) }
|
19
|
+
# font-family: Helvetica;
|
20
|
+
# padding-left: 1in;
|
21
|
+
# @page { size: landscape };
|
22
22
|
# }
|
23
|
-
def mappings
|
23
|
+
def self.mappings
|
24
24
|
{
|
25
|
-
font:
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
bottom:
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
25
|
+
font: "font-family",
|
26
|
+
font_size: "font-size",
|
27
|
+
font_color: "color",
|
28
|
+
color: "color",
|
29
|
+
top_margin: "padding-top",
|
30
|
+
top: "padding-top",
|
31
|
+
bottom_margin: "padding-bottom",
|
32
|
+
bottom: "padding-bottom",
|
33
|
+
left_margin: "padding-left",
|
34
|
+
left: "padding-left",
|
35
|
+
right_margin: "padding-right",
|
36
|
+
right: "padding-right",
|
37
|
+
height: "height",
|
38
|
+
width: "width",
|
39
|
+
columns: "column-count",
|
40
|
+
column_gap: "column-gap",
|
41
|
+
orientation: "@page { size: %s }",
|
42
|
+
indentation: "p+p { text-indent: %s }",
|
43
|
+
indent: "p+p { text-indent: %s }",
|
44
|
+
bullet: "li { list-style-type: %s }",
|
45
|
+
bullet_image: "li { list-style-image: url(%s) }",
|
46
|
+
after_paragraph: "margin-bottom",
|
47
|
+
before_paragraph: "margin-top"
|
43
48
|
}
|
44
49
|
end
|
45
50
|
|
46
|
-
def
|
51
|
+
def self.stylify(key, value)
|
47
52
|
selector = mappings[Helpers.symbolize key]
|
48
53
|
|
49
|
-
if selector.
|
54
|
+
if selector.nil?
|
55
|
+
""
|
56
|
+
elsif selector.include? "%"
|
50
57
|
selector % value
|
51
58
|
else
|
52
59
|
"#{selector || key}: #{value}"
|
53
60
|
end
|
54
61
|
end
|
55
62
|
|
56
|
-
def parse(style)
|
57
|
-
css = style.map {|k,v|
|
58
|
-
"##{container}
|
63
|
+
def self.parse(style)
|
64
|
+
css = style.map {|k,v| stylify(k, v) }.join("\n ")
|
65
|
+
container_scope = "##{container}\n #{css.strip}\n"
|
66
|
+
engine = Sass::Engine.new(container_scope)
|
67
|
+
engine.silence_sass_warnings { engine.render }
|
59
68
|
end
|
60
69
|
end
|
61
70
|
end
|
data/lib/mint/document.rb
CHANGED
@@ -1,15 +1,69 @@
|
|
1
|
-
require
|
2
|
-
require
|
3
|
-
require
|
1
|
+
require "mint/resource"
|
2
|
+
require "mint/layout"
|
3
|
+
require "mint/style"
|
4
4
|
|
5
5
|
module Mint
|
6
6
|
class Document < Resource
|
7
7
|
METADATA_DELIM = "\n\n"
|
8
8
|
|
9
|
+
# Creates a new Mint Document object. Can be block initialized.
|
10
|
+
# Accepts source and options. Block initialization occurs after
|
11
|
+
# all defaults are set, so not all options must be specified.
|
12
|
+
def initialize(source, opts={})
|
13
|
+
options = Mint.default_options.merge opts
|
14
|
+
|
15
|
+
# Loads source and destination, which will be used for
|
16
|
+
# all source_* and destination_* virtual attributes.
|
17
|
+
super(source, options)
|
18
|
+
self.type = :document
|
19
|
+
|
20
|
+
# Each of these should invoke explicitly defined method
|
21
|
+
self.content = source
|
22
|
+
self.layout = options[:layout]
|
23
|
+
self.style = options[:style]
|
24
|
+
self.style_destination = options[:style_destination]
|
25
|
+
|
26
|
+
# The template option will override layout and style choices
|
27
|
+
self.template = options[:template]
|
28
|
+
|
29
|
+
# Yield self to block after all other parameters are loaded,
|
30
|
+
# so we only have to tweak. (We don't have to give up our
|
31
|
+
# defaults or re-test blocks beyond them being tweaked.)
|
32
|
+
yield self if block_given?
|
33
|
+
end
|
34
|
+
|
35
|
+
# Renders content in the context of layout and returns as a String.
|
36
|
+
def render(args={})
|
37
|
+
intermediate_content = layout.render self, args
|
38
|
+
Mint.after_render(intermediate_content)
|
39
|
+
end
|
40
|
+
|
41
|
+
# Writes all rendered content where a) possible, b) required,
|
42
|
+
# and c) specified. Outputs to specified file.
|
43
|
+
def publish!(opts={})
|
44
|
+
options = { :render_style => true }.merge(opts)
|
45
|
+
FileUtils.mkdir_p self.destination_directory
|
46
|
+
File.open(self.destination_file, "w+") do |f|
|
47
|
+
f << self.render
|
48
|
+
end
|
49
|
+
|
50
|
+
# Only renders style if a) it's specified by the options path and
|
51
|
+
# b) it actually needs rendering (i.e., it's in template form and
|
52
|
+
# not raw, browser-parseable CSS) or it if it doesn't need
|
53
|
+
# rendering but there is an explicit style_destination.
|
54
|
+
if options[:render_style]
|
55
|
+
FileUtils.mkdir_p style_destination_directory
|
56
|
+
File.open(self.style_destination_file, "w+") do |f|
|
57
|
+
f << self.style.render
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
Mint.after_publish(self, opts)
|
62
|
+
end
|
63
|
+
|
9
64
|
# Implicit readers are paired with explicit accessors. This
|
10
65
|
# allows for processing variables before storing them.
|
11
|
-
attr_reader :content, :layout, :style
|
12
|
-
attr_accessor :metadata
|
66
|
+
attr_reader :content, :metadata, :layout, :style
|
13
67
|
|
14
68
|
# Passes content through a renderer before assigning it to be
|
15
69
|
# the Document's content
|
@@ -21,11 +75,12 @@ module Mint
|
|
21
75
|
tempfile = Helpers.generate_temp_file! content
|
22
76
|
original_content = File.read content
|
23
77
|
|
24
|
-
metadata, text = Document.parse_metadata_from original_content
|
25
|
-
self.metadata = metadata
|
78
|
+
@metadata, text = Document.parse_metadata_from original_content
|
26
79
|
intermediate_content = Mint.before_render text
|
27
80
|
|
28
|
-
File.open(tempfile,
|
81
|
+
File.open(tempfile, "w") do |file|
|
82
|
+
file << intermediate_content
|
83
|
+
end
|
29
84
|
|
30
85
|
@renderer = Mint.renderer tempfile
|
31
86
|
@content = @renderer.render
|
@@ -65,6 +120,17 @@ module Mint
|
|
65
120
|
abort "Template '#{style}' does not exist."
|
66
121
|
end
|
67
122
|
|
123
|
+
# Overrides layout and style settings with named template.
|
124
|
+
#
|
125
|
+
# @param [String] template the name of the template to set as
|
126
|
+
# layout and string
|
127
|
+
def template=(template)
|
128
|
+
if template
|
129
|
+
self.layout = template
|
130
|
+
self.style = template
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
68
134
|
# Explanation of style_destination:
|
69
135
|
#
|
70
136
|
# I'm going to maintain a document's official style_destination
|
@@ -126,72 +192,6 @@ module Mint
|
|
126
192
|
style_destination_directory_path.to_s
|
127
193
|
end
|
128
194
|
|
129
|
-
# Overrides layout and style settings with named template.
|
130
|
-
#
|
131
|
-
# @param [String] template the name of the template to set as
|
132
|
-
# layout and string
|
133
|
-
def template=(template)
|
134
|
-
if template
|
135
|
-
self.layout = template
|
136
|
-
self.style = template
|
137
|
-
end
|
138
|
-
end
|
139
|
-
|
140
|
-
# Creates a new Mint Document object. Can be block initialized.
|
141
|
-
# Accepts source and options. Block initialization occurs after
|
142
|
-
# all defaults are set, so not all options must be specified.
|
143
|
-
def initialize(source, opts={})
|
144
|
-
options = Mint.default_options.merge opts
|
145
|
-
|
146
|
-
# Loads source and destination, which will be used for
|
147
|
-
# all source_* and destination_* virtual attributes.
|
148
|
-
super(source, options)
|
149
|
-
self.type = :document
|
150
|
-
|
151
|
-
# Each of these should invoke explicitly defined method
|
152
|
-
self.content = source
|
153
|
-
self.layout = options[:layout]
|
154
|
-
self.style = options[:style]
|
155
|
-
self.style_destination = options[:style_destination]
|
156
|
-
|
157
|
-
# The template option will override layout and style choices
|
158
|
-
self.template = options[:template]
|
159
|
-
|
160
|
-
# Yield self to block after all other parameters are loaded,
|
161
|
-
# so we only have to tweak. (We don't have to give up our
|
162
|
-
# defaults or re-test blocks beyond them being tweaked.)
|
163
|
-
yield self if block_given?
|
164
|
-
end
|
165
|
-
|
166
|
-
# Renders content in the context of layout and returns as a String.
|
167
|
-
def render(args={})
|
168
|
-
intermediate_content = layout.render self, args
|
169
|
-
Mint.after_render(intermediate_content)
|
170
|
-
end
|
171
|
-
|
172
|
-
# Writes all rendered content where a) possible, b) required,
|
173
|
-
# and c) specified. Outputs to specified file.
|
174
|
-
def publish!(opts={})
|
175
|
-
options = { :render_style => true }.merge(opts)
|
176
|
-
FileUtils.mkdir_p self.destination_directory
|
177
|
-
File.open(self.destination_file, 'w+') do |f|
|
178
|
-
f << self.render
|
179
|
-
end
|
180
|
-
|
181
|
-
# Only renders style if a) it's specified by the options path and
|
182
|
-
# b) it actually needs rendering (i.e., it's in template form and
|
183
|
-
# not raw, browser-parseable CSS) or it if it doesn't need
|
184
|
-
# rendering but there is an explicit style_destination.
|
185
|
-
if options[:render_style]
|
186
|
-
FileUtils.mkdir_p style_destination_directory
|
187
|
-
File.open(self.style_destination_file, 'w+') do |f|
|
188
|
-
f << self.style.render
|
189
|
-
end
|
190
|
-
end
|
191
|
-
|
192
|
-
Mint.after_publish(self, opts)
|
193
|
-
end
|
194
|
-
|
195
195
|
# Convenience methods for views
|
196
196
|
|
197
197
|
# Returns a relative path from the document to its stylesheet. Can
|
@@ -201,29 +201,35 @@ module Mint
|
|
201
201
|
self.destination_directory).to_s
|
202
202
|
end
|
203
203
|
|
204
|
-
|
205
|
-
|
206
|
-
def self.metadata_chunk(text)
|
207
|
-
text.split(METADATA_DELIM).first
|
204
|
+
def inline_styles
|
205
|
+
CSS.parse(metadata)
|
208
206
|
end
|
209
207
|
|
210
|
-
|
211
|
-
raw_metadata = YAML.load metadata_chunk(text)
|
212
|
-
raw_metadata.is_a?(String) ? {} : raw_metadata
|
213
|
-
rescue
|
214
|
-
{}
|
215
|
-
end
|
208
|
+
# Functions
|
216
209
|
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
text.sub metadata_chunk(text) + METADATA_DELIM, ''
|
222
|
-
else
|
223
|
-
text
|
224
|
-
end
|
210
|
+
class << self
|
211
|
+
def metadata_chunk(text)
|
212
|
+
text.split(METADATA_DELIM).first
|
213
|
+
end
|
225
214
|
|
226
|
-
|
215
|
+
def metadata_from(text)
|
216
|
+
raw_metadata = YAML.load metadata_chunk(text)
|
217
|
+
raw_metadata.is_a?(String) ? {} : raw_metadata
|
218
|
+
rescue
|
219
|
+
{}
|
220
|
+
end
|
221
|
+
|
222
|
+
def parse_metadata_from(text)
|
223
|
+
metadata = metadata_from text
|
224
|
+
new_text =
|
225
|
+
if !metadata.empty?
|
226
|
+
text.sub metadata_chunk(text) + METADATA_DELIM, ""
|
227
|
+
else
|
228
|
+
text
|
229
|
+
end
|
230
|
+
|
231
|
+
[metadata, new_text]
|
232
|
+
end
|
227
233
|
end
|
228
234
|
end
|
229
235
|
end
|