class Kramdown::Parser::Base

Have a look at the Base::parse, Base::new and Base#parse methods for additional information!
the parsing code.
parser works correctly. Then you need to implement the #parse method which has to contain
in the Kramdown::Parser module – the latter is needed so that the auto-detection of the new
Implementing a new parser is rather easy: just derive a new class from this class and put it
== Implementing a parser
only use the Base::parse method.
state information during parsing. Therefore one can’t instantiate a parser object directly but
A parser object is used as a throw-away object, i.e. it is only used for storing the needed
used by all parsers, especially by those using StringScanner(Kramdown) for parsing.
This class serves as base class for parsers. It provides common methods that can/should be
== Base class for parsers

def self.parse(source, options = {})

be implemented by each subclass.
Initializes a new instance of the calling class and then calls the +#parse+ method that must

return the root element of the element tree and an array with warning messages.
Parse the +source+ string into an element tree, possibly using the parsing +options+, and
def self.parse(source, options = {})
  parser = new(source, options)
  parser.parse
  [parser.root, parser.warnings]
end

def adapt_source(source)

+\n+ and makes sure +source+ ends with a new line character).
Modify the string +source+ to be usable by the parser (unifies line ending characters to
def adapt_source(source)
  unless source.valid_encoding?
    raise "The source text contains invalid characters for the used encoding #{source.encoding}"
  end
  source = source.encode('UTF-8')
  source.gsub!(/\r\n?/, "\n")
  source.chomp!
  source << "\n"
end

def add_text(text, tree = @tree, type = @text_type)

+type+ element or creates a new text element with the given +type+.
This helper method adds the given +text+ either to the last element in the +tree+ if it is a
def add_text(text, tree = @tree, type = @text_type)
  last = tree.children.last
  if last && last.type == type
    last.value << text
  elsif !text.empty?
    location = (last && last.options[:location] || tree.options[:location])
    tree.children << Element.new(type, text, nil, location: location)
  end
end

def extract_string(range, strscan)

method works correctly under Ruby 1.8 and Ruby 1.9.
Extract the part of the StringScanner +strscan+ backed string specified by the +range+. This
def extract_string(range, strscan)
  result = nil
  begin
    enc = strscan.string.encoding
    strscan.string.force_encoding('ASCII-8BIT')
    result = strscan.string[range].force_encoding(enc)
  ensure
    strscan.string.force_encoding(enc)
  end
  result
end

def initialize(source, options)

created text nodes) are automatically initialized.
The @root element, the @warnings array and @text_type (specifies the default type for newly

Initialize the parser object with the +source+ string and the parsing +options+.
def initialize(source, options)
  @source = source
  @options = Kramdown::Options.merge(options)
  @root = Element.new(:root, nil, nil, encoding: (source.encoding rescue nil), location: 1,
                      options: {}, abbrev_defs: {}, abbrev_attr: {})
  @root.options[:abbrev_defs].default_proc = @root.options[:abbrev_attr].default_proc =
    lambda do |h, k|
      k_mod = k.gsub(/[\s\p{Z}]+/, " ")
      k != k_mod ? h[k_mod] : nil
    end
  @warnings = []
  @text_type = :text
end

def parse

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

root of which should be @root.
The parsing code should parse the source provided in @source and build an element tree the

Parse the source string into an element tree.
def parse
  raise NotImplementedError
end

def warning(text)

Add the given warning +text+ to the warning array.
def warning(text)
  @warnings << text
  # TODO: add position information
end