Module: Hamlit::Concerns::Indentable

Includes:
Error
Included in:
Parsers::Comment, Parsers::Filter, Parsers::Script, Parsers::Tag
Defined in:
lib/hamlit/concerns/indentable.rb

Instance Method Summary collapse

Methods included from Error

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

Instance Method Details

#count_indent(line, strict: false) ⇒ Object



32
33
34
35
36
37
38
39
40
# File 'lib/hamlit/concerns/indentable.rb', line 32

def count_indent(line, strict: false)
  return EOF unless line
  width = count_width(line)

  return (width + 1) / 2 unless strict
  compile_error!('Expected to count even-width indent') if width.odd?

  width / 2
end

#count_width(line) ⇒ Object



42
43
44
45
# File 'lib/hamlit/concerns/indentable.rb', line 42

def count_width(line)
  return EOF unless line
  line[/\A +/].to_s.length
end

#indent_label(indent) ⇒ Object



67
68
69
70
71
72
73
74
# File 'lib/hamlit/concerns/indentable.rb', line 67

def indent_label(indent)
  return %Q{"#{indent}"} if indent.include?(' ') && indent.include?("\t")

  label  = indent.include?(' ') ? 'space' : 'tab'
  length = indent.match(/[ \t]+/).to_s.length

  "#{length} #{label}#{'s' if length > 1}"
end

#next_indentObject

Return nearest line’s indent level since next line. This method ignores empty line. It returns -1 if next_line does not exist.



16
17
18
# File 'lib/hamlit/concerns/indentable.rb', line 16

def next_indent
  count_indent(next_line)
end

#next_widthObject



20
21
22
# File 'lib/hamlit/concerns/indentable.rb', line 20

def next_width
  count_width(next_line)
end

#replace_hard_tabs(template) ⇒ Object

Replace hard tabs into 2 spaces



77
78
79
80
81
82
83
84
85
# File 'lib/hamlit/concerns/indentable.rb', line 77

def replace_hard_tabs(template)
  lines = []
  template.each_line do |line|
    lines << line.gsub(/^\t+/) do |match|
      ' ' * (match.length * 2)
    end
  end
  lines.join
end

#reset_indentObject



10
11
12
# File 'lib/hamlit/concerns/indentable.rb', line 10

def reset_indent
  @current_indent = 0
end

#same_indent?(line) ⇒ Boolean

Returns:

  • (Boolean)


47
48
49
50
# File 'lib/hamlit/concerns/indentable.rb', line 47

def same_indent?(line)
  return false unless line
  count_indent(line) == @current_indent
end

#validate_indentation!(template) ⇒ Object

Validate the template is using consitent indentation, 2 spaces or a tab.



53
54
55
56
57
58
59
60
61
62
63
64
65
# File 'lib/hamlit/concerns/indentable.rb', line 53

def validate_indentation!(template)
  last_indent = ''

  indents = template.scan(/^[ \t]+/)
  indents.each do |indent|
    if last_indent.include?(' ') && indent.include?("\t") ||
        last_indent.include?("\t") && indent.include?(' ')
      syntax_error!(%Q{Inconsistent indentation: #{indent_label(indent)} used for indentation, but the rest of the document was indented using #{indent_label(last_indent)}.})
    end

    last_indent = indent
  end
end

#with_indented(&block) ⇒ Object



24
25
26
27
28
29
30
# File 'lib/hamlit/concerns/indentable.rb', line 24

def with_indented(&block)
  @current_indent += 1
  result = block.call
  @current_indent -= 1

  result
end