munge 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: e8fc56a43cc01c94bce65df0af73e6d2028ac93f
4
- data.tar.gz: 136d8b5a37e8fbc6ecb9fd69ae951eebe0a10b32
3
+ metadata.gz: 1a6fdef4a9e19d71e01f67961124f1bc0ca14d46
4
+ data.tar.gz: 1abf979491cce35a858f227f800402f7899d7efa
5
5
  SHA512:
6
- metadata.gz: 1c4d0b4818104f8f08aa1a7fc196ab2d710b8259a04e7b98bede587f56487f06d533915621c1920e93338d6974432dac46432d26320fd5dd1284b4028ed51d13
7
- data.tar.gz: cf7c2270b12795bdf4623596bc026967b55b8fb0c6e052c20c983d55d291ed0f8dfbf92c31813857b28672969b459a063a92a76314f920eaa90e08bd23506f2c
6
+ metadata.gz: 14a64e75bf2ac7044816052bb9742819c1561c49335305f2ade3583ef9dfaeb4e685655bcb82440d4a40a5aa2766cee8409f0f090800d82ea11953c619775857
7
+ data.tar.gz: b9152a9873565d2575137bd9e3c644af6c13fa3f1b937572d76d4e2a73e571fb843579211ed51a0c09ba1b93b3784bacb873f9e631b8db1a62ad993b4a1f95eb
data/README.md CHANGED
@@ -11,6 +11,20 @@ Until then,
11
11
  the API should be considered experimental.
12
12
 
13
13
 
14
+ ## Features
15
+
16
+ - No metaprogramming
17
+ - Suitable for large, complex sites (e.g., multiple blogs with different templates, a single blog with multiple data sources)
18
+ - Concise rule definition
19
+ - Rules defined by iterating through arrays and modifying objects
20
+
21
+
22
+ ## Caveats
23
+
24
+ - Not optimized (Pull requests welcome, gradual optimizations preferred)
25
+ - Rules can seem pretty dense (because of its conciseness)
26
+
27
+
14
28
  ## Installation
15
29
 
16
30
  Add this line to your application's Gemfile:
@@ -32,8 +46,11 @@ Or install it yourself as:
32
46
 
33
47
  After installing your gem, you can start a project using the command line client.
34
48
 
