Module: Hamlit::Compilers::Text

Extended by:
Hamlit::Concerns::Included
Includes:
Hamlit::Concerns::Error, Hamlit::Concerns::Lexable, Hamlit::Concerns::StringInterpolation
Included in:
Hamlit::Compiler
Defined in:
lib/hamlit/compilers/text.rb

Constant Summary collapse

STRING_MARKERS =

To ask ripper to consider a given text as string literal, I change “foo” to “%!foo!”. This constant is the candidates for the literal surrounder.

%w[' " ! @ $ % ^ & * | =].freeze

Constants included from Hamlit::Concerns::Lexable

Hamlit::Concerns::Lexable::TYPE_POSITION

Instance Method Summary collapse

Methods included from Hamlit::Concerns::Included

extended

Methods included from Hamlit::Concerns::StringInterpolation

#contains_interpolation?, #string_literal

Methods included from Hamlit::Concerns::Lexable

#convert_position, #skip_tokens!, #type_of

Methods included from Hamlit::Concerns::Error

#assert_scan!, #copmile_error!, #syntax_error, #syntax_error!

Instance Method Details

#find_interpolation(exp, marker) ⇒ Object



44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
# File 'lib/hamlit/compilers/text.rb', line 44

def find_interpolation(exp, marker)
  return unless contains_interpolation?(exp)

  offset     = 2 # 2 is the length of '%' and marker
  open_pos   = nil
  open_count = 0
  literal    = literalify_string(exp, marker)

  Ripper.lex(literal).each do |(row, col), type, str|
    case type
    when :on_embexpr_beg
      open_pos = shifted_position(exp, row, col, offset) if open_count == 0
      open_count += 1
    when :on_embexpr_end
      open_count -= 1
      return [open_pos, shifted_position(exp, row, col, offset)] if open_count == 0
    end
    open_count
  end

  nil
end

#on_haml_text(exp, escape_html = true) ⇒ Object

Return static and dynamic temple ast. It splits expression to optimize because string interpolation is slow.



26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
# File 'lib/hamlit/compilers/text.rb', line 26

def on_haml_text(exp, escape_html = true)
  return syntax_error('Unbalanced brackets.') unless valid_interpolation?(exp)
  return static_text(exp) unless contains_interpolation?(exp)

  marker = find_string_marker(exp)
  return [:dynamic, string_literal(exp)] unless marker

  open_pos, close_pos = find_interpolation(exp, marker)
  return static_text(exp) unless open_pos && close_pos

  pre  = exp.byteslice(0...open_pos)
  body = exp.byteslice((open_pos + 2)...close_pos)
  post = exp.byteslice((close_pos + 1)...exp.bytesize)

  body_ast = escape_html ? escape_html([:dynamic, body]) : [:dynamic, body]
  [:multi, [:static, pre], body_ast, on_haml_text(post)]
end