rundoc 4.1.4 → 6.0.0

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.
Files changed (61) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ci.yml +3 -1
  3. data/.standard.yml +1 -1
  4. data/CHANGELOG.md +12 -0
  5. data/README.md +98 -10
  6. data/lib/rundoc/cli.rb +18 -2
  7. data/lib/rundoc/code_command/background/log/clear.rb +12 -2
  8. data/lib/rundoc/code_command/background/log/read.rb +12 -2
  9. data/lib/rundoc/code_command/background/process_spawn.rb +3 -1
  10. data/lib/rundoc/code_command/background/start.rb +25 -6
  11. data/lib/rundoc/code_command/background/stdin_write.rb +21 -8
  12. data/lib/rundoc/code_command/background/stop.rb +12 -2
  13. data/lib/rundoc/code_command/background/wait.rb +15 -3
  14. data/lib/rundoc/code_command/background.rb +2 -0
  15. data/lib/rundoc/code_command/bash/cd.rb +12 -18
  16. data/lib/rundoc/code_command/bash.rb +43 -19
  17. data/lib/rundoc/code_command/comment.rb +33 -0
  18. data/lib/rundoc/code_command/deferred.rb +66 -0
  19. data/lib/rundoc/code_command/empty_binding.rb +18 -0
  20. data/lib/rundoc/code_command/file_command/append.rb +29 -8
  21. data/lib/rundoc/code_command/file_command/remove.rb +27 -5
  22. data/lib/rundoc/code_command/no_such_command.rb +8 -3
  23. data/lib/rundoc/code_command/pipe.rb +36 -16
  24. data/lib/rundoc/code_command/pre/erb.rb +28 -18
  25. data/lib/rundoc/code_command/print/erb.rb +27 -16
  26. data/lib/rundoc/code_command/print/text.rb +27 -8
  27. data/lib/rundoc/code_command/raw.rb +17 -5
  28. data/lib/rundoc/code_command/rundoc/ensure_later.rb +59 -0
  29. data/lib/rundoc/code_command/rundoc/require.rb +25 -17
  30. data/lib/rundoc/code_command/rundoc_command.rb +26 -9
  31. data/lib/rundoc/code_command/website/driver.rb +2 -0
  32. data/lib/rundoc/code_command/website/navigate.rb +18 -12
  33. data/lib/rundoc/code_command/website/screenshot.rb +17 -11
  34. data/lib/rundoc/code_command/website/visit.rb +23 -12
  35. data/lib/rundoc/code_command/website.rb +2 -0
  36. data/lib/rundoc/code_command/write.rb +37 -9
  37. data/lib/rundoc/code_command.rb +6 -48
  38. data/lib/rundoc/context/after_build.rb +2 -0
  39. data/lib/rundoc/context/execution.rb +2 -0
  40. data/lib/rundoc/document.rb +6 -2
  41. data/lib/rundoc/fenced_code_block.rb +10 -7
  42. data/lib/rundoc/peg_parser.rb +25 -9
  43. data/lib/rundoc/version.rb +3 -1
  44. data/lib/rundoc.rb +89 -17
  45. data/rundoc.gemspec +3 -0
  46. data/test/integration/ensure_later_test.rb +335 -0
  47. data/test/integration/print_test.rb +51 -0
  48. data/test/rundoc/code_commands/append_file_test.rb +35 -10
  49. data/test/rundoc/code_commands/background_test.rb +24 -22
  50. data/test/rundoc/code_commands/bash_test.rb +10 -5
  51. data/test/rundoc/code_commands/comment_test.rb +116 -0
  52. data/test/rundoc/code_commands/pipe_test.rb +2 -2
  53. data/test/rundoc/code_commands/print_test.rb +13 -25
  54. data/test/rundoc/code_commands/remove_contents_test.rb +8 -3
  55. data/test/rundoc/code_section_test.rb +28 -21
  56. data/test/rundoc/peg_parser_test.rb +42 -1
  57. data/test/test_helper.rb +4 -2
  58. metadata +23 -6
  59. data/lib/rundoc/code_command/rundoc/depend_on.rb +0 -13
  60. data/test/fixtures/depend_on/dependency/rundoc.md +0 -5
  61. data/test/fixtures/depend_on/main/rundoc.md +0 -10
