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.



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

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

Instance Attribute Details

#configObject (readonly)

Get the configuration Hash for this processor instance.



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

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
74
# File 'lib/asciidoctor/extensions.rb', line 66

def enable_dsl
  if const_defined? :DSL
    if singleton_class?
      include const_get :DSL
    else
      extend const_get :DSL
    end
  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



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

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.



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

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 = {}) ⇒ Object



205
206
207
# File 'lib/asciidoctor/extensions.rb', line 205

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.



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

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.



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

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.



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
153
# File 'lib/asciidoctor/extensions.rb', line 112

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
  else
    sect.numbered = true if opts.fetch :numbered, (book && (doc.attr? 'partnums'))
  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



229
230
231
232
233
# File 'lib/asciidoctor/extensions.rb', line 229

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?



214
215
216
217
218
# File 'lib/asciidoctor/extensions.rb', line 214

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)


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

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

#update_config(config) ⇒ Object



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

def update_config config
  @config.update config
end