flora 0.1.2 → 0.4.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b340a03e054b40453f05f5b751bd3abc4cf186111bb825dbe5990fa26f970d42
4
- data.tar.gz: b35a8ede2c532cd62b779c47501533a559722a92881e4e9fe6f4461b317798db
3
+ metadata.gz: 1b44217297cbd020d161b21d49829be840dd7ec4b99327108aa1b0c14e4f3286
4
+ data.tar.gz: 32871444dfee770b17d99e57aa4753e1f8a40e02d3743e7e52e3a1ef77098a8d
5
5
  SHA512:
6
- metadata.gz: ba753c9a4eae80973985438f154c30cfbd3706ffd29acccb7918b3fe212c1d248f6a63c3148635f89d874e62f3b50f61fedec9dff2f67ef0948ccf0944ad4895
7
- data.tar.gz: 14c102dae1d31a85bd12bc3d9f50d5775230ed94f4342312d94d97df13ee0759770a5b576118fb5776fc9275cc348a20cb802686e307719a195a54155de07801
6
+ metadata.gz: 6567dab062a120dca84dabec2246266c5f482fcc2ba8899c541f2d4fd5a0801f7e6c7a9ef8f4af47896495dcf1768ce6eb763eea9df8b33db935a70fdc561617
7
+ data.tar.gz: f24f358cb9c3da51053b2c1301f2d5c0f85aaebadf1956558f623839e8c24acc241157b77962f7772e83a6e7d3542a768e488d0efbd6785878ba5431386dd747
data/README.md CHANGED
@@ -1,3 +1,27 @@
1
1
  # Flora
2
2
 
3
3
  A static site generator.
4
+
5
+ ## Quickstart
6
+
7
+ Make a new directory with a Gemfile that looks like this:
8
+
9
+ ```ruby
10
+ source "https://rubygems.org"
11
+
12
+ gem 'flora'
13
+ ```
14
+
15
+ Make a new `index.rb` file that looks like this:
16
+
17
+ ```ruby
18
+ html do
19
+ body do
20
+ h1 do
21
+ 'Hello world!'
22
+ end
23
+ end
24
+ end
25
+ ```
26
+
27
+ Install everything with `bundle install`, and then run `bundle exec flora serve` and open up http://localhost:3000!
data/lib/flora/app.rb CHANGED
@@ -7,7 +7,7 @@ class Flora::App
7
7
 
8
8
  def initialize(app, dir)
9
9
  @app = app
10
- @dir = dir
10
+ @dir = Pathname.new(dir)
11
11
  end
12
12
 
13
13
  def call(env)
@@ -24,13 +24,13 @@ class Flora::App
24
24
 
25
25
 
26
26
  def self.app(path)
27
- flora = Flora::Engine.new(path, '/tmp/flora/')
27
+ flora = Flora.new(path)
28
28
  # TODO: rebuild every req?
29
- flora.build
29
+ flora.build('/tmp/flora/')
30
30
 
31
31
  Rack::Builder.new do
32
- use StaticWithoutHtml, flora.out_dir
33
- use Rack::Static, urls: [''], root: flora.out_dir.to_s, index: 'index.html'
32
+ use StaticWithoutHtml, '/tmp/flora'
33
+ use Rack::Static, urls: [''], root: '/tmp/flora', index: 'index.html'
34
34
  map "/" do
35
35
  run ->(env) do
36
36
  [404, {'Content-Type' => 'text/plain'}, ['Page Not Found!']]
data/lib/flora/cli.rb CHANGED
@@ -4,7 +4,7 @@ class Flora::Cli < Thor
4
4
 
5
5
  desc 'build OUT_DIR', 'Build a site'
6
6
  def build(out_dir)
7
- Flora::Engine.new('.', out_dir).build
7
+ Flora.new('.').build(out_dir)
8
8
  end
9
9
 
10
10
 
@@ -1,15 +1,12 @@
1
1
  class Flora::Engine::Config
2
2
 
3
- attr_reader(:plugins)
4
-
5
-
6
- def initialize
7
- @plugins = []
3
+ def initialize(plugin_loader)
4
+ @plugin_loader = plugin_loader
8
5
  end
9
6
 
10
7
 
11
8
  def plugin(mod)
12
- @plugins << mod
9
+ @plugin_loader.load_plugin(mod)
13
10
  end
14
11
 
15
12
  end
@@ -9,7 +9,7 @@ module Flora::Engine::Page::Html
9
9
  fieldset figcaption figure footer form
10
10
  h1 h2 h3 h4 h5 h6 head header hr html i iframe img input ins
11
11
  kbd keygen
12
- label legend li
12
+ label legend li link
13
13
  main map mark menu meter
14
14
  nav
15
15
  object ol optgroup option output
@@ -10,6 +10,7 @@ class Flora::Engine::Page
10
10
  path.find do |file|
11
11
  next if IGNORES.any? { file.fnmatch((path / it).to_s) }
