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 CHANGED
@@ -1,10 +1,12 @@
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.*
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
- I. Use cases
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
- II. The Mint library
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.mint
46
+ document.publish!
45
47
 
46
- And voilà, Minimalism.html will show up next to Minimalism.md.
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 pass any of the following to a new document:
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
- - `:layout` and `:style` are names of templates or file names. They can be overridden by `:template`, which sets both to the same name.
68
+ Defaults:
63
69
 
64
- Defaults:
70
+ :template => 'default'
65
71
 
66
- :template => 'default'
72
+ Notes:
67
73
 
68
- Notes:
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
- 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:
76
+ ${MINT_PATH}/templates/template_name/style.css
77
+ ${MINT_PATH}/templates/template_name/layout.haml
71
78
 
72
- ${MINT_PATH}/templates/template_name/style.css
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
- 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.
81
+ #### Destination ####
76
82
 
77
- - `: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`.
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
- Defaults:
85
+ Defaults:
80
86
 
81
- :destination => nil
82
- :style_destination => nil
87
+ :destination => nil
88
+ :style_destination => nil
83
89
 
84
- Notes:
90
+ Notes:
85
91
 
86
- 1. `:destination` *must* refer to a directory (existing or not) and not a file.
92
+ 1. `:destination` *must* refer to a directory (existing or not) and not a file.
87
93
 
88
- 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.
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
- III. Designing a template
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. Serif Pro
180
- 3. Sans Pro
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: These aren't all designed yet. Also, if you have a killer
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'm going to build a template extension system soon so that you can easily base your template off of another one using its template name, and without knowing its location on disk.
195
+ I've included a base stylesheet that is useful for setting sensible typographic defaults.
191
196
 
192
- IV. The Mint path
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
- V. The `mint` command
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
- VI. The future of Mint
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
- optparse = OptionParser.new do |opts|
12
- opts.banner = 'Usage: mint [command] files [options]'
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
- v['short'] = "-#{v['short']}"
18
- v['long'] = "--#{v['long']}"
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
- if has_param
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(optparse.help)
37
-
24
+ Mint::CommandLine.help(parser.help)
38
25
  when :install
39
- commandline_options[:local] = true
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
- layout = commandline_options[:layout]
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
- # Determine scope, using local as the default
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 ARGV, commandline_options
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'
@@ -1,6 +1,6 @@
1
1
  require 'pathname'
2
2
  require 'yaml'
3
- require 'mint'
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 = '../../../config/options.yaml'
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.configuration
17
- config_file = Pathname.new(Mint.files[:config])
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
- # def self.install(file, scope=:local)
40
- # directory = path_for_scope(scope)
41
- # FileUtils.copy file, directory
42
- # end
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, layout_or_style=:layout)
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'] || 'vim'
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 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, scope=:local)
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
- root = options[:root] || Dir.getwd
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(root, render_style)
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 eliminates edge cases
57
- # nicely and lets us maintain document-specific information
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
- super(source, :document, options)
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
- def mint(root=Dir.getwd, render_style=true)
96
- root = Pathname.new root
97
-
98
- # Only render style if a) it's specified by the options path and
99
- # b) it actually needs rendering (i.e., it's in template form and
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
- style_dest =
111
- if style_destination
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
- style_dest = self.style_destination || self.style.destination
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
@@ -0,0 +1,3 @@
1
+ module Mint
2
+ class TemplateNotFoundException < Exception; end
3
+ 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(/\s+/, '-').
11
- gsub(/-+/, '-').
12
- gsub(/[^a-z0-9-]/, '')
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
- # Returns the relative path to dir1 from dir2.
29
- def self.normalize_path(dir1, dir2)
30
- path1, path2 = [dir1, dir2].map {|d| pathize d }
31
- path1.relative_path_from path2
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
- def self.ensure_directory(dir)
35
- FileUtils.mkdir_p dir
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
@@ -6,7 +6,8 @@ module Mint
6
6
  # file to use when a template name is specified.
7
7
  class Layout < Resource
8
8
  def initialize(source, opts=Mint.default_options)
9
- super(source, :layout, opts)
9
+ super(source, opts)
10
+ self.type = :layout
10
11
  end
11
12
  end
12
13
  end