mint 0.1.5 → 0.2
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +1 -1
- data/bin/mint +20 -97
- data/config/options.yaml +1 -1
- data/features/mint_document.feature +48 -0
- data/features/step_definitions/mint_steps.rb +1 -0
- data/features/support/env.rb +33 -0
- data/lib/mint/commandline.rb +97 -0
- data/lib/mint/css.rb +54 -0
- data/lib/mint/helpers.rb +24 -9
- data/lib/mint/mint.rb +28 -24
- data/lib/mint/version.rb +1 -1
- data/lib/mint.rb +2 -0
- data/spec/document_spec.rb +173 -0
- data/spec/spec_helper.rb +7 -0
- data/templates/default/layout.haml +7 -0
- data/templates/default/style.css +110 -0
- data/templates/pro/layout.haml +7 -0
- data/templates/pro/style.sass +0 -0
- metadata +60 -7
data/README.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
*The following is a **rough draft** of the current Mint design, along with my future plans for the library and tool. The
|
1
|
+
*The following is a **rough draft** of the current Mint design, along with my future plans for the library and tool. The templates are not all there yet (that's the next step) and my first plugins aren't quite there. That said, I'm excited about where this library is going to go.*
|
2
2
|
|
3
3
|
If I believed in slogans...
|
4
4
|
---------------------------
|
data/bin/mint
CHANGED
@@ -1,86 +1,11 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
+
|
2
3
|
# A script for harnessing Mint at the commandline
|
4
|
+
# Usage: mint [options] files
|
3
5
|
|
4
|
-
require 'pathname'
|
5
6
|
require 'optparse'
|
6
|
-
require 'yaml'
|
7
7
|
require 'mint'
|
8
8
|
|
9
|
-
module Mint
|
10
|
-
module CommandLine
|
11
|
-
# A map of all options that OptParse will accept from the commandline.
|
12
|
-
# All other arguments are taken to be filenames.
|
13
|
-
def self.options
|
14
|
-
# Options file, relative to this one
|
15
|
-
options_file = '../../config/options.yaml'
|
16
|
-
YAML.load_file File.expand_path(options_file, __FILE__)
|
17
|
-
end
|
18
|
-
|
19
|
-
def self.config_options
|
20
|
-
config_filename = Pathname.new(Mint.files[:config])
|
21
|
-
|
22
|
-
# Merge config options from all config files on the Mint path,
|
23
|
-
# where more local options take precedence over more global
|
24
|
-
# options
|
25
|
-
Mint.path.map {|p| p + config_filename }.
|
26
|
-
select(&:exist?).
|
27
|
-
map {|p| YAML.load_file p }.
|
28
|
-
reverse.
|
29
|
-
reduce(Mint.default_options) {|r,p| r.merge p }
|
30
|
-
end
|
31
|
-
|
32
|
-
def self.full_options_with(commandline_options)
|
33
|
-
config_options.merge commandline_options
|
34
|
-
end
|
35
|
-
|
36
|
-
# def self.install(file, scope=:local)
|
37
|
-
# directory = path_for_scope(scope)
|
38
|
-
# FileUtils.copy file, directory
|
39
|
-
# end
|
40
|
-
|
41
|
-
def self.edit(name, layout_or_style=:layout)
|
42
|
-
file = Mint.lookup_template name, layout_or_style
|
43
|
-
|
44
|
-
editor = ENV['EDITOR'] || 'vim'
|
45
|
-
system "#{editor} #{file}"
|
46
|
-
end
|
47
|
-
|
48
|
-
def self.write_config(opts, scope=:local)
|
49
|
-
config_directory = Mint.path_for_scope scope
|
50
|
-
Helpers.ensure_directory config_directory
|
51
|
-
Helpers.update_yaml(opts, config_directory + Mint.files[:config])
|
52
|
-
end
|
53
|
-
|
54
|
-
def self.set(key, value, scope=:local)
|
55
|
-
write_config({ key => value }, scope)
|
56
|
-
end
|
57
|
-
|
58
|
-
def self.config
|
59
|
-
puts YAML.dump(config_options)
|
60
|
-
end
|
61
|
-
|
62
|
-
# Renders and writes to file all resources described by a document.
|
63
|
-
# Specifically: it renders itself (inside of its own layout) and then
|
64
|
-
# renders its style. This method will overwrite any existing content
|
65
|
-
# in a document's destination files. The `render_style` option
|
66
|
-
# provides an easy way to stop Mint from rendering a style, even
|
67
|
-
# if the document's style is not nil.
|
68
|
-
def self.mint(files, commandline_options)
|
69
|
-
documents = []
|
70
|
-
options = Mint::CommandLine.full_options_with commandline_options
|
71
|
-
|
72
|
-
root = options[:root] || Dir.getwd
|
73
|
-
|
74
|
-
# Eventually render_style should be replaced with file change detection
|
75
|
-
render_style = true
|
76
|
-
files.each do |file|
|
77
|
-
Document.new(file, options).mint(root, render_style)
|
78
|
-
render_style = false
|
79
|
-
end
|
80
|
-
end
|
81
|
-
end
|
82
|
-
end
|
83
|
-
|
84
9
|
# Parse options from the commandline
|
85
10
|
commandline_options = {}
|
86
11
|
optparse = OptionParser.new do |opts|
|
@@ -107,12 +32,9 @@ end
|
|
107
32
|
optparse.parse!
|
108
33
|
|
109
34
|
case ARGV.first.downcase.to_sym
|
110
|
-
|
111
35
|
when :help
|
112
|
-
|
36
|
+
Mint::CommandLine.help(optparse.help)
|
113
37
|
|
114
|
-
# ... if we get the install command, install the listed file to the
|
115
|
-
# scope listed, using local as the default scope
|
116
38
|
when :install
|
117
39
|
commandline_options[:local] = true
|
118
40
|
scope = [:global, :user, :local].
|
@@ -121,12 +43,9 @@ when :install
|
|
121
43
|
|
122
44
|
Mint::CommandLine.install ARGV.shift, scope
|
123
45
|
|
124
|
-
# If we get the edit command, will retrieve appropriate file
|
125
|
-
# (probably a Mint template) and shell out that file to
|
126
|
-
# the user's favorite editor. Otherwise ...
|
127
46
|
when :edit
|
128
47
|
layout = commandline_options[:layout]
|
129
|
-
style
|
48
|
+
style = commandline_options[:style]
|
130
49
|
|
131
50
|
if layout and not style
|
132
51
|
Mint::CommandLine.edit layout, :layout
|
@@ -136,8 +55,6 @@ when :edit
|
|
136
55
|
puts optparse.help
|
137
56
|
end
|
138
57
|
|
139
|
-
# ... if we get the set command, we will try to set
|
140
|
-
# a config option (at the specified scope) per the user's command. Else ...
|
141
58
|
when :set
|
142
59
|
# Determine scope, using local as the default
|
143
60
|
commandline_options[:local] = true
|
@@ -147,18 +64,24 @@ when :set
|
|
147
64
|
|
148
65
|
Mint::CommandLine.set ARGV.shift, ARGV.shift, scope
|
149
66
|
|
150
|
-
# ... if we get the config command, display all active configurations,
|
151
|
-
# where local configurations override global ones
|
152
67
|
when :config
|
153
68
|
Mint::CommandLine.config
|
154
69
|
|
155
|
-
# ... we know we've been passed a set of documents, so parse the
|
156
|
-
# commandline options, merge them with the config options, and
|
157
|
-
# start minting the document list.
|
158
70
|
else
|
159
|
-
#
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
71
|
+
# If no commands were found, search the PATH for commands prefixed
|
72
|
+
# with mint-. If no matching executables are found, we know we've
|
73
|
+
# been passed a set of documents, so parse the commandline options,
|
74
|
+
# merge them with the config options, and start minting the
|
75
|
+
# document list.
|
76
|
+
|
77
|
+
# begin
|
78
|
+
# system "mint-#{ARGV.first}"
|
79
|
+
|
80
|
+
# rescue
|
81
|
+
# The Mint library can't parse these options
|
82
|
+
commandline_options.delete :verbose
|
83
|
+
commandline_options.delete :simulation
|
84
|
+
|
85
|
+
Mint::CommandLine.mint ARGV, commandline_options
|
86
|
+
# end
|
164
87
|
end
|
data/config/options.yaml
CHANGED
@@ -0,0 +1,48 @@
|
|
1
|
+
# This is a test of the mint binary. It only covers named templates
|
2
|
+
# (layouts and styles) that are included with Mint or that are passed
|
3
|
+
# in via relative path on document creation. Further testing might include:
|
4
|
+
#
|
5
|
+
# - MINT_PATH & scope selection
|
6
|
+
# - File configuration
|
7
|
+
# - Header parsing
|
8
|
+
|
9
|
+
Feature: Mint document with varying options at the command line
|
10
|
+
As a writer
|
11
|
+
I want to create a document at the command line from plain text
|
12
|
+
So that I can view a typeset version in a web browser
|
13
|
+
|
14
|
+
Background:
|
15
|
+
Given a file named "content.md" with:
|
16
|
+
"""
|
17
|
+
Header
|
18
|
+
======
|
19
|
+
|
20
|
+
This is a test. It is theoretically formatted in
|
21
|
+
the Markdown templating language.
|
22
|
+
"""
|
23
|
+
Scenario: Mint document with defaults
|
24
|
+
When I run "mint content.md"
|
25
|
+
Then a file named "content.md" should exist
|
26
|
+
And a file named "content.html" should exist
|
27
|
+
|
28
|
+
Scenario Outline: Mint document with named template, layout & style
|
29
|
+
# Note: For all rendering, we're assuming Tilt is doing its own testing.
|
30
|
+
# Therefore, we're not testing anything except that our content made it
|
31
|
+
# into our destination file.
|
32
|
+
|
33
|
+
When I run "mint <template> <layout> <style> content.md"
|
34
|
+
Then a file named "content.html" should exist
|
35
|
+
And the file "content.html" should contain "This is a test"
|
36
|
+
And a file named "<style file>" should exist
|
37
|
+
And the file "content.html" should match /templates.*style.css/
|
38
|
+
And the file "content.html" should contain "<style file>"
|
39
|
+
|
40
|
+
Examples:
|
41
|
+
| template | layout | style | style file |
|
42
|
+
| | | | ../../templates/default/style.css |
|
43
|
+
| -t pro | | | ../../templates/pro/style.css |
|
44
|
+
| | -l pro | -s pro | ../../templates/pro/style.css |
|
45
|
+
|
46
|
+
Scenario: Mint document with non-existent template
|
47
|
+
When I run "mint -t nonexistent content.md"
|
48
|
+
Then the stdout should contain "Template 'nonexistent' does not exist."
|
@@ -0,0 +1 @@
|
|
1
|
+
require 'mint'
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'aruba/cucumber'
|
2
|
+
|
3
|
+
$LOAD_PATH.unshift File.expand_path('../../../lib', __FILE__)
|
4
|
+
|
5
|
+
module ArubaOverrides
|
6
|
+
def detect_ruby(cmd)
|
7
|
+
if cmd =~ /^mint /
|
8
|
+
"ruby -I ../../lib -S ../../bin/#{cmd}"
|
9
|
+
else
|
10
|
+
super(cmd)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
World(ArubaOverrides)
|
16
|
+
|
17
|
+
Before do
|
18
|
+
@aruba_timeout_seconds = 3
|
19
|
+
@old_path = ENV['PATH']
|
20
|
+
@bin_path = File.expand_path('../../../bin', __FILE__)
|
21
|
+
|
22
|
+
# puts "path is #{@old_path}"
|
23
|
+
unless @old_path.include? @bin_path
|
24
|
+
puts "changing path to #{@bin_path}"
|
25
|
+
system "export PATH=#{@bin_path}:$PATH"
|
26
|
+
end
|
27
|
+
# puts "now mint command should alias to #{`which mint`}"
|
28
|
+
end
|
29
|
+
|
30
|
+
After do
|
31
|
+
# puts "reverting path to #{@old_path}"
|
32
|
+
ENV['PATH'] = @old_path
|
33
|
+
end
|
@@ -0,0 +1,97 @@
|
|
1
|
+
require 'pathname'
|
2
|
+
require 'yaml'
|
3
|
+
require 'mint'
|
4
|
+
|
5
|
+
module Mint
|
6
|
+
module CommandLine
|
7
|
+
# A map of all options that mint allows by default. Mint will
|
8
|
+
# consume these arguments, with optional parameters, from
|
9
|
+
# the commandline. (All other arguments are taken to be
|
10
|
+
# filenames.)
|
11
|
+
def self.options
|
12
|
+
options_file = '../../../config/options.yaml'
|
13
|
+
YAML.load_file File.expand_path(options_file, __FILE__)
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.configuration
|
17
|
+
config_file = Pathname.new(Mint.files[:config])
|
18
|
+
|
19
|
+
# Merge config options from all config files on the Mint path,
|
20
|
+
# where more local options take precedence over more global
|
21
|
+
# options
|
22
|
+
Mint.path.map {|p| p + config_file }.
|
23
|
+
select(&:exist?).
|
24
|
+
map {|p| YAML.load_file p }.
|
25
|
+
reverse.
|
26
|
+
reduce(Mint.default_options) {|r,p| r.merge p }
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.configuration_with(opts)
|
30
|
+
configuration.merge opts
|
31
|
+
end
|
32
|
+
|
33
|
+
def self.help(message)
|
34
|
+
puts message
|
35
|
+
end
|
36
|
+
|
37
|
+
# Install the listed file to the scope listed, using
|
38
|
+
# local as the default scope.
|
39
|
+
# def self.install(file, scope=:local)
|
40
|
+
# directory = path_for_scope(scope)
|
41
|
+
# FileUtils.copy file, directory
|
42
|
+
# end
|
43
|
+
|
44
|
+
|
45
|
+
# If we get the edit command, will retrieve appropriate file
|
46
|
+
# (probably a Mint template) and shell out that file to
|
47
|
+
# the user's favorite editor.
|
48
|
+
def self.edit(name, layout_or_style=:layout)
|
49
|
+
file = Mint.lookup_template name, layout_or_style
|
50
|
+
|
51
|
+
editor = ENV['EDITOR'] || 'vim'
|
52
|
+
system "#{editor} #{file}"
|
53
|
+
end
|
54
|
+
|
55
|
+
def self.configure(opts, scope=:local)
|
56
|
+
config_directory = Mint.path_for_scope scope
|
57
|
+
config_file = config_directory + Mint.files[:config]
|
58
|
+
Helpers.ensure_directory config_directory
|
59
|
+
Helpers.update_yaml opts, config_file
|
60
|
+
end
|
61
|
+
|
62
|
+
|
63
|
+
# Try to set a config option (at the specified scope) per
|
64
|
+
# the user's command.
|
65
|
+
def self.set(key, value, scope=:local)
|
66
|
+
configure({ key => value }, scope)
|
67
|
+
end
|
68
|
+
|
69
|
+
# Display all active configurations, where local
|
70
|
+
# configurations override global ones.
|
71
|
+
def self.config
|
72
|
+
puts YAML.dump(configuration)
|
73
|
+
end
|
74
|
+
|
75
|
+
# Renders and writes to file all resources described by a document.
|
76
|
+
# Specifically: it renders itself (inside of its own layout) and then
|
77
|
+
# renders its style. This method will overwrite any existing content
|
78
|
+
# in a document's destination files. The `render_style` option
|
79
|
+
# provides an easy way to stop Mint from rendering a style, even
|
80
|
+
# if the document's style is not nil.
|
81
|
+
def self.mint(files, commandline_options)
|
82
|
+
documents = []
|
83
|
+
options = configuration_with commandline_options
|
84
|
+
|
85
|
+
root = options[:root] || Dir.getwd
|
86
|
+
|
87
|
+
# Eventually render_style should be replaced with file
|
88
|
+
# change detection
|
89
|
+
render_style = true
|
90
|
+
files.each do |file|
|
91
|
+
Document.new(file, options).mint(root, render_style)
|
92
|
+
render_style = false
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
data/lib/mint/css.rb
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
module Mint
|
2
|
+
module CSS
|
3
|
+
def container
|
4
|
+
'container'
|
5
|
+
end
|
6
|
+
|
7
|
+
# Mappings from "DSL" to actual CSS. The plan is to translate
|
8
|
+
# this into something like:
|
9
|
+
#
|
10
|
+
# #container {
|
11
|
+
# font: (value specified and cleaned up)
|
12
|
+
# padding-left: (value specified and cleaned up)
|
13
|
+
# ...
|
14
|
+
# p { line-height: (value specified and cleaned up) }
|
15
|
+
# }
|
16
|
+
def mappings
|
17
|
+
{
|
18
|
+
font: 'font',
|
19
|
+
color: 'color',
|
20
|
+
top_margin: 'padding-top',
|
21
|
+
bottom_margin: 'padding-bottom',
|
22
|
+
left_margin: 'padding-left',
|
23
|
+
right_margin: 'padding-right',
|
24
|
+
top: 'padding-top',
|
25
|
+
bottom: 'padding-bottom',
|
26
|
+
left: 'padding-left',
|
27
|
+
right: 'padding-right',
|
28
|
+
height: 'height',
|
29
|
+
width: 'width',
|
30
|
+
line_spacing: 'p { line-height: %s }',
|
31
|
+
bullet: 'bullet-shape',
|
32
|
+
indentation: 'text-indent',
|
33
|
+
after_paragraph: 'margin-bottom',
|
34
|
+
before_paragraph: 'margin-top',
|
35
|
+
smart_typography: 'optimizeLegibility'
|
36
|
+
}
|
37
|
+
end
|
38
|
+
|
39
|
+
def format(key, value)
|
40
|
+
selector = mappings[Helpers.symbolize key]
|
41
|
+
|
42
|
+
if selector.include? '%'
|
43
|
+
selector % value
|
44
|
+
else
|
45
|
+
"#{selector || key}: #{value}"
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def parse(style)
|
50
|
+
css = style.map {|k,v| format(k, v) }.join("\n ")
|
51
|
+
"##{container} {\n #{css.strip}\n}"
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
data/lib/mint/helpers.rb
CHANGED
@@ -4,16 +4,31 @@ require 'yaml'
|
|
4
4
|
|
5
5
|
module Mint
|
6
6
|
module Helpers
|
7
|
+
def self.slugize(obj)
|
8
|
+
obj.to_s.downcase.
|
9
|
+
gsub(/&/, 'and').
|
10
|
+
gsub(/\s+/, '-').
|
11
|
+
gsub(/-+/, '-').
|
12
|
+
gsub(/[^a-z0-9-]/, '')
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.symbolize(obj)
|
16
|
+
slugize(obj).gsub(/-/, '_').to_sym
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.pathize(str_or_path)
|
20
|
+
case str_or_path
|
21
|
+
when String
|
22
|
+
Pathname.new str_or_path
|
23
|
+
when Pathname
|
24
|
+
str_or_path
|
25
|
+
end.expand_path
|
26
|
+
end
|
27
|
+
|
7
28
|
# Returns the relative path to dir1 from dir2.
|
8
29
|
def self.normalize_path(dir1, dir2)
|
9
|
-
|
10
|
-
|
11
|
-
Pathname.new dir1
|
12
|
-
when Pathname
|
13
|
-
dir1
|
14
|
-
end
|
15
|
-
|
16
|
-
path.expand_path.relative_path_from(dir2.expand_path)
|
30
|
+
path1, path2 = [dir1, dir2].map {|d| pathize d }
|
31
|
+
path1.relative_path_from path2
|
17
32
|
end
|
18
33
|
|
19
34
|
def self.ensure_directory(dir)
|
@@ -24,7 +39,7 @@ module Mint
|
|
24
39
|
curr_opts = file.exist? ? YAML.load_file(file) : {}
|
25
40
|
|
26
41
|
File.open file, 'w' do |f|
|
27
|
-
YAML.dump
|
42
|
+
YAML.dump(curr_opts.merge(new_opts), f)
|
28
43
|
end
|
29
44
|
end
|
30
45
|
end
|
data/lib/mint/mint.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'pathname'
|
2
2
|
require 'fileutils'
|
3
|
+
require 'yaml'
|
3
4
|
require 'tilt'
|
4
5
|
|
5
6
|
module Mint
|
@@ -70,7 +71,7 @@ module Mint
|
|
70
71
|
# Registered Css formats, for source -> destination
|
71
72
|
# name guessing/conversion only.
|
72
73
|
def self.css_formats
|
73
|
-
css_formats = ['
|
74
|
+
css_formats = ['css', 'sass', 'scss', 'less']
|
74
75
|
end
|
75
76
|
|
76
77
|
# Decides whether the template specified by `name_or_file` is a real
|
@@ -112,9 +113,10 @@ module Mint
|
|
112
113
|
# Guesses an appropriate name for the resource output file based on
|
113
114
|
# its source file's base name
|
114
115
|
def self.guess_name_from(name)
|
116
|
+
name = name.basename if name.respond_to? :basename
|
115
117
|
css = Mint.css_formats.join '|'
|
116
|
-
name.
|
117
|
-
gsub(
|
118
|
+
name.to_s.
|
119
|
+
gsub(/\.(#{css})$/, '.css').
|
118
120
|
gsub(/(\.[^css]+)$/, '.html')
|
119
121
|
end
|
120
122
|
|
@@ -197,8 +199,6 @@ module Mint
|
|
197
199
|
end
|
198
200
|
|
199
201
|
class Document < Resource
|
200
|
-
include Helpers
|
201
|
-
|
202
202
|
# The following provide reader/accessor methods for the objects's
|
203
203
|
# important attributes. Each implicit reader is paired with an
|
204
204
|
# explicit assignment method that processes a variety of input to a
|
@@ -209,14 +209,6 @@ module Mint
|
|
209
209
|
# Html, which you can then access using via the content reader.
|
210
210
|
attr_reader :content
|
211
211
|
def content=(content)
|
212
|
-
meta, body = src.split "\n\n"
|
213
|
-
@inline_style = YAML.load meta
|
214
|
-
@renderer = Mint.renderer body
|
215
|
-
@content = @renderer.render
|
216
|
-
rescue
|
217
|
-
# I want to dry up this part of the code - and maybe look up which
|
218
|
-
# error Yaml will throw if it can't parse the first paragraph
|
219
|
-
# in the content
|
220
212
|
@renderer = Mint.renderer content
|
221
213
|
@content = @renderer.render
|
222
214
|
end
|
@@ -240,6 +232,10 @@ module Mint
|
|
240
232
|
# existing style file.
|
241
233
|
attr_reader :style
|
242
234
|
def style=(style)
|
235
|
+
# Before setting this document's style to a new one, save
|
236
|
+
# the current style destination, if it exists
|
237
|
+
destination = @style ? @style.destination : ''
|
238
|
+
|
243
239
|
@style =
|
244
240
|
if style.respond_to? :render
|
245
241
|
style
|
@@ -250,9 +246,22 @@ module Mint
|
|
250
246
|
end
|
251
247
|
|
252
248
|
def template=(template)
|
253
|
-
|
249
|
+
if template
|
250
|
+
self.layout = template
|
251
|
+
self.style = template
|
252
|
+
end
|
254
253
|
end
|
255
254
|
|
255
|
+
# Convenience methods for reaching into a document's style
|
256
|
+
# via a unified interface
|
257
|
+
def style_destination=(style_destination)
|
258
|
+
self.style.destination = style_destination if self.style
|
259
|
+
end
|
260
|
+
|
261
|
+
def style_destination
|
262
|
+
self.style.destination
|
263
|
+
end
|
264
|
+
|
256
265
|
def initialize(source, opts={})
|
257
266
|
options = Mint.default_options.merge opts
|
258
267
|
super(source, :document, options)
|
@@ -262,11 +271,13 @@ module Mint
|
|
262
271
|
self.layout = options[:layout]
|
263
272
|
self.style = options[:style]
|
264
273
|
|
265
|
-
# The template option
|
274
|
+
# The template option will override layout and style choices
|
266
275
|
self.template = options[:template]
|
267
276
|
|
268
|
-
self.
|
277
|
+
self.style_destination =
|
269
278
|
options[:style_destination] || self.style.source.dirname.expand_path
|
279
|
+
|
280
|
+
yield self if block_given?
|
270
281
|
end
|
271
282
|
|
272
283
|
def render(args={})
|
@@ -296,17 +307,10 @@ module Mint
|
|
296
307
|
|
297
308
|
# Convenience methods for views
|
298
309
|
|
299
|
-
# Returns any inline document style that was parsed from the
|
300
|
-
# content file, in the header. For use in view where we want
|
301
|
-
# document-specific Css modifications.
|
302
|
-
def inline_style
|
303
|
-
@inline_style
|
304
|
-
end
|
305
|
-
|
306
310
|
# Returns a relative path from the document to its stylesheet. Can
|
307
311
|
# be called directly from inside a layout template.
|
308
312
|
def stylesheet
|
309
|
-
Helpers.normalize_path(style.destination
|
313
|
+
Helpers.normalize_path(style.destination, destination) +
|
310
314
|
style.name.to_s
|
311
315
|
end
|
312
316
|
end
|
data/lib/mint/version.rb
CHANGED
data/lib/mint.rb
CHANGED
@@ -0,0 +1,173 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'fakefs/safe'
|
3
|
+
|
4
|
+
FakeFS do
|
5
|
+
module Mint
|
6
|
+
describe Document do
|
7
|
+
before(:each) do
|
8
|
+
@file = 'content.md'
|
9
|
+
@layout_file = 'local.haml'
|
10
|
+
@style_file = 'local.sass'
|
11
|
+
|
12
|
+
@content = <<-HERE.gsub(/^\s*/, '')
|
13
|
+
Header
|
14
|
+
------
|
15
|
+
|
16
|
+
This is just a test.
|
17
|
+
HERE
|
18
|
+
|
19
|
+
@layout = <<-HERE.gsub(/^\s*/, '')
|
20
|
+
!!!
|
21
|
+
%html
|
22
|
+
%head
|
23
|
+
%body= content
|
24
|
+
HERE
|
25
|
+
|
26
|
+
@style = 'body { font-size: 16px }'
|
27
|
+
|
28
|
+
File.open @file, 'w' do |f|
|
29
|
+
f << @content
|
30
|
+
end
|
31
|
+
|
32
|
+
File.open @layout_file, 'w' do |f|
|
33
|
+
f << @layout
|
34
|
+
end
|
35
|
+
|
36
|
+
File.open @style_file, 'w' do |f|
|
37
|
+
f << @style
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
shared_examples_for "all documents" do
|
42
|
+
it "loads content as its source" do
|
43
|
+
@document.source.to_s.should == 'content.md'
|
44
|
+
end
|
45
|
+
|
46
|
+
it "guesses its name from the source" do
|
47
|
+
@document.name.to_s.should =~ /content/
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
shared_examples_for "documents with the default template" do
|
52
|
+
it "chooses the default layout" do
|
53
|
+
@document.layout.should be_in_directory('default')
|
54
|
+
end
|
55
|
+
|
56
|
+
it "chooses the default style" do
|
57
|
+
@document.style.should be_in_directory('default')
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
shared_examples_for "documents with the pro template" do
|
62
|
+
it "chooses the pro layout" do
|
63
|
+
@document.layout.should be_in_directory('pro')
|
64
|
+
end
|
65
|
+
|
66
|
+
it "chooses the pro style" do
|
67
|
+
@document.style.should be_in_directory('pro')
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
shared_examples_for "documents with the local template" do
|
72
|
+
it "chooses the 'local' layout" do
|
73
|
+
@document.layout.name.to_s.should =~ /local/
|
74
|
+
@document.layout.source.to_s.should == @layout_file
|
75
|
+
end
|
76
|
+
|
77
|
+
it "chooses the 'local' style" do
|
78
|
+
@document.style.name.to_s.should =~ /local/
|
79
|
+
@document.style.source.to_s.should == @style_file
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
shared_examples_for "documents without explicit directories" do
|
84
|
+
it "sets the root directory as its destination directory" do
|
85
|
+
@document.destination.to_s.should == ''
|
86
|
+
end
|
87
|
+
|
88
|
+
it "sets the style's current directory as the style's destination directory" do
|
89
|
+
@document.style_destination.should ==
|
90
|
+
@document.style.source.dirname.expand_path
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
shared_examples_for "documents with explicit directories" do
|
95
|
+
it "sets the root directory as its destination directory" do
|
96
|
+
@document.destination.to_s.should == 'destination'
|
97
|
+
end
|
98
|
+
|
99
|
+
it "sets the destination directory as its style destination directory" do
|
100
|
+
@document.style_destination.to_s.should == 'styles'
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
context "when it's created without explicit options" do
|
105
|
+
before(:each) do
|
106
|
+
@document = Document.new @file
|
107
|
+
end
|
108
|
+
|
109
|
+
it_behaves_like "all documents"
|
110
|
+
it_behaves_like "documents with the default template"
|
111
|
+
it_behaves_like "documents without explicit directories"
|
112
|
+
end
|
113
|
+
|
114
|
+
context "when it's created inline with named layouts and styles" do
|
115
|
+
before(:each) do
|
116
|
+
@document = Document.new @file, :layout => 'pro', :style => 'pro'
|
117
|
+
end
|
118
|
+
|
119
|
+
it_behaves_like "all documents"
|
120
|
+
it_behaves_like "documents with the pro template"
|
121
|
+
it_behaves_like "documents without explicit directories"
|
122
|
+
end
|
123
|
+
|
124
|
+
context "when it's created inline with local layouts and styles" do
|
125
|
+
before(:each) do
|
126
|
+
@document = Document.new @file, :layout => 'local.haml',
|
127
|
+
:style => 'local.sass'
|
128
|
+
end
|
129
|
+
|
130
|
+
it_behaves_like "all documents"
|
131
|
+
it_behaves_like "documents with the local template"
|
132
|
+
it_behaves_like "documents without explicit directories"
|
133
|
+
end
|
134
|
+
|
135
|
+
context "when it's created with a template" do
|
136
|
+
before(:each) do
|
137
|
+
@document = Document.new @file, :template => 'pro'
|
138
|
+
end
|
139
|
+
|
140
|
+
it_behaves_like "all documents"
|
141
|
+
it_behaves_like "documents with the pro template"
|
142
|
+
it_behaves_like "documents without explicit directories"
|
143
|
+
end
|
144
|
+
|
145
|
+
context "when it's created with a non-default destinations" do
|
146
|
+
before(:each) do
|
147
|
+
@document = Document.new @file, :root => 'root',
|
148
|
+
:destination => 'destination', :style_destination => 'styles'
|
149
|
+
end
|
150
|
+
|
151
|
+
it_behaves_like "all documents"
|
152
|
+
it_behaves_like "documents with the default template"
|
153
|
+
it_behaves_like "documents with explicit directories"
|
154
|
+
end
|
155
|
+
|
156
|
+
context "when it's created with a block" do
|
157
|
+
before(:each) do
|
158
|
+
@document = Document.new @file do |document|
|
159
|
+
document.destination = 'destination'
|
160
|
+
document.style_destination = 'styles'
|
161
|
+
|
162
|
+
document.layout = 'pro'
|
163
|
+
document.style = 'pro'
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
it_behaves_like "all documents"
|
168
|
+
it_behaves_like "documents with the pro template"
|
169
|
+
it_behaves_like "documents with explicit directories"
|
170
|
+
end
|
171
|
+
end
|
172
|
+
end
|
173
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,110 @@
|
|
1
|
+
@import "../reset.css";
|
2
|
+
|
3
|
+
body {
|
4
|
+
font-family: 'Hoefler Text', Georgia, Garamond, FreeSerif, serif;
|
5
|
+
line-height: 1.3
|
6
|
+
}
|
7
|
+
|
8
|
+
h1 {
|
9
|
+
font-size: 130%;
|
10
|
+
font-weight: normal;
|
11
|
+
border-bottom: solid 2px #666;
|
12
|
+
margin-bottom: 15px;
|
13
|
+
}
|
14
|
+
|
15
|
+
h2 {
|
16
|
+
font-size: 125%;
|
17
|
+
font-weight: normal;
|
18
|
+
margin-top: 10px;
|
19
|
+
margin-bottom: 5px
|
20
|
+
}
|
21
|
+
|
22
|
+
h3 {
|
23
|
+
margin-top: 10px;
|
24
|
+
font-size: 100%;
|
25
|
+
font-weight: normal;
|
26
|
+
font-style: normal;
|
27
|
+
text-decoration: underline;
|
28
|
+
}
|
29
|
+
|
30
|
+
code {
|
31
|
+
font-family: Monaco, 'Lucida Console', Consolas, Monotype, mono;
|
32
|
+
font-size: 12px;
|
33
|
+
}
|
34
|
+
|
35
|
+
pre {
|
36
|
+
display: block;
|
37
|
+
background-color: #eee;
|
38
|
+
padding: 5px 10px
|
39
|
+
}
|
40
|
+
|
41
|
+
ul {
|
42
|
+
list-style-type: square;
|
43
|
+
}
|
44
|
+
|
45
|
+
ul ul {
|
46
|
+
list-style-type: circle;
|
47
|
+
}
|
48
|
+
|
49
|
+
li {
|
50
|
+
margin: 5px 0;
|
51
|
+
}
|
52
|
+
|
53
|
+
ol {
|
54
|
+
}
|
55
|
+
|
56
|
+
ul li, ol li {
|
57
|
+
margin-left: 5px;
|
58
|
+
}
|
59
|
+
|
60
|
+
p {
|
61
|
+
font-size: 100%;
|
62
|
+
margin: 0 0 10px 0;
|
63
|
+
}
|
64
|
+
|
65
|
+
p+p, ul+p, ol+p {
|
66
|
+
text-indent: 1em;
|
67
|
+
}
|
68
|
+
|
69
|
+
blockquote {
|
70
|
+
display: block;
|
71
|
+
font-size: 95%;
|
72
|
+
font-style: italic;
|
73
|
+
line-height: 1.15;
|
74
|
+
padding: 1px 5px 1px 10px;
|
75
|
+
margin: 5px 35px 5px 5px;
|
76
|
+
}
|
77
|
+
|
78
|
+
@media screen {
|
79
|
+
body {
|
80
|
+
font-size: 16px;
|
81
|
+
background-color: #666;
|
82
|
+
}
|
83
|
+
|
84
|
+
#container {
|
85
|
+
display: block;
|
86
|
+
border: solid 1px #999;
|
87
|
+
width: 500px;
|
88
|
+
padding: 50px;
|
89
|
+
margin: 10px auto;
|
90
|
+
background-color: #fff;
|
91
|
+
}
|
92
|
+
|
93
|
+
blockquote {
|
94
|
+
background-color: #429bdf;
|
95
|
+
}
|
96
|
+
}
|
97
|
+
|
98
|
+
@media print {
|
99
|
+
body {
|
100
|
+
font-size: 12pt;
|
101
|
+
margin: 1in 1.25in; }
|
102
|
+
|
103
|
+
img {
|
104
|
+
display: block;
|
105
|
+
}
|
106
|
+
|
107
|
+
blockquote {
|
108
|
+
background-color: #ddd;
|
109
|
+
}
|
110
|
+
}
|
File without changes
|
metadata
CHANGED
@@ -4,9 +4,8 @@ version: !ruby/object:Gem::Version
|
|
4
4
|
prerelease: false
|
5
5
|
segments:
|
6
6
|
- 0
|
7
|
-
-
|
8
|
-
|
9
|
-
version: 0.1.5
|
7
|
+
- 2
|
8
|
+
version: "0.2"
|
10
9
|
platform: ruby
|
11
10
|
authors:
|
12
11
|
- David Jacobs
|
@@ -14,7 +13,7 @@ autorequire:
|
|
14
13
|
bindir: bin
|
15
14
|
cert_chain: []
|
16
15
|
|
17
|
-
date: 2011-02-
|
16
|
+
date: 2011-02-28 00:00:00 -05:00
|
18
17
|
default_executable:
|
19
18
|
dependencies:
|
20
19
|
- !ruby/object:Gem::Dependency
|
@@ -30,6 +29,45 @@ dependencies:
|
|
30
29
|
version: "0"
|
31
30
|
type: :runtime
|
32
31
|
version_requirements: *id001
|
32
|
+
- !ruby/object:Gem::Dependency
|
33
|
+
name: rspec
|
34
|
+
prerelease: false
|
35
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
36
|
+
none: false
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
segments:
|
41
|
+
- 0
|
42
|
+
version: "0"
|
43
|
+
type: :development
|
44
|
+
version_requirements: *id002
|
45
|
+
- !ruby/object:Gem::Dependency
|
46
|
+
name: cucumber
|
47
|
+
prerelease: false
|
48
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ">="
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
segments:
|
54
|
+
- 0
|
55
|
+
version: "0"
|
56
|
+
type: :development
|
57
|
+
version_requirements: *id003
|
58
|
+
- !ruby/object:Gem::Dependency
|
59
|
+
name: aruba
|
60
|
+
prerelease: false
|
61
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
62
|
+
none: false
|
63
|
+
requirements:
|
64
|
+
- - ">="
|
65
|
+
- !ruby/object:Gem::Version
|
66
|
+
segments:
|
67
|
+
- 0
|
68
|
+
version: "0"
|
69
|
+
type: :development
|
70
|
+
version_requirements: *id004
|
33
71
|
description:
|
34
72
|
email: david@allthingsprogress.com
|
35
73
|
executables:
|
@@ -42,10 +80,21 @@ files:
|
|
42
80
|
- README.md
|
43
81
|
- bin/mint
|
44
82
|
- lib/mint.rb
|
45
|
-
- lib/mint/mint.rb
|
46
83
|
- lib/mint/helpers.rb
|
84
|
+
- lib/mint/mint.rb
|
47
85
|
- lib/mint/version.rb
|
86
|
+
- lib/mint/css.rb
|
87
|
+
- lib/mint/commandline.rb
|
48
88
|
- config/options.yaml
|
89
|
+
- templates/default/layout.haml
|
90
|
+
- templates/default/style.css
|
91
|
+
- templates/pro/layout.haml
|
92
|
+
- templates/pro/style.sass
|
93
|
+
- features/mint_document.feature
|
94
|
+
- features/step_definitions/mint_steps.rb
|
95
|
+
- features/support/env.rb
|
96
|
+
- spec/document_spec.rb
|
97
|
+
- spec/spec_helper.rb
|
49
98
|
has_rdoc: true
|
50
99
|
homepage: http://github.com/davejacobs/mint
|
51
100
|
licenses: []
|
@@ -80,5 +129,9 @@ rubygems_version: 1.3.7
|
|
80
129
|
signing_key:
|
81
130
|
specification_version: 3
|
82
131
|
summary: Clean, simple library for maintaining and styling documents without a word processor
|
83
|
-
test_files:
|
84
|
-
|
132
|
+
test_files:
|
133
|
+
- features/mint_document.feature
|
134
|
+
- features/step_definitions/mint_steps.rb
|
135
|
+
- features/support/env.rb
|
136
|
+
- spec/document_spec.rb
|
137
|
+
- spec/spec_helper.rb
|