Module: Mint

Defined in:
lib/mint/plugins/epub.rb,
lib/mint/css.rb,
lib/mint/mint.rb,
lib/mint/style.rb,
lib/mint/plugin.rb,
lib/mint/layout.rb,
lib/mint/helpers.rb,
lib/mint/version.rb,
lib/mint/resource.rb,
lib/mint/document.rb,
lib/mint/exceptions.rb,
lib/mint/command_line.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: Document, EPub, InvalidDocumentError, Layout, Plugin, Resource, Style, TemplateNotFoundException

Constant Summary collapse

ROOT =
(Pathname.new(__FILE__).realpath.dirname + "../..").to_s
SCOPES =
{
  local:  Pathname.new(".mint"),
  user:   Pathname.new("~/.mint").expand_path,
  global: Pathname.new("#{ROOT}/config").expand_path
}
SCOPE_NAMES =
SCOPES.keys
VERSION =
"0.7.4"
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.

Parameters:

  • file (String)

    a filename pointing to a Mint configuration file

Returns:

  • (Hash)

    a structured set of configuration options


107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
# File 'lib/mint/mint.rb', line 107

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(:scopes => opts[:scopes]).
    map {|p| p + Mint.files[:defaults] }.
    select(&:exist?).
    map {|p| YAML.load_file p }.
    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.

Parameters:

  • additional (Hash)

    options to add to the current configuration

Returns:

  • (Hash)

    a structured set of configuration options with opts overriding any options from config files


129
130
131
# File 'lib/mint/mint.rb', line 129

def self.configuration_with(opts)
  configuration.merge opts
end

.css_formatsArray

Returns CSS formats, for source -> destination name guessing/conversion only.

Returns:

  • (Array)

    CSS formats, for source -> destination name guessing/conversion only.


96
97
98
# File 'lib/mint/mint.rb', line 96

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

.default_optionsHash

Returns last-resort options for creating Mint documents.

Returns:

  • (Hash)

    last-resort options for creating Mint documents.


78
79
80
81
82
83
84
85
86
87
# File 'lib/mint/mint.rb', line 78

def self.default_options
  {
    # Do not set default `template`--will override style and
    # layout when already specified -- causes tricky bugs
    layout: "default",     # default layout
    style: "default",      # default style
    destination: nil,      # do not create a subdirectory
    style_destination: nil # do not copy style to root
  }
end

.directoriesHash

Returns key Mint directories

Returns:

  • (Hash)

    key Mint directories


63
64
65
66
67
# File 'lib/mint/mint.rb', line 63

def self.directories
  { 
    templates: "templates"
  }
end

.filesHash

Returns key Mint files

Returns:

  • (Hash)

    key Mint files


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

def self.files
  { 
    syntax: "syntax.yaml",
    defaults: "defaults.yaml"
  }
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/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.

