Skip to content

Commit 8a6ae59

Browse files
authored
Generalize UnicodeGraphics to generic filtering functions (#5)
* Fix Braille typos * Fix `blockize` docstring * Refactor to print to IOBuffer * Update `braille_hex` * Generalize to all boolean functions for filtering * Type stability fixes for default cutoff filter * Add higher level `bprint` interface * Rename `brailize` to `brailleize` * Update README * Formatting fix to README * Rename core functions to `to_braille`, `to_block` * Use ReferenceTests.jl and test/Project.toml Since saving runtests.jl runs some code formatters (i.e. in VSCode) and removes white space from strings, breaking the tests * Remove `cutoff` defaults in `to_braille`, `to_block` * Return newline instead of null char at the end of a string * Refactor API to print to IO, add `bstring` * Add more tests * Format README example * Fix and test deprecations * Add CI workflow * Document `bstring` in README * Revert "Add CI workflow" This reverts commit 422156c. * Increase code coverage * Add CI workflow * Update README * Drop support for Julia < 1.6 * Rename `bprint`/`bstring` to `uprint`/`ustring` Using `u` since it is mnemonic with the package name
1 parent b1adbf1 commit 8a6ae59

File tree

15 files changed

+440
-242
lines changed

15 files changed

+440
-242
lines changed

.github/workflows/CI.yml

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
name: CI
2+
on:
3+
push:
4+
branches:
5+
- master
6+
tags: '*'
7+
pull_request:
8+
branches:
9+
- master
10+
11+
jobs:
12+
test:
13+
name: Julia ${{ matrix.version }} - ${{ matrix.os }} - ${{ matrix.arch }} - ${{ github.event_name }}
14+
runs-on: ${{ matrix.os }}
15+
continue-on-error: ${{ matrix.version == 'nightly' }}
16+
strategy:
17+
fail-fast: false
18+
matrix:
19+
version:
20+
- '1.6'
21+
- '1'
22+
- 'nightly'
23+
os:
24+
- ubuntu-latest
25+
arch:
26+
- x64
27+
steps:
28+
- uses: actions/checkout@v2
29+
- uses: julia-actions/setup-julia@v1
30+
with:
31+
version: ${{ matrix.version }}
32+
arch: ${{ matrix.arch }}
33+
- uses: actions/cache@v1
34+
env:
35+
cache-name: cache-artifacts
36+
with:
37+
path: ~/.julia/artifacts
38+
key: ${{ runner.os }}-test-${{ env.cache-name }}-${{ hashFiles('**/Project.toml') }}
39+
restore-keys: |
40+
${{ runner.os }}-test-${{ env.cache-name }}-
41+
${{ runner.os }}-test-
42+
${{ runner.os }}-
43+
- uses: julia-actions/julia-buildpkg@v1
44+
- uses: julia-actions/julia-runtest@v1
45+
- uses: julia-actions/julia-processcoverage@v1
46+
- uses: codecov/codecov-action@v1
47+
with:
48+
file: lcov.info
49+

.github/workflows/CompatHelper.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ jobs:
99
runs-on: ${{ matrix.os }}
1010
strategy:
1111
matrix:
12-
julia-version: [1.2.0]
12+
julia-version: [1.6]
1313
julia-arch: [x86]
1414
os: [ubuntu-latest]
1515
steps:

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
*.jl.cov
22
*.jl.*.cov
33
*.jl.mem
4+
Manifest.toml

Project.toml

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,4 @@ authors = ["Rafael Schouten <[email protected]>"]
44
version = "0.1.2"
55

66
[compat]
7-
julia = "1"
8-
9-
[extras]
10-
OffsetArrays = "6fe1bfb0-de20-5000-8ca7-80f57d26f881"
11-
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
12-
13-
[targets]
14-
test = ["OffsetArrays", "Test"]
7+
julia = "1.6"

README.md

Lines changed: 77 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -3,68 +3,90 @@
33
[![Build Status](https://travis-ci.org/rafaqz/UnicodeGraphics.jl.svg?branch=master)](https://travis-ci.org/rafaqz/UnicodeGraphics.jl)
44
[![codecov.io](http://codecov.io/github/rafaqz/UnicodeGraphics.jl/coverage.svg?branch=master)](http://codecov.io/github/rafaqz/UnicodeGraphics.jl?branch=master)
55

6-
Convert a matrix of Real into a braile or block Unicode string, real fast.
6+
Convert any matrix into a braille or block Unicode string, real fast and dependency free.
77

8+
## Installation
9+
This package supports Julia ≥1.6. To install it, open the Julia REPL and run
10+
```julia-repl
11+
julia> ]add UnicodeGraphics
812
```
9-
pac = [0 0 0 0 0 0 0 1 1 1 1 1 1 0 0 0 0 0 0 0;
10-
0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0;
11-
0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0;
12-
0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0;
13-
0 0 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 0;
14-
0 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 0;
15-
0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0;
16-
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0;
17-
1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0;
18-
1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0;
19-
1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 1;
20-
1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0;
21-
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0;
22-
0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0;
23-
0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0;
24-
0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0;
25-
0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0;
26-
0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0;
27-
0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0;
28-
0 0 0 0 0 0 0 1 1 1 1 1 1 0 0 0 0 0 0 0]
2913

30-
julia> print(blockize(pac))
31-
▄▄██████▄▄
32-
▄██████████████▄
33-
▄███████ ████████
34-
▄██████████████▀▀
35-
███████████▀▀
14+
## Examples
15+
```julia
16+
julia> pac = [
17+
0 0 0 0 0 0 0 1 1 1 1 1 1 0 0 0 0 0 0 0
18+
0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0
19+
0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0
20+
0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0
21+
0 0 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 0
22+
0 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 0
23+
0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0
24+
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0
25+
1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0
26+
1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0
27+
1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 1
28+
1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0
29+
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0
30+
0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0
31+
0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0
32+
0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0
33+
0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0
34+
0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0
35+
0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0
36+
0 0 0 0 0 0 0 1 1 1 1 1 1 0 0 0 0 0 0 0
37+
];
38+
39+
julia> uprint(pac) # same as uprint(pac, :braille)
40+
⠀⣠⣴⣾⣿⣿⣷⣦⣄⠀
41+
⣰⣿⣿⣿⣧⣼⣿⡿⠟⠃
42+
⣿⣿⣿⣿⣿⣏⡁⠀⠀⠠
43+
⠹⣿⣿⣿⣿⣿⣿⣷⣦⡄
44+
⠀⠙⠻⢿⣿⣿⡿⠟⠋⠀
45+
46+
julia> uprint(pac, :block)
47+
▄▄██████▄▄
48+
▄██████████████▄
49+
▄███████ ████████
50+
▄██████████████▀▀
51+
███████████▀▀
3652
███████████▄▄ ▀
37-
▀██████████████▄▄
38-
▀█████████████████
39-
▀██████████████▀
40-
▀▀██████▀▀
53+
▀██████████████▄▄
54+
▀█████████████████
55+
▀██████████████▀
56+
▀▀██████▀▀
4157
```
4258

43-
Or braile:
44-
59+
It is also possible to pass a filtering function, filling values for which the function returns `true`:
4560
```julia
46-
ghost = [1.0 0.0 1.0 0.0 1.0 0.0 1.0 0.0 1.0 0.0 1.0 0.0 1.0 0.0 1.0 0.0 1.0 0.0 1.0;
47-
0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0;
48-
1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 1.0 1.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0;
49-
0.0 0.0 0.0 0.0 0.0 0.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.0 0.0 0.0 0.0 0.0;
50-
1.0 0.0 0.0 0.0 0.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.0 0.0 0.0 1.0;
51-
0.0 0.0 0.0 0.0 1.0 0.0 0.0 1.0 1.0 1.0 1.0 0.0 0.0 1.0 1.0 1.0 0.0 0.0 0.0;
52-
1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 1.0 0.0 0.0 0.0 0.0 1.0 1.0 0.0 0.0 1.0;
53-
0.0 0.0 0.0 0.0 1.0 1.0 0.0 0.0 1.0 1.0 1.0 1.0 0.0 0.0 1.0 1.0 0.0 0.0 0.0;
54-
1.0 0.0 0.0 1.0 1.0 1.0 0.0 0.0 1.0 1.0 1.0 1.0 0.0 0.0 1.0 1.0 1.0 0.0 1.0;
55-
0.0 0.0 0.0 1.0 1.0 0.0 0.0 1.0 1.0 1.0 1.0 0.0 0.0 1.0 1.0 1.0 1.0 0.0 0.0;
56-
1.0 0.0 0.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.0 1.0;
57-
0.0 0.0 0.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.0 0.0;
58-
1.0 0.0 0.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.0 1.0;
59-
0.0 0.0 0.0 1.0 1.0 0.0 1.0 1.0 1.0 0.0 0.0 1.0 1.0 1.0 0.0 1.0 1.0 0.0 0.0;
60-
1.0 0.0 0.0 1.0 0.0 0.0 0.0 1.0 1.0 0.0 0.0 1.0 1.0 0.0 0.0 0.0 1.0 0.0 1.0;
61-
0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0;
62-
1.0 0.0 1.0 0.0 1.0 0.0 1.0 0.0 1.0 0.0 1.0 0.0 1.0 0.0 1.0 0.0 1.0 0.0 1.0]
61+
julia> ghost = [
62+
1 7 7 7 7 8 6 4 6 3 9 9 9 7
63+
1 5 3 6 6 8 2 8 2 2 2 9 3 7
64+
9 5 4 8 8 6 4 8 4 8 2 6 5 9
65+
5 2 5 1 8 8 6 8 3 3 6 8 6 9
66+
9 9 9 3 1 8 4 5 3 7 9 6 8 3
67+
3 8 8 7 5 6 4 4 2 5 5 6 4 1
68+
2 8 8 3 7 4 6 2 8 9 7 6 8 2
69+
2 4 9 7 2 6 2 4 1 5 6 4 8 8
70+
8 2 4 4 4 4 8 6 4 4 6 4 2 2
71+
6 8 2 6 4 4 8 6 4 2 4 4 2 8
72+
4 2 6 4 2 6 8 6 6 2 8 8 8 8
73+
8 2 3 6 6 8 9 1 2 4 8 5 4 8
74+
8 3 7 3 8 6 9 3 6 6 1 9 1 6
75+
];
76+
77+
julia> uprint(iseven, ghost)
78+
⢀⠴⣾⣿⠷⣦⡀
79+
⣴⠆⣸⣷⠆⣸⣧
80+
⣿⢿⣿⠿⣿⡿⣿
81+
⠁⠀⠉⠀⠉⠀⠈
82+
```
83+
`uprint` can be used to write into any `IO` stream, defaulting to `stdout`.
6384

85+
`ustring` can be used to return a string instead of printing to IO:
86+
```julia-repl
87+
julia> ustring(iseven, ghost)
88+
"⢀⠴⣾⣿⠷⣦⡀\n⣴⠆⣸⣷⠆⣸⣧\n⣿⢿⣿⠿⣿⡿⣿\n⠁⠀⠉⠀⠉⠀⠈\n"
6489
65-
julia> print(brailize(view(ghost, 2:15, 4:17), 0.5))
66-
⠀⣠⣴⣶⣦⣄⠀
67-
⣨⡄⢹⣯⡄⢹⣇
68-
⣿⣶⣿⣿⣶⣿⣿
69-
⠋⠈⠛⠀⠛⠁⠙
90+
julia> ustring(iseven, ghost, :block)
91+
" ▄▄████▄▄ \n ▄▀▀████▀▀██▄ \n ▄▄ ██▄▄ ██ \n██▀ ▄███▀ ▄███\n██████████████\n██▀███▀▀███▀██\n▀ ▀▀ ▀▀ ▀\n"
7092
```

src/UnicodeGraphics.jl

Lines changed: 6 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -1,96 +1,13 @@
11
"""
2-
Block and braile rendering of julia arrays, for terminal graphics.
2+
Block and braille rendering of julia arrays, for terminal graphics.
33
"""
44
module UnicodeGraphics
55

6-
export blockize, brailize, blockize!, brailize!
6+
const DEFAULT_METHOD = :braille
7+
include("api.jl")
8+
include("core.jl")
9+
include("deprecate.jl")
710

8-
"""
9-
brailize(a, cutoff=0)
10-
11-
Convert an array to a block unicode string, filling values above the cutoff point.
12-
"""
13-
blockize(a, cutoff=0) = blockize!(initblock(size(a)), a, cutoff)
14-
15-
# x and y are inverted: repl rows are columns.
16-
initblock((y, x)) = initblock(y, x)
17-
initblock(y, x) = Array{Char,2}(undef, x + 1, (y - 1) ÷ 2 + 1)
18-
19-
"""
20-
blockize!(out, a, cutoff=0)
21-
22-
Convert an array to a braile unicode string, filling the `out` array.
23-
Calculation of array dims is a little complicated:
24-
"""
25-
blockize!(out, a, cutoff=0) = join(block_array!(out, a, cutoff))
26-
27-
function block_array!(out, a, cutoff)
28-
yrange, xrange = axes(a)
29-
for y in first(yrange):2:last(yrange)
30-
for x in xrange
31-
top = checkval(a, y, x, yrange, xrange, cutoff)
32-
bottom = checkval(a, y + 1, x, yrange, xrange, cutoff)
33-
if top
34-
ch = bottom ? '' : ''
35-
else
36-
ch = bottom ? '' : ' '
37-
end
38-
out[x-first(xrange) + 1, (y-first(yrange)) ÷ 2 + 1] = Char(ch)
39-
end
40-
# Return after every column
41-
out[end, (y-first(yrange)) ÷ 2 + 1] = Char('\n')
42-
end
43-
# The last character is null
44-
out[end, end] = 0x00
45-
out
46-
end
47-
48-
const braile_hex = ((0x01, 0x08), (0x02, 0x10), (0x04, 0x20), (0x40, 0x80))
49-
50-
"""
51-
brailize(a, cutoff=0)
52-
53-
Convert an array to a braile unicode string, filling values above the cutoff point.
54-
"""
55-
brailize(a, cutoff=0) = brailize!(initbraile(size(a)), a, cutoff)
56-
57-
# x and y are inverted: repl rows are columns.
58-
initbraile((y, x)) = initbraile(y, x)
59-
initbraile(y, x) = Array{Char,2}(undef, (x - 1) ÷ 2 + 2, (y - 1) ÷ 4 + 1)
60-
61-
"""
62-
brailize!(out, a, cutoff=0)
63-
64-
Convert an array to a braile unicode string, filling the `out` array.
65-
"""
66-
brailize!(out, a, cutoff=0) = join(braile_array!(out, a, cutoff))
67-
68-
function braile_array!(out, a, cutoff)
69-
yrange, xrange = axes(a)
70-
for y in first(yrange):4:last(yrange)
71-
for x in first(xrange):2:last(xrange)
72-
ch = 0x2800
73-
for j = 0:3, i = 0:1
74-
if checkval(a, y+j, x+i, yrange, xrange, cutoff)
75-
ch += braile_hex[j % 4 + 1][i % 2 + 1]
76-
end
77-
end
78-
out[(x - first(xrange)) ÷ 2 + 1, (y-first(yrange)) ÷ 4 + 1] = ch
79-
end
80-
# Return after every column
81-
out[end, (y-first(yrange)) ÷ 4 + 1] = Char('\n')
82-
end
83-
# The last character is null
84-
out[end, end] = 0x00
85-
out
86-
end
87-
88-
checkval(a, y, x, yrange, xrange, cutoff) = begin
89-
if x <= last(xrange) && y <= last(yrange)
90-
a[y, x] > cutoff
91-
else
92-
false
93-
end
94-
end
11+
export uprint, ustring
9512

9613
end # module

0 commit comments

Comments
 (0)