lib/asciidoctor/extensions.rb in asciidoctor-1.5.7.1 vs lib/asciidoctor/extensions.rb in asciidoctor-1.5.8
- old
+ new
@@ -157,10 +157,33 @@
def create_block parent, context, source, attrs, opts = {}
Block.new parent, context, { :source => source, :attributes => attrs }.merge(opts)
end
+ # Public: Creates a list node and links it to the specified parent.
+ #
+ # parent - The parent Block (Block, Section, or Document) of this new list block.
+ # context - The list context (e.g., :ulist, :olist, :colist, :dlist)
+ # attrs - A Hash of attributes to set on this list block
+ #
+ # Returns a [List] node with all properties properly initialized.
+ def create_list parent, context, attrs = nil
+ list = List.new parent, context
+ list.update_attributes attrs if attrs
+ list
+ end
+
+ # Public: Creates a list item node and links it to the specified parent.
+ #
+ # parent - The parent List of this new list item block.
+ # text - The text of the list item.
+ #
+ # Returns a [ListItem] node with all properties properly initialized.
+ def create_list_item parent, text = nil
+ ListItem.new parent, text
+ end
+
# Public: Creates an image block node and links it to the specified parent.
#
# parent - The parent Block (Block, Section, or Document) of this new image block.
# attrs - A Hash of attributes to control how the image block is built.
# Use the target attribute to set the source of the image.
@@ -171,11 +194,17 @@
def create_image_block parent, attrs, opts = {}
unless (target = attrs['target'])
raise ::ArgumentError, 'Unable to create an image block, target attribute is required'
end
attrs['alt'] ||= (attrs['default-alt'] = Helpers.basename(target, true).tr('_-', ' '))
- create_block parent, :image, nil, attrs, opts
+ title = (attrs.key? 'title') ? (attrs.delete 'title') : nil
+ block = create_block parent, :image, nil, attrs, opts
+ if title
+ block.title = title
+ block.assign_caption((attrs.delete 'caption'), (opts[:caption_context] || 'figure'))
+ end
+ block
end
def create_inline parent, context, text, opts = {}
Inline.new parent, context, text, opts
end
@@ -241,13 +270,21 @@
def process_block_given?
defined? @process_block
end
end
- module SyntaxDsl
+ module DocumentProcessorDsl
include ProcessorDsl
+ def prefer
+ option :position, :>>
+ end
+ end
+
+ module SyntaxProcessorDsl
+ include ProcessorDsl
+
def named value
# NOTE due to how processors get initialized, we must defer this assignment in some scenarios
if Processor === self
@name = value
else
@@ -341,11 +378,11 @@
class Preprocessor < Processor
def process document, reader
raise ::NotImplementedError, %(Asciidoctor::Extensions::Preprocessor subclass must implement ##{__method__} method)
end
end
- Preprocessor::DSL = ProcessorDsl
+ Preprocessor::DSL = DocumentProcessorDsl
# Public: TreeProcessors are run on the Document after the source has been
# parsed into an abstract syntax tree (AST), as represented by the Document
# object and its child Node objects (e.g., Section, Block, List, ListItem).
#
@@ -358,11 +395,11 @@
class TreeProcessor < Processor
def process document
raise ::NotImplementedError, %(Asciidoctor::Extensions::TreeProcessor subclass must implement ##{__method__} method)
end
end
- TreeProcessor::DSL = ProcessorDsl
+ TreeProcessor::DSL = DocumentProcessorDsl
# Alias deprecated class name for backwards compatibility
Treeprocessor = TreeProcessor
# Public: Postprocessors are run after the document is converted, but before
@@ -383,11 +420,11 @@
class Postprocessor < Processor
def process document, output
raise ::NotImplementedError, %(Asciidoctor::Extensions::Postprocessor subclass must implement ##{__method__} method)
end
end
- Postprocessor::DSL = ProcessorDsl
+ Postprocessor::DSL = DocumentProcessorDsl
# Public: IncludeProcessors are used to process `include::<target>[]`
# directives in the source document.
#
# When Asciidoctor comes across a `include::<target>[]` directive in the
@@ -407,11 +444,11 @@
true
end
end
module IncludeProcessorDsl
- include ProcessorDsl
+ include DocumentProcessorDsl
def handles? *args, &block
if block_given?
raise ::ArgumentError, %(wrong number of arguments (given #{args.size}, expected 0)) unless args.empty?
@handles_block = block
@@ -449,11 +486,11 @@
raise ::NotImplementedError, %(Asciidoctor::Extensions::DocinfoProcessor subclass must implement ##{__method__} method)
end
end
module DocinfoProcessorDsl
- include ProcessorDsl
+ include DocumentProcessorDsl
def at_location value
option :location, value
end
end
@@ -505,11 +542,11 @@
raise ::NotImplementedError, %(Asciidoctor::Extensions::BlockProcessor subclass must implement ##{__method__} method)
end
end
module BlockProcessorDsl
- include SyntaxDsl
+ include SyntaxProcessorDsl
def contexts *value
option :contexts, value.flatten.to_set
end
alias on_contexts contexts
@@ -531,11 +568,11 @@
raise ::NotImplementedError, %(Asciidoctor::Extensions::MacroProcessor subclass must implement ##{__method__} method)
end
end
module MacroProcessorDsl
- include SyntaxDsl
+ include SyntaxProcessorDsl
def resolves_attributes *args
if args.size == 1 && !args[0]
option :content_model, :text
return
@@ -550,10 +587,14 @@
# Public: BlockMacroProcessors are used to handle block macros that have a
# custom name.
#
# BlockMacroProcessor implementations must extend BlockMacroProcessor.
class BlockMacroProcessor < MacroProcessor
+ def name
+ raise ::ArgumentError, %(invalid name for block macro: #{@name}) unless MacroNameRx.match? @name.to_s
+ @name
+ end
end
BlockMacroProcessor::DSL = MacroProcessorDsl
# Public: InlineMacroProcessors are used to handle block macros that have a
# custom name.
@@ -1251,10 +1292,30 @@
# Returns an [Array] of Extension proxy objects.
def inline_macros
@inline_macro_extensions.values
end
+ # Public: Inserts the document processor {Extension} instance as the first
+ # processor of its kind in the extension registry.
+ #
+ # Examples
+ #
+ # prefer :include_processor do
+ # process do |document, reader, target, attrs|
+ # ...
+ # end
+ # end
+ #
+ # Returns the [Extension] stored in the registry that proxies the instance
+ # of this processor.
+ def prefer *args, &block
+ extension = ProcessorExtension === (arg0 = args.shift) ? arg0 : (send arg0, *args, &block)
+ extensions_store = instance_variable_get(%(@#{extension.kind}_extensions).to_sym)
+ extensions_store.unshift extensions_store.delete extension
+ extension
+ end
+
private
def add_document_processor kind, args, &block
kind_name = kind.to_s.tr '_', ' '
kind_class_symbol = kind_name.split.map {|it| it.capitalize }.join.to_sym
@@ -1296,15 +1357,12 @@
else
raise ::ArgumentError, %(Invalid arguments specified for registering #{kind_name} extension: #{args})
end
end
- if extension.config[:position] == :>>
- kind_store.unshift extension
- else
- kind_store << extension
- end
+ extension.config[:position] == :>> ? (kind_store.unshift extension) : (kind_store << extension)
+ extension
end
def add_syntax_processor kind, args, &block
kind_name = kind.to_s.tr '_', ' '
kind_class_symbol = (kind_name.split.map {|it| it.capitalize }.push 'Processor').join.to_sym
@@ -1488,18 +1546,18 @@
end
# Public: Resolves the Class object for the qualified name.
#
# Returns Class
- if RUBY_MIN_VERSION_2
+ if ::RUBY_MIN_VERSION_2
def class_for_name qualified_name
resolved = ::Object.const_get qualified_name, false
raise unless ::Class === resolved
resolved
rescue
raise ::NameError, %(Could not resolve class for name: #{qualified_name})
end
- elsif RUBY_MIN_VERSION_1_9
+ elsif ::RUBY_MIN_VERSION_1_9
def class_for_name qualified_name
resolved = (qualified_name.split '::').reduce ::Object do |current, name|
name.empty? ? current : (current.const_get name, false)
end
raise unless ::Class === resolved