35
- ```
36
- munge init path/to/project
49
+ ```bash
50
+ munge init path/to/project # create a barebones project
51
+ cd path/to/project
52
+ munge build # compiles your project
53
+ munge view # open http://localhost:3000/ to see output
37
54
  ```
38
55
 
39
56
  The three main files of your application are `config.yml`, `data.yml`, and `rules.rb`.
@@ -51,7 +68,7 @@ app.source
51
68
 
52
69
  # blog posts
53
70
  app.source
54
- .select { |item| item.relpath =~ %r(^posts/) } # looks for items in "src/posts/**/*"
71
+ .select { |item| item.relpath?("posts") } # looks for items in "src/posts/**/*"
55
72
  .each { |item| item.route = "blog/#{item.basename}" } # sets output file to "/blog/#{basename}/index.html"
56
73
  .each { |item| item.layout = "post" }
57
74
  .each { |item| item.transform } # sets transform to Tilt (default)
@@ -59,8 +76,8 @@ app.source
59
76
  # blog index
60
77
  posts_for_index =
61
78
  app.source
62
- .find_all { |item| item.route =~ %r(^blog/) }
63
- .sort_by { |item| item.route }
79
+ .select { |item| item.route?("blog") }
80
+ .sort_by { |item| item.route }
64
81
  .reverse
65
82
 
66
83
  app.create("blog/index.html.erb", "", posts: posts_for_index) do |item|
data/lib/munge.rb CHANGED
@@ -1,21 +1,24 @@
1
1
  require "fileutils"
2
2
  require "pathname"
3
+ require "set"
3
4
  require "yaml"
4
5
 
6
+ require "adsf"
7
+ require "rack"
5
8
  require "tilt"
6
9
 
7
10
  require "munge/version"
8
11
  require "munge/attribute/content"
9
12
  require "munge/attribute/metadata"
10
13
  require "munge/attribute/path"
11
- require "munge/item/base"
12
- require "munge/item/binary"
13
- require "munge/item/text"
14
- require "munge/item/virtual"
14
+ require "munge/item"
15
15
  require "munge/helper"
16
16
  require "munge/helper/find"
17
+ require "munge/helper/link"
17
18
  require "munge/helper/rendering"
18
19
  require "munge/transformer/tilt"
20
+ require "munge/core/config"
21
+ require "munge/core/router"
19
22
  require "munge/core/source"
20
23
  require "munge/core/transform"
21
24
  require "munge/core/transform_scope_factory"
@@ -2,24 +2,50 @@ module Munge
2
2
  class Application
3
3
  # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
4
4
  def initialize(config_path)
5
- config = YAML.load_file(File.expand_path(config_path))
5
+ config = Core::Config.new(config_path)
6
6
 
7
7
  root_path = File.dirname(File.expand_path(config_path))
8
- source_path = File.expand_path(config["source"], root_path)
9
- layouts_path = File.expand_path(config["layouts"], root_path)
10
- output_path = File.expand_path(config["output"], root_path)
11
- data_path = File.expand_path(config["data"], root_path)
8
+ source_path = File.expand_path(config[:source], root_path)
9
+ layouts_path = File.expand_path(config[:layouts], root_path)
10
+ output_path = File.expand_path(config[:output], root_path)
11
+ data_path = File.expand_path(config[:data], root_path)
12
12
 
13
13
  global_data = YAML.load_file(data_path) || {}
14
14
 
15
- @source = Core::Source.new(source_path, config["binary_extensions"])
16
- @transform = Core::Transform.new(
17
- source_path,
18
- layouts_path,
19
- global_data,
20
- @source
21
- )
22
- @writer = Core::Write.new(output_path, config["index"])
15
+ @source =
16
+ Core::Source.new(
17
+ source_abspath: source_path,
18
+ binary_extensions: config[:binary_extensions],
19
+ location: :fs_memory,
20
+ ignored_basenames: config[:ignored_basenames]
21
+ )
22
+
23
+ @layouts =
24
+ Core::Source.new(
25
+ source_abspath: layouts_path,
26
+ binary_extensions: [],
27
+ location: :fs_memory,
28
+ ignored_basenames: []
29
+ )
30
+
31
+ @router =
32
+ Core::Router.new(
33
+ index: config[:index],
34
+ keep_extensions: config[:keep_extensions]
35
+ )
36
+
37
+ @transform =
38
+ Core::Transform.new(
39
+ global_data: global_data,
40
+ layouts: @layouts,
41
+ source: @source,
42
+ router: @router
43
+ )
44
+
45
+ @writer =
46
+ Core::Write.new(
47
+ output: output_path
48
+ )
23
49
  end
24
50
  # rubocop:enable Metrics/AbcSize, Metrics/MethodLength
25
51
 
@@ -31,12 +57,12 @@ module Munge
31
57
  .each { |item| render_and_write(item, &block) }
32
58
  end
33
59
 
34
- def new_virtual_item(*args)
35
- Munge::Item::Virtual.new(*args)
60
+ def build_virtual_item(*args)
61
+ @source.build_virtual_item(*args)
36
62
  end
37
63
 
38
64
  def create(*args, &block)
39
- item = new_virtual_item(*args)
65
+ item = build_virtual_item(*args)
40
66
  yield item if block_given?
41
67
  @source.push(item)
42
68
  end
@@ -44,9 +70,12 @@ module Munge
44
70
  private
45
71
 
46
72
  def render_and_write(item, &block)
47
- did_write = @writer.write(item.route, @transform.call(item))
73
+ relpath = @router.filepath(item)
74
+
75
+ write_status = @writer.write(relpath, @transform.call(item))
76
+
48
77
  if block_given?
49
- block.call(item, did_write)
78
+ block.call(item, write_status)
50
79
  end
51
80
  end
52
81
  end
data/lib/munge/cli.rb CHANGED
@@ -15,15 +15,43 @@ module Munge
15
15
 
16
16
  desc "build", "Build in current directory"
17
17
  def build
18
- config_path = File.join(destination_root, "config.yml")
19
- rules_path = File.join(destination_root, "rules.rb")
20
-
21
18
  Munge::Runner.write(config_path, rules_path)
22
19
  end
23
20
 
21
+ desc "view", "View built files"
22
+ method_option :port, aliases: "-p", desc: "Set port", default: 3000, type: :numeric
23
+ method_option :host, aliases: "-h", desc: "Set host", default: "0.0.0.0", type: :string
24
+ def view
25
+ config = Munge::Core::Config.new(config_path)
26
+ handler = Rack::Handler::WEBrick
27
+ rack_opts = { Host: options[:host], Port: options[:port] }
28
+
29
+ app =
30
+ Rack::Builder.new do
31
+ use Rack::CommonLogger
32
+ use Rack::ShowExceptions
33
+ use Rack::Lint
34
+ use Rack::Head
35
+ use Adsf::Rack::IndexFileFinder, root: config[:output]
36
+ run Rack::File.new(config[:output])
37
+ end
38
+
39
+ Rack::Handler::WEBrick.run(app, rack_opts)
40
+ end
41
+
24
42
  desc "version", "Print version"
25
43
  def version
26
44
  puts "munge #{Munge::VERSION}"
27
45
  end
46
+
47
+ private
48
+
49
+ def config_path
50
+ File.join(destination_root, "config.yml")
51
+ end
52
+
53
+ def rules_path
54
+ File.join(destination_root, "rules.rb")
55
+ end
28
56
  end
29
57
  end
@@ -0,0 +1,23 @@
1
+ module Munge
2
+ module Core
3
+ class Config
4
+ def initialize(path)
5
+ abspath = File.expand_path(path)
6
+ @datastore =
7
+ read_yaml(abspath)
8
+ .map { |key, value| [key.to_sym, value] }
9
+ .to_h
10
+ end
11
+
12
+ def [](key)
13
+ @datastore[key]
14
+ end
15
+
16
+ private
17
+
18
+ def read_yaml(abspath)
19
+ YAML.load_file(abspath) || {}
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,63 @@
1
+ module Munge
2
+ module Core
3
+ class Router
4
+ def initialize(index:, keep_extensions:)
5
+ @index = index
6
+ @keep_extensions = keep_extensions
7
+ end
8
+
9
+ def route(item)
10
+ fail "item has no route" unless item.route
11
+
12
+ if keep_extension?(item)
13
+ "/#{filepath(item)}"
14
+ else
15
+ item.route
16
+ end
17
+ end
18
+
19
+ def filepath(item)
20
+ fail "item has no route" unless item.route
21
+
22
+ relroute = relativeize(item.route)
23
+
24
+ path =
25
+ if route_has_extension?(item)
26
+ "#{relroute}"
27
+ elsif keep_extension?(item)
28
+ "#{relroute}.#{main_extension(item)}"
29
+ else
30
+ "#{relroute}/#{@index}"
31
+ end
32
+
33
+ relativeize(path)
34
+ end
35
+
36
+ private
37
+
38
+ def relativeize(path)
39
+ while path[0] == "/"
40
+ path = path[1..-1]
41
+ end
42
+
43
+ path
44
+ end
45
+
46
+ def route_has_extension?(item)
47
+ route_basename(item) =~ /\./
48
+ end
49
+
50
+ def keep_extension?(item)
51
+ @keep_extensions.include?(main_extension(item))
52
+ end
53
+
54
+ def main_extension(item)
55
+ item.extensions.first
56
+ end
57
+
58
+ def route_basename(item)
59
+ File.basename(item.route)
60
+ end
61
+ end
62
+ end
63
+ end
@@ -5,18 +5,31 @@ module Munge
5
5
  class Source
6
6
  include Enumerable
7
7
 
8
- def initialize(source_abspath, binary_extensions = [])
9
- item_factory = ItemFactory.new(source_abspath, binary_extensions)
10
- pattern = File.join(source_abspath, "**", "*")
8
+ def initialize(source_abspath:,
9
+ binary_extensions:,
10
+ location:,
11
+ ignored_basenames:)
12
+ @item_factory =
13
+ ItemFactory.new(
14
+ source_path: source_abspath,
15
+ binary_extensions: binary_extensions,
16
+ location: location,
17
+ ignored_basenames: ignored_basenames
18
+ )
19
+ pattern = File.join(source_abspath, "**", "*")
11
20
 
12
21
  @items =
13
22
  Dir.glob(pattern)
14
23
  .reject { |item_path| File.directory?(item_path) }
15
- .map { |item_path| item_factory.create(item_path) }
24
+ .map { |item_path| @item_factory.read(item_path) }
16
25
  .map { |item| [item.id, item] }
17
26
  .to_h
18
27
  end
19
28
 
29
+ def build_virtual_item(*args)
30
+ @item_factory.build_virtual(*args)
31
+ end
32
+
20
33
  def each
21
34
  return enum_for(:each) unless block_given?
22
35
 
@@ -1,30 +1,109 @@
1
1
  module Munge
2
2
  class ItemFactory
3
- def initialize(sourcepath, binary_extensions)
4
- @sourcepath = sourcepath
5
- @binary_extensions = binary_extensions
3
+ def initialize(source_path:,
4
+ binary_extensions:,
5
+ location:,
6
+ ignored_basenames:)
7
+ @source_path = source_path
8
+ @binary_extensions = Set.new(binary_extensions)
9
+ @location = location
10
+ @ignored_basenames = ignored_basenames
6
11
  end
7
12
 
8
- def create(filepath)
9
- path = Munge::Attribute::Path.new(@sourcepath, filepath)
10
- content = Munge::Attribute::Content.new(File.read(path.absolute))
11
- stat = Munge::Attribute::Metadata.new(filepath)
13
+ def read(abspath)
14
+ content, frontmatter = compute_content_and_frontmatter(abspath)
12
15
 
13
- if binary_extension?(filepath)
14
- Munge::Item::Binary.new(path, content, stat)
16
+ relpath = compute_relpath(abspath)
17
+
18
+ Munge::Item.new(
19
+ type: compute_file_type(abspath),
20
+ location: @location,
21
+ abspath: abspath,
22
+ relpath: relpath,
23
+ id: compute_id(relpath),
24
+ content: content,
25
+ frontmatter: frontmatter,
26
+ stat: compute_stat(abspath)
27
+ )
28
+ end
29
+
30
+ def build_virtual(relpath, content, frontmatter, type: :text)
31
+ Munge::Item.new(
32
+ type: type,
33
+ location: :virtual,
34
+ abspath: nil,
35
+ relpath: relpath,
36
+ id: compute_id(relpath),
37
+ content: content,
38
+ frontmatter: frontmatter,
39
+ stat: nil
40
+ )
41
+ end
42
+
43
+ private
44
+
45
+ def compute_content_and_frontmatter(abspath)
46
+ case @location
47
+ when :fs_memory
48
+ content = Munge::Attribute::Content.new(File.read(abspath))
49
+ [content.content, content.frontmatter]
50
+ when :fs, :virtual
51
+ ["", {}]
15
52
  else
16
- Munge::Item::Text.new(path, content, stat)
53
+ fail "invalid @location `#{@location}`"
17
54
  end
