jekyll-asciidoc 2.1.1 → 3.0.0.beta.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (115) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.adoc +26 -0
  3. data/Gemfile +4 -16
  4. data/LICENSE.adoc +1 -1
  5. data/README.adoc +370 -192
  6. data/jekyll-asciidoc.gemspec +23 -11
  7. data/lib/jekyll-asciidoc/compat.rb +5 -9
  8. data/lib/jekyll-asciidoc/converter.rb +89 -69
  9. data/lib/jekyll-asciidoc/filters.rb +2 -3
  10. data/lib/jekyll-asciidoc/integrator.rb +18 -29
  11. data/lib/jekyll-asciidoc/utils.rb +6 -3
  12. data/lib/jekyll-asciidoc/version.rb +1 -1
  13. metadata +48 -220
  14. data/Rakefile +0 -24
  15. data/spec/fixtures/alternate_page_attribute_prefix/_config.yml +0 -4
  16. data/spec/fixtures/alternate_page_attribute_prefix/_layouts/default.html +0 -12
  17. data/spec/fixtures/alternate_page_attribute_prefix/explicit-permalink.adoc +0 -4
  18. data/spec/fixtures/attributes_as_array/_config.yml +0 -7
  19. data/spec/fixtures/attributes_as_hash/_config.yml +0 -7
  20. data/spec/fixtures/basic_site/_config.yml +0 -2
  21. data/spec/fixtures/basic_site/_layouts/custom.html +0 -15
  22. data/spec/fixtures/basic_site/_layouts/page.html +0 -15
  23. data/spec/fixtures/basic_site/auto-layout.adoc +0 -4
  24. data/spec/fixtures/basic_site/bare-header.adoc +0 -4
  25. data/spec/fixtures/basic_site/custom-layout.adoc +0 -4
  26. data/spec/fixtures/basic_site/docid.adoc +0 -4
  27. data/spec/fixtures/basic_site/empty-layout.adoc +0 -4
  28. data/spec/fixtures/basic_site/empty-page-attribute.adoc +0 -4
  29. data/spec/fixtures/basic_site/liquid-enabled.adoc +0 -6
  30. data/spec/fixtures/basic_site/nil-layout.adoc +0 -4
  31. data/spec/fixtures/basic_site/no-doctitle.adoc +0 -2
  32. data/spec/fixtures/basic_site/no-liquid.adoc +0 -3
  33. data/spec/fixtures/basic_site/not-published.adoc +0 -4
  34. data/spec/fixtures/basic_site/section-with-id-and-role.adoc +0 -6
  35. data/spec/fixtures/basic_site/standalone-a.adoc +0 -4
  36. data/spec/fixtures/basic_site/standalone-b.adoc +0 -4
  37. data/spec/fixtures/basic_site/subdir/page-in-subdir.adoc +0 -7
  38. data/spec/fixtures/basic_site/with-front-matter-header-only.adoc +0 -4
  39. data/spec/fixtures/basic_site/with-front-matter-header.adoc +0 -6
  40. data/spec/fixtures/basic_site/without-front-matter-header.adoc +0 -3
  41. data/spec/fixtures/blank_page_attribute_prefix/_config.yml +0 -4
  42. data/spec/fixtures/blank_page_attribute_prefix/_layouts/default.html +0 -12
  43. data/spec/fixtures/blank_page_attribute_prefix/explicit-permalink.adoc +0 -4
  44. data/spec/fixtures/default_config/_config.yml +0 -2
  45. data/spec/fixtures/explicit_site_time/_config.yml +0 -4
  46. data/spec/fixtures/explicit_site_time/_layouts/default.html +0 -12
  47. data/spec/fixtures/explicit_site_time/home.adoc +0 -3
  48. data/spec/fixtures/fallback_to_default_layout/_blueprints/blueprint.adoc +0 -3
  49. data/spec/fixtures/fallback_to_default_layout/_config.yml +0 -5
  50. data/spec/fixtures/fallback_to_default_layout/_layouts/default.html +0 -15
  51. data/spec/fixtures/fallback_to_default_layout/_posts/2016-01-01-post.adoc +0 -4
  52. data/spec/fixtures/fallback_to_default_layout/home.adoc +0 -3
  53. data/spec/fixtures/front_matter_defaults/_config.yml +0 -10
  54. data/spec/fixtures/front_matter_defaults/_layouts/docs.html +0 -15
  55. data/spec/fixtures/front_matter_defaults/_layouts/general.html +0 -15
  56. data/spec/fixtures/front_matter_defaults/docs/page.adoc +0 -3
  57. data/spec/fixtures/front_matter_defaults/page.adoc +0 -3
  58. data/spec/fixtures/hybrid_config/_config.yml +0 -8
  59. data/spec/fixtures/imagesdir_relative_to_root/_config.yml +0 -5
  60. data/spec/fixtures/include_relative_to_docdir/_config.yml +0 -4
  61. data/spec/fixtures/include_relative_to_docdir/_layouts/default.html +0 -12
  62. data/spec/fixtures/include_relative_to_docdir/about/_people.adoc +0 -2
  63. data/spec/fixtures/include_relative_to_docdir/about/index.adoc +0 -13
  64. data/spec/fixtures/include_relative_to_root/source/_config.yml +0 -2
  65. data/spec/fixtures/include_relative_to_root/source/_layouts/default.html +0 -11
  66. data/spec/fixtures/include_relative_to_root/source/about/_people.adoc +0 -2
  67. data/spec/fixtures/include_relative_to_root/source/about/index.adoc +0 -13
  68. data/spec/fixtures/include_relative_to_source/_config.yml +0 -4
  69. data/spec/fixtures/include_relative_to_source/_layouts/default.html +0 -12
  70. data/spec/fixtures/include_relative_to_source/about/_people.adoc +0 -2
  71. data/spec/fixtures/include_relative_to_source/about/index.adoc +0 -13
  72. data/spec/fixtures/legacy_config/_config.yml +0 -5
  73. data/spec/fixtures/pygments_code_highlighting/_config.yml +0 -6
  74. data/spec/fixtures/pygments_code_highlighting/_layouts/page.html +0 -13
  75. data/spec/fixtures/pygments_code_highlighting/page-with-code.adoc +0 -16
  76. data/spec/fixtures/read_error/_config.yml +0 -2
  77. data/spec/fixtures/read_error/unreadable.adoc +0 -3
  78. data/spec/fixtures/require_front_matter_header/_config.yml +0 -4
  79. data/spec/fixtures/require_front_matter_header/_layouts/default.html +0 -12
  80. data/spec/fixtures/require_front_matter_header/with-front-matter-header.adoc +0 -5
  81. data/spec/fixtures/require_front_matter_header/without-front-matter-header.adoc +0 -3
  82. data/spec/fixtures/safe_mode/_config.yml +0 -4
  83. data/spec/fixtures/safe_mode/_layouts/home.html +0 -15
  84. data/spec/fixtures/safe_mode/home.adoc +0 -5
  85. data/spec/fixtures/tocify_filter/_config.yml +0 -2
  86. data/spec/fixtures/tocify_filter/_layouts/default.html +0 -15
  87. data/spec/fixtures/tocify_filter/index.adoc +0 -25
  88. data/spec/fixtures/with_custom_collection/_blueprints/blueprint-a.adoc +0 -4
  89. data/spec/fixtures/with_custom_collection/_blueprints/blueprint-b.adoc +0 -10
  90. data/spec/fixtures/with_custom_collection/_config.yml +0 -7
  91. data/spec/fixtures/with_custom_collection/_layouts/blueprint.html +0 -15
  92. data/spec/fixtures/with_custom_collection/_layouts/default.html +0 -15
  93. data/spec/fixtures/with_posts/_config.yml +0 -6
  94. data/spec/fixtures/with_posts/_drafts/a-draft-post.adoc +0 -5
  95. data/spec/fixtures/with_posts/_layouts/custom.html +0 -15
  96. data/spec/fixtures/with_posts/_layouts/post.html +0 -23
  97. data/spec/fixtures/with_posts/_posts/2016-01-01-welcome.adoc +0 -4
  98. data/spec/fixtures/with_posts/_posts/2016-01-02-empty-layout.adoc +0 -4
  99. data/spec/fixtures/with_posts/_posts/2016-01-03-auto-layout.adoc +0 -4
  100. data/spec/fixtures/with_posts/_posts/2016-01-04-custom-layout.adoc +0 -4
  101. data/spec/fixtures/with_posts/_posts/2016-01-05-nil-layout.adoc +0 -4
  102. data/spec/fixtures/with_posts/_posts/2016-02-01-post-with-categories.adoc +0 -4
  103. data/spec/fixtures/with_posts/_posts/2016-02-02-post-with-singular-vars.adoc +0 -7
  104. data/spec/fixtures/with_posts/_posts/2016-03-01-post-with-excerpt.adoc +0 -4
  105. data/spec/fixtures/with_posts/_posts/2016-04-01-show-me-the-title.adoc +0 -4
  106. data/spec/fixtures/with_posts/_posts/2016-05-31-automatic-title.adoc +0 -1
  107. data/spec/fixtures/with_posts/_posts/2016-06-15-post-with-date.adoc +0 -4
  108. data/spec/fixtures/with_posts/_posts/2016-07-15-post-with-date-and-tz.adoc +0 -4
  109. data/spec/fixtures/with_posts/_posts/2016-07-20-post-with-date-in-revision-line.adoc +0 -6
  110. data/spec/fixtures/with_posts/index.html +0 -22
  111. data/spec/fixtures/xhtml_syntax/_config.yml +0 -6
  112. data/spec/fixtures/xhtml_syntax/home.adoc +0 -5
  113. data/spec/fixtures/xhtml_syntax/images/sunset.jpg +0 -0
  114. data/spec/jekyll-asciidoc_spec.rb +0 -1103
  115. data/spec/spec_helper.rb +0 -64
