isola 0.1.1 → 0.1.3

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: d1d603cb56640c3cef57383a675c18280a05f7e31cb0b7e12e93a590ab5a3756
4
- data.tar.gz: a143ef3efdb79ea497a74c0843189d8b40e21f1ab4bed895f8533648e50fb714
3
+ metadata.gz: 2bb22047ab87f7c563e5970881ccb38fc9efd2a2f6330dacdb6d59f7d8b45692
4
+ data.tar.gz: 361457eac4fe0368b586258f36b02a9a7748e64be5f31f6cc83acb4ed7bf6ee1
5
5
  SHA512:
6
- metadata.gz: 21a9977148002a45b0bed065e2f22c12da1378b6f0354ee0758bcded391ee9c9b574511d4ce37fa8e0615077f02e5ce281d0950f11a42ae83612fcefab165216
7
- data.tar.gz: f93813208135b400d2de4bb6e8d49c4de710fe722f704e1d7f13a5275e008323bfe64222f52e2fb2885648527cb920b459874cbe8978ff06540f32be674caa76
6
+ metadata.gz: e4bc2dada021f9fddda63594d32fccbe2d9d25040340344632c1efedf9319fd13113049b95e04f29d1c1f81dee39489bbd2ea4221119af2e7f28414cb4d724a0
7
+ data.tar.gz: b19a681a05704dd1223e6914cdede398229e6f4b6e727169557a19ecea77f49aff0e7ea59f12718a7954e8013ec02410eb5ad8dbea0b59d5bad30d8879aef6ce
data/USAGE.ja.md CHANGED
@@ -59,7 +59,7 @@ title: トップページ
59
59
  ```erb
60
60
  <html>
61
61
  <head>
62
- <title><%= page.title %></title>
62
+ <title><%= page[:title] %></title>
63
63
  </head>
64
64
  <body>
65
65
  <%= content %>
@@ -70,8 +70,8 @@ title: トップページ
70
70
  テンプレート内では以下が使えます:
71
71
 
72
72
  - `content` — ページ本文
73
- - `page.title` など — front-matterの値
74
- - `site.title`, `site.url`, `site.lang` — サイト設定
73
+ - `page[:title]`, `page[:lang]` など — front-matterの値(`lang`はサイト設定から自動的に含まれますが、設定すれば上書きされます)
74
+ - `site[:title]`, `site[:url]` など — サイト設定
75
75
  - `include 'head', key: value` — インクルードの挿入
76
76
 
77
77
  ### 5. ビルド
@@ -83,6 +83,22 @@ isola build
83
83
 
84
84
  `_site/`に生成されます。
85
85
 
86
+ ### 6. 開発サーバー
87
+
88
+ ```bash
89
+ cd my-site
90
+ isola serve
91
+ ```
92
+
93
+ サイトをビルドし、ローカル開発サーバーを起動します。デフォルトでは `http://127.0.0.1:4444` で待ち受けます。ホストとポートは `_config.yaml` で変更できます:
94
+
95
+ ```yaml
96
+ host: 127.0.0.1
97
+ port: 4444
98
+ ```
99
+
100
+ サーバーはファイルの変更を監視し、自動的にサイトを再ビルドします。`</body>` タグを含むHTMLページにはライブリロード用のスクリプトが挿入され、再ビルド後にブラウザが自動的にリロードされます。ライブリロードが機能するのは `</body>` タグを含むHTMLファイルのみです。
101
+
86
102
  ## ファイルの処理
87
103
 
88
104
  Isolaが処理するテンプレートエンジンは現在 **ERB**(`.erb`)と **Markdown**(`.md`, `.markdown`, `.mkd`)のみです。
data/USAGE.md CHANGED
@@ -59,7 +59,7 @@ Use the `.md.erb` extension to enable ERB inside Markdown.
59
59
  ```erb
60
60
  <html>
61
61
  <head>
62
- <title><%= page.title %></title>
62
+ <title><%= page[:title] %></title>
63
63
  </head>
64
64
  <body>
65
65
  <%= content %>
@@ -70,8 +70,8 @@ Use the `.md.erb` extension to enable ERB inside Markdown.
70
70
  The following are available in templates:
71
71
 
72
72
  - `content` — page body
73
- - `page.title` etc. — front-matter values
74
- - `site.title`, `site.url`, `site.lang` — site configuration
73
+ - `page[:title]`, `page[:lang]` etc. — front-matter values (including `lang` from site config; you can overwrite in the page front-matter)
74
+ - `site[:title]`, `site[:url]` etc. — site configuration
75
75
  - `include 'head', key: value` — insert an include
76
76
 
77
77
  ### 5. Build
@@ -83,6 +83,22 @@ isola build
83
83
 
84
84
  Output is generated in `_site/`.
85
85
 
86
+ ### 6. Development Server
87
+
88
+ ```bash
89
+ cd my-site
90
+ isola serve
91
+ ```
92
+
93
+ Builds the site and starts a local development server. By default, the server listens on `http://127.0.0.1:4444`. You can change the host and port in `_config.yaml`:
94
+
95
+ ```yaml
96
+ host: 127.0.0.1
97
+ port: 4444
98
+ ```
99
+
100
+ The server watches for file changes and automatically rebuilds the site. HTML pages that contain a `</body>` tag are injected with a live-reload script, so the browser refreshes automatically after each rebuild. Live reload only works for HTML files with a `</body>` tag.
101
+
86
102
  ## File Processing
