Class: Ruty::Parser

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

Overview

the parser class. parses a given template into a nodelist

Defined Under Namespace

Classes: ArgumentLexer

Constant Summary collapse

TAG_REGEX =
/
  (.*?)(?:
    #{Regexp.escape(Constants::BLOCK_START)}    (.*?)
    #{Regexp.escape(Constants::BLOCK_END)}          |
    #{Regexp.escape(Constants::VAR_START)}      (.*?)
    #{Regexp.escape(Constants::VAR_END)}            |
    #{Regexp.escape(Constants::COMMENT_START)}  (.*?)
    #{Regexp.escape(Constants::COMMENT_END)}
  )
/xim
STRING_ESCAPE_REGEX =
/\\([\\nt'"])/m

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(source, loader = nil, name = nil) ⇒ Parser

create a new parser for a given sourcecode and an optional template loader. If a template loader is given the template inheritance and include system will work. Otherwise those tags create an error. If name is given it will be used by the loaders to resolve relative paths on inclutions/inheritance



36
37
38
39
40
# File 'lib/ruty/parser.rb', line 36

def initialize source, loader=nil, name=nil
  @source = source
  @loader = loader
  @name = name
end

Class Method Details

.parse_arguments(arguments) ⇒ Object

helper function for parsing arguments the return value will be a list of lists. names are returned as symbols, strings as strings, numbers as floats or integers, filters are returned as arrays:

for item in seq

results in:

[:for, :item, :in, :seq]

This:

user.username|lower|replace '\'', '"'

results in:

[:"user.username", [:lower], [:replace, "'", "\""]]


85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
# File 'lib/ruty/parser.rb', line 85

def self.parse_arguments arguments
  lexer = Parser::ArgumentLexer.new(arguments)
  result = cur_buffer = []
  filter_buffer = []

  lexer.lex do |token, value|
    if token == :filter_start
      cur_buffer = filter_buffer.clear
    elsif token == :filter_end
      result << filter_buffer.dup if not filter_buffer.empty?
      cur_buffer = result
    elsif token == :name
      cur_buffer << value.to_sym
    elsif token == :number
      cur_buffer << (value.include?('.') ? value.to_f : value.to_i)
    elsif token == :string
      cur_buffer << value[1...-1].gsub(STRING_ESCAPE_REGEX) {
        $1.tr!(%q{\\\\nt"'}, %q{\\\\\n\t"'})
      }
    end
  end

  result
end

Instance Method Details

#parseObject

parse the template and return a nodelist representing the parsed template.



44
45
46
47
# File 'lib/ruty/parser.rb', line 44

def parse
  controller = ParserController::new(tokenize, @loader, @name)
  controller.parse_all
end

#tokenizeObject

tokenize the sourcecode and return an array of tokens



50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
# File 'lib/ruty/parser.rb', line 50

def tokenize
  result = Datastructure::TokenStream.new
  @source.scan(TAG_REGEX).each do |match|
    result << [:text, match[0]] if match[0] and not match[0].empty?
    if data = match[1]
      result << [:block, data.strip]
    elsif data = match[2]
      result << [:var, data.strip]
    elsif data = match[3]
      result << [:comment, data.strip]
    end
  end
  rest = @source[$~.end(0)..-1]
  result << [:text, rest] if not rest.empty?
  result.close
end