@@ -0,0 +1,66 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Rundoc
4
+ module CodeCommand
5
+ # Hold enough information to construct commands, but don't yet
6
+ #
7
+ # Allows us to separate parse time constructs from runtime injectables
8
+ # (such as IO). Which gives us a cleaner running model.
9
+ class Deferred
10
+ attr_accessor :render_result, :render_command,
11
+ :contents, :keyword, :original_args
12
+
13
+ alias_method :render_result?, :render_result
14
+ alias_method :render_command?, :render_command
15
+
16
+ attr_reader :runner_klass
17
+
18
+ def initialize(args_instance:, runner_klass:, always_hidden: false)
19
+ @args_instance = args_instance
20
+ @runner_klass = runner_klass
21
+ @always_hidden = always_hidden
22
+ end
23
+
24
+ def hidden?
25
+ !render_command? && !render_result?
26
+ end
27
+
28
+ def not_hidden?
29
+ !hidden?
30
+ end
31
+
32
+ def push(contents)
33
+ @contents ||= +""
34
+ @contents << contents
35
+ end
36
+ alias_method :<<, :push
37
+
38
+ def build(io: $stdout)
39
+ @built ||= begin
40
+ runner = @runner_klass.new(
41
+ user_args: @args_instance,
42
+ render_command: render_command,
43
+ render_result: render_result,
44
+ contents: @contents,
45
+ io: io
46
+ )
47
+ if @always_hidden
48
+ @render_command = false
49
+ @render_result = false
50
+ end
51
+ runner
52
+ end
53
+ rescue UnknownCommand
54
+ raise "No such command registered with rundoc #{keyword.inspect} for `#{keyword} #{original_args}`"
55
+ end
56
+
57
+ def call(env = {})
58
+ build.call(env)
59
+ end
60
+
61
+ def to_md(env = {})
62
+ build.to_md(env)
63
+ end
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "erb"
4
+
5
+ class EmptyBinding
6
+ def self.create
7
+ new.empty_binding
8
+ end
9
+
10
+ def empty_binding
11
+ binding
12
+ end
13
+ end
14
+
15
+ module Rundoc::CodeCommand
16
+ RUNDOC_ERB_BINDINGS = Hash.new { |h, k| h[k] = EmptyBinding.create }
17
+ RUNDOC_DEFAULT_ERB_BINDING = "default"
18
+ end
@@ -1,18 +1,39 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class Rundoc::CodeCommand::FileCommand
2
- class Append < Rundoc::CodeCommand
3
- include FileUtil
4
+ class AppendArgs
5
+ attr_reader :filename
4
6
 
5
7
  def initialize(filename)
6
- @filename, line = filename.split("#")
8
+ @filename = filename
9
+ end
10
+ end
11
+
12
+ class AppendRunner
13
+ NEWLINE = Rundoc::CodeCommand::WriteRunner::NEWLINE
14
+
15
+ include Rundoc::CodeCommand::FileUtil
16
+
17
+ attr_reader :io, :contents
18
+
19
+ def initialize(user_args:, render_command:, render_result:, io:, contents: nil)
20
+ @filename, line = user_args.filename.split("#")
7
21
  @line_number = if line
8
22
  Integer(line)
9
23
  end
24
+ @io = io
25
+ @render_command = render_command
26
+ @contents = contents.dup if contents && !contents.empty?
27
+ end
28
+
29
+ def render_command?
30
+ @render_command
10
31
  end
11
32
 
12
33
  def to_md(env)
13
34
  return unless render_command?
14
35
 
15
- if env[:commands].any? { |c| c[:object].not_hidden? }
36
+ if env[:commands].any? { |c| c[:visibility].not_hidden? }
16
37
  raise "Must call append in its own code section"
