PandocAnsiFilter/ansi2html.lua
2022-09-22 13:11:06 +02:00

167 lines
3.8 KiB
Lua

-- this is essentially
-- https://github.com/jupyter/nbconvert/blob/main/nbconvert/filters/ansi.py
-- converted to lua
local ANSI_COLORS = {
"ansi-black",
"ansi-red",
"ansi-green",
"ansi-yellow",
"ansi-blue",
"ansi-magenta",
"ansi-cyan",
"ansi-white",
"ansi-black-intense",
"ansi-red-intense",
"ansi-green-intense",
"ansi-yellow-intense",
"ansi-blue-intense",
"ansi-magenta-intense",
"ansi-cyan-intense",
"ansi-white-intense"
}
--[[
local re = require "re"
local codes = {
-- attributes
reset = 0,
bright = 1,
dim = 2,
underscore = 4,
-- blink = 5,
reverse = 7,
-- hidden = 8,
-- foreground
black = 30,
red = 31,
green = 32,
yellow = 33,
blue = 34,
magenta = 35,
cyan = 36,
white = 37,
-- background
onblack = 40,
onred = 41,
ongreen = 42,
onyellow = 43,
onblue = 44,
onmagenta = 45,
oncyan = 46,
onwhite = 47,
}
local ANSI = re.compile [[
'\x1b%[' {.*?} {[@-~]}
]]
--]]
local function LaTeXconverter()
end
local function HTMLconverter(fg, bg, bold, underline, inverse)
if not (fg or bg or bold or underline or inverse) then
return "",""
end
local classes = {}
local styles = {}
if inverse then
fg, bg = bg, fg
end
if type(fg) == "number" then
table.insert(classes, ANSI_COLORS[fg] .. "-fg")
elseif fg then
table.insert(styles, string.format("color: rgb(%d,%d,%d)", fg[1], fg[2], fg[3]))
elseif inverse then
table.insert(classes,"ansi-default-inverse-fg")
end
if type(bg) == "number" then
table.insert(classes, ANSI_COLORS[bg] .. "-bg")
elseif bg then
table.insert(styles, string.format("background-color: rgb(%d,%d,%d)", bg[1], bg[2], bg[3]))
elseif inverse then
table.insert(classes,"ansi-default-inverse-bg")
end
if bold then
table.insert(classes, "ansi-bold")
end
if underline then
table.insert(classes, "ansi-underline")
end
local starttag = "<span"
if classes then
starttag = starttag .. ' class="' .. table.concat(classes, " ") .. '"'
end
if styles then
starttag = starttag .. ' style="' .. table.concat(styles, " ") .. '"'
end
return starttag,"</span>"
end
function CodeBlock(e)
local converter
if FORMAT:match 'latex' then
converter = LaTeXconverter
elseif FORMAT:match 'html' then
converter = HTMLconverter
elseif FORMAT:match 'native' then
converter = HTMLconverter
else
return
end
if string.find(e.text, "\x1b%[") then
local bold = false
local underline = false
local inverse = false
local text = e.text
local out = ""
local chunk = ""
local fg = {}
local bg = {}
local starttag = ""
local endtag = ""
while text do
local s1, e1, c1, d1 = string.find(text, "\x1b%[(.-)([@-~])")
if s1 then
if d1 == "m" then
local numbers={}
for i in string.gmatch(c1, "[^;]") do
table.insert(numbers, tonumber(i))
end
end
chunk, text = text:sub(1, s1-1), text:sub(e1+1)
else
chunk, text = text, ""
end
if chunk then
if bold and type(fg)=="number" and fg<8 then
starttag, endtag = converter(fg+8, bg, bold, underline, inverse)
else
starttag, endtag = converter(fg, bg, bold, underline, inverse)
end
out = out .. starttag .. chunk .. endtag
end
end
end
end