markdown_exec 1.5 → 1.7
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +1 -1
- data/CHANGELOG.md +10 -0
- data/Gemfile +3 -0
- data/Gemfile.lock +6 -1
- data/Rakefile +1 -0
- data/bin/tab_completion.sh +2 -2
- data/examples/import0.md +41 -5
- data/examples/import1.md +9 -8
- data/examples/linked1.md +8 -4
- data/examples/opts.md +4 -7
- data/lib/array.rb +27 -0
- data/lib/array_util.rb +21 -0
- data/lib/cached_nested_file_reader.rb +51 -31
- data/lib/constants.rb +46 -0
- data/lib/env.rb +2 -1
- data/lib/exceptions.rb +34 -0
- data/lib/fcb.rb +41 -1
- data/lib/filter.rb +32 -17
- data/lib/fout.rb +52 -0
- data/lib/hash.rb +21 -0
- data/lib/hash_delegator.rb +2709 -0
- data/lib/markdown_exec/version.rb +1 -1
- data/lib/markdown_exec.rb +137 -1456
- data/lib/mdoc.rb +0 -3
- data/lib/menu.src.yml +145 -31
- data/lib/menu.yml +136 -27
- data/lib/method_sorter.rb +19 -17
- data/lib/object_present.rb +1 -1
- data/lib/option_value.rb +4 -2
- data/lib/pty1.rb +26 -0
- data/lib/regexp.rb +4 -5
- data/lib/saved_assets.rb +4 -2
- data/lib/saved_files_matcher.rb +7 -3
- data/lib/shared.rb +0 -5
- data/lib/string_util.rb +22 -0
- data/lib/tap.rb +5 -2
- metadata +11 -3
- data/lib/environment_opt_parse.rb +0 -209
data/lib/pty1.rb
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'pty'
|
4
|
+
|
5
|
+
def launch_and_interact_with_terminal
|
6
|
+
PTY.spawn('bash') do |stdout, stdin, _pid|
|
7
|
+
# Send a command to the terminal
|
8
|
+
stdin.puts "echo 'Hello from Ruby!'"
|
9
|
+
|
10
|
+
# Read the output of the command
|
11
|
+
stdout.each do |line|
|
12
|
+
puts line
|
13
|
+
break if line.include?('Hello from Ruby!')
|
14
|
+
end
|
15
|
+
|
16
|
+
# You can continue to interact with the terminal here
|
17
|
+
# ...
|
18
|
+
|
19
|
+
# Ensure to exit the spawned shell
|
20
|
+
stdin.puts 'exit'
|
21
|
+
end
|
22
|
+
rescue PTY::ChildExited
|
23
|
+
puts 'The child process exited!'
|
24
|
+
end
|
25
|
+
|
26
|
+
launch_and_interact_with_terminal
|
data/lib/regexp.rb
CHANGED
@@ -25,15 +25,13 @@
|
|
25
25
|
# captures_hash[:file_name] = $~.pre_match.split("\n").last
|
26
26
|
# captures_hash[:line_number] = $~.pre_match.count("\n") + 1
|
27
27
|
# captures_hash[:line] = $&
|
28
|
-
|
29
|
-
require 'English'
|
30
28
|
class Regexp
|
31
29
|
def gsub_format(input_str, format_str, context: {})
|
32
30
|
input_str.gsub(self) do
|
33
31
|
format(
|
34
32
|
format_str,
|
35
|
-
context.merge(
|
36
|
-
hash[name.to_sym] =
|
33
|
+
context.merge($~.names.each_with_object({}) do |name, hash|
|
34
|
+
hash[name.to_sym] = $~[name]
|
37
35
|
end)
|
38
36
|
)
|
39
37
|
end
|
@@ -92,7 +90,8 @@ if $PROGRAM_NAME == __FILE__
|
|
92
90
|
re = /^(?<name>\w+) is (?<age>\d+).*$/
|
93
91
|
fmt = "%<name>s's age is %<age>d and she lives in %<city>s"
|
94
92
|
|
95
|
-
result = re.gsub_format(input_str, re, fmt,
|
93
|
+
result = re.gsub_format(input_str, re, fmt,
|
94
|
+
context: { city: 'New York' })
|
96
95
|
|
97
96
|
assert_equal "Jane's age is 25 and she lives in New York", result
|
98
97
|
end
|
data/lib/saved_assets.rb
CHANGED
@@ -18,12 +18,14 @@ module MarkdownExec
|
|
18
18
|
# Generates a formatted script name based on the provided parameters.
|
19
19
|
def self.script_name(filename:, prefix:, time:, blockname:)
|
20
20
|
fne = filename.gsub(FNR11, FNR12)
|
21
|
-
"#{[prefix, time.strftime('%F-%H-%M-%S'), fne, ',',
|
21
|
+
"#{[prefix, time.strftime('%F-%H-%M-%S'), fne, ',',
|
22
|
+
blockname].join('_')}.sh"
|
22
23
|
end
|
23
24
|
|
24
25
|
# Generates a formatted stdout name based on the provided parameters.
|
25
26
|
def self.stdout_name(filename:, prefix:, time:, blockname:)
|
26
|
-
"#{[prefix, time.strftime('%F-%H-%M-%S'), filename,
|
27
|
+
"#{[prefix, time.strftime('%F-%H-%M-%S'), filename,
|
28
|
+
blockname].join('_')}.out.txt"
|
27
29
|
end
|
28
30
|
end
|
29
31
|
end
|
data/lib/saved_files_matcher.rb
CHANGED
@@ -45,15 +45,19 @@ if $PROGRAM_NAME == __FILE__
|
|
45
45
|
end
|
46
46
|
|
47
47
|
def test_list_all
|
48
|
-
assert_kind_of Array,
|
48
|
+
assert_kind_of Array,
|
49
|
+
MarkdownExec::SavedFilesMatcher.list_all(@folder, @glob)
|
49
50
|
end
|
50
51
|
|
51
52
|
def test_most_recent
|
52
|
-
assert_match(/\.md$/,
|
53
|
+
assert_match(/\.md$/,
|
54
|
+
MarkdownExec::SavedFilesMatcher.most_recent(@folder,
|
55
|
+
@glob))
|
53
56
|
end
|
54
57
|
|
55
58
|
def test_most_recent_list
|
56
|
-
result = MarkdownExec::SavedFilesMatcher.most_recent_list(@folder,
|
59
|
+
result = MarkdownExec::SavedFilesMatcher.most_recent_list(@folder,
|
60
|
+
@glob, 5)
|
57
61
|
assert_kind_of Array, result
|
58
62
|
assert_operator result.size, :<=, 16
|
59
63
|
end
|
data/lib/shared.rb
CHANGED
@@ -16,11 +16,6 @@ DISPLAY_LEVEL_DUMP = 3
|
|
16
16
|
DISPLAY_LEVEL_DEFAULT = DISPLAY_LEVEL_ADMIN
|
17
17
|
DISPLAY_LEVEL_MAX = DISPLAY_LEVEL_DUMP
|
18
18
|
|
19
|
-
# @execute_files[ind] = @execute_files[ind] + [block]
|
20
|
-
EF_STDOUT = 0
|
21
|
-
EF_STDERR = 1
|
22
|
-
EF_STDIN = 2
|
23
|
-
|
24
19
|
LOCAL_YML = 'menu.yml'
|
25
20
|
MENU_YML = "lib/#{LOCAL_YML}"
|
26
21
|
|
data/lib/string_util.rb
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
# encoding=utf-8
|
5
|
+
|
6
|
+
module StringUtil
|
7
|
+
# Splits the given string on the first occurrence of the specified character.
|
8
|
+
# Returns an array containing the portion of the string before the character and the rest of the string.
|
9
|
+
#
|
10
|
+
# @param input_str [String] The string to be split.
|
11
|
+
# @param split_char [String] The character on which to split the string.
|
12
|
+
# @return [Array<String>] An array containing two elements: the part of the string before split_char, and the rest of the string.
|
13
|
+
def self.partition_at_first(input_str, split_char)
|
14
|
+
split_index = input_str.index(split_char)
|
15
|
+
|
16
|
+
if split_index.nil?
|
17
|
+
[input_str, '']
|
18
|
+
else
|
19
|
+
[input_str[0...split_index], input_str[(split_index + 1)..-1]]
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
data/lib/tap.rb
CHANGED
@@ -107,7 +107,9 @@ module Tap
|
|
107
107
|
outs = []
|
108
108
|
outs.push(source.to_s) if source.present?
|
109
109
|
|
110
|
-
vs = (caller_first || caller[0]).scan(/in `?(\S+)'$/).fetch(0, []).fetch(
|
110
|
+
vs = (caller_first || caller[0]).scan(/in `?(\S+)'$/).fetch(0, []).fetch(
|
111
|
+
0, ''
|
112
|
+
)
|
111
113
|
outs.push("#{vs}()") if vs.present?
|
112
114
|
|
113
115
|
outs.push(tap_named_value(name_ || name, method(fn).call))
|
@@ -142,7 +144,8 @@ module Tap
|
|
142
144
|
|
143
145
|
# :reek:ControlParameter
|
144
146
|
# :reek:LongParameterList
|
145
|
-
def tap_yaml(name_ = nil, caller_first: nil, mask: TDD, name: DN,
|
147
|
+
def tap_yaml(name_ = nil, caller_first: nil, mask: TDD, name: DN,
|
148
|
+
source: nil)
|
146
149
|
tap_inspect name_, caller_first: (caller_first || caller[0]),
|
147
150
|
mask: mask, name: name, source: source, type: :yaml
|
148
151
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: markdown_exec
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: '1.
|
4
|
+
version: '1.7'
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Fareed Stevenson
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-
|
11
|
+
date: 2023-12-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: clipboard
|
@@ -127,15 +127,21 @@ files:
|
|
127
127
|
- examples/port.md
|
128
128
|
- examples/vars.md
|
129
129
|
- examples/wrap.md
|
130
|
+
- lib/array.rb
|
131
|
+
- lib/array_util.rb
|
130
132
|
- lib/block_label.rb
|
131
133
|
- lib/block_types.rb
|
132
134
|
- lib/cached_nested_file_reader.rb
|
133
135
|
- lib/cli.rb
|
134
136
|
- lib/colorize.rb
|
137
|
+
- lib/constants.rb
|
135
138
|
- lib/env.rb
|
136
|
-
- lib/
|
139
|
+
- lib/exceptions.rb
|
137
140
|
- lib/fcb.rb
|
138
141
|
- lib/filter.rb
|
142
|
+
- lib/fout.rb
|
143
|
+
- lib/hash.rb
|
144
|
+
- lib/hash_delegator.rb
|
139
145
|
- lib/markdown_exec.rb
|
140
146
|
- lib/markdown_exec/version.rb
|
141
147
|
- lib/mdoc.rb
|
@@ -144,12 +150,14 @@ files:
|
|
144
150
|
- lib/method_sorter.rb
|
145
151
|
- lib/object_present.rb
|
146
152
|
- lib/option_value.rb
|
153
|
+
- lib/pty1.rb
|
147
154
|
- lib/regexp.rb
|
148
155
|
- lib/rspec_helpers.rb
|
149
156
|
- lib/saved_assets.rb
|
150
157
|
- lib/saved_files_matcher.rb
|
151
158
|
- lib/shared.rb
|
152
159
|
- lib/sort_yaml_gpt4.rb
|
160
|
+
- lib/string_util.rb
|
153
161
|
- lib/tap.rb
|
154
162
|
homepage: https://rubygems.org/gems/markdown_exec
|
155
163
|
licenses:
|
@@ -1,209 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
# encoding=utf-8
|
4
|
-
|
5
|
-
require 'optparse'
|
6
|
-
require 'yaml'
|
7
|
-
|
8
|
-
require_relative 'object_present'
|
9
|
-
|
10
|
-
# add Hash.sym_keys
|
11
|
-
#
|
12
|
-
class Hash
|
13
|
-
unless defined?(sym_keys)
|
14
|
-
def sym_keys
|
15
|
-
transform_keys(&:to_sym)
|
16
|
-
# map do |key, value|
|
17
|
-
# [key.to_sym, value]
|
18
|
-
# end.to_h
|
19
|
-
end
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
# parse application configuration from command-line options and environment variables
|
24
|
-
#
|
25
|
-
class EnvironmentOptParse
|
26
|
-
attr_reader :options, :remainder
|
27
|
-
|
28
|
-
# utility functions to create menu
|
29
|
-
#
|
30
|
-
module Menu
|
31
|
-
def menu_all(menu_data, lambdas, config)
|
32
|
-
config.tap_yaml 'config'
|
33
|
-
input_option_values, remainder, = menu_parse(add_proc(menu_data, lambdas))
|
34
|
-
options = menu_default_option_values(menu_data)
|
35
|
-
.merge(config)
|
36
|
-
.merge(input_option_values)
|
37
|
-
|
38
|
-
[options, remainder]
|
39
|
-
end
|
40
|
-
|
41
|
-
def add_proc(menu_data, lambdas)
|
42
|
-
menu_data.each do |menu_item|
|
43
|
-
menu_item.tap_yaml 'menu_item'
|
44
|
-
procname = menu_item[:procname]
|
45
|
-
next if procname.nil?
|
46
|
-
|
47
|
-
menu_item[:proccode] =
|
48
|
-
lambdas.fetch(procname.to_sym, menu_item[:procname])
|
49
|
-
end.tap_yaml
|
50
|
-
end
|
51
|
-
|
52
|
-
def menu_default_option_values(menu_data)
|
53
|
-
menu_data.map do |item|
|
54
|
-
item_default = item[:default]
|
55
|
-
next if item_default.nil?
|
56
|
-
next unless item[:opt_name].present?
|
57
|
-
|
58
|
-
[item[:opt_name].to_sym, item_default]
|
59
|
-
end.compact.to_h
|
60
|
-
end
|
61
|
-
|
62
|
-
def menu_help(menu_data)
|
63
|
-
options = {}
|
64
|
-
option_parser = OptionParser.new do |opts|
|
65
|
-
opts.banner = [
|
66
|
-
"#{APP_NAME} - #{APP_DESC} (#{VERSION})",
|
67
|
-
"Usage: #{File.basename($PROGRAM_NAME)} [options]"
|
68
|
-
].join("\n")
|
69
|
-
|
70
|
-
menu_data.each do |item|
|
71
|
-
menu_option_append opts, options, item
|
72
|
-
end
|
73
|
-
end
|
74
|
-
|
75
|
-
option_parser.help
|
76
|
-
end
|
77
|
-
|
78
|
-
def menu_option_append(opts, options, item)
|
79
|
-
return unless item[:long_name].present? || item[:short_name].present?
|
80
|
-
|
81
|
-
mmoo = [
|
82
|
-
# long name
|
83
|
-
if item[:long_name].present?
|
84
|
-
# if "--#{item[:long_name]}#{item[:arg_name]".present?
|
85
|
-
# " #{item[:arg_name]}"
|
86
|
-
# else
|
87
|
-
# "''}"
|
88
|
-
# end
|
89
|
-
end,
|
90
|
-
|
91
|
-
# short name
|
92
|
-
item[:short_name].present? ? "-#{item[:short_name]}" : nil,
|
93
|
-
|
94
|
-
# description and default
|
95
|
-
[
|
96
|
-
item[:description],
|
97
|
-
item[:default].present? ? "[#{value_for_menu item[:default]}]" : nil
|
98
|
-
].compact.join(' '),
|
99
|
-
|
100
|
-
# apply proccode, if present, to value
|
101
|
-
# save value to options hash if option is named
|
102
|
-
#
|
103
|
-
lambda { |value|
|
104
|
-
(item[:proccode] ? item[:proccode].call(value) : value).tap do |converted|
|
105
|
-
opt_name = item[:opt_name]
|
106
|
-
next if opt_name.nil?
|
107
|
-
|
108
|
-
options[opt_name.to_sym] = converted if item[:opt_name]
|
109
|
-
end
|
110
|
-
}
|
111
|
-
].compact
|
112
|
-
opts.on(*mmoo)
|
113
|
-
end
|
114
|
-
|
115
|
-
def menu_parse(menu_options)
|
116
|
-
options = {}
|
117
|
-
option_parser = OptionParser.new do |opts|
|
118
|
-
menu_options.each do |item|
|
119
|
-
item[:opt_name] = item[:opt_name]&.to_sym
|
120
|
-
menu_option_append opts, options, item
|
121
|
-
end
|
122
|
-
end
|
123
|
-
|
124
|
-
# filename defaults to basename of the program
|
125
|
-
# without suffix in a directory ~/.options
|
126
|
-
option_parser.load
|
127
|
-
option_parser.environment # env defaults to the basename of the program.
|
128
|
-
remainder = option_parser.parse!
|
129
|
-
|
130
|
-
[options, remainder, option_parser.help]
|
131
|
-
end
|
132
|
-
|
133
|
-
# skip :reek:UtilityFunction
|
134
|
-
def value_for_menu(value)
|
135
|
-
case value.class.to_s
|
136
|
-
when 'String'
|
137
|
-
value
|
138
|
-
when 'FalseClass', 'TrueClass'
|
139
|
-
value ? '1' : '0'
|
140
|
-
else
|
141
|
-
value.to_s
|
142
|
-
end
|
143
|
-
end
|
144
|
-
end
|
145
|
-
|
146
|
-
include Menu
|
147
|
-
|
148
|
-
def initialize(menu: {}, lambdas: nil, options: nil, version: nil)
|
149
|
-
@menu = if menu.instance_of?(::String)
|
150
|
-
filetext = File.read(menu).tap_yaml 'filetext'
|
151
|
-
fileyaml = YAML.load(filetext)
|
152
|
-
fileyaml.map(&:sym_keys)
|
153
|
-
else
|
154
|
-
menu
|
155
|
-
end.tap_yaml '@menu'
|
156
|
-
@lambdas = lambdas
|
157
|
-
@version = version || '0.1'
|
158
|
-
# @options = {}
|
159
|
-
@options = if options.instance_of?(::String)
|
160
|
-
YAML.safe_load(File.read(options)).sym_keys.tap_yaml '@options'
|
161
|
-
else
|
162
|
-
{}
|
163
|
-
end #.tap_yaml '@options'
|
164
|
-
|
165
|
-
parse!
|
166
|
-
end
|
167
|
-
|
168
|
-
def parse!
|
169
|
-
@options, @remainder = menu_all(
|
170
|
-
@menu,
|
171
|
-
# @menu.map do |menu_item|
|
172
|
-
# menu_item.tap_inspect 'menu_item'
|
173
|
-
# mion = menu_item[:opt_name]&.to_sym.tap_inspect 'mion'
|
174
|
-
# omion = @options[mion].tap_inspect 'omion'
|
175
|
-
# unless omion.nil?
|
176
|
-
# @options[menu_item[:default]] = omion
|
177
|
-
# end
|
178
|
-
# menu_item
|
179
|
-
# end,
|
180
|
-
{
|
181
|
-
debug: ->(value) { tap_config value: value },
|
182
|
-
|
183
|
-
# stdout_configuration: lambda { |_| self.options.tap_puts 'eop' },
|
184
|
-
# stdout_configuration: (lambda { |options|
|
185
|
-
# lambda { |v| options.tap_puts 'eop_l' }
|
186
|
-
# }).call(@options),
|
187
|
-
|
188
|
-
stdout_defaults: lambda { |_|
|
189
|
-
menu_default_option_values(@menu).to_yaml.tap_puts
|
190
|
-
},
|
191
|
-
stdout_help: lambda { |_|
|
192
|
-
menu_help(@menu).tap_puts
|
193
|
-
exit
|
194
|
-
},
|
195
|
-
val_as_bool: lambda { |value|
|
196
|
-
value.instance_of?(::String) ? (value.chomp != '0') : value
|
197
|
-
},
|
198
|
-
val_as_int: ->(value) { value.to_i },
|
199
|
-
val_as_str: ->(value) { value.to_s },
|
200
|
-
version: lambda { |_|
|
201
|
-
@version.tap_puts
|
202
|
-
exit
|
203
|
-
}
|
204
|
-
}.merge(@lambdas || {}),
|
205
|
-
@options
|
206
|
-
)
|
207
|
-
@options #.tap_yaml '@options'
|
208
|
-
end
|
209
|
-
end
|