17
38
  end
18
39
 
@@ -34,7 +55,7 @@ class Rundoc::CodeCommand::FileCommand
34
55
  end
35
56
 
36
57
  def concat_with_newline(str1, str2)
37
- result = ""
58
+ result = +""
38
59
  result << str1
39
60
  result << "\n" unless ends_in_newline?(result)
40
61
  result << str2
@@ -61,10 +82,10 @@ class Rundoc::CodeCommand::FileCommand
61
82
  mkdir_p
62
83
  doc = File.read(filename)
63
84
  if @line_number
64
- puts "Writing to: '#{filename}' line #{@line_number} with: #{contents.inspect}"
85
+ io.puts "Writing to: '#{filename}' line #{@line_number} with: #{contents.inspect}"
65
86
  doc = insert_contents_into_at_line(doc)
66
87
  else
67
- puts "Appending to file: '#{filename}' with: #{contents.inspect}"
88
+ io.puts "Appending to file: '#{filename}' with: #{contents.inspect}"
68
89
  doc = concat_with_newline(doc, contents)
69
90
  end
70
91
 
@@ -74,4 +95,4 @@ class Rundoc::CodeCommand::FileCommand
74
95
  end
75
96
  end
76
97
 
77
- Rundoc.register_code_command(:"file.append", Rundoc::CodeCommand::FileCommand::Append)
98
+ Rundoc.register_code_command(keyword: :"file.append", args_klass: Rundoc::CodeCommand::FileCommand::AppendArgs, runner_klass: Rundoc::CodeCommand::FileCommand::AppendRunner)
@@ -1,13 +1,35 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class Rundoc::CodeCommand::FileCommand
2
- class Remove < Rundoc::CodeCommand
3
- include FileUtil
4
+ class RemoveArgs
5
+ attr_reader :filename
4
6
 
5
7
  def initialize(filename)
6
8
  @filename = filename
7
9
  end
10
+ end
11
+
12
+ class RemoveRunner
13
+ NEWLINE = Object.new
14
+ def NEWLINE.to_s
15
+ ""
16
+ end
17
+
18
+ def NEWLINE.empty?
19
+ false
20
+ end
21
+ include Rundoc::CodeCommand::FileUtil
22
+
23
+ attr_reader :io, :contents
24
+
25
+ def initialize(user_args:, render_command:, render_result:, io:, contents: nil)
26
+ @filename = user_args.filename
27
+ @io = io
28
+ @contents = contents.dup if contents && !contents.empty?
29
+ end
8
30
 
9
31
  def to_md(env)
10
- if env[:commands].any? { |c| c[:object].not_hidden? }
32
+ if env[:commands].any? { |c| c[:visibility].not_hidden? }
11
33
  raise "Must call remove in its own code section"
12
34
  end
13
35
 
@@ -17,7 +39,7 @@ class Rundoc::CodeCommand::FileCommand
17
39
  end
18
40
 
19
41
  def call(env = {})
20
- puts "Deleting '#{contents.strip}' from #{filename}"
42
+ io.puts "Deleting '#{contents.strip}' from #{filename}"
21
43
  raise "#{filename} does not exist" unless File.exist?(filename)
22
44
 
23
45
  regex = /^\s*#{Regexp.quote(contents)}/
@@ -30,4 +52,4 @@ class Rundoc::CodeCommand::FileCommand
30
52
  end
31
53
  end
32
54
 
33
- Rundoc.register_code_command(:"file.remove", Rundoc::CodeCommand::FileCommand::Remove)
55
+ Rundoc.register_code_command(keyword: :"file.remove", args_klass: Rundoc::CodeCommand::FileCommand::RemoveArgs, runner_klass: Rundoc::CodeCommand::FileCommand::RemoveRunner)
@@ -1,8 +1,13 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Rundoc
2
- class CodeCommand
3
- class NoSuchCommand < Rundoc::CodeCommand
4
+ module CodeCommand
5
+ class NoSuchCommand
6
+ def initialize(user_args: nil, render_command: false, render_result: false, io: nil, contents: nil)
7
+ end
8
+
4
9
  def call(env = {})
