bgotink-hyde 0.1.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 +7 -0
- data/Gemfile +2 -0
- data/History.md +12 -0
- data/LICENSE +1 -0
- data/README.md +7 -0
- data/Rakefile +302 -0
- data/bgotink-hyde.gemspec +69 -0
- data/bin/hyde +68 -0
- data/lib/hyde/command.rb +7 -0
- data/lib/hyde/commands/build.rb +87 -0
- data/lib/hyde/commands/serve.rb +9 -0
- data/lib/hyde/configuration.rb +116 -0
- data/lib/hyde/jekyllfile.rb +52 -0
- data/lib/hyde/site.rb +134 -0
- data/lib/hyde/stevenson.rb +18 -0
- data/lib/hyde.rb +57 -0
- metadata +133 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: b35e2e38e70e2040272eb73e09c1723addeb037e
|
4
|
+
data.tar.gz: 649a9dc6e5865353fd824b0bda1d00c371912e09
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: ba3173c30ede6cba47322d3758b5972f475ba9222ce37fd0ef032c2f5ce4e8ae0bbaf7d6d07c4d54d152776ff53e22ee31cfd040fc7857257eb254b354110d9e
|
7
|
+
data.tar.gz: ae6bcd9e3c0f1ce2b1d7fd0ce49bc25aaa58d0be1f7d3d26618f2c38430f49ca1bdffd33517dd34988fb4e339ca760a1db06566f118f20387cb2fa5feca6660c
|
data/Gemfile
ADDED
data/History.md
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
## HEAD
|
2
|
+
|
3
|
+
### Major Enhancements
|
4
|
+
* copied and modified gemspec, rakefile etc. from [jekyll](//github.com/jekyll/jekyll)
|
5
|
+
* wrote `bin/hyde` based on `jekyll` script
|
6
|
+
* created build command
|
7
|
+
* created serve command
|
8
|
+
* use `mtime` to obtain a date to give jekyll
|
9
|
+
* allow usage of `hyde_data: `, which takes precedense over `mtime`
|
10
|
+
|
11
|
+
## 0.0.0 / 2014-01-07
|
12
|
+
* Birthday! (no really, 23rd birthday)
|
data/LICENSE
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
TODO: fill in MIT license
|
data/README.md
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
Hyde is a user-friendly front-end for [Jekyll](//github.com/jekyll/jekyll).
|
2
|
+
|
3
|
+
## Features
|
4
|
+
|
5
|
+
Hyde needs a Jekyll skeleton and will fill it in with posts.
|
6
|
+
The post format for Jekyll is `year-mo-da-title.ext`, whereas Hyde
|
7
|
+
uses the `mdate` of the file to obtain the date of the post.
|
data/Rakefile
ADDED
@@ -0,0 +1,302 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
require 'rdoc'
|
4
|
+
require 'date'
|
5
|
+
require 'yaml'
|
6
|
+
|
7
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), *%w[lib]))
|
8
|
+
|
9
|
+
#############################################################################
|
10
|
+
#
|
11
|
+
# Helper functions
|
12
|
+
#
|
13
|
+
#############################################################################
|
14
|
+
|
15
|
+
def name
|
16
|
+
rubyforge_project
|
17
|
+
end
|
18
|
+
|
19
|
+
def main_file
|
20
|
+
Dir['lib/*.rb'].first
|
21
|
+
end
|
22
|
+
|
23
|
+
def version
|
24
|
+
line = File.read(main_file)[/^\s*VERSION\s*=\s*.*/]
|
25
|
+
line.match(/.*VERSION\s*=\s*['"](.*)['"]/)[1]
|
26
|
+
end
|
27
|
+
|
28
|
+
def date
|
29
|
+
Date.today.to_s
|
30
|
+
end
|
31
|
+
|
32
|
+
def file_date
|
33
|
+
Date.today.strftime("%F")
|
34
|
+
end
|
35
|
+
|
36
|
+
def rubyforge_project
|
37
|
+
@project ||= gemspec_file.split('.').first
|
38
|
+
end
|
39
|
+
|
40
|
+
def gemspec_file
|
41
|
+
Dir['*.gemspec'].first
|
42
|
+
end
|
43
|
+
|
44
|
+
def gem_file
|
45
|
+
"#{rubyforge_project}-#{version}.gem"
|
46
|
+
end
|
47
|
+
|
48
|
+
def replace_header(head, header_name)
|
49
|
+
head.sub!(/(\.#{header_name}\s*= ').*'/) { "#{$1}#{send(header_name)}'"}
|
50
|
+
end
|
51
|
+
|
52
|
+
def normalize_bullets(markdown)
|
53
|
+
markdown.gsub(/\s{2}\*{1}/, "-")
|
54
|
+
end
|
55
|
+
|
56
|
+
def linkify_prs(markdown)
|
57
|
+
markdown.gsub(/#(\d+)/) do |word|
|
58
|
+
"[#{word}]({{ site.repository }}/issues/#{word.delete("#")})"
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def linkify_users(markdown)
|
63
|
+
markdown.gsub(/(@\w+)/) do |username|
|
64
|
+
"[#{username}](https://github.com/#{username.delete("@")})"
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def linkify(markdown)
|
69
|
+
linkify_users(linkify_prs(markdown))
|
70
|
+
end
|
71
|
+
|
72
|
+
def liquid_escape(markdown)
|
73
|
+
markdown.gsub(/(`{[{%].+[}%]}`)/, "{% raw %}\\1{% endraw %}")
|
74
|
+
end
|
75
|
+
|
76
|
+
def remove_head_from_history(markdown)
|
77
|
+
index = markdown =~ /^##\s+\d+\.\d+\.\d+/
|
78
|
+
markdown[index..-1]
|
79
|
+
end
|
80
|
+
|
81
|
+
def converted_history(markdown)
|
82
|
+
remove_head_from_history(liquid_escape(linkify(normalize_bullets(markdown))))
|
83
|
+
end
|
84
|
+
|
85
|
+
#############################################################################
|
86
|
+
#
|
87
|
+
# Standard tasks
|
88
|
+
#
|
89
|
+
#############################################################################
|
90
|
+
|
91
|
+
if RUBY_VERSION > '1.9' && ENV["TRAVIS"] == "true"
|
92
|
+
require 'coveralls/rake/task'
|
93
|
+
Coveralls::RakeTask.new
|
94
|
+
|
95
|
+
task :default => [:test, :features, 'coveralls:push']
|
96
|
+
else
|
97
|
+
task :default => [:test, :features]
|
98
|
+
end
|
99
|
+
|
100
|
+
require 'rake/testtask'
|
101
|
+
Rake::TestTask.new(:test) do |test|
|
102
|
+
test.libs << 'lib' << 'test'
|
103
|
+
test.pattern = 'test/**/test_*.rb'
|
104
|
+
test.verbose = true
|
105
|
+
end
|
106
|
+
|
107
|
+
require 'rdoc/task'
|
108
|
+
Rake::RDocTask.new do |rdoc|
|
109
|
+
rdoc.rdoc_dir = 'rdoc'
|
110
|
+
rdoc.title = "#{name} #{version}"
|
111
|
+
rdoc.rdoc_files.include('README*')
|
112
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
113
|
+
end
|
114
|
+
|
115
|
+
# begin
|
116
|
+
# require 'cucumber/rake/task'
|
117
|
+
# Cucumber::Rake::Task.new(:features) do |t|
|
118
|
+
# t.profile = "travis"
|
119
|
+
# end
|
120
|
+
# Cucumber::Rake::Task.new(:"features:html", "Run Cucumber features and produce HTML output") do |t|
|
121
|
+
# t.profile = "html_report"
|
122
|
+
# end
|
123
|
+
# rescue LoadError
|
124
|
+
# desc 'Cucumber rake task not available'
|
125
|
+
# task :features do
|
126
|
+
# abort 'Cucumber rake task is not available. Be sure to install cucumber as a gem or plugin'
|
127
|
+
# end
|
128
|
+
# end
|
129
|
+
|
130
|
+
desc "Open an irb session preloaded with this library"
|
131
|
+
task :console do
|
132
|
+
sh "irb -rubygems -r ./#{main_file}"
|
133
|
+
end
|
134
|
+
|
135
|
+
#############################################################################
|
136
|
+
#
|
137
|
+
# Site tasks - http://jekyllrb.com
|
138
|
+
#
|
139
|
+
#############################################################################
|
140
|
+
|
141
|
+
namespace :site do
|
142
|
+
desc "Generate and view the site locally"
|
143
|
+
task :preview do
|
144
|
+
require "launchy"
|
145
|
+
|
146
|
+
# Yep, it's a hack! Wait a few seconds for the Jekyll site to generate and
|
147
|
+
# then open it in a browser. Someday we can do better than this, I hope.
|
148
|
+
Thread.new do
|
149
|
+
sleep 4
|
150
|
+
puts "Opening in browser..."
|
151
|
+
Launchy.open("http://localhost:4000")
|
152
|
+
end
|
153
|
+
|
154
|
+
# Generate the site in server mode.
|
155
|
+
puts "Running Jekyll..."
|
156
|
+
Dir.chdir("site") do
|
157
|
+
sh "#{File.expand_path('bin/jekyll', File.dirname(__FILE__))} serve --watch"
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
desc "Update normalize.css library to the latest version and minify"
|
162
|
+
task :update_normalize_css do
|
163
|
+
Dir.chdir("site/css") do
|
164
|
+
sh 'curl "http://necolas.github.io/normalize.css/latest/normalize.css" -o "normalize.scss"'
|
165
|
+
sh 'sass "normalize.scss":"normalize.css" --style compressed'
|
166
|
+
sh 'rm "normalize.scss"'
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
desc "Commit the local site to the gh-pages branch and publish to GitHub Pages"
|
171
|
+
task :publish => [:history] do
|
172
|
+
# Ensure the gh-pages dir exists so we can generate into it.
|
173
|
+
puts "Checking for gh-pages dir..."
|
174
|
+
unless File.exist?("./gh-pages")
|
175
|
+
puts "No gh-pages directory found. Run the following commands first:"
|
176
|
+
puts " `git clone git@github.com:mojombo/jekyll gh-pages"
|
177
|
+
puts " `cd gh-pages"
|
178
|
+
puts " `git checkout gh-pages`"
|
179
|
+
exit(1)
|
180
|
+
end
|
181
|
+
|
182
|
+
# Ensure gh-pages branch is up to date.
|
183
|
+
Dir.chdir('gh-pages') do
|
184
|
+
sh "git pull origin gh-pages"
|
185
|
+
end
|
186
|
+
|
187
|
+
# Copy to gh-pages dir.
|
188
|
+
puts "Copying site to gh-pages branch..."
|
189
|
+
Dir.glob("site/*") do |path|
|
190
|
+
next if path.include? "_site"
|
191
|
+
sh "cp -R #{path} gh-pages/"
|
192
|
+
end
|
193
|
+
|
194
|
+
# Commit and push.
|
195
|
+
puts "Committing and pushing to GitHub Pages..."
|
196
|
+
sha = `git log`.match(/[a-z0-9]{40}/)[0]
|
197
|
+
Dir.chdir('gh-pages') do
|
198
|
+
sh "git add ."
|
199
|
+
sh "git commit -m 'Updating to #{sha}.'"
|
200
|
+
sh "git push origin gh-pages"
|
201
|
+
end
|
202
|
+
puts 'Done.'
|
203
|
+
end
|
204
|
+
|
205
|
+
desc "Create a nicely formatted history page for the jekyll site based on the repo history."
|
206
|
+
task :history do
|
207
|
+
if File.exist?("History.md")
|
208
|
+
history_file = File.read("History.md")
|
209
|
+
front_matter = {
|
210
|
+
"layout" => "docs",
|
211
|
+
"title" => "History",
|
212
|
+
"permalink" => "/docs/history/",
|
213
|
+
"prev_section" => "contributing"
|
214
|
+
}
|
215
|
+
Dir.chdir('site/docs/') do
|
216
|
+
File.open("history.md", "w") do |file|
|
217
|
+
file.write("#{front_matter.to_yaml}---\n\n")
|
218
|
+
file.write(converted_history(history_file))
|
219
|
+
end
|
220
|
+
end
|
221
|
+
else
|
222
|
+
abort "You seem to have misplaced your History.markdown file. I can haz?"
|
223
|
+
end
|
224
|
+
end
|
225
|
+
|
226
|
+
namespace :releases do
|
227
|
+
desc "Create new release post"
|
228
|
+
task :new, :version do |t, args|
|
229
|
+
raise "Specify a version: rake site:releases:new['1.2.3']" unless args.version
|
230
|
+
today = Time.new.strftime('%Y-%m-%d')
|
231
|
+
release = args.version.to_s
|
232
|
+
filename = "site/_posts/#{today}-jekyll-#{release.split('.').join('-')}-released.markdown"
|
233
|
+
|
234
|
+
File.open(filename, "wb") do |post|
|
235
|
+
post.puts("---")
|
236
|
+
post.puts("layout: news_item")
|
237
|
+
post.puts("title: 'Jekyll #{release} Released'")
|
238
|
+
post.puts("date: #{Time.new.strftime('%Y-%m-%d %H:%M:%S %z')}")
|
239
|
+
post.puts("author: ")
|
240
|
+
post.puts("version: #{release}")
|
241
|
+
post.puts("categories: [release]")
|
242
|
+
post.puts("---")
|
243
|
+
post.puts
|
244
|
+
post.puts
|
245
|
+
end
|
246
|
+
|
247
|
+
puts "Created #{filename}"
|
248
|
+
end
|
249
|
+
end
|
250
|
+
end
|
251
|
+
|
252
|
+
#############################################################################
|
253
|
+
#
|
254
|
+
# Packaging tasks
|
255
|
+
#
|
256
|
+
#############################################################################
|
257
|
+
|
258
|
+
task :release => :build do
|
259
|
+
unless `git branch` =~ /^(\* master|\* v1-stable)$/
|
260
|
+
puts "You must be on the master branch or the v1-stable branch to release!"
|
261
|
+
exit!
|
262
|
+
end
|
263
|
+
sh "git commit --allow-empty -m 'Release #{version}'"
|
264
|
+
sh "git tag v#{version}"
|
265
|
+
sh "git push origin master"
|
266
|
+
sh "git push origin v#{version}"
|
267
|
+
sh "gem push pkg/#{name}-#{version}.gem"
|
268
|
+
end
|
269
|
+
|
270
|
+
task :build => :gemspec do
|
271
|
+
sh "mkdir -p pkg"
|
272
|
+
sh "gem build #{gemspec_file}"
|
273
|
+
sh "mv #{gem_file} pkg"
|
274
|
+
end
|
275
|
+
|
276
|
+
task :gemspec do
|
277
|
+
# read spec file and split out manifest section
|
278
|
+
spec = File.read(gemspec_file)
|
279
|
+
head, manifest, tail = spec.split(" # = MANIFEST =\n")
|
280
|
+
|
281
|
+
# replace name version and date
|
282
|
+
replace_header(head, :name)
|
283
|
+
replace_header(head, :version)
|
284
|
+
replace_header(head, :date)
|
285
|
+
#comment this out if your rubyforge_project has a different name
|
286
|
+
replace_header(head, :rubyforge_project)
|
287
|
+
|
288
|
+
# determine file list from git ls-files
|
289
|
+
files = `git ls-files`.
|
290
|
+
split("\n").
|
291
|
+
sort.
|
292
|
+
reject { |file| file =~ /^\./ }.
|
293
|
+
reject { |file| file =~ /^(rdoc|pkg|coverage)/ }.
|
294
|
+
map { |file| " #{file}" }.
|
295
|
+
join("\n")
|
296
|
+
|
297
|
+
# piece file back together and write
|
298
|
+
manifest = " s.files = %w[\n#{files}\n ]\n"
|
299
|
+
spec = [head, manifest, tail].join(" # = MANIFEST =\n")
|
300
|
+
File.open(gemspec_file, 'w') { |io| io.write(spec) }
|
301
|
+
puts "Updated #{gemspec_file}"
|
302
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
Gem::Specification.new do |s|
|
2
|
+
s.specification_version = 2 if s.respond_to? :specification_version=
|
3
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
4
|
+
s.rubygems_version = '1.3.5'
|
5
|
+
|
6
|
+
s.name = 'bgotink-hyde'
|
7
|
+
s.version = '0.1.0'
|
8
|
+
s.license = 'MIT'
|
9
|
+
s.date = '2014-01-08'
|
10
|
+
s.rubyforge_project = 'bgotink-hyde'
|
11
|
+
|
12
|
+
s.summary = "A user-friendly front-end for Jekyll"
|
13
|
+
s.description = "Hyde is a simple front-end for Jekyll, the simple, blog-aware static site generator."
|
14
|
+
|
15
|
+
s.authors = ["Bram Gotink"]
|
16
|
+
s.email = 'bram@gotink.me'
|
17
|
+
s.homepage = 'http://github.com/bgotink/hyde'
|
18
|
+
|
19
|
+
s.require_paths = %w[lib]
|
20
|
+
|
21
|
+
s.executables = ["hyde"]
|
22
|
+
|
23
|
+
s.rdoc_options = ["--charset=UTF-8"]
|
24
|
+
s.extra_rdoc_files = %w[README.md LICENSE]
|
25
|
+
|
26
|
+
s.add_runtime_dependency('jekyll', "~> 1.4.2")
|
27
|
+
s.add_runtime_dependency('listen', "~> 1.3")
|
28
|
+
s.add_runtime_dependency('commander', "~> 4.1.3")
|
29
|
+
s.add_runtime_dependency('safe_yaml', "~> 0.9.7")
|
30
|
+
|
31
|
+
s.add_development_dependency('rake', "~> 10.1")
|
32
|
+
# s.add_development_dependency('rdoc', "~> 3.11")
|
33
|
+
# s.add_development_dependency('redgreen', "~> 1.2")
|
34
|
+
# s.add_development_dependency('shoulda', "~> 3.3.2")
|
35
|
+
# s.add_development_dependency('rr', "~> 1.1")
|
36
|
+
# s.add_development_dependency('cucumber', "~> 1.3")
|
37
|
+
# s.add_development_dependency('RedCloth', "~> 4.2")
|
38
|
+
# s.add_development_dependency('kramdown', "~> 1.2")
|
39
|
+
# s.add_development_dependency('rdiscount', "~> 1.6")
|
40
|
+
# s.add_development_dependency('launchy', "~> 2.3")
|
41
|
+
# s.add_development_dependency('simplecov', "~> 0.7")
|
42
|
+
# s.add_development_dependency('simplecov-gem-adapter', "~> 1.0.1")
|
43
|
+
# s.add_development_dependency('coveralls', "~> 0.7.0")
|
44
|
+
# s.add_development_dependency('mime-types', "~> 1.5")
|
45
|
+
# s.add_development_dependency('activesupport', '~> 3.2.13')
|
46
|
+
# s.add_development_dependency('jekyll_test_plugin')
|
47
|
+
|
48
|
+
# = MANIFEST =
|
49
|
+
s.files = %w[
|
50
|
+
Gemfile
|
51
|
+
History.md
|
52
|
+
LICENSE
|
53
|
+
README.md
|
54
|
+
Rakefile
|
55
|
+
bgotink-hyde.gemspec
|
56
|
+
bin/hyde
|
57
|
+
lib/hyde.rb
|
58
|
+
lib/hyde/command.rb
|
59
|
+
lib/hyde/commands/build.rb
|
60
|
+
lib/hyde/commands/serve.rb
|
61
|
+
lib/hyde/configuration.rb
|
62
|
+
lib/hyde/jekyllfile.rb
|
63
|
+
lib/hyde/site.rb
|
64
|
+
lib/hyde/stevenson.rb
|
65
|
+
]
|
66
|
+
# = MANIFEST =
|
67
|
+
|
68
|
+
s.test_files = s.files.select { |path| path =~ /^test\/test_.*\.rb/ }
|
69
|
+
end
|
data/bin/hyde
ADDED
@@ -0,0 +1,68 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
STDOUT.sync = true
|
3
|
+
|
4
|
+
$:.unshift File.join(File.dirname(__FILE__), *%w{ .. lib })
|
5
|
+
|
6
|
+
require 'commander/import'
|
7
|
+
require 'hyde'
|
8
|
+
|
9
|
+
program :name, 'Hyde'
|
10
|
+
program :version, Hyde::VERSION
|
11
|
+
program :description, 'A user-friendly front-end for Jekyll'
|
12
|
+
|
13
|
+
default_command :default
|
14
|
+
|
15
|
+
global_option '-s', '--source [DIR]', 'Source directory (defaults to ./_source)'
|
16
|
+
global_option '-j', '--jekyll [DIR]', 'Jekyll input directory (defaults to ./_jekyll)'
|
17
|
+
global_option '-k', '--jekyll-out [DIR]', 'Jekyll intermediate directory (defaults to ./_jekyll-out)'
|
18
|
+
global_option '-d', '--destination [DIR]', 'Output directory (defaults to ./_site)'
|
19
|
+
|
20
|
+
def add_build_options(c)
|
21
|
+
c.option '--config CONFIG_FILE[,CONFIG_FILE2,...]', Array, 'Custom configuration file'
|
22
|
+
c.option '--keep', 'Keep intermediate jekyll files'
|
23
|
+
c.option '-w', '--watch', 'Watch for changes and rebuild'
|
24
|
+
c.option '-V', '--verbose', 'Print verbose output.'
|
25
|
+
end
|
26
|
+
|
27
|
+
command :default do |c|
|
28
|
+
c.action do |args, options|
|
29
|
+
if args.empty?
|
30
|
+
command(:help).run
|
31
|
+
else
|
32
|
+
Hyde.logger.abort_with "Invalid command. Use --help for more information"
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
command :build do |c|
|
38
|
+
c.syntax = 'hyde build [options]'
|
39
|
+
c.description = 'build your site'
|
40
|
+
|
41
|
+
add_build_options(c)
|
42
|
+
|
43
|
+
c.action do |args, options|
|
44
|
+
options = Hyde.configuration(options.__hash__)
|
45
|
+
Hyde::Commands::Build.process(options)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
command :serve do |c|
|
50
|
+
c.syntax = 'hyde serve [options]'
|
51
|
+
c.description = 'Serve your site locally'
|
52
|
+
|
53
|
+
add_build_options(c)
|
54
|
+
|
55
|
+
c.option '-B', '--detach', 'Run the server in the background (detach)'
|
56
|
+
c.option '-P', '--port [PORT]', 'Port to listen on'
|
57
|
+
c.option '-H', '--host [HOST]', 'Host to bind to'
|
58
|
+
c.option '-b', '--baseurl [URL]', 'Base URL'
|
59
|
+
|
60
|
+
c.action do |args, options|
|
61
|
+
options.default :serving => true
|
62
|
+
|
63
|
+
options = Hyde.configuration(options.__hash__)
|
64
|
+
Hyde::Commands::Build.process(options)
|
65
|
+
Hyde::Commands::Serve.process(options)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
alias_command :server, :serve
|
data/lib/hyde/command.rb
ADDED
@@ -0,0 +1,87 @@
|
|
1
|
+
module Hyde
|
2
|
+
module Commands
|
3
|
+
class Build < Command
|
4
|
+
|
5
|
+
def self.process(options)
|
6
|
+
site = Hyde::Site.new(options)
|
7
|
+
|
8
|
+
options['watching'] = true if options['watch']
|
9
|
+
|
10
|
+
self.build(site, options)
|
11
|
+
self.watch(site, options) if options['watch']
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.build(site, options)
|
15
|
+
source = options['source']
|
16
|
+
jekyll = options['jekyll']
|
17
|
+
jekyll_out = options['jekyll-out']
|
18
|
+
destination = options['destination']
|
19
|
+
|
20
|
+
Hyde.logger.info "Source:", source
|
21
|
+
Hyde.logger.info "Jekyll input:", jekyll
|
22
|
+
Hyde.logger.info "Jekyll output:", jekyll_out
|
23
|
+
Hyde.logger.info "Destination:", destination
|
24
|
+
|
25
|
+
Hyde.logger.info "Running Jekyll...", ""
|
26
|
+
|
27
|
+
site.process
|
28
|
+
|
29
|
+
Hyde.logger.info "", "done."
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.watch(site, options)
|
33
|
+
require 'listen'
|
34
|
+
|
35
|
+
# TODO check whether dest is in source?
|
36
|
+
|
37
|
+
source = options['source']
|
38
|
+
intermediary = options['jekyll-out']
|
39
|
+
destination = options['destination']
|
40
|
+
|
41
|
+
ignored = Array.new
|
42
|
+
%w[jekyll-out destination].each do |o|
|
43
|
+
begin
|
44
|
+
d = Pathname.new(options[o]).relative_path_from(Pathname.new(source)).to_s
|
45
|
+
ignored << Regexp.escape(d)
|
46
|
+
rescue ArgumentError
|
47
|
+
# nop
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
if ignored.empty?
|
52
|
+
ignored = nil
|
53
|
+
else
|
54
|
+
ignored = Regexp.new(ignored.join('|'))
|
55
|
+
end
|
56
|
+
|
57
|
+
Hyde.logger.info 'Auto-regeneration:', 'enabled'
|
58
|
+
|
59
|
+
listener = Listen::Listener.new(source, :ignore => ignored) do |modified, added, removed|
|
60
|
+
t = Time.now.strftime("%Y-%m-%d %H:%M:%S")
|
61
|
+
n = modified.length + added.length + removed.length
|
62
|
+
Hyde.logger.info "Regenerating:", "#{n} files at #{t} "
|
63
|
+
|
64
|
+
site.process
|
65
|
+
|
66
|
+
Hyde.logger.info "", "done."
|
67
|
+
end
|
68
|
+
listener.start
|
69
|
+
|
70
|
+
unless options['serving']
|
71
|
+
trap("INT") do
|
72
|
+
options['watching'] = false
|
73
|
+
|
74
|
+
listener.stop
|
75
|
+
site.cleanup
|
76
|
+
|
77
|
+
puts " Halting auto-regeneration."
|
78
|
+
exit 0
|
79
|
+
end
|
80
|
+
|
81
|
+
loop { sleep 1000 }
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
@@ -0,0 +1,116 @@
|
|
1
|
+
module Hyde
|
2
|
+
class Configuration < Hash
|
3
|
+
|
4
|
+
DEFAULTS = {
|
5
|
+
'source' => Dir.pwd,
|
6
|
+
'jekyll' => File.join(Dir.pwd, '_jekyll'),
|
7
|
+
'jekyll-out' => File.join(Dir.pwd, '_jekyll-out'),
|
8
|
+
'destination' => File.join(Dir.pwd, '_site'),
|
9
|
+
|
10
|
+
'keep' => false,
|
11
|
+
|
12
|
+
'encoding' => nil,
|
13
|
+
|
14
|
+
'safe' => false,
|
15
|
+
'detach' => false,
|
16
|
+
|
17
|
+
'port' => Jekyll::Configuration::DEFAULTS['port'],
|
18
|
+
'host' => Jekyll::Configuration::DEFAULTS['host']
|
19
|
+
}
|
20
|
+
|
21
|
+
# Public: Turn all keys into string
|
22
|
+
#
|
23
|
+
# Return a copy of the hash where all its keys are strings
|
24
|
+
def stringify_keys
|
25
|
+
reduce({}) { |hsh,(k,v)| hsh.merge(k.to_s => v) }
|
26
|
+
end
|
27
|
+
|
28
|
+
# Public: Directory of the Jekyll source folder
|
29
|
+
#
|
30
|
+
# override - the command-line options hash
|
31
|
+
#
|
32
|
+
# Returns the path to the Jekyll source directory
|
33
|
+
def source(override)
|
34
|
+
override['source'] || self['source'] || DEFAULTS['source']
|
35
|
+
end
|
36
|
+
|
37
|
+
def safe_load_file(filename)
|
38
|
+
case File.extname(filename)
|
39
|
+
when '.toml'
|
40
|
+
TOML.load_file(filename)
|
41
|
+
when /\.y(a)?ml/
|
42
|
+
YAML.safe_load_file(filename)
|
43
|
+
else
|
44
|
+
raise ArgumentError, "No parser for '#{filename}' is available. Use a .toml or .y(a)ml file instead."
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
# Public: Generate list of configuration files from the override
|
49
|
+
#
|
50
|
+
# override - the command-line options hash
|
51
|
+
#
|
52
|
+
# Returns an Array of config files
|
53
|
+
def config_files(override)
|
54
|
+
# Get configuration from <source>/_config.yml or <source>/<config_file>
|
55
|
+
config_files = override.delete('config')
|
56
|
+
if config_files.to_s.empty?
|
57
|
+
config_files = File.join(source(override), "_config.yml")
|
58
|
+
@default_config_file = true
|
59
|
+
end
|
60
|
+
config_files = [config_files] unless config_files.is_a? Array
|
61
|
+
config_files
|
62
|
+
end
|
63
|
+
|
64
|
+
# Public: Read configuration and return merged Hash
|
65
|
+
#
|
66
|
+
# file - the path to the YAML file to be read in
|
67
|
+
#
|
68
|
+
# Returns this configuration, overridden by the values in the file
|
69
|
+
def read_config_file(file)
|
70
|
+
next_config = safe_load_file(file)
|
71
|
+
raise ArgumentError.new("Configuration file: (INVALID) #{file}".yellow) unless next_config.is_a?(Hash)
|
72
|
+
Hyde.logger.info "Configuration file:", file
|
73
|
+
next_config
|
74
|
+
rescue SystemCallError
|
75
|
+
if @default_config_file
|
76
|
+
Hyde.logger.warn "Configuration file:", "none"
|
77
|
+
{}
|
78
|
+
else
|
79
|
+
Hyde.logger.error "Fatal:", "The configuration file '#{file}' could not be found."
|
80
|
+
raise LoadError, "The Configuration file '#{file}' could not be found."
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
# Public: Read in a list of configuration files and merge with this hash
|
85
|
+
#
|
86
|
+
# files - the list of configuration file paths
|
87
|
+
#
|
88
|
+
# Returns the full configuration, with the defaults overridden by the values in the
|
89
|
+
# configuration files
|
90
|
+
def read_config_files(files)
|
91
|
+
configuration = clone
|
92
|
+
|
93
|
+
begin
|
94
|
+
files.each do |config_file|
|
95
|
+
new_config = read_config_file(config_file)
|
96
|
+
configuration = configuration.deep_merge(new_config)
|
97
|
+
end
|
98
|
+
rescue ArgumentError => err
|
99
|
+
Hyde.logger.warn "WARNING:", "Error reading configuration. " +
|
100
|
+
"Using defaults (and options)."
|
101
|
+
$stderr.puts "#{err}"
|
102
|
+
end
|
103
|
+
|
104
|
+
configuration.fix_common_issues.backwards_compatibilize
|
105
|
+
end
|
106
|
+
|
107
|
+
def fix_common_issues
|
108
|
+
clone
|
109
|
+
end
|
110
|
+
|
111
|
+
def backwards_compatibilize
|
112
|
+
clone
|
113
|
+
end
|
114
|
+
|
115
|
+
end
|
116
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
module Hyde
|
2
|
+
|
3
|
+
class JekyllFile
|
4
|
+
attr_accessor :original, :destination
|
5
|
+
|
6
|
+
def initialize(location, destination)
|
7
|
+
self.original = File.absolute_path(location)
|
8
|
+
data = read_yaml(self.original)
|
9
|
+
|
10
|
+
name = File.basename(location)
|
11
|
+
time = if data['hyde_date']
|
12
|
+
Time.parse(data['hyde_date'])
|
13
|
+
else
|
14
|
+
File.mtime(location)
|
15
|
+
end
|
16
|
+
|
17
|
+
dest_file_name = "#{time.strftime('%Y-%m-%d')}-#{name}"
|
18
|
+
|
19
|
+
self.destination = File.join(destination, dest_file_name)
|
20
|
+
end
|
21
|
+
|
22
|
+
def write
|
23
|
+
File.symlink(self.original, self.destination)
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
# Read the YAML frontmatter.
|
29
|
+
#
|
30
|
+
# base - The String path to the dir containing the file.
|
31
|
+
# name - The String filename of the file.
|
32
|
+
# opts - optional parameter to File.read, default at site configs
|
33
|
+
#
|
34
|
+
# Returns nothing.
|
35
|
+
def read_yaml(file)
|
36
|
+
data = nil
|
37
|
+
|
38
|
+
begin
|
39
|
+
content = File.read_with_options(file, {})
|
40
|
+
if content =~ /\A(---\s*\n.*?\n?)^(---\s*$\n?)/m
|
41
|
+
data = YAML.safe_load($1)
|
42
|
+
end
|
43
|
+
rescue SyntaxError => e
|
44
|
+
puts "YAML Exception reading #{File.join(base, name)}: #{e.message}"
|
45
|
+
rescue Exception => e
|
46
|
+
puts "Error reading file #{File.join(base, name)}: #{e.message}"
|
47
|
+
end
|
48
|
+
|
49
|
+
data ||= {}
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
data/lib/hyde/site.rb
ADDED
@@ -0,0 +1,134 @@
|
|
1
|
+
module Hyde
|
2
|
+
|
3
|
+
class Site
|
4
|
+
attr_accessor :config, :map, :source, :jekyll_source, :dest, :time, :files
|
5
|
+
|
6
|
+
def initialize(config)
|
7
|
+
self.config = config
|
8
|
+
|
9
|
+
self.map = config['map'] || {}
|
10
|
+
self.source = File.expand_path(config['source'])
|
11
|
+
self.jekyll_source = File.expand_path(config['jekyll'])
|
12
|
+
self.dest = File.expand_path(config['jekyll-out'])
|
13
|
+
|
14
|
+
self.reset
|
15
|
+
self.setup
|
16
|
+
end
|
17
|
+
|
18
|
+
def process
|
19
|
+
self.reset
|
20
|
+
self.directories
|
21
|
+
self.read
|
22
|
+
self.write
|
23
|
+
self.build
|
24
|
+
self.cleanup
|
25
|
+
end
|
26
|
+
|
27
|
+
# reset the time
|
28
|
+
def reset
|
29
|
+
self.time = if self.config['time']
|
30
|
+
Time.parse(self.config['time'].to_s)
|
31
|
+
else
|
32
|
+
Time.now
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
# copy Jekyll source files
|
37
|
+
def setup
|
38
|
+
FileUtils.rm_rf(self.dest)
|
39
|
+
FileUtils.cp_r(self.jekyll_source, self.dest, :preserve => true)
|
40
|
+
end
|
41
|
+
|
42
|
+
# create the Hyde-to-Jekyll output directories
|
43
|
+
def directories
|
44
|
+
self.map.each do |source_d, dest_d|
|
45
|
+
source = File.join(self.source, source_d)
|
46
|
+
if File.exists?(source)
|
47
|
+
dest = File.join(self.dest, dest_d)
|
48
|
+
if File.exists?(dest)
|
49
|
+
Hyde.logger.abort_with 'Illegal file:' "Expected destination file #{dest_d}/_posts to be a directory but found a file" unless File.directory?(dest)
|
50
|
+
Hyde.logger.warn 'Destination exists:', "Destination directory #{dest_d} exists, deleting content" unless self.config['watching']
|
51
|
+
|
52
|
+
Dir[File.join(dest, '*')].each do |f|
|
53
|
+
FileUtils.rm_rf(f)
|
54
|
+
end
|
55
|
+
else
|
56
|
+
FileUtils.mkdir_p(dest)
|
57
|
+
end
|
58
|
+
else
|
59
|
+
Hyde.logger.warn 'File not found:', "Directory #{source_d} does not exist, skipping directory"
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
# read files
|
65
|
+
def read
|
66
|
+
self.files ||= Hash.new
|
67
|
+
self.map.each do |source_d, dest_d|
|
68
|
+
files = Hash.new
|
69
|
+
Hyde.logger.error 'Duplicate source:', "directory \"#{source_d}\"" if self.files[source_d]
|
70
|
+
self.files[source_d] = files
|
71
|
+
|
72
|
+
read_directory(source_d, files, File.join(self.dest, dest_d))
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
private
|
77
|
+
|
78
|
+
def read_directory(directory, data, destination)
|
79
|
+
Dir[File.join(directory, '*')].sort.each do |file|
|
80
|
+
if File.directory?(file)
|
81
|
+
fdata = Hash.new
|
82
|
+
read_directory(file, fdata, destination)
|
83
|
+
data[File.basename(file)] = fdata
|
84
|
+
else
|
85
|
+
data[File.basename(file)] = JekyllFile.new(file, destination)
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
public
|
91
|
+
|
92
|
+
# write jekyll files
|
93
|
+
def write
|
94
|
+
self.files.each do |name, files|
|
95
|
+
write_recursive(files, File.join(self.dest, self.map[name]))
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
private
|
100
|
+
|
101
|
+
def write_recursive(files, directory)
|
102
|
+
files.each do |name, file|
|
103
|
+
if file.is_a?(JekyllFile)
|
104
|
+
file.write
|
105
|
+
else
|
106
|
+
write_recursive(file, directory)
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
public
|
112
|
+
|
113
|
+
# cleanup
|
114
|
+
def cleanup
|
115
|
+
self.files = Hash.new
|
116
|
+
FileUtils.rm_rf(self.dest) unless self.config['keep'] or self.config['watching']
|
117
|
+
end
|
118
|
+
|
119
|
+
# runs Jekyll
|
120
|
+
def build
|
121
|
+
jekyll_options = Hash.new
|
122
|
+
|
123
|
+
%w[safe destination verbose].each do |c|
|
124
|
+
jekyll_options[c] = self.config[c] if self.config[c]
|
125
|
+
end
|
126
|
+
|
127
|
+
jekyll_options['source'] = self.dest
|
128
|
+
|
129
|
+
jekyll_options = Jekyll::configuration(jekyll_options)
|
130
|
+
Jekyll::Commands::Build.process(jekyll_options)
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Jekyll
|
2
|
+
|
3
|
+
class Stevenson
|
4
|
+
def formatted_topic(topic)
|
5
|
+
"J " + "#{topic} ".rjust(22)
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
end
|
10
|
+
|
11
|
+
module Hyde
|
12
|
+
|
13
|
+
class Stevenson < Jekyll::Stevenson
|
14
|
+
def formatted_topic(topic)
|
15
|
+
"H " + "#{topic} ".rjust(22)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
data/lib/hyde.rb
ADDED
@@ -0,0 +1,57 @@
|
|
1
|
+
$:.unshift File.dirname(__FILE__) # For use/testing when no gem is installed
|
2
|
+
|
3
|
+
require 'jekyll'
|
4
|
+
|
5
|
+
def require_all(directory)
|
6
|
+
glob = File.join(File.dirname(__FILE__), directory, '*.rb')
|
7
|
+
Dir[glob].each do |f|
|
8
|
+
require f
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
require 'hyde/configuration'
|
13
|
+
require 'hyde/jekyllfile'
|
14
|
+
require 'hyde/site'
|
15
|
+
require 'hyde/command'
|
16
|
+
require 'hyde/stevenson'
|
17
|
+
|
18
|
+
require_all 'hyde/commands'
|
19
|
+
|
20
|
+
module Hyde
|
21
|
+
VERSION = '0.1.0'
|
22
|
+
|
23
|
+
# Public: Generate a Hyde configuration Hash by merging the default
|
24
|
+
# options with anything in _config.yml, and adding the given options on top.
|
25
|
+
#
|
26
|
+
# override - A Hash of config directives that override any options in both
|
27
|
+
# the defaults and the config file. See Hyde::Configuration::DEFAULTS for a
|
28
|
+
# list of option names and their defaults.
|
29
|
+
#
|
30
|
+
# Returns the final configuration Hash.
|
31
|
+
def self.configuration(override)
|
32
|
+
config = Configuration[Configuration::DEFAULTS]
|
33
|
+
override = Configuration[override].stringify_keys
|
34
|
+
config = config.read_config_files(config.config_files(override))
|
35
|
+
|
36
|
+
# Merge DEFAULTS < _config.yml < override
|
37
|
+
config = config.deep_merge(override).stringify_keys
|
38
|
+
set_timezone(config['timezone']) if config['timezone']
|
39
|
+
|
40
|
+
config
|
41
|
+
end
|
42
|
+
|
43
|
+
def self.jekyll_configuration(configuration)
|
44
|
+
config = Jekyll::Configuration[Jekyll::Configuration::DEFAULTS]
|
45
|
+
override = Jekyll::Configuration[{
|
46
|
+
'source' => configuration['jekyll-out'],
|
47
|
+
'destination' => configuration['destination']
|
48
|
+
}].stringify_keys
|
49
|
+
config = config.read_config_files(config.config_files(override))
|
50
|
+
|
51
|
+
config.stringify_keys
|
52
|
+
end
|
53
|
+
|
54
|
+
def self.logger
|
55
|
+
@logger ||= Stevenson.new
|
56
|
+
end
|
57
|
+
end
|
metadata
ADDED
@@ -0,0 +1,133 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: bgotink-hyde
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Bram Gotink
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-01-08 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: jekyll
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ~>
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 1.4.2
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ~>
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 1.4.2
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: listen
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ~>
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '1.3'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ~>
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '1.3'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: commander
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ~>
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 4.1.3
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ~>
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 4.1.3
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: safe_yaml
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ~>
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 0.9.7
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ~>
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: 0.9.7
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rake
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ~>
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '10.1'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ~>
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '10.1'
|
83
|
+
description: Hyde is a simple front-end for Jekyll, the simple, blog-aware static
|
84
|
+
site generator.
|
85
|
+
email: bram@gotink.me
|
86
|
+
executables:
|
87
|
+
- hyde
|
88
|
+
extensions: []
|
89
|
+
extra_rdoc_files:
|
90
|
+
- README.md
|
91
|
+
- LICENSE
|
92
|
+
files:
|
93
|
+
- Gemfile
|
94
|
+
- History.md
|
95
|
+
- LICENSE
|
96
|
+
- README.md
|
97
|
+
- Rakefile
|
98
|
+
- bgotink-hyde.gemspec
|
99
|
+
- bin/hyde
|
100
|
+
- lib/hyde.rb
|
101
|
+
- lib/hyde/command.rb
|
102
|
+
- lib/hyde/commands/build.rb
|
103
|
+
- lib/hyde/commands/serve.rb
|
104
|
+
- lib/hyde/configuration.rb
|
105
|
+
- lib/hyde/jekyllfile.rb
|
106
|
+
- lib/hyde/site.rb
|
107
|
+
- lib/hyde/stevenson.rb
|
108
|
+
homepage: http://github.com/bgotink/hyde
|
109
|
+
licenses:
|
110
|
+
- MIT
|
111
|
+
metadata: {}
|
112
|
+
post_install_message:
|
113
|
+
rdoc_options:
|
114
|
+
- --charset=UTF-8
|
115
|
+
require_paths:
|
116
|
+
- lib
|
117
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
118
|
+
requirements:
|
119
|
+
- - '>='
|
120
|
+
- !ruby/object:Gem::Version
|
121
|
+
version: '0'
|
122
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
123
|
+
requirements:
|
124
|
+
- - '>='
|
125
|
+
- !ruby/object:Gem::Version
|
126
|
+
version: '0'
|
127
|
+
requirements: []
|
128
|
+
rubyforge_project: bgotink-hyde
|
129
|
+
rubygems_version: 2.2.1
|
130
|
+
signing_key:
|
131
|
+
specification_version: 2
|
132
|
+
summary: A user-friendly front-end for Jekyll
|
133
|
+
test_files: []
|