mascot 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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 19f9e7b959947630495440f3a2c7c728dcb02af7
4
+ data.tar.gz: 88f1c9212234555876648f7f77952d6cd3b47fbc
5
+ SHA512:
6
+ metadata.gz: 04c0b817aad5d980a610c88f3e772486d195c4a75ad8b4c16c2326d4159c32f3fe37584f5cb9b990dfefa944cdb54abf84269608985ccf1f9014d8d6518c433a
7
+ data.tar.gz: 3bb29074fdd9c5df6a7bed480b9c748bcce654a5ff8d4a115b6cbe21ef9889ac0ab9f692da952ffa9a8ca63f4074362798f1be8aca2c06c8b5bd6f2b62e9cd95
data/.gitignore ADDED
@@ -0,0 +1,9 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
data/.travis.yml ADDED
@@ -0,0 +1,5 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.3.0
4
+ before_install: gem install bundler -v 1.11.2
5
+ script: bundle exec rspec spec
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in mascot.gemspec
4
+ gemspec
data/Guardfile ADDED
@@ -0,0 +1,70 @@
1
+ # A sample Guardfile
2
+ # More info at https://github.com/guard/guard#readme
3
+
4
+ ## Uncomment and set this to only include directories you want to watch
5
+ # directories %w(app lib config test spec features) \
6
+ # .select{|d| Dir.exists?(d) ? d : UI.warning("Directory #{d} does not exist")}
7
+
8
+ ## Note: if you are using the `directories` clause above and you are not
9
+ ## watching the project directory ('.'), then you will want to move
10
+ ## the Guardfile to a watched dir and symlink it back, e.g.
11
+ #
12
+ # $ mkdir config
13
+ # $ mv Guardfile config/
14
+ # $ ln -s config/Guardfile .
15
+ #
16
+ # and, you'll have to watch "config/Guardfile" instead of "Guardfile"
17
+
18
+ # Note: The cmd option is now required due to the increasing number of ways
19
+ # rspec may be run, below are examples of the most common uses.
20
+ # * bundler: 'bundle exec rspec'
21
+ # * bundler binstubs: 'bin/rspec'
22
+ # * spring: 'bin/rspec' (This will use spring if running and you have
23
+ # installed the spring binstubs per the docs)
24
+ # * zeus: 'zeus rspec' (requires the server to be started separately)
25
+ # * 'just' rspec: 'rspec'
26
+
27
+ guard :rspec, cmd: "bundle exec rspec" do
28
+ require "guard/rspec/dsl"
29
+ dsl = Guard::RSpec::Dsl.new(self)
30
+
31
+ # Feel free to open issues for suggestions and improvements
32
+
33
+ # RSpec files
34
+ rspec = dsl.rspec
35
+ watch(rspec.spec_helper) { rspec.spec_dir }
36
+ watch(rspec.spec_support) { rspec.spec_dir }
37
+ watch(rspec.spec_files)
38
+
39
+ # Ruby files
40
+ ruby = dsl.ruby
41
+ dsl.watch_spec_files_for(ruby.lib_files)
42
+
43
+ # Rails files
44
+ rails = dsl.rails(view_extensions: %w(erb haml slim))
45
+ dsl.watch_spec_files_for(rails.app_files)
46
+ dsl.watch_spec_files_for(rails.views)
47
+
48
+ watch(rails.controllers) do |m|
49
+ [
50
+ rspec.spec.("routing/#{m[1]}_routing"),
51
+ rspec.spec.("controllers/#{m[1]}_controller"),
52
+ rspec.spec.("acceptance/#{m[1]}")
53
+ ]
54
+ end
55
+
56
+ # Rails config changes
57
+ watch(rails.spec_helper) { rspec.spec_dir }
58
+ watch(rails.routes) { "#{rspec.spec_dir}/routing" }
59
+ watch(rails.app_controller) { "#{rspec.spec_dir}/controllers" }
60
+
61
+ # Capybara features specs
62
+ watch(rails.view_dirs) { |m| rspec.spec.("features/#{m[1]}") }
63
+ watch(rails.layouts) { |m| rspec.spec.("features/#{m[1]}") }
64
+
65
+ # Turnip features and steps
66
+ watch(%r{^spec/acceptance/(.+)\.feature$})
67
+ watch(%r{^spec/acceptance/steps/(.+)_steps\.rb$}) do |m|
68
+ Dir[File.join("**/#{m[1]}.feature")][0] || "spec/acceptance"
69
+ end
70
+ end
data/README.md ADDED
@@ -0,0 +1,146 @@
1
+ # Mascot
2
+
3
+ Mascot is a file-backed website content manager that can be embedded in popular web frameworks like Rails, run stand-alone, or be compiled into static sites.
4
+
5
+ [![Build Status](https://travis-ci.org/bradgessler/mascot.svg?branch=master)](https://travis-ci.org/bradgessler/mascot)
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ ```ruby
12
+ gem 'mascot'
13
+ ```
14
+
15
+ And then execute:
16
+
17
+ $ bundle
18
+
19
+ Or install it yourself as:
20
+
21
+ $ gem install mascot
22
+
23
+ ## Usage
24
+
25
+ Given a haml file like:
26
+
27
+ ```haml
28
+ ---
29
+ title: Name
30
+ meta:
31
+ keywords: One
32
+ ---
33
+
34
+ !!!
35
+ %html
36
+ %head
37
+ %title=current_page.data["title"]
38
+ %body
39
+ %h1 Hi
40
+ %p This is just some content
41
+ %h2 There
42
+ ```
43
+
44
+ Mascot can parse out the frontmatter and body to render inside your framework of choice, like Rails:
45
+
46
+ ```ruby
47
+ class MascotController < ApplicationController
48
+ # TODO: Isolate this integration into a rails engine. Copy
49
+ # the way HighVoltage provides routes and scopes everything.
50
+ def show
51
+ sitemap = Rails.application.config.sitemap
52
+
53
+ resource = sitemap.find_by_request_path(request.path)
54
+ if resource
55
+ # TODO: Implement a whitelisted, chained handler for
56
+ # the template type with ActionView::Template::Handlers.extensions
57
+ template_type = resource.file_path.extname.delete(".")
58
+ @_locals = resource.locals.merge(sitemap: sitemap)
59
+ layout = resource.data.fetch("layout", "high_voltage")
60
+ render inline: resource.body, type: template_type, layout: layout, locals: @_locals
61
+ else
62
+ render status: :not_found, text: "#{request.path} Not Found"
63
+ end
64
+ end
65
+ end
66
+ ```
67
+
68
+ so when you call `current_page.data` from your templates, you get something like this:
69
+
70
+ ```irb
71
+ > current_page.data
72
+ => {"title"=>"Name", "meta"=>{"keywords"=>"One"}, "toc"=>["Hi", "There"]}
73
+ > current_page.data.dig("meta", "keywords")
74
+ => "One"
75
+ ```
76
+
77
+ Mascot is designed to be embedded in rails and other Ruby web frameworks.
78
+
79
+ # Features
80
+
81
+ Mascot implements a subset of the best features from the [Middleman](http://www.middlemanapp.com/) static site generator including the Sitemap and Frontmatter.
82
+
83
+ ## Frontmatter
84
+
85
+ Frontmatter is a way to attach metadata to content pages. Its a powerful way to enable a team of writers and engineers work together on content. The engineers focus on reading values from frontmatter while the writers can change values.
86
+
87
+ ```haml
88
+ ---
89
+ title: This is a swell doc
90
+ meta:
91
+ keywords: this, is, a, test
92
+ background_color: #0f0
93
+ ---
94
+
95
+ %html
96
+ %head
97
+ %meta(name="keywords" value="#{current_page.data.dig("meta", "keywords")}")
98
+ %body(style="background: #{current_page.data["background_color"]};")
99
+ %h1=current_page.data["title"]
100
+ %p And here's the rest of the content!
101
+ ```
102
+
103
+ ## Sitemap
104
+
105
+ The Sitemap accepts a directory path
106
+
107
+ ```irb
108
+ > sitemap = Mascot::Sitemap.new(file_path: "spec/pages")
109
+ => #<Mascot::Sitemap:0x007fcd24103710 @file_path=#<Pathname:spec/pages>, @request_path=#<Pathname:/>>
110
+ ```
111
+
112
+ Then you can request a resource by request path:
113
+
114
+ ```irb
115
+ > resource = sitemap.find_by_request_path("/test")
116
+ => #<Mascot::Resource:0x007fcd2488a128 @request_path="/test", @content_type="text/html", @file_path=#<Pathname:spec/pages/test.html.haml>, @frontmatter=#<Mascot::Frontmatter:0x007fcd24889e80 @data="title: Name\nmeta:\n keywords: One", @body="\n!!!\n%html\n %head\n %title=current_page.data[\"title\"]\n %body\n %h1 Hi\n %p This is just some content\n %h2 There\n">>
117
+ ```
118
+
119
+ And access the frontmatter data (if available) and body of the template.
120
+
121
+ ```irb
122
+ > resource.data
123
+ => {"title"=>"Name", "meta"=>{"keywords"=>"One"}}
124
+ > resource.body
125
+ => "\n!!!\n%html\n %head\n %title=current_page.data[\"title\"]\n %body\n %h1 Hi\n %p This is just some content\n %h2 There\n"
126
+ ```
127
+
128
+ ### Resource globbing
129
+
130
+ The Sitemap API is a powerful way to query content via resource globbing. For example, if you have a folder full of files but you only want all `.html` files within the `docs` directory, you'd do something like:
131
+
132
+ ```haml
133
+ %ol
134
+ -sitemap.resources("docs/*.html*").each do |page|
135
+ %li=link_to page.data["title"], page.request_path
136
+ ```
137
+
138
+ ## Development
139
+
140
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
141
+
142
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
143
+
144
+ ## Contributing
145
+
146
+ Bug reports and pull requests are welcome on GitHub at https://github.com/bradgessler/mascot.
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "mascot"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
data/config.ru ADDED
@@ -0,0 +1,3 @@
1
+ require "mascot"
2
+
3
+ run Mascot::Server.glob("spec/pages/*")
@@ -0,0 +1,3 @@
1
+ module Mascot
2
+ VERSION = "0.1.0"
3
+ end
data/lib/mascot.rb ADDED
@@ -0,0 +1,136 @@
1
+ require "mascot/version"
2
+
3
+ module Mascot
4
+ require "yaml"
5
+
6
+ # Parses metadata from the header of the page.
7
+ class Frontmatter
8
+ DELIMITER = "---".freeze
9
+ PATTERN = /\A(#{DELIMITER}\n(.+)\n#{DELIMITER}\n)?(.+)\Z/m
10
+
11
+ attr_reader :body
12
+
13
+ def initialize(content)
14
+ _, @data, @body = content.match(PATTERN).captures
15
+ end
16
+
17
+ def data
18
+ @data ? YAML.load(@data) : {}
19
+ end
20
+
21
+ private
22
+ def parse
23
+ @content
24
+ end
25
+ end
26
+
27
+ # Represents a page in a web server context.
28
+ class Resource
29
+ # TODO: I don't like the Binding, locals, and frontmatter
30
+ # being in the Resource. That should be moved to a page
31
+ # object and be delegated to that. Or perhaps the page body?
32
+ # I'm moving forward with this now though to keep the objects simpler.
33
+ # We'll see how it evolves.
34
+ Binding = Struct.new(:data)
35
+
36
+ CONTENT_TYPE = "text/html".freeze
37
+
38
+ attr_reader :request_path, :file_path, :content_type
39
+
40
+ extend Forwardable
41
+ def_delegators :@frontmatter, :data, :body
42
+
43
+ def initialize(request_path: , file_path: , content_type: CONTENT_TYPE)
44
+ @request_path = request_path
45
+ @content_type = content_type
46
+ @file_path = Pathname.new file_path
47
+ @frontmatter = Frontmatter.new File.read @file_path
48
+ end
49
+
50
+ # Locals that should be merged into or given to the rendering context.
51
+ def locals
52
+ { current_page: Binding.new(data) }
53
+ end
54
+ end
55
+
56
+ # A collection of pages from a directory.
57
+ class Sitemap
58
+ # Default file pattern to pick up in sitemap
59
+ DEFAULT_GLOB = "**/*.*".freeze
60
+ # Default root path for sitemap.
61
+ DEFAULT_ROOT_DIR = Pathname.new(".").freeze
62
+ # Default root request path
63
+ DEFAULT_ROOT_REQUEST_PATH = Pathname.new("/").freeze
64
+
65
+ def initialize(file_path: DEFAULT_ROOT_DIR, request_path: DEFAULT_ROOT_REQUEST_PATH)
66
+ @file_path = Pathname.new(file_path)
67
+ @request_path = Pathname.new(request_path)
68
+ end
69
+
70
+ # Lazy stream of resources.
71
+ def resources(glob = DEFAULT_GLOB)
72
+ Dir[@file_path.join(glob)].lazy.map do |path|
73
+ Resource.new request_path: request_path(path), file_path: path
74
+ end
75
+ end
76
+
77
+ # Find the page with a path.
78
+ def find_by_request_path(request_path)
79
+ resources.find { |r| r.request_path == request_path }
80
+ end
81
+
82
+ private
83
+ # Given a @file_path of `/hi`, this method changes `/hi/there/friend.html.erb`
84
+ # to an absolute `/there/friend` format by removing the file extensions
85
+ def request_path(path)
86
+ # Relative path of resource to the file_path of this project.
87
+ relative_path = Pathname.new(path).relative_path_from(@file_path)
88
+ # Removes the .fooz.baz
89
+ @request_path.join(relative_path).to_s.sub(/\..*/, '')
90
+ end
91
+ end
92
+
93
+ require "tilt"
94
+
95
+ class TiltRenderer
96
+ def initialize(resource)
97
+ @resource = resource
98
+ end
99
+
100
+ def render
101
+ template = engine.new { |t| @resource.body }
102
+ template.render(Object.new, @resource.locals)
103
+ end
104
+
105
+ private
106
+ def engine
107
+ Tilt[@resource.file_path]
108
+ end
109
+ end
110
+
111
+ # Mount inside of a config.ru file to run this as a server.
112
+ class Server
113
+ ROOT_PATH = Pathname.new("/")
114
+
115
+ def initialize(sitemap, relative_to: "/")
116
+ @relative_to = Pathname.new(relative_to)
117
+ @sitemap = sitemap
118
+ end
119
+
120
+ def call(env)
121
+ req = Rack::Request.new(env)
122
+ if resource = @sitemap.find_by_request_path(normalize_path(req.path))
123
+ [ 200, {"Content-Type" => resource.content_type}, [TiltRenderer.new(resource).render] ]
124
+ else
125
+ [ 404, {"Content-Type" => "text/plain"}, ["Not Found"]]
126
+ end
127
+ end
128
+
129
+ private
130
+ # If we mount this middleware in a path other than root, we need to configure it
131
+ # so that it correctly maps the request path to the content path.
132
+ def normalize_path(request_path)
133
+ ROOT_PATH.join(Pathname.new(request_path).relative_path_from(@relative_to)).to_s
134
+ end
135
+ end
136
+ end
data/mascot.gemspec ADDED
@@ -0,0 +1,30 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'mascot/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "mascot"
8
+ spec.version = Mascot::VERSION
9
+ spec.authors = ["Brad Gessler"]
10
+ spec.email = ["bradgessler@gmail.com"]
11
+
12
+ spec.summary = %q{An experiment in data driven static website generation.}
13
+ spec.homepage = "https://github.com/bradgessler/mascot"
14
+
15
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
16
+ spec.bindir = "exe"
17
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
18
+ spec.require_paths = ["lib"]
19
+
20
+ spec.add_development_dependency "bundler", "~> 1.11"
21
+ spec.add_development_dependency "rake", "~> 10.0"
22
+ spec.add_development_dependency "rspec", "~> 3.0"
23
+ spec.add_development_dependency "haml", "~> 4.0"
24
+ spec.add_development_dependency "guard-rspec"
25
+ spec.add_development_dependency "rack-test"
26
+ spec.add_development_dependency "rack"
27
+ spec.add_development_dependency "actionpack", "~> 4.2"
28
+
29
+ spec.add_dependency "tilt"
30
+ end
metadata ADDED
@@ -0,0 +1,183 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: mascot
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Brad Gessler
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2016-07-20 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.11'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.11'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '3.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '3.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: haml
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '4.0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '4.0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: guard-rspec
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rack-test
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: rack
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: actionpack
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - "~>"
116
+ - !ruby/object:Gem::Version
117
+ version: '4.2'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - "~>"
123
+ - !ruby/object:Gem::Version
124
+ version: '4.2'
125
+ - !ruby/object:Gem::Dependency
126
+ name: tilt
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ">="
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ type: :runtime
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - ">="
137
+ - !ruby/object:Gem::Version
138
+ version: '0'
139
+ description:
140
+ email:
141
+ - bradgessler@gmail.com
142
+ executables: []
143
+ extensions: []
144
+ extra_rdoc_files: []
145
+ files:
146
+ - ".gitignore"
147
+ - ".rspec"
148
+ - ".travis.yml"
149
+ - Gemfile
150
+ - Guardfile
151
+ - README.md
152
+ - Rakefile
153
+ - bin/console
154
+ - bin/setup
155
+ - config.ru
156
+ - lib/mascot.rb
157
+ - lib/mascot/version.rb
158
+ - mascot.gemspec
159
+ homepage: https://github.com/bradgessler/mascot
160
+ licenses: []
161
+ metadata: {}
162
+ post_install_message:
163
+ rdoc_options: []
164
+ require_paths:
165
+ - lib
166
+ required_ruby_version: !ruby/object:Gem::Requirement
167
+ requirements:
168
+ - - ">="
169
+ - !ruby/object:Gem::Version
170
+ version: '0'
171
+ required_rubygems_version: !ruby/object:Gem::Requirement
172
+ requirements:
173
+ - - ">="
174
+ - !ruby/object:Gem::Version
175
+ version: '0'
176
+ requirements: []
177
+ rubyforge_project:
178
+ rubygems_version: 2.5.1
179
+ signing_key:
180
+ specification_version: 4
181
+ summary: An experiment in data driven static website generation.
182
+ test_files: []
183
+ has_rdoc: