Skip to content

Commit

Permalink
resolves asciidoctor#82 restructure configuration keys
Browse files Browse the repository at this point in the history
- move AsciiDoc configuration to Hash under asciidoc key
- use old keys if new keys aren't specified
- add deprecation warning if old structure is detected
- chomp trailing hyphen on page_attribute_prefix in initialize
- treat nil value for page_attribute_prefix as empty string
- use a module to mark initialized configuration
- update README to document new keys
- explain that the asciidoctor block accepts any option supported by the Asciidoctor API
  • Loading branch information
mojavelinux committed Jun 5, 2016
1 parent f32fffe commit 1a9a4cd
Show file tree
Hide file tree
Showing 2 changed files with 84 additions and 40 deletions.
54 changes: 40 additions & 14 deletions README.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ ifdef::env-github[]
:tip-caption: :bulb:
:warning-caption: :warning:
endif::[]
// Aliases:
:path-config: pass:q[[path]___config.yml__]
// URIs:
:uri-asciidoc: http://asciidoc.org
:uri-asciidoctor: http://asciidoctor.org
Expand Down Expand Up @@ -73,7 +75,7 @@ Then, run the `bundle` command from Bundler to install the gem:
Using Bundler::
+
--
Add the `jekyll-asciidoc` plugin gem to your [path]_Gemfile_
Add the `jekyll-asciidoc` plugin gem to your [path]_Gemfile_:

[source,ruby]
----
Expand All @@ -94,7 +96,7 @@ If you are not using Bundler for managing Jekyll then install gems manually

$ gem install jekyll-asciidoc

And then, add the `jekyll-asciidoc` gem to the list of gems for Jekyll to load in your site's [path]_{empty}_config.yml_ file:
And then, add the `jekyll-asciidoc` gem to the list of gems for Jekyll to load in your site's {path-config} file:

[source,yaml]
----
Expand Down Expand Up @@ -223,37 +225,59 @@ The `--safe` flag disables third-party plugins such as this one.

== Configuration

This section describes the configuration options for this plugin, which are _optional_.
This section describes the configuration options for this plugin, which are all _optional_.

=== AsciiDoc

NOTE: Prior to v1.2.0 of this plugin, the configuration options in this section were flat, top-level names (e.g., `asciidoc_ext`).
These names are now deprecated, but still supported.

By default, this plugin uses Asciidoctor to convert AsciiDoc files.
Since Asciidoctor is the only option, the default setting is equivalent to the following configuration in [path]_{empty}_config.yml_:
Since Asciidoctor is currently the only option, the default setting is equivalent to the following configuration in {path-config}:

[source,yaml]
----
asciidoc: asciidoctor
asciidoc:
processor: asciidoctor
----

To tell Jekyll which extensions to recognize as AsciiDoc files, add the following line to your [path]_{empty}_config.yml_:
IMPORTANT: The `asciidoc` block should only appear _once_ inside {path-config}.
If you define any other options that are documented in this section, you should append them to the `asciidoc` block.

To tell Jekyll which file extensions to match as AsciiDoc files, append the `ext` option to the `asciidoc` block of your {path-config}:

[source,yaml]
----
asciidoc_ext: asciidoc,adoc,ad
asciidoc:
ext: asciidoc,adoc,ad
----

The extensions shown in the previous listing are the default values, so you don't need to specify this option if those defaults are sufficient.

AsciiDoc attributes defined in the document header whose names begin with `page-` are promoted to Jekyll front matter.
The part of the name after the `page-` prefix is used as the key (e.g., page-layout becomes layout).
If you want to change this attribute prefix, add the following line to your [path]_{empty}_config.yml_:
If you want to change this attribute prefix, append the `page_attribute_prefix` option to the `asciidoc` block of your {path-config}:

[source,yaml]
----
asciidoc_page_attribute_prefix: jekyll
asciidoc:
page_attribute_prefix: jekyll
----

A hyphen is automatically added to the value of this configuration setting if the value is non-empty.

To pass additional attributes to AsciiDoc, or override the default attributes defined in the plugin, add the following lines to your [path]_{empty}_config.yml_:
By default, all eligible AsciiDoc files are processed.
If you only want files containing a front matter header to be processed, add the `require_front_matter_header` option to the `asciidoc` block of your {path-config}:

[source,yaml]
----
asciidoc:
require_front_matter_header: true
----

=== Asciidoctor

To pass additional attributes to AsciiDoc, or override the default attributes defined in the plugin, add the following lines to your {path-config}:

[source,yaml]
----
Expand All @@ -264,12 +288,14 @@ asciidoctor:
- pygments-css=style
----

In addition to `attributes`, you can define any another option key (e.g., `safe`) that is recognized by the http://asciidoctor.org/docs/user-manual/#ruby-api-options[Asciidoctor API].

=== Enabling hard line breaks

