dimples 6.5.3 → 7.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
  SHA256:
3
- metadata.gz: 29f825d2b0c07f416c9d14934cd4de922a57d7f8ffc63a6212b4a7a37f3a17be
4
- data.tar.gz: 9b90c34993bd637ab9c74e446b4c755bba9ab74ca93d7213a6c7f41c49a02964
3
+ metadata.gz: 882aeff0d91ba61d58f331bedabeba0c865dbb7ef355c1fdafde7e1605113d2e
4
+ data.tar.gz: 8ddfc8ea5bcbce38a35c8d0153f96adc4866f5529a074884e966b92a65dce642
5
5
  SHA512:
6
- metadata.gz: 1d11b6b61a326e236cbcf61f70601c16bdff017b7c8751696c7e5c7dfc986be513bab79af18e29e9b8628ccc77f49e946778980d97f56a83eefd98398b8db03a
7
- data.tar.gz: e54743e65c9b6523bfd62d60d832222525486aba0daa92704ed0601bee1c09fa2a72a143aec44e8f7a7e6a1089eb016825ba486d8d9132dbb9696e2ea0977701
6
+ metadata.gz: cc9caa2de2a10ac6a30f84876ad3a3e9bd070b2e3e9783f38763035d286ec46d55343fa6fbf5cb44c6b72fe3c67d773af7918cbcb714cdb10f2c4b4a6b52b1e4
7
+ data.tar.gz: 04510c31f0ee4de0d1e035ddf56003f12e4553bdaaf1b4a8f82d24c0344bae443443b8d4f73c58e6ae7c3a5447e73f734f315964c30dcb400f85b28fa9066042
data/bin/dimples CHANGED
@@ -4,79 +4,11 @@
4
4
  $LOAD_PATH.unshift(File.join(__dir__, '..', 'lib'))
5
5
 
6
6
  require 'dimples'
7
- require 'dimples/version'
8
- require 'optimist'
9
- require 'json'
10
7
 
11
- trap('SIGINT') do
12
- puts 'Generation cancelled!'
13
- exit!
14
- end
8
+ path = if ARGV[0]
9
+ File.expand_path(ARGV[0])
10
+ else
11
+ File.join(Dir.pwd(), 'site')
12
+ end
15
13
 
16
- valid_commands = %w[build]
17
-
18
- options = Optimist.options do
19
- version "dimples v#{Dimples::VERSION}"
20
- banner <<-BANNER
21
- A simple static site generator.
22
-
23
- Usage:
24
- dimples <#{valid_commands.join('|')}> [options]
25
-
26
- Options:
27
- BANNER
28
-
29
- opt :config, 'Config file path', type: :string
30
- opt :source, 'Source directory', type: :string
31
- opt :destination, 'Destination directory', type: :string
32
- end
33
-
34
- Optimist.educate if ARGV.empty?
35
- command = ARGV[0]
36
-
37
- unless valid_commands.include?(command)
38
- Optimist.die "Command must be '#{valid_commands.join('\', \'')}'"
39
- end
40
-
41
- source_path = if options[:source]
42
- File.expand_path(options[:source])
43
- else
44
- Dir.pwd
45
- end
46
-
47
- config_path = options[:config] || File.join(source_path, 'config.json')
48
-
49
- unless File.exist?(config_path)
50
- Optimist.die "Unable to find config file (#{config_path})"
51
- end
52
-
53
- begin
54
- file_contents = File.read(config_path)
55
- Optimist.die "Config file is empty (#{config_path})" if file_contents.empty?
56
-
57
- config = JSON.parse(file_contents, symbolize_names: true)
58
- rescue JSON::ParserError
59
- Optimist.die "Invalid or malformed config file (#{config_path})"
60
- end
61
-
62
- config[:source] = source_path
63
-
64
- if options[:destination]
65
- config[:destination] = File.expand_path(options[:destination])
66
- end
67
-
68
- site = Dimples::Site.new(config)
69
-
70
- case command.to_sym
71
- when :build
72
- puts 'Building site...'
73
-
74
- site.generate
75
-
76
- if site.errors.empty?
77
- puts "Done! Your site has been built in #{site.paths[:destination]}."
78
- else
79
- puts 'Generation failed:'
80
- site.errors.each { |error| puts error }
81
- end
82
- end
14
+ Dimples::Site.generate(path)
@@ -0,0 +1,70 @@
1
+ require 'yaml'
2
+
3
+ module Dimples
4
+ class Document
5
+ FRONT_MATTER_PATTERN = /^(-{3}\n.*?\n?)^(-{3}*$\n?)/m.freeze
6
+
7
+ attr_accessor :metadata, :contents, :path, :rendered_contents
8
+
9
+ def initialize(path = nil)
10
+ @path = path
11
+ @metadata = {}
12
+
13
+ if @path
14
+ @contents = File.read(path)
15
+
16
+ if matches = contents.match(FRONT_MATTER_PATTERN)
17
+ @metadata = YAML.load(matches[1], symbolize_names: true)
18
+ @contents = matches.post_match.strip
19
+ end
20
+ end
21
+ end
22
+
23
+ def filename
24
+ "#{basename}.#{extension}"
25
+ end
26
+
27
+ def basename
28
+ @metadata.fetch(:filename, 'index')
29
+ end
30
+
31
+ def extension
32
+ @metadata.fetch(:extension, 'html')
33
+ end
34
+
35
+ def layout
36
+ @metadata.fetch(:layout, nil)
37
+ end
38
+
39
+ def render(context = {}, content = '')
40
+ context_obj = Object.new
41
+ context.each do |key, value|
42
+ context_obj.instance_variable_set("@#{key}", value)
43
+ end
44
+
45
+ @rendered_contents = renderer.render(context_obj) { content }
46
+ end
47
+
48
+ private
49
+
50
+ def renderer
51
+ @renderer ||= begin
52
+ callback = proc { contents }
53
+
54
+ if @path
55
+ Tilt.new(@path, {}, &callback)
56
+ else
57
+ Tilt::StringTemplate.new(&callback)
58
+ end
59
+ end
60
+ end
61
+
62
+ def method_missing(method_name, *args, &block)
63
+ if @metadata.key?(method_name)
64
+ @metadata[method_name]
65
+ else
66
+ nil
67
+ end
68
+ end
69
+ end
70
+ end
data/lib/dimples/page.rb CHANGED
@@ -1,69 +1,6 @@
1
- # frozen_string_literal: true
1
+ require_relative 'document'
2
2
 
