Module: Mint

Defined in:
lib/mint/plugins/epub.rb,
lib/mint/css.rb,
lib/mint/mint.rb,
lib/mint/style.rb,
lib/mint/layout.rb,
lib/mint/plugin.rb,
lib/mint/helpers.rb,
lib/mint/version.rb,
lib/mint/document.rb,
lib/mint/resource.rb,
lib/mint/css_parser.rb,
lib/mint/exceptions.rb,
lib/mint/command_line.rb,
lib/mint/css_template.rb,
lib/mint/markdown_template.rb

Overview

Note: This code is not as clean as I want it to be. It is an example plugin with which I’m developing the Mint plugin system. Code cleanup to follow.

Defined Under Namespace

Modules: CSS, CommandLine, Helpers Classes: CSSTemplate, CssParser, Document, EPub, InvalidDocumentError, Layout, MarkdownTemplate, Plugin, Resource, Style, TemplateNotFoundException

Constant Summary collapse

ROOT =
(Pathname.new(__FILE__).realpath.dirname + "../..").to_s
MARKDOWN_EXTENSIONS =
%w[md markdown mkd].freeze
LOCAL_SCOPE =
Pathname.new(".mint")
USER_SCOPE =
Pathname.new("~/.config/mint").expand_path
GLOBAL_SCOPE =
Pathname.new("#{ROOT}/config").expand_path
SCOPES =
{ local: LOCAL_SCOPE, user: USER_SCOPE, global: GLOBAL_SCOPE }
SCOPE_NAMES =
SCOPES.keys
CONFIG_FILE =
"config.yaml"
TEMPLATES_DIRECTORY =
"templates"
VERSION =
"0.8.1"
META_DIR =
"META-INF"
CONTENT_DIR =
"OPS"

Class Method Summary collapse

Class Method Details

.activate_plugin!(plugin) ⇒ Object



20
21
22
23
# File 'lib/mint/plugin.rb', line 20

def self.activate_plugin!(plugin)
  @@activated_plugins ||= Set.new
  @@activated_plugins << plugin
end

.activated_pluginsObject



10
11
12
13
# File 'lib/mint/plugin.rb', line 10

def self.activated_plugins
  @@activated_plugins ||= Set.new
  @@activated_plugins.to_a
end

.after_publish(document, opts = {}) ⇒ Object



60
61
62
63
64
65
# File 'lib/mint/plugin.rb', line 60

def self.after_publish(document, opts={})
  active_plugins = opts[:plugins] || Mint.activated_plugins
  active_plugins.each do |plugin|
    plugin.after_publish(document)
  end
end

.after_render(html_text, opts = {}) ⇒ Object



53
54
55
56
57
58
# File 'lib/mint/plugin.rb', line 53

def self.after_render(html_text, opts={})
  active_plugins = opts[:plugins] || Mint.activated_plugins
  active_plugins.reduce(html_text) do |intermediate, plugin|
    plugin.after_render(intermediate)
  end
end

.before_render(plain_text, opts = {}) ⇒ Object



46
47
48
49
50
51
# File 'lib/mint/plugin.rb', line 46

def self.before_render(plain_text, opts={})
  active_plugins = opts[:plugins] || Mint.activated_plugins
  active_plugins.reduce(plain_text) do |intermediate, plugin|
    plugin.before_render(intermediate)
  end
end

.clear_plugins!Object



25
26
27
28
# File 'lib/mint/plugin.rb', line 25

def self.clear_plugins!
  defined?(@@plugins) && @@plugins.clear
  defined?(@@activated_plugins) && @@activated_plugins.clear
end

.commandline_name(plugin) ⇒ Object



42
43
44
# File 'lib/mint/plugin.rb', line 42

def self.commandline_name(plugin)
  plugin.underscore
end

.commandline_options_file(plugin) ⇒ Object



38
39
40
# File 'lib/mint/plugin.rb', line 38

def self.commandline_options_file(plugin)
  plugin.config_directory + "/syntax.yml"
end

.config_directory(plugin) ⇒ Object



34
35
36
# File 'lib/mint/plugin.rb', line 34

def self.config_directory(plugin)
  Mint::ROOT + "/plugins/config/" + plugin.underscore
end

.configuration(opts = {}) ⇒ Hash

Returns a hash of all active options specified by file (for all scopes). That is, if you specify file as “defaults.yaml”, this will return the aggregate of all defaults.yaml-specified options in the Mint path, where more local members of the path take precedence over more global ones.



89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
# File 'lib/mint/mint.rb', line 89

