Class: HackTree::Parser::Desc

Inherits:
Base
  • Object
show all
Defined in:
lib/hack_tree/parser/desc.rb

Overview

DSL desc parser.

Instance Method Summary collapse

Methods inherited from Base

#[], #initialize

Constructor Details

This class inherits a constructor from HackTree::Parser::Base

Instance Method Details

#process(content) ⇒ Object

Parse description text, always return Array of 2 elements.

process(content)    # => [nil, nil]. Neither brief nor full description is present.
process(content)    # => ["...", nil]. Brief description is present, full isn't.
process(content)    # => ["...", "..."]. Both brief and full descriptions are present.


12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
# File 'lib/hack_tree/parser/desc.rb', line 12

def process(content)
  lines = content.lstrip.lines.to_a
  return [nil, nil] if lines.empty?

  # If we're here, `brief` is certainly present.
  brief = lines.shift.rstrip

  # Extract full lines with original indentation on the left.

  indented_lines = []
  gap = true    # We're skipping the gap between the brief and the full.

  lines.each do |line|
    line = line.rstrip
    next if gap and line.empty?

    # First non-empty line, the gap is over.
    gap = false

    indented_lines << line
  end

  # Compute minimum indentation level. Empty lines don't count.
  indent = indented_lines.reject(&:empty?).map do |s|
    s.match(/\A(\s*)\S/)[1].size
  end.min.to_i

  # Apply indentation.
  unindented_lines = indented_lines.map do |line|
    line.empty?? line : line[indent..-1]
  end

  # Reject empty lines at the end.
  final_lines = []
  buf = []
  unindented_lines.each do |line|
    # Accumulate empty lines.
    if line.empty?
      buf << line
      next
    end

    # Non-empty line, flush `buf` and start over.
    final_lines += buf + [line]
    buf = []
  end

  [
    brief,
    (final_lines.join("\n") if not final_lines.empty?),
  ]
end