3
3
  module Dimples
4
- # A single page on a site.
5
- class Page
6
- attr_accessor :contents
7
- attr_accessor :metadata
8
- attr_accessor :path
9
-
10
- def initialize(site, path = nil)
11
- @site = site
12
- @path = path
13
-
14
- if @path
15
- data = File.read(@path)
16
- @contents, @metadata = FrontMatter.parse(data)
17
- else
18
- @contents = ''
19
- @metadata = {}
20
- end
21
- end
22
-
23
- def filename
24
- @metadata[:filename] || 'index'
25
- end
26
-
27
- def extension
28
- @metadata[:extension] || 'html'
29
- end
30
-
31
- def render(context = {})
32
- metadata = @metadata.dup
33
- metadata.merge!(context[:page]) if context[:page]
34
-
35
- context[:page] = Hashie::Mash.new(metadata)
36
-
37
- renderer.render(context)
38
- end
39
-
40
- def write(output_directory, context = {})
41
- FileUtils.mkdir_p(output_directory) unless Dir.exist?(output_directory)
42
- output_path = File.join(output_directory, "#{filename}.#{extension}")
43
-
44
- File.write(output_path, render(context))
45
- rescue SystemCallError => e
46
- raise PublishingError, "Failed to publish file at #{output_path} (#{e})"
47
- end
48
-
49
- private
50
-
51
- def renderer
52
- @renderer ||= Renderer.new(@site, self)
53
- end
54
-
55
- def method_missing(method_name, *args, &block)
56
- if @metadata.key?(method_name)
57
- @metadata[method_name]
58
- elsif (matches = method_name.match(/([a-z_]+)=/))
59
- @metadata[matches[1].to_sym] = args[0]
60
- else
61
- super
62
- end
63
- end
64
-
65
- def respond_to_missing?(method_name, include_private = false)
66
- @metadata.key?(method_name) || method_name.match?(/([a-z_]+)=/) || super
67
- end
4
+ class Page < Document
68
5
  end
69
6
  end
data/lib/dimples/pager.rb CHANGED
@@ -1,9 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Dimples
4
- # A paginated collection of posts that can be walked forward or backwards.
5
4
  class Pager
6
- PER_PAGE_DEFAULT = 10
5
+ PER_PAGE = 5
7
6
 
8
7
  include Enumerable
9
8
 
@@ -11,37 +10,12 @@ module Dimples
11
10
  attr_reader :previous_page
12
11
  attr_reader :next_page
13
12
  attr_reader :page_count
14
- attr_reader :item_count
15
-
16
- def self.paginate(site, posts, path, layout, context = {})
17
- pager = Pager.new(
18
- path.sub(site.paths[:destination], '') + '/',
19
- posts,
20
- site.config.pagination
21
- )
22
-
23
- pager.each do |index|
24
- page = Page.new(site)
25
- page.layout = layout
26
-
27
- page_path = if index == 1
28
- path
29
- else
30
- File.join(path, "page_#{index}")
31
- end
32
-
33
- page.write(
34
- page_path,
35
- context.merge(pagination: pager.to_context)
36
- )
37
- end
38
- end
39
13
 
40
- def initialize(url, posts, options = {})
14
+ def initialize(url, posts)
41
15
  @url = url
42
16
  @posts = posts
