Class: Asciidoctor::Extensions::Processor

Inherits:
Object
  • Object
show all
Defined in:
lib/asciidoctor/extensions.rb

Overview

An abstract base class for document and syntax processors.

This class provides access to a class-level Hash for holding default configuration options defined using the Processor.option method. This style of default configuration is specific to the native Ruby environment and is only consulted inside the initializer. An overriding configuration Hash can be passed to the initializer. Once the processor is initialized, the configuration is accessed using the #config instance variable.

Instances of the Processor class provide convenience methods for creating AST nodes, such as Block and Inline, and for parsing child content.

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(config = {}) ⇒ Processor

Returns a new instance of Processor.



80
81
82
# File 'lib/asciidoctor/extensions.rb', line 80

def initialize config = {}
  @config = self.class.config.merge config
end

Instance Attribute Details

#configObject (readonly)

Get the configuration Hash for this processor instance.



78
79
80
# File 'lib/asciidoctor/extensions.rb', line 78

def config
  @config
end

Class Method Details

.configHash

Get the static configuration for this processor class.

Returns:

  • (Hash)

    Returns a configuration



43
44
45
# File 'lib/asciidoctor/extensions.rb', line 43

def config
  @config ||= {}
end

.enable_dslObject Also known as: use_dsl

Mixes the DSL class for this processor into this processor class or instance.

This method automatically detects whether to use the include or extend keyword to mix in the module.

NOTE Inspiration for this DSL design comes from corcoran.io/2013/09/04/simple-pattern-ruby-dsl/

Returns:

  • self



66
67
68
69
70
71
72
73
# File 'lib/asciidoctor/extensions.rb', line 66

def enable_dsl
  return unless const_defined? :DSL
  if singleton_class?
    include const_get :DSL
  else
    extend const_get :DSL
  end
end

.option(key, default_value) ⇒ void

This method returns an undefined value.

Assigns a default value for the specified option that gets applied to all instances of this processor.

Examples:

option :contexts, [:open, :paragraph]


55
56
57
# File 'lib/asciidoctor/extensions.rb', line 55

def option key, default_value
  config[key] = default_value
end

Instance Method Details

#create_block(parent, context, source, attrs, opts = {}) ⇒ Object



154
155
156
# File 'lib/asciidoctor/extensions.rb', line 154

def create_block parent, context, source, attrs, opts = {}
  Block.new parent, context, { source: source, attributes: attrs }.merge(opts)
end

#create_image_block(parent, attrs, opts = {}) ⇒ Block

Creates an image block node and links it to the specified parent.

Parameters:

  • 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. Use the alt attribute to specify an alternative text for the image.

  • opts (defaults to: {})

    An optional Hash of options (default: {})

Returns:

  • (Block)

    Returns a Block node with all properties properly initialized.



190
191
192
193
194
195
196
197
198
199
200
201
202
# File 'lib/asciidoctor/extensions.rb', line 190

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 '_-', ' ')
  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'), 'figure'
  end
  block
end

#create_inline(parent, context, text, opts = {}) ⇒ Inline

Creates an inline node and binds it to the specified parent.

Parameters:

  • parent

    The parent Block of this new inline node.

  • context

    The context of the inline node to create (e.g., :quoted, :anchor, etc).

  • text

    The text of the inline node.

  • opts (defaults to: {})

    An optional Hash of options (default: {}):

Options Hash (opts):

  • :type (Object)

    The subtype of the inline node context. For a :quoted node, this can be :strong, :emphasis, :monospaced, etc. For an :anchor node, this can be

  • :attributes (Object)

    The attributes to set on the inline node. If the “subs” attribute is specified, the convert will apply the specified substitutions to the

Returns:

  • (Inline)

    Returns an Inline node with all properties properly initialized.



218
219
220
# File 'lib/asciidoctor/extensions.rb', line 218

def create_inline parent, context, text, opts = {}
  Inline.new parent, context, text, context == :quoted ? ({ type: :unquoted }.merge opts) : opts
end

#create_list(parent, context, attrs = nil) ⇒ List

Creates a list node and links it to the specified parent.

Parameters:

  • parent

    The parent Block (Block, Section, or Document) of this new list block.

  • context

    The list context (e.g., :ulist, :olist, :colist, :dlist)

  • attrs (defaults to: nil)

    A Hash of attributes to set on this list block

Returns:

  • (List)

    Returns a List node with all properties properly initialized.



165
166
167
168
169
# File 'lib/asciidoctor/extensions.rb', line 165

def create_list parent, context, attrs = nil
  list = List.new parent, context
  list.update_attributes attrs if attrs
  list
end

#create_list_item(parent, text = nil) ⇒ ListItem

Creates a list item node and links it to the specified parent.

