class Curly::Scanner

Scans Curly templates for tokens.

The Scanner goes through the template piece by piece, extracting tokens until the end of the template is reached.

Constants

COLLECTION_BLOCK_MARKER
COMMENT_MARKER
CONDITIONAL_BLOCK_MARKER
CONTEXT_BLOCK_MARKER
CURLY_END
CURLY_START
END_BLOCK_MARKER
ESCAPED_CURLY_START
INVERSE_BLOCK_MARKER

Public Class Methods

new(source) click to toggle source
# File lib/curly/scanner.rb, line 40
def initialize(source)
  @scanner = StringScanner.new(source)
end
scan(source) click to toggle source

Scans a Curly template for tokens.

source - The String source of the template.

Examples

Curly::Scanner.scan("hello {{name}}!")
#=> [[:text, "hello "], [:component, "name"], [:text, "!"]]

Returns an Array of type/value pairs representing the tokens in the

template.
# File lib/curly/scanner.rb, line 36
def self.scan(source)
  new(source).scan
end

Public Instance Methods

scan() click to toggle source
# File lib/curly/scanner.rb, line 44
def scan
  tokens = []
  tokens << scan_token until @scanner.eos?
  tokens
end

Private Instance Methods

scan_block_end() click to toggle source
# File lib/curly/scanner.rb, line 126
def scan_block_end
  if value = scan_until_end_of_curly
    name, identifier, attributes, contexts = ComponentScanner.scan(value)
    [:block_end, name, identifier, {}, contexts]
  end
end
scan_collection_block_start() click to toggle source
# File lib/curly/scanner.rb, line 112
def scan_collection_block_start
  if value = scan_until_end_of_curly
    name, identifier, attributes, contexts = ComponentScanner.scan(value)
    [:collection_block_start, name, identifier, attributes, contexts]
  end
end
scan_comment() click to toggle source
# File lib/curly/scanner.rb, line 90
def scan_comment
  if value = scan_until_end_of_curly
    [:comment, value]
  end
end
scan_component() click to toggle source
# File lib/curly/scanner.rb, line 133
def scan_component
  if value = scan_until_end_of_curly
    name, identifier, attributes, contexts = ComponentScanner.scan(value)
    [:component, name, identifier, attributes, contexts]
  end
end
scan_conditional_block_start() click to toggle source
# File lib/curly/scanner.rb, line 96
def scan_conditional_block_start
  if value = scan_until_end_of_curly
    name, identifier, attributes, contexts = ComponentScanner.scan(value)

    [:conditional_block_start, name, identifier, attributes, contexts]
  end
end
scan_context_block_start() click to toggle source
# File lib/curly/scanner.rb, line 104
def scan_context_block_start
  if value = scan_until_end_of_curly
    name, identifier, attributes, contexts = ComponentScanner.scan(value)

    [:context_block_start, name, identifier, attributes, contexts]
  end
end
scan_curly() click to toggle source
# File lib/curly/scanner.rb, line 66
def scan_curly
  if @scanner.scan(CURLY_START)
    scan_tag or syntax_error!
  end
end
scan_escaped_curly() click to toggle source
# File lib/curly/scanner.rb, line 60
def scan_escaped_curly
  if @scanner.scan(ESCAPED_CURLY_START)
    [:text, "{{"]
  end
end
scan_inverse_block_start() click to toggle source
# File lib/curly/scanner.rb, line 119
def scan_inverse_block_start
  if value = scan_until_end_of_curly
    name, identifier, attributes, contexts = ComponentScanner.scan(value)
    [:inverse_conditional_block_start, name, identifier, attributes, contexts]
  end
end
scan_remainder() click to toggle source

Scans the remainder of the template and treats it as a text token.

Returns an Array representing the token, or nil if no text is remaining.

# File lib/curly/scanner.rb, line 152
def scan_remainder
  if value = @scanner.scan(/.+/m)
    [:text, value]
  end
end
scan_tag() click to toggle source
# File lib/curly/scanner.rb, line 72
def scan_tag
  if @scanner.scan(COMMENT_MARKER)
    scan_comment
  elsif @scanner.scan(CONDITIONAL_BLOCK_MARKER)
    scan_conditional_block_start
  elsif @scanner.scan(CONTEXT_BLOCK_MARKER)
    scan_context_block_start
  elsif @scanner.scan(INVERSE_BLOCK_MARKER)
    scan_inverse_block_start
  elsif @scanner.scan(COLLECTION_BLOCK_MARKER)
    scan_collection_block_start
  elsif @scanner.scan(END_BLOCK_MARKER)
    scan_block_end
  else
    scan_component
  end
end
scan_text() click to toggle source
# File lib/curly/scanner.rb, line 140
def scan_text
  if value = scan_until_start_of_curly
    @scanner.pos -= 2
    [:text, value]
  else
    scan_remainder
  end
end
scan_token() click to toggle source

Scans the next token in the template.

Returns a two-element Array, the first element being the Symbol type of

the token and the second being the String value.
# File lib/curly/scanner.rb, line 56
def scan_token
  scan_escaped_curly || scan_curly || scan_text
end
scan_until_end_of_curly() click to toggle source
# File lib/curly/scanner.rb, line 164
def scan_until_end_of_curly
  if value = @scanner.scan_until(CURLY_END)
    value[0..-3]
  end
end
scan_until_start_of_curly() click to toggle source
# File lib/curly/scanner.rb, line 158
def scan_until_start_of_curly
  if value = @scanner.scan_until(CURLY_START)
    value[0..-3]
  end
end
syntax_error!() click to toggle source
# File lib/curly/scanner.rb, line 170
def syntax_error!
  raise SyntaxError.new(@scanner.pos, @scanner.string)
end