markdown_exec 2.1.0 → 2.3.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.
- checksums.yaml +4 -4
- data/.rubocop.yml +5 -1
- data/CHANGELOG.md +23 -1
- data/Gemfile +3 -3
- data/Gemfile.lock +134 -92
- data/README.md +13 -13
- data/bin/tab_completion.sh +14 -3
- data/bin/tab_completion.sh.erb +0 -1
- data/examples/bash-blocks.md +58 -0
- data/examples/block-names.md +62 -0
- data/examples/indent.md +43 -2
- data/examples/link-blocks-block.md +5 -0
- data/examples/link-blocks-load-save.md +59 -0
- data/examples/link-blocks-vars.md +56 -0
- data/examples/linked.md +6 -101
- data/examples/opts-blocks-require.md +28 -0
- data/examples/{port.md → port-blocks.md} +18 -9
- data/examples/save.md +76 -4
- data/examples/vars-blocks.md +38 -0
- data/lib/colorize.rb +13 -0
- data/lib/constants.rb +1 -1
- data/lib/fcb.rb +202 -16
- data/lib/filter.rb +12 -12
- data/lib/hash_delegator.rb +695 -326
- data/lib/hierarchy_string.rb +133 -0
- data/lib/input_sequencer.rb +4 -2
- data/lib/link_history.rb +34 -1
- data/lib/markdown_exec/version.rb +1 -1
- data/lib/markdown_exec.rb +67 -79
- data/lib/mdoc.rb +122 -60
- data/lib/menu.src.yml +71 -21
- data/lib/menu.yml +59 -19
- data/lib/namer.rb +50 -0
- data/lib/poly.rb +152 -0
- data/lib/saved_assets.rb +4 -11
- data/lib/string_util.rb +0 -1
- data/lib/text_analyzer.rb +100 -0
- metadata +16 -6
- data/examples/vars.md +0 -20
- /data/examples/{opts.md → opts-blocks.md} +0 -0
- /data/examples/{pass-through.md → pass-through-arguments.md} +0 -0
data/lib/menu.yml
CHANGED
@@ -236,8 +236,10 @@
|
|
236
236
|
:default: false
|
237
237
|
:description: Execute script in own window
|
238
238
|
:env_var: MDE_EXECUTE_IN_OWN_WINDOW
|
239
|
+
:long_name: execute_in_own_window
|
239
240
|
:opt_name: execute_in_own_window
|
240
241
|
:procname: val_as_bool
|
242
|
+
:short_name: w
|
241
243
|
- :default: fg_rgbh_7f_ff_00
|
242
244
|
:description: execution_report_preview_frame_color
|
243
245
|
:env_var: MDE_EXECUTION_REPORT_PREVIEW_FRAME_COLOR
|
@@ -259,12 +261,12 @@
|
|
259
261
|
:long_name: exit
|
260
262
|
:procname: exit
|
261
263
|
:short_name: x
|
262
|
-
- :default: "^(?<indent> *)`{3,}"
|
264
|
+
- :default: "^(?<indent>[ \t]*)`{3,}"
|
263
265
|
:description: Matches the start and end of a fenced code block
|
264
266
|
:env_var: MDE_FENCED_START_AND_END_REGEX
|
265
267
|
:opt_name: fenced_start_and_end_regex
|
266
268
|
:procname: val_as_str
|
267
|
-
- :default: "^(?<indent> *)`{3,}(?<shell>[^`\\s]*) *(:(?<name>[^\\s]*))? *(?<rest>.*)
|
269
|
+
- :default: "^(?<indent>[ \t]*)`{3,}(?<shell>[^`\\s]*) *(:(?<name>[^\\s]*))? *(?<rest>.*)
|
268
270
|
*$"
|
269
271
|
:description: Match the start of a fenced block
|
270
272
|
:env_var: MDE_FENCED_START_EXTENDED_REGEX
|
@@ -325,7 +327,7 @@
|
|
325
327
|
:procname: val_as_str
|
326
328
|
- :arg_name: HOW
|
327
329
|
:default: ''
|
328
|
-
:description: Find in YAML configuration options
|
330
|
+
:description: Find keyword in YAML configuration options
|
329
331
|
:long_name: how
|
330
332
|
:procname: how
|
331
333
|
:short_name: "?"
|
@@ -337,6 +339,35 @@
|
|
337
339
|
:env_var: MDE_IMPORT_PATTERN
|
338
340
|
:opt_name: import_pattern
|
339
341
|
:procname: val_as_str
|
342
|
+
- :default:
|
343
|
+
- :color_method: :bold_underline
|
344
|
+
:pattern: "\\*\\*_([^_]{0,64})_\\*\\*"
|
345
|
+
- :color_method: :bold_italic
|
346
|
+
:pattern: "\\*\\*~([^~]{0,64})~\\*\\*"
|
347
|
+
- :color_method: :bold
|
348
|
+
:pattern: "\\*\\*([^*]{0,64})\\*\\*"
|
349
|
+
- :color_method: :bold
|
350
|
+
:pattern: __([^_]{0,64})__
|
351
|
+
- :color_method: :underline
|
352
|
+
:pattern: "\\*([^*]{0,64})\\*"
|
353
|
+
- :color_method: :underline_italic
|
354
|
+
:pattern: _~([^_]{0,64})~_
|
355
|
+
- :color_method: strikethrough
|
356
|
+
:pattern: "~~([^~]{0,64})~~"
|
357
|
+
:description: Line-oriented text decoration (Main)
|
358
|
+
:env_var: MDE_LINE_DECOR_MAIN
|
359
|
+
:opt_name: line_decor_main
|
360
|
+
:procname: val_as_str
|
361
|
+
- :default: []
|
362
|
+
:description: Line-oriented text decoration (Post)
|
363
|
+
:env_var: MDE_LINE_DECOR_POST
|
364
|
+
:opt_name: line_decor_post
|
365
|
+
:procname: val_as_str
|
366
|
+
- :default: []
|
367
|
+
:description: Line-oriented text decoration (Pre)
|
368
|
+
:env_var: MDE_LINE_DECOR_PRE
|
369
|
+
:opt_name: line_decor_pre
|
370
|
+
:procname: val_as_str
|
340
371
|
- :description: List blocks
|
341
372
|
:long_name: list-blocks
|
342
373
|
:opt_name: list_blocks
|
@@ -373,6 +404,7 @@
|
|
373
404
|
:long_name: load-code
|
374
405
|
:opt_name: load_code
|
375
406
|
:procname: val_as_str
|
407
|
+
:short_name: l
|
376
408
|
- :arg_name: PREFIX
|
377
409
|
:default: mde
|
378
410
|
:description: Name prefix for stdout files
|
@@ -431,7 +463,7 @@
|
|
431
463
|
:env_var: MDE_MENU_DIVIDER_FORMAT
|
432
464
|
:opt_name: menu_divider_format
|
433
465
|
:procname: val_as_str
|
434
|
-
- :default: "
|
466
|
+
- :default: "^(?<indent>[ \t]*):::(?<line>(?<text>.*?)(?<trailing>[ \t]*))?$"
|
435
467
|
:description: Pattern for topics/dividers in block selection menu
|
436
468
|
:env_var: MDE_MENU_DIVIDER_MATCH
|
437
469
|
:opt_name: menu_divider_match
|
@@ -548,7 +580,7 @@
|
|
548
580
|
:env_var: MDE_MENU_NOTE_FORMAT
|
549
581
|
:opt_name: menu_note_format
|
550
582
|
:procname: val_as_str
|
551
|
-
- :default: "^(?<line>(
|
583
|
+
- :default: "^(?<line>(?![ \t]*/)(?<text>.*?)(?<trailing>[ \t]*))?$"
|
552
584
|
:description: Pattern for notes in block selection menu
|
553
585
|
:env_var: MDE_MENU_NOTE_MATCH
|
554
586
|
:opt_name: menu_note_match
|
@@ -820,12 +852,17 @@
|
|
820
852
|
:opt_name: prompt_exit
|
821
853
|
:procname: val_as_str
|
822
854
|
- :default: Back
|
823
|
-
:description:
|
824
|
-
:env_var:
|
855
|
+
:description: User wants out of menu
|
856
|
+
:env_var: MDE_PROMPT_FILESPEC_BACK
|
825
857
|
:opt_name: prompt_filespec_back
|
826
858
|
:procname: val_as_str
|
859
|
+
- :default: Facet
|
860
|
+
:description: User wants to tailor the menu
|
861
|
+
:env_var: MDE_PROMPT_FILESPEC_FACET
|
862
|
+
:opt_name: prompt_filespec_facet
|
863
|
+
:procname: val_as_str
|
827
864
|
- :default: Other
|
828
|
-
:description:
|
865
|
+
:description: User wants a custom file name
|
829
866
|
:env_var: MDE_PROMPT_FILESPEC_OTHER
|
830
867
|
:opt_name: prompt_filespec_other
|
831
868
|
:procname: val_as_str
|
@@ -894,7 +931,7 @@
|
|
894
931
|
:env_var: MDE_PROMPT_YES
|
895
932
|
:opt_name: prompt_yes
|
896
933
|
:procname: val_as_str
|
897
|
-
- :description:
|
934
|
+
- :description: Print the gem's home directory
|
898
935
|
:long_name: pwd
|
899
936
|
:opt_name: pwd
|
900
937
|
:procname: val_as_bool
|
@@ -909,12 +946,12 @@
|
|
909
946
|
:opt_name: runtime_exception_error_level
|
910
947
|
:procname: val_as_int
|
911
948
|
- :default: "%{prefix}%{join}%{time}%{join}%{filename}%{join}%{mark}%{join}%{blockname}%{join}%{exts}"
|
912
|
-
:description:
|
949
|
+
:description: Format for script and log file names
|
913
950
|
:env_var: MDE_SAVED_ASSET_FORMAT
|
914
951
|
:opt_name: saved_asset_format
|
915
952
|
:procname: val_as_str
|
916
953
|
- :default: "^(?<prefix>.+)(?<join>_)(?<time>[0-9\\-]+)\\g'join'(?<filename>.+)\\g'join'(?<mark>~)\\g'join'(?<blockname>.+)\\g'join'(?<exts>\\..+)$"
|
917
|
-
:description:
|
954
|
+
:description: Regexp for script and log file names
|
918
955
|
:env_var: MDE_SAVED_ASSET_MATCH
|
919
956
|
:opt_name: saved_asset_match
|
920
957
|
:procname: val_as_str
|
@@ -940,6 +977,11 @@
|
|
940
977
|
:env_var: MDE_SAVED_FILENAME_REPLACEMENT
|
941
978
|
:opt_name: saved_filename_replacement
|
942
979
|
:procname: val_as_str
|
980
|
+
- :default: "%{time} %{blockname} %{exts}"
|
981
|
+
:description: Format for each row displayed in history
|
982
|
+
:env_var: MDE_SAVED_HISTORY_FORMAT
|
983
|
+
:opt_name: saved_history_format
|
984
|
+
:procname: val_as_str
|
943
985
|
- :arg_name: INT
|
944
986
|
:default: 493
|
945
987
|
:description: chmod for saved scripts
|
@@ -1027,14 +1069,6 @@
|
|
1027
1069
|
:env_var: MDE_SELECT_PAGE_HEIGHT
|
1028
1070
|
:opt_name: select_page_height
|
1029
1071
|
:procname: val_as_int
|
1030
|
-
- :description: Select and execute a recently saved output
|
1031
|
-
:long_name: select-recent-output
|
1032
|
-
:opt_name: select_recent_output
|
1033
|
-
:procname: val_as_bool
|
1034
|
-
- :description: Select and execute a recently saved script
|
1035
|
-
:long_name: select-recent-script
|
1036
|
-
:opt_name: select_recent_script
|
1037
|
-
:procname: val_as_bool
|
1038
1072
|
- :default: "#!/usr/bin/env"
|
1039
1073
|
:description: Shebang for saved scripts
|
1040
1074
|
:env_var: MDE_SHEBANG
|
@@ -1061,6 +1095,12 @@
|
|
1061
1095
|
:env_var: MDE_SHELL_CODE_LABEL_TIME_FORMAT
|
1062
1096
|
:opt_name: shell_code_label_time_format
|
1063
1097
|
:procname: val_as_str
|
1098
|
+
- :arg_name: BOOL
|
1099
|
+
:default: true
|
1100
|
+
:description: Whether saved file names include shell parameter expansion
|
1101
|
+
:env_var: MDE_SHELL_PARAMETER_EXPANSION
|
1102
|
+
:opt_name: shell_parameter_expansion
|
1103
|
+
:procname: val_as_bool
|
1064
1104
|
- :description: List tab completions
|
1065
1105
|
:long_name: tab-completions
|
1066
1106
|
:opt_name: tab_completions
|
data/lib/namer.rb
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
# encoding=utf-8
|
5
|
+
require 'digest'
|
6
|
+
# require_relative 'poly'
|
7
|
+
|
8
|
+
$pd = false unless defined?($pd)
|
9
|
+
|
10
|
+
class Hash
|
11
|
+
# block name in commands and documents
|
12
|
+
def pub_name(**kwargs)
|
13
|
+
full = fetch(:nickname, nil) || fetch(:oname, nil)
|
14
|
+
full&.to_s&.pub_name(**kwargs).tap { |ret| pp [__LINE__, 'Hash.pub_name() ->', ret] if $pd }
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
class String
|
19
|
+
FN_ID_LEN = 4
|
20
|
+
FN_MAX_LEN = 64
|
21
|
+
FN_PATTERN = %r{[^!#%\+\-0-9=@A-Z_a-z()\[\]{}]}.freeze # characters than can be used in a file name without quotes or escaping
|
22
|
+
# except '.', ',', '~' reserved for tokenization
|
23
|
+
# / !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~
|
24
|
+
FN_REPLACEMENT = '_'
|
25
|
+
|
26
|
+
# block name in commands and documents
|
27
|
+
def pub_name(
|
28
|
+
id_len: FN_ID_LEN, max_len: FN_MAX_LEN,
|
29
|
+
pattern: FN_PATTERN, replacement: FN_REPLACEMENT
|
30
|
+
)
|
31
|
+
trimmed = if self[max_len]
|
32
|
+
rand(((10**(id_len - 1)) + 1)..(10**id_len)).to_s
|
33
|
+
dig = Digest::MD5.hexdigest(self)[0, id_len]
|
34
|
+
self[0..max_len - id_len] + dig
|
35
|
+
else
|
36
|
+
self
|
37
|
+
end
|
38
|
+
|
39
|
+
trimmed.gsub(pattern, replacement).tap { |ret| pp [__LINE__, 'String.pub_name() ->', ret] if $pd }
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
# require 'ostruct'
|
44
|
+
|
45
|
+
# class BlkS < OpenStruct
|
46
|
+
# # Method to fetch the value associated with the attribute :nickname or :oname
|
47
|
+
# def pub_name
|
48
|
+
# self.nickname || self.oname
|
49
|
+
# end
|
50
|
+
# end
|
data/lib/poly.rb
ADDED
@@ -0,0 +1,152 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
# encoding=utf-8
|
5
|
+
|
6
|
+
$pd = false
|
7
|
+
|
8
|
+
class Poly
|
9
|
+
# attr_reader :table
|
10
|
+
def initialize(table = {})
|
11
|
+
@table = table.tap{|ret| pp [__LINE__,'Poly.initialize()','table',table.to_yaml] if $pd }
|
12
|
+
end
|
13
|
+
|
14
|
+
def fetch(key, *args)
|
15
|
+
key_sym = key.to_sym
|
16
|
+
if respond_to?("get_#{key}")
|
17
|
+
send("get_#{key}")
|
18
|
+
elsif @table.key?(key_sym)
|
19
|
+
@table[key_sym]
|
20
|
+
elsif block_given?
|
21
|
+
yield key_sym
|
22
|
+
elsif args.count.positive?
|
23
|
+
# binding.irb
|
24
|
+
args.first
|
25
|
+
else
|
26
|
+
binding.irb
|
27
|
+
raise KeyError, "key not found: #{key}"
|
28
|
+
end.tap{|ret| pp([__LINE__,"Poly.fetch #{key} #{args}",'->',ret]) if $pd }
|
29
|
+
end
|
30
|
+
|
31
|
+
def key?(name)
|
32
|
+
@table.key?(name.to_sym).tap{|ret| pp([__LINE__,"Poly.key? #{name}",'->',ret]) if $pd }
|
33
|
+
end
|
34
|
+
|
35
|
+
def method_missing(name, *args)
|
36
|
+
pt = nil
|
37
|
+
if name.to_s.end_with?('=')
|
38
|
+
# Setter method
|
39
|
+
attribute = name.to_s.chomp('=').to_sym
|
40
|
+
value = args.first
|
41
|
+
if respond_to?("set_#{attribute}")
|
42
|
+
pt = 'send set_'
|
43
|
+
send("set_#{attribute}", value)
|
44
|
+
else
|
45
|
+
pt = 'table set'
|
46
|
+
@table[attribute] = value
|
47
|
+
end
|
48
|
+
elsif respond_to?("get_#{name}")
|
49
|
+
pt = 'send get_'
|
50
|
+
# Getter method
|
51
|
+
send("get_#{name}")
|
52
|
+
elsif @table.respond_to?(name)
|
53
|
+
pt = 'send name'
|
54
|
+
@table.send(name, *args)
|
55
|
+
else
|
56
|
+
pt = 'table read'
|
57
|
+
@table[name.to_sym]
|
58
|
+
end.tap{|ret| pp([__LINE__,"Poly.method_missing #{name} #{args.map(&:to_s).join(' ')}",pt,'->',ret]) if $pd }
|
59
|
+
end
|
60
|
+
|
61
|
+
def respond_to_missing?(name, include_private = false)
|
62
|
+
# name.to_s.end_with?('=') || @table.key?(name.to_sym) || @table.respond_to?(name) || super
|
63
|
+
(name.to_s.end_with?('=') || @table.key?(name.to_sym) || @table.respond_to?(name) || super).tap{|ret| pp([__LINE__,"Poly.respond_to_missing? #{name}",'->',ret]) if $pd }
|
64
|
+
end
|
65
|
+
|
66
|
+
def [](key)
|
67
|
+
if respond_to?("get_#{key}")
|
68
|
+
send("get_#{key}")
|
69
|
+
else
|
70
|
+
@table[key.to_sym]
|
71
|
+
end.tap{|ret| pp([__LINE__,"Poly.[] #{key}",'->',ret]) if $pd }
|
72
|
+
end
|
73
|
+
|
74
|
+
def []=(key, value)
|
75
|
+
if respond_to?("set_#{key}")
|
76
|
+
send("set_#{key}", value)
|
77
|
+
else
|
78
|
+
@table[key.to_sym] = value
|
79
|
+
end.tap{|ret| pp([__LINE__,"Poly.[]= #{key} #{value}",'->',ret]) if $pd }
|
80
|
+
end
|
81
|
+
|
82
|
+
# for export to Prompt library
|
83
|
+
# def merge(*args)
|
84
|
+
# Proc.new { |x| @table.merge x }
|
85
|
+
# end
|
86
|
+
def merge(*args)
|
87
|
+
# pp caller
|
88
|
+
# binding.irb
|
89
|
+
@table.merge(*args).tap{|ret| pp([__LINE__,"Poly.merge",'->',ret]) if $pd }
|
90
|
+
end
|
91
|
+
|
92
|
+
# for export to Prompt library
|
93
|
+
def to_h
|
94
|
+
@table.tap{|ret| pp([__LINE__,"Poly.to_h",'->',ret]) if $pd }
|
95
|
+
end
|
96
|
+
|
97
|
+
def to_yaml
|
98
|
+
@table.to_yaml.tap{|ret| pp([__LINE__,"Poly.to_yaml",'->',ret]) if $pd }
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
# class CustomStruct < Poly
|
103
|
+
# # Custom setter for virtual attribute :full_name
|
104
|
+
# def set_full_name(value)
|
105
|
+
# names = value.split(' ')
|
106
|
+
# @table[:first_name] = names.first
|
107
|
+
# @table[:last_name] = names.last
|
108
|
+
# end
|
109
|
+
|
110
|
+
# # Custom getter for virtual attribute :full_name
|
111
|
+
# def get_full_name
|
112
|
+
# "#{@table[:first_name]} #{@table[:last_name]}"
|
113
|
+
# end
|
114
|
+
# end
|
115
|
+
|
116
|
+
# # Example usage
|
117
|
+
# person = CustomStruct.new
|
118
|
+
# person.first_name = 'John'
|
119
|
+
# person.last_name = 'Doe'
|
120
|
+
# puts person.first_name # => John
|
121
|
+
# puts person.last_name # => Doe
|
122
|
+
|
123
|
+
# # Setting and getting a virtual attribute
|
124
|
+
# person.full_name = 'Jane Smith'
|
125
|
+
# puts person.first_name # => Jane
|
126
|
+
# puts person.last_name # => Smith
|
127
|
+
# puts person.full_name # => Jane Smith
|
128
|
+
|
129
|
+
# # Setting and getting a regular attribute
|
130
|
+
# person.age = 30
|
131
|
+
# puts person.age # => 30
|
132
|
+
|
133
|
+
# # Using array notation
|
134
|
+
# person[:age] = 35
|
135
|
+
# puts person[:age] # => 35
|
136
|
+
|
137
|
+
# person[:full_name] = 'Alice Johnson'
|
138
|
+
# puts person[:first_name] # => Alice
|
139
|
+
# puts person[:last_name] # => Johnson
|
140
|
+
# puts person[:full_name] # => Alice Johnson
|
141
|
+
|
142
|
+
# # Using fetch method
|
143
|
+
# puts person.fetch(:age) # => 35
|
144
|
+
# puts person.fetch(:nonexistent, 'default') # => default
|
145
|
+
# puts person.fetch(:nonexistent) { |key| "block default for #{key}" } # => block default for nonexistent
|
146
|
+
|
147
|
+
# # This will raise a KeyError
|
148
|
+
# begin
|
149
|
+
# person.fetch(:nonexistent)
|
150
|
+
# rescue KeyError => e
|
151
|
+
# puts e.message # => key not found: nonexistent
|
152
|
+
# end
|
data/lib/saved_assets.rb
CHANGED
@@ -2,6 +2,7 @@
|
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
4
|
# encoding=utf-8
|
5
|
+
require_relative 'namer'
|
5
6
|
|
6
7
|
module MarkdownExec
|
7
8
|
# SavedAsset
|
@@ -12,10 +13,6 @@ module MarkdownExec
|
|
12
13
|
# method derives a name for stdout redirection.
|
13
14
|
#
|
14
15
|
class SavedAsset
|
15
|
-
FNR11 = %r{[^!#%\+\-0-9=@A-Z_a-z]}.freeze # characters than can be used in a file name without quotes or escaping
|
16
|
-
# except '.', ',', '~' reserved for tokenization
|
17
|
-
# / !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~
|
18
|
-
FNR12 = '_'
|
19
16
|
DEFAULT_FTIME = '%F-%H-%M-%S'
|
20
17
|
FILE_BLOCK_SEP = ','
|
21
18
|
JOIN_STR = '_'
|
@@ -26,21 +23,17 @@ module MarkdownExec
|
|
26
23
|
# @param time [Time] the time object for formatting
|
27
24
|
# @param blockname [String] the block name to include
|
28
25
|
# @param ftime [String] the time format (default: DEFAULT_FTIME)
|
29
|
-
# @param pattern [Regexp] the pattern to search (default: FNR11)
|
30
|
-
# @param replace [String] the string to replace the pattern (default: FNR12)
|
31
26
|
# @param exts [String] the extension to append (default: '.sh')
|
32
27
|
def initialize(
|
33
28
|
saved_asset_format:, filename: nil, prefix: nil, time: nil, blockname: nil,
|
34
|
-
ftime: DEFAULT_FTIME,
|
29
|
+
ftime: DEFAULT_FTIME, exts: nil,
|
35
30
|
mark: nil, join_str: nil
|
36
31
|
)
|
37
|
-
@filename = filename ? filename.
|
32
|
+
@filename = filename ? filename.pub_name : '*' # [String] the name of the file
|
38
33
|
@prefix = prefix || '*' # [String] the prefix to use
|
39
34
|
@time = time ? time.strftime(ftime) : '*' # [Time] the time object for formatting
|
40
|
-
@blockname = blockname ? blockname.
|
35
|
+
@blockname = blockname ? blockname.pub_name : '*' # [String] the block name to include
|
41
36
|
# @ftime = ftime # [String] the time format (default: DEFAULT_FTIME)
|
42
|
-
# @pattern = pattern # [Regexp] the pattern to search (default: FNR11)
|
43
|
-
# @replace = replace # [String] the string to replace the pattern (default: FNR12)
|
44
37
|
@exts = exts || '.*' # [String] the extension to append (default: '.sh')
|
45
38
|
@mark = mark || MARK_STR
|
46
39
|
@join_str = join_str || JOIN_STR
|
data/lib/string_util.rb
CHANGED
@@ -0,0 +1,100 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module TextAnalyzer
|
4
|
+
# Analyzes a hierarchical structure (String or Array) and highlights segments based on the pattern
|
5
|
+
#
|
6
|
+
# @param hierarchy [String, Array] the hierarchical structure to be analyzed
|
7
|
+
# @param pattern [Regexp] the pattern to match against the text
|
8
|
+
# @param default_color [String] the color for non-matching segments
|
9
|
+
# @param match_color [String] the color for matching segments
|
10
|
+
#
|
11
|
+
# @return [Array<Hash>, Array<Array<Hash>>] an array or nested arrays of highlighted segments
|
12
|
+
#
|
13
|
+
# @raise [ArgumentError] if the hierarchy structure is neither a String nor an Array
|
14
|
+
def self.analyze_hierarchy(hierarchy, pattern, default_color, match_color)
|
15
|
+
case hierarchy
|
16
|
+
when String
|
17
|
+
highlight_segments(hierarchy, pattern, default_color, match_color)
|
18
|
+
when Hash
|
19
|
+
decorated = highlight_segments(hierarchy[:text], pattern,
|
20
|
+
hierarchy[:color], match_color)
|
21
|
+
|
22
|
+
case decorated
|
23
|
+
when String
|
24
|
+
hierarchy
|
25
|
+
when Array
|
26
|
+
if decorated.length == 1
|
27
|
+
hierarchy
|
28
|
+
else
|
29
|
+
decorated
|
30
|
+
end
|
31
|
+
else
|
32
|
+
decorated
|
33
|
+
end
|
34
|
+
when Array
|
35
|
+
hierarchy.map do |element|
|
36
|
+
analyze_hierarchy(element, pattern, default_color, match_color)
|
37
|
+
end
|
38
|
+
when HierarchyString
|
39
|
+
|
40
|
+
hierarchy.replace_text! do |substring|
|
41
|
+
substring ### no change
|
42
|
+
end
|
43
|
+
|
44
|
+
else
|
45
|
+
binding.irb
|
46
|
+
raise ArgumentError, 'Invalid hierarchy structure'
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
# Highlights segments of the text based on the pattern
|
51
|
+
#
|
52
|
+
# @param text [String] the text to be analyzed
|
53
|
+
# @param pattern [Regexp] the pattern to match against the text
|
54
|
+
# @param default_color [String] the color for non-matching segments
|
55
|
+
# @param match_color [String] the color for matching segments
|
56
|
+
#
|
57
|
+
# @return [Array<Hash>] an array of hashes, each containing a segment of text and its corresponding color
|
58
|
+
def self.highlight_segments(text, pattern, default_color, match_color)
|
59
|
+
segments = []
|
60
|
+
|
61
|
+
yield_matches_and_non_matches(text, pattern) do |segment, is_match|
|
62
|
+
segments << if is_match
|
63
|
+
{ text: segment, color: match_color }
|
64
|
+
else
|
65
|
+
{ text: segment, color: default_color }
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
segments
|
70
|
+
end
|
71
|
+
|
72
|
+
# Yields matching and non-matching segments of the text based on the pattern
|
73
|
+
#
|
74
|
+
# @param text [String] the text to be analyzed
|
75
|
+
# @param pattern [Regexp] the pattern to match against the text
|
76
|
+
#
|
77
|
+
# @yieldparam segment [String] a segment of the text
|
78
|
+
# @yieldparam is_match [Boolean] true if the segment matches the pattern, false otherwise
|
79
|
+
def self.yield_matches_and_non_matches(text, pattern)
|
80
|
+
last_end = 0
|
81
|
+
|
82
|
+
text.scan(pattern) do |match|
|
83
|
+
match_start = Regexp.last_match.begin(0)
|
84
|
+
match_end = Regexp.last_match.end(0)
|
85
|
+
|
86
|
+
# Yield the non-matching segment before the match
|
87
|
+
yield text[last_end...match_start], false if match_start > last_end
|
88
|
+
|
89
|
+
# Yield the matching segment
|
90
|
+
yield match.first, true
|
91
|
+
|
92
|
+
last_end = match_end
|
93
|
+
end
|
94
|
+
|
95
|
+
# Yield any remaining non-matching segment after the last match
|
96
|
+
return unless last_end < text.length
|
97
|
+
|
98
|
+
yield text[last_end..-1], false
|
99
|
+
end
|
100
|
+
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: 2.
|
4
|
+
version: 2.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Fareed Stevenson
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-
|
11
|
+
date: 2024-08-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: clipboard
|
@@ -113,6 +113,8 @@ files:
|
|
113
113
|
- bin/setup
|
114
114
|
- bin/tab_completion.sh
|
115
115
|
- bin/tab_completion.sh.erb
|
116
|
+
- examples/bash-blocks.md
|
117
|
+
- examples/block-names.md
|
116
118
|
- examples/block_names.md
|
117
119
|
- examples/colors.md
|
118
120
|
- examples/data-files.md
|
@@ -125,6 +127,9 @@ files:
|
|
125
127
|
- examples/index.md
|
126
128
|
- examples/interrupt.md
|
127
129
|
- examples/line-wrapping.md
|
130
|
+
- examples/link-blocks-block.md
|
131
|
+
- examples/link-blocks-load-save.md
|
132
|
+
- examples/link-blocks-vars.md
|
128
133
|
- examples/linked.md
|
129
134
|
- examples/linked1.md
|
130
135
|
- examples/linked2.md
|
@@ -135,15 +140,16 @@ files:
|
|
135
140
|
- examples/load2.sh
|
136
141
|
- examples/load_code.md
|
137
142
|
- examples/nickname.md
|
138
|
-
- examples/opts.md
|
143
|
+
- examples/opts-blocks-require.md
|
144
|
+
- examples/opts-blocks.md
|
139
145
|
- examples/opts_output_execution.md
|
140
|
-
- examples/pass-through.md
|
146
|
+
- examples/pass-through-arguments.md
|
141
147
|
- examples/pause-after-execution.md
|
142
148
|
- examples/plant.md
|
143
|
-
- examples/port.md
|
149
|
+
- examples/port-blocks.md
|
144
150
|
- examples/save.md
|
145
151
|
- examples/search.md
|
146
|
-
- examples/vars.md
|
152
|
+
- examples/vars-blocks.md
|
147
153
|
- examples/wrap.md
|
148
154
|
- lib/ansi_formatter.rb
|
149
155
|
- lib/array.rb
|
@@ -165,6 +171,7 @@ files:
|
|
165
171
|
- lib/fout.rb
|
166
172
|
- lib/hash.rb
|
167
173
|
- lib/hash_delegator.rb
|
174
|
+
- lib/hierarchy_string.rb
|
168
175
|
- lib/input_sequencer.rb
|
169
176
|
- lib/instance_method_wrapper.rb
|
170
177
|
- lib/link_history.rb
|
@@ -173,8 +180,10 @@ files:
|
|
173
180
|
- lib/mdoc.rb
|
174
181
|
- lib/menu.src.yml
|
175
182
|
- lib/menu.yml
|
183
|
+
- lib/namer.rb
|
176
184
|
- lib/object_present.rb
|
177
185
|
- lib/option_value.rb
|
186
|
+
- lib/poly.rb
|
178
187
|
- lib/regexp.rb
|
179
188
|
- lib/resize_terminal.rb
|
180
189
|
- lib/rspec_helpers.rb
|
@@ -185,6 +194,7 @@ files:
|
|
185
194
|
- lib/streams_out.rb
|
186
195
|
- lib/string_util.rb
|
187
196
|
- lib/tap.rb
|
197
|
+
- lib/text_analyzer.rb
|
188
198
|
homepage: https://rubygems.org/gems/markdown_exec
|
189
199
|
licenses:
|
190
200
|
- MIT
|
data/examples/vars.md
DELETED
@@ -1,20 +0,0 @@
|
|
1
|
-
```bash :(defaults)
|
2
|
-
: ${VAULT:=default}
|
3
|
-
```
|
4
|
-
```bash :show_vars +(defaults)
|
5
|
-
source bin/colorize_env_vars.sh
|
6
|
-
colorize_env_vars '' VAULT
|
7
|
-
```
|
8
|
-
```vars :set
|
9
|
-
VAULT: 11
|
10
|
-
```
|
11
|
-
```vars :set_with_show +show_vars
|
12
|
-
VAULT: 22
|
13
|
-
```
|
14
|
-
```bash :(hidden)
|
15
|
-
colorize_env_vars '' NOTHING
|
16
|
-
```
|
17
|
-
```bash :show_with_set +set
|
18
|
-
source bin/colorize_env_vars.sh
|
19
|
-
colorize_env_vars '' VAULT
|
20
|
-
```
|
File without changes
|
File without changes
|