43
- @per_page = options[:per_page] || PER_PAGE_DEFAULT
44
- @page_prefix = options[:page_prefix] || 'page_'
17
+ @per_page = PER_PAGE
18
+ @page_prefix = 'page_'
45
19
  @page_count = (posts.length.to_f / @per_page.to_i).ceil
46
20
 
47
21
  step_to(1)
@@ -94,7 +68,7 @@ module Dimples
94
68
  end
95
69
 
96
70
  def to_context
97
- Hashie::Mash.new(
71
+ {
98
72
  posts: posts_at(current_page),
99
73
  current_page: @current_page,
100
74
  page_count: @page_count,
@@ -108,7 +82,7 @@ module Dimples
108
82
  previous_page: previous_page_url,
109
83
  next_page: next_page_url
110
84
  }
111
- )
85
+ }
112
86
  end
113
87
  end
114
88
  end
data/lib/dimples/post.rb CHANGED
@@ -1,33 +1,19 @@
1
- # frozen_string_literal: true
1
+ require_relative 'document'
2
2
 
3
- module Dimples
4
- # A single dated post on a site.
5
- class Post < Page
6
- POST_FILENAME = /(\d{4})-(\d{2})-(\d{2})-(.+)/.freeze
7
-
8
- def initialize(site, path)
9
- super
10
-
11
- parts = File.basename(path, File.extname(path)).match(POST_FILENAME)
12
-
13
- @metadata[:layout] ||= @site.config.layouts.post
3
+ require 'date'
14
4
 
15
- @metadata[:date] = Date.new(parts[1].to_i, parts[2].to_i, parts[3].to_i)
16
- @metadata[:slug] = parts[4]
17
- @metadata[:categories] ||= []
18
- @metadata[:draft] ||= false
19
- end
20
-
21
- def year
22
- @year ||= @metadata[:date].strftime('%Y')
5
+ module Dimples
6
+ class Post < Document
7
+ def date
8
+ @metadata.fetch(:date, DateTime.now)
23
9
  end
24
10
 
25
- def month
26
- @month ||= @metadata[:date].strftime('%m')
11
+ def layout
12
+ @metadata.fetch(:layout, 'post')
27
13
  end
28
14
 
29
- def day
30
- @day ||= @metadata[:date].strftime('%d')
15
+ def slug
16
+ File.basename(@path, '.markdown')
31
17
  end
32
18
  end
33
19
  end
data/lib/dimples/site.rb CHANGED
@@ -1,164 +1,125 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require_relative 'pager'
4
+
5
+ require 'fileutils'
6
+ require 'tilt'
7
+
3
8
  module Dimples
4
- # A collection of pages, posts and templates that can generate a website.
5
9
  class Site
6
- attr_reader :config
7
- attr_reader :categories
8
- attr_reader :errors
9
- attr_reader :paths
10
- attr_reader :posts
11
- attr_reader :pages
12
- attr_reader :archive
13
- attr_reader :templates
14
- attr_reader :latest_post
15
-
16
- def initialize(config = {})
17
- @config = Configuration.prepare(config)
18
-
19
- @paths = {}.tap do |paths|
20
- paths[:source] = File.expand_path(@config.source)
21
- paths[:destination] = File.expand_path(@config.destination)
22
-
23
- %w[pages posts static templates].each do |type|
24
- paths[type.to_sym] = File.join(paths[:source], type)
25
- end
10
+ def self.generate(output_path)
11
+ new(output_path).generate
12
+ end
13
+
14
+ attr_accessor :posts, :categories
15
+
16
+ def initialize(output_path)
17
+ @paths = {
18
+ source: File.expand_path(Dir.pwd),
19
+ destination: File.expand_path(output_path)
20
+ }
21
+
22
+ %w[pages posts static templates].each do |type|
23
+ @paths[type.to_sym] = File.join(@paths[:source], type)
26
24
  end
27
25
 
28
- prepare
26
+ scan_posts
27
+ scan_pages
28
+ scan_templates
29
29
  end
30
30
 
31
31
  def generate
32
- prepare
32
+ if Dir.exist?(@paths[:destination])
33
+ puts "Error: The output directory (#{@paths[:destination]}) already exists."
34
+ return
35
+ end
33
36
 
34
- read_templates
35
- read_posts
36
- read_pages
37
+ Dir.mkdir(@paths[:destination])
37
38
 
38
- create_output_directory
39
- copy_static_assets
39
+ generate_posts
40
+ generate_pages
41
+ generate_categories
40
42
 
41
- publish_posts
42
- publish_pages
43
- publish_archives if @config.generation.year_archives
44
- publish_categories if @config.generation.categories
45
- rescue PublishingError, RenderingError, GenerationError => e
46
- @errors << e
43
+ copy_assets
47
44
  end
48
45
 
49
- def data
50
- @config.data || {}
51
- end
46
+ private
52
47
 