18
55
  end
19
56
 
20
- private
57
+ def file_extensions(filepath)
58
+ extensions = File.basename(filepath).split(".")[1..-1]
59
+ Set.new(extensions)
60
+ end
61
+
62
+ def compute_file_type(abspath)
63
+ exts = file_extensions(abspath)
64
+
65
+ if exts.intersect?(@binary_extensions)
66
+ :binary
67
+ else
68
+ :text
69
+ end
70
+ end
21
71
 
22
- def binary_extension?(filepath)
23
- file_extensions = File.basename(filepath).split(".")[1..-1]
72
+ def compute_relpath(abspath)
73
+ folder = Pathname.new(@source_path)
74
+ file = Pathname.new(abspath)
24
75
 
25
- extensions_intersection = @binary_extensions & file_extensions
76
+ file.relative_path_from(folder).to_s
77
+ end
78
+
79
+ def compute_stat(abspath)
80
+ File.stat(abspath)
81
+ end
82
+
83
+ def compute_id(relpath)
84
+ dirname = compute_dirname(relpath)
85
+ basename = compute_basename(relpath)
86
+
87
+ id = []
88
+
89
+ unless dirname == "."
90
+ id.push(dirname)
91
+ end
92
+
93
+ unless @ignored_basenames.include?(basename)
94
+ id.push(basename)
95
+ end
96
+
97
+ id.join("/")
98
+ end
99
+
100
+ def compute_dirname(relpath)
101
+ dirname = File.dirname(relpath)
102
+ end
26
103
 
