import WordImperfect

This commit is contained in:
Izaya 2024-03-05 08:02:11 +10:00
parent 3b654dd6ae
commit 48acdfff19
3 changed files with 326 additions and 0 deletions

198
wip/OpenOS/usr/bin/wip.lua Normal file
View File

@ -0,0 +1,198 @@
local component = require "component"
local event = require "event"
local f = component.list("openprinter")()
local printer = f and component.proxy(f)
local _, unicode = pcall(require, "unicode")
local _, printwidth = pcall(require, "printwidth")
local tA = {...}
local buffer = {}
local cx, cy = 1, 1
local vx, vy = 1, 1
local lcx, lcy = 1, 1
local mx, my = 80, 25
local w, f = pcall(require, "mtmenu")
if w then
mx, my = t.getScreenSize()
else
mx, my = require("term").getViewport()
end
local mw = printer and printer.maxWidth() or 164
local width = (printwidth or {}).width or printer.width
if #tA < 1 then
print("Usage: wip <filename>")
os.exit()
end
local f = io.open(tA[1], "rb")
if f then
for line in f:lines() do
buffer[#buffer+1] = line
end
else
buffer[1] = ""
end
local function save(fn)
fn=fn or tA[1]
local f = io.open(fn, "wb")
if f then
for k,v in ipairs(buffer) do
f:write(v.."\n")
end
f:close()
end
end
local function fwrite(...)
return io.write(string.format(...))
end
local function printerFormat(s)
s=s:gsub("^##","§n")
s=s:gsub("^#","§l§n")
s=s:gsub("%*(.-)%*","§o%1§r")
s=s:gsub("$DATE",os.date("%Y-%m-%d"))
return s
end
local function getOF(s, start)
start=start or 1
local f, o = "", ""
for i = start, #s do
if width(printerFormat(s:sub(1,i))) >= mw then
f, o = s:sub(1,i-1), s:sub(i)
return f, o, i
end
end
return s:sub(start), "", 80
end
local function findLastPageBreak(n)
for i = n, 1, -1 do
if (buffer[i] or ""):sub(1,1) == "&" then
return i
end
end
return 0
end
local function displayLine(n)
for i = n, 1, -1 do
if (buffer[i] or ""):sub(1,1) == "&" then
return (n - i)%21
end
end
return n%21
end
local function displayPage(n)
local r,l = 0, 0
for i,v in ipairs(buffer) do
if v:sub(1,1) == "&" or i > l+20 then
r, l = r + 1, i
end
if i == n then break end
end
return r
end
local function draw(full)
cx, cy = math.max(1, math.min(cx, #(buffer[cy] or "")+1)), math.max(1, math.min(cy, #buffer))
local dx=mx-4
while cy > (vy + my - (my/4)) do vy = vy + math.ceil(my/3) end
while cy < (vy + (my/4)) do vy = vy - math.ceil(my/3) end
while cx > (vx + dx - (dx/4)) do vx = vx + math.ceil(dx/3) end
while cx < (vx + (dx/4)) do vx = vx - math.ceil(dx/3) end
vx, vy=math.max(1, vx), math.max(1,vy)
local start, finish = math.max(1,cy-1), math.min(cy+1, #buffer)
if cy ~= lcy or full then start, finish = vy, vy + (my-2) end
local tcx, tcy = cx - vx + 5, cy - vy + 1
for i = start, finish do
local ti = i - vy + 1
local line = buffer[i] or ""
local fit, overflow, ofi = getOF(line, vx)
fit=fit:sub(vx)
local lc = line:sub(1,1) == "#" and 32 or line:sub(1,1) == "&" and 7 or 0
fwrite("\27[%i;1H\27[36m%3i \27[%im%s\27[31m%s\27[0m%s", ti, displayLine(i), lc, fit:gsub("%*(.-)%*","\27[7m*%1*\27[0m"), overflow:sub(1,mx-#fit-4), (" "):rep(mx-#fit-#overflow-4))
end
if cy ~= lcy or cx ~= lcx or full then
local lst = string.format("🗑^W 🖬^S 🖨^P 🗎%s",tA[1])
local rst = string.format("🗐%i/%i%+4i,%-3i", displayPage(cy),displayPage(#buffer), cx, cy)
fwrite("\27[%i;1H%s%"..tostring(mx-unicode.wlen(lst)).."s",my,lst,rst)
end
local cc = buffer[cy]:sub(cx, cx)
cc = #cc > 0 and cc or " "
fwrite("\27[%i;%iH\27[7m%s\27[0m",tcy, tcx,cc)
lcx, lcy = cx, cy
end
io.write("\27[2J\27[H")
draw(true)
local frd = false
while true do
draw(frd)
frd=false
local tE = {event.pull()}
if tE[1] == "key_down" then
ch, co = tE[3], tE[4]
if ch == 23 and co == 17 then
break
elseif co == 200 then -- up
cy = cy - 1
elseif co == 208 then -- down
cy = cy + 1
elseif co == 203 then -- left
cx = cx - 1
elseif co == 205 then -- right
cx = cx + 1
elseif ch > 31 and ch < 127 then -- insert character
buffer[cy] = buffer[cy]:sub(1,cx-1) .. string.char(ch) .. buffer[cy]:sub(cx)
cx = cx + 1
elseif ch == 8 and co == 14 then -- backspace
if cx == 1 and cy > 1 then
cx = #buffer[cy-1]+1
buffer[cy-1] = buffer[cy-1] .. table.remove(buffer, cy)
cy = cy - 1
frd = true
else
buffer[cy] = buffer[cy]:sub(1,cx-2) .. buffer[cy]:sub(cx)
cx = cx - 1
end
elseif ch == 127 and co == 211 then -- delete
if cx == #buffer[cy]+1 then
buffer[cy] = buffer[cy] .. (table.remove(buffer,cy+1) or "")
frd = true
else
buffer[cy] = buffer[cy]:sub(1,cx-1) .. buffer[cy]:sub(cx+1)
end
elseif ch == 13 and co == 28 then -- enter
table.insert(buffer, cy+1, buffer[cy]:sub(cx))
buffer[cy] = buffer[cy]:sub(1,cx-1)
cx,cy=1,cy+1
frd = true
elseif co == 199 then -- home
cx = 1
elseif co == 207 then -- end
cx = #buffer[cy] + 1
elseif co == 201 then -- pgup
cy = cy - (my-1)
elseif co == 209 then -- pgdn
cy = cy + (my-1)
elseif ch == 19 and co == 31 then -- ^s, save
save()
elseif ch == 16 and co == 25 then -- ^p, print
local tn = os.tmpname()
save(tn)
io.write("\27[2J\27[H")
os.execute(string.format("wipprint '%s'", tn))
require("filesystem").remove(tn)
frd = true
end
elseif tE[1] == "touch" then
local tx, ty = tE[3], tE[4]
cx, cy = vx + tx - 5, vy + ty - 1
frd = true
end
end
io.write("\27[2J\27[H")

View File

@ -0,0 +1,71 @@
local component = require "component"
local printer = component.openprinter
local tA = {...}
local debug = tA[2]
local lc, title = 1
local function writeln(...)
if debug then return end
return printer.writeln(...)
end
local function printpg()
if debug then return end
local rv = {printer.print()}
printer.setTitle(title)
return table.unpack(rv)
end
local f = io.open(tA[1], "rb")
printer.clear()
local mw = printer.maxWidth()
for line in f:lines() do
local centre = nil
line=line:gsub("^##","§n")
line=line:gsub("^#","§l§n")
line=line:gsub("%*(.-)%*","§o%1§r")
line=line:gsub("$DATE",os.date("%Y-%m-%d"))
if line:sub(1,1) == "&" then
title = line:sub(2)
if lc > 1 then
print(printpg())
lc = 1
end
printer.setTitle(title)
line = ""
end
while #line > 0 do
local lb = 1
repeat
lb = lb + 1
until printer.width(line:sub(1,lb)) >= mw or lb >= #line
local ws,we = line:sub(1,lb):find("%s+(%S+)$")
if ws and we and printer.width(line:sub(1,lb)) >= mw then
local sw = line:match("%S+",ws)
for i = 1, ws-1 do
io.write(" ")
end
print("v",ws, lb, lb-ws, sw:len(),sw)
if lb - ws < 6 then
lb = ws
else
repeat
lb = lb - 1
until printer.width(line:sub(1,lb+2) .. "-") < mw
line = line:sub(1,lb) .. "-" .. line:sub(lb+1)
lb = lb + 1
end
end
writeln(line:sub(1,lb), nil, centre)
print(line:sub(1,lb))
line = line:sub(lb+1):gsub("^%s+","")
lc = lc + 1
if lc > 20 then
print(printpg())
lc = 1
end
end
end
print(printpg())
f:close()

View File

@ -0,0 +1,57 @@
local _, unicode = pcall(require, "unicode")
local widths = {
[32] = 3,
[33] = 1,
[34] = 3,
[39] = 1,
[40] = 3,
[41] = 3,
[42] = 3,
[44] = 1,
[46] = 1,
[58] = 1,
[59] = 1,
[60] = 4,
[62] = 4,
[64] = 6,
[73] = 3,
[91] = 3,
[93] = 3,
[96] = 2,
[102] = 4,
[105] = 1,
[107] = 4,
[108] = 2,
[116] = 3,
[123] = 3,
[124] = 1,
[125] = 3,
[126] = 6,
}
local sub = (unicode or {}).sub or string.sub
local function width(str)
local dispstr = str:gsub("§[%dabcdefklmnor]","")
local rlen = dispstr:len()
local cc, offset = false, 0
for i = 1, unicode.len(str) do
local c = unicode.sub(str,i,i)
if cc then
if c == "l" then
offset = 1
elseif c == "r" then
offset = 0
end
cc = false
else
if c == "§" then
cc = true
else
rlen = rlen + offset + (widths[string.byte(c)] or 5)
end
end
end
return rlen
end
return {width=width,widths=widths}