class HamlLint::Document

Represents a parsed Haml document and its associated metadata.

Constants

STRING_SOURCE

File name given to source code parsed from just a string.

Attributes

config[R]

@return [HamlLint::Configuration] Configuration used to parse template

file[R]

@return [String] Haml template file path

source[R]

@return [String] original source code

source_lines[R]

@return [Array<String>] original source code as an array of lines

tree[R]

@return [HamlLint::Tree::Node] Root of the parse tree

Public Class Methods

new(source, options) click to toggle source

Parses the specified Haml code into a {Document}.

@param source [String] Haml code to parse @param options [Hash] @option options :file [String] file name of document that was parsed @raise [Haml::Parser::Error] if there was a problem parsing the document

# File lib/haml_lint/document.rb, line 31
def initialize(source, options)
  @config = options[:config]
  @file = options.fetch(:file, STRING_SOURCE)

  process_source(source)
end

Private Instance Methods

convert_tree(haml_node, parent = nil) click to toggle source

Converts a HAML parse tree to a tree of {HamlLint::Tree::Node} objects.

This provides a cleaner interface with which the linters can interact with the parse tree.

@param haml_node [Haml::Parser::ParseNode] @param parent [Haml::Tree::Node] @return [Haml::Tree::Node]

# File lib/haml_lint/document.rb, line 77
def convert_tree(haml_node, parent = nil)
  new_node = @node_transformer.transform(haml_node)
  new_node.parent = parent

  new_node.children = haml_node.children.map do |child|
    convert_tree(child, new_node)
  end

  new_node
end
process_encoding(source) click to toggle source

Ensures source code is interpreted as UTF-8.

This is necessary as sometimes Ruby guesses the encoding of a file incorrectly, for example if the LC_ALL environment variable is set to ā€œCā€. @see unix.stackexchange.com/a/87763

@param source [String] @return [String] source encoded with UTF-8 encoding

# File lib/haml_lint/document.rb, line 96
def process_encoding(source)
  source.force_encoding(Encoding::UTF_8)
end
process_source(source) click to toggle source

@param source [String] Haml code to parse @raise [HamlLint::Exceptions::ParseError] if there was a problem parsing

# File lib/haml_lint/document.rb, line 42
def process_source(source)
  @source = process_encoding(source)
  @source = strip_frontmatter(source)
  @source_lines = @source.split(/\r\n|\r|\n/)

  @tree = process_tree(HamlLint::Adapter.detect_class.new(@source).parse)
rescue Haml::Error => e
  error = HamlLint::Exceptions::ParseError.new(e.message, e.line)
  raise error
end
process_tree(original_tree) click to toggle source

Processes the {Haml::Parser::ParseNode} tree and returns a tree composed of friendlier {HamlLint::Tree::Node}s.

@param original_tree [Haml::Parser::ParseNode] @return [Haml::Tree::Node]

# File lib/haml_lint/document.rb, line 58
def process_tree(original_tree)
  # Remove the trailing empty HAML comment that the parser creates to signal
  # the end of the HAML document
  if Gem::Requirement.new('~> 4.0.0').satisfied_by?(Gem.loaded_specs['haml'].version)
    original_tree.children.pop
  end

  @node_transformer = HamlLint::NodeTransformer.new(self)
  convert_tree(original_tree)
end
strip_frontmatter(source) click to toggle source

Removes YAML frontmatter

# File lib/haml_lint/document.rb, line 101
def strip_frontmatter(source)
  frontmatter = /
    # From the start of the string
    \A
    # First-capture match --- followed by optional whitespace up
    # to a newline then 0 or more chars followed by an optional newline.
    # This matches the --- and the contents of the frontmatter
    (---\s*\n.*?\n?)
    # From the start of the line
    ^
    # Second capture match --- or ... followed by optional whitespace
    # and newline. This matches the closing --- for the frontmatter.
    (---|\.\.\.)\s*$\n?/mx

  if config['skip_frontmatter'] && match = source.match(frontmatter)
    newlines = match[0].count("\n")
    source.sub!(frontmatter, "\n" * newlines)
  end

  source
end