@@ -1,30 +1,42 @@
1
- require File.expand_path '../lib/jekyll-asciidoc/version', __FILE__
1
+ require File.absolute_path 'lib/jekyll-asciidoc/version', __dir__
2
+ require 'open3' unless defined? Open3
2
3
 
3
4
  Gem::Specification.new do |s|
4
5
  s.name = 'jekyll-asciidoc'
5
6
  s.version = Jekyll::AsciiDoc::VERSION
6
7
  s.summary = 'A Jekyll plugin that converts the AsciiDoc source files in your site to HTML pages using Asciidoctor.'
7
- s.description = 'A Jekyll plugin that converts the AsciiDoc source files in your site to HTML pages using Asciidoctor.'
8
+ s.description = s.summary
9
+
8
10
  s.authors = ['Dan Allen', 'Paul Rayner']
9
11
  s.email = ['dan.j.allen@gmail.com']
10
12
  s.homepage = 'https://github.com/asciidoctor/jekyll-asciidoc'
11
13
  s.license = 'MIT'
12
- s.required_ruby_version = '>= 1.9.3'
14
+ s.metadata = {
15
+ 'bug_tracker_uri' => 'https://github.com/asciidoctor/jekyll-asciidoc/issues',
16
+ 'changelog_uri' => 'https://github.com/asciidoctor/jekyll-asciidoc/blob/master/CHANGELOG.adoc',
17
+ 'mailing_list_uri' => 'http://discuss.asciidoctor.org',
18
+ 'source_code_uri' => 'https://github.com/asciidoctor/jekyll-asciidoc',
19
+ }
20
+ # NOTE the required ruby version is informational only
21
+ # it tracks the minimum version required by Jekyll >= 3.0.0 (see https://jekyllrb.com/docs/installation/#requirements)
22
+ # we don't enforce it because it can't be overridden and can cause builds to break
23
+ #s.required_ruby_version = '>= 2.2.0'
13
24
 