def self.configuration(opts={})
  opts = { scopes: SCOPE_NAMES }.merge(opts)

  # Merge config options from all config files on the Mint path,
  # where more local options take precedence over more global
  # options
  configuration = Mint.path(opts[:scopes]).
    map {|p| p + Mint::CONFIG_FILE }.
    select(&:exist?).
    map do |p| 
      begin
        YAML.load_file p
      rescue Psych::SyntaxError, StandardError => e
        {}
      end
    end.
    reverse.
    reduce(Mint.default_options) {|r,p| r.merge p }

  Helpers.symbolize_keys configuration
end

.configuration_with(opts) ⇒ Hash

Returns all configuration options (as specified by the aggregate of all config files), along with opts, where opts take precedence.



117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
# File 'lib/mint/mint.rb', line 117

def self.configuration_with(opts)
  scopes = if opts[:local] || opts[:user] || opts[:global]
    if opts[:local]
      [:local]
    elsif opts[:user]  
      [:user]
    elsif opts[:global]
      [:global]
    end
  else
    SCOPE_NAMES
  end
  
  processed_opts = opts.dup
  if processed_opts[:layout_or_style_or_template]
    option_type, option_value = processed_opts.delete(:layout_or_style_or_template)
    case option_type
    when :template
      processed_opts[:template] = option_value
    when :layout
      processed_opts[:layout] = option_value
    when :style
      processed_opts[:style] = option_value
    end
  end
  
  configuration(scopes: scopes).merge processed_opts
end

.css_formatsArray



77
78
79
# File 'lib/mint/mint.rb', line 77

def self.css_formats
  ["css", "sass", "scss", "less"]
end

.default_optionsObject



23
24
25
26
27
28
29
30
31
32
33
34
35
# File 'lib/mint/mint.rb', line 23

def self.default_options
  {
    root: Dir.getwd,
    destination: nil,
    style_mode: :inline,
    style_destination: nil,
    output_file: '#{basename}.#{new_extension}',
    layout_or_style_or_template: [:template, 'default'],
    scope: :local,
    recursive: false,
    verbose: false
  }
end

.find_template(name, type) ⇒ File

