Class: Rundoc::Parser

Inherits:
Object
  • Object
show all
Defined in:
lib/rundoc/parser.rb

Overview

This poorly named class is responsible for taking in the raw markdown and running it

It works by pulling out the code blocks (CodeSection), and putting them onto a stack. It then executes each in turn and records the results.

Constant Summary collapse

DEFAULT_KEYWORD =
":::"
INDENT_BLOCK =
'(?<before_indent>(^\s*$\n|\A)(^(?:[ ]{4}|\t))(?<indent_contents>.*)(?<after_indent>[^\s].*$\n?(?:(?:^\s*$\n?)*^(?:[ ]{4}|\t).*[^\s].*$\n?)*))'
GITHUB_BLOCK =
'^(?<fence>(?<fence_char>~|`){3,})\s*?(?<lang>\w+)?\s*?\n(?<contents>.*?)^\g<fence>\g<fence_char>*\s*?\n?'
CODEBLOCK_REGEX =
/(#{GITHUB_BLOCK})/m
COMMAND_REGEX =
->(keyword) {
  /^#{keyword}(?<tag>(\s|=|-|>)?(=|-|>)?)\s*(?<command>(\S)+)\s+(?<statement>.*)$/
}
PARTIAL_RESULT =
[]

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(contents, context:, keyword: DEFAULT_KEYWORD) ⇒ Parser

Returns a new instance of Parser.



18
19
20
21
22
23
24
25
26
# File 'lib/rundoc/parser.rb', line 18

def initialize(contents, context:, keyword: DEFAULT_KEYWORD)
  @context = context
  @contents = contents
  @original = contents.dup
  @keyword = keyword
  @stack = []
  partition
  PARTIAL_RESULT.clear
end

Instance Attribute Details

#contentsObject (readonly)

Returns the value of attribute contents.



16
17
18
# File 'lib/rundoc/parser.rb', line 16

def contents
  @contents
end

#contextObject (readonly)

Returns the value of attribute context.



16
17
18
# File 'lib/rundoc/parser.rb', line 16

def context
  @context
end

#keywordObject (readonly)

Returns the value of attribute keyword.



16
17
18
# File 'lib/rundoc/parser.rb', line 16

def keyword
  @keyword
end

#stackObject (readonly)

Returns the value of attribute stack.



16
17
18
# File 'lib/rundoc/parser.rb', line 16

def stack
  @stack
end

Class Method Details

.partial_result_to_docObject



45
46
47
48
49
50
# File 'lib/rundoc/parser.rb', line 45

def self.partial_result_to_doc
  out = to_doc(result: PARTIAL_RESULT)
  unfinished = CodeSection.partial_result_to_doc
  out << unfinished if unfinished
  out
end

.to_doc(result:) ⇒ Object



52
53
54
# File 'lib/rundoc/parser.rb', line 52

def self.to_doc(result:)
  result.join("")
end

Instance Method Details

#partitionObject

split into [before_code, code, after_code], process code, and re-run until tail is empty



57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
# File 'lib/rundoc/parser.rb', line 57

def partition
  until contents.empty?
    head, code, tail = contents.partition(CODEBLOCK_REGEX)
    @stack << head unless head.empty?
    unless code.empty?
      match = code.match(CODEBLOCK_REGEX)
      @stack << CodeSection.new(
        match,
        keyword: keyword,
        context: context
      )
    end
    @contents = tail
  end
end

#to_mdObject



28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
# File 'lib/rundoc/parser.rb', line 28

def to_md
  result = []
  @stack.each do |s|
    result << if s.respond_to?(:render)
      s.render
    else
      s
    end
    PARTIAL_RESULT.replace(result)
  end

  self.class.to_doc(result: result)
rescue => e
  File.write("README.md", result.join(""))
  raise e
end