munge 0.3.0 → 0.4.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 1a6fdef4a9e19d71e01f67961124f1bc0ca14d46
4
- data.tar.gz: 1abf979491cce35a858f227f800402f7899d7efa
3
+ metadata.gz: 493a1b527391a30c807a1c358dda4c9854d1744f
4
+ data.tar.gz: cc9fbb10a2e927e85074b46d7e232477ade37928
5
5
  SHA512:
6
- metadata.gz: 14a64e75bf2ac7044816052bb9742819c1561c49335305f2ade3583ef9dfaeb4e685655bcb82440d4a40a5aa2766cee8409f0f090800d82ea11953c619775857
7
- data.tar.gz: b9152a9873565d2575137bd9e3c644af6c13fa3f1b937572d76d4e2a73e571fb843579211ed51a0c09ba1b93b3784bacb873f9e631b8db1a62ad993b4a1f95eb
6
+ metadata.gz: b4910b7a5825f85eeb970b4c2bc3b5699622f94d2085ad3dbeab5574531425d613fd5653adc5451988507a61b23c758e7a6c0d4f9ce6412591501ca63cbec5cb
7
+ data.tar.gz: 5e85a223fb27596e2fecb3c78ea4860be786c47d272e3d8a0979d1b9b1a05707a580e5b069cf0bde57f1ea14f792f4114af117397061706062e99af585d43a63
@@ -10,22 +10,24 @@ module Munge
10
10
  output_path = File.expand_path(config[:output], root_path)
11
11
  data_path = File.expand_path(config[:data], root_path)
12
12
 
13
- global_data = YAML.load_file(data_path) || {}
13
+ @global_data = YAML.load_file(data_path) || {}
14
14
 
