dimples 6.6.0 → 7.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b8a5a0e150bc568f6593260d6af73dfcdfc2979ff7e39866d3cc798c706955ff
4
- data.tar.gz: 7c5521a81ac0325d431c1027287bf216e4669b341bcf5e6f6fabfa9f05beb0a5
3
+ metadata.gz: 882aeff0d91ba61d58f331bedabeba0c865dbb7ef355c1fdafde7e1605113d2e
4
+ data.tar.gz: 8ddfc8ea5bcbce38a35c8d0153f96adc4866f5529a074884e966b92a65dce642
5
5
  SHA512:
6
- metadata.gz: 73b0502dcdd803eef073c4d075d7f3d2eaa9f6a9b8897f1c5d21d0c49b7c3682c91aba70b7b89c4140c65a14df7e6a0ed83fdaa42b6925327521929cdd37f58b
7
- data.tar.gz: 3750f6c5e82b6d4f84a659bb8f15a36c969cd4698eaa736946f4fd81d7a5a28ec49e3d3529820d6a0b1cd3b3ac6f2e786b83431b0de40bf21a16d60fbd505de3
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,38 +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)
3
+ require 'date'
12
4
 
13
- @metadata[:layout] ||= @site.config.layouts.post
14
-
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 url
22
- path = date.strftime(draft ? @site.config.paths.drafts : @site.config.paths.posts)
23
- "/#{path}/#{slug}/"
24
- end
25
-
26
- def year
27
- @year ||= @metadata[:date].strftime('%Y')
5
+ module Dimples
6
+ class Post < Document
7
+ def date
8
+ @metadata.fetch(:date, DateTime.now)
28
9
  end
29
10
 
30
- def month
31
- @month ||= @metadata[:date].strftime('%m')
11
+ def layout
12
+ @metadata.fetch(:layout, 'post')
32
13
  end
33
14
 
34
- def day
35
- @day ||= @metadata[:date].strftime('%d')
15
+ def slug
16
+ File.basename(@path, '.markdown')
36
17
  end
37
18
  end
38
19
  end
