munge 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.rubocop.yml +9 -0
- data/.travis.yml +14 -1
- data/README.md +46 -45
- data/exe/munge +5 -0
- data/lib/munge/application.rb +34 -15
- data/lib/munge/attribute/content.rb +8 -1
- data/lib/munge/attribute/path.rb +5 -5
- data/lib/munge/cli.rb +29 -0
- data/lib/munge/core/source/item_factory.rb +30 -0
- data/lib/munge/core/source.rb +38 -0
- data/lib/munge/core/transform.rb +51 -0
- data/lib/munge/core/transform_scope_factory.rb +42 -0
- data/lib/munge/core/write.rb +34 -0
- data/lib/munge/helper/find.rb +9 -0
- data/lib/munge/helper/rendering.rb +117 -0
- data/lib/munge/helper.rb +4 -0
- data/lib/munge/item/base.rb +85 -0
- data/lib/munge/item/binary.rb +9 -0
- data/lib/munge/item/text.rb +9 -0
- data/lib/munge/item/virtual.rb +32 -0
- data/lib/munge/runner.rb +34 -0
- data/lib/munge/transformer/image_optim.rb +20 -0
- data/lib/munge/transformer/tilt/scope.rb +19 -0
- data/lib/munge/transformer/tilt.rb +21 -0
- data/lib/munge/version.rb +1 -1
- data/lib/munge.rb +13 -2
- data/munge.gemspec +9 -2
- data/seeds/Gemfile.tt +4 -0
- data/seeds/config.yml +9 -0
- data/seeds/data.yml +1 -0
- data/seeds/layouts/default.html.erb +10 -0
- data/seeds/rules.rb +5 -0
- data/seeds/src/index.html +1 -0
- metadata +129 -8
- data/lib/munge/item.rb +0 -47
- data/lib/munge/source.rb +0 -22
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e8fc56a43cc01c94bce65df0af73e6d2028ac93f
|
4
|
+
data.tar.gz: 136d8b5a37e8fbc6ecb9fd69ae951eebe0a10b32
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1c4d0b4818104f8f08aa1a7fc196ab2d710b8259a04e7b98bede587f56487f06d533915621c1920e93338d6974432dac46432d26320fd5dd1284b4028ed51d13
|
7
|
+
data.tar.gz: cf7c2270b12795bdf4623596bc026967b55b8fb0c6e052c20c983d55d291ed0f8dfbf92c31813857b28672969b459a063a92a76314f920eaa90e08bd23506f2c
|
data/.rubocop.yml
CHANGED
data/.travis.yml
CHANGED
@@ -1,4 +1,17 @@
|
|
1
1
|
language: ruby
|
2
2
|
rvm:
|
3
|
-
- 2.2
|
3
|
+
- 2.2
|
4
|
+
- 2.1
|
5
|
+
- ruby-head
|
6
|
+
cache: bundler
|
4
7
|
before_install: gem install bundler -v 1.10.5
|
8
|
+
script: ./script/test
|
9
|
+
addons:
|
10
|
+
code_climate:
|
11
|
+
repo_token: b8fc4a1660d2067059476e3e579080fb6820daedbdb5e56cd9028f5dcc058fc8
|
12
|
+
notifications:
|
13
|
+
email: false
|
14
|
+
matrix:
|
15
|
+
fast_finish: true
|
16
|
+
allow_failures:
|
17
|
+
- rvm: ruby-head
|
data/README.md
CHANGED
@@ -1,5 +1,9 @@
|
|
1
1
|
# Munge
|
2
2
|
|
3
|
+
[](https://travis-ci.org/zachahn/munge)
|
4
|
+
[](https://codeclimate.com/github/zachahn/munge)
|
5
|
+
[](https://codeclimate.com/github/zachahn/munge/coverage)
|
6
|
+
|
3
7
|
Munge is a static site generator aiming to simplify complex build rules.
|
4
8
|
|
5
9
|
SemVer will be followed once 1.0.0 is released.
|
@@ -7,67 +11,64 @@ Until then,
|
|
7
11
|
the API should be considered experimental.
|
8
12
|
|
9
13
|
|
10
|
-
##
|
11
|
-
|
12
|
-
**Directory structure**
|
13
|
-
|
14
|
-
```
|
15
|
-
dest/
|
16
|
-
src/
|
17
|
-
layouts/
|
18
|
-
layout.html
|
19
|
-
index.html
|
20
|
-
application.rb
|
21
|
-
config.yml
|
22
|
-
Gemfile
|
23
|
-
```
|
14
|
+
## Installation
|
24
15
|
|
25
|
-
|
16
|
+
Add this line to your application's Gemfile:
|
26
17
|
|
27
18
|
```ruby
|
28
|
-
|
19
|
+
gem 'munge'
|
20
|
+
```
|
29
21
|
|
30
|
-
|
22
|
+
And then execute:
|
31
23
|
|
32
|
-
|
33
|
-
.reject { |item| item.path.relative =~ %r(^layouts/) }
|
34
|
-
.each { |item| item.route = item.path.dirname }
|
35
|
-
.map { |item| item.path.dirname }
|
24
|
+
$ bundle
|
36
25
|
|
37
|
-
|
38
|
-
```
|
26
|
+
Or install it yourself as:
|
39
27
|
|
40
|
-
|
41
|
-
|
42
|
-
```yaml
|
43
|
-
---
|
44
|
-
source: src
|
45
|
-
dest: dest
|
46
|
-
binary_extensions:
|
47
|
-
- jpg
|
48
|
-
- jpeg
|
49
|
-
- png
|
50
|
-
- gif
|
51
|
-
- ico
|
52
|
-
index: index.html
|
53
|
-
```
|
28
|
+
$ gem install munge
|
54
29
|
|
55
30
|
|
56
|
-
##
|
31
|
+
## Usage
|
57
32
|
|
58
|
-
|
33
|
+
After installing your gem, you can start a project using the command line client.
|
59
34
|
|
60
|
-
```
|
61
|
-
|
35
|
+
```
|
36
|
+
munge init path/to/project
|
62
37
|
```
|
63
38
|
|
64
|
-
|
39
|
+
The three main files of your application are `config.yml`, `data.yml`, and `rules.rb`.
|
65
40
|
|
66
|
-
|
41
|
+
Here's an example `rules.rb` for a blog.
|
67
42
|
|
68
|
-
|
43
|
+
```ruby
|
44
|
+
# home page
|
45
|
+
app.source
|
46
|
+
.select { |item| item.id == "home" } # looks for items where path is "src/home.*"
|
47
|
+
.each { |item| item.route = "" } # sets output file to "/index.html"
|
48
|
+
.each { |item| item.layout = "default"} # sets layout to "layouts/default.*"
|
49
|
+
.each { |item| item[:title] = "home" } # sets additional frontmatter variables
|
50
|
+
.each { |item| item.transform(:tilt) } # have Tilt compile this file
|
69
51
|
|
70
|
-
|
52
|
+
# blog posts
|
53
|
+
app.source
|
54
|
+
.select { |item| item.relpath =~ %r(^posts/) } # looks for items in "src/posts/**/*"
|
55
|
+
.each { |item| item.route = "blog/#{item.basename}" } # sets output file to "/blog/#{basename}/index.html"
|
56
|
+
.each { |item| item.layout = "post" }
|
57
|
+
.each { |item| item.transform } # sets transform to Tilt (default)
|
58
|
+
|
59
|
+
# blog index
|
60
|
+
posts_for_index =
|
61
|
+
app.source
|
62
|
+
.find_all { |item| item.route =~ %r(^blog/) }
|
63
|
+
.sort_by { |item| item.route }
|
64
|
+
.reverse
|
65
|
+
|
66
|
+
app.create("blog/index.html.erb", "", posts: posts_for_index) do |item|
|
67
|
+
item.route = "blog" # sets output file to "/blog/index.html"
|
68
|
+
item.layout = "list"
|
69
|
+
item.transform
|
70
|
+
end
|
71
|
+
```
|
71
72
|
|
72
73
|
|
73
74
|
## Contributing
|
data/exe/munge
ADDED
data/lib/munge/application.rb
CHANGED
@@ -1,33 +1,52 @@
|
|
1
1
|
module Munge
|
2
2
|
class Application
|
3
|
+
# rubocop:disable Metrics/AbcSize, Metrics/MethodLength
|
3
4
|
def initialize(config_path)
|
4
|
-
|
5
|
-
@root = File.dirname(File.expand_path(config_path))
|
5
|
+
config = YAML.load_file(File.expand_path(config_path))
|
6
6
|
|
7
|
-
|
8
|
-
|
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)
|
9
12
|
|
10
|
-
|
13
|
+
global_data = YAML.load_file(data_path) || {}
|
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"])
|
11
23
|
end
|
24
|
+
# rubocop:enable Metrics/AbcSize, Metrics/MethodLength
|
12
25
|
|
13
26
|
attr_reader :source
|
14
27
|
|
15
|
-
def write
|
28
|
+
def write(&block)
|
16
29
|
@source
|
17
30
|
.reject { |item| item.route.nil? }
|
18
|
-
.
|
19
|
-
|
20
|
-
|
21
|
-
|
31
|
+
.each { |item| render_and_write(item, &block) }
|
32
|
+
end
|
33
|
+
|
34
|
+
def new_virtual_item(*args)
|
35
|
+
Munge::Item::Virtual.new(*args)
|
36
|
+
end
|
37
|
+
|
38
|
+
def create(*args, &block)
|
39
|
+
item = new_virtual_item(*args)
|
40
|
+
yield item if block_given?
|
41
|
+
@source.push(item)
|
22
42
|
end
|
23
43
|
|
24
44
|
private
|
25
45
|
|
26
|
-
def
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
File.join(@dest_dir, item.route)
|
46
|
+
def render_and_write(item, &block)
|
47
|
+
did_write = @writer.write(item.route, @transform.call(item))
|
48
|
+
if block_given?
|
49
|
+
block.call(item, did_write)
|
31
50
|
end
|
32
51
|
end
|
33
52
|
end
|
@@ -43,8 +43,15 @@ module Munge
|
|
43
43
|
end
|
44
44
|
end
|
45
45
|
|
46
|
-
def initialize(string)
|
46
|
+
def initialize(string, frontmatter = nil)
|
47
47
|
@frontmatter, @content = self.class.parse(string)
|
48
|
+
|
49
|
+
if frontmatter
|
50
|
+
@frontmatter = @frontmatter.merge(frontmatter)
|
51
|
+
end
|
52
|
+
rescue ArgumentError
|
53
|
+
@frontmatter = frontmatter || {}
|
54
|
+
@content = string
|
48
55
|
end
|
49
56
|
|
50
57
|
attr_accessor :frontmatter, :content
|
data/lib/munge/attribute/path.rb
CHANGED
@@ -2,11 +2,11 @@ module Munge
|
|
2
2
|
module Attribute
|
3
3
|
class Path
|
4
4
|
def initialize(source_path, file_path)
|
5
|
-
@relative = resolve_relative(source_path, file_path)
|
6
|
-
@absolute = file_path
|
7
|
-
@basename = resolve_basename(file_path)
|
8
|
-
@extnames = resolve_extnames(file_path)
|
9
|
-
@dirname = resolve_dirname(@relative)
|
5
|
+
@relative = resolve_relative(source_path, file_path)
|
6
|
+
@absolute = file_path
|
7
|
+
@basename = resolve_basename(file_path)
|
8
|
+
@extnames = resolve_extnames(file_path)
|
9
|
+
@dirname = resolve_dirname(@relative)
|
10
10
|
end
|
11
11
|
|
12
12
|
attr_reader :relative, :absolute, :basename, :extnames, :dirname
|
data/lib/munge/cli.rb
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
require "thor"
|
2
|
+
|
3
|
+
module Munge
|
4
|
+
class CLI < Thor
|
5
|
+
include Thor::Actions
|
6
|
+
|
7
|
+
def self.source_root
|
8
|
+
File.expand_path("../../../seeds", __FILE__)
|
9
|
+
end
|
10
|
+
|
11
|
+
desc "init PATH", "Create new site at PATH"
|
12
|
+
def init(path)
|
13
|
+
directory ".", path
|
14
|
+
end
|
15
|
+
|
16
|
+
desc "build", "Build in current directory"
|
17
|
+
def build
|
18
|
+
config_path = File.join(destination_root, "config.yml")
|
19
|
+
rules_path = File.join(destination_root, "rules.rb")
|
20
|
+
|
21
|
+
Munge::Runner.write(config_path, rules_path)
|
22
|
+
end
|
23
|
+
|
24
|
+
desc "version", "Print version"
|
25
|
+
def version
|
26
|
+
puts "munge #{Munge::VERSION}"
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module Munge
|
2
|
+
class ItemFactory
|
3
|
+
def initialize(sourcepath, binary_extensions)
|
4
|
+
@sourcepath = sourcepath
|
5
|
+
@binary_extensions = binary_extensions
|
6
|
+
end
|
7
|
+
|
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)
|
12
|
+
|
13
|
+
if binary_extension?(filepath)
|
14
|
+
Munge::Item::Binary.new(path, content, stat)
|
15
|
+
else
|
16
|
+
Munge::Item::Text.new(path, content, stat)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def binary_extension?(filepath)
|
23
|
+
file_extensions = File.basename(filepath).split(".")[1..-1]
|
24
|
+
|
25
|
+
extensions_intersection = @binary_extensions & file_extensions
|
26
|
+
|
27
|
+
!extensions_intersection.empty?
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require_relative "source/item_factory"
|
2
|
+
|
3
|
+
module Munge
|
4
|
+
module Core
|
5
|
+
class Source
|
6
|
+
include Enumerable
|
7
|
+
|
8
|
+
def initialize(source_abspath, binary_extensions = [])
|
9
|
+
item_factory = ItemFactory.new(source_abspath, binary_extensions)
|
10
|
+
pattern = File.join(source_abspath, "**", "*")
|
11
|
+
|
12
|
+
@items =
|
13
|
+
Dir.glob(pattern)
|
14
|
+
.reject { |item_path| File.directory?(item_path) }
|
15
|
+
.map { |item_path| item_factory.create(item_path) }
|
16
|
+
.map { |item| [item.id, item] }
|
17
|
+
.to_h
|
18
|
+
end
|
19
|
+
|
20
|
+
def each
|
21
|
+
return enum_for(:each) unless block_given?
|
22
|
+
|
23
|
+
@items.each_value do |item|
|
24
|
+
yield item
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def push(virtual_item)
|
29
|
+
key = virtual_item.id
|
30
|
+
@items[key] = virtual_item
|
31
|
+
end
|
32
|
+
|
33
|
+
def [](id)
|
34
|
+
@items[id]
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
module Munge
|
2
|
+
module Core
|
3
|
+
class Transform
|
4
|
+
def initialize(source_path,
|
5
|
+
layouts_path,
|
6
|
+
global_data,
|
7
|
+
source)
|
8
|
+
@scope_factory = Core::TransformScopeFactory.new(
|
9
|
+
source_path,
|
10
|
+
layouts_path,
|
11
|
+
global_data,
|
12
|
+
source,
|
13
|
+
Munge::Helper
|
14
|
+
)
|
15
|
+
end
|
16
|
+
|
17
|
+
def call(item)
|
18
|
+
item.transforms
|
19
|
+
.map { |name, args| [resolve_transformer(name), args] }
|
20
|
+
.inject(item.content) do |content, params|
|
21
|
+
transformer, args = params
|
22
|
+
|
23
|
+
t = transformer.new(@scope_factory)
|
24
|
+
|
25
|
+
t.call(item, content, *args)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def resolve_transformer(identifier)
|
30
|
+
resolver = proc do |name|
|
31
|
+
if Munge::Transformer.constants.include?(name)
|
32
|
+
return Munge::Transformer.const_get(name)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
resolver.call(identifier.to_sym)
|
37
|
+
|
38
|
+
resolver.call(underscore_to_camel(identifier.to_s).to_sym)
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
def underscore_to_camel(string)
|
44
|
+
string
|
45
|
+
.split("_")
|
46
|
+
.map(&:capitalize)
|
47
|
+
.join("")
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module Munge
|
2
|
+
module Core
|
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
|
11
|
+
@global_data = global_data
|
12
|
+
@source = source
|
13
|
+
@helper_container = helper_container
|
14
|
+
end
|
15
|
+
|
16
|
+
def create(load_helpers = true)
|
17
|
+
scope = Munge::Transformer::Tilt::Scope.new(
|
18
|
+
@source_path,
|
19
|
+
@layouts_path,
|
20
|
+
@global_data,
|
21
|
+
@source
|
22
|
+
)
|
23
|
+
|
24
|
+
if load_helpers
|
25
|
+
extend_with_helpers(scope)
|
26
|
+
end
|
27
|
+
|
28
|
+
scope
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
def extend_with_helpers(scope)
|
34
|
+
Munge::Helper.constants
|
35
|
+
.map { |sym| @helper_container.const_get(sym) }
|
36
|
+
.each { |helper| scope.extend(helper) }
|
37
|
+
|
38
|
+
scope
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module Munge
|
2
|
+
module Core
|
3
|
+
class Write
|
4
|
+
def initialize(output, index)
|
5
|
+
@output = output
|
6
|
+
@index = index
|
7
|
+
end
|
8
|
+
|
9
|
+
def write(route, content)
|
10
|
+
relpath = resolve_filepath(route)
|
11
|
+
abspath = File.join(@output, relpath)
|
12
|
+
|
13
|
+
FileUtils.mkdir_p(File.dirname(abspath))
|
14
|
+
|
15
|
+
if File.exist?(abspath) && File.read(abspath) == content
|
16
|
+
return false
|
17
|
+
else
|
18
|
+
File.write(abspath, content)
|
19
|
+
true
|
20
|
+
end
|
21
|
+
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
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,117 @@
|
|
1
|
+
module Munge
|
2
|
+
module Helper
|
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)
|
8
|
+
|
9
|
+
renderers
|
10
|
+
.inject(content) do |output, engine|
|
11
|
+
template = engine.new { output }
|
12
|
+
template.render(self, data)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def layout(path, **additional_data, &block)
|
17
|
+
actual_layout = find_layout(path)
|
18
|
+
|
19
|
+
if block_given?
|
20
|
+
if block.binding.local_variable_defined?(:_erbout)
|
21
|
+
layout_within_template(actual_layout, additional_data, &block)
|
22
|
+
else
|
23
|
+
layout_outside_template(actual_layout, additional_data, &block)
|
24
|
+
end
|
25
|
+
else
|
26
|
+
layout_without_block(actual_layout, additional_data)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def render_with_layout(item, manual_engine = nil, **additional_data, &content_block)
|
31
|
+
data =
|
32
|
+
merged_data(item.frontmatter, additional_data)
|
33
|
+
|
34
|
+
inner =
|
35
|
+
if block_given?
|
36
|
+
render(item, manual_engine, **data, &content_block)
|
37
|
+
else
|
38
|
+
render(item, manual_engine, **data)
|
39
|
+
end
|
40
|
+
|
41
|
+
if item.layout.nil?
|
42
|
+
inner
|
43
|
+
else
|
44
|
+
layout(item.layout, data) do
|
45
|
+
inner
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
private
|
51
|
+
|
52
|
+
def merged_data(*data)
|
53
|
+
hash_with_string_and_symbol_keys =
|
54
|
+
data.inject(@global_data) do |merged, datum|
|
55
|
+
merged.merge(datum)
|
56
|
+
end
|
57
|
+
|
58
|
+
hash_with_string_and_symbol_keys
|
59
|
+
.each_with_object({}) do |(key, value), memo|
|
60
|
+
memo[key.to_sym] = value
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def find_layout(path)
|
65
|
+
pattern = File.join(@layouts_path, path)
|
66
|
+
Dir["#{pattern}*"].first
|
67
|
+
end
|
68
|
+
|
69
|
+
def layout_within_template(actual_layout, additional_data, &block)
|
70
|
+
original_erbout = block.binding.local_variable_get(:_erbout)
|
71
|
+
|
72
|
+
block.binding.local_variable_set(:_erbout, "")
|
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
|
80
|
+
|
81
|
+
final = original_erbout + result
|
82
|
+
|
83
|
+
block.binding.local_variable_set(:_erbout, final)
|
84
|
+
|
85
|
+
""
|
86
|
+
end
|
87
|
+
|
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
|
94
|
+
|
95
|
+
def layout_without_block(actual_layout, additional_data)
|
96
|
+
template = ::Tilt.new(actual_layout)
|
97
|
+
template.render(self, merged_data(additional_data))
|
98
|
+
end
|
99
|
+
|
100
|
+
def resolve_render_content(item, &content_block)
|
101
|
+
if block_given?
|
102
|
+
content_block.call
|
103
|
+
else
|
104
|
+
item.content
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
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
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
data/lib/munge/helper.rb
ADDED
@@ -0,0 +1,85 @@
|
|
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
|
@@ -0,0 +1,32 @@
|
|
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
|
data/lib/munge/runner.rb
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
module Munge
|
2
|
+
class Runner
|
3
|
+
class << self
|
4
|
+
def method_missing(method, config_path, rules_path, *args)
|
5
|
+
runner = new(config_path, rules_path)
|
6
|
+
runner.public_send(method, *args)
|
7
|
+
end
|
8
|
+
|
9
|
+
def respond_to_missing?(method, *)
|
10
|
+
if instance_methods.include?(method)
|
11
|
+
true
|
12
|
+
else
|
13
|
+
super
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def initialize(config_path, rules_path)
|
19
|
+
@app = app = Munge::Application.new(config_path)
|
20
|
+
|
21
|
+
binding.eval(File.read(rules_path), rules_path)
|
22
|
+
end
|
23
|
+
|
24
|
+
def write
|
25
|
+
@app.write do |item, did_write|
|
26
|
+
if did_write
|
27
|
+
puts "wrote #{item.route}"
|
28
|
+
else
|
29
|
+
puts "identical #{item.route}"
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Munge
|
2
|
+
module Transformer
|
3
|
+
class ImageOptim
|
4
|
+
def initialize(_scope_factory)
|
5
|
+
end
|
6
|
+
|
7
|
+
def call(item, content = nil, **initialization)
|
8
|
+
actual_content =
|
9
|
+
if content.nil?
|
10
|
+
item.content
|
11
|
+
else
|
12
|
+
content
|
13
|
+
end
|
14
|
+
|
15
|
+
optimizer = ::ImageOptim.new(**initialization)
|
16
|
+
optimizer.optimize_image_data(actual_content)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Munge
|
2
|
+
module Transformer
|
3
|
+
class Tilt
|
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
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require_relative "tilt/scope"
|
2
|
+
|
3
|
+
module Munge
|
4
|
+
module Transformer
|
5
|
+
class Tilt
|
6
|
+
def initialize(scope_factory)
|
7
|
+
@scope = scope_factory.create
|
8
|
+
end
|
9
|
+
|
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
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
data/lib/munge/version.rb
CHANGED
data/lib/munge.rb
CHANGED
@@ -5,12 +5,23 @@ require "yaml"
|
|
5
5
|
require "tilt"
|
6
6
|
|
7
7
|
require "munge/version"
|
8
|
-
require "munge/source"
|
9
8
|
require "munge/attribute/content"
|
10
9
|
require "munge/attribute/metadata"
|
11
10
|
require "munge/attribute/path"
|
12
|
-
require "munge/item"
|
11
|
+
require "munge/item/base"
|
12
|
+
require "munge/item/binary"
|
13
|
+
require "munge/item/text"
|
14
|
+
require "munge/item/virtual"
|
15
|
+
require "munge/helper"
|
16
|
+
require "munge/helper/find"
|
17
|
+
require "munge/helper/rendering"
|
18
|
+
require "munge/transformer/tilt"
|
19
|
+
require "munge/core/source"
|
20
|
+
require "munge/core/transform"
|
21
|
+
require "munge/core/transform_scope_factory"
|
22
|
+
require "munge/core/write"
|
13
23
|
require "munge/application"
|
24
|
+
require "munge/runner"
|
14
25
|
|
15
26
|
module Munge
|
16
27
|
# Your code goes here...
|
data/munge.gemspec
CHANGED
@@ -9,7 +9,7 @@ Gem::Specification.new do |spec|
|
|
9
9
|
spec.authors = ["Zach Ahn"]
|
10
10
|
spec.email = ["zach.ahn@gmail.com"]
|
11
11
|
|
12
|
-
spec.summary = "
|
12
|
+
spec.summary = "Static site generator aiming to simplify complex build rules"
|
13
13
|
spec.homepage = "https://github.com/zachahn/munge"
|
14
14
|
spec.license = "MIT"
|
15
15
|
|
@@ -21,10 +21,17 @@ Gem::Specification.new do |spec|
|
|
21
21
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
22
22
|
spec.require_paths = ["lib"]
|
23
23
|
|
24
|
-
spec.add_development_dependency "bundler", "~> 1.
|
24
|
+
spec.add_development_dependency "bundler", "~> 1.9"
|
25
25
|
spec.add_development_dependency "rake", "~> 10.0"
|
26
26
|
spec.add_development_dependency "minitest", "~> 5.8"
|
27
|
+
spec.add_development_dependency "fakefs", "~> 0.6"
|
28
|
+
spec.add_development_dependency "redcarpet", "~> 3.3"
|
27
29
|
spec.add_development_dependency "rubocop", "~> 0.32"
|
30
|
+
spec.add_development_dependency "codeclimate-test-reporter", "~> 0.4"
|
31
|
+
spec.add_development_dependency "simplecov", "~> 0.10"
|
28
32
|
|
33
|
+
spec.add_runtime_dependency "image_optim", "~> 0.21"
|
34
|
+
spec.add_runtime_dependency "image_optim_pack", "~> 0.2"
|
35
|
+
spec.add_runtime_dependency "thor", "~> 0.19"
|
29
36
|
spec.add_runtime_dependency "tilt", "~> 2.0"
|
30
37
|
end
|
data/seeds/Gemfile.tt
ADDED
data/seeds/config.yml
ADDED
data/seeds/data.yml
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
---
|
data/seeds/rules.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
<h1>Welcome</h1>
|
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.
|
4
|
+
version: 0.2.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-
|
11
|
+
date: 2015-10-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '1.
|
19
|
+
version: '1.9'
|
20
20
|
type: :development
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '1.
|
26
|
+
version: '1.9'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: rake
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -52,6 +52,34 @@ dependencies:
|
|
52
52
|
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '5.8'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: fakefs
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0.6'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0.6'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: redcarpet
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '3.3'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '3.3'
|
55
83
|
- !ruby/object:Gem::Dependency
|
56
84
|
name: rubocop
|
57
85
|
requirement: !ruby/object:Gem::Requirement
|
@@ -66,6 +94,76 @@ dependencies:
|
|
66
94
|
- - "~>"
|
67
95
|
- !ruby/object:Gem::Version
|
68
96
|
version: '0.32'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: codeclimate-test-reporter
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - "~>"
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0.4'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - "~>"
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0.4'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: simplecov
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - "~>"
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0.10'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - "~>"
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '0.10'
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: image_optim
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - "~>"
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '0.21'
|
132
|
+
type: :runtime
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - "~>"
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '0.21'
|
139
|
+
- !ruby/object:Gem::Dependency
|
140
|
+
name: image_optim_pack
|
141
|
+
requirement: !ruby/object:Gem::Requirement
|
142
|
+
requirements:
|
143
|
+
- - "~>"
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
version: '0.2'
|
146
|
+
type: :runtime
|
147
|
+
prerelease: false
|
148
|
+
version_requirements: !ruby/object:Gem::Requirement
|
149
|
+
requirements:
|
150
|
+
- - "~>"
|
151
|
+
- !ruby/object:Gem::Version
|
152
|
+
version: '0.2'
|
153
|
+
- !ruby/object:Gem::Dependency
|
154
|
+
name: thor
|
155
|
+
requirement: !ruby/object:Gem::Requirement
|
156
|
+
requirements:
|
157
|
+
- - "~>"
|
158
|
+
- !ruby/object:Gem::Version
|
159
|
+
version: '0.19'
|
160
|
+
type: :runtime
|
161
|
+
prerelease: false
|
162
|
+
version_requirements: !ruby/object:Gem::Requirement
|
163
|
+
requirements:
|
164
|
+
- - "~>"
|
165
|
+
- !ruby/object:Gem::Version
|
166
|
+
version: '0.19'
|
69
167
|
- !ruby/object:Gem::Dependency
|
70
168
|
name: tilt
|
71
169
|
requirement: !ruby/object:Gem::Requirement
|
@@ -83,7 +181,8 @@ dependencies:
|
|
83
181
|
description:
|
84
182
|
email:
|
85
183
|
- zach.ahn@gmail.com
|
86
|
-
executables:
|
184
|
+
executables:
|
185
|
+
- munge
|
87
186
|
extensions: []
|
88
187
|
extra_rdoc_files: []
|
89
188
|
files:
|
@@ -95,15 +194,37 @@ files:
|
|
95
194
|
- LICENSE.txt
|
96
195
|
- README.md
|
97
196
|
- Rakefile
|
197
|
+
- exe/munge
|
98
198
|
- lib/munge.rb
|
99
199
|
- lib/munge/application.rb
|
100
200
|
- lib/munge/attribute/content.rb
|
101
201
|
- lib/munge/attribute/metadata.rb
|
102
202
|
- lib/munge/attribute/path.rb
|
103
|
-
- lib/munge/
|
104
|
-
- lib/munge/source.rb
|
203
|
+
- lib/munge/cli.rb
|
204
|
+
- lib/munge/core/source.rb
|
205
|
+
- lib/munge/core/source/item_factory.rb
|
206
|
+
- lib/munge/core/transform.rb
|
207
|
+
- lib/munge/core/transform_scope_factory.rb
|
208
|
+
- lib/munge/core/write.rb
|
209
|
+
- lib/munge/helper.rb
|
210
|
+
- lib/munge/helper/find.rb
|
211
|
+
- 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
|
216
|
+
- lib/munge/runner.rb
|
217
|
+
- lib/munge/transformer/image_optim.rb
|
218
|
+
- lib/munge/transformer/tilt.rb
|
219
|
+
- lib/munge/transformer/tilt/scope.rb
|
105
220
|
- lib/munge/version.rb
|
106
221
|
- munge.gemspec
|
222
|
+
- seeds/Gemfile.tt
|
223
|
+
- seeds/config.yml
|
224
|
+
- seeds/data.yml
|
225
|
+
- seeds/layouts/default.html.erb
|
226
|
+
- seeds/rules.rb
|
227
|
+
- seeds/src/index.html
|
107
228
|
homepage: https://github.com/zachahn/munge
|
108
229
|
licenses:
|
109
230
|
- MIT
|
@@ -127,5 +248,5 @@ rubyforge_project:
|
|
127
248
|
rubygems_version: 2.4.5
|
128
249
|
signing_key:
|
129
250
|
specification_version: 4
|
130
|
-
summary:
|
251
|
+
summary: Static site generator aiming to simplify complex build rules
|
131
252
|
test_files: []
|
data/lib/munge/item.rb
DELETED
@@ -1,47 +0,0 @@
|
|
1
|
-
module Munge
|
2
|
-
class Item
|
3
|
-
def self.create(source_abspath, file_abspath)
|
4
|
-
path = Munge::Attribute::Path.new(source_abspath, file_abspath)
|
5
|
-
content = Munge::Attribute::Content.new(File.read(file_abspath))
|
6
|
-
metadata = Munge::Attribute::Metadata.new(file_abspath)
|
7
|
-
|
8
|
-
new(path, content, metadata)
|
9
|
-
end
|
10
|
-
|
11
|
-
def initialize(path, content, metadata)
|
12
|
-
@path = path
|
13
|
-
@content = content
|
14
|
-
@metadata = metadata
|
15
|
-
@route = nil
|
16
|
-
@layout = nil
|
17
|
-
end
|
18
|
-
|
19
|
-
attr_reader :path, :metadata
|
20
|
-
attr_accessor :route, :layout
|
21
|
-
|
22
|
-
def content
|
23
|
-
@content.content
|
24
|
-
end
|
25
|
-
|
26
|
-
def content=(new_content)
|
27
|
-
@content.content = new_content
|
28
|
-
end
|
29
|
-
|
30
|
-
def info
|
31
|
-
@content.frontmatter
|
32
|
-
end
|
33
|
-
|
34
|
-
def rendered_content
|
35
|
-
Tilt
|
36
|
-
.templates_for(@path.relative)
|
37
|
-
.inject(content) do |content, engine|
|
38
|
-
renderer = engine.new { content }
|
39
|
-
renderer.render(nil, info)
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
|
-
def rendered_output
|
44
|
-
rendered_content
|
45
|
-
end
|
46
|
-
end
|
47
|
-
end
|
data/lib/munge/source.rb
DELETED
@@ -1,22 +0,0 @@
|
|
1
|
-
module Munge
|
2
|
-
class Source
|
3
|
-
include Enumerable
|
4
|
-
|
5
|
-
def initialize(source_abspath)
|
6
|
-
@source_abspath = source_abspath
|
7
|
-
@pattern = File.join(source_abspath, "**", "*")
|
8
|
-
|
9
|
-
@items = Dir[@pattern]
|
10
|
-
.reject { |item_path| File.directory?(item_path) }
|
11
|
-
.map { |item_path| Item.create(source_abspath, item_path) }
|
12
|
-
end
|
13
|
-
|
14
|
-
def each
|
15
|
-
return enum_for(:each) unless block_given?
|
16
|
-
|
17
|
-
@items.each do |item|
|
18
|
-
yield item
|
19
|
-
end
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|