Many Jekyll users are used to writing in GitHub-flavored Markdown (GFM), which preserves hard line breaks in paragraph content.
Asciidoctor supports this feature for AsciiDoc files.
(In fact, previous versions of this plugin enabled this behavior by default).
If you want to enable this behavior for AsciiDoc files, add the `hardbreaks-option` attribute to the Asciidoctor attributes configuration in your site's [path]_{empty}_config.yml_ file:
If you want to enable this behavior for AsciiDoc files, add the `hardbreaks-option` attribute to the Asciidoctor attributes configuration in your site's {path-config} file:

[source,yaml]
----
Expand All @@ -287,7 +313,7 @@ asciidoctor:
- hardbreaks-option=@
----

If you already have AsciiDoc attributes defined in the [path]_{empty}_config.yml_, the new attribute should be added as a sibling entry in the YAML collection.
If you already have AsciiDoc attributes defined in the {path-config}, the new attribute should be added as a sibling entry in the YAML collection.

WARNING: Keep in mind, if you enable hard line breaks, you won't be able to use the http://asciidoctor.org/docs/asciidoc-recommended-practices/#one-sentence-per-line[one sentence-per-line writing technique].

Expand All @@ -303,7 +329,7 @@ For Graphviz and PlantUML diagram generation, {uri-graphviz}[Graphviz] must be i
Using Bundler::
+
--
Add `asciidoctor-diagram` gem to your [path]_Gemfile_
Add `asciidoctor-diagram` gem to your [path]_Gemfile_:

[source,ruby]
----
Expand All @@ -327,7 +353,7 @@ Install gems manually

$ gem install asciidoctor-diagram

Then, add the `asciidoctor-diagram` gem to the list of gems for Jekyll to load in your site's [path]_{empty}_config.yml_ file:
Then, add the `asciidoctor-diagram` gem to the list of gems for Jekyll to load in your site's {path-config} file:

[source,yaml]
----
Expand Down
70 changes: 44 additions & 26 deletions lib/jekyll-asciidoc.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ module Jekyll
MIN_VERSION_3 = ::Gem::Version.new(VERSION) >= ::Gem::Version.new('3.0.0') unless defined? MIN_VERSION_3

module AsciiDoc
module Configuration; end
module Utils
def self.has_front_matter?(delegate_method, asciidoc_ext_re, path)
::File.extname(path) =~ asciidoc_ext_re ? true : delegate_method.call(path)
Expand All @@ -24,34 +25,53 @@ class AsciiDocConverter < Converter
highlighter_suffix %(\n)