5
- raise "No such command registered with rundoc: #{@keyword.inspect} for '#{@keyword} #{@original_args}'"
10
+ raise UnknownCommand
6
11
  end
7
12
  end
8
13
  end
@@ -1,11 +1,21 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Rundoc
2
- class CodeCommand
3
- class Pipe < Rundoc::CodeCommand
4
- # ::: ls
5
- # ::: | tail -n 2
6
- # => "test\ntmp.file\n"
4
+ module CodeCommand
5
+ class PipeArgs
6
+ attr_reader :line
7
+
7
8
  def initialize(line)
8
- @delegate = parse(line)
9
+ @line = line
10
+ end
11
+ end
12
+
13
+ class PipeRunner
14
+ attr_reader :io
15
+
16
+ def initialize(user_args:, render_command:, render_result:, io:, contents: nil)
17
+ @io = io
18
+ @delegate = parse(user_args.line)
9
19
  end
10
20
 
11
21
  # before: "",
@@ -14,10 +24,10 @@ module Rundoc
14
24
  # [[cmd, output], [cmd, output]]
15
25
  def call(env = {})
16
26
  last_command = env[:commands].last
17
- puts "Piping: results of '#{last_command[:command]}' to '#{@delegate}'"
27
+ io.puts "Piping: results of '#{last_command[:command]}' to '#{@delegate}'"
18
28
 
19
29
  @delegate.push(last_command[:output])
20
- @delegate.call(env)
30
+ @delegate.build(io: io).call(env)
21
31
  end
22
32
 
23
33
  def to_md(env = {})
@@ -31,17 +41,27 @@ module Rundoc
31
41
 
32
42
  actual = actual.first if actual.is_a?(Array)
33
43
 
34
- actual = Rundoc::CodeCommand::Bash.new(code) if actual.is_a?(Rundoc::CodeCommand::NoSuchCommand)
35
- actual
36
-
37
- # Since `| tail -n 2` does not start with a `$` assume any "naked" commands
38
- # are bash
44
+ if actual.runner_klass == Rundoc::CodeCommand::NoSuchCommand
45
+ bash_deferred(code)
46
+ else
47
+ actual
48
+ end
39
49
  rescue Parslet::ParseFailed
40
- Rundoc::CodeCommand::Bash.new(code)
50
+ bash_deferred(code)
51
+ end
52
+
53
+ private def bash_deferred(code)
54
+ deferred = Rundoc::CodeCommand::Deferred.new(
55
+ args_instance: Rundoc::CodeCommand::BashArgs.new(code),
56
+ runner_klass: Rundoc::CodeCommand::BashRunner
57
+ )
58
+ deferred.render_command = false
59
+ deferred.render_result = false
60
+ deferred
41
61
  end
42
62
  end
43
63
  end
44
64
  end
45
65
 
46
- Rundoc.register_code_command(:pipe, Rundoc::CodeCommand::Pipe)
47
- Rundoc.register_code_command(:|, Rundoc::CodeCommand::Pipe)
66
+ Rundoc.register_code_command(keyword: :pipe, args_klass: Rundoc::CodeCommand::PipeArgs, runner_klass: Rundoc::CodeCommand::PipeRunner)
67
+ Rundoc.register_code_command(keyword: :|, args_klass: Rundoc::CodeCommand::PipeArgs, runner_klass: Rundoc::CodeCommand::PipeRunner)
@@ -1,44 +1,54 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require_relative "../print/erb"
2
4
 
3
- class Rundoc::CodeCommand
4
- class PreErb < Rundoc::CodeCommand
5
+ module Rundoc::CodeCommand
6
+ class PreErbArgs
7
+ attr_reader :line
8
+
5
9
  def initialize(line)
6
10
  @line = line