Parameters:

  • parent

    The parent List of this new list item block.

  • text (defaults to: nil)

    The text of the list item.

Returns:

  • (ListItem)

    Returns a ListItem node with all properties properly initialized.



177
178
179
# File 'lib/asciidoctor/extensions.rb', line 177

def create_list_item parent, text = nil
  ListItem.new parent, text
end

#create_section(parent, title, attrs, opts = {}) ⇒ Section

Creates a new Section node.

Creates a Section node in the same manner as the parser.

Parameters:

  • parent

    The parent Section (or Document) of this new Section.

  • title

    The String title of the new Section.

  • attrs

    A Hash of attributes to control how the section is built. Use the style attribute to set the name of a special section (ex. appendix). Use the id attribute to assign an explicit ID or set the value to false to disable automatic ID generation (when sectids document attribute is set).

  • opts (defaults to: {})

    An optional Hash of options (default: {}):

Options Hash (opts):

  • :level (Integer)

    The level to assign to this section; defaults to one greater than the parent level (optional).

  • :numbered (Boolean)

    A flag to force numbering, which falls back to the state of the sectnums document attribute (optional).

Returns:

  • (Section)

    Returns a Section node with all properties properly initialized.



111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
# File 'lib/asciidoctor/extensions.rb', line 111

def create_section parent, title, attrs, opts = {}
  doc = parent.document
  book = (doctype = doc.doctype) == 'book'
  level = opts[:level] || parent.level + 1
  if (style = attrs.delete 'style')
    if book && style == 'abstract'
      sectname, level = 'chapter', 1
    else
      sectname, special = style, true
      level = 1 if level == 0
    end
  elsif book
    sectname = level == 0 ? 'part' : (level > 1 ? 'section' : 'chapter')
  elsif doctype == 'manpage' && (title.casecmp 'synopsis') == 0
    sectname, special = 'synopsis', true
  else
    sectname = 'section'
  end
  sect = Section.new parent, level
  sect.title, sect.sectname = title, sectname
  if special
    sect.special = true
    if opts.fetch :numbered, (style == 'appendix')
      sect.numbered = true
    elsif !(opts.key? :numbered) && (doc.attr? 'sectnums', 'all')
      sect.numbered = (book && level == 1 ? :chapter : true)
    end
  elsif level > 0
    if opts.fetch :numbered, (doc.attr? 'sectnums')
      sect.numbered = sect.special ? parent.numbered && true : true
    end
  elsif opts.fetch :numbered, (book && (doc.attr? 'partnums'))
    sect.numbered = true
  end
  if (id = attrs['id']) == false
    attrs.delete 'id'
  else
    sect.id = attrs['id'] = id || ((doc.attr? 'sectids') ? (Section.generate_id sect.title, doc) : nil)
  end
  sect.update_attributes attrs
  sect
end

#parse_attributes(block, attrlist, opts = {}) ⇒ Object

Parses the attrlist String into a Hash of attributes

Parameters:

  • block

    the current AbstractBlock or the parent AbstractBlock if there is no current block (used for applying subs)

  • attrlist

    the list of attributes as a String

  • opts (defaults to: {})

    an optional Hash of options to control processing:

Options Hash (opts):

  • :positional_attributes (Object)

    an Array of attribute names to map positional arguments to (optional, default: false)

  • :sub_attributes (Object)

    enables attribute substitution on the attrlist argument (optional, default: false)

Returns:

  • a Hash of parsed attributes



242
243
244
245
246
# File 'lib/asciidoctor/extensions.rb', line 242

def parse_attributes block, attrlist, opts = {}
  return {} if attrlist ? attrlist.empty? : true
  attrlist = block.sub_attributes attrlist if opts[:sub_attributes] && (attrlist.include? ATTR_REF_HEAD)
  (AttributeList.new attrlist).parse opts[:positional_attributes] || []
end

#parse_content(parent, content, attributes = nil) ⇒ The

Parses blocks in the content and attaches the block to the parent.

Returns:

  • (The)

    parent node into which the blocks are parsed. – QUESTION is parse_content the right method name? should we wrap in open block automatically?



227
228
229
230
231
# File 'lib/asciidoctor/extensions.rb', line 227

def parse_content parent, content, attributes = nil
  reader = Reader === content ? content : (Reader.new content)
  Parser.parse_blocks reader, parent, attributes
  parent
end

#process(*args) ⇒ Object

Raises:

  • (::NotImplementedError)


88
89
90
# File 'lib/asciidoctor/extensions.rb', line 88

def process *args
  raise ::NotImplementedError, %(#{Processor} subclass #{self.class} must implement the ##{__method__} method)
end

#update_config(config) ⇒ Object



84
85
86
# File 'lib/asciidoctor/extensions.rb', line 84

def update_config config
  @config.update config
end