gm-notepad 0.0.6 → 0.0.8

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6fad1534243d237bace667966a495af3e787a0bc67ef40283e96a2d7ca49942f
4
- data.tar.gz: b37925618ac94a01fdceadba354c641f704756ce55788c839a518e4e3a474b24
3
+ metadata.gz: da3bbc8cbf352187a313f8815110edef14d41c7c37e4f2dd1f3bb49e43200bcf
4
+ data.tar.gz: 12ffebdda56b6d2e3a4c43da401c884b8c1a659767ea618081792346530ca15c
5
5
  SHA512:
6
- metadata.gz: 80173f33eff4c3f0aa01f4ec706f2759d8f91b698b0c45872c299b94e0ac327f5deb1d9b2bf85fa468eaf28b9744f08aa7af67ccb20dd201fe8ce7159ba15e11
7
- data.tar.gz: 49ef7f14a885164ff70dc9e46bb2d05867fe53a9345cb5223efd2624fad4cad54e3f27d85f4aca4df0233cf973899f73786f1d824f958d9f09a8ceda837e7f3b
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
- - [ ] Add option to dump all tables to the given directory
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
- - [ ] Add column handling `{table[][]}`
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
@@ -1,14 +1,32 @@
1
1
  # Write entry `1|entry one` to in memory table `basic_example`
2
- <#basic_example:1|entry one
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
- # Should dump basic_example onto the file system
14
- +basic_example>
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 = -> { print "#{config.fetch(:shell_prompt)} "; ARGF.gets }
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
- }.freeze
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
- if table_lookup.index
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
- if parsed_dice = Dice.parse(match[:dice])
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
@@ -20,6 +20,7 @@ module Gm
20
20
  private
21
21
 
22
22
  def open!
23
+ renderer.call("Welcome to gm-notepad. type \"?\" for help.", to_interactive: true, to_output: false)
23
24
  return unless config.report_config
24
25
  lines = ["# Configuration Parameters:"]
25
26
  config.each_pair do |key, value|
@@ -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
- WITH_GREP_REGEXP = %r{(?<declaration>\/(?<grep>[^\/]+)/)}
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
- attr_accessor :index, :grep, :table_name
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 = WITH_EMPTY_INDEX_REGEX.match(text)
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
- @index = match[:index]
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
- @grep = match[:grep]
68
+ self.grep = match[:found]
39
69
  end
40
- @table_name = text.downcase
70
+ self.table_name = text.downcase
41
71
  end
42
72
  end
43
73
  end
@@ -29,7 +29,7 @@ module Gm
29
29
  ::Readline.output = $stderr
30
30
 
31
31
  def self.input_getter(**config)
32
- -> { ::Readline.readline("#{config.fetch(:shell_prompt, ">")} ", true) }
32
+ -> { ::Readline.readline("", true) }
33
33
  end
34
34
  end
35
35
  end
@@ -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
- begin
14
- @table.fetch(index.to_s)
15
- rescue KeyError
16
- raise MissingTableEntryError.new(table_name: table_name, index: index.to_s)
17
- end
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
- @table.values[random_index]
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, **config)
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
- self.lookup_column, self.entry_column = line.split(column_delimiter)
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(lookup_column)
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
- [lookup_column]
27
+ [index]
21
28
  end
22
29
  end
23
30
 
24
- attr_reader :lookup_column, :entry_column
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
- "[#{lookup_column}]\t#{entry_column}"
39
+ "[#{index}]\t#{entry}"
28
40
  end
29
- alias to_str entry_column
41
+ alias to_str entry
30
42
 
31
43
  private
32
44
 
33
- def lookup_column=(input)
34
- @lookup_column = input.strip.downcase.freeze
45
+ def index=(input)
46
+ @index = input.strip.downcase.freeze
35
47
  end
36
48
 
37
- def entry_column=(input)
38
- @entry_column = input.strip.freeze
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
- # TODO: Push this onto the table, as it removes nosy neighbor syndrom
63
- begin
64
- table = fetch_table(name: table_name)
65
- table.lookup(**kwargs)
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:)
@@ -1,5 +1,5 @@
1
1
  module Gm
2
2
  module Notepad
3
- VERSION = "0.0.6"
3
+ VERSION = "0.0.8"
4
4
  end
5
5
  end
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.6
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-27 00:00:00.000000000 Z
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