53
- def inspect
54
- "#<#{self.class} @paths=#{paths}>"
48
+ def read_files(path)
49
+ Dir[File.join(path, '**', '*.*')].sort
55
50
  end
56
51
 
57
- private
52
+ def scan_posts
53
+ @posts = read_files(@paths[:posts]).map do |path|
54
+ Dimples::Post.new(path)
55
+ end
58
56
 
59
- def prepare
60
- @archive = Dimples::Archive.new
57
+ @posts.sort_by! { |post| post.date }.reverse!
61
58
 
62
59
  @categories = {}
63
- @templates = {}
64
-
65
- @pages = []
66
- @posts = []
67
- @errors = []
68
60
 
69
- @latest_post = nil
61
+ @posts.each do |post|
62
+ post.categories.each do |category|
63
+ @categories[category] ||= []
64
+ @categories[category] << post
65
+ end
66
+ end
70
67
  end
71
68
 
72
- def read_files(path)
73
- Dir[File.join(path, '**', '*.*')].sort
69
+ def scan_pages
70
+ @pages = read_files(@paths[:pages]).map do |path|
71
+ Dimples::Page.new(path)
72
+ end
74
73
  end
75
74
 
76
- def read_templates
77
- @templates = {}
78
-
79
- read_files(@paths[:templates]).each do |path|
80
- basename = File.basename(path, File.extname(path))
81
- dir_name = File.dirname(path)
82
-
83
- unless dir_name == @paths[:templates]
84
- basename = dir_name.split(File::SEPARATOR)[-1] + '.' + basename
75
+ def scan_templates
76
+ @templates = {}.tap do |templates|
77
+ read_files(@paths[:templates]).each do |path|
78
+ key = File.basename(path, '.erb')
79
+ templates[key] = Dimples::Template.new(path)
85
80
  end
86
-
87
- @templates[basename] = Template.new(self, path)
88
81
  end
89
82
  end
90
83
 
91
- def read_posts
92
- @posts = read_files(@paths[:posts]).map do |path|
93
- Post.new(self, path).tap do |post|
94
- @archive.add_post(post)
95
- categorise_post(post)
96
- end
97
- end.reverse
84
+ def write_file(path, content)
85
+ directory_path = File.dirname(path)
98
86
 
99
- @latest_post = @posts[0]
87
+ Dir.mkdir(directory_path) unless Dir.exist?(directory_path)
88
+ File.write(path, content)
100
89
  end
101
90
 
102
- def read_pages
103
- @pages = read_files(@paths[:pages]).map { |path| Page.new(self, path) }
104
- end
91
+ def generate_paginated_posts(posts, path, context = {})
92
+ pager = Dimples::Pager.new(path.sub(@paths[:destination], '') + '/', posts)
105
93
 
106
- def categorise_post(post)
107
- post.categories.each do |slug|
108
- slug_sym = slug.to_sym
94
+ pager.each do |index|
95
+ page = Dimples::Page.new()
96
+ page.metadata[:layout] = 'posts'
109
97
 
110
- @categories[slug_sym] ||= Category.new(self, slug)
111
- @categories[slug_sym].posts << post
112
- end
113
- end
98
+ page_path = if index == 1
99
+ path
100
+ else
101
+ File.join(path, "page_#{index}")
102
+ end
114
103
 
115
- def create_output_directory
116
- if Dir.exist?(@paths[:destination])
117
- FileUtils.rm_r(@paths[:destination], secure: true)
118
- else
119
- FileUtils.mkdir_p(@paths[:destination])
104
+ context.merge!(pagination: pager.to_context)
105
+ write_file(File.join(page_path, page.filename), render(page, context))
120
106
  end
121
- rescue StandardError => e
122
- message = "Couldn't prepare the output directory (#{e.message})"
123
- raise GenerationError, message
124
107
  end
125
108
 
126
- def copy_static_assets
127
- return unless Dir.exist?(@paths[:static])
128
-
129
- FileUtils.cp_r(File.join(@paths[:static], '.'), @paths[:destination])
130
- rescue StandardError => e
131
- raise GenerationError, "Failed to copy site assets (#{e.message})"
132
- end
109
+ def generate_posts
110
+ directory_path = File.join(@paths[:destination], 'posts')
111
+ Dir.mkdir(directory_path)
133
112
 
134
- def publish_posts
135
113
  @posts.each do |post|
136
- path = File.join(
137
- @paths[:destination],
138
- post.date.strftime(post.draft ? @config.paths.drafts : @config.paths.posts),
139
- post.slug
140
- )
141
-
142
- post.write(path)
114
+ path = File.join(directory_path, post.slug, post.filename)
115
+ write_file(path, render(post, post: post))
143
116
  end
144
117
 
