# class Kramdown::Converter::Base

## Base class for converters¶ ↑

This class serves as base class for all converters. It provides methods that can/should be used by all converters (like `generate_id`) as well as common functionality that is automatically applied to the result (for example, embedding the output into a template).

A converter object is used as a throw-away object, i.e. it is only used for storing the needed state information during conversion. Therefore one can't instantiate a converter object directly but only use the `Base::convert` method.

## Implementing a converter¶ ↑

Implementing a new converter is rather easy: just derive a new class from this class and put it in the `Kramdown::Converter` module (the latter is only needed if auto-detection should work properly). Then you need to implement the `convert` method which has to contain the conversion code for converting an element and has to return the conversion result.

The actual transformation of the document tree can be done in any way. However, writing one method per element type is a straight forward way to do it - this is how the `Html` and `Latex` converters do the transformation.

Have a look at the `Base::convert` method for additional information!

### Attributes

data[R]

Can be used by a converter for storing arbitrary information during the conversion process.

options[R]

The hash with the conversion options.

root[R]

The root element that is converted.

warnings[R]

The warnings array.

### Public Class Methods

convert(tree, options = {}) click to toggle source

Convert the element tree `tree` and return the resulting conversion object (normally a string) and an array with warning messages. The parameter `options` specifies the conversion options that should be used.

Initializes a new instance of the calling class and then calls the `convert` method with `tree` as parameter.

If the `template` option is specified and non-empty, the template is evaluate with ERB before and/or after the tree conversion depending on the result of `apply_template_before?` and `apply_template_after?`. If the template is evaluated before, an empty string is used for the body; if evaluated after, the result is used as body. See ::apply_template.

The template resolution is done in the following way (for the converter ConverterName):

1. Look in the current working directory for the template.

2. Append `.converter_name` (e.g. `.html`) to the template name and look for the resulting file in the current working directory (the form `.convertername` is deprecated).

3. Append `.converter_name` to the template name and look for it in the kramdown data directory (the form `.convertername` is deprecated).

4. Check if the template name starts with 'string://' and if so, strip this prefix away and use the rest as template.

        # File lib/kramdown/converter/base.rb
    100 def self.convert(tree, options = {})
    101   converter = new(tree, ::Kramdown::Options.merge(options.merge(tree.options[:options] || {})))
    102
    103   apply_template(converter, '') if !converter.options[:template].empty? && converter.apply_template_before?
    104   result = converter.convert(tree)
    105   result.encode!(tree.options[:encoding]) if result.respond_to?(:encode!) && result.encoding != Encoding::BINARY
    106   result = apply_template(converter, result) if !converter.options[:template].empty? && converter.apply_template_after?
    107
    108   [result, converter.warnings]
    109 end

get_template(template) click to toggle source

