rsyntaxtree 1.13.2 → 1.14.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: aa35ea4c535165dcf70b1a1b6375ff32666ce42294219a9b3d59ba6cb614ee85
4
- data.tar.gz: 23d80a1781dd85a41d349b670b7610981bba30a87fa90cd0847d91dc65356fe4
3
+ metadata.gz: 965fe8dae50ad6fe7907850239f395fda6a5186654a81d36b89400ebe52108f2
4
+ data.tar.gz: 4a183744f4d05b63efcbd1e9aedb6a4bf060654fde9dfc62abaeb20e6a38ac8a
5
5
  SHA512:
6
- metadata.gz: baa9e98752ce86da774ededc1228b6f588e69da5b381bc94112190f7198f8a2128d64760cc49114b9e3a8815d24e0984714cf562ebdb0e86572dc4c3790e0bab
7
- data.tar.gz: ada76c5d30433a0652be01242c8da0225f63e84c3717accb0eeb3628567df9744b67c408405acc94e52dbd38288fe5352f3ceb2c789b41974184dd2443322f6b
6
+ metadata.gz: ee4fca1e926ad6886aaca041468f61dc0a596eeffa107c4ee3a82576f2ac7ac53eddcdc0ee586fc5f4408fc809188dba1279eb0ff8083892ef1b598aea830ca1
7
+ data.tar.gz: 19173b80e3c2376a9f25d6ea72604bc5774194af7eccfc2b1158dfdf75939ed5d700f654b8122ecf3df99242036686666266ed829710fbe22d94bbea965ae91b
data/CHANGELOG.md CHANGED
@@ -1,6 +1,52 @@
1
1
  # Changelog
2
2
 
3
- ## [1.13.2] - 2026-08
3
+ ## [1.14.0] - 2026-08-27
4
+
5
+ ### Added
6
+ - The notation has a map. The reference the gem ships (`--notation`) is one
7
+ page: the characters that already mean something, then every feature at a
8
+ line each with the notation beside it, then the options. Both manuals open
9
+ with the same list, each row pointing at the section that explains it. A test
10
+ reads the feature set out of the grammar itself and draws every sample, so a
11
+ feature the grammar gains with no row in the documents fails the build, and a
12
+ sample that stops meaning what it says fails with it.
13
+ - The changelog is on the documentation site, at /changelog, built from
14
+ CHANGELOG.md and linked from the manuals and the README.
15
+
16
+ ### Changed
17
+ - Every release in the changelog is dated to the day, from the git tags. Two of
18
+ the old month-only dates were wrong.
19
+ - What the trap section warns about is now, by definition, what the tool
20
+ accepts and draws as something other than what was meant. A mistake the tool
21
+ refuses is the error message's job, and its card has come down; the warning
22
+ about parentheses, which the Penn Treebank conversion had made false, tells
23
+ the truth again.
24
+ - The arrow markers' dimensions are rounded; the defs of every SVG carried
25
+ float dust in an attribute.
26
+
27
+ ### Fixed
28
+ - Turning `derivation` on no longer deletes a column from a node that has no
29
+ daughters. A rule name is written after a column break and names the step
30
+ that produced a node from its daughters, so a node with none names no rule —
31
+ but the label is read before the tree is built, and the name was taken out
32
+ anyway and then had no rule to be drawn beside. `[A\tfoo]` drew "A foo" with
33
+ the option off and "A" with it on. The label is put back once the tree is
34
+ known.
35
+ - A mistake inside a node's label keeps the name of what is wrong with it. The
36
+ first raw space splits a token into a label and its children, and when the
37
+ label would not parse, every cause but one was relabelled "a raw space split
38
+ this" — so the message named an unknown colour while the code and the hint
39
+ talked about spaces, and a caller acting on the code was sent to fix what was
40
+ not wrong. Which story is right is now asked of the parser rather than
41
+ guessed: the token is put back together with its spaces written as the
42
+ notation writes them, and if it reads, the space was the cause.
43
+ - A hex colour is three digits or six, which is what every message about colour
44
+ here already said. The grammar asked for three to six, so four and five
45
+ parsed, passed the validator — which does not look at a value beginning with
46
+ `#` — and reached librsvg, which cannot read them and draws the label black
47
+ without reporting it.
48
+
49
+ ## [1.13.2] - 2026-08-27
4
50
 