def initialize(config)
@setup = false
(@config = config)['asciidoc'] ||= 'asciidoctor'
asciidoc_ext = (config['asciidoc_ext'] ||= 'asciidoc,adoc,ad')
asciidoc_ext_re = (config['asciidoc_ext_re'] = /^\.(?:#{asciidoc_ext.tr ',', '|'})$/ix)
config['asciidoc_page_attribute_prefix'] ||= 'page'
unless (asciidoctor_config = (config['asciidoctor'] ||= {})).frozen?
# NOTE jekyll-watch reinitializes plugins using a shallow clone of config, so no need to reconfigure
unless ::Jekyll::AsciiDoc::Configuration === (asciidoc_config = (config['asciidoc'] ||= {}))
if ::String === asciidoc_config
::Jekyll.logger.warn 'jekyll-asciidoc: The AsciiDoc-related configuration should be defined using a Hash (under the `asciidoc` key) instead of discrete entries.'
asciidoc_config = config['asciidoc'] = { 'processor' => asciidoc_config }
else
asciidoc_config['processor'] ||= 'asciidoctor'
end
old_asciidoc_ext = config.delete('asciidoc_ext')
asciidoc_ext = (asciidoc_config['ext'] ||= (old_asciidoc_ext || 'asciidoc,adoc,ad'))
asciidoc_ext_re = (asciidoc_config['ext_re'] = /^\.(?:#{asciidoc_ext.tr ',', '|'})$/ix)
old_page_attr_prefix_def = config.key?('asciidoc_page_attribute_prefix')
old_page_attr_prefix_val = config.delete('asciidoc_page_attribute_prefix')
unless (page_attr_prefix = asciidoc_config['page_attribute_prefix'])
page_attr_prefix = old_page_attr_prefix_def ? (old_page_attr_prefix_val || '') :
(asciidoc_config.key?('page_attribute_prefix') && '' || 'page')
end
asciidoc_config['page_attribute_prefix'] = page_attr_prefix.chomp('-')
asciidoc_config['require_front_matter_header'] = !!asciidoc_config.fetch('require_front_matter_header', false)

asciidoctor_config = (config['asciidoctor'] ||= {})
asciidoctor_config.replace(::Hash[asciidoctor_config.map {|key, val| [key.to_sym, val] }])
asciidoctor_config[:safe] ||= 'safe'
(asciidoctor_config[:attributes] ||= []).tap do |attributes|
attributes.unshift('notitle', 'idprefix', 'idseparator=-', 'linkattrs')
attributes.concat(IMPLICIT_ATTRIBUTES)
(asciidoctor_config[:attributes] ||= []).tap do |attrs|
attrs.unshift('notitle', 'idprefix', 'idseparator=-', 'linkattrs')
attrs.concat(IMPLICIT_ATTRIBUTES)
end
if ::Jekyll::MIN_VERSION_3 && !config['asciidoc_require_front_matter']

if ::Jekyll::MIN_VERSION_3 && !asciidoc_config['require_front_matter']
if (del_method = ::Jekyll::Utils.method(:has_yaml_header?))
unless (new_method = ::Jekyll::AsciiDoc::Utils.method(:has_front_matter?)).respond_to?(:curry)
new_method = new_method.to_proc # Ruby < 2.2
end
del_method.owner.define_singleton_method(del_method.name, new_method.curry[del_method][asciidoc_ext_re])
end
end
asciidoctor_config.freeze

asciidoc_config.extend ::Jekyll::AsciiDoc::Configuration
end
@config = config
@setup = false
end

def setup
return self if @setup
@setup = true
case @config['asciidoc']
case (processor = @config['asciidoc']['processor'])
when 'asciidoctor'
begin
require 'asciidoctor' unless defined? ::Asciidoctor::VERSION
Expand All @@ -61,15 +81,15 @@ def setup
raise ::FatalException.new('Missing dependency: asciidoctor')
end
else
STDERR.puts %(Invalid AsciiDoc processor: #{@config['asciidoc']})
STDERR.puts %(Invalid AsciiDoc processor: #{processor})
STDERR.puts ' Valid options are [ asciidoctor ]'
raise ::FatalException.new(%(Invalid AsciiDoc processor: #{@config['asciidoc']}))
raise ::FatalException.new(%(Invalid AsciiDoc processor: #{processor}))
end
self
end

def matches(ext)
ext =~ @config['asciidoc_ext_re']
ext =~ @config['asciidoc']['ext_re']
end

def output_ext(ext)
Expand All @@ -82,11 +102,11 @@ def convert(content)
if (standalone = content.start_with?(STANDALONE_HEADER))
content = content[STANDALONE_HEADER.length..-1]
end
case @config['asciidoc']
case (processor = @config['asciidoc']['processor'])
when 'asciidoctor'
::Asciidoctor.convert(content, @config['asciidoctor'].merge(header_footer: standalone))
else
warn 'Unknown AsciiDoc converter. Passing through unparsed content.'
warn %(Unknown AsciiDoc processor: #{processor}. Passing through unparsed content.)
content
end
end
Expand All @@ -95,19 +115,19 @@ def load_header(content)
setup
# NOTE merely an optimization; if this doesn't match, the header still gets isolated by the processor
header = content.split(HEADER_BOUNDARY_RE, 2)[0]
case @config['asciidoc']
case (processor = @config['asciidoc']['processor'])
when 'asciidoctor'
# NOTE return a document even if header is empty because attributes may be inherited from config
# NOTE return instance even if header is empty since attributes may be inherited from config
::Asciidoctor.load(header, @config['asciidoctor'].merge(parse_header_only: true))
else
warn 'Unknown AsciiDoc converter. Cannot load document header.'
warn %(Unknown AsciiDoc processor: #{processor}. Cannot load document header.)
end
end
end
end

module Generators
# Promotes select AsciiDoc attributes to Jekyll front matter
# Promotes sanctioned AsciiDoc attributes to Jekyll front matter
class AsciiDocPreprocessor < Generator
module NoLiquid
def render_with_liquid?
Expand All @@ -122,9 +142,7 @@ def generate(site)
@converter = (::Jekyll::MIN_VERSION_3 ?
site.find_converter_instance(::Jekyll::Converters::AsciiDocConverter) :
site.getConverterImpl(::Jekyll::Converters::AsciiDocConverter)).setup
unless (@page_attr_prefix = site.config['asciidoc_page_attribute_prefix']).empty?
@page_attr_prefix = %(#{@page_attr_prefix.chomp '-'}-)
end
@page_attr_prefix = site.config['asciidoc']['page_attribute_prefix']

site.pages.each do |page|
enhance_page(page) if @converter.matches(page.ext)
Expand All @@ -144,10 +162,10 @@ def enhance_page page, collection = nil
page.data['author'] = doc.author if doc.author
page.data['date'] = ::DateTime.parse(doc.revdate).to_time if collection == 'posts' && doc.attr?('revdate')

page_attr_prefix_length = @page_attr_prefix.length
page_attr_prefix_len = @page_attr_prefix.length
unless (adoc_front_matter = doc.attributes
.select {|name| name.start_with?(@page_attr_prefix) }
.map {|name, val| %(#{name[page_attr_prefix_length..-1]}: #{val == '' ? '""' : val}) }).empty?
.map {|name, val| %(#{name[page_attr_prefix_len..-1]}: #{val == '' ? '""' : val}) }).empty?
page.data.update(::SafeYAML.load(adoc_front_matter * %(\n)))
end

Expand Down

0 comments on commit 1a9a4cd

Please sign in to comment.