11
+ end
12
+ end
13
+
14
+ class PreErbRunner
15
+ attr_reader :io, :contents
16
+
17
+ def initialize(user_args:, render_command:, render_result:, io:, contents: nil)
18
+ @line = user_args.line
7
19
  @binding = RUNDOC_ERB_BINDINGS[RUNDOC_DEFAULT_ERB_BINDING]
8
20
  @code = nil
9
21
  @command = nil
10
22
  @template = nil
11
- @render_delegate_result = nil
12
- @render_delegate_command = nil
13
- # Hide self, pass visibility onto delegate
14
- @render_result = false
15
- @render_command = false
23
+ @render_command = render_command
24
+ @render_result = render_result
25
+ @io = io
26
+ @contents = contents.dup if contents && !contents.empty?
16
27
  end
17
28
 
18
- # Visibility is injected by the parser, capture it and pass it to the delegate
19
- def render_result=(value)
20
- @render_delegate_result = value
29
+ def render_command?
30
+ @render_command
21
31
  end
22
32
 
23
- def render_command=(value)
24
- @render_delegate_command = value
33
+ def render_result?
34
+ @render_result
25
35
  end
26
36
 
27
37
  def code
28
38
  @code ||= begin
29
39
  vis = +""
30
- vis += @render_delegate_command ? ">" : "-"
31
- vis += @render_delegate_result ? ">" : "-"
40
+ vis += render_command? ? ">" : "-"
41
+ vis += render_result? ? ">" : "-"
32
42
  code = [@line, @contents]
33
43
  .compact
34
44
  .reject(&:empty?)
35
45
  .join("\n")
36
46
  @template = ":::#{vis} #{code}"
37
47
 
38
- puts "pre.erb: Applying ERB, template:\n#{@template}"
48
+ io.puts "pre.erb: Applying ERB, template:\n#{@template}"
39
49
  result = ERB.new(@template).result(@binding)
40
- puts "pre.erb: ERB result:\n#{result}"
41
- puts "pre.erb: done, ready to delegate"
50
+ io.puts "pre.erb: ERB result:\n#{result}"
51
+ io.puts "pre.erb: done, ready to delegate"
42
52
  result
43
53
  end
44
54
  end
@@ -60,4 +70,4 @@ class Rundoc::CodeCommand
60
70
  end
61
71
  end
62
72
  end
63
- Rundoc.register_code_command(:"pre.erb", Rundoc::CodeCommand::PreErb)
73
+ Rundoc.register_code_command(keyword: :"pre.erb", args_klass: Rundoc::CodeCommand::PreErbArgs, runner_klass: Rundoc::CodeCommand::PreErbRunner, always_hidden: true)
@@ -1,23 +1,34 @@
1
- require "erb"
1
+ # frozen_string_literal: true
2
2
 
3
- class EmptyBinding
4
- def self.create
5
- new.empty_binding
6
- end
7
-
8
- def empty_binding
9
- binding
10
- end
11
- end
3
+ require_relative "../empty_binding"
12
4
 
13
- class Rundoc::CodeCommand
14
- RUNDOC_ERB_BINDINGS = Hash.new { |h, k| h[k] = EmptyBinding.create }
15
- RUNDOC_DEFAULT_ERB_BINDING = "default"
5
+ module Rundoc::CodeCommand
6
+ class PrintERBArgs
7
+ attr_reader :line, :binding_name
16
8
 
17
- class PrintERB < Rundoc::CodeCommand
18
9
  def initialize(line = nil, binding: RUNDOC_DEFAULT_ERB_BINDING)
19
10
  @line = line
20
- @binding = RUNDOC_ERB_BINDINGS[binding]
11
+ @binding_name = binding
12
+ end
13
+ end
14
+
15
+ class PrintERBRunner
16
+ attr_reader :contents
17
+
18
+ def initialize(user_args:, render_command:, render_result:, io: nil, contents: nil)
19
+ @line = user_args.line
20
+ @binding = RUNDOC_ERB_BINDINGS[user_args.binding_name]
21
+ @render_command = render_command
22
+ @render_result = render_result
23
+ @contents = contents.dup if contents && !contents.empty?
24
+ end
25
+
26
+ def render_command?
27
+ @render_command
28
+ end
29
+
30
+ def render_result?
31
+ @render_result
21
32
  end