5
51
  ### Fixed
6
52
  - A movement path is drawn as one stroke with its corners eased, in place of
@@ -25,7 +71,7 @@
25
71
  the gallery is unchanged to the pixel — every raster figure is byte-identical
26
72
  and the SVGs differ only in the family list they carry.
27
73
 
28
- ## [1.13.1] - 2026-08
74
+ ## [1.13.1] - 2026-08-27
29
75
 
30
76
  ### Fixed
31
77
  - `^` at the head of a leaf draws the triangle it asks for. The mark may be
@@ -44,7 +90,7 @@
44
90
  every input, because the form still read a `format` select the page no longer
45
91
  had. A value that is actually wrong is still rejected.
46
92
 
47
- ## [1.13.0] - 2026-08
93
+ ## [1.13.0] - 2026-08-24
48
94
 
49
95
  ### Added
50
96
  - Derivations. A derivation puts the words first and the result last, and
@@ -63,7 +109,7 @@
63
109
  have when the root is at the top, so every line ran from above the daughter,
64
110
  through its label and the mother's, to below the mother.
65
111
 
66
- ## [1.12.0] - 2026-08
112
+ ## [1.12.0] - 2026-08-22
67
113
 
68
114
  Everything needed to write this notation is now available as text, built from
69
115
  the files the tool itself reads, and a refusal says where that text is.
@@ -93,7 +139,7 @@ the files the tool itself reads, and a refusal says where that text is.
93
139
  meant waiting on a pipe that never closes when stdin is not a terminal,
94
140
  which is how a script reaches them.
95
141
 
96
- ## [1.11.0] - 2026-08
142
+ ## [1.11.0] - 2026-08-21
97
143
 
98
144
  Every input the tool accepts now draws, and every input it refuses says why.
99
145
  Line thickness follows the type size, so figures drawn at any font size keep
@@ -152,7 +198,7 @@ fifth lighter than before.
152
198
  read as a path to the current directory.
153
199
  - Overline was documented as missing from PNG output. It has been there.
154
200
 
155
- ## [1.10.0] - 2026-08
201
+ ## [1.10.0] - 2026-08-19
156
202
 
157
203
  A transitional release ahead of 2.0, which drops JPG/GIF output and the
158
204
  RMagick dependency.
@@ -175,7 +221,7 @@ RMagick dependency.
175
221
  file here carries `frozen_string_literal`, which made the working form the
176
222
  unobvious one.
177
223
 
178
- ## [1.9.0] - 2026-08
224
+ ## [1.9.0] - 2026-08-19
179
225
 
180
226
  ### Added
181
227
  - `hyphen: literal`, which trades the two readings of a hyphen: a bare one is
@@ -243,7 +289,7 @@ RMagick dependency.
243
289
  the arrow was drawn small to fit; now the pair is spread and the arrow keeps
244
290
  its size. Only pairs that carry a link move, and only when they need to.
245
291
 
246
- ## [1.8.2] - 2026-08
292
+ ## [1.8.2] - 2026-08-17
247
293
 
248
294
  ### Changed
249
295
  - `tidy: high` now compresses as far as its name promises. The level-balance
@@ -271,7 +317,7 @@ RMagick dependency.
271
317
  resolved nowhere on macOS, Debian/Ubuntu or Alpine; the chain fell through
272
318
  to `Noto Sans Mono`, which it now names directly.
273
319
 
274
- ## [1.8.1] - 2026-08
320
+ ## [1.8.1] - 2026-08-15
275
321
 
276
322
  ### Fixed
277
323
  - Arabic rendered as isolated, unjoined letterforms in some environments.