12
12
  next if file.directory?
13
+ next unless supported_file_type?(file)
13
14
 
14
15
  yield(self.for(path, file))
15
16
  end
@@ -25,6 +26,13 @@ class Flora::Engine::Page
25
26
  end
26
27
  end
27
28
 
29
+
30
+ private
31
+
32
+ def supported_file_type?(file)
33
+ file.extname == '.rb' || file.extname == '.md'
34
+ end
35
+
28
36
  end
29
37
 
30
38
 
data/lib/flora/engine.rb CHANGED
@@ -1,61 +1,69 @@
1
1
  class Flora::Engine
2
2
 
3
- attr_reader(:out_dir)
3
+ def initialize(path)
4
+ @path = Pathname.new(path)
5
+ @config = Config.new(self)
4
6
 
7
+ @site_loader = Zeitwerk::Loader.new
5
8
 
6
- def initialize(path, out_dir)
7
- @path = Pathname.new(path)
8
- @out_dir = Pathname.new(out_dir)
9
- @out_dir.mkdir unless @out_dir.exist?
10
- @config = Config.new
9
+ if site_has_supporting_code?
10
+ setup_site_loader
11
+ end
11
12
 
12
13
  Kernel.prepend(Flora::Engine::Page::Html)
13
14
  end
14
15
 
15
16
 
16
- def build
17
- with_load_path(@path) do
18
- config_file = @path.join('_config.rb')
19
- @config.instance_eval(config_file.read) if config_file.exist?
17
+ def configure
18
+ config_file = @path.join('_config.rb')
19
+ @config.instance_eval(config_file.read) if config_file.exist?
20
+ end
20
21
 
21
- init_plugins
22
22
 
23
- Page.each(@path) do |page|
24
- layouts = []
25
- page.dir.ascend do |dir|
26
- maybe_layout = dir.join('_layout.rb')
27
- layouts << maybe_layout if maybe_layout.exist?
28
- break if dir == @path
29
- end
23
+ def build(out_dir)
24
+ @out_dir = Pathname.new(out_dir)
25
+ @out_dir.mkdir unless @out_dir.exist?
30
26
 
31
- $flora_added = []
32
- tree = Page::Layout.new(layouts).render do
33
- page.render
34
- end
35
- html = Page::Html.to_html(tree)
27
+ Page.each(@path) do |page|
28
+ layouts = []
29
+ page.dir.ascend do |dir|
30
+ maybe_layout = dir.join('_layout.rb')
31
+ layouts << maybe_layout if maybe_layout.exist?
32
+ break if dir == @path
33
+ end
36
34
 
37
- out_filename = @out_dir.join(page.outname)
38
- out_filename.dirname.mkdir unless out_filename.dirname.exist?
39
- out_filename.write(html)
35
+ $flora_added = []
36
+ tree = Page::Layout.new(layouts).render do
37
+ page.render
40
38
  end
39
+ html = Page::Html.to_html(tree)
40
+
41
+ out_filename = @out_dir.join(page.outname)
42
+ out_filename.dirname.mkdir unless out_filename.dirname.exist?
43
+ out_filename.write(html)
41
44
  end
45
+
46
+ end
47
+
48
+
49
+ def load_plugin(mod)
50
+ self.class.include(mod::EngineMethods) if defined?(mod::EngineMethods)
51
+ Page::RubyPage.include(mod::PageMethods) if defined?(mod::PageMethods)
52
+ Config.include(mod::Config) if defined?(mod::Config)
42
53
  end
43
54
 
44
55
 
45
56
  private
46
57
 
47
- def with_load_path(path)
48
- $LOAD_PATH << path.to_s
49
- yield
50
- $LOAD_PATH.delete(path.to_s)
58
+ def site_has_supporting_code?
59
+ @path.join('lib').exist?
51
60
  end
52
61
 
53
62
 
54
- def init_plugins
55
- @config.plugins.each do |plugin|
56
- Page.include(plugin::Page) if self.class.const_defined?("#{plugin}::Page")
57
- Page::RubyPage.include(plugin::RubyPage) if self.class.const_defined?("#{plugin}::RubyPage")
58
- end
63
+ def setup_site_loader
64
+ @site_loader.push_dir(@path.join('lib').to_s)
65
+ @site_loader.enable_reloading
66
+ @site_loader.setup
59
67
  end
60
68
 
61
69
  end
@@ -1,18 +1,19 @@
1
- class FloraBlog::Post
1
+ class Flora::Plugins::Blog::Post
2
2
 
3
- def initialize(page)
3
+ def initialize(page, root)
4
4
  @page = page
5
+ @root = root
5
6
  @frontmatter = parse_frontmatter
6
7
  end
7
8
 
8
9
 
9
10
  def url
10
- 'https://google.com'
11
+ '/' + @page.relative_path_from(@root).sub(@page.extname, '').to_s
11
12
  end
