tessella 0.3.0 → 0.3.1

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: 8ce17185ecd27997f771fd86221023064a69a3e971f552b8c7c91b4c6e40f526
4
- data.tar.gz: 7e18eafac46af4fda371abe27c1e0f2d0ebf617380e6a0b7a6fb9fb2c8c4ef75
3
+ metadata.gz: 1d193803deddaeae8e0bc86469a9e041a9e03b90a13da001d17d26f3a5b90be3
4
+ data.tar.gz: 016f01a20153c54d3856f007483d341d5f4ba1ede0b6c058821c035677556cb5
5
5
  SHA512:
6
- metadata.gz: 1a5b056fba4777b82cb7083f35f31587b29ad3d9d5a0eced8c978708afe47a3fcf27b413fd0aa3dea0a3c7d4213541b3b5c2fdd09e7ebac09cf5d0e26f942606
7
- data.tar.gz: 852fd9065708c73371b95226b9a3f11803df800c144ff7200d6a799b176e77b76a007a88a903fa621e990f43978e0a323945eb37a693d3cff87e853f3570861a
6
+ metadata.gz: 83e1a6f644364f63241cdc2d6150da86d6fd08355f4916f15a48fed9257e605d0c91829cbc7528377604b17dd81b5e061ea421b9bf79654ef04167d3a9993cff
7
+ data.tar.gz: db56487e22198b30f470967f937098e249e8b6b641496bf57a94ae97a58b3cfd45d56e417a2b0de4aa2bf22858cd0f3d957969a355d668a975a0351d953e24c6
data/README.md CHANGED
@@ -25,14 +25,14 @@ decisions behind them.
25
25
 
26
26
  ## Install
27
27
 
