Class: Rundoc::CodeSection

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

Overview

holds code, parses and creates CodeCommand

Defined Under Namespace

Classes: ParseError

Constant Summary collapse

COMMAND_REGEX =

todo: move whole thing

Rundoc::Parser::COMMAND_REGEX

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(match, options = {}) ⇒ CodeSection

Returns a new instance of CodeSection.



30
31
32
33
34
35
36
37
38
39
# File 'lib/rundoc/code_section.rb', line 30

def initialize(match, options = {})
  @original = match.to_s
  @commands = []
  @stack    = []
  @keyword  = options[:keyword] or raise "keyword is required"
  @fence    = match[:fence]
  @lang     = match[:lang]
  @code     = match[:contents]
  parse_code_command
end

Instance Attribute Details

#codeObject

Returns the value of attribute code.



28
29
30
# File 'lib/rundoc/code_section.rb', line 28

def code
  @code
end

#commandsObject

Returns the value of attribute commands.



28
29
30
# File 'lib/rundoc/code_section.rb', line 28

def commands
  @commands
end

#fenceObject

Returns the value of attribute fence.



28
29
30
# File 'lib/rundoc/code_section.rb', line 28

def fence
  @fence
end

#keywordObject

Returns the value of attribute keyword.



28
29
30
# File 'lib/rundoc/code_section.rb', line 28

def keyword
  @keyword
end

#langObject

Returns the value of attribute lang.



28
29
30
# File 'lib/rundoc/code_section.rb', line 28

def lang
  @lang
end

#originalObject

Returns the value of attribute original.



28
29
30
# File 'lib/rundoc/code_section.rb', line 28

def original
  @original
end

Instance Method Details

#add_code(match, line) ⇒ Object



88
89
90
91
# File 'lib/rundoc/code_section.rb', line 88

def add_code(match, line)
  add_match_to_code_command(match, commands)
  check_parse_error(line, code)
end

#add_contents(line) ⇒ Object



93
94
95
96
97
98
99
# File 'lib/rundoc/code_section.rb', line 93

def add_contents(line)
  if commands.empty?
    @stack << line
  else
    commands.last << line
  end
end

#add_match_to_code_command(match, commands) ⇒ Object



111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
# File 'lib/rundoc/code_section.rb', line 111

def add_match_to_code_command(match, commands)
  command      = match[:command]
  tag          = match[:tag]
  statement    = match[:statement]

  code_command = Rundoc.code_command_from_keyword(command, statement)

  case tag
  when /\-/
    code_command.hidden        = true
  when /\=/
    code_command.render_result = true
  when /\s/
    # default do nothing
  end

  @stack   << "\n" if commands.last.is_a?(Rundoc::CodeCommand)
  @stack   << code_command
  commands << code_command
  code_command
end

#check_parse_error(command, code_block) ⇒ Object



133
134
135
136
137
138
139
140
141
142
143
# File 'lib/rundoc/code_section.rb', line 133

def check_parse_error(command, code_block)
  return unless code_command = @stack.last
  return unless code_command.is_a?(Rundoc::CodeCommand::NoSuchCommand)
  @original.lines.each_with_index do |line, index|
    next unless line == command
    raise ParseError.new(keyword:     code_command.keyword,
                         block:       code_block,
                         command:     command,
                         line_number: index.next)
  end
end

#command_regexObject



84
85
86
# File 'lib/rundoc/code_section.rb', line 84

def command_regex
  COMMAND_REGEX.call(keyword)
end

#hidden?Boolean

all of the commands are hidden

Returns:

  • (Boolean)


74
75
76
# File 'lib/rundoc/code_section.rb', line 74

def hidden?
  !not_hidden?
end

#not_hidden?Boolean

one or more of the commands are not hidden

Returns:

  • (Boolean)


79
80
81
82
# File 'lib/rundoc/code_section.rb', line 79

def not_hidden?
  return true if commands.empty?
  commands.map(&:not_hidden?).detect {|c| c }
end

#parse_code_commandObject



101
102
103
104
105
106
107
108
109
# File 'lib/rundoc/code_section.rb', line 101

def parse_code_command
  code.lines.each do |line|
    if match = line.match(command_regex)
      add_code(match, line)
    else
      add_contents(line)
    end
  end
end

#renderObject



41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
# File 'lib/rundoc/code_section.rb', line 41

def render
  result = []
  env = {}
  env[:commands] = []
  env[:before]   = "#{fence}#{lang}"
  env[:after]    = "#{fence}"

  @stack.each do |s|
    unless s.respond_to?(:call)
      result << s
      next
    end

    code_command = s
    code_output  = code_command.call(env)  || ""
    code_line    = code_command.to_md(env) || ""

    env[:commands] << { object: code_command, output: code_output, command: code_line}

    if code_command.render_result?
      result << [code_line, code_output]
    else
      result << code_line unless code_command.hidden?
    end
  end

  return "" if hidden?

  array = [env[:before], result, env[:after]]
  return array.flatten.compact.map(&:rstrip).reject(&:empty?).join("\n") << "\n"
end