mirror of
https://gitlab.com/jessieh/qrprinter.git
synced 2025-05-22 10:41:46 +00:00
112 lines
4.2 KiB
Fennel
112 lines
4.2 KiB
Fennel
;; qrprinter.fnl
|
|
;; Provides utilities for encoding and printing strings as QR codes
|
|
|
|
;; -------------------------------------------------------------------------- ;;
|
|
;; License
|
|
|
|
;; Copyright (C) 2021 Jessie Hildebrandt
|
|
|
|
;; This program is free software: you can redistribute it and/or modify
|
|
;; it under the terms of the GNU General Public License as published by
|
|
;; the Free Software Foundation, either version 3 of the License, or
|
|
;; (at your option) any later version.
|
|
|
|
;; This program is distributed in the hope that it will be useful,
|
|
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
;; GNU General Public License for more details.
|
|
|
|
;; You should have received a copy of the GNU General Public License
|
|
;; along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
|
|
;; -------------------------------------------------------------------------- ;;
|
|
;; Local modules
|
|
|
|
(local qrencode (require :qrprinter.ffi.qrencode))
|
|
|
|
;; -------------------------------------------------------------------------- ;;
|
|
;; Helper functions
|
|
|
|
;; ---------------------------------- ;;
|
|
;; Padding
|
|
|
|
(fn generate_sequence [element size]
|
|
"Return a sequential table of `element` with length `size`."
|
|
(let [row []]
|
|
(for [_ 1 size]
|
|
(table.insert row element))
|
|
row))
|
|
|
|
(fn pad_sequence [sequence element amount]
|
|
"Return a sequential table containing `sequence` padded with `amount` count of `element`."
|
|
(let [padded_sequence [(unpack sequence)]]
|
|
(for [_ 1 amount]
|
|
(table.insert padded_sequence 1 element)
|
|
(table.insert padded_sequence element))
|
|
padded_sequence))
|
|
|
|
(fn pad_qr [qr amount]
|
|
"Return 2D sequential table `qr` padded with `amount` count of white modules."
|
|
(let [blank_row (generate_sequence false (length qr))
|
|
padded_qr (pad_sequence qr blank_row amount)]
|
|
(icollect [_ row (ipairs padded_qr)]
|
|
(pad_sequence row false amount))))
|
|
|
|
;; ---------------------------------- ;;
|
|
;; Printing
|
|
|
|
(fn print_qr [qr black_cell white_cell ?options]
|
|
"Print 2D sequential table `qr` to stdout.
|
|
Black modules will be printed as `black_cell`, and white modules will be printed as `white_cell`.
|
|
`?options` is optional and may contain two keys:
|
|
- invert: If non-nil, the output colors will be inverted.
|
|
- padding: Amount of blank modules to print around QR code. If nil, defaults to 2."
|
|
(let [invert? (?. ?options :invert)
|
|
padding (or (?. ?options :padding) 2)
|
|
padded_qr (pad_qr qr padding)
|
|
[black_cell white_cell] (if invert? [white_cell black_cell] [black_cell white_cell])
|
|
row_strings (icollect [_ row (ipairs padded_qr)]
|
|
(accumulate [row_string ""
|
|
_ module_black? (ipairs row)]
|
|
(.. row_string (if module_black? black_cell white_cell))))]
|
|
(print (table.concat row_strings "\n"))))
|
|
|
|
;; -------------------------------------------------------------------------- ;;
|
|
;; Module functions
|
|
|
|
;; Some Fennel naming conventions are eschewed here because these are Lua-facing library functions
|
|
;; and the names would be mangled during compilation.
|
|
;; e.g. ?options -> _3foptions, invert? -> invert_3f
|
|
|
|
(fn encode_string [string]
|
|
"Encode string `string` into a table representing a QR code.
|
|
Returns a 2D sequential table of true/false values representing black/white QR modules."
|
|
(qrencode.encode_string_8_bit string))
|
|
|
|
(fn print_qr_ascii [qr options]
|
|
"Print QR code `qr` to stdout using ASCII characters."
|
|
(let [black_cell " "
|
|
white_cell "##"]
|
|
(print_qr qr black_cell white_cell options)))
|
|
|
|
(fn print_qr_ansi [qr options]
|
|
"Print QR code `qr` to stdout using ANSI escape sequences."
|
|
(let [black_cell "\27[40m \27[0m"
|
|
white_cell "\27[47m \27[0m"]
|
|
(print_qr qr black_cell white_cell options)))
|
|
|
|
(fn print_qr_utf8 [qr options]
|
|
"Print QR code `qr` to stdout using UTF8 block elements."
|
|
(let [black_cell " "
|
|
white_cell "██"]
|
|
(print_qr qr black_cell white_cell options)))
|
|
|
|
;; -------------------------------------------------------------------------- ;;
|
|
;; Provide qrprinter module
|
|
|
|
{: encode_string
|
|
: print_qr_ascii
|
|
: print_qr_ansi
|
|
: print_qr_utf8
|
|
:print_qr print_qr_ansi}
|