15
- @source =
16
- Core::Source.new(
17
- source_abspath: source_path,
18
- binary_extensions: config[:binary_extensions],
19
- location: :fs_memory,
15
+ @item_factory =
16
+ Core::ItemFactory.new(
17
+ text_extensions: config[:text_extensions],
20
18
  ignored_basenames: config[:ignored_basenames]
21
19
  )
22
20
 
21
+ @source =
22
+ Core::Collection.new(
23
+ item_factory: @item_factory,
24
+ items: Reader::Filesystem.new(source_path)
25
+ )
26
+
23
27
  @layouts =
24
- Core::Source.new(
25
- source_abspath: layouts_path,
26
- binary_extensions: [],
27
- location: :fs_memory,
28
- ignored_basenames: []
28
+ Core::Collection.new(
29
+ item_factory: @item_factory,
30
+ items: Reader::Filesystem.new(layouts_path)
29
31
  )
30
32
 
31
33
  @router =
@@ -34,18 +36,15 @@ module Munge
34
36
  keep_extensions: config[:keep_extensions]
35
37
  )
36
38
 
37
- @transform =
38
- Core::Transform.new(
39
- global_data: global_data,
40
- layouts: @layouts,
41
- source: @source,
42
- router: @router
43
- )
39
+ @alterant =
40
+ Core::Alterant.new(scope: self)
44
41
 
45
42
  @writer =
46
43
  Core::Write.new(
47
44
  output: output_path
48
45
  )
46
+
47
+ @alterant.register(Transformer::Tilt.new(self))
49
48
  end
50
49
  # rubocop:enable Metrics/AbcSize, Metrics/MethodLength
51
50
 
@@ -58,7 +57,7 @@ module Munge
58
57
  end
59
58
 
60
59
  def build_virtual_item(*args)
61
- @source.build_virtual_item(*args)
60
+ @source.build(*args)
62
61
  end
63
62
 
64
63
  def create(*args, &block)
@@ -72,7 +71,7 @@ module Munge
72
71
  def render_and_write(item, &block)
73
72
  relpath = @router.filepath(item)
74
73
 
75
- write_status = @writer.write(relpath, @transform.call(item))
74
+ write_status = @writer.write(relpath, @alterant.transform(item))
76
75
 
77
76
  if block_given?
78
77
  block.call(item, write_status)
@@ -0,0 +1,43 @@
1
+ module Munge
2
+ module Core
3
+ class Alterant
4
+ def initialize(scope:)
5
+ @scope = scope
6
+ @registry = {}
7
+ end
8
+
9
+ def register(transformer)
10
+ register_manually(transformer.name, transformer)
11
+ end
12
+
13
+ # name should be snake_case Symbol
14
+ def register_manually(name, transformer)
15
+ if @registry.has_key?(name)
16
+ fail "already registered transformer `#{name}`"
17
+ else
18
+ @registry[name] = transformer
19
+ end
20
+ end
21
+
22
+ def transform(item)
23
+ item.transforms
24
+ .map { |name, args| [get_transformer(name), args] }
25
+ .inject(item.content) do |content, params|
26
+ transformer, args = params
27
+
28
+ transformer.call(item, content, *args)
29
+ end
30
+ end
31
+
32
+ private
33
+
34
+ def get_transformer(name)
35
+ if @registry.has_key?(name)
36
+ @registry[name]
37
+ else
38
+ fail "transformer `#{name}` is not installed"
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,49 @@
1
+ module Munge
2
+ module Core
3
+ class Collection
4
+ include Enumerable
5
+
6
+ def initialize(item_factory:,
7
+ items:)
8
+ @item_factory = item_factory
9
+
10
+ @items =
11
+ items
12
+ .map { |item| parse(**item) }
13
+ .map { |item| [item.id, item] }
14
+ .to_h
15
+ end
16
+
17
+ def build(**args)
18
+ @item_factory.build(**prune_args(args))
19
+ end
20
+
21
+ def parse(**args)
22
+ @item_factory.parse(**prune_args(args))
23
+ end
24
+
25
+ def each
26
+ return enum_for(:each) unless block_given?
27
+
28
+ @items.each_value do |item|
29
+ yield item
30
+ end
31
+ end
32
+
33
+ def push(virtual_item)
34
+ key = virtual_item.id
35
+ @items[key] = virtual_item
36
+ end
37
+
38
+ def [](id)
39
+ @items[id]
40
+ end
41
+
42
+ private
43
+
44
+ def prune_args(args)
45
+ args.select { |k, v| %i(relpath content frontmatter stat).include?(k) }
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,62 @@
1
+ module Munge
2
+ module Core
3
+ class ItemFactory
4
+ class ContentParser
5
+ def self.match(string)
6
+ string.match(/
7
+ # Start of string
8
+ \A
9
+ # Begin frontmatter
10
+ (?:^---\s*[\n\r]+)
11
+ # Capture frontmatter
12
+ (.*)
13
+ # End frontmatter
14
+ (?:^---\s*[\n\r]+)
15
+ /mx)
16
+ end
17
+
18
+ def self.parse(string)
19
+ matchdata = match(string)
20
+
21
+ [
22
+ parse_frontmatter(matchdata),
23
+ parse_content(matchdata, string)
24
+ ]
25
+ end
26
+
27
+ def self.parse_frontmatter(matchdata)
28
+ return {} if matchdata.nil?
29
+
30
+ parsed_frontmatter = YAML.load(matchdata[1])
31
+
32
+ if parsed_frontmatter
33
+ parsed_frontmatter
34
+ else
35
+ {}
36
+ end
37
+ end
38
+
39
+ def self.parse_content(matchdata, string)
40
+ if matchdata
41
+ matchdata.post_match
42
+ else
43
+ string
44
+ end
45
+ end
46
+
47
+ def initialize(string, frontmatter = nil)
48
+ @frontmatter, @content = self.class.parse(string)
49
+
50
+ if frontmatter
51
+ @frontmatter = @frontmatter.merge(frontmatter)
52
+ end
53
+ rescue ArgumentError
54
+ @frontmatter = frontmatter || {}
55
+ @content = string
56
+ end
57
+
58
+ attr_accessor :frontmatter, :content
59
+ end
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,126 @@
1
+ require_relative "item_factory/content_parser"
2
+
3
+ module Munge
4
+ module Core
5
+ class ItemFactory
6
+ def initialize(text_extensions:,
7
+ ignored_basenames:)
8
+ @text_extensions = Set.new(text_extensions)
9
+ @ignored_basenames = ignored_basenames
10
+ end
11
+
12
+ def build(relpath:,
13
+ content:,
14
+ frontmatter: {},
15
+ stat: nil)
16
+ type = compute_file_type(relpath)
17
+
18
+ id =
19
+ if type == :text
20
+ compute_id(relpath)
21
+ else
22
+ relpath
23
+ end
24
+
25
+ Munge::Item.new(
26
+ relpath: relpath,
27
+ content: content,
28
+ frontmatter: frontmatter,
29
+ stat: stat,
30
+ type: type,
31
+ id: id
32
+ )
33
+ end
34
+
35
+ def parse(relpath:,
36
+ content:,
37
+ stat: nil)
38
+ type = compute_file_type(relpath)
39
+
40
+ if type == :text
41
+ parsed = Munge::Core::ItemFactory::ContentParser.new(content)
42
+
43
+ build(
44
+ relpath: relpath,
45
+ content: parsed.content,
46
+ frontmatter: parsed.frontmatter,
47
+ stat: stat
48
+ )
49
+ else
50
+ build(
51
+ relpath: relpath,
52
+ content: content,
53
+ frontmatter: {},
54
+ stat: stat
55
+ )
56
+ end
57
+ end
58
+
59
+ private
60
+
61
+ def compute_content_and_frontmatter(abspath)
62
+ case @location
63
+ when :fs_memory
64
+ content = Munge::Attribute::Content.new(File.read(abspath))
65
+ [content.content, content.frontmatter]
66
+ when :fs, :virtual
67
+ ["", {}]
68
+ else
69
+ fail "invalid @location `#{@location}`"
70
+ end
71
+ end
72
+
73
+ def file_extensions(filepath)
74
+ extensions = File.basename(filepath).split(".")[1..-1]
75
+ Set.new(extensions)
76
+ end
77
+
78
+ def compute_file_type(abspath)
79
+ exts = file_extensions(abspath)
80
+
81
+ if exts.intersect?(@text_extensions)
82
+ :text
83
+ else
84
+ :binary
85
+ end
86
+ end
87
+
88
+ def compute_relpath(abspath)
89
+ folder = Pathname.new(@source_path)
90
+ file = Pathname.new(abspath)
91
+
92
+ file.relative_path_from(folder).to_s
93
+ end
94
+
95
+ def compute_stat(abspath)
96
+ File.stat(abspath)
97
+ end
98
+
99
+ def compute_id(relpath)
100
+ dirname = compute_dirname(relpath)
101
+ basename = compute_basename(relpath)
102
+
103
+ id = []
104
+
105
+ unless dirname == "."
106
+ id.push(dirname)
107
+ end
108
+
109
+ unless @ignored_basenames.include?(basename)
110
+ id.push(basename)
111
+ end
112
+
113
+ id.join("/")
114
+ end
115
+
116
+ def compute_dirname(relpath)
117
+ dirname = File.dirname(relpath)
118
+ end
119
+
120
+ def compute_basename(relpath)
121
+ filename = File.basename(relpath)
122
+ filename.split(".").first
123
+ end
124
+ end
125
+ end
126
+ end
@@ -6,29 +6,41 @@ module Munge
6
6
  renderers = tilt_renderer_list(item, engines)
7
7
  mdata = merged_data(item.frontmatter, data)
8
8
 
9
- manual_render(content, mdata, renderers)
9
+ render_string(content, data: mdata, engines: renderers)
10
10
  end
11
11
 
12
12
  def layout(item_or_string, data: {}, &block)
13
13
  layout_item = resolve_layout(item_or_string)
14
+ renderers = tilt_renderer_list(layout_item, nil)
14
15
  mdata = merged_data(layout_item.frontmatter, data)
15
16
 
16
- if block_given?
17
- if block.binding.local_variable_defined?(:_erbout)
18
- layout_within_template(layout_item, mdata, &block)
17
+ render_string(layout_item.content, data: mdata, engines: renderers, &block)
18
+ end
19
+
20
+ def render_string(content, data: {}, engines: [])
21
+ inner =
22
+ if block_given?
23
+ yield
19
24
  else
20
- layout_outside_template(layout_item, mdata, &block)
25
+ nil
26
+ end
27
+
28
+ engines
29
+ .inject(content) do |output, engine|
30
+ template = engine.new { output }
31
+
32
+ if inner
33
+ template.render(self, data) { inner }
34
+ else
35
+ template.render(self, data)
36
+ end
21
37
  end
22
- else
23
- layout_without_block(layout_item, mdata)
24
- end
25
38
  end
26
39
 
27
40
  def render_with_layout(item, content_engines: nil, data: {}, content_override: nil)
41
+ inner = render(item, engines: content_engines, data: data, content_override: content_override)
28
42
  mdata = merged_data(item.frontmatter, data)
29
43
 
30
- inner = render(item, engines: content_engines, data: mdata, content_override: content_override)
31
-
32
44
  if item.layout
33
45
  layout(item.layout, data: mdata) do
34
46
  inner
@@ -60,32 +72,6 @@ module Munge
60
72
  end
61
73
  end
62
74
 
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
- end
68
-
69
- def layout_within_template(layout_item, mdata, &block)
70
- original_erbout = block.binding.local_variable_get(:_erbout)
71
-
72
- block.binding.local_variable_set(:_erbout, "")
73
-
74
- result = layout_outside_template(layout_item, mdata) { block.call }
75
-
76
- final = original_erbout + result
77
-
78
- block.binding.local_variable_set(:_erbout, final)
79
-
80
- ""
81
- end
82
-
83
- def layout_without_block(layout_item, mdata)
84
- engine_list = tilt_renderer_list(layout_item, nil)
85
-
86
- manual_render(layout_item.content, mdata, engine_list)
87
- end
88
-
89
75
  def tilt_renderer_list(item, preferred_engine)
90
76
  if preferred_engine
91
77
  tilt_renderers_from_preferred(preferred_engine)
@@ -108,26 +94,6 @@ module Munge
108
94
 
109
95
  ::Tilt.templates_for(preferred)
110
96
  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
130
- end
131
97
  end
132
98
  end
133
99
  end
data/lib/munge/item.rb CHANGED
@@ -1,16 +1,12 @@
1
1
  module Munge
2
2
  class Item
3
3
  def initialize(type:,
4
- location:,
5
- abspath:,
6
4
  relpath:,
7
5
  id:,
8
6
  content: nil,
9
7
  frontmatter: {},
10
8
  stat: nil)
11
9
  @type = type
12
- @location = location
13
- @abspath = abspath
14
10
  @relpath = relpath
15
11
  @id = id
16
12
  @content = content
@@ -22,8 +18,8 @@ module Munge
22
18
  @transforms = []
23
19
  end
24
20
 
25
- attr_reader :type, :location
26
- attr_reader :abspath, :relpath, :id
21
+ attr_reader :type
22
+ attr_reader :relpath, :id
27
23
  attr_reader :content, :frontmatter
28
24
  attr_reader :stat
29
25
 
@@ -82,7 +78,7 @@ module Munge
82
78
  @layout = remove_surrounding_slashes(new_layout)
83
79
  end
84
80
 
85
- def transform(transformer = :Tilt, *args)
81
+ def transform(transformer = :tilt, *args)
86
82
  @transforms.push([transformer, args])
87
83
  end
88
84
 
@@ -0,0 +1,46 @@
1
+ module Munge
2
+ module Reader
3
+ class Filesystem
4
+ include Enumerable
5
+
6
+ def initialize(source_path)
7
+ @source_path = source_path
8
+ end
9
+
10
+ def each
11
+ return enum_for(:each) unless block_given?
12
+
13
+ filepaths =
14
+ Dir.glob(File.join(@source_path, "**", "*"))
15
+ .select { |path| File.file?(path) }
16
+
17
+ filepaths.each do |abspath|
18
+ filehash = Hash[
19
+ relpath: compute_relpath(abspath),
20
+ content: compute_content(abspath),
21
+ stat: compute_stat(abspath)
22
+ ]
23
+
24
+ yield filehash
25
+ end
26
+ end
27
+
28
+ private
29
+
30
+ def compute_stat(abspath)
31
+ File.stat(abspath)
32
+ end
33
+
34
+ def compute_relpath(abspath)
35
+ folder = Pathname.new(@source_path)
36
+ file = Pathname.new(abspath)
37
+
38
+ file.relative_path_from(folder).to_s
39
+ end
40
+
41
+ def compute_content(abspath)
42
+ File.read(abspath)
43
+ end
44
+ end
45
+ end
46
+ end
@@ -1,14 +1,27 @@
1
- require_relative "tilt/scope"
2
-
3
1
  module Munge
4
2
  module Transformer
5
3
  class Tilt
6
- def initialize(scope_factory)
7
- @scope = scope_factory.create
4
+ def initialize(scope)
5
+ @pristine_scope = scope
6
+ end
7
+
8
+ def name
9
+ :tilt
8
10
  end
9
11
 
10
12
  def call(item, content = nil, renderer = nil)
11
- @scope.render_with_layout(item, content_engines: renderer, content_override: content)
13
+ scope = @pristine_scope.dup
14
+ scope.instance_variable_set :@renderer, @renderer
15
+ dirty_scope = extend_with_helpers(scope)
16
+ dirty_scope.render_with_layout(item, content_engines: renderer, content_override: content)
17
+ end
18
+
19
+ private
20
+
21
+ def extend_with_helpers(scope)
22
+ Munge::Helper.constants
23
+ .map { |sym| Munge::Helper.const_get(sym) }
24
+ .inject(scope) { |scope, helper| scope.extend(helper) }
12
25
  end
13
26
  end
14
27
  end
data/lib/munge/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Munge
2
- VERSION = "0.3.0"
2
+ VERSION = "0.4.0"
3
3
  end
data/lib/munge.rb CHANGED
@@ -8,24 +8,18 @@ require "rack"
8
8
  require "tilt"
9
9
 
10
10
  require "munge/version"
11
- require "munge/attribute/content"
12
- require "munge/attribute/metadata"
13
- require "munge/attribute/path"
14
11
  require "munge/item"
15
12
  require "munge/helper"
16
13
  require "munge/helper/find"
17
14
  require "munge/helper/link"
18
15
  require "munge/helper/rendering"
19
16
  require "munge/transformer/tilt"
17
+ require "munge/readers/filesystem"
20
18
  require "munge/core/config"
21
19
  require "munge/core/router"
22
- require "munge/core/source"
23
- require "munge/core/transform"
24
- require "munge/core/transform_scope_factory"
20
+ require "munge/core/item_factory"
21
+ require "munge/core/collection"
25
22
  require "munge/core/write"
23
+ require "munge/core/alterant"
26
24
  require "munge/application"
27
25
  require "munge/runner"
28
-
29
- module Munge
30
- # Your code goes here...
31
- end
data/munge.gemspec CHANGED
@@ -32,8 +32,6 @@ Gem::Specification.new do |spec|
32
32
  spec.add_development_dependency "simplecov", "~> 0.10"
33
33
 
34
34
  spec.add_runtime_dependency "adsf", "~> 1.2"
35
- spec.add_runtime_dependency "image_optim", "~> 0.21"
36
- spec.add_runtime_dependency "image_optim_pack", "~> 0.2"
37
35
  spec.add_runtime_dependency "thor", "~> 0.19"
38
36
  spec.add_runtime_dependency "tilt", "~> 2.0"
39
37
  end
data/seeds/config.yml CHANGED
@@ -3,12 +3,11 @@ output: dest
3
3
  data: data.yml
4
4
  layouts: layouts
5
5
  index: index.html
6
- binary_extensions:
7
- - gif
8
- - ico
9
- - jpg
10
- - jpeg
11
- - png
6
+ text_extensions:
7
+ - html
8
+ - htm
9
+ - txt
10
+ - md
12
11
  ignored_basenames:
13
12
  - index
14
13
  keep_extensions:
data/seeds/rules.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  app.source
2
- .select { |item| item.id == "index" }
2
+ .select { |item| item.id == "" }
3
3
  .each { |item| item.route = "/" }
4
4
  .each { |item| item.layout = "default" }
5
5
  .each { |item| item.transform }
@@ -0,0 +1,5 @@
1
+ ---
2
+ title: Welcome
3
+ ---
4
+
5
+ <h1><%= title %></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.3.0
4
+ version: 0.4.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-14 00:00:00.000000000 Z
11
+ date: 2015-12-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -136,34 +136,6 @@ dependencies:
136
136
  - - "~>"
137
137
  - !ruby/object:Gem::Version
138
138
  version: '1.2'
139
- - !ruby/object:Gem::Dependency
140
- name: image_optim
141
- requirement: !ruby/object:Gem::Requirement
142
- requirements:
143
- - - "~>"
144
- - !ruby/object:Gem::Version
145
- version: '0.21'
146
- type: :runtime
147
- prerelease: false
148
- version_requirements: !ruby/object:Gem::Requirement
149
- requirements:
150
- - - "~>"
151
- - !ruby/object:Gem::Version
152
- version: '0.21'
153
- - !ruby/object:Gem::Dependency
154
- name: image_optim_pack
155
- requirement: !ruby/object:Gem::Requirement
156
- requirements:
157
- - - "~>"
158
- - !ruby/object:Gem::Version
159
- version: '0.2'
160
- type: :runtime
161
- prerelease: false
162
- version_requirements: !ruby/object:Gem::Requirement
163
- requirements:
164
- - - "~>"
165
- - !ruby/object:Gem::Version
166
- version: '0.2'
167
139
  - !ruby/object:Gem::Dependency
168
140
  name: thor
169
141
  requirement: !ruby/object:Gem::Requirement
@@ -192,7 +164,7 @@ dependencies:
192
164
  - - "~>"
193
165
  - !ruby/object:Gem::Version
194
166
  version: '2.0'
195
- description: Documentation for this release is located in https://github.com/zachahn/munge/blob/v0.3.0/README.md
167
+ description: Documentation for this release is located in https://github.com/zachahn/munge/blob/v0.4.0/README.md
196
168
  email:
197
169
  - zach.ahn@gmail.com
198
170
  executables:
@@ -211,26 +183,22 @@ files:
211
183
  - exe/munge
212
184
  - lib/munge.rb
213
185
  - lib/munge/application.rb
214
- - lib/munge/attribute/content.rb
215
- - lib/munge/attribute/metadata.rb
216
- - lib/munge/attribute/path.rb
217
186
  - lib/munge/cli.rb
187
+ - lib/munge/core/alterant.rb
188
+ - lib/munge/core/collection.rb
218
189
  - lib/munge/core/config.rb
190
+ - lib/munge/core/item_factory.rb
191
+ - lib/munge/core/item_factory/content_parser.rb
219
192
  - lib/munge/core/router.rb
220
- - lib/munge/core/source.rb
221
- - lib/munge/core/source/item_factory.rb
222
- - lib/munge/core/transform.rb
223
- - lib/munge/core/transform_scope_factory.rb
224
193
  - lib/munge/core/write.rb
225
194
  - lib/munge/helper.rb
226
195
  - lib/munge/helper/find.rb
227
196
  - lib/munge/helper/link.rb
228
197
  - lib/munge/helper/rendering.rb
229
198
  - lib/munge/item.rb
199
+ - lib/munge/readers/filesystem.rb
230
200
  - lib/munge/runner.rb
231
- - lib/munge/transformer/image_optim.rb
232
201
  - lib/munge/transformer/tilt.rb
233
- - lib/munge/transformer/tilt/scope.rb
234
202
  - lib/munge/version.rb
235
203
  - munge.gemspec
236
204
  - seeds/Gemfile.tt
@@ -238,7 +206,7 @@ files:
238
206
  - seeds/data.yml
239
207
  - seeds/layouts/default.html.erb
240
208
  - seeds/rules.rb
241
- - seeds/src/index.html
209
+ - seeds/src/index.html.erb
242
210
  homepage: https://github.com/zachahn/munge
243
211
  licenses:
244
212
  - MIT
@@ -1,60 +0,0 @@
1
- module Munge
2
- module Attribute
3
- class Content
4
- def self.match(string)
5
- string.match(/
6
- # Start of string
7
- \A
8
- # Begin frontmatter
9
- (?:^---\s*[\n\r]+)
10
- # Capture frontmatter
11
- (.*)
12
- # End frontmatter
13
- (?:^---\s*[\n\r]+)
14
- /mx)
15
- end
16
-
17
- def self.parse(string)
18
- matchdata = match(string)
19
-
20
- [
21
- parse_frontmatter(matchdata),
22
- parse_content(matchdata, string)
23
- ]
24
- end
25
-
26
- def self.parse_frontmatter(matchdata)
27
- return {} if matchdata.nil?
28
-
29
- parsed_frontmatter = YAML.load(matchdata[1])
30
-
31
- if parsed_frontmatter
32
- parsed_frontmatter
33
- else
34
- {}
35
- end
36
- end
37
-
38
- def self.parse_content(matchdata, string)
39
- if matchdata
40
- matchdata.post_match
41
- else
42
- string
43
- end
44
- end
45
-
46
- def initialize(string, frontmatter = nil)
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
55
- end
56
-
57
- attr_accessor :frontmatter, :content
58
- end
59
- end
60
- end
@@ -1,12 +0,0 @@
1
- module Munge
2
- module Attribute
3
- class Metadata
4
- def initialize(abspath)
5
- @abspath = abspath
6
- @stat = File::Stat.new(abspath)
7
- end
8
-
9
- attr_reader :stat
10
- end
11
- end
12
- end
@@ -1,44 +0,0 @@
1
- module Munge
2
- module Attribute
3
- class Path
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)
10
- end
11
-
12
- attr_reader :relative, :absolute, :basename, :extnames, :dirname
13
-
14
- private
15
-
16
- def resolve_relative(source_path, file_path)
17
- folder = Pathname.new(source_path)
18
- file = Pathname.new(file_path)
19
-
20
- file.relative_path_from(folder).to_s
21
- end
22
-
23
- def resolve_basename(file_path)
24
- file_name = File.basename(file_path)
25
- file_name_parts = file_name.split(".")
26
-
27
- file_name_parts.first
28
- end
29
-
30
- def resolve_extnames(file_path)
31
- file_name = File.basename(file_path)
32
- file_name_parts = file_name.split(".")
33
-
34
- file_name_parts[1..-1]
35
- end
36
-
37
- def resolve_dirname(relpath)
38
- relpath_with_prefix_slash = File.join("/", relpath)
39
- dirname = File.dirname(relpath_with_prefix_slash)
40
- File.join(dirname[1..-1], "/")
41
- end
42
- end
43
- end
44
- end
@@ -1,109 +0,0 @@
1
- module Munge
2
- class ItemFactory
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
11
- end
12
-
13
- def read(abspath)
14
- content, frontmatter = compute_content_and_frontmatter(abspath)
15
-
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
- ["", {}]
52
- else
53
- fail "invalid @location `#{@location}`"
54
- end
55
- end
56
-
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
71
-
72
- def compute_relpath(abspath)
73
- folder = Pathname.new(@source_path)
74
- file = Pathname.new(abspath)
75
-
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
103
-
104
- def compute_basename(relpath)
105
- filename = File.basename(relpath)
106
- filename.split(".").first
107
- end
108
- end
109
- end
@@ -1,51 +0,0 @@
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:,
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, "**", "*")
20
-
21
- @items =
22
- Dir.glob(pattern)
23
- .reject { |item_path| File.directory?(item_path) }
24
- .map { |item_path| @item_factory.read(item_path) }
25
- .map { |item| [item.id, item] }
26
- .to_h
27
- end
28
-
29
- def build_virtual_item(*args)
30
- @item_factory.build_virtual(*args)
31
- end
32
-
33
- def each
34
- return enum_for(:each) unless block_given?
35
-
36
- @items.each_value do |item|
37
- yield item
38
- end
39
- end
40
-
41
- def push(virtual_item)
42
- key = virtual_item.id
43
- @items[key] = virtual_item
44
- end
45
-
46
- def [](id)
47
- @items[id]
48
- end
49
- end
50
- end
51
- end
@@ -1,51 +0,0 @@
1
- module Munge
2
- module Core
3
- class Transform
4
- def initialize(layouts:,
5
- global_data:,
6
- source:,
7
- router:)
8
- @scope_factory = Core::TransformScopeFactory.new(
9
- layouts: layouts,
10
- global_data: global_data,
11
- source: source,
12
- helper_container: Munge::Helper,
13
- router: router
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
@@ -1,42 +0,0 @@
1
- module Munge
2
- module Core
3
- class TransformScopeFactory
4
- def initialize(layouts:,
5
- global_data:,
6
- source:,
7
- helper_container:,
8
- router:)
9
- @layouts = layouts
10
- @global_data = global_data
11
- @source = source
12
- @helper_container = helper_container
13
- @router = router
14
- end
15
-
16
- def create(load_helpers = true)
17
- scope = Munge::Transformer::Tilt::Scope.new(
18
- layouts: @layouts,
19
- global_data: @global_data,
20
- source: @source,
21
- router: @router
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
@@ -1,20 +0,0 @@
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
@@ -1,17 +0,0 @@
1
- module Munge
2
- module Transformer
3
- class Tilt
4
- class Scope
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
13
- end
14
- end
15
- end
16
- end
17
- end
data/seeds/src/index.html DELETED
@@ -1 +0,0 @@
1
- <h1>Welcome</h1>