Return the template specified by `template`.

        # File lib/kramdown/converter/base.rb
    131 def self.get_template(template)
    132   #DEPRECATED: use content of #get_template_new in 2.0
    133   format_ext = '.' + self.name.split(/::/).last.downcase
    134   shipped = File.join(::Kramdown.data_dir, template + format_ext)
    135   if File.exist?(template)
    136     File.read(template)
    137   elsif File.exist?(template + format_ext)
    138     File.read(template + format_ext)
    139   elsif File.exist?(shipped)
    140     File.read(shipped)
    141   elsif template.start_with?('string://')
    142     template.sub(/\Astring:\/\//, '')
    143   else
    144     get_template_new(template)
    145   end
    146 end

### Private Class Methods

new(root, options) click to toggle source

Initialize the converter with the given `root` element and `options` hash.

       # File lib/kramdown/converter/base.rb
    54 def initialize(root, options)
    55   @options = options
    56   @root = root
    57   @data = {}
    58   @warnings = []
    59 end

### Public Instance Methods

apply_template_after?() click to toggle source

Returns whether the template should be applied after the conversion of the tree.

Defaults to true.

       # File lib/kramdown/converter/base.rb
    72 def apply_template_after?
    73   true
    74 end

apply_template_before?() click to toggle source

Returns whether the template should be applied before the conversion of the tree.

Defaults to false.

       # File lib/kramdown/converter/base.rb
    65 def apply_template_before?
    66   false
    67 end

basic_generate_id(str) click to toggle source

The basic version of the ID generator, without any special provisions for empty or unique IDs.

        # File lib/kramdown/converter/base.rb
    246 def basic_generate_id(str)
    247   gen_id = str.gsub(/^[^a-zA-Z]+/, '')
    248   gen_id.tr!('^a-zA-Z0-9 -', '')
    249   gen_id.tr!(' ', '-')
    250   gen_id.downcase!
    251   gen_id
    252 end

convert(el) click to toggle source

Convert the element `el` and return the resulting object.

This is the only method that has to be implemented by sub-classes!

        # File lib/kramdown/converter/base.rb
    114 def convert(el)
    115   raise NotImplementedError
    116 end

extract_code_language(attr) click to toggle source

Extract the code block/span language from the attributes.

        # File lib/kramdown/converter/base.rb
    183 def extract_code_language(attr)
    184   if attr['class'] && attr['class'] =~ /\blanguage-\S+/
    185     attr['class'].scan(/\blanguage-(\S+)/).first.first
    186   end
    187 end

extract_code_language!(attr) click to toggle source

See `extract_code_language`

Warning: This version will modify the given attributes if a language is present.

        # File lib/kramdown/converter/base.rb
    192 def extract_code_language!(attr)
    193   lang = extract_code_language(attr)
    194   attr['class'] = attr['class'].sub(/\blanguage-\S+/, '').strip if lang
    195   attr.delete('class') if lang && attr['class'].empty?
    196   lang
    197 end

format_math(el, opts = {}) click to toggle source

Format the given math element with the math engine configured through the option 'math_engine'.

        # File lib/kramdown/converter/base.rb
    215 def format_math(el, opts = {})
    216   return nil unless @options[:math_engine]
    217
    218   engine = ::Kramdown::Converter.math_engine(@options[:math_engine])
    219   if engine
    220     engine.call(self, el, opts)
    221   else
    222     warning("The configured math engine #{@options[:math_engine]} is not available.")
    223     nil
    224   end
    225 end

generate_id(str) click to toggle source

Generate an unique alpha-numeric ID from the the string `str` for use as a header ID.

Uses the option `auto_id_prefix`: the value of this option is prepended to every generated ID.

        # File lib/kramdown/converter/base.rb
    231 def generate_id(str)
    232   str = ::Kramdown::Utils::Unidecoder.decode(str) if @options[:transliterated_header_ids]
    233   gen_id = basic_generate_id(str)
    234   gen_id = 'section' if gen_id.length == 0
    235   @used_ids ||= {}
    236   if @used_ids.has_key?(gen_id)
    237     gen_id += '-' << (@used_ids[gen_id] += 1).to_s
    238   else
    239     @used_ids[gen_id] = 0
    240   end
    241   @options[:auto_id_prefix] + gen_id
    242 end

highlight_code(text, lang, type, opts = {}) click to toggle source

Highlight the given `text` in the language `lang` with the syntax highlighter configured through the option 'syntax_highlighter'.

        # File lib/kramdown/converter/base.rb
    201 def highlight_code(text, lang, type, opts = {})
    202   return nil unless @options[:syntax_highlighter]
    203
    204   highlighter = ::Kramdown::Converter.syntax_highlighter(@options[:syntax_highlighter])
    205   if highlighter
    206     highlighter.call(self, text, lang, type, opts)
    207   else
    208     warning("The configured syntax highlighter #{@options[:syntax_highlighter]} is not available.")
    209     nil
    210   end
    211 end

output_header_level(level) click to toggle source

Return the output header level given a level.

Uses the `header_offset` option for adjusting the header level.

        # File lib/kramdown/converter/base.rb
    178 def output_header_level(level)
    179   [[level + @options[:header_offset], 6].min, 1].max
    180 end

smart_quote_entity(el) click to toggle source

Return the entity that represents the given smart_quote element.

        # File lib/kramdown/converter/base.rb
    257 def smart_quote_entity(el)
    258   res = @options[:smart_quotes][SMART_QUOTE_INDICES[el.value]]
    259   ::Kramdown::Utils::Entities.entity(res)
    260 end

warning(text) click to toggle source

Add the given warning `text` to the warning array.

        # File lib/kramdown/converter/base.rb
    165 def warning(text)
    166   @warnings << text
    167 end