rsyntaxtree 2.2.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: fe4cd7a8b28ffa968f99ff228e3a182a64d420e0405cd27e120b5f4ff02fe48e
4
- data.tar.gz: 23a64934f448707de2b55cad4c206d65fab18aa7d6c1cd3aab0b1871efd9be1e
3
+ metadata.gz: 8c57f743f27cc6830495cfe9da3ce4483fec13491af8e80d4437357cc9c37968
4
+ data.tar.gz: d051b212a5abe64711fd42622bce06cea77c1e8bfc78a8315dfc1246f0dc22d0
5
5
  SHA512:
6
- metadata.gz: 2dfd53e10a62187649fb3d7285fa38189ef25cf56d6af7ceea27fba3cc7358b1f7d528db6466607061120fab61a2ff7bd9b84fa0b989e4313faaac306af42235
7
- data.tar.gz: 7399787ea179bdd17910fa9695cc292a18cb5b8e9b3948e943bf32fd52fd05f89e6ec0e2792138197d56c839b9960bab678489a976590667eca9b4dd80679029
6
+ metadata.gz: e214718246e31cf0d42a03f91ee4b7e714cf1576f3f60fb70b6d0fb9d2d22a24e2b04e832d9e8be2df0b664b5506bf8a0994f659384a85469a4023535409c615
7
+ data.tar.gz: 5f7638450414b9cb53ac9fe2cdc08e7776af24ea50a0de75166dfbb3d47b9d4a27ab1d45a026012ef6bd9fdcc76400b1cf88f7df5095dac20cd78c629c3ccc33
data/CHANGELOG.md CHANGED
@@ -1,5 +1,25 @@
1
1
  # Changelog
2
2
 
3
+ ## [2.3.0] - 2026-09-01
4
+
5
+ ### Added
6
+ - `RSTError::CODES` lists every error code the library can report. A program
7
+ keyed by code — one that translates the diagnosis, or tallies what kinds of
8
+ mistake a writer makes — needs the whole set rather than the codes it has
9
+ happened to see, and until now that set could only be recovered by reading
10
+ five files and the repair table. The list only grows: a published code is
11
+ not renamed or removed.
12
+
13
+ ### Fixed
14
+ - Whitespace alone is an empty input rather than a defect in the library. It
15
+ reached the drawing, which walked off the end of an empty tree and reported
16
+ `internal_error`, telling the caller that their own fixable input was the
17
+ library's fault.
18
+ - A bracketless input of a single character draws. The tokenizer counted its
19
+ cursor as exhausted one character early, so `A`, and `<>` once it is one
20
+ whitespace block, produced no tokens at all — though the manual has always
21
+ said a label on its own draws as one leaf.
22
+
3
23
  ## [2.2.0] - 2026-09-01
4
24
 
5
25
  ### Changed
@@ -97,9 +117,8 @@ looking at what was left. Every figure in the gallery draws exactly as it did.
97
117
 
98
118
  ### Added
99
119
  - `shear`: the drawn figure tilts by the given angle (degrees, positive
100
- leaning the top to the right) and lies on a plane drawn behind it, so the
101
- lean reads as a surface seen at an angle rather than as a mistake. The
102
- whole picture shears as one affine piece — layout untouched, region
120
+ leaning the top to the right) and lies on a plane drawn behind it, which
121
+ shows the tilt as a surface. The whole picture shears as one affine piece layout untouched, region
103
122
  shades coming out parallelograms on their own, and nothing able to newly
104
123
  touch or cross. The plane is fill without an edge — a region shade is
105
124
  bounded because it marks one part of a figure off from the rest, and a
@@ -245,9 +264,8 @@ looking at what was left. Every figure in the gallery draws exactly as it did.
245
264
  - Derivations. A derivation puts the words first and the result last, and
246
265
  joins what each step combines with one rule drawn across all of it rather
247
266
  than with a line to each daughter. `derivation` draws the rules and
248
- `direction: btt` turns the tree over; together they give the format
249
- categorial grammar is written in, and `derivation` on its own marks the
250
- spans of an ordinary tree. The name of each step rides in the label after a
267
+ `direction: btt` turns the tree over; together they draw a CCG derivation,
268
+ and `derivation` on its own marks the spans of an ordinary tree. The name of each step rides in the label after a
251
269
  column break and is set beside the end of its rule. A derivation runs down
252
270
  the page and is drawn with its rules, so `direction: ltr` and hiding the
253
271
  default connectors are refused rather than approximated.
@@ -379,15 +397,15 @@ RMagick dependency.
379
397
  rule that work never uses.
380
398
  - A matrix nested in a label, written between `#(` and `#)`. The value of an
381
399
  attribute can be another attribute-value matrix, to any depth, which is what
382
- a feature path such as SYNSEM | LOCAL | CATEGORY | HEAD needs and what HPSG,
383
- SBCG and LFG are written in. The nested matrix draws its own brackets and
400
+ a feature path such as SYNSEM | LOCAL | CATEGORY | HEAD needs, and what
401
+ HPSG and LFG are written in. The nested matrix draws its own brackets and
384
402
  lays out its own columns, and the rows after it clear its full height.
385
403
  - `\t` in a label cuts the line into cells. Every line is cut at the same
386
404
  points and each column is drawn at the width of its widest cell, so the
387
405
  parts line up down the label. Together with the bracket enclosure and the
388
406
  horizontal rule this gives attribute-value matrices — the feature structures
389
- of HPSG, SBCG and LFG — without spacing each row by hand, which is how the
390
- gallery's HPSG example used to do it.
407
+ of HPSG, LFG and the like — without spacing each row by hand, which is how
408
+ the gallery's HPSG example used to do it.
391
409
  - `color: gray`, a scheme that keeps node and leaf labels black and draws the