28
- tessella is not on rubygems.org, and it has no public remote. Install
29
- it from a checkout of this repository:
28
+ tessella is on [rubygems.org](https://rubygems.org/gems/tessella):
30
29
 
31
30
  ```bash
32
- cd tessella
33
- make install
31
+ gem install tessella
34
32
  ```
35
33
 
34
+ From a checkout of this repository
35
+ ([github.com/sdalu/tessella](https://github.com/sdalu/tessella)),
36
36
  `make install` builds the gem and installs it for this user (`gem
37
37
  install --user-install --local`). `make uninstall` removes it again.
38
38
  Running `exe/tessella` directly out of a checkout, without installing,
@@ -2,13 +2,13 @@
2
2
 
3
3
  ## Install
4
4
 
5
- tessella is not on rubygems.org. Install it from a checkout:
6
-
7
5
  ```sh
8
- cd tessella
9
- make install # builds the gem, installs it for this user
6
+ gem install tessella
10
7
  ```
11
8
 
9
+ Or from a checkout of
10
+ [github.com/sdalu/tessella](https://github.com/sdalu/tessella):
11
+ `make install` builds the gem and installs it for this user, and
12
12
  `make uninstall` removes it. Without installing, `exe/tessella` runs
13
13
  straight out of the checkout, and `ruby -I lib` finds the library.
14
14
  It needs Ruby 3.4 and nothing else.
data/doc/seq.md CHANGED
@@ -29,7 +29,9 @@ One statement per line; blank lines and `#` comments are skipped.
29
29
  A name is a run of letters, digits, `_`, `.` or `-`, not ending in
30
30
  `-`, so `A-->B` reads as a reply with or without blanks. Participants
31
31
  take their columns in the order they are declared, or first appear;
32
- columns widen to fit every label, never truncating one.
32
+ columns widen to fit every label, never truncating one. A message
33
+ that skips participants carries its label in the gap beside its
34
+ sender, so the label never covers a lifeline the arrow passes.
33
35
 
34
36
  ```text
35
37
  $ cat login.txt
@@ -64,9 +66,9 @@ $ tessella seq login.txt
64
66
  │ │ │ check hash │
65
67
  │ │◄─┘ │
66
68
  │ │ │
67
- │ ┌────────────────┐
69
+ │ ├────────────────┤
68
70
  │ │bcrypt, cost 12 │
69
- │ └────────────────┘
71
+ │ ├────────────────┤
70
72
  │ │ │
71
73
  │ │ log attempt │
72
74
  │ │──────────────►►│
@@ -109,9 +111,9 @@ $ tessella seq --numbered --footer login.txt
109
111
  │ │ │ 4. check hash │
110
112
  │ │◄─┘ │
111
113
  │ │ │
112
- │ ┌───────────────────┐
114
+ │ ├───────────────────┤
113
115
  │ │ bcrypt, cost 12 │
114
- │ └───────────────────┘
116
+ │ ├───────────────────┤
115
117
  │ │ │
116
118
  │ │ 5. log attempt │
117
119
  │ │─────────────────►►│
data/lib/tessella/seq.rb CHANGED
@@ -28,9 +28,9 @@ module Tessella
28
28
  \s*:\s*(.*)\z/x
29
29
 
30
30
  UNI_G = { h: "─", v: "│", tl: "┌", tr: "┐", bl: "└", br: "┘",
31
- td: "┬", tu: "┴", dash: "┄" }.freeze
31
+ td: "┬", tu: "┴", tr_: "├", tl_: "┤", dash: "┄" }.freeze
32
32
  ASC_G = { h: "-", v: "|", tl: "+", tr: "+", bl: "+", br: "+",
33
- td: "+", tu: "+", dash: "-" }.freeze
33
+ td: "+", tu: "+", tr_: "+", tl_: "+", dash: "-" }.freeze
34
34
 
35
35
  def self.bad!(lineno, msg)
36
36
  raise ArgumentError, "line #{lineno}: #{msg}"
@@ -228,11 +228,16 @@ module Tessella
228
228
  label = label_text(stmt)
229
229
  return grow_right!(state, i, self_loop_need(label)) if i == j
230
230
 
231
- lo, hi = [i, j].minmax
231
+ seg = label_gap(i, j)
232
232
  required = Width.of(label) + 2
233
- ensure_width!(state, lo, hi, required, -1)
233
+ ensure_width!(state, seg, seg + 1, required, -1)
234
234
  end
235
235
 
236
+ # The gap a message's label sits in: the one beside its
237
+ # sender, so a message that skips participants never writes
238
+ # its label over a lifeline it passes.
239
+ def self.label_gap(from, to) = from < to ? from : from - 1
240
+
236
241
  def self.widen_note!(state, participants, stmt)
237
242
  idx = stmt[:names].map { participants.index(it) }.sort
238
243
  if idx.size == 1
@@ -374,7 +379,7 @@ module Tessella
374
379
  end
375
380
 
376
381
  def self.arrow_rows(lay, spec, label, style)
377
- lo, hi = spec.values_at(:lo, :hi)
382
+ lo, hi = spec[:label]
378
383
  lr = lifeline_row(lay, style)
379
384
  interior = hi - lo - 1
380
385
  start = lo + 1 + centered_start(interior, Width.of(label))
@@ -435,12 +440,36 @@ module Tessella
435
440
  span_note(idx.first, idx.last, positions)
436
441
  end
437
442
 
443
+ # A note's box drawn over the lifelines: where a lifeline
444
+ # meets its top or bottom edge, the edge takes a junction
445
+ # (├ ┤ at a corner, ┴ ┬ along an edge), so the lifeline
446
+ # ends and resumes at a stroke rather than butting a plain
447
+ # corner or edge.
438
448
  def self.overlay_rows(lay, style, rows, left)
439
449
  canvas = rows.map { lifeline_row(lay, style) }
440
450
  rows.each_with_index { |s, r| place!(canvas[r], left, s) }
451
+ join_lifelines!(canvas, lay, note_joints(style))
441
452
  canvas.map(&:join)
442
453
  end
443
454
 
455
+ def self.join_lifelines!(canvas, lay, joints)
456
+ lay[:positions].each do |p|
457
+ junction!(canvas.first, p[:center], joints[:top])
458
+ junction!(canvas.last, p[:center], joints[:bottom])
459
+ end
460
+ end
461
+
462
+ def self.note_joints(style)
463
+ { top: { style[:tl] => style[:tr_], style[:tr] => style[:tl_],
464
+ style[:h] => style[:tu] },
465
+ bottom: { style[:bl] => style[:tr_], style[:br] => style[:tl_],
466
+ style[:h] => style[:td] } }
467
+ end
468
+
469
+ def self.junction!(row, col, joints)
470
+ row[col] = joints.fetch(row[col], row[col])
471
+ end
472
+
444
473
  def self.note_rows(stmt, lay, participants, style)
445
474
  idx = stmt[:names].map { participants.index(it) }.sort
446
475
  spot = note_spot(idx, lay[:positions], stmt[:text])
@@ -461,8 +490,10 @@ module Tessella
461
490
  lo, hi = idx_pair.minmax
462
491
  dir = i < j ? :right : :left
463
492
  pos = lay[:positions]
493
+ seg = label_gap(i, j)
464
494
  spec = { lo: pos[lo][:center], hi: pos[hi][:center],
465
- kind: kind, dir: dir }
495
+ kind: kind, dir: dir,
496
+ label: [pos[seg][:center], pos[seg + 1][:center]] }
466
497
  arrow_rows(lay, spec, label, style)
467
498
  end
468
499
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Tessella
4
- VERSION = "0.3.0"
4
+ VERSION = "0.3.1"
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tessella
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Stephane D'Alu
@@ -9,8 +9,10 @@ bindir: exe
9
9
  cert_chain: []
10
10
  date: 1980-01-02 00:00:00.000000000 Z
11
11
  dependencies: []
12
- description: Line, scatter, stairs, bar, histogram, box, stem and density plots with
13
- scaled axes, drawn in braille, block, dot or ASCII cells. No runtime dependency.
12
+ description: Charts (line, scatter, bar, histogram, box, stem, density) on braille,
13
+ block or ASCII canvases, trees, tables, bit-field, timing and sequence diagrams,
14
+ meters and sparklines, composed side by side or framed, and a lint for text figures
15
+ in documents. No runtime dependency.
14
16
  executables:
15
17
  - tessella
16
18
  extensions: []
@@ -202,10 +204,15 @@ files:
202
204
  - lib/tessella/width_class.rb
203
205
  - lib/tessella/width_invisible.rb
204
206
  - lib/tessella/width_invisible_high.rb
207
+ homepage: https://github.com/sdalu/tessella
205
208
  licenses:
206
209
  - MIT
207
210
  metadata:
208
211
  rubygems_mfa_required: 'true'
212
+ source_code_uri: https://github.com/sdalu/tessella
213
+ documentation_uri: https://github.com/sdalu/tessella/blob/main/doc/README.md
214
+ changelog_uri: https://github.com/sdalu/tessella/releases
215
+ bug_tracker_uri: https://github.com/sdalu/tessella/issues
209
216
  rdoc_options: []
210
217
  require_paths:
211
218
  - lib
@@ -222,5 +229,5 @@ required_rubygems_version: !ruby/object:Gem::Requirement
222
229
  requirements: []
223
230
  rubygems_version: 4.0.21
224
231
  specification_version: 4
225
- summary: Charts for a monospace grid, in Unicode or pure ASCII
232
+ summary: Text figures for a monospace grid, in Unicode or pure ASCII
226
233
  test_files: []