mill 0.11 → 0.18
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 +4 -4
- data/.gitignore +11 -1
- data/LICENSE +1 -1
- data/Rakefile +1 -2
- data/TODO.md +4 -0
- data/bin/mill +1 -27
- data/lib/mill/command.rb +13 -0
- data/lib/mill/commands/build.rb +17 -0
- data/lib/mill/commands/check.rb +16 -0
- data/lib/mill/commands/diff.rb +18 -0
- data/lib/mill/commands/list.rb +20 -0
- data/lib/mill/commands/snapshot.rb +20 -0
- data/lib/mill/commands/tree.rb +17 -0
- data/lib/mill/commands/types.rb +18 -0
- data/lib/mill/commands/upload.rb +24 -0
- data/lib/mill/config.rb +27 -0
- data/lib/mill/resource.rb +81 -81
- data/lib/mill/resources/blob.rb +4 -0
- data/lib/mill/resources/feed.rb +5 -13
- data/lib/mill/resources/image.rb +10 -18
- data/lib/mill/resources/markdown.rb +20 -0
- data/lib/mill/resources/markup.rb +62 -0
- data/lib/mill/resources/page.rb +140 -0
- data/lib/mill/resources/redirect.rb +17 -16
- data/lib/mill/resources/robots.rb +3 -4
- data/lib/mill/resources/sitemap.rb +3 -5
- data/lib/mill/resources/stylesheet.rb +4 -4
- data/lib/mill/resources/textile.rb +27 -0
- data/lib/mill/resources.rb +89 -0
- data/lib/mill/site.rb +181 -251
- data/lib/mill.rb +28 -8
- data/mill.gemspec +22 -17
- data/test/content/a.md +3 -0
- data/test/content/b/ba.md +3 -0
- data/test/content/b/bb.md +3 -0
- data/test/content/b/index.md +3 -0
- data/test/content/c.md +4 -0
- data/test/content/d.md +4 -0
- data/test/content/index.md +3 -0
- data/test/main_test.rb +68 -0
- data/test/mill.yaml +8 -0
- metadata +189 -40
- data/TODO.txt +0 -61
- data/lib/mill/html_helpers.rb +0 -122
- data/lib/mill/navigator.rb +0 -61
- data/lib/mill/resources/dir.rb +0 -31
- data/lib/mill/resources/google_site_verification.rb +0 -30
- data/lib/mill/resources/text.rb +0 -207
- data/lib/mill/version.rb +0 -5
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 72216a7795be9cfd8a2039e3eac35f73f4c129a30e951074c638d6c77088c869
|
|
4
|
+
data.tar.gz: aead637972f953d1d01aaee384554766361cfb4d9efa1ae95a6aaa2e2e5e6d11
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 34d154f5a9cfa6e0a10d4abc57c7d3d99e18e857b1457e5ab9fbf82b50d426f469ed8cd79dc8821cdcddcf9e7fc95920d868b2025a0a328fdab9624e7d83d115
|
|
7
|
+
data.tar.gz: 8c433c5295ad53229ac23473eddd21b12995f225beb542e9c4d64ecafbec63d215fa343630e3380b5b162b62fd63c29eeba9b58f0404cf281aa89c36ef666bd2
|
data/.gitignore
CHANGED
data/LICENSE
CHANGED
data/Rakefile
CHANGED
|
@@ -1,2 +1 @@
|
|
|
1
|
-
require '
|
|
2
|
-
Gem::Tasks.new
|
|
1
|
+
require 'simple-rake-tasks'
|
data/TODO.md
ADDED
data/bin/mill
CHANGED
|
@@ -2,30 +2,4 @@
|
|
|
2
2
|
|
|
3
3
|
require 'mill'
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
begin
|
|
8
|
-
case (command = ARGV.shift)
|
|
9
|
-
when nil, 'make'
|
|
10
|
-
$site.make
|
|
11
|
-
when 'clean'
|
|
12
|
-
$site.clean
|
|
13
|
-
when 'check'
|
|
14
|
-
$site.check
|
|
15
|
-
when 'list'
|
|
16
|
-
$site.list
|
|
17
|
-
when 'diff'
|
|
18
|
-
$site.diff
|
|
19
|
-
when 'snapshot'
|
|
20
|
-
$site.snapshot
|
|
21
|
-
when 'upload'
|
|
22
|
-
$site.upload
|
|
23
|
-
when 'output-dir'
|
|
24
|
-
puts $site.output_dir
|
|
25
|
-
else
|
|
26
|
-
raise "Unknown command: #{command.inspect}"
|
|
27
|
-
end
|
|
28
|
-
rescue Mill::Error => e
|
|
29
|
-
warn e
|
|
30
|
-
exit(1)
|
|
31
|
-
end
|
|
5
|
+
Simple::CommandParser.run(ARGV)
|
data/lib/mill/command.rb
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
module Mill
|
|
2
|
+
|
|
3
|
+
module Commands
|
|
4
|
+
|
|
5
|
+
class Snapshot < Command
|
|
6
|
+
|
|
7
|
+
def run(args)
|
|
8
|
+
super
|
|
9
|
+
@site.output_dir.chdir do
|
|
10
|
+
run_command(%w[git init]) unless Path.new('.git').exist?
|
|
11
|
+
run_command(%w[git add .])
|
|
12
|
+
run_command(%w[git commit -a -m Update.])
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
module Mill
|
|
2
|
+
|
|
3
|
+
module Commands
|
|
4
|
+
|
|
5
|
+
class Upload < Command
|
|
6
|
+
|
|
7
|
+
def run(args)
|
|
8
|
+
super
|
|
9
|
+
raise "site_rsync not defined" unless @site.site_rsync
|
|
10
|
+
options = %w[
|
|
11
|
+
--progress
|
|
12
|
+
--verbose
|
|
13
|
+
--archive
|
|
14
|
+
--exclude=.git
|
|
15
|
+
--delete-after
|
|
16
|
+
]
|
|
17
|
+
run_command('rsync', *options, @site.output_dir, @site.site_rsync, verbose: true)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
end
|
data/lib/mill/config.rb
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
module Mill
|
|
2
|
+
|
|
3
|
+
ConfigFileName = 'mill.yaml'
|
|
4
|
+
|
|
5
|
+
BaseConfig = Simple::Configurator.define(
|
|
6
|
+
dir: { default: '.', converter: :path },
|
|
7
|
+
input_dir: { default: 'content', converter: :path },
|
|
8
|
+
output_dir: { default: 'public_html', converter: :path },
|
|
9
|
+
code_dir: { default: 'code', converter: :path },
|
|
10
|
+
site_uri: { default: 'http://localhost', converter: :uri },
|
|
11
|
+
site_rsync: nil,
|
|
12
|
+
site_title: nil,
|
|
13
|
+
site_email: nil,
|
|
14
|
+
site_twitter: { converter: :uri },
|
|
15
|
+
site_instagram: { converter: :uri },
|
|
16
|
+
site_postal: nil,
|
|
17
|
+
site_phone: nil,
|
|
18
|
+
site_control_date: { converter: :date },
|
|
19
|
+
html_version: { default: :html5, converter: :symbol },
|
|
20
|
+
make_error: true,
|
|
21
|
+
make_feed: true,
|
|
22
|
+
make_sitemap: true,
|
|
23
|
+
make_robots: true,
|
|
24
|
+
allow_robots: true,
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
end
|
data/lib/mill/resource.rb
CHANGED
|
@@ -4,110 +4,105 @@ module Mill
|
|
|
4
4
|
|
|
5
5
|
FileTypes = []
|
|
6
6
|
|
|
7
|
-
attr_accessor :
|
|
8
|
-
attr_accessor :
|
|
7
|
+
attr_accessor :path
|
|
8
|
+
attr_accessor :uri
|
|
9
|
+
attr_accessor :primary
|
|
10
|
+
attr_accessor :input
|
|
9
11
|
attr_accessor :date
|
|
10
|
-
|
|
11
|
-
attr_accessor :content
|
|
12
|
+
attr_reader :output
|
|
12
13
|
attr_accessor :site
|
|
14
|
+
attr_accessor :node
|
|
13
15
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
@input_file = Path.new(input_file)
|
|
22
|
-
@date = input_file.mtime.to_datetime
|
|
23
|
-
else
|
|
24
|
-
@date = DateTime.now
|
|
16
|
+
include SetParams
|
|
17
|
+
include Simple::Printer::Printable
|
|
18
|
+
|
|
19
|
+
def initialize(params={})
|
|
20
|
+
super({ primary: false }.merge(params))
|
|
21
|
+
unless defined?(@date)
|
|
22
|
+
@date = @input&.kind_of?(Path) ? @input.mtime.to_datetime : DateTime.now
|
|
25
23
|
end
|
|
26
|
-
@
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
def
|
|
34
|
-
@
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
24
|
+
@uri = Addressable::URI.encode(@path, Addressable::URI)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def inspect
|
|
28
|
+
"<#{self.class}>"
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def primary?
|
|
32
|
+
@primary
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def root?
|
|
36
|
+
self == @site.root_resource
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def output_file
|
|
40
|
+
if @site && @path
|
|
41
|
+
@site.output_dir / Path.new(@path).relative_to('/')
|
|
43
42
|
else
|
|
44
|
-
|
|
43
|
+
nil
|
|
45
44
|
end
|
|
46
45
|
end
|
|
47
46
|
|
|
48
|
-
def
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
47
|
+
def printable
|
|
48
|
+
[
|
|
49
|
+
:path,
|
|
50
|
+
{ key: :input, value: input_description },
|
|
51
|
+
{ key: :output_file, value: (o = output_file) ? o.relative_to(@site.output_dir).to_s : nil },
|
|
52
|
+
:date,
|
|
53
|
+
:primary?,
|
|
54
|
+
:class,
|
|
55
|
+
{ label: 'Parent', value: parent&.path || '-' },
|
|
56
|
+
{ label: 'Siblings', value: siblings&.map(&:path)&.join(', ') || '-' },
|
|
57
|
+
{ label: 'Children', value: children&.map(&:path)&.join(', ') || '-' },
|
|
58
|
+
]
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def input_description
|
|
62
|
+
case @input
|
|
63
|
+
when Path
|
|
64
|
+
@input.relative_to(@site.input_dir).to_s
|
|
65
|
+
when String
|
|
66
|
+
(@input[0...100] + '...').inspect
|
|
67
|
+
when nil
|
|
68
|
+
'-'
|
|
54
69
|
else
|
|
55
|
-
|
|
70
|
+
"<#{@input.class}>"
|
|
56
71
|
end
|
|
57
72
|
end
|
|
58
73
|
|
|
59
|
-
def
|
|
60
|
-
@
|
|
74
|
+
def parent
|
|
75
|
+
@node&.parent&.content
|
|
61
76
|
end
|
|
62
77
|
|
|
63
|
-
def
|
|
64
|
-
|
|
65
|
-
self.class,
|
|
66
|
-
@input_file ? @input_file.relative_to(@site.input_dir).to_s : nil,
|
|
67
|
-
@output_file ? @output_file.relative_to(@site.output_dir).to_s : nil,
|
|
68
|
-
@date.to_s,
|
|
69
|
-
@public,
|
|
70
|
-
@content && @content.class,
|
|
71
|
-
]
|
|
78
|
+
def siblings
|
|
79
|
+
@node ? @node.siblings.map(&:content).compact : []
|
|
72
80
|
end
|
|
73
81
|
|
|
74
|
-
def
|
|
75
|
-
|
|
76
|
-
@site.resources.select do |resource|
|
|
77
|
-
resource != self &&
|
|
78
|
-
(klass.nil? || resource.kind_of?(klass)) &&
|
|
79
|
-
resource.parent_uri == parent_uri
|
|
80
|
-
end
|
|
82
|
+
def previous_sibling
|
|
83
|
+
@node&.previous_sibling&.content
|
|
81
84
|
end
|
|
82
85
|
|
|
83
|
-
def
|
|
84
|
-
|
|
85
|
-
path = '/' + @output_file.relative_to(@site.output_dir).to_s
|
|
86
|
-
path.sub!(%r{/index\.html$}, '/')
|
|
87
|
-
path.sub!(%r{\.html$}, '') if @site.shorten_uris
|
|
88
|
-
Addressable::URI.encode(path, Addressable::URI)
|
|
86
|
+
def next_sibling
|
|
87
|
+
@node&.next_sibling&.content
|
|
89
88
|
end
|
|
90
89
|
|
|
91
|
-
def
|
|
92
|
-
|
|
90
|
+
def children
|
|
91
|
+
@node ? @node.children.map(&:content).compact : []
|
|
93
92
|
end
|
|
94
93
|
|
|
95
94
|
def absolute_uri
|
|
96
|
-
@site.site_uri + uri
|
|
95
|
+
@site.site_uri + @uri
|
|
97
96
|
end
|
|
98
97
|
|
|
99
98
|
def tag_uri
|
|
100
|
-
@site.tag_uri + uri
|
|
99
|
+
@site.tag_uri + @uri
|
|
101
100
|
end
|
|
102
101
|
|
|
103
102
|
def change_frequency
|
|
104
103
|
:weekly
|
|
105
104
|
end
|
|
106
105
|
|
|
107
|
-
def final_content
|
|
108
|
-
@content
|
|
109
|
-
end
|
|
110
|
-
|
|
111
106
|
def load
|
|
112
107
|
# implemented in subclass
|
|
113
108
|
end
|
|
@@ -117,16 +112,21 @@ module Mill
|
|
|
117
112
|
end
|
|
118
113
|
|
|
119
114
|
def save
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
@
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
@
|
|
115
|
+
file = output_file
|
|
116
|
+
file.dirname.mkpath
|
|
117
|
+
if @output
|
|
118
|
+
# ;;warn "#{@path}: writing output to #{file}"
|
|
119
|
+
file.write(@output)
|
|
120
|
+
file.utime(@date.to_time, @date.to_time)
|
|
121
|
+
elsif @input.kind_of?(Path)
|
|
122
|
+
# ;;warn "#{@path}: copying #{@input} to #{file}"
|
|
123
|
+
@input.copy(file)
|
|
124
|
+
elsif @input
|
|
125
|
+
# ;;warn "#{@path}: writing input to #{file}"
|
|
126
|
+
file.write(@input)
|
|
127
|
+
file.utime(@date.to_time, @date.to_time)
|
|
128
128
|
else
|
|
129
|
-
raise Error, "Can't build resource without
|
|
129
|
+
raise Error, "#{@path}: Can't build resource without output or input file"
|
|
130
130
|
end
|
|
131
131
|
end
|
|
132
132
|
|
data/lib/mill/resources/blob.rb
CHANGED
|
@@ -5,6 +5,8 @@ module Mill
|
|
|
5
5
|
class Blob < Resource
|
|
6
6
|
|
|
7
7
|
FileTypes = %w{
|
|
8
|
+
text/plain
|
|
9
|
+
|
|
8
10
|
application/pdf
|
|
9
11
|
|
|
10
12
|
application/zip
|
|
@@ -16,9 +18,11 @@ module Mill
|
|
|
16
18
|
application/x-javascript
|
|
17
19
|
|
|
18
20
|
font/otf
|
|
21
|
+
font/woff2
|
|
19
22
|
application/font-sfnt
|
|
20
23
|
application/x-font-opentype
|
|
21
24
|
application/x-font-otf
|
|
25
|
+
application/font-woff
|
|
22
26
|
|
|
23
27
|
application/mp4
|
|
24
28
|
audio/mpeg
|
data/lib/mill/resources/feed.rb
CHANGED
|
@@ -1,20 +1,16 @@
|
|
|
1
|
-
# see http://www.sitemaps.org/protocol.php
|
|
2
|
-
|
|
3
1
|
module Mill
|
|
4
2
|
|
|
5
3
|
class Resource
|
|
6
4
|
|
|
7
5
|
class Feed < Resource
|
|
8
6
|
|
|
9
|
-
include HTMLHelpers
|
|
10
|
-
|
|
11
7
|
def build
|
|
12
8
|
resources = @site.feed_resources
|
|
13
|
-
|
|
9
|
+
@output = Nokogiri::XML::Builder.new do |xml|
|
|
14
10
|
xml.feed(xmlns: 'http://www.w3.org/2005/Atom') do
|
|
15
11
|
xml.id(@site.tag_uri)
|
|
16
12
|
xml.title(@site.site_title) if @site.site_title
|
|
17
|
-
xml.link(rel: 'alternate', type: 'text/html', href: @site.
|
|
13
|
+
xml.link(rel: 'alternate', type: 'text/html', href: @site.root_resource.absolute_uri) if @site.root_resource
|
|
18
14
|
xml.link(rel: 'self', type: 'application/atom+xml', href: absolute_uri)
|
|
19
15
|
xml.author do
|
|
20
16
|
xml.name(@site.feed_author_name) if @site.feed_author_name
|
|
@@ -35,15 +31,11 @@ module Mill
|
|
|
35
31
|
end
|
|
36
32
|
end
|
|
37
33
|
end
|
|
38
|
-
end
|
|
39
|
-
@content = builder.doc
|
|
40
|
-
super
|
|
34
|
+
end.doc
|
|
41
35
|
end
|
|
42
36
|
|
|
43
|
-
def
|
|
44
|
-
|
|
45
|
-
html.link(href: uri, rel: 'alternate', type: 'application/atom+xml')
|
|
46
|
-
end
|
|
37
|
+
def build_link(html)
|
|
38
|
+
html.link(href: uri, rel: 'alternate', type: 'application/atom+xml')
|
|
47
39
|
end
|
|
48
40
|
|
|
49
41
|
end
|
data/lib/mill/resources/image.rb
CHANGED
|
@@ -4,8 +4,6 @@ module Mill
|
|
|
4
4
|
|
|
5
5
|
class Image < Resource
|
|
6
6
|
|
|
7
|
-
include HTMLHelpers
|
|
8
|
-
|
|
9
7
|
FileTypes = %w{
|
|
10
8
|
image/gif
|
|
11
9
|
image/jpeg
|
|
@@ -18,27 +16,21 @@ module Mill
|
|
|
18
16
|
attr_accessor :width
|
|
19
17
|
attr_accessor :height
|
|
20
18
|
|
|
21
|
-
def
|
|
22
|
-
super +
|
|
23
|
-
|
|
24
|
-
|
|
19
|
+
def printable
|
|
20
|
+
super + [
|
|
21
|
+
:width,
|
|
22
|
+
:height,
|
|
25
23
|
]
|
|
26
24
|
end
|
|
27
25
|
|
|
28
26
|
def load
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
def img_html
|
|
35
|
-
html_fragment do |html|
|
|
36
|
-
html.img(
|
|
37
|
-
src: uri,
|
|
38
|
-
alt: @title,
|
|
39
|
-
height: @height,
|
|
40
|
-
width: @width)
|
|
27
|
+
raise Error, "Input must be file" unless @input.kind_of?(Path)
|
|
28
|
+
begin
|
|
29
|
+
info = ImageSize.path(@input.to_s)
|
|
30
|
+
rescue => e
|
|
31
|
+
raise Error, "Can't load image file #{@input.to_s.inspect}: #{e}"
|
|
41
32
|
end
|
|
33
|
+
@width, @height = *info.size
|
|
42
34
|
end
|
|
43
35
|
|
|
44
36
|
end
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
module Mill
|
|
2
|
+
|
|
3
|
+
class Resource
|
|
4
|
+
|
|
5
|
+
class Markup < Resource
|
|
6
|
+
|
|
7
|
+
def printable
|
|
8
|
+
super + [
|
|
9
|
+
:header,
|
|
10
|
+
{ label: 'Text', value: @text[0...100] + '...' },
|
|
11
|
+
]
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def load
|
|
15
|
+
@text = case @input
|
|
16
|
+
when Path
|
|
17
|
+
@input.read
|
|
18
|
+
when String
|
|
19
|
+
@input.dup
|
|
20
|
+
else
|
|
21
|
+
raise Error, "Unknown markup input: #{@input.class}"
|
|
22
|
+
end
|
|
23
|
+
@header = HashStruct.new
|
|
24
|
+
if @text.split(/\n/, 2).first =~ /^\w+:\s+/
|
|
25
|
+
fields = {}
|
|
26
|
+
lines, @text = @text.split(/\n\n/, 2)
|
|
27
|
+
lines.split(/\n/).each do |line|
|
|
28
|
+
if line.start_with?(/\s+/)
|
|
29
|
+
key = fields.keys.last
|
|
30
|
+
fields[key] += line
|
|
31
|
+
else
|
|
32
|
+
key, value = line.strip.split(/:\s*/, 2)
|
|
33
|
+
fields[key] = value
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
@header = HashStruct.new(fields)
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def parse_text(text)
|
|
41
|
+
# implemented in subclass
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def convert_class
|
|
45
|
+
@site.resource_class_for_type('text/html')
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def convert
|
|
49
|
+
return nil if @header[:draft]
|
|
50
|
+
convert_class.new(
|
|
51
|
+
path: @path.sub(%r{\.\w+$}, '.html'),
|
|
52
|
+
input: parse_text(@text),
|
|
53
|
+
date: @date,
|
|
54
|
+
**@header,
|
|
55
|
+
)
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
end
|