Pretty up the CLI with ansi escape codes

This commit is contained in:
Starbeamrainbowlabs 2020-09-06 01:47:35 +01:00
parent 28df89ea7f
commit 4928d200d2
Signed by: sbrl
GPG key ID: 1BE5172E637709C2
3 changed files with 135 additions and 24 deletions

View file

@ -59,9 +59,9 @@ To render a 3D maze as a .STL file, do this:
```bash
# Generate the OpenSCAD file
lua main.lua maze3d_openscad -w 91 -h 91 -d 71 -f 91x91x71.scad
lua main.lua maze3d_openscad -w 15 -h 15 -d 17 -f 15x15x17.scad
# Convert the OpenSCAD file to an STL
openscad -o 91x91x71.stl 91x91x71.scad
openscad -o 15x15x17.stl 15x15x17.scad
```
![(Horizontal line)](https://starbeamrainbowlabs.com/blog/images/20200831-mazes/hr.png)

View file

@ -1,3 +1,4 @@
local a = require("./utils/ansi")
local strings = require("./utils/strings")
local debug = require("./utils/print_r")
local calculations = require("./utils/calculations")
@ -5,6 +6,12 @@ local maze2d = require("./maze")
local maze3d = require("./maze3d")
local openscad = require("./openscad")
-- ANSI escape sequence helpers
function a.header(str) return a.fblue(a.hicol(str)) end
function a.item(str) return a.fyellow(str) end
function a.value(str) return a.fgreen(str) end
local settings = {
mode = "help",
extras = {},
@ -65,29 +72,35 @@ end
local function help()
print([[
multimaze: Multidimensional maze generator
By Starbeamrainbowlabs
]]..a.fgreen(a.hicol("multimaze: "))..a.fyellow(a.hicol("Multidimensional maze generator"))..[[
Usage:
lua main.lua {mode} [{options}]
]]..a.locol("By Starbeamrainbowlabs")..[[
Modes:
help Displays this message
maze Generates a 2d maze
maze3d Generates a 3d maze
maze3d_openscad Generates a 3d maze as an openscad file
Options:
-w --width {int} Sets the width of the maze
-h --height {int} Sets the height of the maze
-d --depth {int} Sets the depth of the maze [3d only]
-s --seed {string} Sets the seed
-f --filename {string} Sets the output filename
--no-invert Don't invert the output [openscad output only]
--scale {int} Sets the scale of the output [openscad output only]
--path-length {int} Sets the path length
--path-width {int} Sets the path width
--path-depth {int} Sets the path depth [3d only]
]]..a.header("Usage:")..[[
lua main.lua ]]..a.item("{mode} [{options}]")..[[
]]..a.header("Modes:")..[[
]]..a.item("help")..[[ Displays this message
]]..a.item("maze")..[[ Generates a 2d maze
]]..a.item("maze3d")..[[ Generates a 3d maze
]]..a.item("maze3d_openscad")..[[ Generates a 3d maze as an openscad file
]]..a.header("Options:")..[[
]]..a.item("-w --width")..a.value(" {int}")..[[ Sets the width of the maze
]]..a.item("-h --height")..a.value(" {int}")..[[ Sets the height of the maze
]]..a.item("-d --depth")..a.value(" {int}")..[[ Sets the depth of the maze [3d only]
]]..a.item("-s --seed")..a.value(" {string}")..[[ Sets the seed
]]..a.item("-f --filename")..a.value(" {string}")..[[ Sets the output filename
]]..a.item("--no-invert")..[[ Don't invert the output [openscad output only]
]]..a.item("--scale")..a.value(" {int}")..[[ Sets the scale of the output [openscad output only]
]]..a.item("--path-length")..a.value(" {int}")..[[ Sets the path length
]]..a.item("--path-width")..a.value(" {int}")..[[ Sets the path width
]]..a.item("--path-depth")..a.value(" {int}")..[[ Sets the path depth [3d only]
]])
end
@ -141,7 +154,7 @@ local function maze3d_openscad()
settings.filename,
openscad_settings
)
print("Maze written to "..settings.filename)
print("Maze written to "..a.fgreen(a.hicol(settings.filename)))
end
local mode_functions = {
@ -153,7 +166,8 @@ local mode_functions = {
local selection = mode_functions[settings.mode]
if not selection then
print("Error: Unrecognised mode '"..settings.mode.."'")
print(a.fred(a.hicol("Error: Unrecognised mode '"..a.FBLE..settings.mode..a.FRED.."'")))
print()
selection = mode_functions["help"]
end

97
utils/ansi.lua Normal file
View file

@ -0,0 +1,97 @@
--[[
VT100 ANSI escape sequences.
Ported from the Lantern Build Engine, which si written in Bash.
Other versions:
- Bash, in the Lantern Build Engine: https://gitlab.com/sbrl/lantern-build-engine/-/blob/master/lantern.sh
- Javascript: massCode/Ansi.mjs
- C: massCode/Ansi.cs
Changelog:
6th September 2020:
Initial release - port complete!
]]--
local ansi
if os.getenv("NO_COLOR") ~= nil then
ansi = {
RS = "",
HC = "",
UL = "",
INV = "",
LC = "",
FBLK = "",
FRED = "",
FGRN = "",
FYEL = "",
FBLE = "",
FMAG = "",
FCYN = "",
FWHT = "",
BBLK = "",
BRED = "",
BGRN = "",
BYEL = "",
BBLE = "",
BMAG = "",
BCYN = "",
BWHT = "",
}
else
ansi = {
RS = "\27[0m", -- reset
HC = "\27[1m", -- hicolor
UL = "\27[4m", -- underline
INV = "\27[7m", -- inverse background and foreground
LC = "\27[2m", -- locolor / dim
FBLK = "\27[30m", -- foreground black
FRED = "\27[31m", -- foreground red
FGRN = "\27[32m", -- foreground green
FYEL = "\27[33m", -- foreground yellow
FBLE = "\27[34m", -- foreground blue
FMAG = "\27[35m", -- foreground magenta
FCYN = "\27[36m", -- foreground cyan
FWHT = "\27[37m", -- foreground white
BBLK = "\27[40m", -- background black
BRED = "\27[41m", -- background red
BGRN = "\27[42m", -- background green
BYEL = "\27[43m", -- background yellow
BBLE = "\27[44m", -- background blue
BMAG = "\27[45m", -- background magenta
BCYN = "\27[46m", -- background cyan
BWHT = "\27[47m", -- background white
-- Invalid escape sequence, apparently - we'll need to look into how to do it properly
-- Perhaps knowing the hex code for the character we want would be helpful
-- URL_START = '\e]8;;',
-- URL_DISPLAY_TEXT = '\e\\',
-- URL_END = '\e]8;;\e\\'
}
end
function ansi.wrap(str, start)
return start..str..ansi.RS
end
function ansi.hicol(str) return ansi.wrap(str, ansi.HC) end
function ansi.locol(str) return ansi.wrap(str, ansi.LC) end
function ansi.uline(str) return ansi.wrap(str, ansi.UL) end
function ansi.invert(str) return ansi.wrap(str, ansi.INV) end
function ansi.fblack(str) return ansi.wrap(str, ansi.FBLK) end
function ansi.fred(str) return ansi.wrap(str, ansi.FRED) end
function ansi.fgreen(str) return ansi.wrap(str, ansi.FGRN) end
function ansi.fyellow(str) return ansi.wrap(str, ansi.FYEL) end
function ansi.fblue(str) return ansi.wrap(str, ansi.FBLE) end
function ansi.fmagenta(str) return ansi.wrap(str, ansi.FMAG) end
function ansi.fcyan(str) return ansi.wrap(str, ansi.FCYN) end
function ansi.fwhite(str) return ansi.wrap(str, ansi.FWHT) end
function ansi.bblack(str) return ansi.wrap(str, ansi.FBLK) end
function ansi.bred(str) return ansi.wrap(str, ansi.BRED) end
function ansi.bgreen(str) return ansi.wrap(str, ansi.BGRN) end
function ansi.byellow(str) return ansi.wrap(str, ansi.BYEL) end
function ansi.bblue(str) return ansi.wrap(str, ansi.BBLE) end
function ansi.bmagenta(str) return ansi.wrap(str, ansi.BMAG) end
function ansi.bcyan(str) return ansi.wrap(str, ansi.BCYN) end
function ansi.bwhite(str) return ansi.wrap(str, ansi.BWHT) end
return ansi