87
103
 
88
104
  Isola currently supports only **ERB** (`.erb`) and **Markdown** (`.md`, `.markdown`, `.mkd`) as template engines.
data/exe/isola CHANGED
@@ -19,13 +19,13 @@ class IsolaCLI < Thor
19
19
  site = construct_site
20
20
  site.build
21
21
 
22
- site_dir = File.join(site.root_dir, site.config[:destination])
23
- host = site.config[:host]
24
- port = site.config[:port]
22
+ site_dir = File.join(site[:root_dir], site[:destination])
23
+ host = site[:host]
24
+ port = site[:port]
25
25
  server = Isola::DevServer.new(site_dir, host, port)
26
26
 
27
27
  watcher = Isola::Watcher.new(site) { server.notify_reload }
28
- listener = Listen.to(File.expand_path(site.root_dir), &watcher.method(:handle_changes))
28
+ listener = Listen.to(File.expand_path(site[:root_dir]), &watcher.method(:handle_changes))
29
29
  listener.start
30
30
 
31
31
  puts "serving at http://#{host}:#{port}"
data/lib/isola/context.rb CHANGED
@@ -3,16 +3,16 @@ require "tilt"
3
3
  module Isola
4
4
  class Context
5
5
  attr_reader :site, :content, :layout
6
- def initialize(page, site)
7
- @page_source = page
8
- @page_meta = Data.define(*page.meta.keys).new(**page.meta)
6
+ def initialize(source, site)
7
+ @source = source
8
+ @meta = {lang: site[:lang]}.merge(source.meta).freeze
9
9
  @site = site
10
10
  @content = ""
11
11
  @layout = {}
12
12
  end
13
13
 
14
14
  def page
15
- @page_meta
15
+ @meta
16
16
  end
17
17
 
18
18
  def include name, params = {}
@@ -22,8 +22,8 @@ module Isola
22
22
  end
23
23
 
24
24
  def render
25
- @current = @page_source
26
- @content, path = @page_source.render(self, @site)
25
+ @current = @source
26
+ @content, path = @source.render(self, @site)
27
27
  while @current.meta[:layout]
28
28
  layout = site.layout(@current.meta[:layout])
29
29
  raise "#{@current.meta[:layout]} not found for #{@current.filepath}" unless layout
@@ -8,7 +8,7 @@ module Isola
8
8
 
9
9
  def readpartial(maxlen, buf = +"")
10
10
  if !@data
11
- @data = @queue.pop
11
+ @data = @queue.pop.dup
12
12
  @data.force_encoding(Encoding::ASCII_8BIT)
13
13
  end
14
14
 
@@ -1,19 +1,20 @@
1
1
  module Isola
2
2
  class FileHandler
3
- attr_reader :pages, :layouts, :includes, :root_dir
3
+ attr_reader :entries, :layouts, :includes, :root_dir
4
4
  DEFAULT_EXCLUDES = [
5
5
  ".sass-cache", "gemfiles",
6
6
  "Gemfile", "Gemfile.lock", "node_modules",
7
7
  "vendor/bundle/", "vendor/cache/",
8
8
  "vendor/gems/", "vendor/ruby/"
9
9
  ]
10
- def initialize(root_dir, excludes: [])
10
+ def initialize(root_dir, output_path_func: nil, excludes: [])
11
11
  @excludes = DEFAULT_EXCLUDES.union(excludes)
12
12
  @rejects = Regexp.union(%r{(?:^|/)[._]}, %r{~$})
13
13
  @root_dir = File.absolute_path(root_dir)
14
- @pages = {}
14
+ @entries = {}
15
15
  @layouts = {}
16
16
  @includes = {}
