class Haml::Compiler::ScriptCompiler

def self.find_and_preserve(input, tags)

def self.find_and_preserve(input, tags)
  tags = tags.map { |tag| Regexp.escape(tag) }.join('|')
  re = /<(#{tags})([^>]*)>(.*?)(<\/\1>)/im
  input.to_s.gsub(re) do |s|
    s =~ re # Can't rely on $1, etc. existing since Rails' SafeBuffer#gsub is incompatible
    "<#{$1}#{$2}>#{Haml::Helpers.preserve($3)}</#{$1}>"
  end
end

def compile(node, &block)

def compile(node, &block)
  unless Ripper.respond_to?(:lex) # No Ripper.lex in truffleruby
    return dynamic_compile(node, &block)
  end
  no_children = node.children.empty?
  case
  when no_children && node.value[:escape_interpolation]
    compile_interpolated_plain(node)
  when no_children && RubyExpression.string_literal?(node.value[:text])
    delegate_optimization(node)
  when no_children && Temple::StaticAnalyzer.static?(node.value[:text])
    static_compile(node)
  else
    dynamic_compile(node, &block)
  end
end

def compile_interpolated_plain(node)

because we have to escape only interpolated values.
String-interpolated plain text must be compiled with this method
def compile_interpolated_plain(node)
  temple = [:multi]
  StringSplitter.compile(node.value[:text]).each do |type, value|
    case type
    when :static
      temple << [:static, value]
    when :dynamic
      temple << [:escape, node.value[:escape_interpolation], [:dynamic, value]]
    end
  end
  temple << [:newline]
end

def compile_script_assign(var, node, &block)

def compile_script_assign(var, node, &block)
  if node.children.empty?
    [:multi,
     [:code, "#{var} = (#{node.value[:text]}"],
     [:newline],
     [:code, ')'],
    ]
  else
    [:multi,
     [:block, "#{var} = #{node.value[:text]}",
      [:multi, [:newline], @disable_capture ? yield(node) : [:capture, Temple::Utils.unique_name, yield(node)]]
     ],
    ]
  end
end

def compile_script_result(result, node)

def compile_script_result(result, node)
  if !node.value[:escape_html] && node.value[:preserve]
    result = find_and_preserve(result)
  end
  [:escapeany, node.value[:escape_html], [:dynamic, result]]
end

def delegate_optimization(node)

:dynamic is optimized in other filter: StringSplitter
def delegate_optimization(node)
  [:multi,
   [:escape, node.value[:escape_html], [:dynamic, node.value[:text]]],
   [:newline],
  ]
end

def dynamic_compile(node, &block)

def dynamic_compile(node, &block)
  var = @identity.generate
  temple = compile_script_assign(var, node, &block)
  temple << compile_script_result(var, node)
end

def escape_html(temple)

def escape_html(temple)
  [:escape, true, temple]
end

def find_and_preserve(code)

def find_and_preserve(code)
  %Q[::Haml::Compiler::ScriptCompiler.find_and_preserve(#{code}, %w(textarea pre code))]
end

def initialize(identity, options)

def initialize(identity, options)
  @identity = identity
  @disable_capture = options[:disable_capture]
end

def static_compile(node)

def static_compile(node)
  str = eval(node.value[:text]).to_s
  if node.value[:escape_html]
    str = Haml::Util.escape_html(str)
  elsif node.value[:preserve]
    str = ScriptCompiler.find_and_preserve(str, %w(textarea pre code))
  end
  [:multi, [:static, str], [:newline]]
end