22
33
 
23
34
  def to_md(env)
@@ -45,4 +56,4 @@ class Rundoc::CodeCommand
45
56
  end
46
57
  end
47
58
  end
48
- Rundoc.register_code_command(:"print.erb", Rundoc::CodeCommand::PrintERB)
59
+ Rundoc.register_code_command(keyword: :"print.erb", args_klass: Rundoc::CodeCommand::PrintERBArgs, runner_klass: Rundoc::CodeCommand::PrintERBRunner)
@@ -1,8 +1,31 @@
1
- class Rundoc::CodeCommand
2
- class PrintText < Rundoc::CodeCommand
3
- def initialize(line)
1
+ # frozen_string_literal: true
2
+
3
+ module Rundoc::CodeCommand
4
+ class PrintTextArgs
5
+ attr_reader :line
6
+
7
+ def initialize(line = nil)
4
8
  @line = line
5
9
  end
10
+ end
11
+
12
+ class PrintTextRunner
13
+ attr_reader :contents
14
+
15
+ def initialize(user_args:, render_command:, render_result:, io: nil, contents: nil)
16
+ @line = user_args.line
17
+ @render_command = render_command
18
+ @render_result = render_result
19
+ @contents = contents.dup if contents && !contents.empty?
20
+ end
21
+
22
+ def render_command?
23
+ @render_command
24
+ end
25
+
26
+ def render_result?
27
+ @render_result
28
+ end
6
29
 
7
30
  def to_md(env)
8
31
  if render_before?
@@ -12,10 +35,6 @@ class Rundoc::CodeCommand
12
35
  ""
13
36
  end
14
37
 
15
- def hidden?
16
- !render_result?
17
- end
18
-
19
38
  def call(env = {})
20
39
  if render_before?
21
40
  ""
@@ -30,4 +49,4 @@ class Rundoc::CodeCommand
30
49
  end
31
50
  end
32
51
 
33
- Rundoc.register_code_command(:"print.text", Rundoc::CodeCommand::PrintText)
52
+ Rundoc.register_code_command(keyword: :"print.text", args_klass: Rundoc::CodeCommand::PrintTextArgs, runner_klass: Rundoc::CodeCommand::PrintTextRunner)
@@ -1,9 +1,21 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Rundoc
2
- class CodeCommand
3
- class Raw < CodeCommand
4
- def initialize(contents, visible: true)
5
- @contents = contents
6
- @render_result = visible
4
+ module CodeCommand
5
+ # Wraps lines inside a fenced code block that are not rundoc commands.
6
+ # These are rendered as-is without executing any code.
7
+ #
8
+ # Example:
9
+ #
10
+ # ```ruby
11
+ # gem 'sqlite3' <- parsed as Raw
12
+ # :::>> $ echo "hi" <- parsed as a code command
13
+ # ```
14
+ class Raw
15
+ attr_reader :contents
16
+
17
+ def initialize(user_args: nil, render_command: true, render_result: true, io: nil, contents: nil)
18
+ @contents = contents.dup if contents && !contents.empty?
7
19
  end
8
20
 
9
21
  def call(env = {})
