bunto 3.0.0 → 3.2.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +124 -76
- data/README.markdown +49 -12
- data/{bin → exe}/bunto +18 -14
- data/lib/bunto.rb +83 -78
- data/lib/bunto/cleaner.rb +10 -8
- data/lib/bunto/collection.rb +33 -17
- data/lib/bunto/command.rb +19 -13
- data/lib/bunto/commands/build.rb +22 -14
- data/lib/bunto/commands/clean.rb +9 -8
- data/lib/bunto/commands/doctor.rb +10 -8
- data/lib/bunto/commands/help.rb +4 -3
- data/lib/bunto/commands/new.rb +30 -21
- data/lib/bunto/commands/new_theme.rb +36 -0
- data/lib/bunto/commands/serve.rb +26 -20
- data/lib/bunto/commands/serve/servlet.rb +4 -5
- data/lib/bunto/configuration.rb +187 -125
- data/lib/bunto/converters/markdown.rb +19 -9
- data/lib/bunto/converters/markdown/kramdown_parser.rb +12 -5
- data/lib/bunto/converters/markdown/rdiscount_parser.rb +4 -4
- data/lib/bunto/converters/markdown/redcarpet_parser.rb +90 -84
- data/lib/bunto/convertible.rb +38 -25
- data/lib/bunto/deprecator.rb +11 -6
- data/lib/bunto/desktop.ini +2 -0
- data/lib/bunto/document.rb +53 -51
- data/lib/bunto/drops/bunto_drop.rb +12 -0
- data/lib/bunto/drops/document_drop.rb +40 -5
- data/lib/bunto/drops/drop.rb +49 -10
- data/lib/bunto/drops/excerpt_drop.rb +15 -0
- data/lib/bunto/drops/site_drop.rb +4 -2
- data/lib/bunto/drops/url_drop.rb +4 -4
- data/lib/bunto/entry_filter.rb +64 -19
- data/lib/bunto/errors.rb +6 -3
- data/lib/bunto/excerpt.rb +4 -6
- data/lib/bunto/external.rb +4 -4
- data/lib/bunto/filters.rb +72 -39
- data/lib/bunto/frontmatter_defaults.rb +45 -38
- data/lib/bunto/hooks.rb +21 -21
- data/lib/bunto/layout.rb +4 -8
- data/lib/bunto/liquid_renderer.rb +14 -3
- data/lib/bunto/liquid_renderer/file.rb +5 -1
- data/lib/bunto/liquid_renderer/table.rb +11 -11
- data/lib/bunto/log_adapter.rb +2 -2
- data/lib/bunto/page.rb +10 -10
- data/lib/bunto/plugin.rb +5 -5
- data/lib/bunto/plugin_manager.rb +12 -8
- data/lib/bunto/publisher.rb +1 -1
- data/lib/bunto/reader.rb +11 -7
- data/lib/bunto/readers/data_reader.rb +9 -9
- data/lib/bunto/readers/layout_reader.rb +7 -7
- data/lib/bunto/readers/page_reader.rb +3 -1
- data/lib/bunto/readers/post_reader.rb +9 -10
- data/lib/bunto/readers/static_file_reader.rb +3 -1
- data/lib/bunto/regenerator.rb +50 -28
- data/lib/bunto/related_posts.rb +1 -1
- data/lib/bunto/renderer.rb +33 -23
- data/lib/bunto/site.rb +94 -51
- data/lib/bunto/static_file.rb +33 -26
- data/lib/bunto/stevenson.rb +6 -5
- data/lib/bunto/tags/highlight.rb +50 -35
- data/lib/bunto/tags/include.rb +42 -31
- data/lib/bunto/tags/link.rb +11 -4
- data/lib/bunto/tags/post_url.rb +8 -7
- data/lib/bunto/theme.rb +10 -8
- data/lib/bunto/theme_builder.rb +117 -0
- data/lib/bunto/url.rb +21 -14
- data/lib/bunto/utils.rb +57 -28
- data/lib/bunto/utils/ansi.rb +9 -9
- data/lib/bunto/utils/platforms.rb +2 -2
- data/lib/bunto/version.rb +1 -1
- data/lib/site_template/_config.yml +3 -1
- data/lib/site_template/_posts/0000-00-00-welcome-to-bunto.markdown.erb +3 -3
- data/lib/site_template/about.md +3 -3
- data/lib/site_template/css/main.scss +3 -17
- data/lib/theme_template/CODE_OF_CONDUCT.md.erb +74 -0
- data/lib/theme_template/Gemfile +2 -0
- data/lib/theme_template/LICENSE.txt.erb +21 -0
- data/lib/theme_template/README.md.erb +48 -0
- data/lib/theme_template/_layouts/default.html +1 -0
- data/lib/theme_template/_layouts/page.html +5 -0
- data/lib/theme_template/_layouts/post.html +5 -0
- data/lib/theme_template/example/_config.yml.erb +1 -0
- data/lib/theme_template/example/_post.md +12 -0
- data/lib/theme_template/example/index.html +14 -0
- data/lib/theme_template/example/style.scss +7 -0
- data/lib/theme_template/gitignore.erb +4 -0
- data/lib/theme_template/theme.gemspec.erb +18 -0
- metadata +40 -19
- data/lib/site_template/_includes/footer.html +0 -38
- data/lib/site_template/_includes/head.html +0 -12
- data/lib/site_template/_includes/header.html +0 -27
- data/lib/site_template/_includes/icon-github.html +0 -1
- data/lib/site_template/_includes/icon-github.svg +0 -1
- data/lib/site_template/_includes/icon-twitter.html +0 -1
- data/lib/site_template/_includes/icon-twitter.svg +0 -1
- data/lib/site_template/_layouts/default.html +0 -20
- data/lib/site_template/_layouts/page.html +0 -14
- data/lib/site_template/_layouts/post.html +0 -15
- data/lib/site_template/_sass/_base.scss +0 -200
- data/lib/site_template/_sass/_layout.scss +0 -242
- data/lib/site_template/_sass/_syntax-highlighting.scss +0 -71
data/lib/bunto/tags/highlight.rb
CHANGED
@@ -8,28 +8,15 @@ module Bunto
|
|
8
8
|
# forms: name, name=value, or name="<quoted list>"
|
9
9
|
#
|
10
10
|
# <quoted list> is a space-separated list of numbers
|
11
|
-
SYNTAX =
|
11
|
+
SYNTAX = %r!^([a-zA-Z0-9.+#-]+)((\s+\w+(=(\w+|"([0-9]+\s)*[0-9]+"))?)*)$!
|
12
12
|
|
13
13
|
def initialize(tag_name, markup, tokens)
|
14
14
|
super
|
15
15
|
if markup.strip =~ SYNTAX
|
16
16
|
@lang = Regexp.last_match(1).downcase
|
17
|
-
@highlight_options =
|
18
|
-
if defined?(Regexp.last_match(2)) && Regexp.last_match(2) != ''
|
19
|
-
# Split along 3 possible forms -- key="<quoted list>", key=value, or key
|
20
|
-
Regexp.last_match(2).scan(/(?:\w="[^"]*"|\w=\w|\w)+/) do |opt|
|
21
|
-
key, value = opt.split('=')
|
22
|
-
# If a quoted list, convert to array
|
23
|
-
if value && value.include?("\"")
|
24
|
-
value.delete!('"')
|
25
|
-
value = value.split
|
26
|
-
end
|
27
|
-
@highlight_options[key.to_sym] = value || true
|
28
|
-
end
|
29
|
-
end
|
30
|
-
@highlight_options[:linenos] = "inline" if @highlight_options.key?(:linenos) && @highlight_options[:linenos] == true
|
17
|
+
@highlight_options = parse_options(Regexp.last_match(2))
|
31
18
|
else
|
32
|
-
raise SyntaxError
|
19
|
+
raise SyntaxError, <<-eos
|
33
20
|
Syntax Error in tag 'highlight' while parsing the following markup:
|
34
21
|
|
35
22
|
#{markup}
|
@@ -42,15 +29,15 @@ eos
|
|
42
29
|
def render(context)
|
43
30
|
prefix = context["highlighter_prefix"] || ""
|
44
31
|
suffix = context["highlighter_suffix"] || ""
|
45
|
-
code = super.to_s.gsub(
|
32
|
+
code = super.to_s.gsub(%r!\A(\n|\r)+|(\n|\r)+\z!, "")
|
46
33
|
|
47
34
|
is_safe = !!context.registers[:site].safe
|
48
35
|
|
49
36
|
output =
|
50
37
|
case context.registers[:site].highlighter
|
51
|
-
when
|
38
|
+
when "pygments"
|
52
39
|
render_pygments(code, is_safe)
|
53
|
-
when
|
40
|
+
when "rouge"
|
54
41
|
render_rouge(code)
|
55
42
|
else
|
56
43
|
render_codehighlighter(code)
|
@@ -66,7 +53,7 @@ eos
|
|
66
53
|
[:startinline, opts.fetch(:startinline, nil)],
|
67
54
|
[:hl_lines, opts.fetch(:hl_lines, nil)],
|
68
55
|
[:linenos, opts.fetch(:linenos, nil)],
|
69
|
-
[:encoding, opts.fetch(:encoding,
|
56
|
+
[:encoding, opts.fetch(:encoding, "utf-8")],
|
70
57
|
[:cssclass, opts.fetch(:cssclass, nil)]
|
71
58
|
].reject { |f| f.last.nil? }]
|
72
59
|
else
|
@@ -74,8 +61,30 @@ eos
|
|
74
61
|
end
|
75
62
|
end
|
76
63
|
|
64
|
+
private
|
65
|
+
|
66
|
+
def parse_options(input)
|
67
|
+
options = {}
|
68
|
+
unless input.empty?
|
69
|
+
# Split along 3 possible forms -- key="<quoted list>", key=value, or key
|
70
|
+
input.scan(%r!(?:\w="[^"]*"|\w=\w|\w)+!) do |opt|
|
71
|
+
key, value = opt.split("=")
|
72
|
+
# If a quoted list, convert to array
|
73
|
+
if value && value.include?("\"")
|
74
|
+
value.delete!('"')
|
75
|
+
value = value.split
|
76
|
+
end
|
77
|
+
options[key.to_sym] = value || true
|
78
|
+
end
|
79
|
+
end
|
80
|
+
if options.key?(:linenos) && options[:linenos] == true
|
81
|
+
options[:linenos] = "inline"
|
82
|
+
end
|
83
|
+
options
|
84
|
+
end
|
85
|
+
|
77
86
|
def render_pygments(code, is_safe)
|
78
|
-
Bunto::External.require_with_graceful_fail(
|
87
|
+
Bunto::External.require_with_graceful_fail("pygments")
|
79
88
|
|
80
89
|
highlighted_code = Pygments.highlight(
|
81
90
|
code,
|
@@ -84,22 +93,27 @@ eos
|
|
84
93
|
)
|
85
94
|
|
86
95
|
if highlighted_code.nil?
|
87
|
-
Bunto.logger.error
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
96
|
+
Bunto.logger.error <<eos
|
97
|
+
There was an error highlighting your code:
|
98
|
+
|
99
|
+
#{code}
|
100
|
+
|
101
|
+
While attempting to convert the above code, Pygments.rb returned an unacceptable value.
|
102
|
+
This is usually a timeout problem solved by running `bunto build` again.
|
103
|
+
eos
|
104
|
+
raise ArgumentError, "Pygments.rb returned an unacceptable value "\
|
105
|
+
"when attempting to highlight some code."
|
95
106
|
end
|
96
107
|
|
97
|
-
highlighted_code.sub('<div class="highlight"><pre>',
|
108
|
+
highlighted_code.sub('<div class="highlight"><pre>', "").sub("</pre></div>", "")
|
98
109
|
end
|
99
110
|
|
100
111
|
def render_rouge(code)
|
101
|
-
Bunto::External.require_with_graceful_fail(
|
102
|
-
formatter = Rouge::Formatters::HTML.new(
|
112
|
+
Bunto::External.require_with_graceful_fail("rouge")
|
113
|
+
formatter = Rouge::Formatters::HTML.new(
|
114
|
+
:line_numbers => @highlight_options[:linenos],
|
115
|
+
:wrap => false
|
116
|
+
)
|
103
117
|
lexer = Rouge::Lexer.find_fancy(@lang, code) || Rouge::Lexers::PlainText
|
104
118
|
formatter.format(lexer.lex(code))
|
105
119
|
end
|
@@ -110,13 +124,14 @@ eos
|
|
110
124
|
|
111
125
|
def add_code_tag(code)
|
112
126
|
code_attributes = [
|
113
|
-
"class=\"language-#{@lang.to_s.tr(
|
127
|
+
"class=\"language-#{@lang.to_s.tr("+", "-")}\"",
|
114
128
|
"data-lang=\"#{@lang}\""
|
115
129
|
].join(" ")
|
116
|
-
"<figure class=\"highlight\"><pre><code #{code_attributes}
|
130
|
+
"<figure class=\"highlight\"><pre><code #{code_attributes}>"\
|
131
|
+
"#{code.chomp}</code></pre></figure>"
|
117
132
|
end
|
118
133
|
end
|
119
134
|
end
|
120
135
|
end
|
121
136
|
|
122
|
-
Liquid::Template.register_tag(
|
137
|
+
Liquid::Template.register_tag("highlight", Bunto::Tags::HighlightBlock)
|
data/lib/bunto/tags/include.rb
CHANGED
@@ -12,17 +12,23 @@ module Bunto
|
|
12
12
|
end
|
13
13
|
|
14
14
|
class IncludeTag < Liquid::Tag
|
15
|
-
VALID_SYNTAX =
|
16
|
-
|
15
|
+
VALID_SYNTAX = %r!
|
16
|
+
([\w-]+)\s*=\s*
|
17
|
+
(?:"([^"\\]*(?:\\.[^"\\]*)*)"|'([^'\\]*(?:\\.[^'\\]*)*)'|([\w\.-]+))
|
18
|
+
!x
|
19
|
+
VARIABLE_SYNTAX = %r!
|
20
|
+
(?<variable>[^{]*(\{\{\s*[\w\-\.]+\s*(\|.*)?\}\}[^\s{}]*)+)
|
21
|
+
(?<params>.*)
|
22
|
+
!x
|
17
23
|
|
18
24
|
def initialize(tag_name, markup, tokens)
|
19
25
|
super
|
20
26
|
matched = markup.strip.match(VARIABLE_SYNTAX)
|
21
27
|
if matched
|
22
|
-
@file = matched[
|
23
|
-
@params = matched[
|
28
|
+
@file = matched["variable"].strip
|
29
|
+
@params = matched["params"].strip
|
24
30
|
else
|
25
|
-
@file, @params = markup.strip.split(
|
31
|
+
@file, @params = markup.strip.split(%r!\s+!, 2)
|
26
32
|
end
|
27
33
|
validate_params if @params
|
28
34
|
@tag_name = tag_name
|
@@ -36,13 +42,13 @@ module Bunto
|
|
36
42
|
params = {}
|
37
43
|
markup = @params
|
38
44
|
|
39
|
-
while match = VALID_SYNTAX.match(markup)
|
45
|
+
while (match = VALID_SYNTAX.match(markup))
|
40
46
|
markup = markup[match.end(0)..-1]
|
41
47
|
|
42
48
|
value = if match[2]
|
43
|
-
match[2].gsub(
|
49
|
+
match[2].gsub(%r!\\"!, '"')
|
44
50
|
elsif match[3]
|
45
|
-
match[3].gsub(
|
51
|
+
match[3].gsub(%r!\\'!, "'")
|
46
52
|
elsif match[4]
|
47
53
|
context[match[4]]
|
48
54
|
end
|
@@ -53,8 +59,8 @@ module Bunto
|
|
53
59
|
end
|
54
60
|
|
55
61
|
def validate_file_name(file)
|
56
|
-
if file !~
|
57
|
-
raise ArgumentError
|
62
|
+
if file !~ %r!^[a-zA-Z0-9_/\.-]+$! || file =~ %r!\./! || file =~ %r!/\.!
|
63
|
+
raise ArgumentError, <<-eos
|
58
64
|
Invalid syntax for include tag. File contains invalid characters or sequences:
|
59
65
|
|
60
66
|
#{file}
|
@@ -68,9 +74,9 @@ eos
|
|
68
74
|
end
|
69
75
|
|
70
76
|
def validate_params
|
71
|
-
full_valid_syntax =
|
77
|
+
full_valid_syntax = %r!\A\s*(?:#{VALID_SYNTAX}(?=\s|\z)\s*)*\z!
|
72
78
|
unless @params =~ full_valid_syntax
|
73
|
-
raise ArgumentError
|
79
|
+
raise ArgumentError, <<-eos
|
74
80
|
Invalid syntax for include tag:
|
75
81
|
|
76
82
|
#{@params}
|
@@ -91,7 +97,10 @@ eos
|
|
91
97
|
# Render the variable if required
|
92
98
|
def render_variable(context)
|
93
99
|
if @file.match(VARIABLE_SYNTAX)
|
94
|
-
partial = context.registers[:site]
|
100
|
+
partial = context.registers[:site]
|
101
|
+
.liquid_renderer
|
102
|
+
.file("(variable)")
|
103
|
+
.parse(@file)
|
95
104
|
partial.render!(context)
|
96
105
|
end
|
97
106
|
end
|
@@ -106,9 +115,9 @@ eos
|
|
106
115
|
path = File.join(dir, file)
|
107
116
|
return path if valid_include_file?(path, dir, safe)
|
108
117
|
end
|
109
|
-
raise IOError, "Could not locate the included file '#{file}' in any of
|
110
|
-
" Ensure it exists in one of those directories and,
|
111
|
-
"does not point outside your site source."
|
118
|
+
raise IOError, "Could not locate the included file '#{file}' in any of "\
|
119
|
+
"#{includes_dirs}. Ensure it exists in one of those directories and, "\
|
120
|
+
"if it is a symlink, does not point outside your site source."
|
112
121
|
end
|
113
122
|
|
114
123
|
def render(context)
|
@@ -120,24 +129,23 @@ eos
|
|
120
129
|
path = locate_include_file(context, file, site.safe)
|
121
130
|
return unless path
|
122
131
|
|
123
|
-
|
132
|
+
add_include_to_dependency(site, path, context)
|
133
|
+
|
134
|
+
partial = load_cached_partial(path, context)
|
135
|
+
|
136
|
+
context.stack do
|
137
|
+
context["include"] = parse_params(context) if @params
|
138
|
+
partial.render!(context)
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
def add_include_to_dependency(site, path, context)
|
124
143
|
if context.registers[:page] && context.registers[:page].key?("path")
|
125
144
|
site.regenerator.add_dependency(
|
126
145
|
site.in_source_dir(context.registers[:page]["path"]),
|
127
146
|
path
|
128
147
|
)
|
129
148
|
end
|
130
|
-
|
131
|
-
#begin
|
132
|
-
partial = load_cached_partial(path, context)
|
133
|
-
|
134
|
-
context.stack do
|
135
|
-
context['include'] = parse_params(context) if @params
|
136
|
-
partial.render!(context)
|
137
|
-
end
|
138
|
-
#rescue => e
|
139
|
-
#raise IncludeTagError.new e.message, path
|
140
|
-
#end
|
141
149
|
end
|
142
150
|
|
143
151
|
def load_cached_partial(path, context)
|
@@ -147,7 +155,10 @@ eos
|
|
147
155
|
if cached_partial.key?(path)
|
148
156
|
cached_partial[path]
|
149
157
|
else
|
150
|
-
cached_partial[path] = context.registers[:site]
|
158
|
+
cached_partial[path] = context.registers[:site]
|
159
|
+
.liquid_renderer
|
160
|
+
.file(path)
|
161
|
+
.parse(read_file(path, context))
|
151
162
|
end
|
152
163
|
end
|
153
164
|
|
@@ -188,5 +199,5 @@ eos
|
|
188
199
|
end
|
189
200
|
end
|
190
201
|
|
191
|
-
Liquid::Template.register_tag(
|
192
|
-
Liquid::Template.register_tag(
|
202
|
+
Liquid::Template.register_tag("include", Bunto::Tags::IncludeTag)
|
203
|
+
Liquid::Template.register_tag("include_relative", Bunto::Tags::IncludeRelativeTag)
|
data/lib/bunto/tags/link.rb
CHANGED
@@ -1,7 +1,11 @@
|
|
1
1
|
module Bunto
|
2
2
|
module Tags
|
3
3
|
class Link < Liquid::Tag
|
4
|
-
|
4
|
+
class << self
|
5
|
+
def tag_name
|
6
|
+
self.name.split("::").last.downcase
|
7
|
+
end
|
8
|
+
end
|
5
9
|
|
6
10
|
def initialize(tag_name, relative_path, tokens)
|
7
11
|
super
|
@@ -16,11 +20,14 @@ module Bunto
|
|
16
20
|
return document.url if document.relative_path == @relative_path
|
17
21
|
end
|
18
22
|
|
19
|
-
raise ArgumentError,
|
20
|
-
|
23
|
+
raise ArgumentError, <<eos
|
24
|
+
Could not find document '#{@relative_path}' in tag '#{self.class.tag_name}'.
|
25
|
+
|
26
|
+
Make sure the document exists and the path is correct.
|
27
|
+
eos
|
21
28
|
end
|
22
29
|
end
|
23
30
|
end
|
24
31
|
end
|
25
32
|
|
26
|
-
Liquid::Template.register_tag(Bunto::Tags::Link
|
33
|
+
Liquid::Template.register_tag(Bunto::Tags::Link.tag_name, Bunto::Tags::Link)
|
data/lib/bunto/tags/post_url.rb
CHANGED
@@ -1,20 +1,20 @@
|
|
1
1
|
module Bunto
|
2
2
|
module Tags
|
3
3
|
class PostComparer
|
4
|
-
MATCHER =
|
4
|
+
MATCHER = %r!^(.+/)*(\d+-\d+-\d+)-(.*)$!
|
5
5
|
|
6
6
|
attr_reader :path, :date, :slug, :name
|
7
7
|
|
8
8
|
def initialize(name)
|
9
9
|
@name = name
|
10
10
|
|
11
|
-
all, @path, @date, @slug = *name.sub(
|
11
|
+
all, @path, @date, @slug = *name.sub(%r!^/!, "").match(MATCHER)
|
12
12
|
unless all
|
13
13
|
raise Bunto::Errors::InvalidPostNameError,
|
14
14
|
"'#{name}' does not contain valid date and/or title."
|
15
15
|
end
|
16
16
|
|
17
|
-
@name_regex =
|
17
|
+
@name_regex = %r!^#{path}#{date}-#{slug}\.[^.]+!
|
18
18
|
end
|
19
19
|
|
20
20
|
def post_date
|
@@ -42,9 +42,9 @@ module Bunto
|
|
42
42
|
def post_slug(other)
|
43
43
|
path = other.basename.split("/")[0...-1].join("/")
|
44
44
|
if path.nil? || path == ""
|
45
|
-
other.data[
|
45
|
+
other.data["slug"]
|
46
46
|
else
|
47
|
-
path +
|
47
|
+
path + "/" + other.data["slug"]
|
48
48
|
end
|
49
49
|
end
|
50
50
|
end
|
@@ -78,7 +78,8 @@ eos
|
|
78
78
|
|
79
79
|
site.posts.docs.each do |p|
|
80
80
|
next unless @post.deprecated_equality p
|
81
|
-
Bunto::Deprecator.deprecation_message "A call to
|
81
|
+
Bunto::Deprecator.deprecation_message "A call to "\
|
82
|
+
"'{{ post_url #{@post.name} }}' did not match " \
|
82
83
|
"a post using the new matching method of checking name " \
|
83
84
|
"(path-date-slug) equality. Please make sure that you " \
|
84
85
|
"change this tag to match the post's name exactly."
|
@@ -95,4 +96,4 @@ eos
|
|
95
96
|
end
|
96
97
|
end
|
97
98
|
|
98
|
-
Liquid::Template.register_tag(
|
99
|
+
Liquid::Template.register_tag("post_url", Bunto::Tags::PostUrl)
|
data/lib/bunto/theme.rb
CHANGED
@@ -10,7 +10,11 @@ module Bunto
|
|
10
10
|
end
|
11
11
|
|
12
12
|
def root
|
13
|
-
|
13
|
+
# Must use File.realpath to resolve symlinks created by rbenv
|
14
|
+
# Otherwise, Bunto.sanitized path with prepend the unresolved root
|
15
|
+
@root ||= File.realpath(gemspec.full_gem_path)
|
16
|
+
rescue Errno::ENOENT, Errno::EACCES, Errno::ELOOP
|
17
|
+
nil
|
14
18
|
end
|
15
19
|
|
16
20
|
def includes_path
|
@@ -27,18 +31,15 @@ module Bunto
|
|
27
31
|
|
28
32
|
def configure_sass
|
29
33
|
return unless sass_path
|
30
|
-
require
|
34
|
+
require "sass"
|
31
35
|
Sass.load_paths << sass_path
|
32
36
|
end
|
33
37
|
|
34
38
|
private
|
35
39
|
|
36
40
|
def path_for(folder)
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
path = Bunto.sanitized_path(root, resolved_dir)
|
41
|
-
path if Dir.exists?(path)
|
41
|
+
path = realpath_for(folder)
|
42
|
+
path if path && File.directory?(path)
|
42
43
|
end
|
43
44
|
|
44
45
|
def realpath_for(folder)
|
@@ -50,7 +51,8 @@ module Bunto
|
|
50
51
|
def gemspec
|
51
52
|
@gemspec ||= Gem::Specification.find_by_name(name)
|
52
53
|
rescue Gem::LoadError
|
53
|
-
raise Bunto::Errors::MissingDependencyException,
|
54
|
+
raise Bunto::Errors::MissingDependencyException,
|
55
|
+
"The #{name} theme could not be found."
|
54
56
|
end
|
55
57
|
end
|
56
58
|
end
|
@@ -0,0 +1,117 @@
|
|
1
|
+
class Bunto::ThemeBuilder
|
2
|
+
SCAFFOLD_DIRECTORIES = %w(
|
3
|
+
_layouts _includes _sass
|
4
|
+
).freeze
|
5
|
+
|
6
|
+
attr_reader :name, :path, :code_of_conduct
|
7
|
+
|
8
|
+
def initialize(theme_name, opts)
|
9
|
+
@name = theme_name.to_s.tr(" ", "_").gsub(%r!_+!, "_")
|
10
|
+
@path = Pathname.new(File.expand_path(name, Dir.pwd))
|
11
|
+
@code_of_conduct = !!opts["code_of_conduct"]
|
12
|
+
end
|
13
|
+
|
14
|
+
def create!
|
15
|
+
create_directories
|
16
|
+
create_starter_files
|
17
|
+
create_gemspec
|
18
|
+
create_accessories
|
19
|
+
initialize_git_repo
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def root
|
25
|
+
@root ||= Pathname.new(File.expand_path("../", __dir__))
|
26
|
+
end
|
27
|
+
|
28
|
+
def template_file(filename)
|
29
|
+
[
|
30
|
+
root.join("theme_template", "#{filename}.erb"),
|
31
|
+
root.join("theme_template", filename.to_s)
|
32
|
+
].find(&:exist?)
|
33
|
+
end
|
34
|
+
|
35
|
+
def template(filename)
|
36
|
+
erb.render(template_file(filename).read)
|
37
|
+
end
|
38
|
+
|
39
|
+
def erb
|
40
|
+
@erb ||= ERBRenderer.new(self)
|
41
|
+
end
|
42
|
+
|
43
|
+
def mkdir_p(directories)
|
44
|
+
Array(directories).each do |directory|
|
45
|
+
full_path = path.join(directory)
|
46
|
+
Bunto.logger.info "create", full_path.to_s
|
47
|
+
FileUtils.mkdir_p(full_path)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def write_file(filename, contents)
|
52
|
+
full_path = path.join(filename)
|
53
|
+
Bunto.logger.info "create", full_path.to_s
|
54
|
+
File.write(full_path, contents)
|
55
|
+
end
|
56
|
+
|
57
|
+
def create_directories
|
58
|
+
mkdir_p(SCAFFOLD_DIRECTORIES)
|
59
|
+
end
|
60
|
+
|
61
|
+
def create_starter_files
|
62
|
+
%w(page post default).each do |layout|
|
63
|
+
write_file("_layouts/#{layout}.html", template("_layouts/#{layout}.html"))
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def create_gemspec
|
68
|
+
write_file("Gemfile", template("Gemfile"))
|
69
|
+
write_file("#{name}.gemspec", template("theme.gemspec"))
|
70
|
+
end
|
71
|
+
|
72
|
+
def create_accessories
|
73
|
+
accessories = %w(README.md LICENSE.txt)
|
74
|
+
accessories << "CODE_OF_CONDUCT.md" if code_of_conduct
|
75
|
+
accessories.each do |filename|
|
76
|
+
write_file(filename, template(filename))
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
def initialize_git_repo
|
81
|
+
Bunto.logger.info "initialize", path.join(".git").to_s
|
82
|
+
Dir.chdir(path.to_s) { `git init` }
|
83
|
+
write_file(".gitignore", template("gitignore"))
|
84
|
+
end
|
85
|
+
|
86
|
+
def user_name
|
87
|
+
@user_name ||= `git config user.name`.chomp
|
88
|
+
end
|
89
|
+
|
90
|
+
def user_email
|
91
|
+
@user_email ||= `git config user.email`.chomp
|
92
|
+
end
|
93
|
+
|
94
|
+
class ERBRenderer
|
95
|
+
extend Forwardable
|
96
|
+
|
97
|
+
def_delegator :@theme_builder, :name, :theme_name
|
98
|
+
def_delegator :@theme_builder, :user_name, :user_name
|
99
|
+
def_delegator :@theme_builder, :user_email, :user_email
|
100
|
+
|
101
|
+
def initialize(theme_builder)
|
102
|
+
@theme_builder = theme_builder
|
103
|
+
end
|
104
|
+
|
105
|
+
def bunto_version_with_minor
|
106
|
+
Bunto::VERSION.split(".").take(2).join(".")
|
107
|
+
end
|
108
|
+
|
109
|
+
def theme_directories
|
110
|
+
SCAFFOLD_DIRECTORIES
|
111
|
+
end
|
112
|
+
|
113
|
+
def render(contents)
|
114
|
+
ERB.new(contents).result binding
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|