class Kramdown::Parser::Kramdown

Used for parsing a document in kramdown format.

def self.parse(source, doc)

Parse the string +source+ using the Kramdown::Document +doc+ and return the parse tree.
def self.parse(source, doc)
  new(doc).parse(source)
end

def adapt_source(source)

Modify the string +source+ to be usable by the parser.
def adapt_source(source)
  source.gsub(/\r\n?/, "\n").chomp + "\n"
end

def add_text(text, tree = @tree)

text element or creates a new text element.
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)
  if tree.children.last && tree.children.last.type == :text
    tree.children.last.value << text
  elsif !text.empty?
    tree.children << Element.new(:text, text)
  end
end

def configure_parser

Adapt the object to allow parsing like specified in the options.
def configure_parser
  @parsers = {}
  BLOCK_PARSERS.each do |name|
    if Registry.has_parser?(name, :block)
      extend(Registry.parser(name).module)
      @parsers[name] = Registry.parser(name)
    else
      raise Kramdown::Error, "Unknown block parser: #{name}"
    end
  end
  SPAN_PARSERS.each do |name|
    if Registry.has_parser?(name, :span)
      extend(Registry.parser(name).module)
      @parsers[name] = Registry.parser(name)
    else
      raise Kramdown::Error, "Unknown span parser: #{name}"
    end
  end
  @span_start = Regexp.union(*SPAN_PARSERS.map {|name| @parsers[name].start_re})
  @span_start_re = /(?=#{@span_start})/
end

def initialize(doc)

Create a new Kramdown parser object for the Kramdown::Document +doc+.
def initialize(doc)
  @doc = doc
  @src = nil
  @tree = nil
  @unclosed_html_tags = []
  @stack = []
  @used_ids = {}
  @doc.parse_infos[:ald] = {}
  @doc.parse_infos[:link_defs] = {}
  @doc.parse_infos[:footnotes] = {}
end

def parse(source)

The source string provided on initialization is parsed and the created +tree+ is returned.
def parse(source)
  configure_parser
  tree = Element.new(:root)
  parse_blocks(tree, adapt_source(source))
  update_tree(tree)
  @doc.parse_infos[:footnotes].each do |name, data|
    update_tree(data[:content])
  end
  tree
end

def parse_blocks(el, text)

element +el+.
Parse all block level elements in +text+ (a string or a StringScanner object) into the
def parse_blocks(el, text)
  @stack.push([@tree, @src, @unclosed_html_tags])
  @tree, @src, @unclosed_html_tags = el, StringScanner.new(text), []
  while !@src.eos?
    BLOCK_PARSERS.any? do |name|
      if @src.check(@parsers[name].start_re)
        send(@parsers[name].method)
      else
        false
      end
    end || begin
      warning('Warning: this should not occur - no block parser handled the line')
      add_text(@src.scan(/.*\n/))
    end
  end
  @unclosed_html_tags.reverse.each do |tag|
    warning("Automatically closing unclosed html tag '#{tag.value}'")
  end
  @tree, @src, @unclosed_html_tags = *@stack.pop
end

def parse_spans(el, stop_re = nil)

Parse all span level elements in the source string.
def parse_spans(el, stop_re = nil)
  @stack.push(@tree)
  @tree = el
  used_re = (stop_re.nil? ? @span_start_re : /(?=#{Regexp.union(stop_re, @span_start)})/)
  stop_re_found = false
  while !@src.eos? && !stop_re_found
    if result = @src.scan_until(used_re)
      add_text(result)
      if stop_re && (stop_re_matched = @src.check(stop_re))
        stop_re_found = (block_given? ? yield : true)
      end
      processed = SPAN_PARSERS.any? do |name|
        if @src.check(@parsers[name].start_re)
          send(@parsers[name].method)
          true
        else
          false
        end
      end unless stop_re_found
      if !processed && !stop_re_found
        if stop_re_matched
          add_text(@src.scan(/./))
        else
          raise Kramdown::Error, 'Bug: please report!'
        end
      end
    else
      add_text(@src.scan_until(/.*/m)) unless stop_re
      break
    end
  end
  @tree = @stack.pop
  stop_re_found
end

def update_tree(element)

+@tree+, +@src+ and the +@stack+) and by updating the attributes from the IALs.
Update the tree by parsing all :text elements with the span level parser (resets
def update_tree(element)
  element.children.map! do |child|
    if child.type == :text
      @stack, @tree = [], nil
      @src = StringScanner.new(child.value)
      parse_spans(child)
      child.children
    else
      update_tree(child)
      update_attr_with_ial(child.options[:attr] ||= {}, child.options[:ial]) if child.options[:ial]
      child
    end
  end.flatten!
end

def warning(text)

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