17
+ @output_path_func = output_path_func || method(:remove_exts)
17
18
  collect(@root_dir)
18
19
  end
19
20
 
@@ -36,7 +37,7 @@ module Isola
36
37
  elsif path.start_with?("_includes/")
37
38
  @includes[remove_exts(path).delete_prefix("_includes/")] = path
38
39
  else
39
- @pages[remove_exts(path)] = path
40
+ @entries[@output_path_func.call(path)] = path
40
41
  end
41
42
  end
42
43
  end
data/lib/isola/site.rb CHANGED
@@ -9,8 +9,8 @@ module Isola
9
9
  default_language: "en",
10
10
  host: "127.0.0.1",
11
11
  port: 4444}.freeze
12
- SUPPORTED_TILT_EXT = [".erb", ".md", ".markdown", ".mkd"]
13
- EXT_MAP = {".md" => ".html", ".mkd" => ".html", ".markdown" => ".html", "" => ".html"}
12
+ SUPPORTED_TILT_EXT = [".erb", ".md", ".markdown", ".mkd", ".html"]
13
+ EXT_MAP = {".md" => ".html", ".mkd" => ".html", ".markdown" => ".html", ".html" => ".html", "" => ".html"}
14
14
  def initialize(config)
15
15
  @config = DEFAULT_CONFIG.merge(YAML.safe_load(config, symbolize_names: true) || {})
16
16
  @config[:root_dir] ||= Dir.pwd
@@ -18,40 +18,37 @@ module Isola
18
18
  collect_files
19
19
  end
20
20
 
21
- def title
22
- @config[:title]
21
+ def [] key
22
+ if key == :lang
23
+ key = :default_language
24
+ end
25
+ @config[key]
23
26
  end
24
27
 
25
- def url
26
- @config[:url]
28
+ def ext_to_process_with_tilt? ext
29
+ SUPPORTED_TILT_EXT.include? ext
27
30
  end
28
31
 
29
- def lang
30
- @config[:default_language]
32
+ def process_extensions(path)
33
+ path = path.dup
34
+ last_ext = nil
35
+ while ext_to_process_with_tilt?(ext = File.extname(path))
36
+ yield(path, ext) if block_given?
37
+ path.delete_suffix!(ext)
38
+ last_ext = ext
39
+ end
40
+ ext.empty? ? path + result_ext_for(last_ext) : path
31
41
  end
32
42
 
33
- def root_dir
34
- @config[:root_dir]
35
- end
36
-
37
- def supported_ext? ext
38
- SUPPORTED_TILT_EXT.include? ext
39
- end
40
-
41
- def result_ext_for ext
42
- EXT_MAP[ext]
43
+ def output_path_for path
44
+ process_extensions path
43
45
  end
44
46
 
45
47
  def build
46
- dest_dir = File.join(@file_handler.root_dir, @config[:destination])
47
48
  FileUtils.rm_rf(dest_dir)
48
- @file_handler.pages.each do |name, path|
49
- page = Source.new(path, read_in_site(path))
50
- puts "building #{path}..."
51
- rendered, path = Context.new(page, self).render
52
- dest_path = File.join(dest_dir, path)
53
- FileUtils.mkdir_p(File.dirname(dest_path))
54
- File.write(dest_path, rendered)
49
+ entries.each do |name, entry|
50
+ puts "building #{name}..."
51
+ render_to_dest entry
55
52
  end
56
53
  puts "done."
57
54
  end
@@ -66,32 +63,75 @@ module Isola
66
63
  end
67
64
 
68
65
  def layout name
69
- find_source(name, @parsed_layouts, @file_handler.layouts)
66
+ find_entry(name, @parsed_layouts, @file_handler.layouts)
70
67
  end
71
68
 
72
69
  def include name
73
- find_source(name, @parsed_includes, @file_handler.includes)
70
+ find_entry(name, @parsed_includes, @file_handler.includes)
71
+ end
72
+
73
+ def entry name
74
+ find_entry(name, @parsed_entries, @file_handler.entries)
75
+ end
76
+
77
+ def entries
78
+ Enumerator.new do |yielder|
79
+ @file_handler.entries.each_key do |name|
80
+ yielder.yield name, entry(name)
81
+ end
82
+ end
74
83
  end
75
84
 
76
85
  private
77
86
 
