bunto 3.0.0 → 3.2.1
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/.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
|