Class: Kramdown::Parser::Base

Inherits:
Object
  • Object
show all
Defined in:
lib/kramdown/parser/base.rb

Overview

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 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!

Direct Known Subclasses

Html, Kramdown

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(source, options) ⇒ Base

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.



62
63
64
65
66
67
68
# File 'lib/kramdown/parser/base.rb', line 62

def initialize(source, options)
  @source = source
  @options = Kramdown::Options.merge(options)
  @root = Element.new(:root, nil, nil, :encoding => (RUBY_VERSION >= '1.9' ? source.encoding : nil))
  @warnings = []
  @text_type = :text
end

Instance Attribute Details

#optionsObject (readonly)

The hash with the parsing options.



47
48
49
# File 'lib/kramdown/parser/base.rb', line 47

def options
  @options
end

#rootObject (readonly)

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



56
57
58
# File 'lib/kramdown/parser/base.rb', line 56

def root
  @root
end

#sourceObject (readonly)

The original source string.



53
54
55
# File 'lib/kramdown/parser/base.rb', line 53

def source
  @source
end

#warningsObject (readonly)

The array with the parser warnings.



50
51
52
# File 'lib/kramdown/parser/base.rb', line 50

def warnings
  @warnings
end

Class Method Details

.parse(source, options = {}) ⇒ Object

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.



76
77
78
79
80
# File 'lib/kramdown/parser/base.rb', line 76

def self.parse(source, options = {})
  parser = new(source, options)
  parser.parse
  [parser.root, parser.warnings]
end

Instance Method Details

#adapt_source(source) ⇒ Object

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).



100
101
102
# File 'lib/kramdown/parser/base.rb', line 100

def adapt_source(source)
  source.gsub(/\r\n?/, "\n").chomp + "\n"
end

#add_text(text, tree = @tree, type = @text_type) ⇒ Object

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.



106
107
108
109
110
111
112
# File 'lib/kramdown/parser/base.rb', line 106

def add_text(text, tree = @tree, type = @text_type)
  if tree.children.last && tree.children.last.type == type
    tree.children.last.value << text
  elsif !text.empty?
    tree.children << Element.new(type, text)
  end
end

#extract_string(range, strscan) ⇒ Object

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.



116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
# File 'lib/kramdown/parser/base.rb', line 116

def extract_string(range, strscan)
  result = nil
  if RUBY_VERSION >= '1.9'
    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
  else
    result = strscan.string[range]
  end
  result
end

#parseObject

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!

Raises:

  • (NotImplementedError)


88
89
90
# File 'lib/kramdown/parser/base.rb', line 88

def parse
  raise NotImplementedError
end

#warning(text) ⇒ Object

Add the given warning text to the warning array.



93
94
95
96
# File 'lib/kramdown/parser/base.rb', line 93

def warning(text)
  @warnings << text
  #TODO: add position information
end