87
+ def dest_dir
88
+ File.join(@file_handler.root_dir, @config[:destination])
89
+ end
90
+
91
+ def render_to_dest entry
92
+ if entry.instance_of? Source
93
+ rendered, path = Context.new(entry, self).render
94
+ dest_path = File.join(dest_dir, path)
95
+ FileUtils.mkdir_p(File.dirname(dest_path))
96
+ File.write(dest_path, rendered)
97
+ elsif entry.instance_of? StaticFile
98
+ path = entry.path
99
+ src_path = File.join(config[:root_dir], path)
100
+ dest_path = File.join(dest_dir, path)
101
+ FileUtils.mkdir_p(File.dirname(dest_path))
102
+ FileUtils.copy(src_path, dest_path)
103
+ else
104
+ raise "can't render class #{entry.class}"
105
+ end
106
+ end
107
+
108
+ def result_ext_for ext
109
+ return "" if ext.nil?
110
+ EXT_MAP[ext]
111
+ end
112
+
78
113
  def collect_files
79
- @file_handler = FileHandler.new(root_dir, excludes: @config[:excludes])
114
+ @file_handler = FileHandler.new(config[:root_dir], output_path_func: method(:output_path_for), excludes: @config[:excludes])
80
115
  @parsed_layouts = {}
81
116
  @parsed_includes = {}
117
+ @parsed_entries = {}
82
118
  end
83
119
 
84
- def find_source(name, cache, store)
120
+ def find_entry(name, cache, store)
85
121
  cache[name] ||=
86
122
  begin
87
123
  p = store[name]
88
124
  return nil unless p
89
- Source.new(p, read_in_site(p))
125
+ if ext_to_process_with_tilt?(File.extname(p))
126
+ Source.new(p, read_in_site(p))
127
+ else
128
+ StaticFile.new(p)
129
+ end
90
130
  end
91
131
  end
92
132
 
93
133
  def read_in_site(p)
94
- File.read(File.join(root_dir, p))
134
+ File.read(File.join(config[:root_dir], p))
95
135
  end
96
136
  end
97
137
  end
data/lib/isola/source.rb CHANGED
@@ -12,21 +12,16 @@ module Isola
12
12
  end
13
13
  end
14
14
 
15
+ def [] key
16
+ @meta[key]
17
+ end
18
+
15
19
  def render(context, site, params = {})
16
- path = @filepath.dup
17
20
  rendered = @content.dup
18
- last_ext = ""
19
- while !(ext = File.extname(path)).empty? && site.supported_ext?(ext)
20
- rendered = Tilt.new(path) { rendered }.render(context, params)
21
- path.delete_suffix! ext
22
- last_ext = ext
23
- end
24
-
25
- if ext.empty?
26
- [rendered, path + site.result_ext_for(last_ext)]
27
- else
28
- [rendered, path]
21
+ output_path = site.process_extensions(@filepath) do |current_path, _ext|
22
+ rendered = Tilt.new(current_path) { rendered }.render(context, params)
29
23
  end
24
+ [rendered, output_path]
30
25
  end
31
26
  end
32
27
  end
@@ -0,0 +1,8 @@
1
+ module Isola
2
+ class StaticFile
3
+ attr_reader :path
4
+ def initialize(path)
5
+ @path = path
6
+ end
7
+ end
8
+ end
data/lib/isola/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Isola
4
- VERSION = "0.1.1"
4
+ VERSION = "0.1.3"
5
5
  end
data/lib/isola.rb CHANGED
@@ -4,6 +4,7 @@ require_relative "isola/version"
4
4
  require_relative "isola/site"
5
5
  require_relative "isola/file_handler"
6
6
  require_relative "isola/source"
7
+ require_relative "isola/static_file"
7
8
  require_relative "isola/context"
8
9
  require_relative "isola/watcher"
9
10
  require_relative "isola/dev_server"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: isola
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.1.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Satoshi Kojima
@@ -99,6 +99,7 @@ files:
99
99
  - lib/isola/file_handler.rb
100
100
  - lib/isola/site.rb
101
101
  - lib/isola/source.rb
102
+ - lib/isola/static_file.rb
102
103
  - lib/isola/version.rb
103
104
  - lib/isola/watcher.rb
104
105
  homepage: https://github.com/skoji/isola
@@ -113,14 +114,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
113
114
  requirements:
114
115
  - - ">="
115
116
  - !ruby/object:Gem::Version
116
- version: 4.0.0
117
+ version: 3.4.0
117
118
  required_rubygems_version: !ruby/object:Gem::Requirement
118
119
  requirements:
119
120
  - - ">="
120
121
  - !ruby/object:Gem::Version
121
122
  version: '0'
122
123
  requirements: []
123
- rubygems_version: 4.0.3
124
+ rubygems_version: 4.0.6
124
125
  specification_version: 4
125
126
  summary: very simple static site generator using ERB
126
127
  test_files: []