gerablog 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: 841577cfe74ad755f922db7916d3a65586ee67a7
4
+ data.tar.gz: c390d5e4f493b5fc39d10fcaf4c6cf6f9a0a588c
5
+ SHA512:
6
+ metadata.gz: d56e2d2c48854cd453ac24f2affca7a226cff52dc56f5e71f943ca43ca481c7aab9f9f9d6af497f1c0c8f0a86e2daf05ea3c0c7d2512a8033683992d0ae4989f
7
+ data.tar.gz: d545dfe321b12f1c69da0ffed74ac0c917abab45e159586dbbc91cf9d015921dc52fb506335a68fba6abc1cd649c99473b94221f50bd464da5b681eae1a6e063
@@ -0,0 +1,68 @@
1
+ body {
2
+ font-family: Verdana, Geneva, sans-serif;
3
+
4
+ background-color: white;
5
+ color: black;
6
+
7
+ width: 90%;
8
+ margin: 0 auto;
9
+ }
10
+
11
+ a:link, a:visited { color: royalblue; text-decoration: none; }
12
+ a:hover { color: blue; text-decoration: underline; font-weight: 500; }
13
+ a:active { color: white; }
14
+
15
+ h1 {
16
+ color: green;
17
+ }
18
+
19
+ /* https://css-tricks.com/snippets/css/simple-and-nice-blockquote-styling/ */
20
+ blockquote {
21
+ background: #f9f9f9;
22
+ border-left: 10px solid #ccc;
23
+ margin: 1.5em 10px;
24
+ padding: 0.5em 10px;
25
+ quotes: "\201C""\201D""\2018""\2019";
26
+ }
27
+
28
+ footer {
29
+ clear: both;
30
+ font-size: 60%;
31
+ margin-top: 3em;
32
+ }
33
+
34
+ #mainnav {
35
+ padding: 0 0;
36
+ margin-bottom: 22px;
37
+ }
38
+
39
+ #mainnav ul {
40
+ margin: 0 0 0 0;
41
+ padding: 0;
42
+ list-style-type: none;
43
+ border-left: 1px solid black;
44
+ }
45
+
46
+ #mainnav li {
47
+ display: inline;
48
+ padding: 0 10px;
49
+ border-right: 1px solid black;
50
+ }
51
+
52
+ h3.textcal {
53
+ color: green;
54
+ margin-bottom: 0;
55
+ }
56
+
57
+ p.textcal {
58
+ color: black;
59
+ margin-top: 0;
60
+ }
61
+
62
+ img {
63
+ vertical-align: top;
64
+ width: auto;
65
+ height: auto;
66
+ max-width:300px;
67
+ max-height:300px;
68
+ }
data/bin/gerablog ADDED
@@ -0,0 +1,41 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'optparse'
4
+ require 'fileutils'
5
+
6
+ require 'gerablog'
7
+
8
+ options = {}
9
+
10
+ optparse = OptionParser.new do |opts|
11
+ opts.banner = 'Usage: optparse [options]'
12
+
13
+ opts.on('-h', '--help', 'Display this screen') do
14
+ puts opts
15
+ exit
16
+ end
17
+
18
+ options[:new] = nil
19
+ opts.on('-n', '--new FILENAME', 'Create a new project.') do |value|
20
+ options[:new] = value
21
+ end
22
+
23
+ options[:generate] = nil
24
+ opts.on('-g', '--generate FILENAME', 'Generate the static blog.') do |value|
25
+ options[:generate] = value
26
+ end
27
+ end
28
+
29
+ optparse.parse!
30
+
31
+ if options[:generate]
32
+ gb = GeraBlog::Blog.new
33
+ gb.load_config options[:generate] unless options[:generate].nil?
34
+ gb.save
35
+ elsif options[:new]
36
+ gb = GeraBlog::Blog.new options[:new]
37
+ gb.new_blog
38
+ gb.save_config
39
+ else
40
+ puts optparse.parse! %w(--help)
41
+ end
@@ -0,0 +1,205 @@
1
+ require 'date'
2
+ require 'parseconfig'
3
+
4
+ require_relative 'render'
5
+
6
+ # GeraBlog - a Static Blog Generator
7
+ module GeraBlog
8
+ VERSION = '0.1.0'.freeze
9
+
10
+ def self.make_dest_dir(src, dest, remove: false)
11
+ return unless Dir.exist? src
12
+ FileUtils.cp_r(src, dest, remove_destination: remove)
13
+ end
14
+
15
+ def self.create_dir(dir)
16
+ FileUtils.mkdir_p(dir) unless Dir.exist?(dir)
17
+ end
18
+
19
+ # Blog
20
+ class Blog
21
+ attr_reader :config
22
+
23
+ @posts = []
24
+
25
+ def ini_blog
26
+ @config.add 'blog',
27
+ 'root' => '.',
28
+ 'url' => 'http://localhost:8080',
29
+ 'title' => 'GeraBlog',
30
+ 'name' => 'GeraBlog Static Blog Generator',
31
+ 'description' => 'GeraBlog - My own static site generator',
32
+ 'language' => 'pt-br',
33
+ 'itens_in_rss' => '50'
34
+ end
35
+
36
+ def ini_dir(root)
37
+ @config.add 'dir',
38
+ 'root' => root,
39
+ 'texts' => File.join(root, 'texts'),
40
+ 'assets' => File.join(root, 'assets'),
41
+ 'output' => File.join(root, 'output'),
42
+ 'template' => File.join(root, 'templates')
43
+ end
44
+
45
+ def full_template_dir(file)
46
+ File.join @config['dir']['template'], file
47
+ end
48
+
49
+ def ini_template
50
+ @config.add 'template',
51
+ 'category' => full_template_dir('category.rbhtml'),
52
+ 'categories' => full_template_dir('categories.rbhtml'),
53
+ 'feed' => full_template_dir('feed.rbxml'),
54
+ 'post' => full_template_dir('post.rbhtml'),
55
+ 'footer' => full_template_dir('footer.rbhtml'),
56
+ 'header' => full_template_dir('header.rbhtml'),
57
+ 'index' => full_template_dir('index.rbhtml')
58
+ end
59
+
60
+ def reset_parser
61
+ @parser = Tenjin::Engine.new path: @config['dir']['templates']
62
+ end
63
+
64
+ def initialize(root = './')
65
+ @config = ParseConfig.new
66
+ ini_blog
67
+ ini_dir root
68
+ ini_template
69
+
70
+ reset_parser
71
+ end
72
+
73
+ def load_config(config_file)
74
+ @config = ParseConfig.new(config_file)
75
+ reset_parser
76
+ end
77
+
78
+ def save_config
79
+ @config.write(
80
+ File.open(File.join(@config['dir']['root'], 'gerablog.conf'), 'w')
81
+ )
82
+ end
83
+
84
+ def create_category_dir(category)
85
+ category_dir = File.join config['dir']['output'], 'texts', category
86
+
87
+ GeraBlog.create_dir category_dir
88
+
89
+ GeraBlog.make_dest_dir(
90
+ File.join(@config['dir']['texts'], category, 'images'),
91
+ category_dir,
92
+ remove: true
93
+ )
94
+ end
95
+
96
+ def new_blog
97
+ @config['dir'].values.map { |dir| GeraBlog.create_dir(dir) }
98
+ GeraBlog.make_dest_dir(
99
+ File.join(__dir__, '..', '..', 'assets'),
100
+ @config['dir']['root']
101
+ )
102
+
103
+ GeraBlog.make_dest_dir(
104
+ File.join(__dir__, '..', '..', 'templates'),
105
+ @config['dir']['root']
106
+ )
107
+ end
108
+
109
+ def create_dirs
110
+ GeraBlog.create_dir File.join(@config['dir']['output'], 'texts')
111
+
112
+ GeraBlog.make_dest_dir(
113
+ @config['dir']['assets'],
114
+ @config['dir']['output'],
115
+ remove: true
116
+ )
117
+
118
+ @posts.map { |p| p[:category] }
119
+ .uniq
120
+ .map { |category| create_category_dir category }
121
+ end
122
+
123
+ def write_category_index(file, template, category, title, posts)
124
+ context = {
125
+ title: title,
126
+ posts: posts,
127
+ config: @config,
128
+ categories: @categories
129
+ }
130
+
131
+ File.write(
132
+ File.join(@config['dir']['output'], 'texts', category, file),
133
+ @parser.render(template, context)
134
+ )
135
+ end
136
+
137
+ def write_posts
138
+ create_dirs
139
+
140
+ @posts.map { |post| File.write(post[:filename], post[:content]) }
141
+ end
142
+
143
+ def write_general_rss
144
+ File.write(
145
+ File.join(@config['dir']['output'], 'feed.xml'),
146
+ @parser.render(
147
+ @config['template']['feed'],
148
+ config: @config,
149
+ posts: @posts.take(Integer(@config['blog']['itens_in_rss']))
150
+ )
151
+ )
152
+ end
153
+
154
+ def write_general_html
155
+ context = {
156
+ config: @config,
157
+ categories: @categories,
158
+ title: {
159
+ title: @config['blog']['title'],
160
+ description: @config['blog']['description']
161
+ }
162
+ }
163
+
164
+ File.write(
165
+ File.join(@config['dir']['output'], 'index.html'),
166
+ @parser.render(@config['template']['index'], context)
167
+ )
168
+ end
169
+
170
+ def write_by_category_files
171
+ @posts.map { |p| p[:category] }.uniq.each do |category|
172
+ title = {
173
+ url: File.join(@config['blog']['url'], 'texts', category),
174
+ description: "#{@config['blog']['description']} (#{category})"
175
+ }
176
+
177
+ category_posts = @posts.select { |p| p[:category] == category }
178
+
179
+ write_category_index(
180
+ 'feed.xml',
181
+ @config['template']['feed'],
182
+ category,
183
+ title,
184
+ category_posts
185
+ )
186
+ write_category_index(
187
+ 'index.html',
188
+ @config['template']['category'],
189
+ category,
190
+ title,
191
+ category_posts
192
+ )
193
+ end
194
+ end
195
+
196
+ def save
197
+ @posts, @categories = GeraBlog::Render.new(@config).render
198
+
199
+ write_posts
200
+ write_general_rss
201
+ write_general_html
202
+ write_by_category_files
203
+ end
204
+ end
205
+ end
@@ -0,0 +1,58 @@
1
+ require 'redcarpet'
2
+
3
+ module GeraBlog
4
+ # My subclass to perform parse with code bloques options
5
+ class RedcarpetCustom < Redcarpet::Render::HTML
6
+ attr_reader :lang
7
+
8
+ def initialize(lang:)
9
+ super(prettify: true, escape_html: true)
10
+ @lang = lang
11
+ end
12
+
13
+ def block_code(code, language = nil)
14
+ l = language.nil? ? @lang : language
15
+ %(<pre><code class="language-#{l}">\n#{html_escape(code)}\n</code></pre>)
16
+ end
17
+
18
+ def html_escape(string)
19
+ string.gsub(
20
+ %r{['&\"<>\/]},
21
+ '&' => '&amp;',
22
+ '<' => '&lt;',
23
+ '>' => '&gt;',
24
+ '"' => '&quot;',
25
+ "'" => '&#x27;',
26
+ '/' => '&#x2F;'
27
+ )
28
+ end
29
+ end
30
+
31
+ # My Render class
32
+ class RedcarpetDriver
33
+ def initialize(lang, config)
34
+ @template = config['template']
35
+ @blog = config['blog']
36
+ @config = config
37
+ @render = Redcarpet::Markdown.new(RedcarpetCustom.new(lang: lang))
38
+ end
39
+
40
+ def converted(post, content)
41
+ post[:converted] = @render.render(content)
42
+ post
43
+ end
44
+
45
+ def to_html(post, content, categories)
46
+ Tenjin::Engine.new.render(
47
+ @template['post'],
48
+ config: @config,
49
+ post: converted(post, content),
50
+ categories: categories,
51
+ title: {
52
+ title: post[:title],
53
+ description: post[:description]
54
+ }
55
+ )
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,78 @@
1
+ require 'tenjin'
2
+ require_relative 'redcarpet'
3
+
4
+ module GeraBlog
5
+ # Get all markdown files and return posts in html
6
+ class Render
7
+ attr_reader :footer
8
+
9
+ def initialize(config)
10
+ @config = config
11
+ end
12
+
13
+ def render
14
+ c_dir = Dir[File.join(@config['dir']['texts'], '*')]
15
+ c_names = c_dir.map { |d| File.basename d }
16
+ categories_dir = Hash[c_names.zip c_dir]
17
+ parser = Tenjin::Engine.new
18
+ context = { categories: c_names, config: @config }
19
+ categories = parser.render @config['template']['categories'], context
20
+
21
+ [rendered_posts(categories_dir, categories), categories]
22
+ end
23
+
24
+ def rendered_posts(categories_dir, categories)
25
+ posts = []
26
+
27
+ categories_dir.each do |category, dir|
28
+ md_render = GeraBlog::RedcarpetDriver.new(category, @config)
29
+
30
+ Dir["#{dir}/*.md"].sort.reverse.each do |file|
31
+ posts.push render_post(md_render, file, category, categories)
32
+ end
33
+ end
34
+
35
+ posts
36
+ end
37
+
38
+ def make_full_filename(filename, category)
39
+ File.join(@config['dir']['output'], 'texts', category, filename)
40
+ end
41
+
42
+ def make_full_url(filename, category)
43
+ File.join(@config['blog']['url'], 'texts', category, filename)
44
+ end
45
+
46
+ def post_element(md_content, newfile, category)
47
+ lines = md_content.split("\n")
48
+
49
+ {
50
+ title: lines[0][2..-1],
51
+ category: category,
52
+ description: lines[2][3..-1],
53
+ date: Date.parse(newfile.match('\A(....-..-..)')[1]).rfc822,
54
+ filename: make_full_filename(newfile, category),
55
+ url: make_full_url(newfile, category),
56
+ markdown: md_content
57
+ }
58
+ end
59
+
60
+ def file_to_post(filename, category)
61
+ md_content = File.read(filename)
62
+ newfile = File.basename(filename).sub(/md$/, 'html')
63
+
64
+ post_element(md_content, newfile, category)
65
+ end
66
+
67
+ def render_post(md_render, filename, category, categories)
68
+ post = file_to_post(filename, category)
69
+ post[:content] = md_render.to_html(
70
+ post,
71
+ post[:markdown],
72
+ categories
73
+ )
74
+
75
+ post
76
+ end
77
+ end
78
+ end
data/lib/gerablog.rb ADDED
@@ -0,0 +1 @@
1
+ require 'gerablog/blog'
@@ -0,0 +1,12 @@
1
+ <?rb #@ARGS categories, config ?>
2
+ <nav id="mainnav">
3
+ <ul>
4
+ <?rb for category in categories do ?>
5
+ <li>
6
+ <a href="${config['blog']['url']}/texts/${category}/">
7
+ ${category}
8
+ </a>
9
+ </li>
10
+ <?rb end ?>
11
+ </ul>
12
+ </nav>
@@ -0,0 +1,11 @@
1
+ <?rb #@ARGS blog, posts, config, title, categories ?>
2
+ <?rb import config['template']['header'] ?>
3
+
4
+ <?rb for post in posts do ?>
5
+ <a href="${post[:url]}">
6
+ <h3 class="textcal">${post[:title]}</h3>
7
+ <p class="textcal">${post[:description]}</p>
8
+ </a>
9
+ <?rb end ?>
10
+
11
+ <?rb import config['template']['footer'] ?>
@@ -0,0 +1,21 @@
1
+ <?rb #@ARGS config, posts ?>
2
+ <?xml version="1.0"?>
3
+
4
+ <rss version="2.0">
5
+ <channel>
6
+ <title>${@config['blog']['name']}</title>
7
+ <link>${@config['blog']['url']}</link>
8
+ <description>${@config['blog']['description']}</description>
9
+ <language>${@config['blog']['language']}</language>
10
+
11
+ <?rb for post in posts ?>
12
+ <item>
13
+ <title>${post[:title]}</title>
14
+ <link>${post[:url]}</link>
15
+ <description>${post[:description]}</description>
16
+ <pubDate>${post[:date]}</pubDate>
17
+ </item>
18
+ <?rb end ?>
19
+
20
+ </channel>
21
+ </rss>
@@ -0,0 +1,20 @@
1
+ <?rb #@ARGS config ?>
2
+ <hr>
3
+
4
+ <footer>
5
+ <p>Copyright &copy; 2016-2017, ${@config['blog']['name']}</p>
6
+ <p><a href="${@config['blog']['url']}/feed.xml">RSS Feed for this blog</a></p>
7
+ <ul>
8
+ <li>Static Blog Engine by
9
+ <a href="https://github.com/paulohrpinheiro/gerablog">GeraBlog</a>
10
+ </li>
11
+ <li>Code syntax highlight by
12
+ <a href="http://prismjs.com/">Prism</a>
13
+ </li>
14
+ </ul>
15
+ </footer>
16
+
17
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.6.0/prism.min.js"></script>
18
+
19
+ </body>
20
+ </html>
@@ -0,0 +1,33 @@
1
+ <?rb #@ARGS config, post, categories, title ?>
2
+ <!DOCTYPE html>
3
+ <html lang="${@config['blog']['language']}">
4
+
5
+ <head>
6
+ <title>${@title[:title]}</title>
7
+
8
+ <meta charset="utf-8"/>
9
+ <meta name="description" content="${@title[:description]}">
10
+ <meta
11
+ name="viewport"
12
+ content="width=device-width, initial-scale=1, maximum-scale=1"
13
+ >
14
+
15
+ <link
16
+ rel="alternate"
17
+ type="application/rss+xml"
18
+ title="RSS Feed for ${@config['blog']['title']}"
19
+ href="${@config['blog']['url']}/feed.xml"
20
+ >
21
+
22
+ <?rb cssdir = File.join config['blog']['url'], 'assets', 'css' ?>
23
+
24
+ <link rel="stylesheet" href="${cssdir}/gerablog.css">
25
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/prism/1.6.0/themes/prism.css" />
26
+ </head>
27
+
28
+ <body>
29
+ <header>
30
+ <h1><a href="/">${@config['blog']['name']}</a></h1>
31
+ <h2>${@config['blog']['description']}</h2>
32
+ #{@categories}
33
+ </header>
@@ -0,0 +1,10 @@
1
+ <?rb #@ARGS config, categories ?>
2
+ <?rb import config['template']['header'] ?>
3
+
4
+ <article>
5
+ <p>
6
+ This is <a href="https://github.com/paulohpinheiro/gerablog">Gerablog</a>
7
+ </p>
8
+ </article>
9
+
10
+ <?rb import config['template']['footer'] ?>
@@ -0,0 +1,8 @@
1
+ <?rb #@ARGS post, config ?>
2
+ <?rb import config['template']['header'] ?>
3
+
4
+ <article>
5
+ #{@post[:converted]}
6
+ </article>
7
+
8
+ <?rb import config['template']['footer'] ?>
metadata ADDED
@@ -0,0 +1,155 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: gerablog
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Paulo Henrique Rodrigues Pinheiro
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2017-01-15 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: redcarpet
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '3.3'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '3.3'
27
+ - !ruby/object:Gem::Dependency
28
+ name: tenjin
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '0.7'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '0.7'
41
+ - !ruby/object:Gem::Dependency
42
+ name: parseconfig
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '1.0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '1.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: minitest-reporters
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '1.1'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '1.1'
69
+ - !ruby/object:Gem::Dependency
70
+ name: nokogiri
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '1.7'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '1.7'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rubocop
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '0.46'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '0.46'
97
+ - !ruby/object:Gem::Dependency
98
+ name: rake
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
+ description: Write posts in Markdown, publish a static blog in HTML
112
+ email: paulohrpinheiro@gmail.com
113
+ executables:
114
+ - gerablog
115
+ extensions: []
116
+ extra_rdoc_files: []
117
+ files:
118
+ - assets/css/gerablog.css
119
+ - bin/gerablog
120
+ - lib/gerablog.rb
121
+ - lib/gerablog/blog.rb
122
+ - lib/gerablog/redcarpet.rb
123
+ - lib/gerablog/render.rb
124
+ - templates/categories.rbhtml
125
+ - templates/category.rbhtml
126
+ - templates/feed.rbxml
127
+ - templates/footer.rbhtml
128
+ - templates/header.rbhtml
129
+ - templates/index.rbhtml
130
+ - templates/post.rbhtml
131
+ homepage: https://github.com/paulohrpinheiro/gerablog
132
+ licenses:
133
+ - MIT
134
+ metadata: {}
135
+ post_install_message:
136
+ rdoc_options: []
137
+ require_paths:
138
+ - lib
139
+ required_ruby_version: !ruby/object:Gem::Requirement
140
+ requirements:
141
+ - - ">="
142
+ - !ruby/object:Gem::Version
143
+ version: '2.0'
144
+ required_rubygems_version: !ruby/object:Gem::Requirement
145
+ requirements:
146
+ - - ">="
147
+ - !ruby/object:Gem::Version
148
+ version: '0'
149
+ requirements: []
150
+ rubyforge_project:
151
+ rubygems_version: 2.5.1
152
+ signing_key:
153
+ specification_version: 4
154
+ summary: My own static site generator.
155
+ test_files: []