Sha256: fca961183fc031ebdb260b821e3636f13fed69ce372c0a45837b5830fa0c5d42

Contents?: true

Size: 1.93 KB

Versions: 3

Compression:

Stored size: 1.93 KB

Contents

# encoding: UTF-8

require 'strscan'

module Cutaneous
  class Lexer
    attr_reader :template, :syntax

    def initialize(template, syntax)
      @template, @syntax = template, syntax
    end

    def tokens
      @tokens ||= parse
    end

    # def script
    #   @script ||= compile
    # end

    protected

    BRACES ||= /\{|\}/
    STRIP_WS = "-"

    def parse
      tokens    = []
      scanner   = StringScanner.new(@template.to_s)
      tag_start = syntax.tag_start_pattern
      tags      = syntax.tags
      token_map = syntax.token_map
      previous  = nil

      while (text = scanner.scan_until(tag_start))
        tag = scanner.matched
        type, brace_count, endtag_length = token_map[tag]
        text.slice!(text.length - tag.length, text.length)
        expression = ""
        strip_whitespace = false

        begin
          expression << scanner.scan_until(BRACES)
          brace = scanner.matched
          brace_count += ((123 - brace.ord)+1) # '{' = 1,  '}' = -1
        end while (brace_count > 0)

        length = expression.length
        expression.slice!(length - endtag_length, length)

        if expression.end_with?(STRIP_WS)
          strip_whitespace = true
          length = expression.length
          expression.slice!(length - 1, length)
        end

        tokens << place_text_token(text) if text.length > 0
        tokens << create_token(type, expression, strip_whitespace)
        previous = type
      end
      tokens << place_text_token(scanner.rest) unless scanner.eos?
      tokens
    end

    def create_token(type, expression, strip_whitespace)
      [type, expression, strip_whitespace]
    end

    #BEGINNING_WHITESPACE ||= /\A\s*?[\r\n]+/
    #ENDING_WHITESPACE    ||= /(\r?\n)[ \t]*\z/
    ESCAPE_STRING        ||= /[`\\]/

    def place_text_token(expression)
      expression.gsub!(syntax.escaped_tag_pattern, '\1')
      expression.gsub!(ESCAPE_STRING, '\\\\\&')
      [:text, expression]
    end
  end
end

Version data entries

3 entries across 3 versions & 1 rubygems

Version Path
cutaneous-0.1.4 lib/cutaneous/lexer.rb
cutaneous-0.1.3 lib/cutaneous/lexer.rb
cutaneous-0.1.2 lib/cutaneous/lexer.rb