27
- !extensions_intersection.empty?
104
+ def compute_basename(relpath)
105
+ filename = File.basename(relpath)
106
+ filename.split(".").first
28
107
  end
29
108
  end
30
109
  end
@@ -1,16 +1,16 @@
1
1
  module Munge
2
2
  module Core
3
3
  class Transform
4
- def initialize(source_path,
5
- layouts_path,
6
- global_data,
7
- source)
4
+ def initialize(layouts:,
5
+ global_data:,
6
+ source:,
7
+ router:)
8
8
  @scope_factory = Core::TransformScopeFactory.new(
9
- source_path,
10
- layouts_path,
11
- global_data,
12
- source,
13
- Munge::Helper
9
+ layouts: layouts,
10
+ global_data: global_data,
11
+ source: source,
12
+ helper_container: Munge::Helper,
13
+ router: router
14
14
  )
15
15
  end
16
16
 
@@ -1,24 +1,24 @@
1
1
  module Munge
2
2
  module Core
3
3
  class TransformScopeFactory
4
- def initialize(source_path,
5
- layouts_path,
6
- global_data,
7
- source,
8
- helper_container)
9
- @source_path = source_path
10
- @layouts_path = layouts_path
4
+ def initialize(layouts:,
5
+ global_data:,
6
+ source:,
7
+ helper_container:,
8
+ router:)
9
+ @layouts = layouts
11
10
  @global_data = global_data
12
11
  @source = source
13
12
  @helper_container = helper_container
13
+ @router = router
14
14
  end
15
15
 
16
16
  def create(load_helpers = true)
