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
Can be used by a converter for storing arbitrary information during the conversion process.
The hash with the conversion options.
The root element that is converted.
The warnings array.
Public Class Methods
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):
-
Look in the current working directory for the template.
-
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). -
Append
.converter_name
to the template name and look for it in the kramdown data directory (the form.convertername
is deprecated). -
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
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
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
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
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
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 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 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
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 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 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 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
Return true
if the header element el
should be used for the table of contents (as specified by the toc_levels
option).
# File lib/kramdown/converter/base.rb 171 def in_toc?(el) 172 @options[:toc_levels].include?(el.options[:level]) && (el.attr['class'] || '') !~ /\bno_toc\b/ 173 end
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
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
Add the given warning text
to the warning array.
# File lib/kramdown/converter/base.rb 165 def warning(text) 166 @warnings << text 167 end