rsyntaxtree 2.4.1 → 2.6.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 +4 -4
- data/CHANGELOG.md +147 -540
- data/CITATION.cff +2 -2
- data/README.md +2 -1
- data/bin/rsyntaxtree +6 -3
- data/lib/rsyntaxtree/base_graph.rb +105 -30
- data/lib/rsyntaxtree/element.rb +1 -1
- data/lib/rsyntaxtree/elementlist.rb +95 -0
- data/lib/rsyntaxtree/json_graph.rb +27 -49
- data/lib/rsyntaxtree/notation_core.md +2 -1
- data/lib/rsyntaxtree/notation_examples.md +57 -2
- data/lib/rsyntaxtree/svg_graph.rb +219 -76
- data/lib/rsyntaxtree/tikz_generator.rb +12 -1
- data/lib/rsyntaxtree/version.rb +1 -1
- data/lib/rsyntaxtree.rb +20 -10
- data/rsyntaxtree.gemspec +2 -2
- metadata +1 -2
- data/.dockerignore +0 -5
data/CHANGELOG.md
CHANGED
|
@@ -1,684 +1,291 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [2.6.0] - 2026-11-12
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
- `leafstyle: dashed` (`-l dashed`): the line down to each word dashed, every line between nodes solid
|
|
7
|
+
- Gallery: each example lists its leaf alignment, and its number can be found with the browser's search
|
|
8
|
+
|
|
9
|
+
### Fixed
|
|
10
|
+
- Two movement paths that meet at one label no longer cross, and run on one level when nothing else is in the way
|
|
11
|
+
|
|
12
|
+
## [2.5.0] - 2026-11-04
|
|
13
|
+
|
|
14
|
+
### Added
|
|
15
|
+
- `leaf_align` (`--leaf-align`): the leaves on one row, by lowering `words` or `subtrees` (#16, thanks @jasperandrew)
|
|
16
|
+
|
|
17
|
+
### Fixed
|
|
18
|
+
- An arrowhead at the lower end of a movement path no longer sits against the corner
|
|
19
|
+
- A movement path no longer runs through a label that stands farther out than its two ends
|
|
20
|
+
- A movement path in a bottom-to-top tree runs above the words instead of through the tree
|
|
21
|
+
- Polyline rails no longer step where a child is a `<>` joint, or between labels drawn bottom to top
|
|
22
|
+
- A connector to a single child no longer leans by half a pixel
|
|
23
|
+
|
|
3
24
|
## [2.4.1] - 2026-09-02
|
|
4
25
|
|
|
5
26
|
### Fixed
|
|
6
|
-
-
|
|
7
|
-
bottom. A row aligns its labels at the top, so a tall one — a feature
|
|
8
|
-
matrix, a two-line label — reaches far below the short ones beside it. The
|
|
9
|
-
downward connector took the row's shared bottom for its upper end, so a
|
|
10
|
-
short node's line began at the tall neighbour's depth: a gap opened under
|
|
11
|
-
the label, and a polyline's branch flattened into a rule above the
|
|
12
|
-
children. No committed figure changes; the effect shows only where a row
|
|
13
|
-
mixes label heights.
|
|
27
|
+
- Connectors from a short node start at its own bottom, not below a taller label in the same row
|
|
14
28
|
|
|
15
29
|
## [2.4.0] - 2026-09-02
|
|
16
30
|
|
|
17
31
|
### Added
|
|
18
|
-
- `RSyntaxTree.escape(text, as:, hyphen:, apostrophe:)
|
|
19
|
-
|
|
20
|
-
not choose. The context (`:word`, `:phrase`, `:label`, `:cell`) decides what
|
|
21
|
-
whitespace means; the hyphen mode has to be given because no one spelling of
|
|
22
|
-
a hyphen serves both; `apostrophe: :keep` keeps a straight apostrophe. The
|
|
23
|
-
test draws every result and reads the text back, so the rules are exercised
|
|
24
|
-
rather than restated. The one text with no spelling under `hyphen: literal`
|
|
25
|
-
— a line of nothing but hyphens, which is the rule — raises `ArgumentError`.
|
|
26
|
-
- `\'` keeps a straight apostrophe, which the notation otherwise sets as a
|
|
27
|
-
curly one. `\@` is an at sign.
|
|
32
|
+
- `RSyntaxTree.escape(text, as:, hyphen:, apostrophe:)`: notation that draws as the given text
|
|
33
|
+
- `\'` for a straight apostrophe and `\@` for an at sign
|
|
28
34
|
|
|
29
35
|
### Fixed
|
|
30
|
-
- `\+` before digits is a plus sign
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
movement path.
|
|
34
|
-
- A label containing a backslash could lose characters in the drawing. The
|
|
35
|
-
text was placed into the SVG as a replacement string, which Ruby reads for
|
|
36
|
-
backreferences: `\+` and `\'` were two of them.
|
|
37
|
-
- An escaped character the tokenizer did not know (`\'`, `\@`) lost its
|
|
38
|
-
backslash before the markup was read.
|
|
36
|
+
- `\+` before digits is a plus sign (labels such as "C++11" no longer start a movement path)
|
|
37
|
+
- Labels containing a backslash could lose characters in the drawing
|
|
38
|
+
- Unknown escapes (`\'`, `\@`) lost their backslash before markup was read
|
|
39
39
|
|
|
40
40
|
## [2.3.0] - 2026-09-01
|
|
41
41
|
|
|
42
42
|
### Added
|
|
43
|
-
- `RSTError::CODES
|
|
44
|
-
keyed by code — one that translates the diagnosis, or tallies what kinds of
|
|
45
|
-
mistake a writer makes — needs the whole set rather than the codes it has
|
|
46
|
-
happened to see, and until now that set could only be recovered by reading
|
|
47
|
-
five files and the repair table. The list only grows: a published code is
|
|
48
|
-
not renamed or removed.
|
|
43
|
+
- `RSTError::CODES`: the complete list of error codes (codes are only ever added)
|
|
49
44
|
|
|
50
45
|
### Fixed
|
|
51
|
-
- Whitespace
|
|
52
|
-
|
|
53
|
-
`internal_error`, telling the caller that their own fixable input was the
|
|
54
|
-
library's fault.
|
|
55
|
-
- A bracketless input of a single character draws. The tokenizer counted its
|
|
56
|
-
cursor as exhausted one character early, so `A`, and `<>` once it is one
|
|
57
|
-
whitespace block, produced no tokens at all — though the manual has always
|
|
58
|
-
said a label on its own draws as one leaf.
|
|
46
|
+
- Whitespace-only input reported as empty input instead of `internal_error`
|
|
47
|
+
- A single character without brackets draws as one leaf
|
|
59
48
|
|
|
60
49
|
## [2.2.0] - 2026-09-01
|
|
61
50
|
|
|
62
51
|
### Changed
|
|
63
|
-
- Validation reports every error
|
|
64
|
-
An input with three bad labels lists all three in the `errors` array of
|
|
65
|
-
the JSON diagnosis, so one round of fixes covers them. The stages are
|
|
66
|
-
ordered — options, bracket structure, labels, whole-tree checks — and a
|
|
67
|
-
mistake stops the later stages, with a `note` saying that fixing what is
|
|
68
|
-
listed may reveal more; nothing is reported whose appearance is an
|
|
69
|
-
artifact of an earlier mistake. Duplicate failures collapse to one entry
|
|
70
|
-
and the list stops at twenty. The schema is unchanged
|
|
71
|
-
(`rsyntaxtree.error/1`): the same array, more of it.
|
|
52
|
+
- Validation reports every error in a stage, not only the first (up to 20; schema unchanged)
|
|
72
53
|
|
|
73
54
|
### Added
|
|
74
|
-
- `RSGenerator.diagnose(text, options)` returns the full diagnosis as a
|
|
75
|
-
hash — what `--validate` prints — for programmatic callers.
|
|
76
|
-
`check_data` keeps its contract of raising the first error.
|
|
55
|
+
- `RSGenerator.diagnose(text, options)` returns the full diagnosis as a hash
|
|
77
56
|
|
|
78
57
|
## [2.1.0] - 2026-08-29
|
|
79
58
|
|
|
80
59
|
### Changed
|
|
81
|
-
-
|
|
82
|
-
|
|
83
|
-
of the same initials, and called itself an interchange format when only
|
|
84
|
-
one tool had ever written or read it. It remains an accepted alias — the
|
|
85
|
-
CLI says so on stderr — until 3.0. The document now identifies itself in a
|
|
86
|
-
top-level `format` object (`name: "rsyntaxtree-json"`, schema 0.4.0) in
|
|
87
|
-
place of the `lsif` key.
|
|
60
|
+
- JSON output renamed from `lsif` to `json` (`-f json`, `syntree.json`); `lsif` remains an alias until 3.0
|
|
61
|
+
- JSON documents carry a top-level `format` object (`rsyntaxtree-json`, schema 0.4.0) in place of `lsif`
|
|
88
62
|
|
|
89
63
|
### Added
|
|
90
|
-
-
|
|
91
|
-
tab stops, rules as rows of their own, and a matrix inside a cell
|
|
92
|
-
recursing. It used to arrive as an empty segment marked "matrix", its
|
|
93
|
-
attribute-value pairs recoverable only by re-parsing the raw label.
|
|
64
|
+
- Feature matrices in the JSON output carry their rows and cells
|
|
94
65
|
|
|
95
66
|
## [2.0.0] - 2026-08-28
|
|
96
67
|
|
|
97
|
-
The removals announced in 1.10.0 and 1.12.0, and the fixes that came out of
|
|
98
|
-
looking at what was left. Every figure in the gallery draws exactly as it did.
|
|
99
|
-
|
|
100
68
|
### Removed
|
|
101
|
-
- JPG and GIF output
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
format is. Use `-f png`.
|
|
105
|
-
- The RMagick dependency, and with it ImageMagick. A machine that installs
|
|
106
|
-
this gem no longer needs ImageMagick's headers to build one, and the gem
|
|
107
|
-
now asks for four libraries instead of five.
|
|
108
|
-
- The deprecated aliases, which a major release is the moment to drop:
|
|
109
|
-
`symmetrize` and its `-y` flag (say `tidy: symmetric`), `tidy_spacing`
|
|
110
|
-
(say `hspacing`), the undocumented `tidy_nest`, and `nothing`'s
|
|
111
|
-
undocumented spelling `none` in `leafstyle`. Each is refused by name and
|
|
112
|
-
told what replaced it. An unknown option is passed over in silence, since
|
|
113
|
-
a caller may hand its own parameters through, and a removed one read that
|
|
114
|
-
way would have handed back a different figure without a word.
|
|
115
|
-
- `symmetrize` from the LSIF `meta.source.params` block. The layout scale it
|
|
116
|
-
duplicated, `tidy`, is written there already.
|
|
117
|
-
|
|
118
|
-
### Fixed
|
|
119
|
-
- A triangle drawn bottom to top pointed the wrong way. The shape spans the
|
|
120
|
-
child's text and points at the parent, and which way that is depends on
|
|
121
|
-
which of the two sits higher — the question the connectors ask and the
|
|
122
|
-
triangle did not. Bottom to top the figure folded through itself: the base
|
|
123
|
-
struck through the leaf and the apex through the node. No gallery figure
|
|
124
|
-
carries one, because every bottom-to-top example is a derivation, which
|
|
125
|
-
draws rules instead of connectors.
|
|
126
|
-
- Every label now keeps the same air above it as below it. The connector
|
|
127
|
-
endpoints were measured from the layout box, whose edges sit unevenly
|
|
128
|
-
around the ink, so every figure carried a little more space under each
|
|
129
|
-
label than over it — visibly once a figure was tilted. The enclosures
|
|
130
|
-
were built with symmetric clearances all along; the plain labels now get
|
|
131
|
-
what the boxes always had. Nearly every gallery figure changes by a few
|
|
132
|
-
pixels of line length; no label, no position and no size moves.
|
|
133
|
-
- A movement rail could reach past the right edge of a left-to-right
|
|
134
|
-
canvas and be cut off at it: the rail grows the canvas as it routes, and
|
|
135
|
-
the width it grew — unlike the height — was then recomputed from the
|
|
136
|
-
elements alone. Four pixels at the default spacing, twenty-four at
|
|
137
|
-
hspacing 0.5.
|
|
138
|
-
- A rule written `---` (or `===` for a double rule) was refused inside a
|
|
139
|
-
`#( … #)` matrix, though it was drawn in every other kind of label. Two
|
|
140
|
-
hyphens and four were accepted there and three were not — a distinction
|
|
141
|
-
nothing could explain. The matrix grammar had no rule for it and the
|
|
142
|
-
matrix renderer dropped every row that was not text.
|
|
143
|
-
- The bracket of a matrix that followed something in the same cell was drawn
|
|
144
|
-
on top of it: `AGR |1| [ … ]`, which is how a shared value is written, put
|
|
145
|
-
the right edge of the tag and the left edge of the bracket on the same
|
|
146
|
-
coordinate exactly. A block now keeps as much room in front of it as the
|
|
147
|
-
bracket keeps inside it.
|
|
148
|
-
- In a left-to-right tree, `hspacing` and `vheight` both moved the width and
|
|
149
|
-
nothing moved the height. The layout replaces the gap that separates
|
|
150
|
-
sisters with one of its own and was not scaling it by `hspacing`, so a
|
|
151
|
-
left-to-right figure could be made wider but never shorter.
|
|
152
|
-
- `storoke-width` in the style of every text element of every SVG. Renderers
|
|
153
|
-
ignored the misspelling, so nothing ever looked wrong.
|
|
69
|
+
- JPG and GIF output, and with them the RMagick and ImageMagick dependency
|
|
70
|
+
- Deprecated aliases `symmetrize` (`-y`), `tidy_spacing`, `tidy_nest` and `leafstyle: none`
|
|
71
|
+
- `symmetrize` from the LSIF `meta.source.params` block
|
|
154
72
|
|
|
155
73
|
### Added
|
|
156
|
-
- `shear`: the
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
shades coming out parallelograms on their own, and nothing able to newly
|
|
160
|
-
touch or cross. The plane is fill without an edge — a region shade is
|
|
161
|
-
bounded because it marks one part of a figure off from the rest, and a
|
|
162
|
-
line round the whole drawing would read as a frame. `shear_plane` turns
|
|
163
|
-
it off or gives it a colour, and a transparent background takes it away
|
|
164
|
-
for you: a clear background is asked for in order to lay the figure over
|
|
165
|
-
something else, and a sheet under it is what would defeat that.
|
|
166
|
-
TikZ refuses a sheared figure the way it refuses a derivation.
|
|
167
|
-
- `vmargin`: the clearance between a label and its connectors, the same
|
|
168
|
-
above and below, measured from the ink its row actually contains — a row
|
|
169
|
-
of capitals pays nothing for descenders nobody wrote, and the ends of a
|
|
170
|
-
row's connectors stay level. From 0.1 to 1.0; at nothing at all a node's
|
|
171
|
-
box stops holding a label that draws its own shape.
|
|
172
|
-
- Three gallery examples, in two new categories: the Indo-European family
|
|
173
|
-
tree (Historical Linguistics), where the region shade groups branches
|
|
174
|
-
rather than marking a c-command domain; type-driven semantic composition
|
|
175
|
-
(Formal Semantics); and a tree of typed feature structures with structure
|
|
176
|
-
sharing (Formal Grammar), which is the figure the matrix rule was missing.
|
|
74
|
+
- `shear` and `shear_plane`: tilt the figure and draw the plane it lies on
|
|
75
|
+
- `vmargin`: clearance between a label and its connectors (0.1–1.0)
|
|
76
|
+
- Gallery examples: Indo-European family tree, type-driven semantic composition, typed feature structures
|
|
177
77
|
|
|
178
78
|
### Changed
|
|
179
|
-
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
-
|
|
191
|
-
movement rail — and moves the direction, `vmargin` and `shear` among its
|
|
192
|
-
settings, and asks of every triangle that it have an area. Each of the two
|
|
193
|
-
defects above lived in a figure the sweep did not draw, at a direction it
|
|
194
|
-
did not set: the settings alone could not have found either, and a
|
|
195
|
-
triangle folded flat passes every other check there is.
|
|
196
|
-
- The manuals say what TikZ output does with what it cannot draw: it drops
|
|
197
|
-
it rather than refusing, so a label that is a matrix arrives with its
|
|
198
|
-
cells run together on one line.
|
|
79
|
+
- A removed option is refused with its replacement named
|
|
80
|
+
- Every option listed in the README and the notation reference
|
|
81
|
+
- Manuals describe what TikZ output drops
|
|
82
|
+
|
|
83
|
+
### Fixed
|
|
84
|
+
- Triangles pointed the wrong way in bottom-to-top trees
|
|
85
|
+
- Labels keep the same space above as below
|
|
86
|
+
- Movement rails cut off at the right edge of left-to-right figures
|
|
87
|
+
- `---` and `===` rules refused inside `#( … #)` matrices
|
|
88
|
+
- Matrix bracket drawn over the content before it in the same cell
|
|
89
|
+
- `hspacing` and `vheight` both changed the width of left-to-right trees
|
|
90
|
+
- Misspelled `storoke-width` in SVG text styles
|
|
199
91
|
|
|
200
92
|
### Migration
|
|
201
|
-
- `format: "jpg"` / `"gif"` → `"png"
|
|
202
|
-
- `symmetrize: "on"` → `tidy: "symmetric"
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
- Everything else — every other option, and every piece of notation — is
|
|
206
|
-
unchanged.
|
|
93
|
+
- `format: "jpg"` / `"gif"` → `"png"`
|
|
94
|
+
- `symmetrize: "on"` → `tidy: "symmetric"`
|
|
95
|
+
- `tidy_spacing: n` → `hspacing: n`
|
|
96
|
+
- `leafstyle: "none"` → `"nothing"`
|
|
207
97
|
|
|
208
98
|
## [1.14.0] - 2026-08-27
|
|
209
99
|
|
|
210
100
|
### Added
|
|
211
|
-
-
|
|
212
|
-
|
|
213
|
-
line each with the notation beside it, then the options. Both manuals open
|
|
214
|
-
with the same list, each row pointing at the section that explains it. A test
|
|
215
|
-
reads the feature set out of the grammar itself and draws every sample, so a
|
|
216
|
-
feature the grammar gains with no row in the documents fails the build, and a
|
|
217
|
-
sample that stops meaning what it says fails with it.
|
|
218
|
-
- The changelog is on the documentation site, at /changelog, built from
|
|
219
|
-
CHANGELOG.md and linked from the manuals and the README.
|
|
101
|
+
- One-page notation reference (`--notation`), with the same feature list at the top of both manuals
|
|
102
|
+
- Changelog page on the documentation site (/changelog)
|
|
220
103
|
|
|
221
104
|
### Changed
|
|
222
|
-
-
|
|
223
|
-
|
|
224
|
-
-
|
|
225
|
-
accepts and draws as something other than what was meant. A mistake the tool
|
|
226
|
-
refuses is the error message's job, and its card has come down; the warning
|
|
227
|
-
about parentheses, which the Penn Treebank conversion had made false, tells
|
|
228
|
-
the truth again.
|
|
229
|
-
- The arrow markers' dimensions are rounded; the defs of every SVG carried
|
|
230
|
-
float dust in an attribute.
|
|
105
|
+
- Changelog dates taken from the git tags
|
|
106
|
+
- Pitfalls section limited to inputs that draw differently from what was meant
|
|
107
|
+
- Arrow-marker dimensions rounded in SVG output
|
|
231
108
|
|
|
232
109
|
### Fixed
|
|
233
|
-
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
but the label is read before the tree is built, and the name was taken out
|
|
237
|
-
anyway and then had no rule to be drawn beside. `[A\tfoo]` drew "A foo" with
|
|
238
|
-
the option off and "A" with it on. The label is put back once the tree is
|
|
239
|
-
known.
|
|
240
|
-
- A mistake inside a node's label keeps the name of what is wrong with it. The
|
|
241
|
-
first raw space splits a token into a label and its children, and when the
|
|
242
|
-
label would not parse, every cause but one was relabelled "a raw space split
|
|
243
|
-
this" — so the message named an unknown colour while the code and the hint
|
|
244
|
-
talked about spaces, and a caller acting on the code was sent to fix what was
|
|
245
|
-
not wrong. Which story is right is now asked of the parser rather than
|
|
246
|
-
guessed: the token is put back together with its spaces written as the
|
|
247
|
-
notation writes them, and if it reads, the space was the cause.
|
|
248
|
-
- A hex colour is three digits or six, which is what every message about colour
|
|
249
|
-
here already said. The grammar asked for three to six, so four and five
|
|
250
|
-
parsed, passed the validator — which does not look at a value beginning with
|
|
251
|
-
`#` — and reached librsvg, which cannot read them and draws the label black
|
|
252
|
-
without reporting it.
|
|
110
|
+
- `derivation` dropped the second column of a childless node's label
|
|
111
|
+
- Errors in a label split by a raw space now name the actual cause
|
|
112
|
+
- Hex colours accept three or six digits only
|
|
253
113
|
|
|
254
114
|
## [1.13.2] - 2026-08-27
|
|
255
115
|
|
|
256
116
|
### Fixed
|
|
257
|
-
-
|
|
258
|
-
|
|
259
|
-
runs round each turn instead of restarting at it, and the arrowhead is the end
|
|
260
|
-
of the stroke rather than a marker on whichever line finished last. The radius
|
|
261
|
-
is held down to half of each run it joins, so a short leg cannot be swallowed
|
|
262
|
-
by its own turn, and to the length of an arrowhead where there is one, so the
|
|
263
|
-
head is never drawn onto the curve. Three gallery figures carry paths and
|
|
264
|
-
change with it.
|
|
265
|
-
- Digits are set in the text face again on machines that have a colour emoji
|
|
266
|
-
font. The font chains named emoji families by name, and asking fontconfig for
|
|
267
|
-
one is asking for the generic `emoji` family, whose preference list fontconfig
|
|
268
|
-
then prepends to the whole pattern with a strong binding — so the emoji face
|
|
269
|
-
arrived ahead of the Noto text faces rather than behind them. A colour emoji
|
|
270
|
-
font carries the ASCII digits, for keycap sequences, so on an ordinary Linux
|
|
271
|
-
desktop `[N 20]` came out in the emoji face at more than twice the width.
|
|
272
|
-
Measurement and drawing read the same chain, so the figure held together; it
|
|
273
|
-
was simply not the figure the same input gives elsewhere. No emoji family is
|
|
274
|
-
named now: a codepoint no named family covers reaches fontconfig's own
|
|
275
|
-
fallback, which is the path this was duplicating. Emoji draw as before, and
|
|
276
|
-
the gallery is unchanged to the pixel — every raster figure is byte-identical
|
|
277
|
-
and the SVGs differ only in the family list they carry.
|
|
117
|
+
- Movement paths drawn as one stroke with rounded corners
|
|
118
|
+
- Digits drawn in a colour emoji font on systems that have one
|
|
278
119
|
|
|
279
120
|
## [1.13.1] - 2026-08-27
|
|
280
121
|
|
|
281
122
|
### Fixed
|
|
282
|
-
- `^`
|
|
283
|
-
|
|
284
|
-
`[NP ^cats]` — and the documentation, the notation reference and the gallery
|
|
285
|
-
all use both, but only the first was drawn: the second lost its caret to the
|
|
286
|
-
parser and then a bar was drawn under it. The two now produce the same figure
|
|
287
|
-
in every connector style, and LSIF records the edge as a triangle. Three
|
|
288
|
-
gallery figures change accordingly, each toward what it was written to show.
|
|
289
|
-
- An option given as an empty string is read as an option not given, rather
|
|
290
|
-
than as a value no list contains. An HTML form posts a field for every
|
|
291
|
-
control it carries, and a control with nothing selected posts the empty
|
|
292
|
-
string, so a form that has outlived one of its own controls sends that field
|
|
293
|
-
empty alongside the rest. Since option validation arrived in 1.11.0 that
|
|
294
|
-
failed the whole request: the web UI's Download buttons answered 500 for
|
|
295
|
-
every input, because the form still read a `format` select the page no longer
|
|
296
|
-
had. A value that is actually wrong is still rejected.
|
|
123
|
+
- `^` on a leaf's own text (`[NP ^cats]`) draws a triangle, as `[^NP cats]` does
|
|
124
|
+
- Options given as empty strings treated as not given (fixes the web UI's Download buttons)
|
|
297
125
|
|
|
298
126
|
## [1.13.0] - 2026-08-24
|
|
299
127
|
|
|
300
128
|
### Added
|
|
301
|
-
-
|
|
302
|
-
|
|
303
|
-
than with a line to each daughter. `derivation` draws the rules and
|
|
304
|
-
`direction: btt` turns the tree over; together they draw a CCG derivation,
|
|
305
|
-
and `derivation` on its own marks the spans of an ordinary tree. The name of each step rides in the label after a
|
|
306
|
-
column break and is set beside the end of its rule. A derivation runs down
|
|
307
|
-
the page and is drawn with its rules, so `direction: ltr` and hiding the
|
|
308
|
-
default connectors are refused rather than approximated.
|
|
309
|
-
- `direction: btt`, the layout turned over, leaves first.
|
|
129
|
+
- `derivation`: one rule across each node's daughters, with rule names (CCG style with `direction: btt`)
|
|
130
|
+
- `direction: btt`: bottom-to-top layout
|
|
310
131
|
|
|
311
132
|
### Fixed
|
|
312
|
-
- Connectors
|
|
313
|
-
have when the root is at the top, so every line ran from above the daughter,
|
|
314
|
-
through its label and the mother's, to below the mother.
|
|
133
|
+
- Connectors in bottom-to-top layout
|
|
315
134
|
|
|
316
135
|
## [1.12.0] - 2026-08-22
|
|
317
136
|
|
|
318
|
-
Everything needed to write this notation is now available as text, built from
|
|
319
|
-
the files the tool itself reads, and a refusal says where that text is.
|
|
320
|
-
|
|
321
137
|
### Added
|
|
322
|
-
- `--examples` prints every
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
- The site carries the same material as plain text for a reader that can fetch
|
|
326
|
-
a URL but cannot run a command: `llms.txt` and `llms-full.txt`, the second
|
|
327
|
-
holding the reference, the manual and every example in one file. Both are
|
|
328
|
-
generated from their sources, and a test fails if they fall behind.
|
|
329
|
-
- A refusal names where the notation is written down, once, alongside the
|
|
330
|
-
cause and the fix. A hint repairs the mistake in front of it and says
|
|
331
|
-
nothing about the rest, which is not enough for a caller that was guessing.
|
|
138
|
+
- `--examples` prints every gallery example with its options
|
|
139
|
+
- `llms.txt` and `llms-full.txt` on the documentation site
|
|
140
|
+
- Error messages point to the notation reference
|
|
332
141
|
|
|
333
142
|
### Changed
|
|
334
|
-
-
|
|
335
|
-
|
|
336
|
-
East Asian pair draws a full em wide, wider than a capital, and had spread
|
|
337
|
-
through the gallery and into the repair that corrects ASCII brackets. Both
|
|
338
|
-
pairs still parse; documents written before this are unaffected.
|
|
339
|
-
- Two feature-structure figures are redrawn at the narrower bracket.
|
|
143
|
+
- Recommended angle brackets are U+27E8/U+27E9 (U+3008/U+3009 still parse)
|
|
144
|
+
- Two feature-structure figures redrawn with the narrower bracket
|
|
340
145
|
|
|
341
146
|
### Fixed
|
|
342
|
-
- `--notation` and `--examples`
|
|
343
|
-
meant waiting on a pipe that never closes when stdin is not a terminal,
|
|
344
|
-
which is how a script reaches them.
|
|
147
|
+
- `--notation` and `--examples` no longer wait on stdin
|
|
345
148
|
|
|
346
149
|
## [1.11.0] - 2026-08-21
|
|
347
150
|
|
|
348
|
-
Every input the tool accepts now draws, and every input it refuses says why.
|
|
349
|
-
Line thickness follows the type size, so figures drawn at any font size keep
|
|
350
|
-
the same balance between text and rules — existing figures come out about a
|
|
351
|
-
fifth lighter than before.
|
|
352
|
-
|
|
353
151
|
### Added
|
|
354
|
-
- `--validate
|
|
355
|
-
|
|
356
|
-
-
|
|
357
|
-
|
|
358
|
-
-
|
|
359
|
-
|
|
360
|
-
is unchanged. Each cause is confirmed by applying its fix and parsing
|
|
361
|
-
again, so a named cause is one whose fix is known to work.
|
|
362
|
-
- A label may be nothing but a matrix: `[#(HEAD\tnoun#)]` had no spelling
|
|
363
|
-
before, since the enclosure rule took the `#` first.
|
|
364
|
-
- `-f tikz` on the command line, which the documentation had offered while
|
|
365
|
-
the CLI rejected it. TikZ output also carries the line width, which it
|
|
366
|
-
had been accepting and dropping.
|
|
367
|
-
- A gallery figure and a heading of its own for levelling the terminals with
|
|
368
|
-
`<>` joints.
|
|
152
|
+
- `--validate`: check input without drawing (JSON diagnosis on stdout, verdict in the exit code)
|
|
153
|
+
- `--notation`: short notation reference, shipped with the gem
|
|
154
|
+
- Errors carry a code, location, one-line fix and retryable flag
|
|
155
|
+
- A label may be a matrix alone (`[#(HEAD\tnoun#)]`)
|
|
156
|
+
- `-f tikz` in the CLI; TikZ output carries the line width
|
|
157
|
+
- Gallery figure for levelling terminals with `<>` joints
|
|
369
158
|
|
|
370
159
|
### Changed
|
|
371
|
-
- Line width
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
- On/off options accept every spelling of off. `mirror: "no"` reversed the
|
|
378
|
-
tree and `transparent: "0"` cut the background away, because anything but
|
|
379
|
-
`"off"` and `"false"` was read as on.
|
|
380
|
-
- Option values are checked against the values the option takes. A value
|
|
381
|
-
nobody defines was taken and read as something else — `direction:
|
|
382
|
-
"left-to-right"` laid the tree out top to bottom. The CLI has always
|
|
383
|
-
refused these; the library did not, which left the web interface and other
|
|
384
|
-
programmatic callers unguarded.
|
|
385
|
-
- Colour names are checked against the CSS colour names. A name nobody
|
|
386
|
-
defines passed validation and drew black.
|
|
387
|
-
- Penn Treebank input converts in the library, not only in the CLI. Other
|
|
388
|
-
callers got no conversion and no error: `(S (NP the dog))` drew as one
|
|
389
|
-
leaf containing that text.
|
|
390
|
-
- Font sizes go down to 6, which the web interface has always offered while
|
|
391
|
-
the documentation said 8.
|
|
160
|
+
- Line width relative to font size (`0.5`–`3.0`, `1` = 5% of the font size); figures about a fifth lighter
|
|
161
|
+
- On/off options accept every spelling of off (`no`, `0`, …)
|
|
162
|
+
- Option values validated in the library, not only in the CLI
|
|
163
|
+
- Colour names checked against the CSS colour names
|
|
164
|
+
- Penn Treebank conversion in the library
|
|
165
|
+
- Minimum font size 6
|
|
392
166
|
|
|
393
167
|
### Fixed
|
|
394
|
-
- Validation
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
-
|
|
399
|
-
writer to fix a `#` that was never the problem.
|
|
400
|
-
- A left-to-right matrix drew its brackets on top of the attribute names.
|
|
401
|
-
- Text in front of a tree crashed symmetrization, and an empty argument was
|
|
402
|
-
read as a path to the current directory.
|
|
403
|
-
- Overline was documented as missing from PNG output. It has been there.
|
|
168
|
+
- Validation passed input that drawing then refused
|
|
169
|
+
- Malformed colour reported as an unclosed enclosure
|
|
170
|
+
- Matrix brackets over attribute names in left-to-right trees
|
|
171
|
+
- Crash on text before a tree; empty argument read as a path
|
|
172
|
+
- Documentation said overline was missing from PNG output
|
|
404
173
|
|
|
405
174
|
## [1.10.0] - 2026-08-19
|
|
406
175
|
|
|
407
|
-
A transitional release ahead of 2.0, which drops JPG/GIF output and the
|
|
408
|
-
RMagick dependency.
|
|
409
|
-
|
|
410
176
|
### Deprecated
|
|
411
|
-
- JPG and GIF output
|
|
412
|
-
requested, and the documentation marks both as deprecated. JPEG blurs
|
|
413
|
-
line art and GIF has no use case here — use PNG. Both formats are
|
|
414
|
-
removed in 2.0.
|
|
177
|
+
- JPG and GIF output (removed in 2.0)
|
|
415
178
|
|
|
416
179
|
### Changed
|
|
417
|
-
-
|
|
418
|
-
TikZ and LSIF work without ImageMagick installed; only a JPG or GIF
|
|
419
|
-
request needs RMagick, and a request without it reports the missing
|
|
420
|
-
dependency as a regular input error instead of a bare `LoadError`.
|
|
180
|
+
- RMagick loaded only when JPG or GIF is requested
|
|
421
181
|
|
|
422
182
|
### Fixed
|
|
423
|
-
- `
|
|
424
|
-
string literal crashed inside the error class with a `FrozenError`. Every
|
|
425
|
-
file here carries `frozen_string_literal`, which made the working form the
|
|
426
|
-
unobvious one.
|
|
183
|
+
- `FrozenError` when raising `RSTError` with a string literal
|
|
427
184
|
|
|
428
185
|
## [1.9.0] - 2026-08-19
|
|
429
186
|
|
|
430
187
|
### Added
|
|
431
|
-
- `hyphen: literal
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
-
|
|
436
|
-
|
|
437
|
-
a feature path such as SYNSEM | LOCAL | CATEGORY | HEAD needs, and what
|
|
438
|
-
HPSG and LFG are written in. The nested matrix draws its own brackets and
|
|
439
|
-
lays out its own columns, and the rows after it clear its full height.
|
|
440
|
-
- `\t` in a label cuts the line into cells. Every line is cut at the same
|
|
441
|
-
points and each column is drawn at the width of its widest cell, so the
|
|
442
|
-
parts line up down the label. Together with the bracket enclosure and the
|
|
443
|
-
horizontal rule this gives attribute-value matrices — the feature structures
|
|
444
|
-
of HPSG, LFG and the like — without spacing each row by hand, which is how
|
|
445
|
-
the gallery's HPSG example used to do it.
|
|
446
|
-
- `color: gray`, a scheme that keeps node and leaf labels black and draws the
|
|
447
|
-
connectors, triangles and movement paths in grey. It is for diagrams whose
|
|
448
|
-
links outnumber their labels — an ontology, a network of constructions —
|
|
449
|
-
where a page of black lines buries the text. `grey` is accepted too.
|
|
450
|
-
- Gallery examples for two more frameworks: LFG (an annotated c-structure and
|
|
451
|
-
the f-structure it maps to, after Kaplan & Bresnan 1982 and Bresnan 2001)
|
|
452
|
-
and DRT (a discourse representation structure, after Kamp 1981).
|
|
453
|
-
- The example gallery scales each figure by its own width rather than by one
|
|
454
|
-
factor for all of them, so a small tree and a wide one are read at a similar
|
|
455
|
-
apparent size; a figure now fits its row instead of scrolling, loads lazily,
|
|
456
|
-
and carries an anchor of its own.
|
|
188
|
+
- `hyphen: literal`: a bare hyphen is a hyphen and `\-…\-` underlines
|
|
189
|
+
- Nested matrices with `#(` … `#)`
|
|
190
|
+
- `\t` splits a label into aligned columns, for attribute-value matrices
|
|
191
|
+
- `color: gray` (or `grey`): black labels with grey connectors and paths
|
|
192
|
+
- Gallery examples for LFG and DRT
|
|
193
|
+
- Gallery figures scaled by their own width and loaded lazily, each with an anchor
|
|
457
194
|
|
|
458
195
|
### Changed
|
|
459
|
-
-
|
|
460
|
-
|
|
461
|
-
standing a head taller than the numeral inside it, and each shape was
|
|
462
|
-
centred on its own glyph, so the box around `s` sat lower than the one
|
|
463
|
-
around `G`. A shape is now drawn at a fixed fraction of the font size,
|
|
464
|
-
centred on a capital, and grows only for content that will not fit. Every
|
|
465
|
-
figure with a boxed or circled label is redrawn.
|
|
466
|
-
- The SVG's declared width and height agree with its viewBox. They did not,
|
|
467
|
-
so every figure was scaled down by a few percent and letterboxed inside
|
|
468
|
-
its own canvas.
|
|
196
|
+
- Boxes and circles drawn at one size on one centre line
|
|
197
|
+
- SVG width and height match the viewBox
|
|
469
198
|
|
|
470
199
|
### Fixed
|
|
471
|
-
- TikZ export dropped
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
- LSIF records which of the two readings of a hyphen the input was parsed
|
|
477
|
-
under. It records the input verbatim, and the same string means different
|
|
478
|
-
things under the two, so a reader could not re-parse it.
|
|
479
|
-
- A line-type connection with only one end raised a NoMethodError from inside
|
|
480
|
-
the drawing instead of being reported as the input error it is.
|
|
481
|
-
- A line-type connection between two nodes was anchored a full inter-node gap
|
|
482
|
-
outside each of them, so the link fell short of both boxes where the gap was
|
|
483
|
-
wide and reached inside them where it was narrow. It now runs between the
|
|
484
|
-
boxes' own edges, a quarter of a gap short of each. The double arrowhead
|
|
485
|
-
keeps the shape it had but is sized to the link, instead of one fixed size
|
|
486
|
-
that spilled over both boxes on a short link. The same anchors are used in
|
|
487
|
-
left-to-right layout, where a link between siblings had been drawn diagonally
|
|
488
|
-
from the movement-path anchors and now runs straight between the facing
|
|
489
|
-
edges.
|
|
490
|
-
- Two nodes joined by a line-type connection are laid out far enough apart for
|
|
491
|
-
a full-size arrowhead between them. Where the layout had packed them closer
|
|
492
|
-
than the arrow is wide — the two leaves at the foot of the quicksort figure —
|
|
493
|
-
the arrow was drawn small to fit; now the pair is spread and the arrow keeps
|
|
494
|
-
its size. Only pairs that carry a link move, and only when they need to.
|
|
200
|
+
- TikZ export dropped the contents of nested matrices
|
|
201
|
+
- LSIF records the hyphen mode
|
|
202
|
+
- A one-ended line connection raised `NoMethodError`
|
|
203
|
+
- Line connections anchored to the facing box edges, with arrowheads sized to the link
|
|
204
|
+
- Nodes joined by a line connection spaced for a full-size arrowhead
|
|
495
205
|
|
|
496
206
|
## [1.8.2] - 2026-08-17
|
|
497
207
|
|
|
498
208
|
### Changed
|
|
499
|
-
- `tidy: high`
|
|
500
|
-
|
|
501
|
-
narrower than the level below it, applied to `medium` and `high` alike and
|
|
502
|
-
bound first in nearly every tree: across the 75 gallery examples the two
|
|
503
|
-
modes produced identical figures 70 times. The floor now applies to `medium`
|
|
504
|
-
only, leaving `high` free to trade even branch angles for width — 29 of the
|
|
505
|
-
75 examples now differ, by up to 19%. `off`, `low` and `medium` are
|
|
506
|
-
unchanged; `high`, like `symmetric` at the other end of the scale, is for
|
|
507
|
-
figures that ask for it.
|
|
508
|
-
- Mathematical alphanumerics (U+1D400–, such as the little *v* of *v*P) are
|
|
509
|
-
named in the family chains. Neither Noto Sans nor Noto Serif covers the
|
|
510
|
-
block, so the glyphs came from whatever the machine offered: Noto Sans Math
|
|
511
|
-
on Alpine, DejaVu Serif on Debian/Ubuntu, STIX Two Math on macOS. The serif
|
|
512
|
-
style now asks for a serif source first, so a serif tree no longer shows a
|
|
513
|
-
sans *v*. The Docker images install `font-dejavu` for it.
|
|
209
|
+
- `tidy: high` compresses further than `medium`
|
|
210
|
+
- Mathematical alphanumerics (U+1D400–) named in the font chains; serif trees use a serif source
|
|
514
211
|
|
|
515
212
|
### Fixed
|
|
516
|
-
-
|
|
517
|
-
|
|
518
|
-
to stderr and the exit status is 1.
|
|
519
|
-
- Dropped `Noto Sans Mono SemiCondensed` from the mono chain. It is a width
|
|
520
|
-
style of the variable Noto Sans Mono rather than a family of its own, and
|
|
521
|
-
resolved nowhere on macOS, Debian/Ubuntu or Alpine; the chain fell through
|
|
522
|
-
to `Noto Sans Mono`, which it now names directly.
|
|
213
|
+
- CLI errors go to stderr with exit status 1
|
|
214
|
+
- `Noto Sans Mono SemiCondensed` removed from the mono chain
|
|
523
215
|
|
|
524
216
|
## [1.8.1] - 2026-08-15
|
|
525
217
|
|
|
526
218
|
### Fixed
|
|
527
|
-
- Arabic
|
|
528
|
-
|
|
529
|
-
fallback, which is not the same font on every machine: on Alpine the Arabic
|
|
530
|
-
block was claimed by Noto Sans Math, which has the glyphs but no joining
|
|
531
|
-
rules, while on Debian/Ubuntu the same text fell to DejaVu Sans. The family
|
|
532
|
-
chains now name the scripts the gallery covers — Arabic (`Noto Sans Arabic`,
|
|
533
|
-
with `Noto Naskh Arabic` for the serif style), Hebrew, Devanagari, Thai and
|
|
534
|
-
Khmer — so machines that have those fonts installed produce the same shapes.
|
|
535
|
-
Mathematical alphanumerics (U+1D400–) are not named yet and still vary by
|
|
536
|
-
environment. Gallery example 067 (Arabic) was affected and has been
|
|
537
|
-
regenerated.
|
|
538
|
-
- Emoji were measured with one font and drawn with another where a colour
|
|
539
|
-
emoji font was installed: Pango selects `Noto Color Emoji`, but the
|
|
540
|
-
librsvg/Cairo pipeline does not rasterise its bitmap glyphs, so the drawing
|
|
541
|
-
fell back to whatever outline font happened to cover the codepoint. The
|
|
542
|
-
project's Docker images now install the monochrome Noto Emoji and leave the
|
|
543
|
-
colour build out.
|
|
219
|
+
- Arabic drawn as unjoined letterforms on some systems
|
|
220
|
+
- Emoji measured and drawn with different fonts where a colour emoji font was installed
|
|
544
221
|
|
|
545
222
|
### Changed
|
|
546
|
-
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
alphanumerics (used for the little *v* of *v*P).
|
|
550
|
-
- Documentation records how to override any of the named families with a
|
|
551
|
-
fontconfig alias, for users who prefer their own script fonts.
|
|
223
|
+
- Font chains name Arabic, Hebrew, Devanagari, Thai and Khmer families
|
|
224
|
+
- Docker images install Noto fonts for those scripts, with a fontconfig rule for Noto Sans Math
|
|
225
|
+
- Documentation on overriding font families with fontconfig
|
|
552
226
|
|
|
553
227
|
## [1.8.0] - 2026-08-15
|
|
554
228
|
|
|
555
229
|
### Added
|
|
556
|
-
- `tidy` layout scale
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
angles. Tidy never produces overlapping labels (collisions roll back).
|
|
564
|
-
- `mirror` option: flips the finished layout horizontally for the
|
|
565
|
-
right-to-left tree convention of Arabic/Hebrew syntax (composes with
|
|
566
|
-
`direction`).
|
|
567
|
-
- `hspacing` option: scales every horizontal gap in every layout mode — the
|
|
568
|
-
horizontal counterpart of `vheight`/connector height.
|
|
569
|
-
- Pass-through empty nodes: a node labeled only `<>` renders as an invisible
|
|
570
|
-
joint with the connector running continuously through it, so a `<>` chain
|
|
571
|
-
aligns a shallow leaf with deeper leaves without a broken line.
|
|
572
|
-
- Full CJK coverage in every font style: the family chains fall back to
|
|
573
|
-
Noto Sans/Serif/Mono CJK, so Hangul and simplified/traditional Han render
|
|
574
|
-
in all styles (the standalone Noto JP faces carry no Hangul).
|
|
575
|
-
- Example gallery: Multilingual category (the same UD-PUD sentence in nine
|
|
576
|
-
languages, constituency derived mechanically from the dependency
|
|
577
|
-
annotation; the Arabic example demonstrates `mirror`), a Morphology
|
|
578
|
-
category, and per-figure tidy settings across the whole gallery.
|
|
579
|
-
- CI on GitHub Actions (Ruby 3.2/3.4).
|
|
230
|
+
- `tidy` layout scale: `symmetric` | `off` | `low` | `medium` | `high`
|
|
231
|
+
- `mirror` option for right-to-left trees
|
|
232
|
+
- `hspacing` option for horizontal gaps
|
|
233
|
+
- Pass-through `<>` nodes for levelling leaves
|
|
234
|
+
- CJK coverage in every font style
|
|
235
|
+
- Gallery: Multilingual and Morphology categories
|
|
236
|
+
- CI on GitHub Actions (Ruby 3.2/3.4)
|
|
580
237
|
|
|
581
238
|
### Changed
|
|
582
|
-
- LSIF
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
-
|
|
586
|
-
`tidy: symmetric`; `tidy_spacing` is a deprecated alias of `hspacing`.
|
|
587
|
-
- `--direction` now owns the `-d` short flag (it had been auto-assigned to
|
|
588
|
-
`--hide-default-connectors`, so the documented `-d ltr` silently did
|
|
589
|
-
nothing). Every published short flag is now declared explicitly rather
|
|
590
|
-
than derived from the option set. One undocumented auto-assignment moved
|
|
591
|
-
as a result: `-e` was `--direction` in 1.7.0 and is `--version` here.
|
|
592
|
-
- The gem no longer bundles font files (38MB that were never opened at
|
|
593
|
-
runtime since the Pango migration): fonts resolve by family name through
|
|
594
|
-
fontconfig. See README for the system font packages. The dead `--font`
|
|
595
|
-
CLI option (its value was never read) is gone.
|
|
239
|
+
- LSIF records `geometry.mirror` and the layout settings in `meta.source.params`
|
|
240
|
+
- `symmetrize` (`-y`) and `tidy_spacing` deprecated
|
|
241
|
+
- `-d` is `--direction` (it had been taken by `--hide-default-connectors`)
|
|
242
|
+
- Font files no longer bundled; fonts resolve through fontconfig; `--font` removed
|
|
596
243
|
|
|
597
244
|
### Fixed
|
|
598
|
-
- Boolean options left at their defaults
|
|
599
|
-
when the caller passes only a partial parameter set (e.g. `tidy: off`
|
|
600
|
-
rendered as `symmetric` in the web UI).
|
|
245
|
+
- Boolean options left at their defaults misread as on with a partial parameter set
|
|
601
246
|
|
|
602
247
|
## [1.7.0] - 2026-08-13
|
|
603
248
|
|
|
604
249
|
### Changed
|
|
605
|
-
- Text
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
the font that actually draws them, which fixes off-center labels for scripts
|
|
609
|
-
the bundled fonts do not cover (e.g. Khmer, #14) without bundling per-script
|
|
610
|
-
fonts. Horizontal dimensions of the output may change slightly.
|
|
611
|
-
- Vertical rhythm is now derived deterministically from the font size
|
|
612
|
-
(1.4 x size, matching the previous Latin line height) and is identical
|
|
613
|
-
across scripts; the old engine spaced Japanese text 1.5x and WenQuanYi
|
|
614
|
-
1.25x, so mixed-language documents had inconsistent spacing.
|
|
615
|
-
- The font-family lists used in the SVG output and in measurement are now
|
|
616
|
-
defined in a single place (`FONT_FAMILIES` / `FontFamily`).
|
|
250
|
+
- Text measured with Pango instead of RMagick (fixes off-centre Khmer labels, #14)
|
|
251
|
+
- Line height fixed at 1.4 × font size for every script
|
|
252
|
+
- Font family lists defined in one place
|
|
617
253
|
|
|
618
254
|
### Added
|
|
619
|
-
- Runtime dependency on the `pango` gem
|
|
620
|
-
requirements: librsvg already depends on Pango.
|
|
255
|
+
- Runtime dependency on the `pango` gem
|
|
621
256
|
|
|
622
257
|
## [1.6.3] - 2026-07-19
|
|
623
258
|
|
|
624
259
|
### Fixed
|
|
625
|
-
- Packaged files no longer carry owner-only permissions
|
|
626
|
-
on-disk modes, so gems built from a checkout with `0600`/`0700` files shipped
|
|
627
|
-
a library unreadable — and a `rsyntaxtree` CLI unexecutable — by anyone but
|
|
628
|
-
the owner after `sudo gem install`. File modes are now normalized before the
|
|
629
|
-
gem is built: `0755` for commands (`bin/`, `exe/`) and shebang scripts, `0644`
|
|
630
|
-
for everything else. This also drops stray executable bits that the working
|
|
631
|
-
tree had picked up on data files (images, fonts, Markdown, CSS, library
|
|
632
|
-
sources).
|
|
260
|
+
- Packaged files no longer carry owner-only permissions
|
|
633
261
|
|
|
634
262
|
## [1.6.2] - 2026-06-26
|
|
635
263
|
|
|
636
264
|
### Fixed
|
|
637
|
-
- Region shade no longer touches the image edge
|
|
638
|
-
past the tree's natural extent (e.g. a deep enclosed/multi-line node): the
|
|
639
|
-
canvas now grows with a margin around the shaded plane.
|
|
265
|
+
- Region shade no longer touches the image edge
|
|
640
266
|
|
|
641
267
|
## [1.6.1] - 2026-06-26
|
|
642
268
|
|
|
643
269
|
### Improved
|
|
644
|
-
-
|
|
645
|
-
padding; bracket/rectangle enclosures are kept inside the plane; the incoming
|
|
646
|
-
parent connector stops just short of the plane (no overlap or touching); and
|
|
647
|
-
the margin is consistent between root and non-root regions. Works in both
|
|
648
|
-
top-to-bottom and left-to-right layouts (the connector-facing edge is the top
|
|
649
|
-
in TTB and the left in LTR, with symmetric padding on the other sides).
|
|
270
|
+
- Cleaner padding and connector clearance around region shades
|
|
650
271
|
|
|
651
272
|
### Added
|
|
652
|
-
- Example 065: nested
|
|
653
|
-
darker gray.
|
|
273
|
+
- Example 065: nested region shades
|
|
654
274
|
|
|
655
275
|
## [1.6.0] - 2026-06-25
|
|
656
276
|
|
|
657
277
|
### Added
|
|
658
|
-
- Region shade (`%` prefix)
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
`%` for a gray monochrome shade. Works in both TTB and LTR layouts and across
|
|
664
|
-
SVG/PNG/PDF/JPG/GIF.
|
|
665
|
-
- Region shade support in TikZ export (via `forest` `fit to=tree`) and in LSIF
|
|
666
|
-
node `style.region`. TikZ region colors (names and hex, including SVG/CSS
|
|
667
|
-
names like `lightblue` that xcolor lacks) are emitted as explicit RGB so the
|
|
668
|
-
output compiles.
|
|
669
|
-
- `\%` escape for a literal leading percent sign.
|
|
670
|
-
- Typographic apostrophe: a straight ASCII apostrophe (`'`) in a label is now
|
|
671
|
-
rendered as a curly apostrophe (`’`, U+2019) for smarter typography, e.g. the
|
|
672
|
-
X-bar prime in `T'`. Applied to all fonts and measured before layout so
|
|
673
|
-
spacing stays correct.
|
|
674
|
-
- Example 064: region shade for a c-command domain.
|
|
278
|
+
- Region shade (`%` prefix), coloured with `%@color:`
|
|
279
|
+
- Region shade in TikZ export and in LSIF (`style.region`)
|
|
280
|
+
- `\%` for a literal leading percent sign
|
|
281
|
+
- Straight apostrophes drawn as curly apostrophes (`’`)
|
|
282
|
+
- Example 064: region shade for a c-command domain
|
|
675
283
|
|
|
676
284
|
### Changed
|
|
677
|
-
- LSIF
|
|
285
|
+
- LSIF version 0.3.0
|
|
678
286
|
|
|
679
287
|
### Fixed
|
|
680
|
-
- Region shade on the root
|
|
681
|
-
SVG viewBox now grows to include region planes that extend past the tree.
|
|
288
|
+
- Region shade on the root clipped by the canvas
|
|
682
289
|
|
|
683
290
|
## [1.5.0] - 2026-04-06
|
|
684
291
|
|