class Asciidoctor::Extensions::Registry

def add_syntax_processor kind, args, &block

def add_syntax_processor kind, args, &block
  kind_name = kind.to_s.tr '_', ' '
  kind_class_symbol = (kind_name.split.map {|it| it.capitalize } << 'Processor').join.to_sym
  kind_class = Extensions.const_get kind_class_symbol, false
  kind_java_class = (defined? ::AsciidoctorJ) ? (::AsciidoctorJ::Extensions.const_get kind_class_symbol, false) : nil
  kind_store = instance_variable_get(%(@#{kind}_extensions).to_sym) || instance_variable_set(%(@#{kind}_extensions).to_sym, {})
  # style 1: specified as block
  if block_given?
    name, config = resolve_args args, 2
    (processor = kind_class.new (as_symbol name), config).singleton_class.enable_dsl
    if block.arity == 0
      processor.instance_exec(&block)
    else
      yield processor
    end
    unless (name = as_symbol processor.name)
      raise ::ArgumentError, %(No name specified for #{kind_name} extension at #{block.source_location})
    end
    unless processor.process_block_given?
      raise ::NoMethodError, %(No block specified to process #{kind_name} extension at #{block.source_location})
    end
    processor.freeze
    kind_store[name] = ProcessorExtension.new kind, processor
  else
    processor, name, config = resolve_args args, 3
    # style 2: specified as Class or String class name
    if (processor_class = Helpers.resolve_class processor)
      unless processor_class < kind_class || (kind_java_class && processor_class < kind_java_class)
        raise ::ArgumentError, %(Class specified for #{kind_name} extension does not inherit from #{kind_class}: #{processor})
      end
      processor_instance = processor_class.new as_symbol(name), config
      unless (name = as_symbol processor_instance.name)
        raise ::ArgumentError, %(No name specified for #{kind_name} extension: #{processor})
      end
      processor_instance.freeze
      kind_store[name] = ProcessorExtension.new kind, processor_instance
    # style 3: specified as instance
    elsif kind_class === processor || (kind_java_class && kind_java_class === processor)
      processor.update_config config
      # TODO need a test for this override!
      unless (name = name ? (processor.name = as_symbol name) : (as_symbol processor.name))
        raise ::ArgumentError, %(No name specified for #{kind_name} extension: #{processor})
      end
      processor.freeze
      kind_store[name] = ProcessorExtension.new kind, processor
    else
      raise ::ArgumentError, %(Invalid arguments specified for registering #{kind_name} extension: #{args})
    end
  end
end