14
25
  files = begin
15
- output = IO.popen('git ls-files -z', err: File::NULL) {|io| io.read }.split %(\0)
16
- $?.success? ? output : Dir['**/*']
17
- rescue
26
+ (result = Open3.popen3('git ls-files -z') {|_, out| out.read }.split ?\0).empty? ? Dir['**/*'] : result
27
+ rescue ::SystemCallError
18
28
  Dir['**/*']
19
29
  end
20
- s.files = files.grep %r/^(?:lib\/.+|Gemfile|Rakefile|(?:CHANGELOG|LICENSE|README)\.adoc|#{s.name}\.gemspec)$/
21
- s.test_files = files.grep %r/^spec\//
30
+ s.files = files.grep %r/^(?:lib\/.+|Gemfile|(?:CHANGELOG|LICENSE|README)\.adoc|jekyll-asciidoc\.gemspec)$/
31
+ #s.test_files = files.grep %r/^spec\/./
22
32
 
23
33
  s.require_paths = ['lib']
24
34
 
25
35
  s.add_runtime_dependency 'asciidoctor', '>= 1.5.0'
26
- s.add_runtime_dependency 'jekyll', '>= 2.3.0'
36
+ s.add_runtime_dependency 'jekyll', '>= 3.0.0'
27
37
 
28
- s.add_development_dependency 'rake'
29
- s.add_development_dependency 'rspec', '~> 3.5.0'
38
+ s.add_development_dependency 'deep-cover-core', '~> 0.7.0'
39
+ s.add_development_dependency 'rake', '~> 12.3.2'
40
+ s.add_development_dependency 'rspec', '~> 3.8.0'
41
+ s.add_development_dependency 'simplecov', '~> 0.16.1'
30
42
  end
@@ -1,20 +1,16 @@
1
1
  module Jekyll
2
2
  module AsciiDoc
3
- Jekyll3Compatible = (jekyll_version = ::Gem::Version.new ::Jekyll::VERSION) >= (::Gem::Version.new '3.0.0')
4
- Jekyll3_1 = (::Gem::Requirement.new '~> 3.1.0').satisfied_by? jekyll_version
3
+ Jekyll3_1 = (::Gem::Requirement.new '~> 3.1.0').satisfied_by? ::Gem::Version.new ::Jekyll::VERSION
5
4
  end
6
- end
7
5
 
8
- module Jekyll
9
6
  class Site
10
- # Backport {::Jekyll::Site#find_converter_instance} to Jekyll 2.
11
- def find_converter_instance type
12
- converters.find {|candidate| type === candidate } || (raise %(No Converters found for #{type}))
13
- end unless method_defined? :find_converter_instance
14
-
15
7
  # Introduce complement to {::Jekyll::Site#find_converter_instance} for generators.
16
8
  def find_generator_instance type
17
9
  generators.find {|candidate| type === candidate } || (raise %(No Generators found for #{type}))
18
10
  end unless method_defined? :find_generator_instance
19
11
  end
20
12
  end
13
+
14
+ class Regexp
15
+ alias match? ===
16
+ end unless Regexp.method_defined? :match?
@@ -4,7 +4,7 @@ module Jekyll
4
4
  DefaultAttributes = {
5
5
  'idprefix' => '',
6
6
  'idseparator' => '-',
7
- 'linkattrs' => '@'
7
+ 'linkattrs' => '@',
8
8
  }
9
9
  DefaultFileExtensions = %w(asciidoc adoc ad)
10
10
  DefaultPageAttributePrefix = 'page'
@@ -15,14 +15,13 @@ module Jekyll
15
15
  'site-gen-jekyll' => '',
16
16
  'builder' => 'jekyll',
17
17
  'builder-jekyll' => '',
18
- 'jekyll-version' => ::Jekyll::VERSION
18
+ 'jekyll-version' => ::Jekyll::VERSION,
19
19
  }
20
20
  MessageTopic = Utils::MessageTopic
21
21
  NewLine = Utils::NewLine
22
- StandaloneOptionLine = %([%standalone]#{NewLine})
23
22
 
24
23
  AttributeReferenceRx = /\\?\{(\w+(?:[\-]\w+)*)\}/
25
- HeaderBoundaryRx = /(?<=\p{Graph})#{NewLine * 2}/
24
+ HeaderBoundaryRx = /(?<=\p{Graph}#{NewLine * 2})/
26
25
 
27
26
  # Enable plugin when running in safe mode; jekyll-asciidoc gem must also be declared in whitelist
28
27
  safe true
@@ -35,13 +34,13 @@ module Jekyll
35
34
  @config = config
36
35
  @logger = ::Jekyll.logger
37
36
  @page_context = {}
38
- @setup = false
39
37
 
40
38
  # NOTE jekyll-watch reinitializes plugins using a shallow clone of config, so no need to reconfigure
41
39
  # NOTE check for Configured only works if value of key is defined in _config.yml as Hash
42
40
  unless Configured === (asciidoc_config = (config['asciidoc'] ||= {}))
43
41
  if ::String === asciidoc_config
44
- @logger.warn MessageTopic, 'The AsciiDoc configuration should be defined as Hash under asciidoc key instead of as discrete entries.'
42
+ @logger.warn MessageTopic,
43
+ 'The AsciiDoc configuration should be defined using Hash on asciidoc key instead of discrete entries.'
45
44
  asciidoc_config = config['asciidoc'] = { 'processor' => asciidoc_config }
46
45
  else
47
46
  asciidoc_config['processor'] ||= 'asciidoctor'
@@ -52,43 +51,40 @@ module Jekyll
52
51
  old_page_attr_prefix_def = config.key? 'asciidoc_page_attribute_prefix'
53
52
  old_page_attr_prefix_val = config.delete 'asciidoc_page_attribute_prefix'
54
53
  unless (page_attr_prefix = asciidoc_config['page_attribute_prefix'])
55
- page_attr_prefix = old_page_attr_prefix_def ? (old_page_attr_prefix_val || '') :
56
- ((asciidoc_config.key? 'page_attribute_prefix') ? '' : DefaultPageAttributePrefix)
54
+ page_attr_prefix = old_page_attr_prefix_def ? old_page_attr_prefix_val || '' :
55
+ (asciidoc_config.key? 'page_attribute_prefix') ? '' : DefaultPageAttributePrefix
57
56
  end
58
- asciidoc_config['page_attribute_prefix'] = page_attr_prefix.chomp '-'
57
+ asciidoc_config['page_attribute_prefix'] = (page_attr_prefix = page_attr_prefix.chomp '-').empty? ?
58
+ '' : %(#{page_attr_prefix}-)
59
59
  asciidoc_config['require_front_matter_header'] = !!asciidoc_config['require_front_matter_header']
60
60
  asciidoc_config.extend Configured
61
61
 
62
- begin
63
- if (dlg_method = Utils.method :has_yaml_header?) && asciidoc_config['require_front_matter_header']
64
- if (::Jekyll::Utils.method dlg_method.name).arity == -1 # not original method
65
- ::Jekyll::Utils.define_singleton_method dlg_method.name, &dlg_method
66
- end
67
- else
68
- unless (new_method = dlg_method.owner.method :has_front_matter?).respond_to? :curry
69
- new_method = new_method.to_proc # Ruby < 2.2
70
- end
71
- ::Jekyll::Utils.define_singleton_method dlg_method.name, new_method.curry[dlg_method][asciidoc_ext_re]
62
+ if asciidoc_config['require_front_matter_header']
63
+ unless (::Jekyll::Utils.method :has_yaml_header?).owner == ::Jekyll::Utils
64
+ # NOTE restore original method
65
+ ::Jekyll::Utils.extend (::Module.new do
66
+ define_method :has_yaml_header?, &(Utils.method :has_yaml_header?)
67
+ end)
72
68
  end
73
- rescue ::NameError; end
69
+ else
70
+ ::Jekyll::Utils.extend (::Module.new do
71
+ define_method :has_yaml_header?,
72
+ (Utils.method :has_front_matter?).curry[Utils.method :has_yaml_header?][asciidoc_ext_re]
73
+ end)
74
+ end
74
75
  end
75
76
 
76
77
  if (@asciidoc_config = asciidoc_config)['processor'] == 'asciidoctor'
77
78
  unless Configured === (@asciidoctor_config = (config['asciidoctor'] ||= {}))
78
79
  asciidoctor_config = @asciidoctor_config
79
- asciidoctor_config.replace (symbolize_keys asciidoctor_config)
80
+ asciidoctor_config.replace symbolize_keys asciidoctor_config
80
81
  source = ::File.expand_path config['source']
81
82
  dest = ::File.expand_path config['destination']
82
83
  case (base = asciidoctor_config[:base_dir])
83
84
  when ':source'
84
85
  asciidoctor_config[:base_dir] = source
85
86
  when ':docdir'
86
- if defined? ::Jekyll::Hooks
87
- asciidoctor_config[:base_dir] = :docdir
88
- else
89
- @logger.warn MessageTopic, 'Using :docdir as value of base_dir option requires Jekyll 3. Falling back to source directory.'
90
- asciidoctor_config[:base_dir] = source
91
- end
87
+ asciidoctor_config[:base_dir] = :docdir
92
88
  else
93
89
  asciidoctor_config[:base_dir] = ::File.expand_path base if base
94
90
  end
@@ -98,9 +94,9 @@ module Jekyll
98
94
  'site-source' => source,
99
95
  'site-destination' => dest,
100
96
  'site-baseurl' => config['baseurl'],
101
- 'site-url' => config['url']
97
+ 'site-url' => config['url'],
102
98
  }
103
- attrs = asciidoctor_config[:attributes] = assemble_attributes asciidoctor_config[:attributes],
99
+ attrs = asciidoctor_config[:attributes] = compile_attributes asciidoctor_config[:attributes],
104
100
  ((site_attributes.merge ImplicitAttributes).merge DefaultAttributes)
105
101
  if (imagesdir = attrs['imagesdir']) && !(attrs.key? 'imagesoutdir') && (imagesdir.start_with? '/')
106
102
  attrs['imagesoutdir'] = ::File.join dest, (imagesdir.chomp '@')
@@ -108,17 +104,17 @@ module Jekyll
108
104
  asciidoctor_config.extend Configured
109
105
  end
110
106
  end
107
+
108
+ load_processor
111
109
  end
112
110
 
113
- def setup
114
- return self if @setup
115
- @setup = true
111
+ def load_processor
116
112
  case @asciidoc_config['processor']
117
113
  when 'asciidoctor'
118
114
  begin
119
115
  require 'asciidoctor' unless defined? ::Asciidoctor::VERSION
120
116
  rescue ::LoadError
121
- @logger.error MessageTopic, 'You are missing a library required to convert AsciiDoc files. Please install using:'
117
+ @logger.error MessageTopic, 'You\'re missing a library required to convert AsciiDoc files. Install using:'
122
118
  @logger.error '', '$ [sudo] gem install asciidoctor'
123
119
  @logger.abort_with 'Bailing out; missing required dependency: asciidoctor'
124
120
  end
@@ -127,7 +123,7 @@ module Jekyll
127
123
  @logger.error '', 'Valid options are: asciidoctor'
128
124
  @logger.abort_with 'Bailing out; invalid Asciidoctor processor.'
129
125
  end
130
- self
126
+ nil
131
127
  end
132
128
 
133
129
  def self.get_instance site
@@ -135,10 +131,10 @@ module Jekyll
135
131
  end
136
132
 
137
133
  def matches ext
138
- ext =~ @asciidoc_config['ext_re']
134
+ @asciidoc_config['ext_re'].match? ext
139
135
  end
140
136
 
141
- def output_ext ext
137
+ def output_ext _ext
142
138
  '.html'
143
139
  end
144
140
 
@@ -156,7 +152,7 @@ module Jekyll
156
152
  record_paths document
157
153
  end
158
154
 
159
- def after_render document
155
+ def after_render _document
160
156
  @page_context.clear
161
157
  end
162
158
 
@@ -164,13 +160,13 @@ module Jekyll
164
160
  @page_context[:paths] = paths = {
165
161
  'docfile' => (docfile = ::File.join document.site.source, document.relative_path),
166
162
  'docdir' => (::File.dirname docfile),
167
- 'docname' => (::File.basename docfile, (::File.extname docfile))
163
+ 'docname' => (::File.basename docfile, (::File.extname docfile)),
168
164
  }
169
- paths.update({
165
+ paths.update(
170
166
  'outfile' => (outfile = document.destination document.site.dest),
171
167
  'outdir' => (::File.dirname outfile),
172
168
  'outpath' => document.url
173
- }) unless opts[:source_only]
169
+ ) unless opts[:source_only]
174
170
  end
175
171
 
176
172
  def clear_paths
@@ -178,10 +174,9 @@ module Jekyll
178
174
  end
179
175
 
180
176
  def load_header document
181
- setup
182
- record_paths document, source_only: true if defined? ::Jekyll::Hooks
183
- # NOTE merely an optimization; if this doesn't match, the header still gets isolated by the processor
184
- header = (document.content.split HeaderBoundaryRx, 2)[0] || ''
177
+ record_paths document, source_only: true
178
+ # NOTE merely an optimization; if this doesn't match, the header still gets extracted by the processor
179
+ header = (content = document.content) ? (HeaderBoundaryRx =~ content ? $` : content) : ''
185
180
  case @asciidoc_config['processor']
186
181
  when 'asciidoctor'
187
182
  opts = @asciidoctor_config.merge parse_header_only: true
@@ -193,26 +188,27 @@ module Jekyll
193
188
  end
194
189
  opts[:attributes] = opts[:attributes].merge paths
195
190
  end
191
+ if (layout_attr = resolve_default_layout document, opts[:attributes])
192
+ opts[:attributes] = opts[:attributes].merge layout_attr
193
+ end
196
194
  # NOTE return instance even if header is empty since attributes may be inherited from config
197
195
  doc = ::Asciidoctor.load header, opts
198
196
  else
199
- @logger.warn MessageTopic, %(Unknown AsciiDoc processor: #{@asciidoc_config['processor']}. Cannot load document header.)
197
+ @logger.warn MessageTopic,
198
+ %(Unknown AsciiDoc processor: #{@asciidoc_config['processor']}. Cannot load document header.)
200
199
  doc = nil
201
200
  end
202
- clear_paths if defined? ::Jekyll::Hooks
201
+ clear_paths
203
202
  doc
204
203
  end
205
204
 
206
205
  def convert content
207
206
  # NOTE don't use nil_or_empty? since that's only provided only by Asciidoctor
208
207
  return '' unless content && !content.empty?
209
- setup
210
- if (standalone = content.start_with? StandaloneOptionLine)
211
- content = content[StandaloneOptionLine.length..-1]
212
- end
208
+
213
209
  case @asciidoc_config['processor']
214
210
  when 'asciidoctor'
215
- opts = @asciidoctor_config.merge header_footer: standalone
211
+ opts = @asciidoctor_config.merge header_footer: (@page_context[:data] || {})['standalone']
216
212
  if (paths = @page_context[:paths])
217
213
  if opts[:base_dir] == :docdir
218
214
  opts[:base_dir] = paths['docdir'] # NOTE this assignment happens inside the processor anyway
@@ -226,7 +222,8 @@ module Jekyll
226
222
  end
227
223
  ((@page_context[:data] || {})['document'] = ::Asciidoctor.load content, opts).extend(Liquidable).convert
228
224
  else
229
- @logger.warn MessageTopic, %(Unknown AsciiDoc processor: #{@asciidoc_config['processor']}. Passing through unparsed content.)
225
+ @logger.warn MessageTopic,
226
+ %(Unknown AsciiDoc processor: #{@asciidoc_config['processor']}. Passing through unparsed content.)
230
227
  content
231
228
  end
232
229
  end
@@ -237,9 +234,9 @@ module Jekyll
237
234
  hash.each_with_object({}) {|(key, val), accum| accum[key.to_sym] = val }
238
235
  end
239
236
 
240
- def assemble_attributes attrs, initial = {}
237
+ def compile_attributes attrs, initial = {}
241
238
  if (is_array = ::Array === attrs) || ::Hash === attrs
242
- attrs.each_with_object(initial) {|entry, new_attrs|
239
+ attrs.each_with_object(initial) do |entry, new_attrs|
243
240
  key, val = is_array ? ((entry.split '=', 2) + ['', ''])[0..1] : entry
244
241
  if key.start_with? '!'
245
242
  new_attrs[key[1..-1]] = nil
@@ -249,23 +246,22 @@ module Jekyll
249
246
  elsif key.start_with? '-'
250
247
  new_attrs.delete key[1..-1]
251
248
  else
252
- new_attrs[key] = if val
253
- case val
254
- when ::String
255
- resolve_attribute_refs val, new_attrs
256
- when ::Numeric
257
- val.to_s
258
- when true
259
- ''
260
- else
261
- val
262
- end
263
- else
249
+ case val
250
+ when ::String
251
+ new_attrs[key] = resolve_attribute_refs val, new_attrs
252
+ when ::Numeric
253
+ new_attrs[key] = val.to_s
254
+ when true
255
+ new_attrs[key] = ''
256
+ when nil, false
264
257
  # we may preserve false in the future to mean "unset implicit value but allow doc to override"
265
- nil
258
+ # false already has special meaning for page-layout, so don't coerce it
259
+ new_attrs[key] = key == 'page-layout' ? val : nil
260
+ else
261
+ new_attrs[key] = val
266
262
  end
267
263
  end
268
- }
264
+ end
269
265
  else
270
266
  initial
271
267
  end
@@ -281,11 +277,35 @@ module Jekyll
281
277
  end
282
278
  end
283
279
 
280
+ def resolve_default_layout document, attributes
281
+ layout_attr_name = %(#{document.site.config['asciidoc']['page_attribute_prefix']}layout)
282
+ if attributes.key? layout_attr_name
283
+ if ::String === (layout = attributes[layout_attr_name])
284
+ if layout == '~@'
285
+ layout = 'none@'
286
+ elsif (layout.end_with? '@') && ((document.data.key? 'layout') || document.data['layout'])
287
+ layout = %(#{(layout = document.data['layout']).nil? ? 'none' : layout}@)
288
+ else
289
+ layout = nil
290
+ end
291
+ elsif layout.nil?
292
+ layout = 'none'
293
+ else
294
+ layout = layout.to_s
295
+ end
296
+ elsif (document.data.key? 'layout') || document.data['layout']
297
+ layout = %(#{(layout = document.data['layout']).nil? ? 'none' : layout}@)
298
+ else
299
+ layout = '@'
300
+ end
301
+ layout ? { layout_attr_name => layout } : nil
302
+ end
303
+
284
304
  # Register pre and post render callbacks for saving and clearing contextual AsciiDoc attributes, respectively.
285
305
  ::Jekyll::Hooks.tap do |hooks|
286
306
  hooks.register [:pages, :documents], :pre_render, &(method :before_render)
287
307
  hooks.register [:pages, :documents], :post_render, &(method :after_render)
288
- end if defined? ::Jekyll::Hooks
308
+ end
289
309
  end
290
310
  end
291
311
  end
@@ -27,9 +27,8 @@ module Jekyll
27
27
  #
28
28
  # Returns the table of contents as an HTML-formatted String.
29
29
  def tocify_asciidoc document, levels = nil
30
- if ::Asciidoctor::Document === document
31
- document.converter.convert document, 'outline', toclevels: (levels.nil_or_empty? ? nil : levels.to_i)
32
- end
30
+ ::Asciidoctor::Document === document ?
31
+ (document.converter.convert document, 'outline', toclevels: (levels.nil_or_empty? ? nil : levels.to_i)) : nil
33
32
  end
34
33
  end
35
34
 
@@ -5,7 +5,6 @@ module Jekyll
5
5
  # source highlighter and configured to use class-based styling.
6
6
  class Integrator < ::Jekyll::Generator
7
7
  NewLine = Utils::NewLine
8
- StandaloneOptionLine = Converter::StandaloneOptionLine
9
8
 
10
9
  # Enable plugin when running in safe mode; jekyll-asciidoc gem must also be declared in whitelist
11
10
  safe true
@@ -17,23 +16,13 @@ module Jekyll
17
16
  # This method is triggered each time the site is generated, including after any file has changed when running in
18
17
  # watch mode (regardless of incremental setting).
19
18
  def generate site
20
- @converter = converter = (Converter.get_instance site).setup
21
-
22
- unless (@page_attr_prefix = site.config['asciidoc']['page_attribute_prefix']).empty?
23
- @page_attr_prefix = %(#{@page_attr_prefix}-)
24
- end
19
+ @converter = converter = Converter.get_instance site
25
20
 
26
21
  site.pages.select! do |page|
27
22
  (converter.matches page.ext) ? (integrate page) : true
28
23
  end
29
24
 
30
- # NOTE posts were migrated to a collection named 'posts' in Jekyll 3
31
- site.posts.select! do |post|
32
- (converter.matches post.ext) ? (integrate post, 'posts') : true
33
- end if site.respond_to? :posts=
34
-
35
25
  site.collections.each do |name, collection|
36
- next unless collection.write?
37
26
  collection.docs.select! do |doc|
38
27
  (converter.matches doc.extname) ? (integrate doc, name) : true
39
28
  end
@@ -55,10 +44,10 @@ module Jekyll
55
44
  #
56
45
  # Returns a [Boolean] indicating whether the document should be published.
57
46
  def integrate document, collection_name = nil
58
- data = document.data
59
- document.content = [%(:#{@page_attr_prefix}layout: _auto), document.content] * NewLine unless data['layout']
60
47
  return true unless (doc = @converter.load_header document)
61
48
 
49
+ data = document.data
50
+ data['asciidoc'] = true
62
51
  # NOTE id is already reserved in Jekyll for another purpose, so we'll map id to docid instead
63
52
  data['docid'] = doc.id if doc.id
64
53
  data['title'] = doc.doctitle if doc.header?
@@ -66,35 +55,35 @@ module Jekyll
66
55
  if collection_name == 'posts' && (doc.attr? 'revdate')
67
56
  data['date'] = ::Jekyll::Utils.parse_date doc.revdate,
68
57
  %(Document '#{document.relative_path}' does not have a valid revdate in the AsciiDoc header.)
69
- # NOTE Jekyll 2.3 requires date field to be set explicitly
70
- document.date = data['date'] if document.respond_to? :date=
71
58
  end
72
59
 
73
- no_prefix = (prefix_size = @page_attr_prefix.length) == 0
74
- unless (adoc_data = doc.attributes.each_with_object({}) {|(key, val), accum|
75
- if no_prefix || ((key.start_with? @page_attr_prefix) && key = key[prefix_size..-1])
76
- accum[key] = ::String === val ? (parse_yaml_value val) : val
77
- end
78
- }).empty?
79
- data.update adoc_data
60
+ page_attr_prefix = document.site.config['asciidoc']['page_attribute_prefix']
61
+ no_prefix = (prefix_size = page_attr_prefix.length) == 0
62
+ adoc_data = doc.attributes.each_with_object({}) do |(key, val), accum|
63
+ if no_prefix || ((key.start_with? page_attr_prefix) && (key = key[prefix_size..-1]))
64
+ accum[key] = ::String === val ? (parse_yaml_value val) : val
65
+ end
80
66
  end
67
+ data.update adoc_data unless adoc_data.empty?
81
68
 
82
69
  { 'category' => 'categories', 'tag' => 'tags' }.each do |sole_key, coll_key|
83
- if (sole_val = data.delete sole_key) &&
84
- !((coll_val = (data[coll_key] ||= [])).include? sole_val)
85
- coll_val << sole_val
70
+ if (sole_val = data[sole_key])
71
+ (coll_val = data[coll_key] ||= []).delete sole_val
72
+ coll_val.unshift sole_val
73
+ elsif (coll_val = data[coll_key])
74
+ data[sole_key] = coll_val[0]
86
75
  end
87
76
  end
88
77
 
89
78
  case data['layout']
90
79
  when nil
91
- document.content = %(#{StandaloneOptionLine}#{document.content}) unless data.key? 'layout'
80
+ data['standalone'] = true unless data.key? 'layout'
92
81
  when '', '_auto'
93
82
  layout = collection_name ? (collection_name.chomp 's') : 'page'
94
83
  data['layout'] = (document.site.layouts.key? layout) ? layout : 'default'
95
84
  when false
96
85
  data['layout'] = 'none'
97
- document.content = %(#{StandaloneOptionLine}#{document.content})
86
+ data['standalone'] = true
98
87
  end
99
88
 
100
89
  document.extend Document
@@ -116,7 +105,7 @@ module Jekyll
116
105
  if site.static_files.any? {|f| f.path == css_file }
117
106
  ::IO.write css_file, css unless css == (::IO.read css_file)
118
107
  else
119
- ::Asciidoctor::Helpers.mkdir_p (::File.dirname css_file)
108
+ ::Asciidoctor::Helpers.mkdir_p ::File.dirname css_file
120
109
  ::IO.write css_file, css
121
110
  site.static_files << (::Jekyll::StaticFile.new site, css_base, css_dir, css_name)
122
111
  end