392
410
  connectors, triangles and movement paths in grey. It is for diagrams whose
393
411
  links outnumber their labels — an ontology, a network of constructions —
@@ -64,7 +64,12 @@ module RSyntaxTree
64
64
  end
65
65
 
66
66
  def self.valid?(data)
67
- raise RSTError.new(+"Error: input text is empty", code: :empty_input, retryable: false) if data.empty?
67
+ # Whitespace alone is an empty input, not a tree with one blank label:
68
+ # nothing survives the parse, and what used to happen is that the
69
+ # drawing walked off the end of an empty element list and reported a
70
+ # defect in the library for what the caller could see and fix. A space
71
+ # meant as a label is written <>, which is not whitespace here.
72
+ raise RSTError.new(+"Error: input text is empty", code: :empty_input, retryable: false) if data.strip.empty?
68
73
 
69
74
  if /\[\s*\]/m =~ data
70
75
  raise RSTError.new(+"Error: inside the brackets is empty", code: :empty_brackets,
@@ -204,7 +209,11 @@ module RSyntaxTree
204
209
  token = ""
205
210
  i = 0
206
211
 
207
- return "" if (@pos + 1) >= data.length
212
+ # The cursor is exhausted when it reaches the end, not one before it:
213
+ # counting from @pos + 1 skipped the last character, so an input of a
214
+ # single character — "A", or "<>" once it is one whitespace block —
215
+ # produced no tokens at all and drew from an empty element list.
216
+ return "" if @pos >= data.length
208
217
 
209
218
  escape = false
210
219
  while ((@pos + i) < data.length) && !gottoken
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module RSyntaxTree
4
- VERSION = "2.2.0"
4
+ VERSION = "2.3.0"
5
5
  end
data/lib/rsyntaxtree.rb CHANGED
@@ -133,6 +133,50 @@ class RSTError < StandardError
133
133
  super(msg.gsub(WHITESPACE_BLOCK, "<>"))
134
134
  end
135
135
 
136
+ # Every code an error from this library can carry. Consumers dispatch on
137
+ # these — a translation keyed by code, a harness counting what kinds of
138
+ # mistake occur — and both need to know the whole set, not only the codes
139
+ # they have happened to see: a kind of mistake nobody made is not the same
140
+ # as a kind that cannot happen. Until this list existed the set was only
141
+ # discoverable by reading five files and a repair table.
142
+ #
143
+ # Written out rather than computed, because it is a contract and a contract
144
+ # should be readable at a glance and visible in a diff. A test keeps it
145
+ # honest by finding the codes the library actually raises and comparing.
146
+ #
147
+ # The list grows and does not churn: a code once published is not renamed
148
+ # or removed, so a consumer keyed by code — a translation table, a tally of
149
+ # what kinds of mistake a writer makes — only ever has entries to add.
150
+ #
151
+ # Eight are named by the repair table, which diagnoses a label by rewriting
152
+ # it and asking the parser whether the rewrite reads: angle_brackets,
153
+ # bare_hyphen, incomplete_path, invalid_color, rule_name_without_derivation,
154
+ # stray_triangle, unclosed_markup, unclosed_matrix. invalid_markup is where
155
+ # a label lands whose mistake no single rewrite fits, which in practice
156
+ # means more than one. unknown_color and label_split are mistakes inside a
157
+ # label too, found before the repair table is reached.
158
+ CODES = %i[
159
+ angle_brackets
160
+ bare_hyphen
161
+ empty_brackets
162
+ empty_input
163
+ incomplete_path
164
+ internal_error
165
+ invalid_color
166
+ invalid_markup
167
+ invalid_option
168
+ label_split
169
+ path_multiple_ends
170
+ path_single_end
171
+ result_too_big
172
+ rule_name_without_derivation
173
+ stray_triangle
174
+ unbalanced_brackets
175
+ unclosed_markup
176
+ unclosed_matrix
177
+ unknown_color
178
+ ].freeze
179
+
136
180
  # Where the notation is written down. A hint repairs the mistake in front of
137
181
  # it and says nothing about the rest, which is enough for a reader who knows
138
182
  # the notation and not enough for one who was guessing at it. Given once, at
@@ -435,8 +479,21 @@ module RSyntaxTree
435
479
  !OFF.include?(value.to_s.strip.downcase)
436
480
  end
437
481
 
482
+ # Whether the input is nothing to draw. Whitespace alone counts: it
483
+ # leaves no label behind, and reporting it as a defect in the library
484
+ # told the caller their own fixable input was our fault. Asked without
485
+ # strip when the bytes are not valid UTF-8, because strip raises there
486
+ # and that input is not blank — it is malformed, which the caller
487
+ # learns further down.
488
+ def self.blank?(text)
489
+ s = text.to_s
490
+ return true if s.empty?
491
+
492
+ s.valid_encoding? && s.strip.empty?
493
+ end
494
+
438
495
  def self.check_data(text, params = {})
439
- raise RSTError.new(+"Error: input text is empty", code: :empty_input, retryable: false) if text.to_s == ""
496
+ raise RSTError.new(+"Error: input text is empty", code: :empty_input, retryable: false) if blank?(text)
440
497
 
441
498
  begin
442
499
  StringParser.valid?(text)
@@ -510,7 +567,7 @@ module RSyntaxTree
510
567
  def self.diagnose(text, params = {})
511
568
  errors = []
512
569
  note = nil
513
- if text.to_s == ""
570
+ if blank?(text)
514
571
  errors << RSTError.new(+"Error: input text is empty", code: :empty_input, retryable: false)
515
572
  else
516
573
  begin
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rsyntaxtree
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.2.0
4
+ version: 2.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Yoichiro Hasebe