foresite 1.1.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 495db3b9b94366d4ec2ee21650912ce9f545ccab88a5206aebf49e6cb08cfee8
4
+ data.tar.gz: 1712e43ee2800c9158fb54879423693b5f764e0f7ad53565ebff9151c76e322d
5
+ SHA512:
6
+ metadata.gz: 3079e9d70d3d1020d209251caeb1bc85b6a286d9db03bb9a29a8abfaecdbb0522f815b8680ceab129a4247388dfe2d5d8326c275f975c3b1608b83fea18b1f6d
7
+ data.tar.gz: e5263d34aea71db355288285d168e607fbfe30415bbc19b5eb2679bddbf48ebc255118e58b8c7bfa13ea2f1fbf24bca4e3c5136a4c62e4bbdd7d9e8e71c085fa
data/Gemfile ADDED
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2023 Carl Wiedemann
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,128 @@
1
+ # Foresite
2
+
3
+ An extremely minimal static site generator.
4
+
5
+ CLI executable that converts markdown wrapped in a single template to static HTML for simple blogs hosted on [GitHub Pages](https://pages.github.com/) or similar.
6
+
7
+ ## Installation
8
+
9
+ The only requirement is Ruby >= 2.7.0.
10
+
11
+ $ gem install foresite
12
+
13
+ ## Quick start: Hello World
14
+
15
+ $ mkdir my_blog # Create a project directory
16
+
17
+ $ cd my_blog
18
+
19
+ $ foresite init # Initialize
20
+
21
+ $ foresite touch "Hello World" # Create markdown post titled "Hello World"
22
+
23
+ $ foresite build # Converts markdown to HTML
24
+
25
+ ![Screenshot of Hello World post](screenshot.png)
26
+
27
+ ## Getting started guide
28
+
29
+ ### 1. Create your project directory
30
+
31
+ Create a project directory for your site and run `foresite init` from within it:
32
+
33
+ $ mkdir my_blog
34
+
35
+ $ cd my_blog
36
+
37
+ $ foresite init
38
+ Created md/
39
+ Created post/
40
+ Created erb/
41
+ Created erb/post.md.erb
42
+ Created erb/wrapper.html.erb
43
+ Created erb/_list.html.erb
44
+
45
+ Three subdirectories are created, along with three [ERB](https://docs.ruby-lang.org/en/3.2/ERB.html) template files.
46
+
47
+ Some facts:
48
+
49
+ * `md` subdirectory will contain markdown files known as posts, which are your site's content.
50
+ * `post` subdirectory will contain HTML files generated from the markdown posts with the exception of an `index.html` file listing all posts, which will exist in the top-level project directory.
51
+ * `erb` subdirectory contains [ERB](https://docs.ruby-lang.org/en/3.2/ERB.html) templates you can modify:
52
+ * `post.md.erb` is the default markdown file for every post.
53
+ * `wrapper.html.erb` is a HTML wrapper template for every generated HTML file.
54
+ * `_list.html.erb` is a HTML template partial for the list of posts on the `index.html` page.
55
+
56
+ ### 2. Write your first post
57
+
58
+ Run `foresite touch` to generate a new post in the `md` subdirectory. The title is its sole argument.
59
+
60
+ $ foresite touch "Welcome to my site"
61
+ Created md/2023-01-15-welcome-to-my-site.md
62
+
63
+ $ cat md/2023-01-15-welcome-to-my-site.md
64
+ # Welcome to my site
65
+
66
+ 2023-01-15
67
+
68
+ A single markdown file is created in the `md` subdirectory. **This file is meant for you to edit.**
69
+
70
+ Some facts:
71
+
72
+ * The title is the first line formatted as H1 (mandatory).
73
+ * Current date in YYYY-MM-DD format is the first markdown paragraph (optional).
74
+ * Current date and title are "slugified" for filename.
75
+
76
+ ### 3. Modify templates as desired
77
+
78
+ `post.md.erb` is used to when running `foresite touch` for the default markdown content. It has two variables, `@title` for the post title and `@date_ymd` for the created date in ISO 8601 `YYYY-MM-DD` format. Modify to have different defaults when running `foresite touch`.
79
+
80
+ `wrapper.html.erb` wraps all of your markdown. Its sole variable `@content` will be a given post's HTML (converted from markdown). For the `index.html` file, `@content` will be an list of links to all posts in reverse-chronological order. Modify to have different overall page structure, or to add `<style>` etc.
81
+
82
+ `_list.html.erb` is used to generate the `<ul>` list of posts on the `index.html` file. Modify to show posts in a different way.
83
+
84
+ ### 4. Generate HTML from markdown
85
+
86
+ Run `foresite build` to create HTML in the `post` subdirectory and the `index.html` file:
87
+
88
+ $ foresite build
89
+ Created post/2023-01-15-welcome-to-my-site.html
90
+ Created index.html
91
+
92
+ In this example, two HTML files are created.
93
+
94
+ Some facts:
95
+
96
+ * For every post markdown file in the `md` subdirectory an equivalent HTML file is generated in the `post` subdirectory, each wrapped with wrapper template markup.
97
+ * A single `index.html` file shows a list of links to all posts in reverse-chronological order, prefixed with post date.
98
+ * Post titles are parsed from the first H1 tag in each post markdown file.
99
+ * Post dates are parsed from the post markdown filename.
100
+ * Re-running `foresite build` removes and recreates all HTML files in the `post` subdirectory as well as the `index.html` file.
101
+
102
+ In this example, the `index.html` will contain:
103
+
104
+ ```html
105
+ <ul>
106
+ <li>2023-01-15 <a href="2023-01-15-welcome-to-my-site.html">Welcome to my site</a></li>
107
+ </ul>
108
+ ```
109
+
110
+ ## Development
111
+
112
+ 1. Clone
113
+ 2. `bundle` to install dependencies
114
+ 3. `bundle exec rake` to run tests & linter
115
+
116
+ To install this gem from local source, run `bundle exec rake install:local`.
117
+
118
+ ## Contributing
119
+
120
+ Bug reports and pull requests are welcome. The goals of Foresite are:
121
+
122
+ * Extremely lightweight
123
+ * Simple to use & understand
124
+ * Minimal features
125
+
126
+ ## License
127
+
128
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
data/bin/foresite ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env ruby
2
+ require_relative '../lib/foresite'
3
+ Foresite::Cli.start
@@ -0,0 +1,120 @@
1
+ module Foresite
2
+ ##
3
+ # Cli class.
4
+ #
5
+ # For CLI functionality to generate static content.
6
+ #
7
+ class Cli < ::Thor
8
+ ##
9
+ # Ensure that failures exit with a status of zero.
10
+ #
11
+ def self.exit_on_failure?
12
+ true
13
+ end
14
+
15
+ desc "init", "Initializes foresite in current directory"
16
+ long_desc <<-LONGDESC
17
+ Initializes foresite in the current directory.
18
+
19
+ Creates `#{Foresite::DIRNAME_MARKDOWN}/` for storing editable markdown posts, `#{Foresite::DIRNAME_POST}/` for storing generated HTML, and `#{Foresite::DIRNAME_ERB}` for storing editable template.
20
+
21
+ Does not overwrite existing subdirectories.
22
+ LONGDESC
23
+
24
+ def init
25
+ unless Foresite.root_exists?
26
+ warn("Nonexistent directory #{Foresite.get_path_to_root}")
27
+ exit(1)
28
+ end
29
+
30
+ unless Foresite.root_writable?
31
+ warn("Cannot write to directory #{Foresite.get_path_to_root}")
32
+ exit(1)
33
+ end
34
+
35
+ Foresite.touch_directories.map { $stdout.puts(_1) }
36
+ Foresite.copy_templates.map { $stdout.puts(_1) }
37
+ end
38
+
39
+ desc "touch [TITLE]", "Creates new `.md` file with TITLE in `#{Foresite::DIRNAME_MARKDOWN}` directory"
40
+ long_desc <<-LONGDESC
41
+ Creates a markdown file for usage as a post, with optional title.
42
+
43
+ The name of the file will be the current date suffixed by the `TITLE` argument. The current date will be formatted as `YYYY-MM-DD` and the title will be transformed to use lowercase alphanumeric characters, separated by hyphens.
44
+
45
+ Example: (If today is 14 January 2023, and the command is run from /Users/carlos/my_project)
46
+
47
+ $ foresite touch "Happy new year!"
48
+ \x5> Created #{Foresite::DIRNAME_MARKDOWN}/2023-01-14-happy-new-year.md
49
+ LONGDESC
50
+
51
+ def touch(title)
52
+ unless Foresite.subdirectories_exist?
53
+ warn("Missing subdirectories, try running `foresite init`")
54
+ exit(1)
55
+ end
56
+
57
+ date_ymd = Time.now.strftime("%F")
58
+ slug = title.downcase.gsub(/[^a-z]/i, " ").strip.gsub(/ +/, "-")
59
+
60
+ path = Foresite.get_path_to_md_file("#{date_ymd}-#{slug}.md")
61
+
62
+ if File.exist?(path)
63
+ $stdout.puts("File #{Foresite.relative_path(path)} already exists")
64
+ else
65
+ File.write(path, Foresite.render_post(title, date_ymd))
66
+ $stdout.puts("Created #{Foresite.relative_path(path)}")
67
+ end
68
+ end
69
+
70
+ desc "build", "Generates HTML from markdown into `#{Foresite::DIRNAME_POST}` directory"
71
+ long_desc <<-LONGDESC
72
+ Creates HTML files from all markdown posts and writes them to the `#{Foresite::DIRNAME_POST}` directory.
73
+
74
+ The names of the HTML files match corresponding markdown files with extension `.html` instead of `.md`.
75
+ LONGDESC
76
+
77
+ def build
78
+ unless Foresite.subdirectories_exist?
79
+ warn("Missing subdirectories, try running `foresite init`")
80
+ exit(1)
81
+ end
82
+
83
+ # Wipe all output files.
84
+ Dir.glob(File.join(Foresite.get_path_to_out, "*.html")).each { File.delete(_1) }
85
+ File.delete(Foresite.get_path_to_index_file) if File.exist?(Foresite.get_path_to_index_file)
86
+
87
+ markdown_paths = Dir.glob(File.join(Foresite.get_path_to_md, "*.md"))
88
+
89
+ if markdown_paths.count == 0
90
+ warn("No markdown files, try running `foresite touch`")
91
+ exit(1)
92
+ end
93
+
94
+ links = markdown_paths.map do |markdown_path|
95
+ markdown_content = File.read(markdown_path)
96
+
97
+ filename_markdown = File.basename(markdown_path)
98
+ html_path = Foresite.get_path_to_out_file(filename_markdown.gsub(/\.md$/, ".html"))
99
+
100
+ File.write(html_path, Foresite.render_wrapped(markdown_content))
101
+ $stdout.puts("Created #{Foresite.relative_path(html_path)}")
102
+
103
+ # Extract date if it exists.
104
+ match_data = /\d{4}-\d{2}-\d{2}/.match(filename_markdown)
105
+
106
+ {
107
+ date_ymd: match_data.nil? ? "" : match_data[0],
108
+ href: Foresite.relative_path(html_path),
109
+ title: markdown_content.split("\n").first { |line| /^# [a-z]/i =~ line }.gsub(/^#/, "").strip
110
+ }
111
+ end
112
+
113
+ # Generate index file.
114
+ index_html_path = Foresite.get_path_to_index_file
115
+ File.write(index_html_path, Foresite.render_wrapped_index(links))
116
+
117
+ $stdout.puts("Created #{Foresite.relative_path(index_html_path)}")
118
+ end
119
+ end
120
+ end
@@ -0,0 +1,43 @@
1
+ module Foresite
2
+ ##
3
+ # Renderer class.
4
+ #
5
+ # Basic implementation of ERB for a path to a given template and variables.
6
+ #
7
+ class Renderer
8
+ ##
9
+ # Constructor.
10
+ #
11
+ # @param [String] path Path to file.
12
+ # @param [Hash] vars Variables for template.
13
+ def initialize(path, vars)
14
+ @path = path
15
+ vars.each do |k, v|
16
+ if k.is_a?(Symbol)
17
+ instance_variable_set("@#{k}".to_sym, v)
18
+ end
19
+ end
20
+ end
21
+
22
+ ##
23
+ # Renders template with variables.
24
+ #
25
+ # @return [String] Rendered template output.
26
+ #
27
+ def render
28
+ ::ERB.new(File.read(@path), trim_mode: "-").result(binding)
29
+ end
30
+
31
+ ##
32
+ # Statically renders template with variables.
33
+ #
34
+ # @param [String] path Path to file.
35
+ # @param [Hash] vars Variables for template.
36
+ #
37
+ # @return [String] Rendered template output.
38
+ #
39
+ def self.render(path, vars)
40
+ new(path, vars).render
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Foresite
4
+ VERSION = "1.1.3"
5
+ end
data/lib/foresite.rb ADDED
@@ -0,0 +1,121 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "erb"
4
+ require "thor"
5
+ require "kramdown"
6
+ require "zeitwerk"
7
+
8
+ loader = Zeitwerk::Loader.for_gem
9
+ loader.setup
10
+
11
+ module Foresite
12
+ DIRNAME_MARKDOWN = "md"
13
+ DIRNAME_POST = "post"
14
+ DIRNAME_ERB = "erb"
15
+
16
+ FILENAME_POST_MD = "post.md.erb"
17
+ FILENAME_WRAPPER_HTML = "wrapper.html.erb"
18
+ FILENAME_LIST_HTML = "_list.html.erb"
19
+
20
+ ENV_ROOT = "FORESITE_ROOT"
21
+
22
+ PATH_TO_DEFAULTS = File.join(__dir__, "skeleton")
23
+
24
+ def self.get_path_to_root
25
+ ENV[ENV_ROOT] || Dir.pwd
26
+ end
27
+
28
+ def self.root_exists?
29
+ Dir.exist?(get_path_to_root)
30
+ end
31
+
32
+ def self.root_writable?
33
+ File.writable?(get_path_to_root)
34
+ end
35
+
36
+ def self.subdirectories_exist?
37
+ [get_path_to_md, get_path_to_out, get_path_to_erb].all? do |path|
38
+ Dir.exist?(path)
39
+ end
40
+ end
41
+
42
+ def self.get_path_to_md
43
+ File.join(get_path_to_root, DIRNAME_MARKDOWN)
44
+ end
45
+
46
+ def self.get_path_to_out
47
+ File.join(get_path_to_root, DIRNAME_POST)
48
+ end
49
+
50
+ def self.get_path_to_erb
51
+ File.join(get_path_to_root, DIRNAME_ERB)
52
+ end
53
+
54
+ def self.get_path_to_erb_file(file)
55
+ File.join(get_path_to_erb, file)
56
+ end
57
+
58
+ def self.get_path_to_md_file(file)
59
+ File.join(get_path_to_md, file)
60
+ end
61
+
62
+ def self.get_path_to_out_file(file)
63
+ File.join(get_path_to_out, file)
64
+ end
65
+
66
+ def self.get_path_to_index_file
67
+ File.join(get_path_to_root, "index.html")
68
+ end
69
+
70
+ def self.relative_path(full_path)
71
+ full_path.gsub(get_path_to_root, "").gsub(Regexp.new("^#{File::SEPARATOR}"), "")
72
+ end
73
+
74
+ def self.render_erb_file(file, vars)
75
+ Renderer.render(get_path_to_erb_file(file), vars)
76
+ end
77
+
78
+ def self.render_post(title, date_ymd)
79
+ render_erb_file(FILENAME_POST_MD, {
80
+ title: title,
81
+ date_ymd: date_ymd
82
+ })
83
+ end
84
+
85
+ def self.render_wrapped(markdown_content)
86
+ render_erb_file(FILENAME_WRAPPER_HTML, {
87
+ content: ::Kramdown::Document.new(markdown_content).to_html
88
+ })
89
+ end
90
+
91
+ def self.render_wrapped_index(links)
92
+ render_erb_file(FILENAME_WRAPPER_HTML, {
93
+ content: render_erb_file(FILENAME_LIST_HTML, {
94
+ links: links.reverse
95
+ })
96
+ })
97
+ end
98
+
99
+ def self.touch_directories
100
+ [get_path_to_md, get_path_to_out, get_path_to_erb].map do |path|
101
+ if Dir.exist?(path)
102
+ "#{relative_path(path)}/ already exists"
103
+ else
104
+ Dir.mkdir(path)
105
+ "Created #{relative_path(path)}/"
106
+ end
107
+ end
108
+ end
109
+
110
+ def self.copy_templates
111
+ [FILENAME_POST_MD, FILENAME_WRAPPER_HTML, FILENAME_LIST_HTML].map do |filename|
112
+ full_file_path = File.join(get_path_to_erb, filename)
113
+ if File.exist?(full_file_path)
114
+ "#{relative_path(full_file_path)} already exists"
115
+ else
116
+ File.copy_stream(File.join(PATH_TO_DEFAULTS, filename), full_file_path)
117
+ "Created #{relative_path(full_file_path)}"
118
+ end
119
+ end
120
+ end
121
+ end
@@ -0,0 +1,7 @@
1
+ <% if @links.count > 0 -%>
2
+ <ul>
3
+ <% @links.each do |link| -%>
4
+ <li><%= link[:date_ymd] %> <a href="<%= link[:href] %>"><%= link[:title] %></a></li>
5
+ <% end -%>
6
+ </ul>
7
+ <% end -%>
@@ -0,0 +1,4 @@
1
+ # <%= @title %>
2
+
3
+ <%= @date_ymd %>
4
+
@@ -0,0 +1,23 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <title>Another Foresite Blog</title>
6
+ <style></style>
7
+ </head>
8
+ <body>
9
+ <header>
10
+ <h1><a href="/">Another Foresite Blog</a></h1>
11
+ <nav>
12
+ <ul>
13
+ <li><a href="https://rubygems.org/gems/foresite">Foresite on RubyGems</a></li>
14
+ <li><a href="https://github.com/carlwiedemann/foresite">Foresite on GitHub</a></li>
15
+ </ul>
16
+ </nav>
17
+ </header>
18
+ <main>
19
+ <%= @content %>
20
+ </main>
21
+ <footer></footer>
22
+ </body>
23
+ </html>
metadata ADDED
@@ -0,0 +1,142 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: foresite
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.1.3
5
+ platform: ruby
6
+ authors:
7
+ - Carl Wiedemann
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2023-01-17 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: kramdown
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '2.4'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '2.4'
27
+ - !ruby/object:Gem::Dependency
28
+ name: thor
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.2'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.2'
41
+ - !ruby/object:Gem::Dependency
42
+ name: zeitwerk
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '2.6'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '2.6'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rspec
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '3.2'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '3.2'
69
+ - !ruby/object:Gem::Dependency
70
+ name: standard
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '1.3'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '1.3'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rake
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '13'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '13'
97
+ description:
98
+ email:
99
+ - carl.wiedemann@gmail.com
100
+ executables:
101
+ - foresite
102
+ extensions: []
103
+ extra_rdoc_files: []
104
+ files:
105
+ - Gemfile
106
+ - LICENSE.txt
107
+ - README.md
108
+ - bin/foresite
109
+ - lib/foresite.rb
110
+ - lib/foresite/cli.rb
111
+ - lib/foresite/renderer.rb
112
+ - lib/foresite/version.rb
113
+ - lib/skeleton/_list.html.erb
114
+ - lib/skeleton/post.md.erb
115
+ - lib/skeleton/wrapper.html.erb
116
+ homepage: https://github.com/carlwiedemann/foresite
117
+ licenses:
118
+ - MIT
119
+ metadata:
120
+ homepage_uri: https://github.com/carlwiedemann/foresite
121
+ source_code_uri: https://github.com/carlwiedemann/foresite
122
+ changelog_uri: https://github.com/carlwiedemann/foresite/blob/main/CHANGELOG.md
123
+ post_install_message:
124
+ rdoc_options: []
125
+ require_paths:
126
+ - lib
127
+ required_ruby_version: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ">="
130
+ - !ruby/object:Gem::Version
131
+ version: 2.7.0
132
+ required_rubygems_version: !ruby/object:Gem::Requirement
133
+ requirements:
134
+ - - ">="
135
+ - !ruby/object:Gem::Version
136
+ version: '0'
137
+ requirements: []
138
+ rubygems_version: 3.4.3
139
+ signing_key:
140
+ specification_version: 4
141
+ summary: An extremely minimal static site generator.
142
+ test_files: []