# class Kramdown::Parser::Base

## Base class for parsers¶ ↑

This class serves as base class for parsers. It provides common methods that can/should be used by all parsers, especially by those using StringScanner(`Kramdown`) for parsing.

A parser object is used as a throw-away object, i.e. it is only used for storing the needed state information during parsing. Therefore one can't instantiate a parser object directly but only use the `Base::parse` method.

## Implementing a parser¶ ↑

Implementing a new parser is rather easy: just derive a new class from this class and put it in the `Kramdown::Parser` module – the latter is needed so that the auto-detection of the new parser works correctly. Then you need to implement the `#parse` method which has to contain the parsing code.

Have a look at the `Base::parse`, `Base::new` and `Base#parse` methods for additional information!

### Attributes

options[R]

The hash with the parsing options.

root[R]

The root element of element tree that is created from the source string.

source[R]

The original source string.

warnings[R]

The array with the parser warnings.

### Public Class Methods

parse(source, options = {}) click to toggle source

Parse the `source` string into an element tree, possibly using the parsing `options`, and return the root element of the element tree and an array with warning messages.

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

       # File lib/kramdown/parser/base.rb
    66 def self.parse(source, options = {})
    67   parser = new(source, options)
    68   parser.parse
    69   [parser.root, parser.warnings]
    70 end

### Private Class Methods

new(source, options) click to toggle source

Initialize the parser object with the `source` string and the parsing `options`.

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

       # File lib/kramdown/parser/base.rb
    51 def initialize(source, options)
    52   @source = source
    53   @options = Kramdown::Options.merge(options)
    54   @root = Element.new(:root, nil, nil, :encoding => (source.encoding rescue nil), :location => 1,
    55                       :options => {}, :abbrev_defs => {}, :abbrev_attr => {})
    56   @warnings = []
    57   @text_type = :text
    58 end

### Public Instance Methods

adapt_source(source) click to toggle source

Modify the string `source` to be usable by the parser (unifies line ending characters to `\n` and makes sure `source` ends with a new line character).

       # File lib/kramdown/parser/base.rb
    90 def adapt_source(source)
    91   unless source.valid_encoding?
    92     raise "The source text contains invalid characters for the used encoding #{source.encoding}"
    93   end
    94   source = source.encode('UTF-8')
    95   source.gsub(/\r\n?/, "\n").chomp + "\n"
    96 end

add_text(text, tree = @tree, type = @text_type) click to toggle source

This helper method adds the given `text` either to the last element in the `tree` if it is a `type` element or creates a new text element with the given `type`.

        # File lib/kramdown/parser/base.rb
    100 def add_text(text, tree = @tree, type = @text_type)
    101   last = tree.children.last
    102   if last && last.type == type
    103     last.value << text
    104   elsif !text.empty?
    105     tree.children << Element.new(type, text, nil, :location => (last && last.options[:location] || tree.options[:location]))
    106   end
    107 end

extract_string(range, strscan) click to toggle source

Extract the part of the StringScanner `strscan` backed string specified by the `range`. This method works correctly under Ruby 1.8 and Ruby 1.9.

        # File lib/kramdown/parser/base.rb
    111 def extract_string(range, strscan)
    112   result = nil
    113   begin
    114     enc = strscan.string.encoding
    115     strscan.string.force_encoding('ASCII-8BIT')
    116     result = strscan.string[range].force_encoding(enc)
    117   ensure
    118     strscan.string.force_encoding(enc)
    119   end
    120   result
    121 end

parse() click to toggle source

Parse the source string into an element tree.

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

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

       # File lib/kramdown/parser/base.rb
    78 def parse
    79   raise NotImplementedError
    80 end

warning(text) click to toggle source

Add the given warning `text` to the warning array.

       # File lib/kramdown/parser/base.rb
    83 def warning(text)
    84   @warnings << text
    85   #TODO: add position information
    86 end