mint 0.7.4 → 0.8.0
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.
- checksums.yaml +7 -0
- data/Gemfile +23 -14
- data/LICENSE +22 -0
- data/README.md +82 -56
- data/bin/mint +47 -10
- data/bin/mint-epub +1 -4
- data/config/templates/base/style.css +187 -0
- data/config/templates/default/css/style.css +126 -79
- data/config/templates/default/layout.erb +10 -0
- data/config/templates/default/style.css +237 -0
- data/config/templates/garden/layout.erb +38 -0
- data/config/templates/garden/style.css +303 -0
- data/config/templates/newspaper/layout.erb +16 -0
- data/config/templates/nord/layout.erb +11 -0
- data/config/templates/nord/style.css +339 -0
- data/config/templates/nord-dark/layout.erb +11 -0
- data/config/templates/nord-dark/style.css +339 -0
- data/config/templates/protocol/layout.erb +9 -0
- data/config/templates/protocol/style.css +25 -0
- data/config/templates/zen/layout.erb +11 -0
- data/config/templates/zen/style.css +114 -0
- data/lib/mint/command_line.rb +253 -111
- data/lib/mint/css.rb +11 -4
- data/lib/mint/css_template.rb +37 -0
- data/lib/mint/document.rb +185 -43
- data/lib/mint/helpers.rb +50 -10
- data/lib/mint/layout.rb +2 -3
- data/lib/mint/markdown_template.rb +47 -0
- data/lib/mint/mint.rb +181 -114
- data/lib/mint/plugin.rb +3 -3
- data/lib/mint/plugins/epub.rb +1 -2
- data/lib/mint/resource.rb +19 -9
- data/lib/mint/style.rb +10 -14
- data/lib/mint/version.rb +1 -1
- data/lib/mint.rb +1 -0
- data/man/mint.1 +135 -0
- data/spec/cli/README.md +99 -0
- data/spec/cli/argument_parsing_spec.rb +207 -0
- data/spec/cli/bin_integration_spec.rb +348 -0
- data/spec/cli/configuration_management_spec.rb +363 -0
- data/spec/cli/full_workflow_integration_spec.rb +527 -0
- data/spec/cli/publish_workflow_spec.rb +368 -0
- data/spec/cli/template_management_spec.rb +300 -0
- data/spec/css_spec.rb +1 -1
- data/spec/document_spec.rb +102 -69
- data/spec/helpers_spec.rb +42 -42
- data/spec/mint_spec.rb +104 -80
- data/spec/plugin_spec.rb +86 -88
- data/spec/run_cli_tests.rb +95 -0
- data/spec/spec_helper.rb +8 -1
- data/spec/style_spec.rb +18 -16
- data/spec/support/cli_helpers.rb +169 -0
- data/spec/support/fixtures/content-2.md +16 -0
- data/spec/support/matchers.rb +1 -1
- metadata +116 -223
- data/config/syntax.yaml +0 -71
- data/config/templates/base/style.sass +0 -144
- data/config/templates/default/layout.haml +0 -8
- data/config/templates/default/style.sass +0 -36
- data/config/templates/protocol/layout.haml +0 -7
- data/config/templates/protocol/style.sass +0 -20
- data/config/templates/zen/css/style.css +0 -145
- data/config/templates/zen/layout.haml +0 -7
- data/config/templates/zen/style.sass +0 -24
- data/features/config.feature +0 -21
- data/features/plugins/epub.feature +0 -23
- data/features/publish.feature +0 -73
- data/features/support/env.rb +0 -15
- data/features/templates.feature +0 -79
- data/spec/command_line_spec.rb +0 -87
- data/spec/plugins/epub_spec.rb +0 -242
data/lib/mint/command_line.rb
CHANGED
@@ -2,64 +2,84 @@ require "pathname"
|
|
2
2
|
require "yaml"
|
3
3
|
require "optparse"
|
4
4
|
require "fileutils"
|
5
|
-
|
6
5
|
require "active_support/core_ext/object/blank"
|
7
6
|
|
8
7
|
module Mint
|
9
8
|
module CommandLine
|
10
|
-
#
|
11
|
-
|
12
|
-
# Returns a map of all options that mint allows by default. Mint will
|
13
|
-
# consume these arguments, with optional parameters, from
|
14
|
-
# the commandline. (All other arguments are taken to be
|
15
|
-
# filenames.)
|
16
|
-
#
|
17
|
-
# @return [Hash] a structured set of options that the commandline
|
18
|
-
# executable accepts
|
19
|
-
def self.options
|
20
|
-
options_file = "../../../config/#{Mint.files[:syntax]}"
|
21
|
-
YAML.load_file File.expand_path(options_file, __FILE__)
|
22
|
-
end
|
23
|
-
|
24
|
-
# Parses ARGV according to the specified or default commandline syntax
|
9
|
+
# Parses ARGV using OptionParser
|
25
10
|
#
|
26
11
|
# @param [Array] argv a list of arguments to parse
|
27
|
-
# @param [Hash] opts default parsing options (to specify syntax file)
|
28
12
|
# @return [Hash] an object that contains parsed options, remaining arguments,
|
29
13
|
# and a help message
|
30
|
-
def self.parse(argv
|
31
|
-
opts = { syntax: options }.merge(opts)
|
14
|
+
def self.parse(argv)
|
32
15
|
parsed_options = {}
|
33
16
|
|
34
17
|
parser = OptionParser.new do |cli|
|
35
18
|
cli.banner = "Usage: mint [command] files [options]"
|
36
19
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
20
|
+
cli.on "-t", "--template TEMPLATE", "Specify the template (layout + style)" do |t|
|
21
|
+
parsed_options[:layout_or_style_or_template] = [:template, t]
|
22
|
+
end
|
23
|
+
|
24
|
+
cli.on "-l", "--layout LAYOUT", "Specify only the layout" do |l|
|
25
|
+
parsed_options[:layout_or_style_or_template] = [:layout, l]
|
26
|
+
end
|
27
|
+
|
28
|
+
cli.on "-s", "--style STYLE", "Specify only the style" do |s|
|
29
|
+
parsed_options[:layout_or_style_or_template] = [:style, s]
|
30
|
+
end
|
31
|
+
|
32
|
+
cli.on "-w", "--root ROOT", "Specify a root outside the current directory" do |r|
|
33
|
+
parsed_options[:root] = r
|
34
|
+
end
|
35
|
+
|
36
|
+
cli.on "-o", "--output-file FORMAT", "Specify the output file format with substitutions: \#{basename}, \#{original_extension}, \#{new_extension}" do |o|
|
37
|
+
parsed_options[:output_file] = o
|
38
|
+
end
|
39
|
+
|
40
|
+
cli.on "-d", "--destination DESTINATION", "Specify a destination directory, relative to the root" do |d|
|
41
|
+
parsed_options[:destination] = d
|
42
|
+
end
|
43
|
+
|
44
|
+
cli.on "--inline-style", "Inline CSS into the HTML document (default)" do
|
45
|
+
parsed_options[:style_mode] = :inline
|
46
|
+
end
|
47
|
+
|
48
|
+
cli.on "--style-destination DESTINATION", "Create stylesheet at specified directory or file path and link it" do |destination|
|
49
|
+
parsed_options[:style_mode] = :external
|
50
|
+
parsed_options[:style_destination] = destination
|
51
|
+
end
|
52
|
+
|
53
|
+
cli.on "-g", "--global", "Specify config changes on a global level" do
|
54
|
+
parsed_options[:scope] = :global
|
55
|
+
end
|
56
|
+
|
57
|
+
cli.on "-u", "--user", "Specify config changes on a user-wide level" do
|
58
|
+
parsed_options[:scope] = :user
|
59
|
+
end
|
60
|
+
|
61
|
+
cli.on "-l", "--local", "Specify config changes on a project-specific level" do
|
62
|
+
parsed_options[:scope] = :local
|
63
|
+
end
|
64
|
+
|
65
|
+
cli.on "-r", "--recursive", "Recursively find all Markdown files in subdirectories" do
|
66
|
+
parsed_options[:recursive] = true
|
53
67
|
end
|
54
68
|
end
|
55
69
|
|
56
|
-
transient_argv = argv.dup
|
70
|
+
transient_argv = argv.dup
|
57
71
|
parser.parse! transient_argv
|
58
|
-
|
72
|
+
|
73
|
+
if parsed_options[:style_mode] == :inline && parsed_options[:style_destination]
|
74
|
+
raise ArgumentError, "--inline-style and --style-destination cannot be used together"
|
75
|
+
end
|
76
|
+
|
77
|
+
default_options = Mint.default_options.merge(destination: Dir.getwd)
|
78
|
+
{ argv: transient_argv, options: default_options.merge(parsed_options), help: parser.help }
|
59
79
|
end
|
60
80
|
|
61
81
|
# Mint built-in commands
|
62
|
-
|
82
|
+
|
63
83
|
# Prints a help banner
|
64
84
|
#
|
65
85
|
# @param [String, #to_s] message a message to output
|
@@ -71,137 +91,237 @@ module Mint
|
|
71
91
|
# Install the named file as a template
|
72
92
|
#
|
73
93
|
# @param [File] file the file to install to the appropriate Mint directory
|
74
|
-
# @param [
|
75
|
-
#
|
76
|
-
# installation directory
|
94
|
+
# @param [String] name the template name to install as
|
95
|
+
# @param [Symbol] scope the scope at which to install
|
77
96
|
# @return [void]
|
78
|
-
def self.install(file,
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
97
|
+
def self.install(file, name, scope = :local)
|
98
|
+
if file.nil?
|
99
|
+
raise "[error] No file specified for installation"
|
100
|
+
end
|
101
|
+
|
84
102
|
filename, ext = file.split "."
|
85
103
|
|
86
|
-
|
104
|
+
template_name = name || filename
|
87
105
|
type = Mint.css_formats.include?(ext) ? :style : :layout
|
88
|
-
destination = Mint.template_path(
|
89
|
-
FileUtils.mkdir_p File.
|
90
|
-
|
91
|
-
puts "reading file"
|
92
|
-
puts File.read file
|
106
|
+
destination = Mint.template_path(template_name, scope) + "#{type}.#{ext}"
|
107
|
+
FileUtils.mkdir_p File.dirname(destination)
|
93
108
|
|
94
109
|
if File.exist? file
|
95
110
|
FileUtils.cp file, destination
|
96
111
|
else
|
97
|
-
raise "[error]
|
112
|
+
raise "[error] No such file: #{file}"
|
98
113
|
end
|
99
114
|
end
|
100
115
|
|
101
116
|
# Uninstall the named template
|
102
117
|
#
|
103
118
|
# @param [String] name the name of the template to be uninstalled
|
104
|
-
# @param [
|
105
|
-
# a scope label that the method will use to choose the appropriate
|
106
|
-
# installation directory
|
119
|
+
# @param [Symbol] scope the scope from which to uninstall
|
107
120
|
# @return [void]
|
108
|
-
def self.uninstall(name,
|
109
|
-
|
110
|
-
FileUtils.rm_r Mint.template_path(name, :all, :scope => opts[:scope])
|
121
|
+
def self.uninstall(name, scope = :local)
|
122
|
+
FileUtils.rm_r Mint.template_path(name, scope)
|
111
123
|
end
|
112
124
|
|
113
125
|
# List the installed templates
|
114
126
|
#
|
127
|
+
# @param [String] filter optional filter pattern
|
128
|
+
# @param [Symbol] scope the scope to list templates from
|
115
129
|
# @return [void]
|
116
|
-
def self.templates(filter=
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
Mint.templates(:scopes => scopes).
|
122
|
-
grep(Regexp.new(filter || "")).
|
130
|
+
def self.templates(filter = "", scope = :local)
|
131
|
+
filter = filter.to_s # Convert nil to empty string
|
132
|
+
Mint.templates(scope).
|
133
|
+
grep(Regexp.new(filter)).
|
123
134
|
sort.
|
124
135
|
each do |template|
|
125
|
-
|
126
|
-
|
127
|
-
|
136
|
+
puts "#{File.basename template} [#{template}]"
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
# Processes the output file format string with substitutions
|
141
|
+
#
|
142
|
+
# @param [String] format_string the format string with #{} substitutions
|
143
|
+
# @param [String] input_file the original input file path
|
144
|
+
# @return [String] the processed output file name
|
145
|
+
def self.process_output_format(format_string, input_file)
|
146
|
+
basename = File.basename(input_file, ".*")
|
147
|
+
original_extension = File.extname(input_file)[1..-1] || ""
|
148
|
+
|
149
|
+
# TODO: Remove hardcoded new_extension
|
150
|
+
new_extension = "html"
|
151
|
+
|
152
|
+
format_string.
|
153
|
+
gsub('#{basename}', basename).
|
154
|
+
gsub('#{original_extension}', original_extension).
|
155
|
+
gsub('#{new_extension}', new_extension)
|
156
|
+
end
|
157
|
+
|
158
|
+
# Creates a new template directory and file at the specified scope
|
159
|
+
#
|
160
|
+
# @param [String] name the name of the template to create
|
161
|
+
# @param [Symbol] type the type of template (:layout or :style)
|
162
|
+
# @param [Symbol] scope the scope at which to create the template
|
163
|
+
# @return [String] the path to the created template file
|
164
|
+
def self.create_template(name, type, scope)
|
165
|
+
content, ext =
|
166
|
+
case type
|
167
|
+
when :layout
|
168
|
+
[default_layout_content, "erb"]
|
169
|
+
when :style
|
170
|
+
[default_style_content, "css"]
|
171
|
+
else
|
172
|
+
abort "Invalid template type: #{type}"
|
128
173
|
end
|
174
|
+
|
175
|
+
template_dir = Mint.template_path(name, scope)
|
176
|
+
file_path = "#{template_dir}/#{type}.#{ext}"
|
177
|
+
FileUtils.mkdir_p template_dir
|
178
|
+
File.write(file_path, content)
|
179
|
+
file_path
|
180
|
+
end
|
181
|
+
|
182
|
+
# @return [String] default content for layout templates
|
183
|
+
def self.default_layout_content
|
184
|
+
<<~LAYOUT_TEMPLATE
|
185
|
+
<!DOCTYPE html>
|
186
|
+
<html>
|
187
|
+
<head>
|
188
|
+
<meta charset="utf-8">
|
189
|
+
<title>Document</title>
|
190
|
+
<% if style %>
|
191
|
+
<link rel="stylesheet" href="<%= style %>">
|
192
|
+
<% end %>
|
193
|
+
</head>
|
194
|
+
<body>
|
195
|
+
<%= content %>
|
196
|
+
</body>
|
197
|
+
</html>
|
198
|
+
LAYOUT_TEMPLATE
|
199
|
+
end
|
200
|
+
|
201
|
+
# @return [String] default content for style templates
|
202
|
+
def self.default_style_content
|
203
|
+
<<~STYLE_TEMPLATE
|
204
|
+
body {
|
205
|
+
font-family: -apple-system, 'Segoe UI', Roboto, sans-serif;
|
206
|
+
line-height: 1.25;
|
207
|
+
max-width: 960px;
|
208
|
+
margin: 0 auto;
|
209
|
+
padding: 2rem;
|
210
|
+
color: #333;
|
211
|
+
}
|
212
|
+
|
213
|
+
h1, h2, h3, h4, h5, h6 {
|
214
|
+
color: #2c3e50;
|
215
|
+
}
|
216
|
+
|
217
|
+
a {
|
218
|
+
color: #3498db;
|
219
|
+
text-decoration: none;
|
220
|
+
}
|
221
|
+
|
222
|
+
a:hover {
|
223
|
+
text-decoration: underline;
|
224
|
+
}
|
225
|
+
|
226
|
+
code {
|
227
|
+
background-color: #f8f9fa;
|
228
|
+
padding: 0.2em 0.4em;
|
229
|
+
border-radius: 3px;
|
230
|
+
font-family: 'Monaco', 'Ubuntu Mono', monospace;
|
231
|
+
}
|
232
|
+
STYLE_TEMPLATE
|
129
233
|
end
|
130
234
|
|
131
|
-
# Retrieve named template file (probably a built-in or installed
|
235
|
+
# Retrieve named template file (probably a built-in or installed
|
132
236
|
# template) and shell out that file to the user's favorite editor.
|
133
237
|
#
|
134
|
-
# @param [String] name the name of a
|
135
|
-
# @param [
|
136
|
-
#
|
137
|
-
# file to edit
|
238
|
+
# @param [String] name the name of a template to edit
|
239
|
+
# @param [Symbol] type either :layout or :style
|
240
|
+
# @param [Symbol] scope the scope at which to look for/create the template
|
138
241
|
# @return [void]
|
139
|
-
def self.edit(name,
|
140
|
-
|
141
|
-
style = commandline_options[:style]
|
142
|
-
|
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
|
149
|
-
else
|
150
|
-
layout_or_style = :style
|
151
|
-
end
|
242
|
+
def self.edit(name, type, scope)
|
243
|
+
abort "[error] No template specified" if name.nil? || name.empty?
|
152
244
|
|
153
|
-
|
245
|
+
begin
|
246
|
+
file = case type
|
247
|
+
when :layout
|
248
|
+
Mint.lookup_layout(name)
|
249
|
+
when :style
|
250
|
+
Mint.lookup_style(name)
|
251
|
+
else
|
252
|
+
abort "[error] Invalid template type: #{type}. Use :layout or :style"
|
253
|
+
end
|
254
|
+
rescue Mint::TemplateNotFoundException
|
255
|
+
print "Template '#{name}' does not exist. Create it? [y/N]: "
|
256
|
+
response = STDIN.gets.chomp.downcase
|
257
|
+
|
258
|
+
if response == 'y' || response == 'yes'
|
259
|
+
file = create_template(name, type, scope)
|
260
|
+
puts "Created template: #{file}"
|
261
|
+
else
|
262
|
+
abort "Template creation cancelled."
|
263
|
+
end
|
264
|
+
end
|
154
265
|
|
155
|
-
file = Mint.lookup_template name, layout_or_style
|
156
|
-
|
157
266
|
editor = ENV["EDITOR"] || "vi"
|
158
267
|
system "#{editor} #{file}"
|
159
268
|
end
|
160
269
|
|
161
|
-
# Updates configuration options persistently in the appropriate scope,
|
270
|
+
# Updates configuration options persistently in the appropriate scope,
|
162
271
|
# which defaults to local.
|
163
272
|
#
|
164
|
-
# @param [Hash] opts a structured set of options to set on Mint at the specified
|
273
|
+
# @param [Hash] opts a structured set of options to set on Mint at the specified
|
165
274
|
# scope
|
166
275
|
# @param [Symbol] scope the scope at which to apply the set of options
|
167
276
|
# @return [void]
|
168
277
|
def self.configure(opts, scope=:local)
|
169
|
-
config_directory = Mint.path_for_scope(scope
|
278
|
+
config_directory = Mint.path_for_scope(scope)
|
170
279
|
FileUtils.mkdir_p config_directory
|
171
|
-
Helpers.update_yaml! "#{config_directory}/#{Mint
|
280
|
+
Helpers.update_yaml! "#{config_directory}/#{Mint::CONFIG_FILE}", opts
|
172
281
|
end
|
173
282
|
|
174
|
-
# Tries to set a config option (at the specified scope) per
|
283
|
+
# Tries to set a config option (at the specified scope) per
|
175
284
|
# the user's command.
|
176
285
|
#
|
177
286
|
# @param key the key to set
|
178
287
|
# @param value the value to set key to
|
179
|
-
# @param
|
180
|
-
# a scope label that the method will use to choose the appropriate
|
181
|
-
# scope
|
288
|
+
# @param scope the scope at which to set the configuration
|
182
289
|
# @return [void]
|
183
|
-
def self.set(key, value,
|
184
|
-
commandline_options[:local] = true
|
185
|
-
scope = [:global, :user, :local].
|
186
|
-
select {|e| commandline_options[e] }.
|
187
|
-
first
|
188
|
-
|
290
|
+
def self.set(key, value, scope = :local)
|
189
291
|
configure({ key => value }, scope)
|
190
292
|
end
|
191
293
|
|
192
|
-
# Displays the sum of all active configurations, where local
|
294
|
+
# Displays the sum of all active configurations, where local
|
193
295
|
# configurations override global ones.
|
194
296
|
#
|
195
297
|
# @return [void]
|
196
298
|
def self.config
|
197
299
|
puts YAML.dump(Mint.configuration)
|
198
300
|
end
|
199
|
-
|
301
|
+
|
302
|
+
# Recursively discovers Markdown files in the given directories
|
303
|
+
#
|
304
|
+
# @param [Array] directories the directories to search
|
305
|
+
# @return [Array] an array of markdown file paths
|
306
|
+
def self.discover_files_recursively(directories)
|
307
|
+
markdown_files = []
|
308
|
+
directories.each do |dir|
|
309
|
+
if File.file?(dir)
|
310
|
+
markdown_files << dir if dir =~ /\.(#{Mint::MARKDOWN_EXTENSIONS.join('|')})$/i
|
311
|
+
elsif File.directory?(dir)
|
312
|
+
Dir.glob("#{dir}/**/*.{#{Mint::MARKDOWN_EXTENSIONS.join(',')}}", File::FNM_CASEFOLD).each do |file|
|
313
|
+
markdown_files << file
|
314
|
+
end
|
315
|
+
end
|
316
|
+
end
|
317
|
+
markdown_files.sort
|
318
|
+
end
|
319
|
+
|
200
320
|
# Renders and writes to file all resources described by a document.
|
201
321
|
# Specifically: it publishes a document, using the document's accessors
|
202
|
-
# to determine file placement and naming, and then renders its style.
|
203
|
-
# This method will overwrite any existing content in a document's destination
|
204
|
-
# files. The `render_style` option provides an easy way to stop Mint from
|
322
|
+
# to determine file placement and naming, and then renders its style.
|
323
|
+
# This method will overwrite any existing content in a document's destination
|
324
|
+
# files. The `render_style` option provides an easy way to stop Mint from
|
205
325
|
# rendering a style, even if the document's style is not nil.
|
206
326
|
#
|
207
327
|
# @param [Array, #each] files a group of filenames
|
@@ -209,9 +329,31 @@ module Mint
|
|
209
329
|
# that will guide Mint.publish!
|
210
330
|
# @return [void]
|
211
331
|
def self.publish!(files, commandline_options={})
|
332
|
+
# TODO: Establish commandline defaults in one place
|
333
|
+
# TODO: Use `commandline_options` everywhere instead of `options` and `doc_options`
|
212
334
|
options = { root: Dir.getwd }.merge(Mint.configuration_with commandline_options)
|
335
|
+
|
336
|
+
if commandline_options[:recursive]
|
337
|
+
files = discover_files_recursively(files.empty? ? ["."] : files)
|
338
|
+
end
|
339
|
+
|
213
340
|
files.each_with_index do |file, idx|
|
214
|
-
|
341
|
+
# Pass all files list when processing multiple files (for navigation in templates like garden)
|
342
|
+
all_files = files.size > 1 ? files : nil
|
343
|
+
|
344
|
+
Document.new(file,
|
345
|
+
root: options[:root],
|
346
|
+
destination: options[:destination],
|
347
|
+
context: options[:context],
|
348
|
+
name: options[:name],
|
349
|
+
style_mode: options[:style_mode],
|
350
|
+
style_destination: options[:style_destination],
|
351
|
+
layout: options[:layout],
|
352
|
+
style: options[:style],
|
353
|
+
template: options[:template],
|
354
|
+
layout_or_style_or_template: options[:layout_or_style_or_template],
|
355
|
+
all_files: all_files
|
356
|
+
).publish!(:render_style => (idx == 0))
|
215
357
|
end
|
216
358
|
end
|
217
359
|
end
|
data/lib/mint/css.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
require "sass"
|
1
|
+
require "sass-embedded"
|
2
2
|
|
3
3
|
module Mint
|
4
4
|
module CSS
|
@@ -21,7 +21,7 @@ module Mint
|
|
21
21
|
# @page { size: landscape };
|
22
22
|
# }
|
23
23
|
def self.mappings
|
24
|
-
{
|
24
|
+
{
|
25
25
|
font: "font-family",
|
26
26
|
font_size: "font-size",
|
27
27
|
font_color: "color",
|
@@ -63,8 +63,15 @@ module Mint
|
|
63
63
|
def self.parse(style)
|
64
64
|
css = style.map {|k,v| stylify(k, v) }.join("\n ")
|
65
65
|
container_scope = "##{container}\n #{css.strip}\n"
|
66
|
-
|
67
|
-
|
66
|
+
|
67
|
+
# Suppress warnings by capturing $stderr
|
68
|
+
original_stderr = $stderr
|
69
|
+
$stderr = StringIO.new
|
70
|
+
|
71
|
+
result = Sass.compile_string(container_scope, syntax: :indented)
|
72
|
+
result.css
|
73
|
+
ensure
|
74
|
+
$stderr = original_stderr
|
68
75
|
end
|
69
76
|
end
|
70
77
|
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'tilt/template'
|
2
|
+
|
3
|
+
module Mint
|
4
|
+
class CSSTemplate < Tilt::Template
|
5
|
+
self.default_mime_type = 'text/css'
|
6
|
+
|
7
|
+
def prepare
|
8
|
+
@data = data
|
9
|
+
end
|
10
|
+
|
11
|
+
def evaluate(scope, locals, &block)
|
12
|
+
process_imports(@data, File.dirname(file))
|
13
|
+
end
|
14
|
+
|
15
|
+
def process_imports(css_content, base_dir)
|
16
|
+
css_content.gsub(/@import\s+["']([^"']+)["'];?/) do |match|
|
17
|
+
import_path = $1
|
18
|
+
|
19
|
+
# If we find a relative path, resolve it
|
20
|
+
if import_path.start_with?('../', './')
|
21
|
+
full_path = File.expand_path(import_path, base_dir)
|
22
|
+
else
|
23
|
+
full_path = File.join(base_dir, import_path)
|
24
|
+
end
|
25
|
+
|
26
|
+
full_path += '.css' unless full_path.end_with?('.css')
|
27
|
+
|
28
|
+
if File.exist?(full_path)
|
29
|
+
imported_content = File.read(full_path)
|
30
|
+
process_imports(imported_content, File.dirname(full_path))
|
31
|
+
else
|
32
|
+
match
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|