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
The hash with the parsing options.
The root element of element tree that is created from the source string.
The original source string.
The array with the parser warnings.
Public Class Methods
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 72 def self.parse(source, options = {}) 73 parser = new(source, options) 74 parser.parse 75 [parser.root, parser.warnings] 76 end
Private Class Methods
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 57 @root.options[:abbrev_defs].default_proc = @root.options[:abbrev_attr].default_proc = 58 lambda do |h, k| 59 k_mod = k.gsub(/[\s\p{Z}]+/, " ") 60 k != k_mod ? h[k_mod] : nil 61 end 62 @warnings = [] 63 @text_type = :text 64 end
Public Instance Methods
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 96 def adapt_source(source) 97 unless source.valid_encoding? 98 raise "The source text contains invalid characters for the used encoding #{source.encoding}" 99 end 100 source = source.encode('UTF-8') 101 source.gsub!(/\r\n?/, "\n") 102 source.chomp! 103 source << "\n" 104 end
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 108 def add_text(text, tree = @tree, type = @text_type) 109 last = tree.children.last 110 if last && last.type == type 111 last.value << text 112 elsif !text.empty? 113 location = (last && last.options[:location] || tree.options[:location]) 114 tree.children << Element.new(type, text, nil, location: location) 115 end 116 end
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 120 def extract_string(range, strscan) 121 result = nil 122 begin 123 enc = strscan.string.encoding 124 strscan.string.force_encoding('ASCII-8BIT') 125 result = strscan.string[range].force_encoding(enc) 126 ensure 127 strscan.string.force_encoding(enc) 128 end 129 result 130 end
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 84 def parse 85 raise NotImplementedError 86 end
Add the given warning text
to the warning array.
# File lib/kramdown/parser/base.rb 89 def warning(text) 90 @warnings << text 91 # TODO: add position information 92 end