17
17
  scope = Munge::Transformer::Tilt::Scope.new(
18
- @source_path,
19
- @layouts_path,
20
- @global_data,
21
- @source
18
+ layouts: @layouts,
19
+ global_data: @global_data,
20
+ source: @source,
21
+ router: @router
22
22
  )
23
23
 
24
24
  if load_helpers
@@ -1,13 +1,11 @@
1
1
  module Munge
2
2
  module Core
3
3
  class Write
4
- def initialize(output, index)
4
+ def initialize(output:)
5
5
  @output = output
6
- @index = index
7
6
  end
8
7
 
9
- def write(route, content)
10
- relpath = resolve_filepath(route)
8
+ def write(relpath, content)
11
9
  abspath = File.join(@output, relpath)
12
10
 
13
11
  FileUtils.mkdir_p(File.dirname(abspath))
@@ -19,16 +17,6 @@ module Munge
19
17
  true
20
18
  end
21
19
  end
22
-
23
- def resolve_filepath(preferred_filename)
24
- basename = File.basename(preferred_filename)
25
-
26
- if basename.include?(".")
27
- preferred_filename
28
- else
29
- "#{preferred_filename}/#{@index}"
30
- end
31
- end
32
20
  end
33
21
  end
34
22
  end
@@ -0,0 +1,29 @@
1
+ module Munge
2
+ module Helper
3
+ module Link
4
+ def url_for(item)
5
+ @router.route(item)
6
+ end
7
+
8
+ def link_to(item, text = nil, **opts)
9
+ link = url_for(item)
10
+
11
+ optstr = opts.map { |key, val| %(#{key}="#{val}") }
12
+
13
+ parts =
14
+ [
15
+ [
16
+ "<a",
17
+ %(href="#{link}"),
18
+ optstr
19
+ ].flatten.join(" "),
20
+ ">",
21
+ text || link,
22
+ "</a>"
23
+ ]
24
+
25
+ parts.join
26
+ end
27
+ end
28
+ end
29
+ end
@@ -1,49 +1,40 @@
1
1
  module Munge
2
2
  module Helper
3
3
  module Rendering
4
- def render(item, manual_engine = nil, **additional_data, &content_block)
5
- content = resolve_render_content(item, &content_block)
6
- renderers = resolve_render_renderer(item, manual_engine)
7
- data = merged_data(item.frontmatter, additional_data)
4
+ def render(item, engines: nil, data: {}, content_override: nil)
5
+ content = content_override || item.content
6
+ renderers = tilt_renderer_list(item, engines)
7
+ mdata = merged_data(item.frontmatter, data)
8
8
 
9
- renderers
10
- .inject(content) do |output, engine|
11
- template = engine.new { output }
12
- template.render(self, data)
13
- end
9
+ manual_render(content, mdata, renderers)
14
10
  end
15
11
 
16
- def layout(path, **additional_data, &block)
17
- actual_layout = find_layout(path)
12
+ def layout(item_or_string, data: {}, &block)
13
+ layout_item = resolve_layout(item_or_string)
14
+ mdata = merged_data(layout_item.frontmatter, data)
18
15
 
19
16
  if block_given?
20
17
  if block.binding.local_variable_defined?(:_erbout)
21
- layout_within_template(actual_layout, additional_data, &block)
18
+ layout_within_template(layout_item, mdata, &block)
22
19
  else
23
- layout_outside_template(actual_layout, additional_data, &block)
20
+ layout_outside_template(layout_item, mdata, &block)
24
21
  end
25
22
  else
26
- layout_without_block(actual_layout, additional_data)
23
+ layout_without_block(layout_item, mdata)
27
24
  end
28
25
  end
29
26
 
30
- def render_with_layout(item, manual_engine = nil, **additional_data, &content_block)
31
- data =
32
- merged_data(item.frontmatter, additional_data)
27
+ def render_with_layout(item, content_engines: nil, data: {}, content_override: nil)
28
+ mdata = merged_data(item.frontmatter, data)
33
29
 
34
- inner =
35
- if block_given?
36
- render(item, manual_engine, **data, &content_block)
37
- else
38
- render(item, manual_engine, **data)
39
- end
30
+ inner = render(item, engines: content_engines, data: mdata, content_override: content_override)
40
31
 
41
- if item.layout.nil?
42
- inner
43
- else
44
- layout(item.layout, data) do
32
+ if item.layout
33
+ layout(item.layout, data: mdata) do
45
34
  inner
46
35
  end
36
+ else
37
+ inner
47
38
  end
48
39
  end
49
40
 
@@ -61,22 +52,26 @@ module Munge
61
52
  end
62
53
  end
63
54
 
64
- def find_layout(path)
65
- pattern = File.join(@layouts_path, path)
66
- Dir["#{pattern}*"].first
55
+ def resolve_layout(item_or_string)
56
+ if item_or_string.is_a?(String)
57
+ @layouts[item_or_string]
58
+ else
59
+ item_or_string
60
+ end
61
+ end
62
+
63
+ def layout_outside_template(layout_item, mdata, &block)
64
+ engine_list = tilt_renderer_list(layout_item, nil)
65
+
66
+ manual_render(layout_item.content, mdata, engine_list, &block)
67
67
  end
68
68
 
69
- def layout_within_template(actual_layout, additional_data, &block)
69
+ def layout_within_template(layout_item, mdata, &block)
70
70
  original_erbout = block.binding.local_variable_get(:_erbout)
71
71
 
72
72
  block.binding.local_variable_set(:_erbout, "")
73
73
 
74
- inside = block.call
75
-
76
- template = ::Tilt.new(actual_layout)
77
- result = template.render(self, merged_data(additional_data)) do
78
- inside
79
- end
74
+ result = layout_outside_template(layout_item, mdata) { block.call }
80
75
 
81
76
  final = original_erbout + result
82
77
 
@@ -85,32 +80,53 @@ module Munge
85
80
  ""
86
81
  end
87
82
 
88
- def layout_outside_template(actual_layout, additional_data, &block)
89
- template = ::Tilt.new(actual_layout)
90
- template.render(self, merged_data(additional_data)) do
91
- block.call
92
- end
93
- end
83
+ def layout_without_block(layout_item, mdata)
84
+ engine_list = tilt_renderer_list(layout_item, nil)
94
85
 
95
- def layout_without_block(actual_layout, additional_data)
96
- template = ::Tilt.new(actual_layout)
97
- template.render(self, merged_data(additional_data))
86
+ manual_render(layout_item.content, mdata, engine_list)
98
87
  end
99
88
 
100
- def resolve_render_content(item, &content_block)
101
- if block_given?
102
- content_block.call
89
+ def tilt_renderer_list(item, preferred_engine)
90
+ if preferred_engine
91
+ tilt_renderers_from_preferred(preferred_engine)
103
92
  else
104
- item.content
93
+ tilt_renderers_from_path(item.relpath)
105
94
  end
106
95
  end
107
96
 
108
- def resolve_render_renderer(item, manual_engine)
109
- if manual_engine.nil?
110
- ::Tilt.templates_for(item.relpath)
111
- else
112
- [::Tilt[manual_engine]].compact
113
- end
97
+ def tilt_renderers_from_path(path)
98
+ ::Tilt.templates_for(path)
99
+ end
100
+
101
+ def tilt_renderers_from_preferred(preferred_engines)
102
+ preferred =
103
+ if preferred_engines.is_a?(Array)
104
+ preferred_engines.flatten.join(".")
105
+ else
106
+ preferred_engines
107
+ end
108
+
109
+ ::Tilt.templates_for(preferred)
110
+ end
111
+
112
+ def manual_render(content, data, engine_list, &block)
113
+ inner =
114
+ if block_given?
115
+ block.call
116
+ else
117
+ nil
118
+ end
119
+
120
+ engine_list
121
+ .inject(content) do |output, engine|
122
+ template = engine.new { output }
123
+
124
+ if inner
125
+ template.render(self, data) { inner }
126
+ else
127
+ template.render(self, data)
128
+ end
129
+ end
114
130
  end
115
131
  end
116
132
  end
data/lib/munge/item.rb ADDED
@@ -0,0 +1,102 @@
1
+ module Munge
2
+ class Item
3
+ def initialize(type:,
4
+ location:,
5
+ abspath:,
6
+ relpath:,
7
+ id:,
8
+ content: nil,
9
+ frontmatter: {},
10
+ stat: nil)
11
+ @type = type
12
+ @location = location
13
+ @abspath = abspath
14
+ @relpath = relpath
15
+ @id = id
16
+ @content = content
17
+ @frontmatter = frontmatter
18
+ @stat = stat
19
+
20
+ @route = nil
21
+ @layout = nil
22
+ @transforms = []
23
+ end
24
+
25
+ attr_reader :type, :location
26
+ attr_reader :abspath, :relpath, :id
27
+ attr_reader :content, :frontmatter
28
+ attr_reader :stat
29
+
30
+ attr_reader :layout, :transforms
31
+
32
+ def dirname
33
+ if File.dirname(@relpath) == "."
34
+ ""
35
+ else
36
+ File.dirname(@relpath)
37
+ end
38
+ end
39
+
40
+ def filename
41
+ File.basename(@relpath)
42
+ end
43
+
44
+ def basename
45
+ filename.split(".").first
46
+ end
47
+
48
+ def extensions
49
+ filename.split(".")[1..-1]
50
+ end
51
+
52
+ def [](key)
53
+ @frontmatter[key]
54
+ end
55
+
56
+ def []=(key, value)
57
+ @frontmatter[key] = value
58
+ end
59
+
60
+ def route=(new_route)
61
+ @route = remove_surrounding_slashes(new_route)
62
+ end
63
+
64
+ def route
65
+ if @route
66
+ "/#{@route}"
67
+ end
68
+ end
69
+
70
+ def relpath?(*subdir_patterns)
71
+ regexp = generate_regex(subdir_patterns)
72
+ regexp === @relpath
73
+ end
74
+
75
+ # do not query with slashes
76
+ def route?(*subdir_patterns)
77
+ regexp = generate_regex(subdir_patterns)
78
+ regexp === @route
79
+ end
80
+
81
+ def layout=(new_layout)
82
+ @layout = remove_surrounding_slashes(new_layout)
83
+ end
84
+
85
+ def transform(transformer = :Tilt, *args)
86
+ @transforms.push([transformer, args])
87
+ end
88
+
89
+ private
90
+
91
+ def generate_regex(pattern_list)
92
+ joined_pattern = pattern_list.join("/")
93
+ Regexp.new("^#{joined_pattern}")
94
+ end
95
+
96
+ def remove_surrounding_slashes(string)
97
+ string
98
+ .sub(%r(^/+), "")
99
+ .sub(%r(/+$), "")
100
+ end
101
+ end
102
+ end
@@ -8,13 +8,7 @@ module Munge
8
8
  end
9
9
 
10
10
  def call(item, content = nil, renderer = nil)
11
- if content.nil?
12
- @scope.render_with_layout(item, renderer)
13
- else
14
- @scope.render_with_layout(item, renderer) do
15
- content
16
- end
17
- end
11
+ @scope.render_with_layout(item, content_engines: renderer, content_override: content)
18
12
  end
19
13
  end
20
14
  end
@@ -2,16 +2,14 @@ module Munge
2
2
  module Transformer
3
3
  class Tilt
4
4
  class Scope
5
- include Munge::Helper::Rendering
6
-
7
- def initialize(source_path,
8
- layouts_path,
9
- global_data,
10
- source)
11
- @source_path = source_path
12
- @layouts_path = layouts_path
13
- @global_data = global_data
14
- @source = source
5
+ def initialize(layouts:,
6
+ global_data:,
7
+ source:,
8
+ router:)
9
+ @global_data = global_data
10
+ @layouts = layouts
11
+ @source = source
12
+ @router = router
15
13
  end
16
14
  end
17
15
  end
data/lib/munge/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Munge
2
- VERSION = "0.2.0"
2
+ VERSION = "0.3.0"
3
3
  end
data/munge.gemspec CHANGED
@@ -10,6 +10,7 @@ Gem::Specification.new do |spec|
10
10
  spec.email = ["zach.ahn@gmail.com"]
11
11
 
12
12
  spec.summary = "Static site generator aiming to simplify complex build rules"
13
+ spec.description = "Documentation for this release is located in https://github.com/zachahn/munge/blob/v#{Munge::VERSION}/README.md"
13
14
  spec.homepage = "https://github.com/zachahn/munge"
14
15
  spec.license = "MIT"
15
16
 
@@ -30,6 +31,7 @@ Gem::Specification.new do |spec|
30
31
  spec.add_development_dependency "codeclimate-test-reporter", "~> 0.4"
31
32
  spec.add_development_dependency "simplecov", "~> 0.10"
32
33
 
34
+ spec.add_runtime_dependency "adsf", "~> 1.2"
33
35
  spec.add_runtime_dependency "image_optim", "~> 0.21"
34
36
  spec.add_runtime_dependency "image_optim_pack", "~> 0.2"
35
37
  spec.add_runtime_dependency "thor", "~> 0.19"
data/seeds/config.yml CHANGED
@@ -4,6 +4,18 @@ data: data.yml
4
4
  layouts: layouts
5
5
  index: index.html
6
6
  binary_extensions:
7
+ - gif
8
+ - ico
9
+ - jpg
10
+ - jpeg
7
11
  - png
12
+ ignored_basenames:
13
+ - index
14
+ keep_extensions:
8
15
  - gif
16
+ - ico
9
17
  - jpg
18
+ - jpeg
19
+ - png
20
+ - css
21
+ - js
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: munge
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Zach Ahn
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2015-10-01 00:00:00.000000000 Z
11
+ date: 2015-10-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -122,6 +122,20 @@ dependencies:
122
122
  - - "~>"
123
123
  - !ruby/object:Gem::Version
124
124
  version: '0.10'
125
+ - !ruby/object:Gem::Dependency
126
+ name: adsf
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - "~>"
130
+ - !ruby/object:Gem::Version
131
+ version: '1.2'
132
+ type: :runtime
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - "~>"
137
+ - !ruby/object:Gem::Version
138
+ version: '1.2'
125
139
  - !ruby/object:Gem::Dependency
126
140
  name: image_optim
127
141
  requirement: !ruby/object:Gem::Requirement
@@ -178,7 +192,7 @@ dependencies:
178
192
  - - "~>"
179
193
  - !ruby/object:Gem::Version
180
194
  version: '2.0'
181
- description:
195
+ description: Documentation for this release is located in https://github.com/zachahn/munge/blob/v0.3.0/README.md
182
196
  email:
183
197
  - zach.ahn@gmail.com
184
198
  executables:
@@ -201,6 +215,8 @@ files:
201
215
  - lib/munge/attribute/metadata.rb
202
216
  - lib/munge/attribute/path.rb
203
217
  - lib/munge/cli.rb
218
+ - lib/munge/core/config.rb
219
+ - lib/munge/core/router.rb
204
220
  - lib/munge/core/source.rb
205
221
  - lib/munge/core/source/item_factory.rb
206
222
  - lib/munge/core/transform.rb
@@ -208,11 +224,9 @@ files:
208
224
  - lib/munge/core/write.rb
209
225
  - lib/munge/helper.rb
210
226
  - lib/munge/helper/find.rb
227
+ - lib/munge/helper/link.rb
211
228
  - lib/munge/helper/rendering.rb
212
- - lib/munge/item/base.rb
213
- - lib/munge/item/binary.rb
214
- - lib/munge/item/text.rb
215
- - lib/munge/item/virtual.rb
229
+ - lib/munge/item.rb
216
230
  - lib/munge/runner.rb
217
231
  - lib/munge/transformer/image_optim.rb
218
232
  - lib/munge/transformer/tilt.rb
@@ -1,85 +0,0 @@
1
- module Munge
2
- module Item
3
- class Base
4
- def initialize(path = nil, content = nil, info = nil)
5
- @path = path
6
- @content = content
7
- @info = info
8
- @layout = nil
9
- @route = nil
10
- @transforms = []
11
- end
12
-
13
- attr_reader :transforms
14
- attr_accessor :route, :layout
15
-
16
- def id
17
- if dirname == ""
18
- basename
19
- else
20
- "#{dirname}/#{basename}"
21
- end
22
- end
23
-
24
- def relpath
25
- @path.relative
26
- end
27
-
28
- def dirname
29
- if File.dirname(relpath) == "."
30
- ""
31
- else
32
- File.dirname(relpath)
33
- end
34
- end
35
-
36
- def filename
37
- File.basename(relpath)
38
- end
39
-
40
- def basename
41
- filename.split(".").first
42
- end
43
-
44
- def content
45
- @content.content
46
- end
47
-
48
- def frontmatter
49
- @content.frontmatter
50
- end
51
-
52
- def stat
53
- @info.stat
54
- end
55
-
56
- def virtual?
57
- false
58
- end
59
-
60
- def binary?
61
- false
62
- end
63
-
64
- def text?
65
- false
66
- end
67
-
68
- def transform(transformer = :tilt, *args)
69
- @transforms.push([transformer, args])
70
- end
71
-
72
- def [](key)
73
- frontmatter[key]
74
- end
75
-
76
- def []=(key, value)
77
- frontmatter[key] = value
78
- end
79
-
80
- def to_s
81
- "#{super} #{relpath} #{route}"
82
- end
83
- end
84
- end
85
- end
@@ -1,9 +0,0 @@
1
- module Munge
2
- module Item
3
- class Binary < Base
4
- def binary?
5
- true
6
- end
7
- end
8
- end
9
- end
@@ -1,9 +0,0 @@
1
- module Munge
2
- module Item
3
- class Text < Base
4
- def text?
5
- true
6
- end
7
- end
8
- end
9
- end
@@ -1,32 +0,0 @@
1
- module Munge
2
- module Item
3
- class Virtual < Base
4
- def initialize(relpath, kontent, frontmatter = nil)
5
- content =
6
- if kontent.is_a?(String)
7
- Munge::Attribute::Content.new(kontent, frontmatter)
8
- else
9
- kontent
10
- end
11
-
12
- super(relpath, content)
13
- end
14
-
15
- def relpath
16
- @path
17
- end
18
-
19
- def virtual?
20
- true
21
- end
22
-
23
- def text?
24
- true
25
- end
26
-
27
- def content=(new_content)
28
- @content.content = new_content
29
- end
30
- end
31
- end
32
- end