145
- published_posts = @posts.select { |post| !post.draft }
146
-
147
- if @config.generation.main_feed
148
- publish_feeds(published_posts, @paths[:destination])
149
- end
150
-
151
- return unless @config.generation.paginated_posts
152
-
153
- Dimples::Pager.paginate(
154
- self,
155
- published_posts,
156
- File.join(@paths[:destination], @config.paths.paginated_posts),
157
- @config.layouts.paginated_post
158
- )
118
+ generate_paginated_posts(@posts, directory_path)
119
+ generate_feed(@posts.slice(0, 10), @paths[:destination])
159
120
  end
160
121
 
161
- def publish_pages
122
+ def generate_pages
162
123
  @pages.each do |page|
163
124
  path = if page.path
164
125
  File.dirname(page.path).sub(
@@ -169,82 +130,41 @@ module Dimples
169
130
  @paths[:destination]
170
131
  end
171
132
 
172
- page.write(path)
133
+ write_file(File.join(path, page.filename), render(page, page: page))
173
134
  end
174
135
  end
175
136
 
176
- def publish_archives
177
- @archive.years.each do |year|
178
- publish_archive(year)
179
- next unless @config.generation.month_archives
180
-
181
- @archive.months(year).each do |month|
182
- publish_archive(year, month)
183
- next unless @config.generation.day_archives
137
+ def generate_categories
138
+ @categories.each do |category, posts|
139
+ category_path = File.join(@paths[:destination], 'categories', category)
184
140
 
185
- @archive.days(year, month).each do |day|
186
- publish_archive(year, month, day)
187
- end
188
- end
141
+ generate_paginated_posts(posts, category_path, category: category)
142
+ generate_feed(posts.slice(0, 10), category_path)
189
143
  end
190
144
  end
191
145
 
192
- def publish_archive(year, month = nil, day = nil)
193
- date_type = if day
194
- 'day'
195
- elsif month
196
- 'month'
197
- else
198
- 'year'
199
- end
200
-
201
- posts = @archive.posts_for_date(year, month, day)
202
-
203
- date_parts = [year, month, day].compact
204
- path = File.join(@paths[:destination], @config.paths.archives, date_parts)
205
- layout = @config.layouts.date_archive
206
-
207
- data = {
208
- page: {
209
- title: posts[0].date.strftime(@config.date_formats[date_type]),
210
- archive_date: posts[0].date,
211
- archive_type: date_type
212
- }
213
- }
146
+ def generate_feed(posts, path)
147
+ page = Dimples::Page.new()
148
+ page.metadata[:layout] = 'feed'
214
149
 
215
- Dimples::Pager.paginate(self, posts.reverse, path, layout, data)
150
+ write_file(File.join(path, 'feed.atom'), render(page, posts: posts))
216
151
  end
217
152
 
218
- def publish_categories
219
- @categories.each_value do |category|
220
- path = File.join(
221
- @paths[:destination],
222
- @config.paths.categories,
223
- category.slug
224
- )
225
-
226
- category_posts = category.posts.reverse
227
- context = { page: { title: category.name, category: category } }
228
-
229
- Dimples::Pager.paginate(
230
- self,
231
- category_posts,
232
- path,
233
- @config.layouts.category,
234
- context
235
- )
236
-
237
- publish_feeds(category_posts, path, context)
238
- end
153
+ def copy_assets
154
+ return unless Dir.exist?(@paths[:static])
155
+ FileUtils.cp_r(File.join(@paths[:static], '.'), @paths[:destination])
239
156
  end
240
157
 
241
- def publish_feeds(posts, path, context = {})
242
- @config.feed_formats.each do |format|
243
- feed = Feed.new(self, format)
158
+ def render(object, context = {}, content = nil)
159
+ context[:site] ||= self
160
+
161
+ output = object.render(context, content)
244
162
 
245
- feed.feed_posts = posts.slice(0, @config.pagination.per_page)
246
- feed.write(path, context)
163
+ if object.layout && @templates[object.layout]
164
+ output = render(@templates[object.layout], context, output)
247
165
  end
166
+
167
+ output
248
168
  end
249
169
  end
250
170
  end
@@ -1,29 +1,6 @@
1
- # frozen_string_literal: true
1
+ require_relative 'document'
2
2
 
3
3
  module Dimples
4
- # A single template used when rendering pages, posts and other templates.
5
- class Template
6
- attr_accessor :path
7
- attr_accessor :contents
8
- attr_accessor :metadata
9
-
10
- def initialize(site, path)
11
- @site = site
12
- @path = path
13
-
14
- data = File.read(path)
15
- @contents, @metadata = FrontMatter.parse(data)
16
- end
17
-
18
- def render(context = {}, body = nil)
19
- context[:template] ||= Hashie::Mash.new(@metadata)
20
- renderer.render(context, body)
21
- end
22
-
23
- private
24
-
25
- def renderer
26
- @renderer ||= Renderer.new(@site, self)
27
- end
4
+ class Template < Document
28
5
  end
29
6
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Dimples
4
- VERSION = '6.5.3'
4
+ VERSION = '7.0'
5
5
  end
data/lib/dimples.rb CHANGED
@@ -2,22 +2,7 @@
2
2
 
3
3
  $LOAD_PATH.unshift(__dir__)
4
4
 
5
- require 'fileutils'
6
- require 'hashie'
7
- require 'tilt'
8
- require 'yaml'
9
-
10
- require 'dimples/archive'
11
- require 'dimples/category'
12
- require 'dimples/configuration'
13
- require 'dimples/errors'
14
- require 'dimples/frontmatter'
15
- require 'dimples/pager'
16
- require 'dimples/renderer'
17
-
18
5
  require 'dimples/page'
19
- require 'dimples/feed'
20
6
  require 'dimples/post'
21
7
  require 'dimples/template'
22
-
23
8
  require 'dimples/site'
metadata CHANGED
@@ -1,49 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dimples
3
3
  version: !ruby/object:Gem::Version
4
- version: 6.5.3
4
+ version: '7.0'
5
5
  platform: ruby
6
6
  authors:
7
7
  - Daniel Bogan
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-01-28 00:00:00.000000000 Z
11
+ date: 2022-08-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: hashie
14
+ name: erubi
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '3.5'
20
- - - ">="
21
- - !ruby/object:Gem::Version
22
- version: 3.5.7
23
- type: :runtime
24
- prerelease: false
25
- version_requirements: !ruby/object:Gem::Requirement
26
- requirements:
27
- - - "~>"
28
- - !ruby/object:Gem::Version
29
- version: '3.5'
30
- - - ">="
31
- - !ruby/object:Gem::Version
32
- version: 3.5.7
33
- - !ruby/object:Gem::Dependency
34
- name: optimist
35
- requirement: !ruby/object:Gem::Requirement
36
- requirements:
37
- - - "~>"
38
- - !ruby/object:Gem::Version
39
- version: '3.0'
19
+ version: '1.10'
40
20
  type: :runtime
41
21
  prerelease: false
42
22
  version_requirements: !ruby/object:Gem::Requirement
43
23
  requirements:
44
24
  - - "~>"
45
25
  - !ruby/object:Gem::Version
46
- version: '3.0'
26
+ version: '1.10'
47
27
  - !ruby/object:Gem::Dependency
48
28
  name: tilt
49
29
  requirement: !ruby/object:Gem::Requirement
@@ -59,115 +39,47 @@ dependencies:
59
39
  - !ruby/object:Gem::Version
60
40
  version: '2.0'
61
41
  - !ruby/object:Gem::Dependency
62
- name: codeclimate-test-reporter
63
- requirement: !ruby/object:Gem::Requirement
64
- requirements:
65
- - - ">="
66
- - !ruby/object:Gem::Version
67
- version: 1.0.0
68
- - - "~>"
69
- - !ruby/object:Gem::Version
70
- version: '1.0'
71
- type: :development
72
- prerelease: false
73
- version_requirements: !ruby/object:Gem::Requirement
74
- requirements:
75
- - - ">="
76
- - !ruby/object:Gem::Version
77
- version: 1.0.0
78
- - - "~>"
79
- - !ruby/object:Gem::Version
80
- version: '1.0'
81
- - !ruby/object:Gem::Dependency
82
- name: erubis
42
+ name: redcarpet
83
43
  requirement: !ruby/object:Gem::Requirement
84
44
  requirements:
85
45
  - - "~>"
86
46
  - !ruby/object:Gem::Version
87
- version: '2.7'
88
- type: :development
47
+ version: '3.5'
48
+ type: :runtime
89
49
  prerelease: false
90
50
  version_requirements: !ruby/object:Gem::Requirement
91
51
  requirements:
92
52
  - - "~>"
93
53
  - !ruby/object:Gem::Version
94
- version: '2.7'
54
+ version: '3.5'
95
55
  - !ruby/object:Gem::Dependency
96
56
  name: rake
97
57
  requirement: !ruby/object:Gem::Requirement
98
58
  requirements:
99
59
  - - "~>"
100
60
  - !ruby/object:Gem::Version
101
- version: '10.0'
61
+ version: 12.3.3
102
62
  type: :development
103
63
  prerelease: false
104
64
  version_requirements: !ruby/object:Gem::Requirement
105
65
  requirements:
106
66
  - - "~>"
107
67
  - !ruby/object:Gem::Version
108
- version: '10.0'
109
- - !ruby/object:Gem::Dependency
110
- name: redcarpet
111
- requirement: !ruby/object:Gem::Requirement
112
- requirements:
113
- - - "~>"
114
- - !ruby/object:Gem::Version
115
- version: '3.3'
116
- type: :development
117
- prerelease: false
118
- version_requirements: !ruby/object:Gem::Requirement
119
- requirements:
120
- - - "~>"
121
- - !ruby/object:Gem::Version
122
- version: '3.3'
68
+ version: 12.3.3
123
69
  - !ruby/object:Gem::Dependency
124
70
  name: rspec
125
- requirement: !ruby/object:Gem::Requirement
126
- requirements:
127
- - - ">="
128
- - !ruby/object:Gem::Version
129
- version: 3.7.0
130
- - - "~>"
131
- - !ruby/object:Gem::Version
132
- version: '3.7'
133
- type: :development
134
- prerelease: false
135
- version_requirements: !ruby/object:Gem::Requirement
136
- requirements:
137
- - - ">="
138
- - !ruby/object:Gem::Version
139
- version: 3.7.0
140
- - - "~>"
141
- - !ruby/object:Gem::Version
142
- version: '3.7'
143
- - !ruby/object:Gem::Dependency
144
- name: simplecov
145
- requirement: !ruby/object:Gem::Requirement
146
- requirements:
147
- - - "~>"
148
- - !ruby/object:Gem::Version
149
- version: '0.14'
150
- type: :development
151
- prerelease: false
152
- version_requirements: !ruby/object:Gem::Requirement
153
- requirements:
154
- - - "~>"
155
- - !ruby/object:Gem::Version
156
- version: '0.14'
157
- - !ruby/object:Gem::Dependency
158
- name: timecop
159
71
  requirement: !ruby/object:Gem::Requirement
160
72
  requirements:
161
73
  - - "~>"
162
74
  - !ruby/object:Gem::Version
163
- version: 0.9.1
75
+ version: '3.10'
164
76
  type: :development
165
77
  prerelease: false
166
78
  version_requirements: !ruby/object:Gem::Requirement
167
79
  requirements:
168
80
  - - "~>"
169
81
  - !ruby/object:Gem::Version
170
- version: 0.9.1
82
+ version: '3.10'
171
83
  description: A simple tool for building static websites.
172
84
  email:
173
85
  - d+dimples@waferbaby.com
@@ -178,16 +90,10 @@ extra_rdoc_files: []
178
90
  files:
179
91
  - bin/dimples
180
92
  - lib/dimples.rb
181
- - lib/dimples/archive.rb
182
- - lib/dimples/category.rb
183
- - lib/dimples/configuration.rb
184
- - lib/dimples/errors.rb
185
- - lib/dimples/feed.rb
186
- - lib/dimples/frontmatter.rb
93
+ - lib/dimples/document.rb
187
94
  - lib/dimples/page.rb
188
95
  - lib/dimples/pager.rb
189
96
  - lib/dimples/post.rb
190
- - lib/dimples/renderer.rb
191
97
  - lib/dimples/site.rb
192
98
  - lib/dimples/template.rb
193
99
  - lib/dimples/version.rb
@@ -203,14 +109,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
203
109
  requirements:
204
110
  - - "~>"
205
111
  - !ruby/object:Gem::Version
206
- version: '2.4'
112
+ version: '2.7'
207
113
  required_rubygems_version: !ruby/object:Gem::Requirement
208
114
  requirements:
209
115
  - - ">="
210
116
  - !ruby/object:Gem::Version
211
117
  version: '0'
212
118
  requirements: []
213
- rubygems_version: 3.0.3
119
+ rubygems_version: 3.1.6
214
120
  signing_key:
215
121
  specification_version: 4
216
122
  summary: A basic static site generator
@@ -1,64 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Dimples
4
- # A collection of posts, organised by date.
5
- class Archive
6
- def initialize
7
- @years = {}
8
- end
9
-
10
- def add_post(post)
11
- year(post.year)[:posts] << post
12
- month(post.year, post.month)[:posts] << post
13
- day(post.year, post.month, post.day)[:posts] << post
14
- end
15
-
16
- def years
17
- @years.keys
18
- end
19
-
20
- def months(year)
21
- year(year)[:months].keys
22
- end
23
-
24
- def days(year, month)
25
- month(year, month)[:days].keys
26
- end
27
-
28
- def posts_for_date(year, month = nil, day = nil)
29
- if day
30
- day_posts(year, month, day)
31
- elsif month
32
- month_posts(year, month)
33
- else
34
- year_posts(year)
35
- end
36
- end
37
-
38
- def year_posts(year)
39
- year(year)[:posts]
40
- end
41
-
42
- def month_posts(year, month)
43
- month(year, month)[:posts]
44
- end
45
-
46
- def day_posts(year, month, day)
47
- day(year, month, day)[:posts]
48
- end
49
-
50
- private
51
-
52
- def year(year)
53
- @years[year.to_s] ||= { months: {}, posts: [] }
54
- end
55
-
56
- def month(year, month)
57
- year(year)[:months][month.to_s] ||= { days: {}, posts: [] }
58
- end
59
-
60
- def day(year, month, day)
61
- month(year, month)[:days][day.to_s] ||= { posts: [] }
62
- end
63
- end
64
- end
@@ -1,18 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Dimples
4
- # A single post category for a site.
5
- class Category
6
- attr_reader :name
7
- attr_reader :slug
8
- attr_accessor :posts
9
-
10
- def initialize(site, slug)
11
- @site = site
12
- @slug = slug
13
- @name = @site.config.category_names[slug.to_sym] || slug.capitalize
14
-
15
- @posts = []
16
- end
17
- end
18
- end
@@ -1,76 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Dimples
4
- # Default configuration options for a site.
5
- module Configuration
6
- def self.prepare(config)
7
- Hashie::Mash.new(defaults).deep_merge(config)
8
- end
9
-
10
- def self.defaults
11
- {
12
- source: Dir.pwd,
13
- destination: File.join(Dir.pwd, 'public'),
14
- paths: default_paths,
15
- generation: default_generation,
16
- layouts: default_layouts,
17
- pagination: default_pagination,
18
- date_formats: default_date_formats,
19
- feed_formats: default_feed_formats,
20
- category_names: {},
21
- rendering: {}
22
- }
23
- end
24
-
25
- def self.default_paths
26
- {
27
- archives: 'archives',
28
- paginated_posts: 'posts',
29
- posts: 'archives/%Y/%m/%d',
30
- drafts: 'archives/drafts/%Y/%m/%d',
31
- categories: 'archives/categories'
32
- }
33
- end
34
-
35
- def self.default_generation
36
- {
37
- paginated_posts: true,
38
- year_archives: true,
39
- month_archives: true,
40
- day_archives: true,
41
- categories: true,
42
- main_feed: true,
43
- category_feeds: true
44
- }
45
- end
46
-
47
- def self.default_layouts
48
- {
49
- post: 'post',
50
- category: 'category',
51
- paginated_post: 'paginated_post',
52
- archive: 'archive',
53
- date_archive: 'archive'
54
- }
55
- end
56
-
57
- def self.default_date_formats
58
- {
59
- year: '%Y',
60
- month: '%Y-%m',
61
- day: '%Y-%m-%d'
62
- }
63
- end
64
-
65
- def self.default_feed_formats
66
- ['atom']
67
- end
68
-
69
- def self.default_pagination
70
- {
71
- page_prefix: 'page_',
72
- per_page: 10
73
- }
74
- end
75
- end
76
- end
@@ -1,12 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Dimples
4
- class PublishingError < StandardError
5
- end
6
-
7
- class RenderingError < StandardError
8
- end
9
-
10
- class GenerationError < StandardError
11
- end
12
- end
data/lib/dimples/feed.rb DELETED
@@ -1,14 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Dimples
4
- # A single feed.
5
- class Feed < Page
6
- def initialize(site, format)
7
- super(site)
8
-
9
- self.filename = 'feed'
10
- self.extension = format
11
- self.layout = "feeds.#{format}"
12
- end
13
- end
14
- end
@@ -1,19 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Dimples
4
- # Adds the ability to parse front matter from a file.
5
- class FrontMatter
6
- FRONT_MATTER_PATTERN = /^(-{3}\n.*?\n?)^(-{3}*$\n?)/m.freeze
7
-
8
- def self.parse(contents)
9
- if (matches = contents.match(FRONT_MATTER_PATTERN))
10
- metadata = Hashie.symbolize_keys(YAML.safe_load(matches[1]))
11
- contents = matches.post_match.strip
12
- else
13
- metadata = {}
14
- end
15
-
16
- [contents, metadata]
17
- end
18
- end
19
- end
@@ -1,58 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Dimples
4
- # A wrapper around Tilt, tied to a single post, page or template.
5
- class Renderer
6
- def initialize(site, source)
7
- @site = site
8
- @source = source
9
- end
10
-
11
- def render(context = {}, body = nil)
12
- context[:site] ||= @site
13
- context[:pagination] ||= nil
14
-
15
- begin
16
- output = engine.render(scope, context) { body }.strip
17
- rescue StandardError => e
18
- raise RenderingError,
19
- "Unable to render #{@source.path || 'dynamic file'} (#{e})"
20
- end
21
-
22
- @source.metadata[:rendered_contents] = output
23
-
24
- if @source.metadata[:layout]
25
- template = @site.templates[@source.metadata[:layout]]
26
- end
27
-
28
- return output if template.nil?
29
-
30
- template.render(context, output)
31
- end
32
-
33
- def engine
34
- @engine ||= begin
35
- callback = proc { @source.contents }
36
-
37
- if @source.path
38
- extension = File.extname(@source.path)
39
- options = @site.config.rendering[extension.to_sym] || {}
40
-
41
- Tilt.new(@source.path, options, &callback)
42
- else
43
- Tilt::StringTemplate.new(&callback)
44
- end
45
- end
46
- end
47
-
48
- def scope
49
- @scope ||= Object.new.tap do |scope|
50
- scope.instance_variable_set(:@site, @site)
51
-
52
- scope.class.send(:define_method, :render) do |layout, locals = {}|
53
- @site.templates[layout]&.render(locals)
54
- end
55
- end
56
- end
57
- end
58
- end