12
13
 
13
14
 
14
15
  def title
15
- 'google'
16
+ @frontmatter['title']
16
17
  end
17
18
 
18
19
 
@@ -0,0 +1,11 @@
1
+ module Flora::Plugins::Blog
2
+
3
+ module PageMethods
4
+
5
+ def posts
6
+ @root.glob('posts/**').map { Post.new(it, @root) }
7
+ end
8
+
9
+ end
10
+
11
+ end
@@ -0,0 +1,39 @@
1
+ module Flora::Plugins::Redirector
2
+
3
+ module EngineMethods
4
+
5
+ def build(*)
6
+ super
7
+
8
+ @config.redirects.each do |src, dest|
9
+ out_filename = @out_dir.join(src + '.html')
10
+ out_filename.dirname.mkdir unless out_filename.dirname.exist?
11
+ out_filename.write(build_redir_file(dest))
12
+ end
13
+ end
14
+
15
+
16
+ def build_redir_file(url)
17
+ <<~HTML
18
+ <html>
19
+ <head>
20
+ <meta http-equiv="refresh" content="0; url=#{url}" />
21
+ </head>
22
+ </html>
23
+ HTML
24
+ end
25
+
26
+ end
27
+
28
+
29
+ module Config
30
+
31
+ def self.included(base)
32
+ base.class_eval do
33
+ attr_accessor(:redirects)
34
+ end
35
+ end
36
+
37
+ end
38
+
39
+ end
@@ -0,0 +1,46 @@
1
+ module Flora::Plugins::StaticFiles
2
+
3
+ class Copier
4
+
5
+ def initialize(dir)
6
+ @dir = dir
7
+ end
8
+
9
+
10
+ def copy_to(out)
11
+ @dir.find do |public_file|
12
+ next if public_file.directory?
13
+
14
+ out_filename = out.join(Pathname.new(public_file).relative_path_from(@dir))
15
+ out_filename.dirname.mkdir unless out_filename.dirname.exist?
16
+ out_filename.write(File.read(public_file))
17
+ end
18
+ end
19
+
20
+ end
21
+
22
+
23
+ module EngineMethods
24
+
25
+ def build(*)
26
+ super
27
+
28
+ base = @config.static_files_dir || 'public'
29
+ copier = Copier.new(@path.join(base))
30
+ copier.copy_to(@out_dir.join(base))
31
+ end
32
+
33
+ end
34
+
35
+
36
+ module Config
37
+
38
+ def self.included(base)
39
+ base.class_eval do
40
+ attr_accessor(:static_files_dir)
41
+ end
42
+ end
43
+
44
+ end
45
+
46
+ end
data/lib/flora/version.rb CHANGED
@@ -1,3 +1,3 @@
1
- module Flora
2
- VERSION = "0.1.2"
1
+ class Flora
2
+ VERSION = "0.4.0"
3
3
  end
data/lib/flora.rb CHANGED
@@ -5,5 +5,17 @@ require 'kramdown'
5
5
  loader = Zeitwerk::Loader.for_gem(warn_on_extra_files: false)
6
6
  loader.setup
7
7
 
8
- module Flora
8
+ class Flora
9
+
10
+ def initialize(dir)
11
+ # A new class so plugins only affect one instance.
12
+ @engine = Class.new(Engine).new(dir)
13
+ @engine.configure
14
+ end
15
+
16
+
17
+ def build(out)
18
+ @engine.build(out)
19
+ end
20
+
9
21
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: flora
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nick Vladimiroff
@@ -113,11 +113,12 @@ files:
113
113
  - lib/flora/engine/page/html.rb
114
114
  - lib/flora/engine/page/layout.rb
115
115
  - lib/flora/engine/page/markdown_page.rb
116
- - lib/flora/engine/page/plugin_hooks.rb
117
116
  - lib/flora/engine/page/ruby_page.rb
117
+ - lib/flora/plugins/blog.rb
118
+ - lib/flora/plugins/blog/post.rb
119
+ - lib/flora/plugins/redirector.rb
120
+ - lib/flora/plugins/static_files.rb
118
121
  - lib/flora/version.rb
119
- - lib/flora_blog.rb
120
- - lib/flora_blog/post.rb
121
122
  - tmp/.keep
122
123
  homepage: https://code.kat5.dev/nick/flora
123
124
  licenses:
@@ -1,10 +0,0 @@
1
- module Flora::Engine::Page::PluginHooks
2
-
3
- def before_render
4
- end
5
-
6
-
7
- def after_render(html)
8
- end
9
-
10
- end
data/lib/flora_blog.rb DELETED
@@ -1,13 +0,0 @@
1
- module FloraBlog
2
-
3
- module RubyPage
4
-
5
- def render
6
- @posts = @root.glob('posts/**').map { Post.new(it) }
7
-
8
- super
9
- end
10
-
11
- end
12
-
13
- end