bgotink-hyde 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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: []
|