rundoc 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +5 -0
- data/Gemfile +3 -0
- data/Gemfile.lock +38 -0
- data/README.md +309 -0
- data/Rakefile +16 -0
- data/bin/rundoc +82 -0
- data/lib/rundoc.rb +76 -0
- data/lib/rundoc/code_command.rb +32 -0
- data/lib/rundoc/code_command/bash.rb +57 -0
- data/lib/rundoc/code_command/bash/cd.rb +18 -0
- data/lib/rundoc/code_command/file_command/append.rb +74 -0
- data/lib/rundoc/code_command/file_command/remove.rb +32 -0
- data/lib/rundoc/code_command/no_such_command.rb +6 -0
- data/lib/rundoc/code_command/pipe.rb +37 -0
- data/lib/rundoc/code_command/repl.rb +37 -0
- data/lib/rundoc/code_command/rundoc_command.rb +22 -0
- data/lib/rundoc/code_command/write.rb +34 -0
- data/lib/rundoc/code_section.rb +145 -0
- data/lib/rundoc/parser.rb +53 -0
- data/lib/rundoc/version.rb +3 -0
- data/rundoc.gemspec +28 -0
- data/test/fixtures/play/source.md +231 -0
- data/test/fixtures/rails_4/rundoc.md +504 -0
- data/test/rundoc/code_commands/append_file_test.rb +55 -0
- data/test/rundoc/code_commands/bash_test.rb +29 -0
- data/test/rundoc/code_commands/pipe_test.rb +15 -0
- data/test/rundoc/code_commands/remove_contents_test.rb +42 -0
- data/test/rundoc/code_section_test.rb +42 -0
- data/test/rundoc/parser_test.rb +104 -0
- data/test/rundoc/regex_test.rb +200 -0
- data/test/rundoc/test_parse_java.rb +8 -0
- data/test/test_helper.rb +15 -0
- metadata +144 -0
data/lib/rundoc.rb
ADDED
@@ -0,0 +1,76 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
require 'pathname'
|
3
|
+
require 'rundoc/version'
|
4
|
+
|
5
|
+
module Rundoc
|
6
|
+
extend self
|
7
|
+
|
8
|
+
def code_command_from_keyword(keyword, args)
|
9
|
+
klass = code_command(keyword.to_sym) || Rundoc::CodeCommand::NoSuchCommand
|
10
|
+
cc = klass.new(args)
|
11
|
+
cc.keyword = keyword
|
12
|
+
cc
|
13
|
+
end
|
14
|
+
|
15
|
+
def parser_options
|
16
|
+
@parser_options ||= {}
|
17
|
+
end
|
18
|
+
|
19
|
+
def code_lookup
|
20
|
+
@code_lookup ||= {}
|
21
|
+
end
|
22
|
+
|
23
|
+
def code_command(keyword)
|
24
|
+
code_lookup[:"#{keyword}"]
|
25
|
+
end
|
26
|
+
|
27
|
+
def known_commands
|
28
|
+
code_lookup.keys
|
29
|
+
end
|
30
|
+
|
31
|
+
def register_code_command(keyword, klass)
|
32
|
+
code_lookup[keyword] = klass
|
33
|
+
end
|
34
|
+
|
35
|
+
def configure(&block)
|
36
|
+
yield self
|
37
|
+
end
|
38
|
+
|
39
|
+
def run_after_build
|
40
|
+
@after_build_block ||= []
|
41
|
+
@after_build_block.each(&:call)
|
42
|
+
end
|
43
|
+
|
44
|
+
def after_build(&block)
|
45
|
+
@after_build_block ||= []
|
46
|
+
@after_build_block << block
|
47
|
+
end
|
48
|
+
|
49
|
+
def config
|
50
|
+
yield self
|
51
|
+
end
|
52
|
+
|
53
|
+
def register_repl(*args, &block)
|
54
|
+
ReplRunner.register_commands(*args, &block)
|
55
|
+
end
|
56
|
+
|
57
|
+
def filter_sensitive(sensitive)
|
58
|
+
raise "Expecting #{sensitive} to be a hash" unless sensitive.is_a?(Hash)
|
59
|
+
@sensitive ||= {}
|
60
|
+
@sensitive.merge!(sensitive)
|
61
|
+
end
|
62
|
+
|
63
|
+
def sanitize(doc)
|
64
|
+
return doc if @sensitive.nil?
|
65
|
+
@sensitive.each do |sensitive, replace|
|
66
|
+
doc.gsub!(sensitive.to_s, replace)
|
67
|
+
end
|
68
|
+
return doc
|
69
|
+
end
|
70
|
+
|
71
|
+
attr_accessor :project_root
|
72
|
+
end
|
73
|
+
|
74
|
+
require 'rundoc/parser'
|
75
|
+
require 'rundoc/code_section'
|
76
|
+
require 'rundoc/code_command'
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module Rundoc
|
2
|
+
class CodeCommand
|
3
|
+
attr_accessor :hidden, :render_result, :command, :contents, :keyword
|
4
|
+
alias :hidden? :hidden
|
5
|
+
alias :render_result? :render_result
|
6
|
+
|
7
|
+
def initialize(arg)
|
8
|
+
end
|
9
|
+
|
10
|
+
def not_hidden?
|
11
|
+
!hidden?
|
12
|
+
end
|
13
|
+
|
14
|
+
def push(contents)
|
15
|
+
@contents ||= ""
|
16
|
+
@contents << contents
|
17
|
+
end
|
18
|
+
alias :<< :push
|
19
|
+
|
20
|
+
# executes command to build project
|
21
|
+
def call(env = {})
|
22
|
+
raise "not implemented"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
require 'rundoc/code_command/bash'
|
28
|
+
require 'rundoc/code_command/pipe'
|
29
|
+
require 'rundoc/code_command/write'
|
30
|
+
require 'rundoc/code_command/repl'
|
31
|
+
require 'rundoc/code_command/rundoc_command'
|
32
|
+
require 'rundoc/code_command/no_such_command'
|
@@ -0,0 +1,57 @@
|
|
1
|
+
class Rundoc::CodeCommand::Bash < Rundoc::CodeCommand
|
2
|
+
|
3
|
+
# line = "cd ..""
|
4
|
+
# line = "pwd"
|
5
|
+
# line = "ls"
|
6
|
+
def initialize(line)
|
7
|
+
@line = line
|
8
|
+
@contents = ""
|
9
|
+
@delegate = case @line.split(' ').first.downcase
|
10
|
+
when 'cd'
|
11
|
+
Cd.new(@line)
|
12
|
+
else
|
13
|
+
false
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def to_md(env = {})
|
18
|
+
return @delegate.to_md(env) if @delegate
|
19
|
+
|
20
|
+
"$ #{@line}"
|
21
|
+
end
|
22
|
+
|
23
|
+
def call(env = {})
|
24
|
+
return @delegate.call(env) if @delegate
|
25
|
+
|
26
|
+
shell(@line, @contents)
|
27
|
+
end
|
28
|
+
|
29
|
+
# markdown doesn't understand bash color codes
|
30
|
+
def sanitize_escape_chars(input)
|
31
|
+
input.gsub(/\e\[(\d+)m/, '')
|
32
|
+
end
|
33
|
+
|
34
|
+
def shell(cmd, stdin = nil)
|
35
|
+
msg = "Running: $ '#{cmd}'"
|
36
|
+
msg << " with stdin: '#{stdin.inspect}'" if stdin && !stdin.empty?
|
37
|
+
puts msg
|
38
|
+
|
39
|
+
result = ""
|
40
|
+
IO.popen("#{cmd} 2>&1", "w+") do |io|
|
41
|
+
io << stdin if stdin
|
42
|
+
io.close_write
|
43
|
+
result = sanitize_escape_chars io.read
|
44
|
+
end
|
45
|
+
unless $?.success?
|
46
|
+
raise "Command `#{@line}` exited with non zero status: #{result}" unless keyword.include?("fail")
|
47
|
+
end
|
48
|
+
return result
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
|
53
|
+
Rundoc.register_code_command(:bash, Rundoc::CodeCommand::Bash)
|
54
|
+
Rundoc.register_code_command(:'$', Rundoc::CodeCommand::Bash)
|
55
|
+
Rundoc.register_code_command(:'fail.$', Rundoc::CodeCommand::Bash)
|
56
|
+
|
57
|
+
require 'rundoc/code_command/bash/cd'
|
@@ -0,0 +1,18 @@
|
|
1
|
+
class Rundoc::CodeCommand::Bash
|
2
|
+
# special purpose class to persist cd behavior across the entire program
|
3
|
+
# we change the directory of the parent program (rundoc) rather than
|
4
|
+
# changing the directory of a spawned child (via exec, ``, system, etc.)
|
5
|
+
class Cd < Rundoc::CodeCommand::Bash
|
6
|
+
|
7
|
+
def initialize(line)
|
8
|
+
@line = line
|
9
|
+
end
|
10
|
+
|
11
|
+
def call(env)
|
12
|
+
line = @line.sub('cd', '').strip
|
13
|
+
puts "running $ cd #{line}"
|
14
|
+
Dir.chdir(line)
|
15
|
+
nil
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
class Rundoc::CodeCommand::FileCommand
|
2
|
+
class Append < Rundoc::CodeCommand
|
3
|
+
|
4
|
+
def initialize(filename)
|
5
|
+
@filename, line = filename.split('#')
|
6
|
+
@line_number = Integer(line) if line
|
7
|
+
end
|
8
|
+
|
9
|
+
def to_md(env)
|
10
|
+
raise "must call write in its own code section" unless env[:commands].empty?
|
11
|
+
before = env[:before]
|
12
|
+
if @line_number
|
13
|
+
env[:before] = "In file `#{@filename}`, on line #{@line_number} add:\n\n#{before}"
|
14
|
+
else
|
15
|
+
env[:before] = "At the end of `#{@filename}` add:\n\n#{before}"
|
16
|
+
end
|
17
|
+
nil
|
18
|
+
end
|
19
|
+
|
20
|
+
def last_char_of(string)
|
21
|
+
string[-1,1]
|
22
|
+
end
|
23
|
+
|
24
|
+
def ends_in_newline?(string)
|
25
|
+
last_char_of(string) == "\n"
|
26
|
+
end
|
27
|
+
|
28
|
+
def concat_with_newline(str1, str2)
|
29
|
+
result = ""
|
30
|
+
result << str1
|
31
|
+
result << "\n" unless ends_in_newline?(result)
|
32
|
+
result << str2
|
33
|
+
result << "\n" unless ends_in_newline?(result)
|
34
|
+
result
|
35
|
+
end
|
36
|
+
|
37
|
+
def insert_contents_into_at_line(doc)
|
38
|
+
lines = doc.lines
|
39
|
+
raise "Expected #{@filename} to have at least #{@line_number} but only has #{lines.count}" if lines.count < @line_number
|
40
|
+
result = []
|
41
|
+
lines.each_with_index do |line, index|
|
42
|
+
line_number = index.next
|
43
|
+
if line_number == @line_number
|
44
|
+
result << contents
|
45
|
+
result << "\n" unless ends_in_newline?(contents)
|
46
|
+
end
|
47
|
+
result << line
|
48
|
+
end
|
49
|
+
doc = result.flatten.join("")
|
50
|
+
end
|
51
|
+
|
52
|
+
def call(env = {})
|
53
|
+
dir = File.expand_path("../", @filename)
|
54
|
+
FileUtils.mkdir_p(dir)
|
55
|
+
|
56
|
+
doc = File.read(@filename)
|
57
|
+
if @line_number
|
58
|
+
puts "Writing to: '#{@filename}' line #{@line_number} with: #{contents.inspect}"
|
59
|
+
doc = insert_contents_into_at_line(doc)
|
60
|
+
else
|
61
|
+
puts "Appending to file: '#{@filename}' with: #{contents.inspect}"
|
62
|
+
doc = concat_with_newline(doc, contents)
|
63
|
+
end
|
64
|
+
|
65
|
+
File.open(@filename, "w") do |f|
|
66
|
+
f.write(doc)
|
67
|
+
end
|
68
|
+
contents
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
|
74
|
+
Rundoc.register_code_command(:'file.append', Rundoc::CodeCommand::FileCommand::Append)
|
@@ -0,0 +1,32 @@
|
|
1
|
+
class Rundoc::CodeCommand::FileCommand
|
2
|
+
class Remove < Rundoc::CodeCommand
|
3
|
+
|
4
|
+
def initialize(filename)
|
5
|
+
@filename = filename
|
6
|
+
end
|
7
|
+
|
8
|
+
def to_md(env)
|
9
|
+
raise "must call write in its own code section" unless env[:commands].empty?
|
10
|
+
before = env[:before]
|
11
|
+
env[:before] = "In file `#{@filename}` remove:\n\n#{before}"
|
12
|
+
nil
|
13
|
+
end
|
14
|
+
|
15
|
+
def call(env = {})
|
16
|
+
puts "Deleting '#{contents.strip}' from #{@filename}"
|
17
|
+
raise "#{@filename} does not exist" unless File.exist?(@filename)
|
18
|
+
|
19
|
+
regex = /^\s*#{Regexp.quote(contents)}/
|
20
|
+
doc = File.read(@filename)
|
21
|
+
doc.sub!(regex, '')
|
22
|
+
|
23
|
+
File.open(@filename, "w") do |f|
|
24
|
+
f.write(doc)
|
25
|
+
end
|
26
|
+
contents
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
|
32
|
+
Rundoc.register_code_command(:'file.remove', Rundoc::CodeCommand::FileCommand::Remove)
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module Rundoc
|
2
|
+
class CodeCommand
|
3
|
+
class Pipe < Rundoc::CodeCommand
|
4
|
+
|
5
|
+
# ::: ls
|
6
|
+
# ::: | tail -n 2
|
7
|
+
# => "test\ntmp.file\n"
|
8
|
+
def initialize(line)
|
9
|
+
line_array = line.split(" ")
|
10
|
+
@first = line_array.shift.strip
|
11
|
+
@delegate = Rundoc.code_command_from_keyword(@first, line_array.join(" "))
|
12
|
+
@delegate = Rundoc::CodeCommand::Bash.new(line) if @delegate.kind_of?(Rundoc::CodeCommand::NoSuchCommand)
|
13
|
+
end
|
14
|
+
|
15
|
+
# before: "",
|
16
|
+
# after: "",
|
17
|
+
# commands:
|
18
|
+
# [[cmd, output], [cmd, output]]
|
19
|
+
def call(env = {})
|
20
|
+
last_command = env[:commands].last
|
21
|
+
puts "Piping: results of '#{last_command[:command]}' to '#{@delegate}'"
|
22
|
+
|
23
|
+
@delegate.push(last_command[:output])
|
24
|
+
@delegate.call(env)
|
25
|
+
end
|
26
|
+
|
27
|
+
def to_md(env = {})
|
28
|
+
""
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
|
35
|
+
Rundoc.register_code_command(:pipe, Rundoc::CodeCommand::Pipe)
|
36
|
+
Rundoc.register_code_command(:|, Rundoc::CodeCommand::Pipe)
|
37
|
+
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'repl_runner'
|
2
|
+
|
3
|
+
module Rundoc
|
4
|
+
class CodeCommand
|
5
|
+
class Repl < Rundoc::CodeCommand
|
6
|
+
def initialize(command)
|
7
|
+
@command = command
|
8
|
+
@contents = ""
|
9
|
+
end
|
10
|
+
|
11
|
+
def keyword=(keyword)
|
12
|
+
@keyword = keyword
|
13
|
+
if keyword.to_s == "repl"
|
14
|
+
command_array = @command.split(" ")
|
15
|
+
@keyword = command_array.first
|
16
|
+
else
|
17
|
+
@command = "#{keyword} #{@command}"
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def call(env = {})
|
22
|
+
puts "Running '#{@command}'' with repl: #{keyword}"
|
23
|
+
repl = ReplRunner.new(:"#{keyword}", @command)
|
24
|
+
@result = repl.zip(contents.strip).flatten.join("\n")
|
25
|
+
return @result
|
26
|
+
end
|
27
|
+
|
28
|
+
def to_md(env = {})
|
29
|
+
return "$ #{@command}"
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
|
36
|
+
Rundoc.register_code_command(:repl, Rundoc::CodeCommand::Repl)
|
37
|
+
Rundoc.register_code_command(:irb, Rundoc::CodeCommand::Repl)
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module ::Rundoc
|
2
|
+
class CodeCommand
|
3
|
+
class ::RundocCommand < ::Rundoc::CodeCommand
|
4
|
+
|
5
|
+
def initialize(line)
|
6
|
+
end
|
7
|
+
|
8
|
+
def to_md(env = {})
|
9
|
+
""
|
10
|
+
end
|
11
|
+
|
12
|
+
def call(env = {})
|
13
|
+
puts "Running: #{contents}"
|
14
|
+
eval(contents)
|
15
|
+
""
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
|
22
|
+
Rundoc.register_code_command(:rundoc, ::Rundoc::CodeCommand::RundocCommand)
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module Rundoc
|
2
|
+
class CodeCommand
|
3
|
+
class Write < Rundoc::CodeCommand
|
4
|
+
def initialize(filename)
|
5
|
+
@filename = filename
|
6
|
+
end
|
7
|
+
|
8
|
+
def to_md(env)
|
9
|
+
raise "must call write in its own code section" unless env[:commands].empty?
|
10
|
+
before = env[:before]
|
11
|
+
env[:before] = "In file `#{@filename}` write:\n\n#{before}"
|
12
|
+
nil
|
13
|
+
end
|
14
|
+
|
15
|
+
def call(env = {})
|
16
|
+
puts "Writing to: '#{@filename}'"
|
17
|
+
|
18
|
+
dir = File.expand_path("../", @filename)
|
19
|
+
FileUtils.mkdir_p(dir)
|
20
|
+
File.open(@filename, "w") do |f|
|
21
|
+
f.write(contents)
|
22
|
+
end
|
23
|
+
contents
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
|
30
|
+
Rundoc.register_code_command(:write, Rundoc::CodeCommand::Write)
|
31
|
+
Rundoc.register_code_command(:'file.write', Rundoc::CodeCommand::Write)
|
32
|
+
|
33
|
+
require 'rundoc/code_command/file_command/append'
|
34
|
+
require 'rundoc/code_command/file_command/remove'
|
@@ -0,0 +1,145 @@
|
|
1
|
+
module Rundoc
|
2
|
+
# holds code, parses and creates CodeCommand
|
3
|
+
class CodeSection
|
4
|
+
class ParseError < StandardError
|
5
|
+
def initialize(options = {})
|
6
|
+
keyword = options[:keyword]
|
7
|
+
command = options[:command]
|
8
|
+
line_number = options[:line_number]
|
9
|
+
block = options[:block].lines.map do |line|
|
10
|
+
if line == command
|
11
|
+
" > #{line}"
|
12
|
+
else
|
13
|
+
" #{line}"
|
14
|
+
end
|
15
|
+
end.join("")
|
16
|
+
|
17
|
+
msg = "Error parsing (line:#{line_number}):\n"
|
18
|
+
msg << "> '#{command.strip}'\n"
|
19
|
+
msg << "No such registered command: '#{keyword}'\n"
|
20
|
+
msg << "registered commands: #{Rundoc.known_commands.inspect}\n\n"
|
21
|
+
msg << block
|
22
|
+
msg << "\n"
|
23
|
+
super msg
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
COMMAND_REGEX = Rundoc::Parser::COMMAND_REGEX # todo: move whole thing
|
28
|
+
attr_accessor :original, :fence, :lang, :code, :commands, :keyword
|
29
|
+
|
30
|
+
def initialize(match, options = {})
|
31
|
+
@original = match.to_s
|
32
|
+
@commands = []
|
33
|
+
@stack = []
|
34
|
+
@keyword = options[:keyword] or raise "keyword is required"
|
35
|
+
@fence = match[:fence]
|
36
|
+
@lang = match[:lang]
|
37
|
+
@code = match[:contents]
|
38
|
+
parse_code_command
|
39
|
+
end
|
40
|
+
|
41
|
+
def render
|
42
|
+
result = []
|
43
|
+
env = {}
|
44
|
+
env[:commands] = []
|
45
|
+
env[:before] = "#{fence}#{lang}"
|
46
|
+
env[:after] = "#{fence}"
|
47
|
+
|
48
|
+
@stack.each do |s|
|
49
|
+
unless s.respond_to?(:call)
|
50
|
+
result << s
|
51
|
+
next
|
52
|
+
end
|
53
|
+
|
54
|
+
code_command = s
|
55
|
+
code_output = code_command.call(env) || ""
|
56
|
+
code_line = code_command.to_md(env) || ""
|
57
|
+
|
58
|
+
env[:commands] << { object: code_command, output: code_output, command: code_line}
|
59
|
+
|
60
|
+
if code_command.render_result?
|
61
|
+
result << [code_line, code_output]
|
62
|
+
else
|
63
|
+
result << code_line unless code_command.hidden?
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
return "" if hidden?
|
68
|
+
|
69
|
+
array = [env[:before], result, env[:after]]
|
70
|
+
return array.flatten.compact.map(&:rstrip).reject(&:empty?).join("\n") << "\n"
|
71
|
+
end
|
72
|
+
|
73
|
+
# all of the commands are hidden
|
74
|
+
def hidden?
|
75
|
+
!not_hidden?
|
76
|
+
end
|
77
|
+
|
78
|
+
# one or more of the commands are not hidden
|
79
|
+
def not_hidden?
|
80
|
+
return true if commands.empty?
|
81
|
+
commands.map(&:not_hidden?).detect {|c| c }
|
82
|
+
end
|
83
|
+
|
84
|
+
def command_regex
|
85
|
+
COMMAND_REGEX.call(keyword)
|
86
|
+
end
|
87
|
+
|
88
|
+
def add_code(match, line)
|
89
|
+
add_match_to_code_command(match, commands)
|
90
|
+
check_parse_error(line, code)
|
91
|
+
end
|
92
|
+
|
93
|
+
def add_contents(line)
|
94
|
+
if commands.empty?
|
95
|
+
@stack << line
|
96
|
+
else
|
97
|
+
commands.last << line
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
def parse_code_command
|
102
|
+
code.lines.each do |line|
|
103
|
+
if match = line.match(command_regex)
|
104
|
+
add_code(match, line)
|
105
|
+
else
|
106
|
+
add_contents(line)
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
def add_match_to_code_command(match, commands)
|
112
|
+
command = match[:command]
|
113
|
+
tag = match[:tag]
|
114
|
+
statement = match[:statement]
|
115
|
+
|
116
|
+
code_command = Rundoc.code_command_from_keyword(command, statement)
|
117
|
+
|
118
|
+
case tag
|
119
|
+
when /\-/
|
120
|
+
code_command.hidden = true
|
121
|
+
when /\=/
|
122
|
+
code_command.render_result = true
|
123
|
+
when /\s/
|
124
|
+
# default do nothing
|
125
|
+
end
|
126
|
+
|
127
|
+
@stack << "\n" if commands.last.is_a?(Rundoc::CodeCommand)
|
128
|
+
@stack << code_command
|
129
|
+
commands << code_command
|
130
|
+
code_command
|
131
|
+
end
|
132
|
+
|
133
|
+
def check_parse_error(command, code_block)
|
134
|
+
return unless code_command = @stack.last
|
135
|
+
return unless code_command.is_a?(Rundoc::CodeCommand::NoSuchCommand)
|
136
|
+
@original.lines.each_with_index do |line, index|
|
137
|
+
next unless line == command
|
138
|
+
raise ParseError.new(keyword: code_command.keyword,
|
139
|
+
block: code_block,
|
140
|
+
command: command,
|
141
|
+
line_number: index.next)
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end
|