Parameters:

  • name (String, #to_s)

    the name of a template to find

  • type (Symbol)

    the resource type to find

Returns:

  • (File)

    the named, typed template file


177
178
179
180
181
182
183
184
185
186
187
188
# File 'lib/mint/mint.rb', line 177

def self.find_template(name, type)
  templates_dir = Mint.directories[:templates]

  file_name  = lambda {|x| x + templates_dir + name + type.to_s }
  find_files = lambda {|x| Pathname.glob "#{x.to_s}.*" }
  acceptable = lambda {|x| x.to_s =~ /#{Mint.formats.join "|"}/ }

  Mint.path.map(&file_name).map(&find_files).flatten.
    select(&acceptable).select(&:exist?).first.tap do |template|
    raise TemplateNotFoundException unless template
  end.to_s
end

.formatsArray

Returns all file extensions that Tilt will render

Returns:

  • (Array)

    all file extensions that Tilt will render


90
91
92
# File 'lib/mint/mint.rb', line 90

def self.formats
  Tilt.mappings.keys
end

.guess_name_from(name) ⇒ String

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

Parameters:

  • name (String)

    source file name

Returns:

  • (String)

    probably output file name


223
224
225
226
227
228
229
# File 'lib/mint/mint.rb', line 223

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_template(name_or_file, type = :layout) ⇒ File

Decides whether the template specified by `name_or_file` is a real file or the name of a template. If it is a real file, Mint will return a that file. Otherwise, Mint will look for a file with that name in the Mint path. The `type` argument indicates whether the template we are looking for is a layout or a style and will affect which type of template is returned for a given template name. For example, `lookup_template :normal` might return a layout template referring to the file ~/.mint/templates/normal/layout.erb. Adding :style as a second argument returns ~/.mint/templates/normal/style.css.

Parameters:

  • name_or_file (String, File, #to_s)

    a name or template file to look up

  • type (Symbol) (defaults to: :layout)

    the resource type to look up

Returns:

  • (File)

    the named, typed template file


159
160
161
162
# File 'lib/mint/mint.rb', line 159

def self.lookup_template(name_or_file, type=:layout)
  name = name_or_file.to_s
  File.exist?(name) ? name : find_template(name, type)
end

.path(opts = {}) ⇒ 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.

Parameters:

  • opts (Hash) (defaults to: {})

    a list of options, including :scopes

Returns:

  • (Array)

    the Mint path as an Array of Pathnames


35
36
37
38
# File 'lib/mint/mint.rb', line 35

def self.path(opts={})
  opts = { scopes: SCOPE_NAMES }.merge(opts)
  SCOPES.slice(*opts[:scopes]).values
end

.path_for_scope(scope = :local, as_path = false) ⇒ String

Returns the part of Mint.path relevant to scope. I want to refactor this so that Mint.path is always a Hash… should take care of this in the Mint.path=() method. Right now, this is a hack. It assumes a sane MINT_PATH, where the first entry is most local, the second is user-level, and the last entry is most global.

Parameters:

  • scope (Symbol) (defaults to: :local)

    the scope we want to find the path for

  • as_path (Boolean) (defaults to: false)

    if as_path is true, will return Pathname object

Returns:

  • (String)

    the Mint path for scope as a String or Pathname


50
51
52
53
54
55
56
57
58
59
60
# File 'lib/mint/mint.rb', line 50

def self.path_for_scope(scope=:local, as_path=false)
  case Mint.path
  when Array
    index = { local: 0, user: 1, global: 2 }[scope]
    Mint.path[index]
  when Hash
    Mint.path[scope]
  else
    nil
  end
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.

Parameters:

  • document (Document)

    a Mint document


243
244
245
# File 'lib/mint/mint.rb', line 243

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

Parameters:

  • path (Path, File, String, #to_s)

    the file to render


235
236
237
# File 'lib/mint/mint.rb', line 235

def self.renderer(path)
  Tilt.new path.to_s, :smart => true, :ugly => true
end

.rootString

Returns the Mint root path name

Returns:

  • (String)

    the Mint root path name


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

def self.root
  ROOT
end

.template?(file) ⇒ Boolean

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

Parameters:

  • file (String, File, #to_s)

    the file to look up

Returns:

  • (Boolean)

    true if template file is found in Mint path


211
212
213
214
215
216
# File 'lib/mint/mint.rb', line 211

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, type, opts = {}) ⇒ Object


190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
# File 'lib/mint/mint.rb', line 190

def self.template_path(name, type, opts={})
  defaults = { 
    scope: :local,
    ext: { layout: "haml", style: "sass" }[type]
  }
  opts = defaults.merge(opts)
  path = Mint.path_for_scope(opts[:scope])

  case type
  when :layout, :style
    "#{path}/templates/#{name}/#{type}.#{opts[:ext]}"
  when :all
    "#{path}/templates/#{name}"
  end
end

.templates(opts = {}) ⇒ Array

Returns the full path for each known template in the Mint path

Returns:

  • (Array)

    the full path for each known template in the Mint path


134
135
136
137
138
139
140
141
142
# File 'lib/mint/mint.rb', line 134

def self.templates(opts={})
  opts = { scopes: SCOPE_NAMES }.merge(opts)
  Mint.path(:scopes => opts[:scopes]).
    map {|p| p + directories[:templates] }.
    select(&:exist?).
    map {|p| p.children.select(&:directory?).map(&:to_s) }.
    flatten.
    sort
end