@@ -300,7 +346,7 @@ RMagick dependency.
300
346
  - Documentation records how to override any of the named families with a
301
347
  fontconfig alias, for users who prefer their own script fonts.
302
348
 
303
- ## [1.8.0] - 2026-08
349
+ ## [1.8.0] - 2026-08-15
304
350
 
305
351
  ### Added
306
352
  - `tidy` layout scale, one option covering every layout mode from the most
@@ -349,7 +395,7 @@ RMagick dependency.
349
395
  when the caller passes only a partial parameter set (e.g. `tidy: off`
350
396
  rendered as `symmetric` in the web UI).
351
397
 
352
- ## [1.7.0] - 2026-08
398
+ ## [1.7.0] - 2026-08-13
353
399
 
354
400
  ### Changed
355
401
  - Text measurement now uses Pango, the same engine (and the same fontconfig
@@ -369,7 +415,7 @@ RMagick dependency.
369
415
  - Runtime dependency on the `pango` gem (ruby-gnome). No new system
370
416
  requirements: librsvg already depends on Pango.
371
417
 
372
- ## [1.6.3] - 2026-07
418
+ ## [1.6.3] - 2026-07-19
373
419
 
374
420
  ### Fixed
375
421
  - Packaged files no longer carry owner-only permissions. `gem build` preserves
@@ -381,14 +427,14 @@ RMagick dependency.
381
427
  tree had picked up on data files (images, fonts, Markdown, CSS, library
382
428
  sources).
383
429
 
384
- ## [1.6.2] - 2026-06
430
+ ## [1.6.2] - 2026-06-26
385
431
 
386
432
  ### Fixed
387
433
  - Region shade no longer touches the image edge when its padded bounds reach
388
434
  past the tree's natural extent (e.g. a deep enclosed/multi-line node): the
389
435
  canvas now grows with a margin around the shaded plane.
390
436
 
391
- ## [1.6.1] - 2026-06
437
+ ## [1.6.1] - 2026-06-26
392
438
 
393
439
  ### Improved
394
440
  - Region shade rendering wraps the subtree more cleanly: wider, balanced
@@ -402,7 +448,7 @@ RMagick dependency.
402
448
  - Example 065: nested (overlapping) region shades, shown as progressively
403
449
  darker gray.
404
450
 
405
- ## [1.6.0] - 2026-06
451
+ ## [1.6.0] - 2026-06-25
406
452
 
407
453
  ### Added
408
454
  - Region shade (`%` prefix): paints a semi-transparent plane behind the whole
@@ -430,7 +476,7 @@ RMagick dependency.
430
476
  - Region shade on the root/topmost node no longer clipped by the canvas: the
431
477
  SVG viewBox now grows to include region planes that extend past the tree.
432
478
 
433
- ## [1.5.0] - 2026-04
479
+ ## [1.5.0] - 2026-04-06
434
480
 
435
481
  ### Added
436
482
  - Left-to-right tree layout (`-d ltr` / `--direction ltr`)
@@ -445,7 +491,7 @@ RMagick dependency.
445
491
  ### Improved
446
492
  - TTB path bulge proportional to endpoint distance (reduced excess)
447
493
 
448
- ## [1.4.0] - 2026-01
494
+ ## [1.4.0] - 2026-01-06
449
495
 
450
496
  ### Added
451
497
  - LSIF (Linguistic Structure Interchange Format) JSON output (`-f lsif`)
@@ -461,15 +507,15 @@ RMagick dependency.
461
507
  - Added examples for per-node coloring (054, 055, 056)
462
508
  - Added example 057: Subscript and superscript demo
463
509
 
464
- ## [1.3.2] - 2024
510
+ ## [1.3.2] - 2025-03-03
465
511
 
466
512
  - Garbage collection friendly implementation
467
513
 
468
- ## [1.3.1] - 2024
514
+ ## [1.3.1] - 2024-10-24
469
515
 
470
516
  - Bug fixes and improvements
471
517
 
472
- ## [1.3.0] - 2024
518
+ ## [1.3.0] - 2024-08-27
473
519
 
474
520
  - TikZ/forest LaTeX output support
475
521
 
data/README.md CHANGED
@@ -206,6 +206,50 @@ fontsize: 18
206
206
 
207
207
  CLI options override config file settings.
208
208
 
209
+ ## Using RSyntaxTree with an AI Model
210
+
211
+ The notation is small, but several characters in it already mean something, so
212
+ a model writing it does better with the reference in front of it than without.
213
+
214
+ **If the model only writes the notation** and you draw it yourself — in the
215
+ [web interface](https://yohasebe.com/rsyntaxtree) or on your own machine —
216
+ nothing needs installing. Give the model one of these to read:
217
+
218
+ - [The brief reference](https://yohasebe.github.io/rsyntaxtree/llms.txt), about
219
+ a page, leading with the characters that already mean something.
220
+ - [Everything in one file](https://yohasebe.github.io/rsyntaxtree/llms-full.txt):
221
+ the reference, the manual and all the gallery examples, 78 KB.
222
+
223
+ **If the model can run a shell**, it can draw and then look at what it drew,
224
+ which is the part that lets it correct itself:
225
+
226
+ ```bash
227
+ docker run --rm -v "$PWD:/work" -w /work ghcr.io/yohasebe/rsyntaxtree \
228
+ rsyntaxtree --notation # the reference, on stdout
229
+ docker run --rm -v "$PWD:/work" -w /work ghcr.io/yohasebe/rsyntaxtree \
230
+ rsyntaxtree -f png -o . "[S [NP a tree] [VP appears]]"
231
+ ```
232
+
233
+ Then read `syntree.png` back. `--examples` prints every gallery example with
234
+ the settings it was drawn at, and `--validate` reports what is wrong with an
235
+ input as JSON — including whether rewriting it is worth trying — without
236
+ drawing anything:
237
+
238
+ ```json
239
+ { "schema": "rsyntaxtree.error/1", "ok": false,
240
+ "errors": [ { "code": "unbalanced_brackets",
241
+ "message": "Error: open and close brackets do not match",
242
+ "hint": "Count the brackets: every '[' needs one ']'.",
243
+ "retryable": true } ],
244
+ "reference": "rsyntaxtree --notation, or https://yohasebe.github.io/rsyntaxtree/llms-full.txt" }
245
+ ```
246
+
247
+ The exit code carries the verdict too, so a script can branch on it without
248
+ reading the JSON. The Docker image is used above because this tool draws
249
+ through Pango and librsvg, and a figure depends on which versions of those —
250
+ and which fonts — are installed; the image fixes all of them. Installed as a
251
+ gem it works the same, once those libraries are on the machine.
252
+
209
253
  ## Documentation
210
254
 
211
255
  For detailed documentation on syntax and markup:
@@ -213,6 +257,7 @@ For detailed documentation on syntax and markup:
213
257
  - [Documentation in English](https://yohasebe.github.io/rsyntaxtree/documentation)
214
258
  - [日本語ドキュメント](https://yohasebe.github.io/rsyntaxtree/documentation_ja)
215
259
  - [Example Gallery](https://yohasebe.github.io/rsyntaxtree/examples)
260
+ - [Changelog](https://yohasebe.github.io/rsyntaxtree/changelog)
216
261
 
217
262
  ## How to Cite
218
263
 
@@ -13,7 +13,7 @@ require_relative "color_names"
13
13
 
14
14
  module RSyntaxTree
15
15
  class Element
16
- attr_accessor :rule_name, :id, :parent, :type, :level, :width, :height, :content, :content_width, :text_width, :content_height, :horizontal_indent, :vertical_indent, :triangle, :enclosure, :children, :font, :fontsize, :contains_phrase, :path, :color, :raw_content, :region, :region_color
16
+ attr_accessor :rule_name, :label_with_rule_name, :id, :parent, :type, :level, :width, :height, :content, :content_width, :text_width, :content_height, :horizontal_indent, :vertical_indent, :triangle, :enclosure, :children, :font, :fontsize, :contains_phrase, :path, :color, :raw_content, :region, :region_color
17
17
 
18
18
  # names_a_rule says the content is a mother's label rather than a leaf's
19
19
  # text. Only a mother has a step under it for a name to sit beside, and a
@@ -42,7 +42,11 @@ module RSyntaxTree
42
42
  @fontset = fontset
43
43
  @fontsize = fontsize
44
44
  # In a derivation the label may carry the name of the rule that produced
45
- # it, written after a column break: `S/NP\t\>B`. The name belongs beside
45
+ # it, written after a column break: `S/NP\t>B`. The name is taken out
46
+ # before the label is read as markup, so it is drawn exactly as written —
47
+ # `>` and `<` need no escaping there, and escaping them puts the backslash
48
+ # in the figure. (This example carried one, which is the opposite of what
49
+ # the gallery's derivations do.) The name belongs beside
46
50
  # the rule rather than beside the result, so it comes out of the label
47
51
  # here, before the label is measured, and BaseGraph draws it at the end
48
52
  # of the rule.
@@ -51,6 +55,11 @@ module RSyntaxTree
51
55
  name = at && content[(at + 2)..].to_s.strip
52
56
  if name && !name.empty?
53
57
  @rule_name = name
58
+ # Kept whole, because whether this node has daughters — and so
59
+ # whether it names a rule at all — is not known until the tree
60
+ # is built. StringParser puts the label back if it turns out
61
+ # there was no step for the name to belong to.
62
+ @label_with_rule_name = content
54
63
  content = content[0...at]
55
64
  end
56
65
  end
@@ -15,7 +15,14 @@ class MarkupParser < Parslet::Parser
15
15
 
16
16
  # Color specification: @colorname: or @#hexcode:
17
17
  rule(:color_name) { match('[a-zA-Z]').repeat(1) }
18
- rule(:color_hex) { str('#') >> match('[0-9a-fA-F]').repeat(3, 6) }
18
+ # Three digits or six, which is what every message about colour in this
19
+ # codebase already says. The rule used to be written as "three to six", so
20
+ # four and five passed the parser, passed the validator (which does not look
21
+ # at a value beginning with '#' at all), and went into the SVG — where
22
+ # librsvg cannot read them and draws the label black, with nothing reported.
23
+ # Six first: on a six-digit value the three-digit branch matches and then
24
+ # the ':' is not there to be found.
25
+ rule(:color_hex) { str('#') >> (match('[0-9a-fA-F]').repeat(6, 6) | match('[0-9a-fA-F]').repeat(3, 3)) }
19
26
  rule(:color_spec) { str('@') >> (color_hex | color_name).as(:color_value) >> str(':') }
20
27
 
21
28
  # Region shade: '%' marks the node so that the whole subtree it governs
@@ -1,52 +1,105 @@
1
- RSyntaxTree notation, in brief.
1
+ RSyntaxTree notation, on one page.
2
2
 
3
3
  A tree is labeled brackets: [S [NP the cat] [VP sat]]. The label follows the
4
- opening bracket; children follow the label.
5
-
6
- Within a label:
7
- - `\n` breaks a line; `\t` separates columns, and every line is cut at the
8
- same points, so the columns line up down the label. (`\t` is the two
9
- characters backslash and t, not a real tab.)
10
- - `#label` draws square brackets around the whole label; `##label` a
11
- rectangle. `#( ... #)` nests a matrix inside a label, to any depth.
12
- - `*italic*`, `**bold**`, `x_sub_`, `x__super__`, `|x|` in a box, `{x}` in a
13
- circle, `---` a horizontal rule.
14
- - `+n` on two nodes links them with a movement arrow; `+>n` puts the
15
- arrowhead on that end.
16
-
17
- Four traps, because these characters already mean something:
18
- - `<` and `>` are never angle brackets in this notation: `<>` is one space,
19
- `<3>` is three. Wherever linguistics uses angle brackets a list ⟨NP⟩,
20
- an argument structure like 'hand⟨SUBJ,OBJ⟩', anything write the
21
- characters and themselves (U+27E8 and U+27E9):
22
- SPR\t⟨<>NP<>⟩ PRED\t'hand⟨SUBJ,OBJ⟩'
23
- - `-` opens and closes an underline, so a bare hyphen in ANY word is an
24
- error: V-bar, f-structure, HEAD-DTR. Write `V'`, or escape the hyphen:
25
- `V\-bar`, `f\-structure`, `HEAD\-DTR`.
26
- - A raw space is safe in a one-line label, and unreliable in a label that
27
- has `\n` or `\t` in it: there it splits a value that carries markup, and
28
- it breaks a matrix nested with `#( ... #)`. Since matrices are exactly the
29
- multi-line case, write a space as `<>` inside any label with columns:
30
- 'a<>toy', not 'a toy'.
31
- - Parentheses are not brackets, and this is silent: `(S (NP ...))` raises no
32
- error and draws one leaf with that text in it. Convert it first.
33
-
34
- An attribute-value matrix is columns plus an enclosure:
35
-
36
- [#*word*\
37
- HEAD\t*verb*\
38
- SPR\t⟨<>NP<>⟩\
39
- COMPS\t⟨<>⟩
40
- ]
4
+ opening bracket; children follow the label. Parentheses are read as Penn
5
+ Treebank notation and converted: (S (NP the cat) (VP sat)) draws the same tree.
6
+
7
+ ## What already means something
8
+
9
+ The characters that bite, first. A mistake the tool can see is refused with a
10
+ hint; everything below is taken silently, and the figure that draws is not the
11
+ figure that was meant.
12
+
13
+ - `<>` is one space and `<3>` is three, everywhere never angle brackets.
14
+ Where linguistics wants the brackets themselves, write and (U+27E8/9):
15
+ SPR\t⟨<>NP<>⟩, 'hand⟨SUBJ,OBJ⟩'. A label written <NP> is refused with this
16
+ advice; a stray <3> simply draws three spaces.
17
+ - A pair of hyphens underlines what stands between them: well-made-word draws
18
+ "made" underlined. (A lone hyphen is refused with a hint.) Write `\-` for a
19
+ hyphen V\-bar, HEAD\-DTR or set the hyphen option to literal.
20
+ - A raw space is safe in a one-line label and unreliable in a label that has
21
+ `\n` or `\t` in it: there it can split a value that carries markup, and it
22
+ breaks a nested #( ... #) matrix. Inside any label with columns, write a
23
+ space as `<>`: 'a<>toy', not 'a toy'.
24
+ - A straight apostrophe is typeset as the curly ’ (U+2019).
25
+ - A backslash takes the character after it, whatever it is: \q draws q, and
26
+ C:\path draws C:path. A backslash itself is \\.
27
+ - The prefixes of a label compose in one order, and only this one:
28
+ `^` `#`/`##`/`###` `%` `@color:`. So ^#%@red:NP is read whole, while
29
+ @red:%NP leaves the % as a literal character and silently drops the shade.
30
+ - A rule name (for derivations) is written after the label's last `\t`, as in
31
+ [S/NP\t>B ...], and needs the derivation option ON with it off the name is
32
+ drawn as a column. The name is taken out before markup runs, so `>` and `<`
33
+ need no escaping there and `\>` would put the backslash in the figure. A
34
+ label that also carries `\n` keeps all its columns instead.
35
+
36
+ ## What there is
37
+
38
+ Structure:
39
+
40
+ | what | how it is written |
41
+ |----------------------------------------|-------------------|
42
+ | a node with children | [S [NP the cat] [VP sat]] |
43
+ | a phrase under one leaf (triangle) | [NP a toy] — one word, forced: [NP ^cats] |
44
+ | an invisible joint, to align leaves | a label of only <>, as in [X [<> [Y y]] [Z z]] |
45
+ | a movement path (dashed) | [S [NP a+1] [VP [V b] [NP c+1]]] |
46
+ | the same, with an arrowhead | write +>1 on the end the arrow points at |
47
+ | an extra straight connector | +-1 on two nodes; +->1 for an arrowhead |
41
48
 
42
- A value can be another matrix. Nest it with `#( ... #)`, never with square
43
- brackets — those are read as tree structure:
49
+ Inside a label:
50
+
51
+ | what | how it is written |
52
+ |----------------------------------------|-------------------|
53
+ | italic, bold, both | *x*, **x**, ***x*** |
54
+ | subscript, superscript | x_i_, x__2__ |
55
+ | small capitals | H___EAD___ |
56
+ | overline, underline, strikethrough | =x=, -x-, ~x~ |
57
+ | a line break; a blank line | a\nb (or a\ b); \n\n |
58
+ | columns, aligned down the label | HEAD\t*verb*\nSPR\t⟨<>⟩ |
59
+ | a horizontal rule across the label | a line of --- (or === for a double rule) |
60
+ | boxed, circled text | |1|, {2} — more than one character draws a capsule |
61
+ | empty and hatched boxes and circles | ||, {}, |/|, {/} |
62
+ | bar and arrows as symbols | --, ->, <-, <-> — bold with *...*, as in *->* |
63
+
64
+ Around a label:
65
+
66
+ | what | how it is written |
67
+ |----------------------------------------|-------------------|
68
+ | square brackets, rectangle, bold | #NP, ##NP, ###NP |
69
+ | a feature matrix as a value | #(HEAD\tnoun#), nested to any depth |
70
+ | a whole label that is one matrix | [#(CAT\tS#) [#(CAT\tNP#) Kim] [#(CAT\tVP#) sleeps]] |
71
+ | a region shade behind the subtree | %NP, coloured: %@blue:NP |
72
+ | a colour | @red:NP, @#3af:NP, @#33aaff:NP (3 or 6 hex digits) |
73
+
74
+ An attribute-value matrix is columns plus an enclosure, and a value can be
75
+ another matrix — nested with #( ... #), never with square brackets, which are
76
+ read as tree structure:
44
77
 
45
78
  [#PRED\t'hand⟨SUBJ,OBJ⟩'\
46
79
  TENSE\tpast\
47
80
  SUBJ\t#(PRED\t'David'#)
48
81
  ]
49
82
 
50
- A movement arrow links the two nodes that carry the same number:
83
+ Options (the command line spells them --like-this):
84
+
85
+ | option | what it decides |
86
+ |------------|-----------------|
87
+ | format | png, svg, pdf, gif, jpg, tikz, lsif |
88
+ | fontstyle | sans, serif, mono, cjk |
89
+ | fontsize | 6–26 |
90
+ | color | modern, traditional, off, gray |
91
+ | linewidth | every line's weight, 0.5–3.0, as a ratio of the font size |
92
+ | leafstyle | auto, bar, nothing — what joins a node to its leaf |
93
+ | direction | ttb, ltr, btt |
94
+ | mirror | flip the finished layout, for RTL scripts |
95
+ | tidy | off, symmetric, low, medium, high — how tightly subtrees pack |
96
+ | hspacing | horizontal spacing factor, 0.5–3.0 (tidy_spacing is its old name) |
97
+ | vheight | vertical spacing factor, 0.5–5.0 |
98
+ | derivation | one rule across the daughters, categorial-grammar style |
99
+ | hyphen | markup (hyphens underline) or literal (hyphens are hyphens) |
100
+
101
+ The full manual explains each of these with figures, and every example in the
102
+ gallery is written out beside the figure it draws:
51
103
 
52
- [S [NP what+>1] [VP [V see] [NP+1 t]]]
104
+ https://yohasebe.github.io/rsyntaxtree/documentation
105
+ https://yohasebe.github.io/rsyntaxtree/examples
@@ -96,9 +96,44 @@ module RSyntaxTree
96
96
  end
97
97
  end
98
98
 
99
+ # Whether the raw space that split this token is what stopped it parsing.
100
+ # Asked of the parser rather than reasoned about: the whole token, with its
101
+ # spaces written as `<>`, either reads as one label or it does not.
102
+ def space_is_the_cause?(token, parent)
103
+ Element.new(-1, parent, token.gsub(" ", WHITESPACE_BLOCK), @level,
104
+ @fontset, @fontsize, @global, true)
105
+ true
106
+ rescue StandardError
107
+ false
108
+ end
109
+
99
110
  def parse
100
111
  make_tree(0);
101
112
  @elist.set_hierarchy
113
+ restore_rule_names_without_a_rule
114
+ end
115
+
116
+ # A rule name names the step that produced a node from its daughters. A node
117
+ # with no daughters is the product of no step, so what looked like a name is
118
+ # a column of the label like any other, and it goes back.
119
+ #
120
+ # Whether a node will have daughters is not known where the label is read —
121
+ # they arrive as later tokens — so the label is read first and put right
122
+ # here, once the tree is built. Left alone, turning the option on deleted a
123
+ # column: `[A\tfoo]` drew "A foo" with derivation off and "A" with it on,
124
+ # and said nothing about the difference.
125
+ def restore_rule_names_without_a_rule
126
+ @elist.elements.each_with_index do |e, i|
127
+ next if e.rule_name.nil? || e.rule_name.empty?
128
+ next unless e.children.empty?
129
+ next if e.label_with_rule_name.nil?
130
+
131
+ restored = Element.new(e.id, e.parent, e.label_with_rule_name,
132
+ e.level, @fontset, @fontsize, @global)
133
+ restored.children = e.children
134
+ restored.type = e.type
135
+ @elist.elements[i] = restored
136
+ end
102
137
  end
103
138
 
104
139
  def get_elementlist
@@ -215,7 +250,21 @@ module RSyntaxTree
215
250
  # parse, the likeliest story is that the space belongs
216
251
  # inside the label and cut a construct in two — say so,
217
252
  # unless a more specific cause is already known.
218
- raise e if e.code == :bare_hyphen
253
+ #
254
+ # Which story is right is not a thing to guess at: ask
255
+ # whether the space is the one that breaks it. Put the whole
256
+ # token back together with the spaces written as the notation
257
+ # writes them, and try again. If it parses, the space was
258
+ # cutting a construct in two and that is what to say. If it
259
+ # fails the same way, the space is a red herring and the cause
260
+ # already named is the one to keep.
261
+ #
262
+ # It used to keep :bare_hyphen and relabel every other cause,
263
+ # so one error said two things: the message naming an unknown
264
+ # colour while the code and the hint talked about spaces. A
265
+ # caller acting on the code — which is what these are for —
266
+ # was sent to fix what was not wrong.
267
+ raise e unless space_is_the_cause?(token_r.join, parent)
219
268
 
220
269
  raise RSTError.new(e.message,
221
270
  code: :label_split,
@@ -92,8 +92,11 @@ module RSyntaxTree
92
92
 
93
93
  extra_lines = @extra_lines.join("\n")
94
94
 
95
- as2 = @global[:h_gap_between_nodes] * 1.0
96
- as4 = as2 * 3
95
+ # Rounded like the stroke widths are: the arithmetic leaves float dust
96
+ # (13.600000000000001) in an attribute of every figure, and the SVG is a
97
+ # deliverable people open in editors.
98
+ as2 = (@global[:h_gap_between_nodes] * 1.0).round(3)
99
+ as4 = (as2 * 3).round(3)
97
100
  # The hatch density follows the type size the way the enclosure it
98
101
  # fills does: the cell is 10/32 of the font size, the line 4/32 —
99
102
  # the ratios the absolute 10 and 4 had at the default size.
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module RSyntaxTree
4
- VERSION = "1.13.2"
4
+ VERSION = "1.14.0"
5
5
  end
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: 1.13.2
4
+ version: 1.14.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Yoichiro Hasebe