Finds a template named ‘name` in the Mint path. If `type` is :layout, will look for `MINT_PATH/templates/template_name/layout.*`. If it is :style, will look for `MINT_PATH/templates/template_name/style.*`. Mint assumes that a named template will hold only one layout and one style template. It does not know how to decide between style.css and style.less, for example. For predictable results, only include one template file called `layout.*` in the `template_name` directory. Returns nil if it cannot find a template.



202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
# File 'lib/mint/mint.rb', line 202

def self.find_template(name, type)
  file_name  = lambda {|x| x + Mint::TEMPLATES_DIRECTORY + name + type.to_s }
  find_files = lambda {|x| Pathname.glob "#{x.to_s}.*" }
  acceptable = lambda {|x| 
    ext = File.extname(x.to_s)[1..-1]
    return false unless ext
    case type
    when :layout
      formats.include?(ext)
    when :style  
      css_formats.include?(ext)
    else
      false
    end
  }

  template_file = Mint.path.
    map(&file_name).
    map(&find_files).
    flatten.
    select(&acceptable).
    select(&:exist?).
    first
    
  unless template_file
    template_dirs = Mint.path.map {|p| p + Mint::TEMPLATES_DIRECTORY + name }.select(&:exist?)
    if template_dirs.any?
      expected_exts = case type
                      when :layout then formats.join(', ')
                      when :style then css_formats.join(', ')
                      end
      raise TemplateNotFoundException, "Template '#{name}' exists but has no valid #{type} file. Expected #{type}.{#{expected_exts}}"
    else
      raise TemplateNotFoundException, "Template '#{name}' does not exist."
    end
  end
  
  template_file.to_s
end

.find_template_directory(name) ⇒ String

Finds a template directory by name



246
247
248
249
250
251
252
253
254
255
256
257
# File 'lib/mint/mint.rb', line 246

def self.find_template_directory(name)
  template_dir = Mint.path.
    map {|p| p + Mint::TEMPLATES_DIRECTORY + name }.
    select(&:exist?).
    first
    
  unless template_dir
    raise TemplateNotFoundException, "Template '#{name}' does not exist."
  end
  
  template_dir.to_s
end

.find_template_file(name, type) ⇒ String

Finds a specific template file by name and type



264
265
266
# File 'lib/mint/mint.rb', line 264

def self.find_template_file(name, type)
  find_template(name, type)
end

.formatsArray



71
72
73
# File 'lib/mint/mint.rb', line 71

def self.formats
  mapping.template_map.keys
end

.guess_name_from(name) ⇒ String

Guesses an appropriate name for the resource output file based on its source file’s base name



290
291
292
293
294
295
296
# File 'lib/mint/mint.rb', line 290

def self.guess_name_from(name)
  name = Pathname(name).basename if name
  css = Mint.css_formats.join "|"
  name.to_s.
    gsub(/\.(#{css})$/, ".css").
    gsub(/(\.(?!css).*)$/, ".html")
end

.lookup_layout(name) ⇒ String

Returns the layout file for the given template name



177
178
179
# File 'lib/mint/mint.rb', line 177

def self.lookup_layout(name)
  find_template(name, :layout)
end

.lookup_style(name) ⇒ String

Returns the style file for the given template name



185
186
187
# File 'lib/mint/mint.rb', line 185

def self.lookup_style(name)
  find_template(name, :style)
end

.lookup_template(name_or_file, type = :layout) ⇒ File

Returns the template directory for the given template name



162
163
164
165
166
167
168
169
170
171
# File 'lib/mint/mint.rb', line 162

def self.lookup_template(name_or_file, type=:layout)
  name = name_or_file.to_s
  
  # Only treat as a direct file if it's an actual file (not directory) 
  if File.file?(name) && formats.include?(File.extname(name)[1..-1])
    Pathname.new(name).dirname
  else
    Pathname.new(find_template_directory(name))
  end
end

.mappingObject



37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
# File 'lib/mint/mint.rb', line 37

def self.mapping
  if @mapping
    @mapping
  else
    @mapping = Tilt::Mapping.new.tap do |m|
      m.register Mint::CSSTemplate,       'css'                # Inline Css @imports, creating a single file
      m.register Mint::MarkdownTemplate, 'txt'                # Process Txt as Markdown
      m.register Mint::MarkdownTemplate, *MARKDOWN_EXTENSIONS
      m.register Tilt::ScssTemplate,      'scss'
      m.register Tilt::SassTemplate,      'sass'
      m.register Tilt::ERBTemplate,       'erb', 'html'        # Allow for Erb inside HTML
      m.register Tilt::HamlTemplate,      'haml'
    end
  end
end

.path(scopes = SCOPE_NAMES) ⇒ Array

Returns an array with the Mint template path for the named scope or scopes. This path is used to lookup templates and configuration options.



58
59
60
# File 'lib/mint/mint.rb', line 58

def self.path(scopes = SCOPE_NAMES)
  SCOPES.slice(*scopes).values
end

.path_for_scope(scope = :local) ⇒ Pathname

Returns the base directory for Mint configuration at the specified scope.



66
67
68
# File 'lib/mint/mint.rb', line 66

def self.path_for_scope(scope = :local)
  SCOPES[scope]
end

.pluginsObject



5
6
7
8
# File 'lib/mint/plugin.rb', line 5

def self.plugins
  @@plugins ||= Set.new
  @@plugins.to_a
end

.publish!(document, opts = {}) ⇒ void

This method returns an undefined value.

Publishes a Document object according to its internal specifications.



310
311
312
# File 'lib/mint/mint.rb', line 310

def self.publish!(document, opts={})
  document.publish! opts
end

.register_plugin!(plugin) ⇒ Object



15
16
17
18
# File 'lib/mint/plugin.rb', line 15

def self.register_plugin!(plugin)
  @@plugins ||= Set.new
  @@plugins << plugin
end

.renderer(path) ⇒ Object

Transforms a path into a template that will render the file specified at that path



302
303
304
# File 'lib/mint/mint.rb', line 302

def self.renderer(path)
  mapping.new path.to_s
end

.template?(file) ⇒ Boolean

Checks (non-rigorously) to see if the file is somewhere on the MINT_PATH



278
279
280
281
282
283
# File 'lib/mint/mint.rb', line 278

def self.template?(file)
  paths = Mint.path.map {|f| File.expand_path f }
  file_path = Pathname.new(file)
  file_path.exist? and
    file_path.dirname.expand_path.to_s =~ /#{paths.map(&:to_s).join("|")}/
end

.template_directory(plugin) ⇒ Object



30
31
32
# File 'lib/mint/plugin.rb', line 30

def self.template_directory(plugin)
  Mint::ROOT + "/plugins/templates/" + plugin.underscore
end

.template_path(name, scope) ⇒ Object

Returns the template directory for the given scope, if found



269
270
271
# File 'lib/mint/mint.rb', line 269

def self.template_path(name, scope)
  Mint.path_for_scope(scope) + "templates/#{name}"
end

.templates(scope = :local) ⇒ Array



147
148
149
150
151
152
153
154
# File 'lib/mint/mint.rb', line 147

def self.templates(scope = :local)
  Mint.path([scope]).
    map {|p| p + TEMPLATES_DIRECTORY }.
    select(&:exist?).
    map {|p| p.children.select(&:directory?).map(&:to_s) }.
    flatten.
    sort
end