Class: Kramdown::Converter::Base

Inherits:
Object
  • Object
show all
Defined in:
lib/kramdown/converter/base.rb

Overview

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!

Direct Known Subclasses

Html, Kramdown, Latex, Toc

Constant Summary collapse

SMART_QUOTE_INDICES =

:nodoc:

{:lsquo => 0, :rsquo => 1, :ldquo => 2, :rdquo => 3}

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(root, options) ⇒ Base

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



66
67
68
69
70
71
# File 'lib/kramdown/converter/base.rb', line 66

def initialize(root, options)
  @options = options
  @root = root
  @data = {}
  @warnings = []
end

Instance Attribute Details

#dataObject (readonly)

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



54
55
56
# File 'lib/kramdown/converter/base.rb', line 54

def data
  @data
end

#optionsObject (readonly)

The hash with the conversion options.



57
58
59
# File 'lib/kramdown/converter/base.rb', line 57

def options
  @options
end

#rootObject (readonly)

The root element that is converted.



60
61
62
# File 'lib/kramdown/converter/base.rb', line 60

def root
  @root
end

#warningsObject (readonly)

The warnings array.



63
64
65
# File 'lib/kramdown/converter/base.rb', line 63

def warnings
  @warnings
end

Class Method Details

.apply_template(converter, body) ⇒ Object

Apply the template using body as the body string.



104
105
106
107
108
109
110
# File 'lib/kramdown/converter/base.rb', line 104

def self.apply_template(converter, body) # :nodoc:
  erb = ERB.new(get_template(converter.options[:template]))
  obj = Object.new
  obj.instance_variable_set(:@converter, converter)
  obj.instance_variable_set(:@body, body)
  erb.result(obj.instance_eval{binding})
end

.convert(tree, options = {}) ⇒ Object

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 result is rendered into the specified template. The template resolution is done in the following way:

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

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

  3. Append .convertername to the template name and look for it in the kramdown data directory.



89
90
91
92
93
94
# File 'lib/kramdown/converter/base.rb', line 89

def self.convert(tree, options = {})
  converter = new(tree, ::Kramdown::Options.merge(options.merge(tree.options[:options] || {})))
  result = converter.convert(tree)
  result = apply_template(converter, result) if !converter.options[:template].empty?
  [result, converter.warnings]
end

.get_template(template) ⇒ Object

Return the template specified by template.



113
114
115
116
117
118
119
120
121
122
123
124
125
# File 'lib/kramdown/converter/base.rb', line 113

def self.get_template(template) # :nodoc:
  format_ext = '.' + self.name.split(/::/).last.downcase
  shipped = File.join(::Kramdown.data_dir, template + format_ext)
  if File.exist?(template)
    File.read(template)
  elsif File.exist?(template + format_ext)
    File.read(template + format_ext)
  elsif File.exist?(shipped)
    File.read(shipped)
  else
    raise "The specified template file #{template} does not exist"
  end
end

Instance Method Details

#convert(el) ⇒ Object

Convert the element el and return the resulting object.

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

Raises:

  • (NotImplementedError)


99
100
101
# File 'lib/kramdown/converter/base.rb', line 99

def convert(el)
  raise NotImplementedError
end

#generate_id(str) ⇒ Object

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.



142
143
144
145
146
147
148
149
150
151
152
153
154
155
# File 'lib/kramdown/converter/base.rb', line 142

def generate_id(str)
  gen_id = str.gsub(/^[^a-zA-Z]+/, '')
  gen_id.tr!('^a-zA-Z0-9 -', '')
  gen_id.tr!(' ', '-')
  gen_id.downcase!
  gen_id = 'section' if gen_id.length == 0
  @used_ids ||= {}
  if @used_ids.has_key?(gen_id)
    gen_id += '-' << (@used_ids[gen_id] += 1).to_s
  else
    @used_ids[gen_id] = 0
  end
  @options[:auto_id_prefix] + gen_id
end

#in_toc?(el) ⇒ Boolean

Return true if the header element el should be used for the table of contents (as specified by the toc_levels option).

Returns:

  • (Boolean)


134
135
136
# File 'lib/kramdown/converter/base.rb', line 134

def in_toc?(el)
  @options[:toc_levels].include?(el.options[:level])
end

#smart_quote_entity(el) ⇒ Object

Return the entity that represents the given smart_quote element.



160
161
162
163
# File 'lib/kramdown/converter/base.rb', line 160

def smart_quote_entity(el)
  res = @options[:smart_quotes][SMART_QUOTE_INDICES[el.value]]
  ::Kramdown::Utils::Entities.entity(res)
end

#warning(text) ⇒ Object

Add the given warning text to the warning array.



128
129
130
# File 'lib/kramdown/converter/base.rb', line 128

def warning(text)
  @warnings << text
end