jekyll-asciidoc 1.1.2 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/Rakefile CHANGED
@@ -2,6 +2,15 @@ require 'rake/clean'
2
2
 
3
3
  default_tasks = []
4
4
 
5
+ begin
6
+ require 'rspec/core/rake_task'
7
+ RSpec::Core::RakeTask.new(:spec) do |t|
8
+ t.rspec_opts = ['-c']
9
+ end
10
+ default_tasks << :spec
11
+ rescue LoadError
12
+ end
13
+
5
14
  begin
6
15
  require 'bundler/gem_tasks'
7
16
  default_tasks << :build
@@ -9,7 +18,7 @@ rescue LoadError
9
18
  warn 'jekyll-asciidoc: Bundler is required to build this gem.
10
19
  You can install Bundler using the `gem install` command:
11
20
 
12
- $ gem install bundler' + %(\n\n)
21
+ $ [sudo] gem install bundler' + %(\n\n)
13
22
  end
14
23
 
15
24
  task :default => default_tasks unless default_tasks.empty?
@@ -1,151 +1,6 @@
1
- JEKYLL_MIN_VERSION_3 = Gem::Version.new(Jekyll::VERSION) >= Gem::Version.new('3.0.0') unless defined? JEKYLL_MIN_VERSION_3
2
-
3
- module Jekyll
4
- module Converters
5
- class AsciiDocConverter < Converter
6
- IMPLICIT_ATTRIBUTES = %W(
7
- env=site env-site site-gen=jekyll site-gen-jekyll builder=jekyll builder-jekyll jekyll-version=#{Jekyll::VERSION}
8
- )
9
-
10
- safe true
11
-
12
- highlighter_prefix "\n"
13
- highlighter_suffix "\n"
14
-
15
- def initialize(config)
16
- @config = config
17
- config['asciidoc'] ||= 'asciidoctor'
18
- asciidoc_ext = (config['asciidoc_ext'] ||= 'asciidoc,adoc,ad')
19
- config['asciidoc_ext_re'] = Regexp.new("\.(#{asciidoc_ext.tr ',', '|'})$", Regexp::IGNORECASE)
20
- config['asciidoc_page_attribute_prefix'] ||= 'page'
21
- unless (asciidoctor_config = (config['asciidoctor'] ||= {})).frozen?
22
- # NOTE convert keys to symbols
23
- asciidoctor_config.keys.each do |key|
24
- asciidoctor_config[key.to_sym] = asciidoctor_config.delete(key)
25
- end
26
- asciidoctor_config[:safe] ||= 'safe'
27
- (asciidoctor_config[:attributes] ||= []).tap do |attributes|
28
- attributes.unshift('notitle', 'hardbreaks', 'idprefix', 'idseparator=-', 'linkattrs')
29
- attributes.concat(IMPLICIT_ATTRIBUTES)
30
- end
31
- asciidoctor_config.freeze
32
- end
33
- end
34
-
35
- def setup
36
- return if @setup
37
- @setup = true
38
- case @config['asciidoc']
39
- when 'asciidoctor'
40
- begin
41
- require 'asciidoctor' unless defined? ::Asciidoctor
42
- rescue LoadError
43
- STDERR.puts 'You are missing a library required to convert AsciiDoc files. Please run:'
44
- STDERR.puts ' $ [sudo] gem install asciidoctor'
45
- raise FatalException.new('Missing dependency: asciidoctor')
46
- end
47
- else
48
- STDERR.puts "Invalid AsciiDoc processor: #{@config['asciidoc']}"
49
- STDERR.puts ' Valid options are [ asciidoctor ]'
50
- raise FatalException.new("Invalid AsciiDoc processor: #{@config['asciidoc']}")
51
- end
52
- end
53
-
54
- def matches(ext)
55
- ext =~ @config['asciidoc_ext_re']
56
- end
57
-
58
- def output_ext(ext)
59
- '.html'
60
- end
61
-
62
- def convert(content)
63
- setup
64
- case @config['asciidoc']
65
- when 'asciidoctor'
66
- Asciidoctor.convert(content, @config['asciidoctor'])
67
- else
68
- warn 'Unknown AsciiDoc converter. Passing through raw content.'
69
- content
70
- end
71
- end
72
-
73
- def load_header(content)
74
- setup
75
- case @config['asciidoc']
76
- when 'asciidoctor'
77
- Asciidoctor.load(content, parse_header_only: true)
78
- else
79
- warn 'Unknown AsciiDoc converter. Cannot load document header.'
80
- nil
81
- end
82
- end
83
- end
84
- end
85
-
86
- module Generators
87
- # Promotes select AsciiDoc attributes to Jekyll front matter
88
- class AsciiDocPreprocessor < Generator
89
- def generate(site)
90
- asciidoc_converter = JEKYLL_MIN_VERSION_3 ?
91
- site.find_converter_instance(Jekyll::Converters::AsciiDocConverter) :
92
- site.getConverterImpl(Jekyll::Converters::AsciiDocConverter)
93
- asciidoc_converter.setup
94
- unless (page_attr_prefix = site.config['asciidoc_page_attribute_prefix']).empty?
95
- page_attr_prefix = %(#{page_attr_prefix}-)
96
- end
97
- page_attr_prefix_l = page_attr_prefix.length
98
-
99
- site.pages.each do |page|
100
- if asciidoc_converter.matches(page.ext)
101
- next unless (doc = asciidoc_converter.load_header(page.content))
102
-
103
- page.data['title'] = doc.doctitle if doc.header?
104
- page.data['author'] = doc.author if doc.author
105
-
106
- unless (adoc_front_matter = doc.attributes
107
- .select {|name| name.start_with?(page_attr_prefix) }
108
- .map {|name, val| %(#{name[page_attr_prefix_l..-1]}: #{val}) }).empty?
109
- page.data.update(SafeYAML.load(adoc_front_matter * "\n"))
110
- end
111
-
112
- page.data['layout'] = 'default' unless page.data.key? 'layout'
113
- end
114
- end
115
-
116
- (JEKYLL_MIN_VERSION_3 ? site.posts.docs : site.posts).each do |post|
117
- if asciidoc_converter.matches(JEKYLL_MIN_VERSION_3 ? post.data['ext'] : post.ext)
118
- next unless (doc = asciidoc_converter.load_header(post.content))
119
-
120
- post.data['title'] = doc.doctitle if doc.header?
121
- post.data['author'] = doc.author if doc.author
122
- post.data['date'] = DateTime.parse(doc.revdate).to_time if doc.attr? 'revdate'
123
-
124
- unless (adoc_front_matter = doc.attributes
125
- .select {|name| name.start_with?(page_attr_prefix) }
126
- .map {|name, val| %(#{name[page_attr_prefix_l..-1]}: #{val}) }).empty?
127
- post.data.update(SafeYAML.load(adoc_front_matter * "\n"))
128
- end
129
-
130
- post.data['layout'] = 'post' unless post.data.key? 'layout'
131
- end
132
- end
133
- end
134
- end
135
- end
136
-
137
- module Filters
138
- # Convert an AsciiDoc string into HTML output.
139
- #
140
- # input - The AsciiDoc String to convert.
141
- #
142
- # Returns the HTML formatted String.
143
- def asciidocify(input)
144
- site = @context.registers[:site]
145
- converter = JEKYLL_MIN_VERSION_3 ?
146
- site.find_converter_instance(Jekyll::Converters::AsciiDocConverter) :
147
- site.getConverterImpl(Jekyll::Converters::AsciiDocConverter)
148
- converter.convert(input)
149
- end
150
- end
151
- end
1
+ require_relative 'jekyll-asciidoc/compat'
2
+ require_relative 'jekyll-asciidoc/utils'
3
+ require_relative 'jekyll-asciidoc/mixins'
4
+ require_relative 'jekyll-asciidoc/converter'
5
+ require_relative 'jekyll-asciidoc/integrator'
6
+ require_relative 'jekyll-asciidoc/filters'
@@ -0,0 +1,14 @@
1
+ module Jekyll
2
+ module AsciiDoc
3
+ Jekyll3Compatible = (::Gem::Version.new ::Jekyll::VERSION) >= (::Gem::Version.new '3.0.0')
4
+ end
5
+ end
6
+
7
+ module Jekyll
8
+ class Site
9
+ # Backport {::Jekyll::Site#find_converter_instance} to Jekyll 2.
10
+ def find_converter_instance klass
11
+ @converters.find {|candidate| klass === candidate } || raise(%(No Converters found for #{klass}))
12
+ end unless respond_to? :find_converter_instance
13
+ end
14
+ end
@@ -0,0 +1,218 @@
1
+ module Jekyll
2
+ module AsciiDoc
3
+ class Converter < ::Jekyll::Converter
4
+ DefaultAttributes = {
5
+ 'idprefix' => '',
6
+ 'idseparator' => '-',
7
+ 'linkattrs' => '@'
8
+ }
9
+ DefaultFileExtensions = %w(asciidoc adoc ad)
10
+ DefaultPageAttributePrefix = 'page'
11
+ ImplicitAttributes = {
12
+ 'env' => 'site',
13
+ 'env-site' => '',
14
+ 'site-gen' => 'jekyll',
15
+ 'site-gen-jekyll' => '',
16
+ 'builder' => 'jekyll',
17
+ 'builder-jekyll' => '',
18
+ 'jekyll-version' => ::Jekyll::VERSION
19
+ }
20
+ MessageTopic = 'Jekyll AsciiDoc:'
21
+ StandaloneOptionLine = Utils::StandaloneOptionLine
22
+
23
+ HeaderBoundaryRx = /(?<=\p{Graph})#{Utils::NewLine * 2}/
24
+
25
+ # Enable plugin when running in safe mode
26
+ # jekyll-asciidoc gem must also be declared in whitelist
27
+ safe true
28
+
29
+ # highlighter prefix/suffix not used by this plugin; defined only to avoid warning
30
+ highlighter_prefix nil
31
+ highlighter_suffix nil
32
+
33
+ def initialize config
34
+ @config = config
35
+ @logger = ::Jekyll.logger
36
+ @path_info = nil
37
+ @setup = false
38
+
39
+ # NOTE jekyll-watch reinitializes plugins using a shallow clone of config, so no need to reconfigure
40
+ # NOTE check for Configured only works if value of key is defined in _config.yml as Hash
41
+ unless Configured === (asciidoc_config = (config['asciidoc'] ||= {}))
42
+ if ::String === asciidoc_config
43
+ @logger.warn MessageTopic, 'The AsciiDoc configuration should be defined as Hash under asciidoc key instead of as discrete entries.'
44
+ asciidoc_config = config['asciidoc'] = { 'processor' => asciidoc_config }
45
+ else
46
+ asciidoc_config['processor'] ||= 'asciidoctor'
47
+ end
48
+ old_asciidoc_ext = config.delete 'asciidoc_ext'
49
+ asciidoc_ext = (asciidoc_config['ext'] ||= (old_asciidoc_ext || (DefaultFileExtensions * ',')))
50
+ asciidoc_ext_re = asciidoc_config['ext_re'] = /^\.(?:#{asciidoc_ext.tr ',', '|'})$/ix
51
+ old_page_attr_prefix_def = config.key? 'asciidoc_page_attribute_prefix'
52
+ old_page_attr_prefix_val = config.delete 'asciidoc_page_attribute_prefix'
53
+ unless (page_attr_prefix = asciidoc_config['page_attribute_prefix'])
54
+ page_attr_prefix = old_page_attr_prefix_def ? (old_page_attr_prefix_val || '') :
55
+ ((asciidoc_config.key? 'page_attribute_prefix') ? '' : DefaultPageAttributePrefix)
56
+ end
57
+ asciidoc_config['page_attribute_prefix'] = page_attr_prefix.chomp '-'
58
+ asciidoc_config['require_front_matter_header'] = !!asciidoc_config['require_front_matter_header']
59
+ asciidoc_config.extend Configured
60
+
61
+ begin
62
+ if (dlg_method = Utils.method :has_yaml_header?) && asciidoc_config['require_front_matter_header']
63
+ if (::Jekyll::Utils.method dlg_method.name).arity == -1 # not original method
64
+ ::Jekyll::Utils.define_singleton_method dlg_method.name, &dlg_method
65
+ end
66
+ else
67
+ unless (new_method = dlg_method.owner.method :has_front_matter?).respond_to? :curry
68
+ new_method = new_method.to_proc # Ruby < 2.2
69
+ end
70
+ ::Jekyll::Utils.define_singleton_method dlg_method.name, new_method.curry[dlg_method][asciidoc_ext_re]
71
+ end
72
+ rescue ::NameError; end
73
+ end
74
+
75
+ if (@asciidoc_config = asciidoc_config)['processor'] == 'asciidoctor'
76
+ unless Configured === (@asciidoctor_config = (config['asciidoctor'] ||= {}))
77
+ asciidoctor_config = @asciidoctor_config
78
+ asciidoctor_config.replace Utils.symbolize_keys asciidoctor_config
79
+ source = ::File.expand_path config['source']
80
+ dest = ::File.expand_path config['destination']
81
+ case (base = asciidoctor_config[:base_dir])
82
+ when ':source'
83
+ asciidoctor_config[:base_dir] = source
84
+ when ':docdir'
85
+ if defined? ::Jekyll::Hooks
86
+ asciidoctor_config[:base_dir] = :docdir
87
+ else
88
+ @logger.warn MessageTopic, 'Using :docdir as value of base_dir option requires Jekyll 3. Falling back to source directory.'
89
+ asciidoctor_config[:base_dir] = source
90
+ end
91
+ else
92
+ asciidoctor_config[:base_dir] = ::File.expand_path base if base
93
+ end
94
+ asciidoctor_config[:safe] ||= 'safe'
95
+ site_attributes = {
96
+ 'site-root' => ::Dir.pwd,
97
+ 'site-source' => source,
98
+ 'site-destination' => dest,
99
+ 'site-baseurl' => config['baseurl'],
100
+ 'site-url' => config['url']
101
+ }
102
+ attrs = asciidoctor_config[:attributes] = Utils.hashify_attributes asciidoctor_config[:attributes],
103
+ ((site_attributes.merge ImplicitAttributes).merge DefaultAttributes)
104
+ if (imagesdir = attrs['imagesdir']) && !(attrs.key? 'imagesoutdir') && (imagesdir.start_with? '/')
105
+ attrs['imagesoutdir'] = ::File.join dest, imagesdir
106
+ end
107
+ asciidoctor_config.extend Configured
108
+ end
109
+ end
110
+ end
111
+
112
+ def setup
113
+ return self if @setup
114
+ @setup = true
115
+ case @asciidoc_config['processor']
116
+ when 'asciidoctor'
117
+ begin
118
+ require 'asciidoctor' unless defined? ::Asciidoctor::VERSION
119
+ rescue ::LoadError
120
+ @logger.error MessageTopic, 'You are missing a library required to convert AsciiDoc files. Please install using:'
121
+ @logger.error '', '$ [sudo] gem install asciidoctor'
122
+ @logger.abort_with 'Bailing out; missing required dependency: asciidoctor'
123
+ end
124
+ else
125
+ @logger.error MessageTopic, %(Invalid AsciiDoc processor given: #{@asciidoc_config['processor']})
126
+ @logger.error '', 'Valid options are: asciidoctor'
127
+ @logger.abort_with 'Bailing out; invalid Asciidoctor processor.'
128
+ end
129
+ self
130
+ end
131
+
132
+ def matches ext
133
+ ext =~ @asciidoc_config['ext_re']
134
+ end
135
+
136
+ def output_ext ext
137
+ '.html'
138
+ end
139
+
140
+ def before_render document, payload
141
+ record_path_info document if Document === document
142
+ end
143
+
144
+ def after_render document
145
+ clear_path_info if Document === document
146
+ end
147
+
148
+ def record_path_info document, opts = {}
149
+ @path_info = {
150
+ 'docfile' => (docfile = ::File.join document.site.source, document.relative_path),
151
+ 'docdir' => (::File.dirname docfile),
152
+ 'docname' => (::File.basename docfile, (::File.extname docfile))
153
+ }
154
+ unless opts[:source_only]
155
+ @path_info.update({
156
+ 'outfile' => (outfile = document.destination document.site.dest),
157
+ 'outdir' => (::File.dirname outfile),
158
+ 'outpath' => document.url
159
+ })
160
+ end
161
+ end
162
+
163
+ def clear_path_info
164
+ @path_info = nil
165
+ end
166
+
167
+ def load_header document
168
+ setup
169
+ record_path_info document, source_only: true if defined? ::Jekyll::Hooks
170
+ # NOTE merely an optimization; if this doesn't match, the header still gets isolated by the processor
171
+ header = (document.content.split HeaderBoundaryRx, 2)[0]
172
+ case @asciidoc_config['processor']
173
+ when 'asciidoctor'
174
+ opts = @asciidoctor_config.merge parse_header_only: true
175
+ if @path_info
176
+ if opts[:base_dir] == :docdir
177
+ opts[:base_dir] = @path_info['docdir'] # NOTE this assignment happens inside the processor anyway
178
+ else
179
+ @path_info.delete 'docdir'
180
+ end
181
+ opts[:attributes] = opts[:attributes].merge @path_info
182
+ end
183
+ # NOTE return instance even if header is empty since attributes may be inherited from config
184
+ doc = ::Asciidoctor.load header, opts
185
+ else
186
+ @logger.warn MessageTopic, %(Unknown AsciiDoc processor: #{@asciidoc_config['processor']}. Cannot load document header.)
187
+ doc = nil
188
+ end
189
+ clear_path_info if defined? ::Jekyll::Hooks
190
+ doc
191
+ end
192
+
193
+ def convert content
194
+ return '' if content.nil_or_empty?
195
+ setup
196
+ if (standalone = content.start_with? StandaloneOptionLine)
197
+ content = content[StandaloneOptionLine.length..-1]
198
+ end
199
+ case @asciidoc_config['processor']
200
+ when 'asciidoctor'
201
+ opts = @asciidoctor_config.merge header_footer: standalone
202
+ if @path_info
203
+ if opts[:base_dir] == :docdir
204
+ opts[:base_dir] = @path_info['docdir'] # NOTE this assignment happens inside the processor anyway
205
+ else
206
+ @path_info.delete 'docdir'
207
+ end
208
+ opts[:attributes] = opts[:attributes].merge @path_info
209
+ end
210
+ ::Asciidoctor.convert content, opts
211
+ else
212
+ @logger.warn MessageTopic, %(Unknown AsciiDoc processor: #{@asciidoc_config['processor']}. Passing through unparsed content.)
213
+ content
214
+ end
215
+ end
216
+ end
217
+ end
218
+ end
@@ -0,0 +1,18 @@
1
+ module Jekyll
2
+ module AsciiDoc
3
+ module Filters
4
+ # A Liquid filter for converting an AsciiDoc string to HTML.
5
+ #
6
+ # input - The AsciiDoc String to convert.
7
+ # doctype - The target AsciiDoc doctype (optional, default: nil).
8
+ #
9
+ # Returns the HTML formatted String.
10
+ def asciidocify input, doctype = nil
11
+ (@context.registers[:cached_asciidoc_converter] ||= (Utils.get_converter @context.registers[:site]))
12
+ .convert(doctype ? %(:doctype: #{doctype}#{Utils::NewLine}#{input}) : (input || ''))
13
+ end
14
+ end
15
+
16
+ ::Liquid::Template.register_filter Filters
17
+ end
18
+ end
@@ -0,0 +1,119 @@
1
+ module Jekyll
2
+ module AsciiDoc
3
+ # Registers before and after render hooks to set contextual attributes,
4
+ # promotes eligible AsciiDoc attributes to page variables, and applies
5
+ # certain page-level settings.
6
+ class Integrator < ::Jekyll::Generator
7
+ NewLine = Utils::NewLine
8
+ StandaloneOptionLine = Utils::StandaloneOptionLine
9
+
10
+ # Enable plugin when running in safe mode
11
+ # jekyll-asciidoc gem must also be declared in whitelist
12
+ safe true
13
+
14
+ def generate site
15
+ @converter = converter = (Utils.get_converter site).setup
16
+
17
+ if defined? ::Jekyll::Hooks
18
+ before_render_callback = converter.method :before_render
19
+ after_render_callback = converter.method :after_render
20
+ [:pages, :documents].each do |collection_name|
21
+ ::Jekyll::Hooks.register collection_name, :pre_render, &before_render_callback
22
+ ::Jekyll::Hooks.register collection_name, :post_render, &after_render_callback
23
+ end
24
+ end
25
+
26
+ unless (@page_attr_prefix = site.config['asciidoc']['page_attribute_prefix']).empty?
27
+ @page_attr_prefix = %(#{@page_attr_prefix}-)
28
+ end
29
+
30
+ site.pages.select! do |page|
31
+ (converter.matches page.ext) ? (integrate page) : true
32
+ end
33
+
34
+ # NOTE posts were migrated to a collection named 'posts' in Jekyll 3
35
+ site.posts.select! do |post|
36
+ (converter.matches post.ext) ? (integrate post, 'posts') : true
37
+ end if site.respond_to? :posts=
38
+
39
+ site.collections.each do |name, collection|
40
+ next unless collection.write?
41
+ collection.docs.select! do |doc|
42
+ (converter.matches doc.extname) ? (integrate doc, name) : true
43
+ end
44
+ end
45
+
46
+ if (attrs = site.config['asciidoctor'][:attributes]) &&
47
+ ((attrs['source-highlighter'] || '').chomp '@') == 'pygments' &&
48
+ ((attrs['pygments-css'] || '').chomp '@') != 'style' && (attrs.fetch 'pygments-stylesheet', '')
49
+ generate_pygments_stylesheet site, attrs
50
+ end
51
+ end
52
+
53
+ # Integrate the page-related attributes from the AsciiDoc document header
54
+ # into the data Array of the specified {::Jekyll::Page}, {::Jekyll::Post}
55
+ # or {::Jekyll::Document}.
56
+ #
57
+ # document - the Page, Post or Document instance to integrate.
58
+ # collection_name - the String name of the collection to which this
59
+ # document belongs (optional, default: nil).
60
+ #
61
+ # Returns a [Boolean] indicating whether the document should be published.
62
+ def integrate document, collection_name = nil
63
+ document.extend Document
64
+ document.content = [%(:#{@page_attr_prefix}layout: _auto), document.content] * NewLine unless document.data.key? 'layout'
65
+ return unless (doc = @converter.load_header document)
66
+
67
+ document.data['title'] = doc.doctitle if doc.header?
68
+ document.data['author'] = doc.author if doc.author
69
+ document.data['date'] = (::DateTime.parse doc.revdate).to_time if collection_name == 'posts' && (doc.attr? 'revdate')
70
+
71
+ no_prefix = (prefix_size = @page_attr_prefix.length).zero?
72
+ unless (adoc_header_data = doc.attributes
73
+ .each_with_object({}) {|(key, val), accum|
74
+ if no_prefix || ((key.start_with? @page_attr_prefix) && key = key[prefix_size..-1])
75
+ accum[key] = ::String === val ? (Utils.parse_yaml_value val) : val
76
+ end
77
+ }).empty?
78
+ document.data.update adoc_header_data
79
+ end
80
+
81
+ case document.data['layout']
82
+ when nil
83
+ document.content = %(#{StandaloneOptionLine}#{document.content}) unless document.data.key? 'layout'
84
+ when '', '_auto'
85
+ layout = collection_name ? (collection_name.chomp 's') : 'page'
86
+ document.data['layout'] = (document.site.layouts.key? layout) ? layout : 'default'
87
+ when false
88
+ document.data.delete 'layout'
89
+ document.content = %(#{StandaloneOptionLine}#{document.content})
90
+ end
91
+
92
+ document.extend NoLiquid unless document.data['liquid']
93
+ document.data.fetch 'published', true
94
+ end
95
+
96
+ def generate_pygments_stylesheet site, attrs
97
+ css_base = site.source
98
+ unless (css_dir = (attrs['stylesdir'] || '').chomp '@').empty? || (css_dir.start_with? '/')
99
+ css_dir = %(/#{css_dir})
100
+ end
101
+ if (css_name = attrs['pygments-stylesheet']).nil_or_empty?
102
+ css_name = 'asciidoc-pygments.css'
103
+ end
104
+ css_file = ::File.join css_base, css_dir, css_name
105
+ css_style = (attrs['pygments-style'] || 'vs').chomp '@'
106
+ css = ::Asciidoctor::Stylesheets.instance.pygments_stylesheet_data css_style
107
+ # NOTE apply stronger CSS rule for general text color
108
+ css = css.sub '.listingblock .pygments {', '.listingblock .pygments, .listingblock .pygments code {'
109
+ if site.static_files.any? {|f| f.path == css_file }
110
+ ::IO.write css_file, css unless css == (::IO.read css_file)
111
+ else
112
+ ::Asciidoctor::Helpers.mkdir_p ::File.dirname css_file
113
+ ::IO.write css_file, css
114
+ site.static_files << (::Jekyll::StaticFile.new site, css_base, css_dir, css_name)
115
+ end
116
+ end
117
+ end
118
+ end
119
+ end