class Kramdown::Parser::Kramdown

def parse_definition_list

Parse the ordered or unordered list at the current location.
def parse_definition_list
  children = @tree.children
  if !children.last || (children.length == 1 && children.last.type != :p) ||
      (children.length >= 2 && children[-1].type != :p &&
       (children[-1].type != :blank || children[-1].value != "\n" || children[-2].type != :p))
    return false
  end
  first_as_para = false
  deflist = new_block_el(:dl)
  para = @tree.children.pop
  if para.type == :blank
    para = @tree.children.pop
    first_as_para = true
  end
  # take location from preceding para which is the first definition term
  deflist.options[:location] = para.options[:location]
  para.children.first.value.split(/\n/).each do |term|
    el = Element.new(:dt, nil, nil, location: @src.current_line_number)
    term.sub!(self.class::LIST_ITEM_IAL) do
      parse_attribute_list($1, el.options[:ial] ||= {})
      ''
    end
    el.options[:raw_text] = term
    el.children << Element.new(:raw_text, term)
    deflist.children << el
  end
  deflist.options[:ial] = para.options[:ial]
  item = nil
  content_re, lazy_re, indent_re = nil
  def_start_re = DEFINITION_LIST_START
  last_is_blank = false
  until @src.eos?
    start_line_number = @src.current_line_number
    if @src.scan(def_start_re)
      item = Element.new(:dd, nil, nil, location: start_line_number)
      item.options[:first_as_para] = first_as_para
      item.value, indentation, content_re, lazy_re, indent_re =
        parse_first_list_line(@src[1].length, @src[2])
      deflist.children << item
      item.value.sub!(self.class::LIST_ITEM_IAL) do |_match|
        parse_attribute_list($1, item.options[:ial] ||= {})
        ''
      end
      def_start_re = /^( {0,#{[3, indentation - 1].min}}:)([\t| ].*?\n)/
      first_as_para = false
      last_is_blank = false
    elsif @src.check(EOB_MARKER)
      break
    elsif (result = @src.scan(content_re)) || (!last_is_blank && (result = @src.scan(lazy_re)))
      result.sub!(/^(\t+)/) { " " * ($1 ? 4 * $1.length : 0) }
      result.sub!(indent_re, '')
      item.value << result
      first_as_para = false
      last_is_blank = false
    elsif (result = @src.scan(BLANK_LINE))
      first_as_para = true
      item.value << result
      last_is_blank = true
    else
      break
    end
  end
  last = nil
  deflist.children.each do |it|
    next if it.type == :dt
    parse_blocks(it, it.value)
    it.value = nil
    next if it.children.empty?
    last = (it.children.last.type == :blank ? it.children.pop : nil)
    if it.children.first && it.children.first.type == :p && !it.options.delete(:first_as_para)
      it.children.first.children.first.value << "\n" if it.children.size > 1
      it.children.first.options[:transparent] = true
    end
  end
  if @tree.children.length >= 1 && @tree.children.last.type == :dl
    @tree.children[-1].children.concat(deflist.children)
  elsif @tree.children.length >= 2 && @tree.children[-1].type == :blank &&
      @tree.children[-2].type == :dl
    @tree.children.pop
    @tree.children[-1].children.concat(deflist.children)
  else
    @tree.children << deflist
  end
  @tree.children << last if last
  true
end