@@ -0,0 +1,59 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ::Rundoc::CodeCommand
4
+ class RundocCommand
5
+ class EnsureLaterArgs
6
+ MAPPING = {
7
+ cwd: ->(context:) {
8
+ Dir.pwd
9
+ },
10
+ rundoc_root: ->(context:) {
11
+ context.output_dir.to_s
12
+ }
13
+ }.freeze
14
+
15
+ def initialize(dir:)
16
+ @dir = dir
17
+ @logic = MAPPING[dir] or raise ArgumentError, "Invalid argument dir: #{dir} must be one of #{MAPPING.keys}"
18
+ end
19
+
20
+ def call(context:)
21
+ @logic.call(context: context)
22
+ end
23
+
24
+ def to_s
25
+ @dir
26
+ end
27
+ end
28
+
29
+ class EnsureLaterRunner
30
+ attr_reader :io, :contents
31
+
32
+ def initialize(user_args:, render_command:, render_result:, io:, contents: nil)
33
+ @io = io
34
+ @contents = contents.dup if contents && !contents.empty?
35
+ @dir = user_args
36
+ @binding = RUNDOC_ERB_BINDINGS[RUNDOC_DEFAULT_ERB_BINDING]
37
+ end
38
+
39
+ def to_md(env = {})
40
+ ""
41
+ end
42
+
43
+ def call(env = {})
44
+ resolved_dir = @dir.call(context: env[:context])
45
+
46
+ io.puts "Registering ensure_later block (dir: #{@dir} => #{resolved_dir})"
47
+ Rundoc.add_ensure_later(dir: resolved_dir, code: @contents, binding: @binding)
48
+ ""
49
+ end
50
+ end
51
+ end
52
+ end
53
+
54
+ Rundoc.register_code_command(
55
+ keyword: :"rundoc.ensure_later",
56
+ args_klass: Rundoc::CodeCommand::RundocCommand::EnsureLaterArgs,
57
+ runner_klass: Rundoc::CodeCommand::RundocCommand::EnsureLaterRunner,
58
+ always_hidden: true
59
+ )
@@ -1,13 +1,28 @@
1
- class ::Rundoc::CodeCommand
1
+ # frozen_string_literal: true
2
+
3
+ module ::Rundoc::CodeCommand
2
4
  class RundocCommand
3
- class Require < ::Rundoc::CodeCommand
4
- # Pass in the relative path of another rundoc document in order to
5
- # run all of it's commands. Resulting contents will be displayed
6
- # in current document
5
+ class RequireArgs
6
+ attr_reader :path
7
+
7
8
  def initialize(path)
8
9
  raise "Path must be relative (i.e. start with `.` or `..`. #{path.inspect} does not" unless path.start_with?(".")
9
10
  @path = Pathname.new(path)
10
11
  end
12
+ end
13
+
14
+ class RequireRunner
15
+ attr_reader :io
16
+
17
+ def initialize(user_args:, render_command:, render_result:, io:, contents: nil)
18
+ @path = user_args.path
19
+ @io = io
20
+ @render_result = render_result
21
+ end
22
+
23
+ def render_result?
24
+ @render_result
25
+ end
11
26
 
12
27
  def to_md(env = {})
13
28
  ""
@@ -24,28 +39,21 @@ class ::Rundoc::CodeCommand
24
39
  output_dir: execution_context.output_dir,
25
40
  screenshots_dirname: execution_context.screenshots_dir,
26
41
  with_contents_dir: execution_context.with_contents_dir
27
- )
42
+ ),
43
+ io: io
28
44
  ).to_md
29
45
 
30
46
  if render_result?
31
- puts "rundoc.require: Done executing #{@path.to_s.inspect}, putting contents into document"
47
+ io.puts "rundoc.require: Done executing #{@path.to_s.inspect}, putting contents into document"
32
48
  env[:before] << output
33
49
  else
34
- puts "rundoc.require: Done executing #{@path.to_s.inspect}, quietly"
50
+ io.puts "rundoc.require: Done executing #{@path.to_s.inspect}, quietly"
35
51
  end
36
52
 
37
53
  ""
38
54
  end
39
-
40
- def hidden?
41
- !render_result?
42
- end
43
-
44
- def not_hidden?
45
- !hidden?
46
- end
47
55
  end
48
56
  end
49
57
  end
50
58
 
51
- Rundoc.register_code_command(:"rundoc.require", ::Rundoc::CodeCommand::RundocCommand::Require)
59
+ Rundoc.register_code_command(keyword: :"rundoc.require", args_klass: ::Rundoc::CodeCommand::RundocCommand::RequireArgs, runner_klass: ::Rundoc::CodeCommand::RundocCommand::RequireRunner)