tessella 0.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 +7 -0
- data/LICENSE +21 -0
- data/README.md +900 -0
- data/doc/README.md +74 -0
- data/doc/bitfield.md +123 -0
- data/doc/charts.md +1370 -0
- data/doc/check.rb +75 -0
- data/doc/cli.md +483 -0
- data/doc/composition.md +599 -0
- data/doc/getting-started.md +121 -0
- data/doc/glyphs.md +134 -0
- data/doc/images.md +325 -0
- data/doc/library.md +239 -0
- data/doc/lint.md +270 -0
- data/doc/meter.md +210 -0
- data/doc/rule.md +51 -0
- data/doc/seq.md +169 -0
- data/doc/sparkline.md +63 -0
- data/doc/table.md +347 -0
- data/doc/targets.md +222 -0
- data/doc/text.md +84 -0
- data/doc/tree.md +108 -0
- data/doc/wave.md +122 -0
- data/examples/README.md +103 -0
- data/examples/ages.txt +9 -0
- data/examples/bad.csv +3 -0
- data/examples/boxes.txt +3 -0
- data/examples/broken.txt +4 -0
- data/examples/calibration.rb +12 -0
- data/examples/cities.csv +4 -0
- data/examples/cjk.rb +13 -0
- data/examples/comment.rb +9 -0
- data/examples/comment.sh +13 -0
- data/examples/cpu.txt +60 -0
- data/examples/dashboard.sh +25 -0
- data/examples/datasheet.rb +16 -0
- data/examples/disc.pgm +0 -0
- data/examples/disks.sh +18 -0
- data/examples/disks.txt +5 -0
- data/examples/dose.txt +7 -0
- data/examples/drift.txt +4 -0
- data/examples/ethernet.txt +3 -0
- data/examples/figure.c +5 -0
- data/examples/fit.rb +16 -0
- data/examples/floors.rb +21 -0
- data/examples/gallery.sh +20 -0
- data/examples/gauges.sh +31 -0
- data/examples/gradient.rb +16 -0
- data/examples/growth.txt +6 -0
- data/examples/hosts.csv +4 -0
- data/examples/icmp.txt +3 -0
- data/examples/ipv4.txt +12 -0
- data/examples/kinds.csv +4 -0
- data/examples/langs.csv +4 -0
- data/examples/lint.rb +16 -0
- data/examples/load.rb +14 -0
- data/examples/login.txt +10 -0
- data/examples/neg.csv +4 -0
- data/examples/normal.txt +200 -0
- data/examples/note.txt +2 -0
- data/examples/notes-fixed.md +17 -0
- data/examples/notes.md +17 -0
- data/examples/ohlc.txt +7 -0
- data/examples/os.csv +10 -0
- data/examples/outline.txt +8 -0
- data/examples/plot.txt +5 -0
- data/examples/refusals.rb +17 -0
- data/examples/report.sh +21 -0
- data/examples/rfc.sh +22 -0
- data/examples/samples.txt +7 -0
- data/examples/shapes.pgm +0 -0
- data/examples/sizes.tsv +3 -0
- data/examples/spi.txt +6 -0
- data/examples/status.sh +23 -0
- data/examples/stem.txt +12 -0
- data/examples/table-drift.txt +4 -0
- data/examples/temps.txt +31 -0
- data/examples/trig.sh +13 -0
- data/examples/trig.txt +102 -0
- data/examples/week.txt +8 -0
- data/examples/wide.txt +2 -0
- data/exe/tessella +6 -0
- data/lib/tessella/axis.rb +71 -0
- data/lib/tessella/bitfield.rb +194 -0
- data/lib/tessella/block.rb +56 -0
- data/lib/tessella/borders.rb +85 -0
- data/lib/tessella/canvas/area.rb +155 -0
- data/lib/tessella/canvas/ascii.rb +120 -0
- data/lib/tessella/canvas/block.rb +40 -0
- data/lib/tessella/canvas/braille.rb +30 -0
- data/lib/tessella/canvas/clip.rb +49 -0
- data/lib/tessella/canvas/density.rb +51 -0
- data/lib/tessella/canvas/dot.rb +27 -0
- data/lib/tessella/canvas/eighths.rb +43 -0
- data/lib/tessella/canvas/half.rb +51 -0
- data/lib/tessella/canvas/sextant.rb +36 -0
- data/lib/tessella/canvas.rb +168 -0
- data/lib/tessella/cell.rb +10 -0
- data/lib/tessella/chart.rb +211 -0
- data/lib/tessella/check.rb +52 -0
- data/lib/tessella/cli/bitfield.rb +121 -0
- data/lib/tessella/cli/chart.rb +615 -0
- data/lib/tessella/cli/chart_candle.rb +36 -0
- data/lib/tessella/cli/chart_heatmap.rb +21 -0
- data/lib/tessella/cli/chart_help.rb +85 -0
- data/lib/tessella/cli/chart_pie.rb +38 -0
- data/lib/tessella/cli/compose.rb +156 -0
- data/lib/tessella/cli/compose_options.rb +259 -0
- data/lib/tessella/cli/glyphs.rb +97 -0
- data/lib/tessella/cli/image.rb +250 -0
- data/lib/tessella/cli/input.rb +44 -0
- data/lib/tessella/cli/iso_time.rb +28 -0
- data/lib/tessella/cli/lint.rb +102 -0
- data/lib/tessella/cli/lint_options.rb +99 -0
- data/lib/tessella/cli/main.rb +121 -0
- data/lib/tessella/cli/meter.rb +80 -0
- data/lib/tessella/cli/rule.rb +57 -0
- data/lib/tessella/cli/seq.rb +117 -0
- data/lib/tessella/cli/sparkline.rb +72 -0
- data/lib/tessella/cli/table.rb +167 -0
- data/lib/tessella/cli/text.rb +78 -0
- data/lib/tessella/cli/tree.rb +100 -0
- data/lib/tessella/cli/wave.rb +148 -0
- data/lib/tessella/cli.rb +36 -0
- data/lib/tessella/color.rb +106 -0
- data/lib/tessella/compose.rb +243 -0
- data/lib/tessella/compose_fill.rb +176 -0
- data/lib/tessella/compose_grid.rb +36 -0
- data/lib/tessella/compose_shadow.rb +41 -0
- data/lib/tessella/error.rb +13 -0
- data/lib/tessella/frame.rb +170 -0
- data/lib/tessella/glyphs.rb +106 -0
- data/lib/tessella/image.rb +454 -0
- data/lib/tessella/image_octant.rb +46 -0
- data/lib/tessella/image_petscii.rb +116 -0
- data/lib/tessella/kinds/bar.rb +344 -0
- data/lib/tessella/kinds/box.rb +213 -0
- data/lib/tessella/kinds/box_upright.rb +110 -0
- data/lib/tessella/kinds/candlestick.rb +164 -0
- data/lib/tessella/kinds/columns.rb +259 -0
- data/lib/tessella/kinds/date_axis.rb +102 -0
- data/lib/tessella/kinds/error_bars.rb +71 -0
- data/lib/tessella/kinds/heatmap.rb +130 -0
- data/lib/tessella/kinds/line.rb +173 -0
- data/lib/tessella/kinds/multibar.rb +98 -0
- data/lib/tessella/kinds/multibar_columns.rb +130 -0
- data/lib/tessella/kinds/multibar_fine.rb +45 -0
- data/lib/tessella/kinds/multibar_rows.rb +93 -0
- data/lib/tessella/kinds/pie.rb +123 -0
- data/lib/tessella/kinds/pie_rim.rb +78 -0
- data/lib/tessella/kinds/sideways.rb +62 -0
- data/lib/tessella/kinds/stem.rb +134 -0
- data/lib/tessella/kinds/threshold.rb +73 -0
- data/lib/tessella/legend.rb +31 -0
- data/lib/tessella/lint/alphabet.rb +56 -0
- data/lib/tessella/lint/drift.rb +82 -0
- data/lib/tessella/lint/fences.rb +51 -0
- data/lib/tessella/lint/geometry.rb +120 -0
- data/lib/tessella/lint/geometry_checks.rb +224 -0
- data/lib/tessella/lint/lines.rb +115 -0
- data/lib/tessella/lint/mixing.rb +61 -0
- data/lib/tessella/lint/runner.rb +73 -0
- data/lib/tessella/lint/shadows.rb +120 -0
- data/lib/tessella/lint/target_rows.rb +66 -0
- data/lib/tessella/lint.rb +158 -0
- data/lib/tessella/meter.rb +133 -0
- data/lib/tessella/meter_upright.rb +43 -0
- data/lib/tessella/png.rb +456 -0
- data/lib/tessella/raster.rb +92 -0
- data/lib/tessella/rmagick_reader.rb +52 -0
- data/lib/tessella/rule.rb +59 -0
- data/lib/tessella/seq.rb +522 -0
- data/lib/tessella/sparkline.rb +57 -0
- data/lib/tessella/stats.rb +199 -0
- data/lib/tessella/table.rb +547 -0
- data/lib/tessella/table_cells.rb +225 -0
- data/lib/tessella/target.rb +105 -0
- data/lib/tessella/text.rb +76 -0
- data/lib/tessella/text_forms.rb +150 -0
- data/lib/tessella/tree.rb +221 -0
- data/lib/tessella/version.rb +5 -0
- data/lib/tessella/wave.rb +353 -0
- data/lib/tessella/width.rb +122 -0
- data/lib/tessella/width_class.rb +77 -0
- data/lib/tessella/width_invisible.rb +66 -0
- data/lib/tessella/width_invisible_high.rb +60 -0
- data/lib/tessella.rb +94 -0
- metadata +226 -0
data/doc/meter.md
ADDED
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
# Meters
|
|
2
|
+
|
|
3
|
+
`meter` draws one line: a bar filled to a fraction, between brackets,
|
|
4
|
+
with its percentage after it. A progress line in a log, a gauge in a
|
|
5
|
+
status report, a column of them in a dashboard.
|
|
6
|
+
|
|
7
|
+
```ruby
|
|
8
|
+
Tessella.meter(fraction, style: :block, width: 20, title: nil,
|
|
9
|
+
title_width: nil, label: true, brackets: true,
|
|
10
|
+
orientation: :horizontal, height: 8,
|
|
11
|
+
ascii: false) # => Block
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
```text
|
|
15
|
+
tessella meter [--style S] [--width N] [--title T] [--title-width N]
|
|
16
|
+
[--no-label] [--no-brackets] [--ascii]
|
|
17
|
+
[--orientation horizontal|vertical] [--height N] FRACTION
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
`FRACTION` is a number from 0 to 1, or a percentage, `45%`.
|
|
21
|
+
|
|
22
|
+
```text
|
|
23
|
+
$ tessella meter 0.5
|
|
24
|
+
[██████████··········] 50 %
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
```text
|
|
28
|
+
$ tessella meter --width 10 --title disk 37%
|
|
29
|
+
disk [███▊······] 37 %
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
`--width` is the bar's cells, 20 by default. The default `block`
|
|
33
|
+
style fills its last cell by eighths, so a bar moves by an eighth of
|
|
34
|
+
a cell, not a whole one. `--no-label` drops the percentage and
|
|
35
|
+
`--no-brackets` the brackets:
|
|
36
|
+
|
|
37
|
+
```text
|
|
38
|
+
$ tessella meter --no-label --no-brackets 0.25
|
|
39
|
+
█████···············
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## Styles
|
|
43
|
+
|
|
44
|
+
A style is a fill glyph and a track glyph. The named ones are the
|
|
45
|
+
meter sets in the [registry](glyphs.md#the-registry):
|
|
46
|
+
|
|
47
|
+
```text
|
|
48
|
+
$ for s in arrow chevron classic rectangle wave block box circle star; do \
|
|
49
|
+
tessella meter --style $s --width 12 --title $s --title-width 9 0.6; \
|
|
50
|
+
done
|
|
51
|
+
arrow [▸▸▸▸▸▸▸▹▹▹▹▹] 60 %
|
|
52
|
+
chevron [››››››› ] 60 %
|
|
53
|
+
classic [======= ] 60 %
|
|
54
|
+
rectangle [▮▮▮▮▮▮▮▯▯▯▯▯] 60 %
|
|
55
|
+
wave [~~~~~~~_____] 60 %
|
|
56
|
+
block [███████▎····] 60 %
|
|
57
|
+
box [■■■■■■■□□□□□] 60 %
|
|
58
|
+
circle [●●●●●●●○○○○○] 60 %
|
|
59
|
+
star [★★★★★★★☆☆☆☆☆] 60 %
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
`blade` (`▰▱`) and `button` (`⦿⦾`) exist too, but many fonts lack
|
|
63
|
+
their glyphs: try them in the reader's font first.
|
|
64
|
+
`tessella glyphs meter` lists every set with its width class.
|
|
65
|
+
|
|
66
|
+
A style of one's own is two glyphs, fill then track, one column each
|
|
67
|
+
and of one [width class](glyphs.md#width-classes):
|
|
68
|
+
|
|
69
|
+
```text
|
|
70
|
+
$ tessella meter --style '▰▱' 0.33
|
|
71
|
+
[▰▰▰▰▰▰▰▱▱▱▱▱▱▱▱▱▱▱▱▱] 33 %
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
```text
|
|
75
|
+
$ tessella meter --style '■░' 0.5
|
|
76
|
+
tessella meter: meter style "■░" mixes width classes: A, N
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
## Upright meters
|
|
80
|
+
|
|
81
|
+
`--orientation vertical` stands the bar up: a column `--height` cells
|
|
82
|
+
tall (8 by default), filled from the bottom, between `─` caps (`-`
|
|
83
|
+
under `--ascii`, none with `--no-brackets`), the title centred above
|
|
84
|
+
and the percentage below. The block style tops its column with an
|
|
85
|
+
eighth, `▁` to `▇`. An upright meter takes `--height`, not
|
|
86
|
+
`--width`, and the other way round across; either one in the wrong
|
|
87
|
+
orientation is a usage error.
|
|
88
|
+
|
|
89
|
+
```text
|
|
90
|
+
$ tessella meter --orientation vertical --height 6 --title cpu 0.62
|
|
91
|
+
cpu
|
|
92
|
+
─
|
|
93
|
+
·
|
|
94
|
+
·
|
|
95
|
+
▆
|
|
96
|
+
█
|
|
97
|
+
█
|
|
98
|
+
█
|
|
99
|
+
─
|
|
100
|
+
62 %
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
Upright meters stand side by side with `compose beside`, their
|
|
104
|
+
bottoms aligned. `gauges.sh` draws one per line of `disks.txt`:
|
|
105
|
+
|
|
106
|
+
```sh
|
|
107
|
+
#!/bin/sh
|
|
108
|
+
# examples/gauges.sh -- upright meters side by side, one per line of
|
|
109
|
+
# "name fraction", bottoms aligned: a row of gauges.
|
|
110
|
+
# usage: sh gauges.sh [file] (default disks.txt)
|
|
111
|
+
set -eu
|
|
112
|
+
|
|
113
|
+
cd -- "$(dirname -- "$0")" || exit 1
|
|
114
|
+
input=${1:-disks.txt}
|
|
115
|
+
|
|
116
|
+
tmpdir=
|
|
117
|
+
cleanup() { [ -z "$tmpdir" ] || rm -rf -- "$tmpdir"; }
|
|
118
|
+
trap cleanup EXIT INT HUP TERM
|
|
119
|
+
tmpdir=$(mktemp -d "${TMPDIR:-/tmp}/gauges.XXXXXX") || exit 1
|
|
120
|
+
|
|
121
|
+
n=0
|
|
122
|
+
while read -r name fraction; do
|
|
123
|
+
case $name in
|
|
124
|
+
'' | '#'*) continue ;;
|
|
125
|
+
esac
|
|
126
|
+
n=$((n + 1))
|
|
127
|
+
tessella meter --orientation vertical --height 6 --title "$name" \
|
|
128
|
+
-- "$fraction" > "$tmpdir/$n"
|
|
129
|
+
done < "$input"
|
|
130
|
+
|
|
131
|
+
set --
|
|
132
|
+
i=1
|
|
133
|
+
while [ "$i" -le "$n" ]; do
|
|
134
|
+
set -- "$@" "$tmpdir/$i"
|
|
135
|
+
i=$((i + 1))
|
|
136
|
+
done
|
|
137
|
+
tessella compose beside --gap 3 --align bottom "$@"
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
```text
|
|
141
|
+
$ sh gauges.sh
|
|
142
|
+
/ /home /var /tmp
|
|
143
|
+
─ ─ ─ ─
|
|
144
|
+
· ▂ · ·
|
|
145
|
+
· █ · ·
|
|
146
|
+
▆ █ · ·
|
|
147
|
+
█ █ · ·
|
|
148
|
+
█ █ ▇ ·
|
|
149
|
+
█ █ █ ▂
|
|
150
|
+
─ ─ ─ ─
|
|
151
|
+
62 % 87 % 31 % 4 %
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
## ASCII
|
|
155
|
+
|
|
156
|
+
`--ascii` draws the classic style, `=` on a blank track:
|
|
157
|
+
|
|
158
|
+
```text
|
|
159
|
+
$ tessella meter --ascii 0.5
|
|
160
|
+
[========== ] 50 %
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
## A status board
|
|
164
|
+
|
|
165
|
+
Meters are blocks like any figure, so they stack and frame.
|
|
166
|
+
`--title-width N` (`title_width:`) pads a title to N columns, so a
|
|
167
|
+
column of meters lines up; a longer title is refused (exit 2).
|
|
168
|
+
`disks.sh` reads `name fraction` lines and draws one meter each:
|
|
169
|
+
|
|
170
|
+
```sh
|
|
171
|
+
#!/bin/sh
|
|
172
|
+
# examples/disks.sh -- one meter per line of "name fraction", their
|
|
173
|
+
# titles padded to one width so the bars line up, framed: a small
|
|
174
|
+
# status board.
|
|
175
|
+
# usage: sh disks.sh [file] (default disks.txt)
|
|
176
|
+
set -eu
|
|
177
|
+
|
|
178
|
+
cd -- "$(dirname -- "$0")" || exit 1
|
|
179
|
+
input=${1:-disks.txt}
|
|
180
|
+
|
|
181
|
+
while read -r name fraction; do
|
|
182
|
+
case $name in
|
|
183
|
+
'' | '#'*) continue ;;
|
|
184
|
+
esac
|
|
185
|
+
tessella meter --width 16 --title "$name" --title-width 6 \
|
|
186
|
+
-- "$fraction"
|
|
187
|
+
done < "$input" |
|
|
188
|
+
tessella compose frame --title disks -
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
```text
|
|
192
|
+
$ sh disks.sh
|
|
193
|
+
┌──────────── disks ─────────────┐
|
|
194
|
+
│ / [█████████▉······] 62 % │
|
|
195
|
+
│ /home [█████████████▉··] 87 % │
|
|
196
|
+
│ /var [█████···········] 31 % │
|
|
197
|
+
│ /tmp [▋···············] 4 % │
|
|
198
|
+
└────────────────────────────────┘
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
## Errors
|
|
202
|
+
|
|
203
|
+
A fraction outside 0..1 (or 0%..100%), an unknown style, a style that
|
|
204
|
+
is not two glyphs of one class, or a missing fraction is a usage error,
|
|
205
|
+
exit 2:
|
|
206
|
+
|
|
207
|
+
```text
|
|
208
|
+
$ tessella meter 1.5
|
|
209
|
+
tessella meter: fraction must be 0..1 or 0%..100%: "1.5"
|
|
210
|
+
```
|
data/doc/rule.md
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# Rules
|
|
2
|
+
|
|
3
|
+
`rule` draws a divider: one line in a rule style, with an optional
|
|
4
|
+
ornament centred in it. It separates the parts of a report, a log, a
|
|
5
|
+
plain-text document.
|
|
6
|
+
|
|
7
|
+
```ruby
|
|
8
|
+
Tessella.rule(width: 78, ornament: nil, style: :light,
|
|
9
|
+
ascii: false) # => Block
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
```text
|
|
13
|
+
tessella rule [--width N] [--ornament T] [--style S] [--ascii]
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
```text
|
|
17
|
+
$ tessella rule --width 30
|
|
18
|
+
──────────────────────────────
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
The ornament is any text, centred by display width with a blank on
|
|
22
|
+
each side:
|
|
23
|
+
|
|
24
|
+
```text
|
|
25
|
+
$ tessella rule --width 30 --ornament '✦'
|
|
26
|
+
───────────── ✦ ──────────────
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
```text
|
|
30
|
+
$ tessella rule --width 30 --style double --ornament 'Part II'
|
|
31
|
+
══════════ Part II ═══════════
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
The styles are the rule sets in the [registry](glyphs.md#the-registry):
|
|
35
|
+
`light` (`─`, the default), `heavy` (`━`), `double` (`═`), `dashed`
|
|
36
|
+
(`┄`) and `ascii` (`-`). `--ascii` draws `-`, and refuses an ornament
|
|
37
|
+
that is not ASCII:
|
|
38
|
+
|
|
39
|
+
```text
|
|
40
|
+
$ tessella rule --width 30 --ascii --ornament '* * *'
|
|
41
|
+
----------- * * * ------------
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
```text
|
|
45
|
+
$ tessella rule --ascii --ornament '✦'
|
|
46
|
+
tessella rule: ornament is non-ASCII under ascii: true
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
`stack`'s `rule:` draws a plain line between figures; `rule` is the
|
|
50
|
+
one to reach for when the line needs a style or an ornament, or
|
|
51
|
+
stands alone.
|
data/doc/seq.md
ADDED
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
# Sequence diagrams
|
|
2
|
+
|
|
3
|
+
`seq` draws a UML-style sequence diagram: participants across the
|
|
4
|
+
top, their lifelines down, and messages between them in order.
|
|
5
|
+
|
|
6
|
+
```ruby
|
|
7
|
+
Tessella.seq(text, ascii: false, numbered: false, footer: false)
|
|
8
|
+
# => Block
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
```text
|
|
12
|
+
tessella seq [--ascii] [--numbered] [--footer] [--max-width N] [file]
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Input
|
|
16
|
+
|
|
17
|
+
One statement per line; blank lines and `#` comments are skipped.
|
|
18
|
+
|
|
19
|
+
| Statement | Draws |
|
|
20
|
+
|-------------------------|-----------------------------------------|
|
|
21
|
+
| `participant A` | declares A, fixing its column |
|
|
22
|
+
| `A -> B: text` | a call, solid arrow |
|
|
23
|
+
| `A --> B: text` | a reply, dashed arrow |
|
|
24
|
+
| `A ->> B: text` | an asynchronous message, double head |
|
|
25
|
+
| `A -> A: text` | a self call, a loop right of A |
|
|
26
|
+
| `note over A: text` | a note on A's lifeline |
|
|
27
|
+
| `note over A,B: text` | a note spanning A to B |
|
|
28
|
+
|
|
29
|
+
A name is a run of letters, digits, `_`, `.` or `-`, not ending in
|
|
30
|
+
`-`, so `A-->B` reads as a reply with or without blanks. Participants
|
|
31
|
+
take their columns in the order they are declared, or first appear;
|
|
32
|
+
columns widen to fit every label, never truncating one.
|
|
33
|
+
|
|
34
|
+
```text
|
|
35
|
+
$ cat login.txt
|
|
36
|
+
participant Browser
|
|
37
|
+
participant Server
|
|
38
|
+
participant DB
|
|
39
|
+
Browser -> Server: POST /login
|
|
40
|
+
Server -> DB: SELECT user
|
|
41
|
+
DB --> Server: row
|
|
42
|
+
Server -> Server: check hash
|
|
43
|
+
note over Server,DB: bcrypt, cost 12
|
|
44
|
+
Server ->> DB: log attempt
|
|
45
|
+
Server --> Browser: 200 + cookie
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
```text
|
|
49
|
+
$ tessella seq login.txt
|
|
50
|
+
┌─────────┐ ┌─────────┐ ┌─────┐
|
|
51
|
+
│ Browser │ │ Server │ │ DB │
|
|
52
|
+
└────┬────┘ └────┬────┘ └──┬──┘
|
|
53
|
+
│ │ │
|
|
54
|
+
│ POST /login │ │
|
|
55
|
+
│─────────────►│ │
|
|
56
|
+
│ │ │
|
|
57
|
+
│ │ SELECT user │
|
|
58
|
+
│ │───────────────►│
|
|
59
|
+
│ │ │
|
|
60
|
+
│ │ row │
|
|
61
|
+
│ │◄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄│
|
|
62
|
+
│ │ │
|
|
63
|
+
│ │──┐ │
|
|
64
|
+
│ │ │ check hash │
|
|
65
|
+
│ │◄─┘ │
|
|
66
|
+
│ │ │
|
|
67
|
+
│ ┌────────────────┐
|
|
68
|
+
│ │bcrypt, cost 12 │
|
|
69
|
+
│ └────────────────┘
|
|
70
|
+
│ │ │
|
|
71
|
+
│ │ log attempt │
|
|
72
|
+
│ │──────────────►►│
|
|
73
|
+
│ │ │
|
|
74
|
+
│ 200 + cookie │ │
|
|
75
|
+
│◄┄┄┄┄┄┄┄┄┄┄┄┄┄│ │
|
|
76
|
+
│ │ │
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
## Arrow heads
|
|
80
|
+
|
|
81
|
+
Calls and replies end in `►` or `◄`, asynchronous messages in a
|
|
82
|
+
double head, `►►` or `◄◄`, in every [width target](targets.md). These
|
|
83
|
+
heads read at a glance and never turn into emoji in a browser, but a
|
|
84
|
+
font that lacks them draws them at a fallback width
|
|
85
|
+
([on the web](targets.md#web)). Under `--ascii` they are `>` and `<`,
|
|
86
|
+
and `>>` and `<<` for an asynchronous message.
|
|
87
|
+
|
|
88
|
+
## Options
|
|
89
|
+
|
|
90
|
+
`--numbered` numbers the messages; `--footer` repeats the participant
|
|
91
|
+
boxes under the lifelines, which helps a long diagram:
|
|
92
|
+
|
|
93
|
+
```text
|
|
94
|
+
$ tessella seq --numbered --footer login.txt
|
|
95
|
+
┌─────────┐ ┌─────────┐ ┌─────┐
|
|
96
|
+
│ Browser │ │ Server │ │ DB │
|
|
97
|
+
└────┬────┘ └────┬────┘ └──┬──┘
|
|
98
|
+
│ │ │
|
|
99
|
+
│ 1. POST /login │ │
|
|
100
|
+
│────────────────►│ │
|
|
101
|
+
│ │ │
|
|
102
|
+
│ │ 2. SELECT user │
|
|
103
|
+
│ │──────────────────►│
|
|
104
|
+
│ │ │
|
|
105
|
+
│ │ 3. row │
|
|
106
|
+
│ │◄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄│
|
|
107
|
+
│ │ │
|
|
108
|
+
│ │──┐ │
|
|
109
|
+
│ │ │ 4. check hash │
|
|
110
|
+
│ │◄─┘ │
|
|
111
|
+
│ │ │
|
|
112
|
+
│ ┌───────────────────┐
|
|
113
|
+
│ │ bcrypt, cost 12 │
|
|
114
|
+
│ └───────────────────┘
|
|
115
|
+
│ │ │
|
|
116
|
+
│ │ 5. log attempt │
|
|
117
|
+
│ │─────────────────►►│
|
|
118
|
+
│ │ │
|
|
119
|
+
│ 6. 200 + cookie │ │
|
|
120
|
+
│◄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄│ │
|
|
121
|
+
│ │ │
|
|
122
|
+
┌────┴────┐ ┌────┴────┐ ┌──┴──┐
|
|
123
|
+
│ Browser │ │ Server │ │ DB │
|
|
124
|
+
└─────────┘ └─────────┘ └─────┘
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
`--ascii` draws in `+ - |`, with `- - -` for a reply:
|
|
128
|
+
|
|
129
|
+
```text
|
|
130
|
+
$ tessella seq --ascii login.txt
|
|
131
|
+
+---------+ +---------+ +-----+
|
|
132
|
+
| Browser | | Server | | DB |
|
|
133
|
+
+----+----+ +----+----+ +--+--+
|
|
134
|
+
| | |
|
|
135
|
+
| POST /login | |
|
|
136
|
+
|------------->| |
|
|
137
|
+
| | |
|
|
138
|
+
| | SELECT user |
|
|
139
|
+
| |--------------->|
|
|
140
|
+
| | |
|
|
141
|
+
| | row |
|
|
142
|
+
| |<- - - - - - - -|
|
|
143
|
+
| | |
|
|
144
|
+
| |--+ |
|
|
145
|
+
| | | check hash |
|
|
146
|
+
| |<-+ |
|
|
147
|
+
| | |
|
|
148
|
+
| +----------------+
|
|
149
|
+
| |bcrypt, cost 12 |
|
|
150
|
+
| +----------------+
|
|
151
|
+
| | |
|
|
152
|
+
| | log attempt |
|
|
153
|
+
| |-------------->>|
|
|
154
|
+
| | |
|
|
155
|
+
| 200 + cookie | |
|
|
156
|
+
|<- - - - - - -| |
|
|
157
|
+
| | |
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
## Errors
|
|
161
|
+
|
|
162
|
+
A line that is none of the statements above is refused, quoting it
|
|
163
|
+
(exit 1); so is input with no statement, and a non-ASCII name under
|
|
164
|
+
`--ascii`.
|
|
165
|
+
|
|
166
|
+
```text
|
|
167
|
+
$ printf 'A => B: x\n' | tessella seq
|
|
168
|
+
tessella seq: line 1: A => B: x
|
|
169
|
+
```
|
data/doc/sparkline.md
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# Sparklines
|
|
2
|
+
|
|
3
|
+
A sparkline is a chart one line high and one cell a value, small
|
|
4
|
+
enough to sit in a sentence, a table cell or a log line: ▁▂▄▃█▁▂.
|
|
5
|
+
|
|
6
|
+
```ruby
|
|
7
|
+
Tessella.sparkline(values, width: nil, min: nil, max: nil,
|
|
8
|
+
ascii: false) # => Block
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
```text
|
|
12
|
+
tessella sparkline [--width N] [--min A] [--max B] [--ascii] [VALUE ...]
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
The command reads the values given, or stdin when there are none,
|
|
16
|
+
split on blanks and commas:
|
|
17
|
+
|
|
18
|
+
```text
|
|
19
|
+
$ tessella sparkline 1 5 22 13 53 2 8
|
|
20
|
+
▁▂▄▃█▁▂
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
```text
|
|
24
|
+
$ printf '1,2\n3 4\n' | tessella sparkline
|
|
25
|
+
▁▃▆█
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Each value takes one of eight steps, `▁` to `█`, from the lowest value
|
|
29
|
+
to the highest. Under `--ascii` the steps are `_.-:=+*#`:
|
|
30
|
+
|
|
31
|
+
```text
|
|
32
|
+
$ tessella sparkline --ascii 1 5 22 13 53 2 8
|
|
33
|
+
_.:-#_.
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Width and range
|
|
37
|
+
|
|
38
|
+
`--width N` averages the values into N cells, for a long series in a
|
|
39
|
+
short space (with fewer values than cells, each is repeated to fill
|
|
40
|
+
them). `cpu.txt` holds 60 values:
|
|
41
|
+
|
|
42
|
+
```text
|
|
43
|
+
$ tessella sparkline --width 20 < cpu.txt
|
|
44
|
+
▅▇██▇▆▄▃▂▁▁▃▄▆▇██▇▅▄
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
By default the range is the values' own, so every sparkline uses all
|
|
48
|
+
eight steps. `--min` and `--max` fix it, so several sparklines share
|
|
49
|
+
one scale and can be compared:
|
|
50
|
+
|
|
51
|
+
```text
|
|
52
|
+
$ tessella sparkline --min 0 --max 100 10 50 90
|
|
53
|
+
▂▅▇
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## Errors
|
|
57
|
+
|
|
58
|
+
A value that is not a number is bad input, exit 1:
|
|
59
|
+
|
|
60
|
+
```text
|
|
61
|
+
$ tessella sparkline 1 x
|
|
62
|
+
tessella sparkline: not a number: "x"
|
|
63
|
+
```
|