gm-notepad 0.0.6 → 0.0.8
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 +9 -3
- data/examples/basic_example_file +21 -3
- data/exe/gm-notepad +1 -1
- data/lib/gm/notepad/configuration.rb +1 -2
- data/lib/gm/notepad/evaluators/dice_evaluator.rb +16 -0
- data/lib/gm/notepad/exceptions.rb +3 -0
- data/lib/gm/notepad/line_evaluator.rb +4 -14
- data/lib/gm/notepad/pad.rb +1 -0
- data/lib/gm/notepad/parameters/table_lookup.rb +42 -12
- data/lib/gm/notepad/readline.rb +1 -1
- data/lib/gm/notepad/table.rb +21 -9
- data/lib/gm/notepad/table_entry.rb +22 -10
- data/lib/gm/notepad/table_registry.rb +4 -9
- data/lib/gm/notepad/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: da3bbc8cbf352187a313f8815110edef14d41c7c37e4f2dd1f3bb49e43200bcf
|
4
|
+
data.tar.gz: 12ffebdda56b6d2e3a4c43da401c884b8c1a659767ea618081792346530ca15c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fa277d748161cb37f2b1105d02d17cc551769f171953746bfd8aed13cd009c48fbb155a96c08a980f1c34ab66e6c6afa07cf42b804eac77cf5a5a79016533f4e
|
7
|
+
data.tar.gz: a0539f38a29bcce258255da060388f29cbeab6cd59505fbcb2af2f757f8094637d8b821f63e339f8002169ffe720b9346d5b10c5fd6a03ead9ad6ba759308116
|
data/README.md
CHANGED
@@ -177,6 +177,10 @@ Hello SamWise
|
|
177
177
|
The line with starting with `=>` is the `interactive` buffer. The other line
|
178
178
|
is written to the `output` buffer.
|
179
179
|
|
180
|
+
You can also roll within a table. In the `gm-notepad` type the following:
|
181
|
+
`{first-name[1d4]}`. The system will output "Frodo", "Merry", "Pippin", or "Sam".
|
182
|
+
You won't get a "SamWise" or "FrodoWise" (or "FrodoWiseWise").
|
183
|
+
|
180
184
|
To wrap up our first session, let's try one more thing. In your `gm-notepad`
|
181
185
|
session type the following: `{first-name} owes [2d6]gp to {first-name}`:
|
182
186
|
|
@@ -213,7 +217,7 @@ entry has a 1 in 3 chance of being randomly chosen.
|
|
213
217
|
- [X] Skip table lines that begin with `#`
|
214
218
|
- [X] Skip processing input lines that begin with `#`
|
215
219
|
- [X] Allow configuration to specify table delimiter
|
216
|
-
- [ ]
|
220
|
+
- [ ] Raise load error if table index is a "dice" expression
|
217
221
|
- [X] Allow configuration for where to dump data
|
218
222
|
- [ ] Normalize `WriteToTableHandler` to use a renderer
|
219
223
|
- [ ] Normalize `WriteToTableHandler` to deliver on `grep` and `index` behavior
|
@@ -221,7 +225,6 @@ entry has a 1 in 3 chance of being randomly chosen.
|
|
221
225
|
- [X] Gracefully handle `+name[]`, where "name" is a registered table
|
222
226
|
- [ ] Add time to live for line expansion (to prevent infinite loops); I suspect 100 to be reasonable
|
223
227
|
- [X] Enable "up" and "down" to scroll through history
|
224
|
-
- [ ] Add config that expands dice results while including the requested roll
|
225
228
|
- [X] Add index name when rendering table entries
|
226
229
|
- [ ] Gracefully handle loading a malformed data file (maybe?)
|
227
230
|
- [X] Add concept of history
|
@@ -229,7 +232,8 @@ entry has a 1 in 3 chance of being randomly chosen.
|
|
229
232
|
- [ ] Separate the InputHandler into pre-amble (e.g. allow overrides to where we are writing, determine what command we are writing)
|
230
233
|
- [X] Create a configuration object that captures the initial input (reduce passing around parameters and persisting copies of the config)
|
231
234
|
- [ ] Add concept of "journal entry"; its not a table (perhaps) but something that you could capture notes.
|
232
|
-
- [
|
235
|
+
- [X] Add column handling `{table[][]}`
|
236
|
+
- [ ] Gracefully handle cell lookup when named cell for entry is not found
|
233
237
|
- [X] Support `\{\{table}-name}` You should be able to do `\{\{culture}-name}` and first evaluate to `{arabic-name}` and then get a value from the `arabic-name` table
|
234
238
|
- [X] Ensure index names are lower-case
|
235
239
|
- [ ] Hit 100% spec coverage
|
@@ -245,3 +249,5 @@ entry has a 1 in 3 chance of being randomly chosen.
|
|
245
249
|
- [ ] Add auto index expansion for "["
|
246
250
|
- [ ] Determine feasibility of adding dice to the `{}` expansion syntax (instead of the `[]` syntax)
|
247
251
|
- [ ] Add force write results to `output`
|
252
|
+
- [ ] Add option to dump all tables to the given directory
|
253
|
+
- [ ] Add config that expands dice results while including the requested roll
|
data/examples/basic_example_file
CHANGED
@@ -1,14 +1,32 @@
|
|
1
1
|
# Write entry `1|entry one` to in memory table `basic_example`
|
2
|
-
|
2
|
+
<basic_example:1|entry one
|
3
|
+
|
3
4
|
# Should render to interactive the internal help
|
4
5
|
?
|
6
|
+
|
7
|
+
# Should roll the dice
|
8
|
+
[2d6] goblins attack
|
9
|
+
|
5
10
|
# Should render to interactive the given tables
|
6
11
|
+
|
12
|
+
|
7
13
|
# Should render to interactive the table `basic_example`
|
8
14
|
+basic_example
|
15
|
+
|
9
16
|
# Should render `entry one`
|
10
17
|
{basic_example}
|
18
|
+
|
11
19
|
# Should append entry `2|entry two` into memory table `basic_example`
|
12
20
|
<basic_example:2|entry two
|
13
|
-
|
14
|
-
|
21
|
+
|
22
|
+
# Should show that there are two entries in `basic example`
|
23
|
+
+basic_example
|
24
|
+
|
25
|
+
# Should lookup entry 1 and 2
|
26
|
+
{basic_example[1]} and {basic_example[2]}
|
27
|
+
|
28
|
+
# Should lookup entry 1 and 2
|
29
|
+
{basic_example[1d1]}
|
30
|
+
|
31
|
+
# Should lookup entry 1 and 2
|
32
|
+
{2d6} {basic_example[1d1]}
|
data/exe/gm-notepad
CHANGED
@@ -80,7 +80,7 @@ end
|
|
80
80
|
begin
|
81
81
|
@notepad = Gm::Notepad.new(**config)
|
82
82
|
if config.fetch(:skip_readlines)
|
83
|
-
input_getter =
|
83
|
+
input_getter = ARGF.method(:gets)
|
84
84
|
else
|
85
85
|
require 'gm/notepad/readline'
|
86
86
|
input_getter = Gm::Notepad::Readline.input_getter(**config)
|
@@ -14,11 +14,10 @@ module Gm
|
|
14
14
|
output_buffer: $stdout,
|
15
15
|
paths: ['.'],
|
16
16
|
column_delimiter: Gm::Notepad::DEFAULT_COLUMN_DELIMITER,
|
17
|
-
shell_prompt: Gm::Notepad::DEFAULT_SHELL_PROMPT,
|
18
17
|
skip_readlines: false,
|
19
18
|
table_extension: '.txt',
|
20
19
|
with_timestamp: false
|
21
|
-
}
|
20
|
+
}
|
22
21
|
|
23
22
|
# NOTE: ORDER MATTERS! I have a temporal dependency in these
|
24
23
|
# defaults
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'dice'
|
2
|
+
module Gm
|
3
|
+
module Notepad
|
4
|
+
module Evaluators
|
5
|
+
module DiceEvaluator
|
6
|
+
def self.call(text:, fallback: text)
|
7
|
+
if parsed_text = Dice.parse(text)
|
8
|
+
parsed_text.evaluate.to_s
|
9
|
+
else
|
10
|
+
fallback.to_s
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -9,13 +9,16 @@ module Gm
|
|
9
9
|
end
|
10
10
|
class MissingTableError < RuntimeError
|
11
11
|
def initialize(name:)
|
12
|
+
@name = name
|
12
13
|
super(%(Missing table "#{name}"))
|
13
14
|
end
|
15
|
+
alias to_buffer_message to_s
|
14
16
|
end
|
15
17
|
class MissingTableEntryError < RuntimeError
|
16
18
|
def initialize(table_name:, index:)
|
17
19
|
super(%(Missing index "#{index}" for table "#{table_name}"))
|
18
20
|
end
|
21
|
+
alias to_buffer_message to_s
|
19
22
|
end
|
20
23
|
end
|
21
24
|
end
|
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'dice'
|
2
2
|
require 'gm/notepad/parameters/table_lookup'
|
3
|
+
require 'gm/notepad/evaluators/dice_evaluator'
|
3
4
|
module Gm
|
4
5
|
module Notepad
|
5
6
|
# Responsible for recording entries and then dumping them accordingly.
|
@@ -20,15 +21,8 @@ module Gm
|
|
20
21
|
|
21
22
|
def parse_table(text:)
|
22
23
|
while match = text.match(TABLE_NAME_REGEXP)
|
23
|
-
table_lookup = Parameters::TableLookup.new(text: match[:table_name].strip)
|
24
|
-
|
25
|
-
if index = Dice.parse(table_lookup.index)
|
26
|
-
table_lookup.index = index.evaluate
|
27
|
-
end
|
28
|
-
entry = table_registry.lookup(index: table_lookup.index, table_name: table_lookup.table_name)
|
29
|
-
else
|
30
|
-
entry = table_registry.lookup(table_name: table_lookup.table_name)
|
31
|
-
end
|
24
|
+
table_lookup = Parameters::TableLookup.new(text: match[:table_name].strip, roll_dice: true)
|
25
|
+
entry = table_registry.lookup(**table_lookup.parameters)
|
32
26
|
text = text.sub(match[:table_name_container], entry)
|
33
27
|
end
|
34
28
|
text
|
@@ -36,11 +30,7 @@ module Gm
|
|
36
30
|
DICE_REGEXP = %r{(?<dice_container>\[(?<dice>[^\]]+)\])}
|
37
31
|
def parse_dice(text:)
|
38
32
|
while match = text.match(DICE_REGEXP)
|
39
|
-
|
40
|
-
evaluated_dice = "#{parsed_dice.evaluate}"
|
41
|
-
else
|
42
|
-
evaluated_dice = "(#{match[:dice]})"
|
43
|
-
end
|
33
|
+
evaluated_dice = Evaluators::DiceEvaluator.call(text: match[:dice], fallback: "(#{match[:dice]})")
|
44
34
|
text = text.sub(match[:dice_container], evaluated_dice)
|
45
35
|
end
|
46
36
|
text
|
data/lib/gm/notepad/pad.rb
CHANGED
@@ -1,43 +1,73 @@
|
|
1
|
+
require 'gm/notepad/evaluators/dice_evaluator'
|
1
2
|
module Gm
|
2
3
|
module Notepad
|
3
4
|
module Parameters
|
4
5
|
# Responsible for teasing apart the table logic
|
5
6
|
class TableLookup
|
6
|
-
|
7
|
-
WITH_INDEX_REGEXP = %r{(?<declaration>\[(?<index>[^\]]+)\])}
|
8
|
-
WITH_EMPTY_INDEX_REGEX = %r{(?<declaration>\[\])}
|
9
|
-
WITH_EMPTY_GREP_REGEX = %r{(?<declaration>\/\/)}
|
10
|
-
|
11
|
-
def initialize(text:)
|
7
|
+
def initialize(text:, roll_dice: false)
|
12
8
|
@text = text
|
9
|
+
@role_dice = false
|
10
|
+
@parameters = {}
|
13
11
|
extract_parameters!
|
12
|
+
roll_them_bones! if roll_dice
|
14
13
|
end
|
15
14
|
|
16
|
-
|
15
|
+
attr_reader :cell, :index, :grep, :table_name
|
17
16
|
|
18
17
|
def parameters
|
19
18
|
parameters = { table_name: table_name }
|
20
19
|
parameters[:grep] = grep if grep
|
21
20
|
parameters[:index] = index if index
|
21
|
+
parameters[:cell] = cell if cell
|
22
22
|
parameters
|
23
23
|
end
|
24
24
|
|
25
25
|
private
|
26
|
+
|
27
|
+
attr_writer :cell, :index, :grep, :table_name
|
28
|
+
|
29
|
+
def roll_them_bones!
|
30
|
+
if index
|
31
|
+
self.index = Evaluators::DiceEvaluator.call(text: index)
|
32
|
+
end
|
33
|
+
if cell
|
34
|
+
self.cell = Evaluators::DiceEvaluator.call(text: cell)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
WITH_GREP_REGEXP = %r{(?<declaration>\/(?<found>[^\/]+)/)}
|
39
|
+
WITH_INDEX_REGEXP = %r{(?<declaration>\[(?<found>[^\]]+)\])}
|
40
|
+
CELL_WITHOUT_INDEX_REGEXP = %r{(?<declaration>\[\]\[(?<found>[^\]]+)\])}
|
41
|
+
EMPTY_INDEX_EMPTY_CELL_REGEXP = %r{(?<declaration>\[\]\[\])}
|
42
|
+
WITH_EMPTY_INDEX_REGEX = %r{(?<declaration>\[\])}
|
43
|
+
WITH_EMPTY_GREP_REGEX = %r{(?<declaration>\/\/)}
|
44
|
+
|
26
45
|
def extract_parameters!
|
27
|
-
@parameters = {}
|
28
46
|
text = @text
|
29
|
-
if match =
|
47
|
+
if match = EMPTY_INDEX_EMPTY_CELL_REGEXP.match(text)
|
48
|
+
text = text.sub(match[:declaration], '')
|
49
|
+
elsif match = CELL_WITHOUT_INDEX_REGEXP.match(text)
|
50
|
+
text = text.sub(match[:declaration], '')
|
51
|
+
self.cell = match[:found]
|
52
|
+
elsif match = WITH_EMPTY_INDEX_REGEX.match(text)
|
30
53
|
text = text.sub(match[:declaration], '')
|
31
54
|
elsif match = WITH_INDEX_REGEXP.match(text)
|
32
55
|
text = text.sub(match[:declaration], '')
|
33
|
-
|
56
|
+
self.index = match[:found]
|
57
|
+
# Moving on to the cell
|
58
|
+
if match = WITH_EMPTY_INDEX_REGEX.match(text)
|
59
|
+
text = text.sub(match[:declaration], '')
|
60
|
+
elsif match = WITH_INDEX_REGEXP.match(text)
|
61
|
+
text = text.sub(match[:declaration], '')
|
62
|
+
self.cell = match[:found]
|
63
|
+
end
|
34
64
|
elsif match = WITH_EMPTY_GREP_REGEX.match(text)
|
35
65
|
text = text.sub(match[:declaration], '')
|
36
66
|
elsif match = WITH_GREP_REGEXP.match(text)
|
37
67
|
text = text.sub(match[:declaration], '')
|
38
|
-
|
68
|
+
self.grep = match[:found]
|
39
69
|
end
|
40
|
-
|
70
|
+
self.table_name = text.downcase
|
41
71
|
end
|
42
72
|
end
|
43
73
|
end
|
data/lib/gm/notepad/readline.rb
CHANGED
data/lib/gm/notepad/table.rb
CHANGED
@@ -8,15 +8,15 @@ module Gm
|
|
8
8
|
process(lines: lines)
|
9
9
|
end
|
10
10
|
|
11
|
-
def lookup(index: false)
|
12
|
-
if index
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
11
|
+
def lookup(index: false, cell: false)
|
12
|
+
if index && cell
|
13
|
+
lookup_entry_by(index: index).lookup(cell: cell)
|
14
|
+
elsif index
|
15
|
+
lookup_entry_by(index: index)
|
16
|
+
elsif cell
|
17
|
+
lookup_random_entry.lookup(cell: cell)
|
18
18
|
else
|
19
|
-
|
19
|
+
lookup_random_entry
|
20
20
|
end
|
21
21
|
end
|
22
22
|
|
@@ -45,6 +45,18 @@ module Gm
|
|
45
45
|
|
46
46
|
private
|
47
47
|
|
48
|
+
def lookup_entry_by(index:)
|
49
|
+
begin
|
50
|
+
@table.fetch(index.to_s)
|
51
|
+
rescue KeyError
|
52
|
+
raise MissingTableEntryError.new(table_name: table_name, index: index.to_s)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def lookup_random_entry
|
57
|
+
@table.values[random_index]
|
58
|
+
end
|
59
|
+
|
48
60
|
attr_accessor :filename, :config
|
49
61
|
attr_reader :table_name
|
50
62
|
|
@@ -60,7 +72,7 @@ module Gm
|
|
60
72
|
@table = {}
|
61
73
|
lines.each do |line|
|
62
74
|
next if line[0] == '#'
|
63
|
-
entry = TableEntry.new(line: line,
|
75
|
+
entry = TableEntry.new(line: line, config: config)
|
64
76
|
entry.lookup_range.each do |i|
|
65
77
|
key = i.to_s
|
66
78
|
raise DuplicateKeyError.new(key: table_name, object: self) if @table.key?(key)
|
@@ -4,7 +4,9 @@ module Gm
|
|
4
4
|
TABLE_ENTRY_RANGE_MARKER = "-".freeze
|
5
5
|
class TableEntry
|
6
6
|
Configuration.init!(target: self, from_config: [:column_delimiter], additional_params: [:line]) do
|
7
|
-
|
7
|
+
row = line.split(column_delimiter)
|
8
|
+
self.index = row.shift
|
9
|
+
self.cells = row
|
8
10
|
end
|
9
11
|
|
10
12
|
include Comparable
|
@@ -12,30 +14,40 @@ module Gm
|
|
12
14
|
to_str <=> String(other)
|
13
15
|
end
|
14
16
|
|
17
|
+
def lookup(cell:)
|
18
|
+
# TODO: Need to deal with named columns
|
19
|
+
cells[cell.to_i]
|
20
|
+
end
|
21
|
+
|
15
22
|
NUMBER_RANGE_REGEXP = %r{(?<left>\d+) *- *(?<right>\d+)}
|
16
23
|
def lookup_range
|
17
|
-
if match = NUMBER_RANGE_REGEXP.match(
|
24
|
+
if match = NUMBER_RANGE_REGEXP.match(index)
|
18
25
|
(match[:left].to_i..match[:right].to_i).map(&:to_s)
|
19
26
|
else
|
20
|
-
[
|
27
|
+
[index]
|
21
28
|
end
|
22
29
|
end
|
23
30
|
|
24
|
-
attr_reader :
|
31
|
+
attr_reader :index, :cells
|
32
|
+
|
33
|
+
def entry
|
34
|
+
cells.join("\t")
|
35
|
+
end
|
36
|
+
alias entry_column entry
|
25
37
|
|
26
38
|
def to_s
|
27
|
-
"[#{
|
39
|
+
"[#{index}]\t#{entry}"
|
28
40
|
end
|
29
|
-
alias to_str
|
41
|
+
alias to_str entry
|
30
42
|
|
31
43
|
private
|
32
44
|
|
33
|
-
def
|
34
|
-
@
|
45
|
+
def index=(input)
|
46
|
+
@index = input.strip.downcase.freeze
|
35
47
|
end
|
36
48
|
|
37
|
-
def
|
38
|
-
@
|
49
|
+
def cells=(input)
|
50
|
+
@cells = Array(input).map { |i| i.strip.freeze }.freeze
|
39
51
|
end
|
40
52
|
end
|
41
53
|
end
|
@@ -59,15 +59,10 @@ module Gm
|
|
59
59
|
end
|
60
60
|
|
61
61
|
def lookup(table_name:, **kwargs)
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
rescue MissingTableError
|
67
|
-
"(undefined table_name: #{table_name.inspect})"
|
68
|
-
rescue KeyError
|
69
|
-
"(missing entry for #{kwargs.inspect})"
|
70
|
-
end
|
62
|
+
table = fetch_table(name: table_name)
|
63
|
+
table.lookup(**kwargs)
|
64
|
+
rescue MissingTableError, MissingTableEntryError => e
|
65
|
+
e.to_buffer_message
|
71
66
|
end
|
72
67
|
|
73
68
|
def evaluate(line:)
|
data/lib/gm/notepad/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: gm-notepad
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.8
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jeremy Friesen
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-07-
|
11
|
+
date: 2019-07-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: dice_parser
|
@@ -146,6 +146,7 @@ files:
|
|
146
146
|
- lib/gm/notepad.rb
|
147
147
|
- lib/gm/notepad/configuration.rb
|
148
148
|
- lib/gm/notepad/defaults.rb
|
149
|
+
- lib/gm/notepad/evaluators/dice_evaluator.rb
|
149
150
|
- lib/gm/notepad/exceptions.rb
|
150
151
|
- lib/gm/notepad/input_handler_registry.rb
|
151
152
|
- lib/gm/notepad/input_handlers/comment_handler.rb
|