Liking cljdoc? Tell your friends :D

Clojars Project

Bytemap (Clojure)

bytemap is a library for creating text-based graphics using Unicode braille characters. Each braille character contains 8 “pixels” arranged in a 2x4 grid, allowing for reasonably high-resolution terminal output.

This is a Clojure(Script) port of Ian Henry’s Janet library.

Installation

Add to your deps.edn:

{:deps {dev.tomwaddington/bytemap.clj {:mvn/version "RELEASE"}}

Usage

Basic Drawing

(require '[bytemap.core :as bm])

;; Create a canvas and draw points
(-> (bm/new-canvas 10 5)
    (bm/draw-point [10 10])
    (bm/print-canvas!))
;; ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
;; ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
;; ⠀⠀⠀⠀⠀⠄⠀⠀⠀⠀
;; ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
;; ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀

;; Draw lines
(-> (bm/new-canvas 10 5)
    (bm/draw-line [0 0] [20 20])
    (bm/draw-line [0 20] [20 0])
    (bm/print-canvas!))
;; ⠑⢄⠀⠀⠀⠀⠀⠀⢀⠔
;; ⠀⠀⠑⢄⠀⠀⢀⠔⠁⠀
;; ⠀⠀⠀⠀⢑⢔⠁⠀⠀⠀
;; ⠀⠀⢀⠔⠁⠀⠑⢄⠀⠀
;; ⢀⠔⠁⠀⠀⠀⠀⠀⠑⢄

Drawing the Union Jack

(let [canvas (bm/new-canvas 10 5)
      ;; Diagonal lines
      canvas (reduce (fn [c x]
                       (-> c
                           (bm/draw-point [x x])
                           (bm/draw-point [x (- 20 x)])))
                     canvas
                     (range 21))
      ;; Cross lines
      canvas (reduce (fn [c x]
                       (-> c
                           (bm/draw-point [10 x])
                           (bm/draw-point [x 10])))
                     canvas
                     (range 21))]
  (bm/print-canvas! canvas))
;; ⠑⢄⠀⠀⠀⡇⠀⠀⢀⠔
;; ⠀⠀⠑⢄⠀⡇⢀⠔⠁⠀
;; ⠤⠤⠤⠤⢵⣷⠥⠤⠤⠤
;; ⠀⠀⢀⠔⠁⡇⠑⢄⠀⠀
;; ⢀⠔⠁⠀⠀⡇⠀⠀⠑⢄

Plotting Functions

;; Plot a sine wave (prints to stdout)
(bm/print-plot! #(Math/sin %) [40 10] Math/PI 1)
;; ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⠀⢀⠤⠖⠚⠒⠒⢤⡀⠀⠀⠀⠀⠀⠀
;; ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⢀⠔⠁⠀⠀⠀⠀⠀⠀⠈⠢⡀⠀⠀⠀⠀
;; ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⠀⢀⠔⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⢆⠀⠀⠀
;; ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⢠⠊⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠱⡀⠀
;; ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡷⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠘⢄
;; ⠹⡉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⢉⠝⡏⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉
;; ⠀⠘⢄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢠⠊⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
;; ⠀⠀⠈⠢⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡰⠁⠀⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
;; ⠀⠀⠀⠀⠑⢄⠀⠀⠀⠀⠀⠀⠀⠀⡠⠊⠀⠀⠀⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
;; ⠀⠀⠀⠀⠀⠀⠑⢤⣀⣀⢀⣀⡤⠊⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀

;; Get plot as a string (no side effects)
(def plot-str (bm/plot->string #(Math/cos %) [40 10] Math/PI 1))

;; Plot without axes
(bm/print-plot! #(Math/sin %) [40 10] Math/PI 1 :axis false)
;; ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⠤⠖⠚⠒⠒⢤⡀⠀⠀⠀⠀⠀⠀
;; ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⠔⠁⠀⠀⠀⠀⠀⠀⠈⠢⡀⠀⠀⠀⠀
;; ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⠔⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⢆⠀⠀⠀
;; ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢠⠊⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠱⡀⠀
;; ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡰⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠘⢄
;; ⠱⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⠜⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
;; ⠀⠘⢄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢠⠊⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
;; ⠀⠀⠈⠢⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡰⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
;; ⠀⠀⠀⠀⠑⢄⠀⠀⠀⠀⠀⠀⠀⠀⡠⠊⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
;; ⠀⠀⠀⠀⠀⠀⠑⢤⣀⣀⢀⣀⡤⠊⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀

Working with Canvas as Data

;; Canvas is an immutable data structure
(let [canvas (bm/new-canvas 10 5)
      canvas-with-line (bm/draw-line canvas [0 0] [20 20])]
  ;; Original canvas is unchanged
  (bm/canvas->string canvas)            ;; => blank canvas
  (bm/canvas->string canvas-with-line)) ;; => canvas with line

API

Canvas Creation and Rendering

  • (new-canvas width height) - Creates a new canvas. Dimensions are in “pixels” (braille characters), where each pixel is 2x4 sub-pixels.
  • (bounds canvas) - Returns [width height] in sub-pixels.
  • (canvas->string canvas) - Converts canvas to a string.
  • (print-canvas! canvas) - Prints canvas to standard output (side-effecting).

Drawing Functions

  • (draw-point canvas [x y]) - Draws a point at sub-pixel coordinates. Returns new canvas.
  • (draw-point canvas [x y] false) - Clears a point. Returns new canvas.
  • (draw-line canvas [x1 y1] [x2 y2]) - Draws a line using Bresenham’s algorithm. Returns new canvas.

Plotting Functions

  • (plot canvas f & {:keys [axis x-scale y-scale]}) - Plots a function.
  • (plot->string f [w h] x-scale y-scale & {:keys [axis]}) - Plots a function and returns the string representation.
  • (print-plot! f [w h] x-scale y-scale & {:keys [axis]}) - Plots a function, prints to standard output, and returns nil.

Low-Level Functions

  • (braille byte-val) - Converts a byte (0–255) to a braille character.
  • (bit-of-sub-pixel [x y]) - Maps sub-pixel coordinates to bit position.
  • (set-sub-pixel num [x y] value) - Sets or clears a specific sub-pixel bit.

License

Copyright © 2025–2026 Tom Waddington

Distributed under the MIT License. See LICENSE file for details.

Can you improve this documentation?Edit on GitHub

cljdoc builds & hosts documentation for Clojure/Script libraries

Keyboard shortcuts
Ctrl+kJump to recent docs
Move to previous article
Move to next article
Ctrl+/Jump to the search field
× close