gm-notepad 0.0.10 → 0.0.11
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/README.md +8 -4
- data/Rakefile +1 -1
- data/exe/gm-notepad +18 -20
- data/gm-notepad.gemspec +3 -0
- data/lib/gm/notepad.rb +8 -6
- data/lib/gm/notepad/app.rb +45 -0
- data/lib/gm/notepad/buffer_wrapper.rb +47 -0
- data/lib/gm/notepad/config.rb +31 -0
- data/lib/gm/notepad/container.rb +50 -0
- data/lib/gm/notepad/exceptions.rb +1 -1
- data/lib/gm/notepad/input_handler_registry.rb +3 -3
- data/lib/gm/notepad/input_handlers/comment_handler.rb +6 -8
- data/lib/gm/notepad/input_handlers/default_handler.rb +12 -20
- data/lib/gm/notepad/input_handlers/help_handler.rb +4 -8
- data/lib/gm/notepad/input_handlers/query_table_handler.rb +16 -14
- data/lib/gm/notepad/input_handlers/query_table_names_handler.rb +12 -17
- data/lib/gm/notepad/input_handlers/write_line_handler.rb +4 -12
- data/lib/gm/notepad/input_handlers/write_to_table_handler.rb +9 -12
- data/lib/gm/notepad/input_processor.rb +10 -11
- data/lib/gm/notepad/line_evaluator.rb +16 -15
- data/lib/gm/notepad/line_renderer.rb +24 -62
- data/lib/gm/notepad/table.rb +17 -6
- data/lib/gm/notepad/table_column_set.rb +20 -7
- data/lib/gm/notepad/table_entry.rb +12 -4
- data/lib/gm/notepad/table_registry.rb +23 -16
- data/lib/gm/notepad/throughput_text.rb +80 -0
- data/lib/gm/notepad/version.rb +1 -1
- metadata +49 -5
- data/lib/gm/notepad/configuration.rb +0 -138
- data/lib/gm/notepad/defaults.rb +0 -6
- data/lib/gm/notepad/pad.rb +0 -36
@@ -6,17 +6,11 @@ module Gm
|
|
6
6
|
HELP_PREFIX = '?'.freeze
|
7
7
|
|
8
8
|
def self.handles?(input:)
|
9
|
-
return false unless input
|
9
|
+
return false unless input.match(/^\?/)
|
10
10
|
true
|
11
11
|
end
|
12
12
|
|
13
13
|
def after_initialize!
|
14
|
-
self.to_interactive = true
|
15
|
-
self.to_output = false
|
16
|
-
self.expand_line = false
|
17
|
-
end
|
18
|
-
|
19
|
-
def lines
|
20
14
|
[
|
21
15
|
"Prefixes:",
|
22
16
|
"\t? - Help (this command)",
|
@@ -28,7 +22,9 @@ module Gm
|
|
28
22
|
"\t/search/ - Grep for the given 'search' within the prefix",
|
29
23
|
"\t[index] - Target a specific 'index'",
|
30
24
|
"\t{table_name} - expand_line the given 'table_name'"
|
31
|
-
]
|
25
|
+
].each do |text|
|
26
|
+
input.for_rendering(text: text, to_interactive: true, to_output: false, expand_line: false)
|
27
|
+
end
|
32
28
|
end
|
33
29
|
end
|
34
30
|
end
|
@@ -9,46 +9,48 @@ module Gm
|
|
9
9
|
QUERY_TABLE_NAMES_PREFIX = '+'.freeze
|
10
10
|
def self.handles?(input:)
|
11
11
|
# Does not have the table prefix
|
12
|
-
return false unless input
|
12
|
+
return false unless input.match(/^\+/)
|
13
13
|
# It is only the table prefix
|
14
|
-
return false if input
|
14
|
+
return false if input.match(/^\+$/)
|
15
15
|
# It is querying all tables by way of grep
|
16
|
-
return false if input
|
16
|
+
return false if input.match(/^\+\//)
|
17
17
|
true
|
18
18
|
end
|
19
19
|
|
20
20
|
def after_initialize!
|
21
|
-
self.expand_line = false
|
22
|
-
self.to_output = false
|
23
|
-
self.to_interactive = true
|
24
|
-
|
25
21
|
line = input[1..-1].to_s
|
26
|
-
self.expand_line = false
|
27
22
|
@table_lookup_parameters = Parameters::TableLookup.new(text: line)
|
23
|
+
evaluate_lines!
|
28
24
|
end
|
29
25
|
|
30
26
|
extend Forwardable
|
31
27
|
def_delegators :@table_lookup_parameters, :index, :grep, :table_name
|
32
28
|
|
33
|
-
def
|
29
|
+
def evaluate_lines!
|
34
30
|
begin
|
35
31
|
table = table_registry.fetch_table(name: table_name)
|
36
32
|
rescue MissingTableError
|
37
33
|
message = "Unknown table #{table_name.inspect}. Did you mean: "
|
38
34
|
message += table_registry.table_names.grep(/\A#{table_name}/).map(&:inspect).join(", ")
|
39
|
-
|
35
|
+
input.for_rendering(text: message, to_output: false, to_interactive: true, expand_line: false)
|
36
|
+
return
|
40
37
|
end
|
41
38
|
if index
|
42
39
|
begin
|
43
|
-
|
40
|
+
text = table.lookup(index: index)
|
41
|
+
input.for_rendering(text: text, to_output: false, to_interactive: true, expand_line: false)
|
44
42
|
rescue MissingTableEntryError
|
45
|
-
|
43
|
+
input.for_rendering(text: %(Entry with index "#{index}" not found in "#{table_name}" table), to_interactive: true, to_output: false)
|
46
44
|
end
|
47
45
|
elsif grep
|
48
46
|
regexp = %r{#{grep}}i
|
49
|
-
table.grep(regexp)
|
47
|
+
table.grep(regexp).each do |text|
|
48
|
+
input.for_rendering(text: text, to_output: false, to_interactive: true, expand_line: false)
|
49
|
+
end
|
50
50
|
else
|
51
|
-
table.all
|
51
|
+
table.all.each do |text|
|
52
|
+
input.for_rendering(text: text, to_output: false, to_interactive: true, expand_line: false)
|
53
|
+
end
|
52
54
|
end
|
53
55
|
end
|
54
56
|
end
|
@@ -7,33 +7,28 @@ module Gm
|
|
7
7
|
QUERY_TABLE_NAMES_PREFIX = '+'.freeze
|
8
8
|
def self.handles?(input:)
|
9
9
|
# Does not have the table prefix
|
10
|
-
return false unless input
|
10
|
+
return false unless input.match(/^\+/)
|
11
11
|
# It is only the table prefix
|
12
|
-
return true if input
|
12
|
+
return true if input.match(/^\+$/)
|
13
13
|
# It is querying all tables by way of grep
|
14
|
-
return true if input
|
14
|
+
return true if input.match(/^\+\//)
|
15
15
|
false
|
16
16
|
end
|
17
17
|
|
18
18
|
WITH_GREP_REGEXP = %r{(?<declaration>\/(?<grep>[^\/]+)/)}
|
19
19
|
def after_initialize!
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
if match = WITH_GREP_REGEXP.match(line)
|
26
|
-
line = line.sub(match[:declaration], '')
|
27
|
-
self.grep = match[:grep]
|
20
|
+
grep = nil
|
21
|
+
input.sub!(/^./,'')
|
22
|
+
if match = input.match(WITH_GREP_REGEXP)
|
23
|
+
input.sub!(match[:declaration], '')
|
24
|
+
grep = match[:grep]
|
28
25
|
end
|
29
|
-
end
|
30
26
|
|
31
|
-
attr_accessor :grep
|
32
|
-
|
33
|
-
def lines
|
34
27
|
table_names = table_registry.table_names
|
35
|
-
|
36
|
-
table_names.
|
28
|
+
table_names = table_names.grep(%r{#{grep}}) if grep
|
29
|
+
table_names.each do |table_name|
|
30
|
+
input.render_current_text(text: table_name, to_interactive: true, to_output: false, expand_line: false)
|
31
|
+
end
|
37
32
|
end
|
38
33
|
end
|
39
34
|
end
|
@@ -9,22 +9,14 @@ module Gm
|
|
9
9
|
true
|
10
10
|
end
|
11
11
|
|
12
|
-
attr_accessor :line
|
13
12
|
def after_initialize!
|
14
|
-
self.expand_line = false
|
15
|
-
self.to_output = true
|
16
|
-
self.to_interactive = true
|
17
13
|
if input[0] == NON_EXPANDING_CHARATER
|
18
|
-
|
19
|
-
|
14
|
+
input.sub!(/^\!/,'')
|
15
|
+
expand_line = false
|
20
16
|
else
|
21
|
-
|
22
|
-
self.expand_line = true
|
17
|
+
expand_line = true
|
23
18
|
end
|
24
|
-
|
25
|
-
|
26
|
-
def lines
|
27
|
-
[line]
|
19
|
+
input.render_current_text(to_interactive: true, to_output: true, expand_line: expand_line)
|
28
20
|
end
|
29
21
|
end
|
30
22
|
end
|
@@ -6,7 +6,7 @@ module Gm
|
|
6
6
|
class WriteToTableHandler < DefaultHandler
|
7
7
|
HANDLED_PREFIX = "<".freeze
|
8
8
|
def self.handles?(input:)
|
9
|
-
return true if input
|
9
|
+
return true if input.match(/^\</)
|
10
10
|
end
|
11
11
|
|
12
12
|
attr_accessor :index, :grep, :table_name, :line
|
@@ -15,11 +15,8 @@ module Gm
|
|
15
15
|
WITH_GREP_REGEXP = %r{(?<declaration>\/(?<grep>[^\/]+)/)}
|
16
16
|
WITH_WRITE_TARGET_REGEXP = %r{\A#{HANDLED_PREFIX}(?<table_name>[^:]+):(?<line>.*)}
|
17
17
|
def after_initialize!
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
if match = WITH_WRITE_TARGET_REGEXP.match(input)
|
22
|
-
line = match[:line].strip
|
18
|
+
if match = input.match(WITH_WRITE_TARGET_REGEXP)
|
19
|
+
input.text_to_evaluate = match[:line].strip
|
23
20
|
table_name = match[:table_name]
|
24
21
|
if index_match = WITH_INDEX_REGEXP.match(table_name)
|
25
22
|
table_name = table_name.sub(index_match[:declaration], '')
|
@@ -32,13 +29,13 @@ module Gm
|
|
32
29
|
else
|
33
30
|
raise "I don't know what to do"
|
34
31
|
end
|
35
|
-
if
|
36
|
-
|
37
|
-
|
32
|
+
if input.match(/^\!/)
|
33
|
+
expand_line = false
|
34
|
+
input.sub!(/^\!/, '')
|
38
35
|
else
|
39
|
-
|
36
|
+
expand_line = true
|
40
37
|
end
|
41
|
-
|
38
|
+
input.render_current_text(to_interactive: true , to_output: false, to_filesystem: true, expand_line: expand_line)
|
42
39
|
end
|
43
40
|
|
44
41
|
def lines
|
@@ -48,7 +45,7 @@ module Gm
|
|
48
45
|
if expand_line
|
49
46
|
else
|
50
47
|
end
|
51
|
-
table_registry.append(table_name: table_name, line:
|
48
|
+
table_registry.append(table_name: table_name, line: input.text_to_evaluate, write: true)
|
52
49
|
[]
|
53
50
|
end
|
54
51
|
end
|
@@ -1,24 +1,23 @@
|
|
1
|
-
require 'gm/notepad/
|
1
|
+
require 'gm/notepad/container'
|
2
|
+
require 'dry/configurable'
|
2
3
|
module Gm
|
3
4
|
module Notepad
|
4
5
|
# Responsible for processing the given input into a renderable state
|
5
6
|
class InputProcessor
|
6
|
-
|
7
|
+
extend Dry::Initializer
|
8
|
+
option :table_registry, default: -> { Container.resolve(:table_registry) }
|
9
|
+
option :input_handler_registry, default: -> { Container.resolve(:input_handler_registry) }
|
7
10
|
|
8
|
-
def
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
end
|
11
|
+
def convert_to_output(input:)
|
12
|
+
input = ThroughputText.new(original_text: input, table_registry: table_registry)
|
13
|
+
build_for(input: input)
|
14
|
+
input
|
13
15
|
end
|
14
16
|
|
15
17
|
private
|
16
18
|
|
17
19
|
def build_for(input:)
|
18
|
-
input
|
19
|
-
handler = input_handler_registry.handler_for(input: input)
|
20
|
-
handler.table_registry = table_registry
|
21
|
-
handler
|
20
|
+
input_handler_registry.handler_for(input: input, table_registry: table_registry)
|
22
21
|
end
|
23
22
|
end
|
24
23
|
end
|
@@ -1,39 +1,40 @@
|
|
1
1
|
require 'dice'
|
2
|
+
require 'dry-initializer'
|
3
|
+
require 'gm/notepad/container'
|
2
4
|
require 'gm/notepad/parameters/table_lookup'
|
5
|
+
require 'gm/notepad/throughput_text'
|
3
6
|
require 'gm/notepad/evaluators/dice_evaluator'
|
4
7
|
module Gm
|
5
8
|
module Notepad
|
6
9
|
# Responsible for recording entries and then dumping them accordingly.
|
7
10
|
class LineEvaluator
|
8
|
-
|
9
|
-
|
10
|
-
end
|
11
|
-
attr_reader :table_registry
|
11
|
+
extend Dry::Initializer
|
12
|
+
option :table_registry, default: -> { Container.resolve(:table_registry) }, reader: :private
|
12
13
|
|
13
14
|
TABLE_NAME_REGEXP = %r{(?<table_name_container>\{(?<table_name>[^\{\}]+)\})}
|
14
15
|
def call(line:, expand_line: true)
|
15
|
-
|
16
|
-
|
17
|
-
|
16
|
+
input = ThroughputText.new(original_text: line, table_registry: table_registry)
|
17
|
+
return input unless expand_line
|
18
|
+
parse_table(input: input)
|
19
|
+
parse_dice(input: input)
|
20
|
+
input
|
18
21
|
end
|
19
22
|
|
20
23
|
private
|
21
24
|
|
22
|
-
def parse_table(
|
23
|
-
while match =
|
25
|
+
def parse_table(input:)
|
26
|
+
while match = input.match(TABLE_NAME_REGEXP)
|
24
27
|
table_lookup = Parameters::TableLookup.new(text: match[:table_name].strip, roll_dice: true)
|
25
28
|
entry = table_registry.lookup(**table_lookup.parameters)
|
26
|
-
|
29
|
+
input.sub!(match[:table_name_container], entry)
|
27
30
|
end
|
28
|
-
text
|
29
31
|
end
|
30
32
|
DICE_REGEXP = %r{(?<dice_container>\[(?<dice>[^\]]+)\])}
|
31
|
-
def parse_dice(
|
32
|
-
while match =
|
33
|
+
def parse_dice(input:)
|
34
|
+
while match = input.match(DICE_REGEXP)
|
33
35
|
evaluated_dice = Evaluators::DiceEvaluator.call(text: match[:dice], fallback: "(#{match[:dice]})")
|
34
|
-
|
36
|
+
input.sub!(match[:dice_container], evaluated_dice)
|
35
37
|
end
|
36
|
-
text
|
37
38
|
end
|
38
39
|
end
|
39
40
|
end
|
@@ -1,18 +1,32 @@
|
|
1
|
-
require 'gm/notepad/configuration'
|
2
1
|
require 'time'
|
3
|
-
require '
|
2
|
+
require 'dry-initializer'
|
3
|
+
require 'gm/notepad/container'
|
4
|
+
require 'gm/notepad/buffer_wrapper'
|
5
|
+
|
4
6
|
module Gm
|
5
7
|
module Notepad
|
6
8
|
# Responsible for rendering lines to the corresponding buffers
|
7
9
|
class LineRenderer
|
8
|
-
|
9
|
-
|
10
|
-
|
10
|
+
extend Dry::Initializer
|
11
|
+
option :with_timestamp, default: -> { Container[:config].with_timestamp }
|
12
|
+
option :interactive_buffer, type: -> (buffer, renderer) { BufferWrapper.for_interactive(buffer: buffer) }, default: -> { Container[:config].interactive_buffer }
|
13
|
+
option :output_buffer, type: -> (buffer, renderer) { BufferWrapper.for_output(buffer: buffer) }, default: -> { Container[:config].output_buffer }
|
14
|
+
|
15
|
+
def render(output:, as_of: Time.now)
|
16
|
+
output.evaluate!
|
17
|
+
output.lines_for_rendering.each do |line|
|
18
|
+
next unless line.to_interactive
|
19
|
+
render_interactive(line)
|
20
|
+
end
|
21
|
+
output.lines_for_rendering.each do |line|
|
22
|
+
next unless line.to_output
|
23
|
+
render_output(line, as_of: as_of)
|
24
|
+
end
|
11
25
|
end
|
12
26
|
|
13
27
|
def call(lines, to_output: false, to_interactive: true, as_of: Time.now)
|
14
28
|
render_interactive(lines) if to_interactive
|
15
|
-
render_output(lines,
|
29
|
+
render_output(lines, as_of: as_of) if to_output
|
16
30
|
end
|
17
31
|
|
18
32
|
def close!
|
@@ -22,32 +36,12 @@ module Gm
|
|
22
36
|
|
23
37
|
private
|
24
38
|
|
25
|
-
def
|
26
|
-
if config[:interactive_color]
|
27
|
-
@interactive_buffer = BufferWrapper.new(buffer, color: :faint, as: :interactive)
|
28
|
-
else
|
29
|
-
@interactive_buffer = BufferWrapper.new(buffer, as: :interactive)
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
def output_buffer=(buffer)
|
34
|
-
if config[:output_color]
|
35
|
-
@output_buffer = BufferWrapper.new(buffer, color: :bold, as: :output)
|
36
|
-
else
|
37
|
-
@output_buffer = BufferWrapper.new(buffer, as: :output)
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
|
-
def render_output(lines, defer_output:, as_of:)
|
39
|
+
def render_output(lines, as_of:)
|
42
40
|
each_expanded_line(lines: lines) do |line|
|
43
|
-
if
|
41
|
+
if with_timestamp
|
44
42
|
line = "#{as_of}\t#{line}"
|
45
43
|
end
|
46
|
-
|
47
|
-
output_buffer.defer(line)
|
48
|
-
else
|
49
|
-
output_buffer.puts(line)
|
50
|
-
end
|
44
|
+
output_buffer.puts(line)
|
51
45
|
end
|
52
46
|
end
|
53
47
|
|
@@ -60,44 +54,12 @@ module Gm
|
|
60
54
|
# Gracefully expand the \t and \n for the output buffer
|
61
55
|
def each_expanded_line(lines:)
|
62
56
|
Array(lines).each do |unexpanded_line|
|
63
|
-
unexpanded_line.
|
57
|
+
String(unexpanded_line).split('\\n').each do |line|
|
64
58
|
line = line.gsub('\\t', "\t")
|
65
59
|
yield(line)
|
66
60
|
end
|
67
61
|
end
|
68
62
|
end
|
69
63
|
end
|
70
|
-
|
71
|
-
# To provide a means for colorizing the output
|
72
|
-
class BufferWrapper
|
73
|
-
attr_reader :buffer, :color, :as
|
74
|
-
def initialize(buffer, color: false, as:)
|
75
|
-
@buffer = buffer
|
76
|
-
@buffer.extend(Term::ANSIColor)
|
77
|
-
@color = color
|
78
|
-
@as = as
|
79
|
-
@lines = []
|
80
|
-
end
|
81
|
-
|
82
|
-
def puts(text)
|
83
|
-
if color
|
84
|
-
buffer.puts("#{buffer.public_send(color)}#{text}#{buffer.reset}")
|
85
|
-
else
|
86
|
-
buffer.puts("#{text}")
|
87
|
-
end
|
88
|
-
end
|
89
|
-
|
90
|
-
def defer(line)
|
91
|
-
@lines << line
|
92
|
-
end
|
93
|
-
|
94
|
-
def close!
|
95
|
-
buffer.print("\n") if as == :interactive
|
96
|
-
@lines.each do |line|
|
97
|
-
puts(line)
|
98
|
-
end
|
99
|
-
end
|
100
|
-
end
|
101
|
-
private_constant :BufferWrapper
|
102
64
|
end
|
103
65
|
end
|
data/lib/gm/notepad/table.rb
CHANGED
@@ -1,13 +1,20 @@
|
|
1
|
+
require 'dry-initializer'
|
1
2
|
require "gm/notepad/exceptions"
|
2
|
-
require "gm/notepad/configuration"
|
3
3
|
require "gm/notepad/table_entry"
|
4
4
|
require "gm/notepad/table_column_set"
|
5
|
+
require 'gm/notepad/container'
|
5
6
|
|
6
7
|
module Gm
|
7
8
|
module Notepad
|
8
9
|
class Table
|
9
|
-
|
10
|
-
|
10
|
+
extend Dry::Initializer
|
11
|
+
option :table_name, proc(&:to_s)
|
12
|
+
option :filename, optional: true
|
13
|
+
option :lines, type: method(:Array)
|
14
|
+
option :index_entry_prefix_regexp, default: -> { Container.resolve(:config).index_entry_prefix_regexp }
|
15
|
+
|
16
|
+
def initialize(*args)
|
17
|
+
super
|
11
18
|
set_null_table_column_set!
|
12
19
|
process(lines: lines)
|
13
20
|
end
|
@@ -32,6 +39,10 @@ module Gm
|
|
32
39
|
@table_column_set.names
|
33
40
|
end
|
34
41
|
|
42
|
+
def column_index_for(cell:)
|
43
|
+
@table_column_set.column_index_for(cell: cell)
|
44
|
+
end
|
45
|
+
|
35
46
|
def grep(expression)
|
36
47
|
returning_value = []
|
37
48
|
@table.each_value do |entry|
|
@@ -65,7 +76,7 @@ module Gm
|
|
65
76
|
@table.values[random_index]
|
66
77
|
end
|
67
78
|
|
68
|
-
attr_accessor :filename
|
79
|
+
attr_accessor :filename
|
69
80
|
attr_reader :table_name
|
70
81
|
|
71
82
|
def table_name=(input)
|
@@ -98,11 +109,11 @@ module Gm
|
|
98
109
|
end
|
99
110
|
|
100
111
|
def register_index_declaration!(line:)
|
101
|
-
@table_column_set = TableColumnSet.new(table: self, line: line
|
112
|
+
@table_column_set = TableColumnSet.new(table: self, line: line)
|
102
113
|
end
|
103
114
|
|
104
115
|
def make_entry!(line:)
|
105
|
-
entry = TableEntry.new(table: self, line: line
|
116
|
+
entry = TableEntry.new(table: self, line: line)
|
106
117
|
entry.lookup_range.each do |i|
|
107
118
|
key = i.to_s
|
108
119
|
raise DuplicateKeyError.new(key: table_name, object: self) if @table.key?(key)
|