data/lib/dimples/site.rb CHANGED
@@ -1,159 +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(Time.now.strftime(@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(@paths[:destination], post.url.split('/'))
137
- post.write(path)
114
+ path = File.join(directory_path, post.slug, post.filename)
115
+ write_file(path, render(post, post: post))
138
116
  end
139
117
 
140
- published_posts = @posts.select { |post| !post.draft }
141
-
142
- if @config.generation.main_feed
143
- publish_feeds(published_posts, @paths[:destination])
144
- end
145
-
146
- return unless @config.generation.paginated_posts
147
-
148
- Dimples::Pager.paginate(
149
- self,
150
- published_posts,
151
- File.join(@paths[:destination], @config.paths.paginated_posts),
152
- @config.layouts.paginated_post
153
- )
118
+ generate_paginated_posts(@posts, directory_path)
119
+ generate_feed(@posts.slice(0, 10), @paths[:destination])
154
120
  end
155
121
 
156
- def publish_pages
122
+ def generate_pages
157
123
  @pages.each do |page|
158
124
  path = if page.path
159
125
  File.dirname(page.path).sub(
@@ -164,82 +130,41 @@ module Dimples
164
130
  @paths[:destination]
165
131
  end
166
132
 
167
- page.write(path)
133
+ write_file(File.join(path, page.filename), render(page, page: page))
168
134
  end
169
135
  end
170
136
 
171
- def publish_archives
172
- @archive.years.each do |year|
173
- publish_archive(year)
174
- next unless @config.generation.month_archives
175
-
176
- @archive.months(year).each do |month|
177
- publish_archive(year, month)
178
- 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)
179
140
 
180
- @archive.days(year, month).each do |day|
181
- publish_archive(year, month, day)
182
- end
183
- end
141
+ generate_paginated_posts(posts, category_path, category: category)
142
+ generate_feed(posts.slice(0, 10), category_path)
184
143
  end
185
144
  end
186
145
 
187
- def publish_archive(year, month = nil, day = nil)
188
- date_type = if day
189
- 'day'
190
- elsif month
191
- 'month'
192
- else
193
- 'year'
194
- end
195
-
196
- posts = @archive.posts_for_date(year, month, day)
197
-
198
- date_parts = [year, month, day].compact
199
- path = File.join(@paths[:destination], @config.paths.archives, date_parts)
200
- layout = @config.layouts.date_archive
201
-
202
- data = {
203
- page: {
204
- title: posts[0].date.strftime(@config.date_formats[date_type]),
205
- archive_date: posts[0].date,
206
- archive_type: date_type
207
- }
208
- }
146
+ def generate_feed(posts, path)
147
+ page = Dimples::Page.new()
148
+ page.metadata[:layout] = 'feed'
209
149
 
210
- Dimples::Pager.paginate(self, posts.reverse, path, layout, data)
150
+ write_file(File.join(path, 'feed.atom'), render(page, posts: posts))
211
151
  end
212
152
 
213
- def publish_categories
214
- @categories.each_value do |category|
215
- path = File.join(
216
- @paths[:destination],
217
- @config.paths.categories,
218
- category.slug
219
- )
220
-
221
- category_posts = category.posts.reverse
222
- context = { page: { title: category.name, category: category } }
223
-
224
- Dimples::Pager.paginate(
225
- self,
226
- category_posts,
227
- path,
228
- @config.layouts.category,
229
- context
230
- )
231
-
232
- publish_feeds(category_posts, path, context)
233
- end
153
+ def copy_assets
154
+ return unless Dir.exist?(@paths[:static])
155
+ FileUtils.cp_r(File.join(@paths[:static], '.'), @paths[:destination])
234
156
  end
235
157
 
236
- def publish_feeds(posts, path, context = {})
237
- @config.feed_formats.each do |format|
238
- feed = Feed.new(self, format)
158
+ def render(object, context = {}, content = nil)
159
+ context[:site] ||= self
160
+
161
+ output = object.render(context, content)
239
162
 
240
- feed.feed_posts = posts.slice(0, @config.pagination.per_page)
241
- feed.write(path, context)
163
+ if object.layout && @templates[object.layout]
164
+ output = render(@templates[object.layout], context, output)
242
165
  end
166
+
167
+ output
243
168
  end
244
169
  end
245
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.6.0'
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,43 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dimples
3
3
  version: !ruby/object:Gem::Version
4
- version: 6.6.0
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: 2021-02-20 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: '4.1'
19
+ version: '1.10'
20
20
  type: :runtime
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: '4.1'
27
- - !ruby/object:Gem::Dependency
28
- name: optimist
29
- requirement: !ruby/object:Gem::Requirement
30
- requirements:
31
- - - "~>"
32
- - !ruby/object:Gem::Version
33
- version: '3.0'
34
- type: :runtime
35
- prerelease: false
36
- version_requirements: !ruby/object:Gem::Requirement
37
- requirements:
38
- - - "~>"
39
- - !ruby/object:Gem::Version
40
- version: '3.0'
26
+ version: '1.10'
41
27
  - !ruby/object:Gem::Dependency
42
28
  name: tilt
43
29
  requirement: !ruby/object:Gem::Requirement
@@ -53,33 +39,19 @@ dependencies:
53
39
  - !ruby/object:Gem::Version
54
40
  version: '2.0'
55
41
  - !ruby/object:Gem::Dependency
56
- name: codeclimate-test-reporter
57
- requirement: !ruby/object:Gem::Requirement
58
- requirements:
59
- - - "~>"
60
- - !ruby/object:Gem::Version
61
- version: '1.0'
62
- type: :development
63
- prerelease: false
64
- version_requirements: !ruby/object:Gem::Requirement
65
- requirements:
66
- - - "~>"
67
- - !ruby/object:Gem::Version
68
- version: '1.0'
69
- - !ruby/object:Gem::Dependency
70
- name: erubis
42
+ name: redcarpet
71
43
  requirement: !ruby/object:Gem::Requirement
72
44
  requirements:
73
45
  - - "~>"
74
46
  - !ruby/object:Gem::Version
75
- version: '2.7'
76
- type: :development
47
+ version: '3.5'
48
+ type: :runtime
77
49
  prerelease: false
78
50
  version_requirements: !ruby/object:Gem::Requirement
79
51
  requirements:
80
52
  - - "~>"
81
53
  - !ruby/object:Gem::Version
82
- version: '2.7'
54
+ version: '3.5'
83
55
  - !ruby/object:Gem::Dependency
84
56
  name: rake
85
57
  requirement: !ruby/object:Gem::Requirement
@@ -94,20 +66,6 @@ dependencies:
94
66
  - - "~>"
95
67
  - !ruby/object:Gem::Version
96
68
  version: 12.3.3
97
- - !ruby/object:Gem::Dependency
98
- name: redcarpet
99
- requirement: !ruby/object:Gem::Requirement
100
- requirements:
101
- - - "~>"
102
- - !ruby/object:Gem::Version
103
- version: '3.5'
104
- type: :development
105
- prerelease: false
106
- version_requirements: !ruby/object:Gem::Requirement
107
- requirements:
108
- - - "~>"
109
- - !ruby/object:Gem::Version
110
- version: '3.5'
111
69
  - !ruby/object:Gem::Dependency
112
70
  name: rspec
113
71
  requirement: !ruby/object:Gem::Requirement
@@ -122,20 +80,6 @@ dependencies:
122
80
  - - "~>"
123
81
  - !ruby/object:Gem::Version
124
82
  version: '3.10'
125
- - !ruby/object:Gem::Dependency
126
- name: simplecov
127
- requirement: !ruby/object:Gem::Requirement
128
- requirements:
129
- - - "~>"
130
- - !ruby/object:Gem::Version
131
- version: '0.21'
132
- type: :development
133
- prerelease: false
134
- version_requirements: !ruby/object:Gem::Requirement
135
- requirements:
136
- - - "~>"
137
- - !ruby/object:Gem::Version
138
- version: '0.21'
139
83
  description: A simple tool for building static websites.
140
84
  email:
141
85
  - d+dimples@waferbaby.com
@@ -146,16 +90,10 @@ extra_rdoc_files: []
146
90
  files:
147
91
  - bin/dimples
148
92
  - lib/dimples.rb
149
- - lib/dimples/archive.rb
150
- - lib/dimples/category.rb
151
- - lib/dimples/configuration.rb
152
- - lib/dimples/errors.rb
153
- - lib/dimples/feed.rb
154
- - lib/dimples/frontmatter.rb
93
+ - lib/dimples/document.rb
155
94
  - lib/dimples/page.rb
156
95
  - lib/dimples/pager.rb
157
96
  - lib/dimples/post.rb
158
- - lib/dimples/renderer.rb
159
97
  - lib/dimples/site.rb
160
98
  - lib/dimples/template.rb
161
99
  - lib/dimples/version.rb
@@ -178,7 +116,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
178
116
  - !ruby/object:Gem::Version
179
117
  version: '0'
180
118
  requirements: []
181
- rubygems_version: 3.1.4
119
+ rubygems_version: 3.1.6
182
120
  signing_key:
183
121
  specification_version: 4
184
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