jekyll-asciidoc 1.1.2 → 2.0.0

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.
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