diff --git a/wip/OpenOS/usr/bin/wip.lua b/wip/OpenOS/usr/bin/wip.lua new file mode 100644 index 0000000..183f0df --- /dev/null +++ b/wip/OpenOS/usr/bin/wip.lua @@ -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 ") + 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") diff --git a/wip/OpenOS/usr/bin/wipprint.lua b/wip/OpenOS/usr/bin/wipprint.lua new file mode 100644 index 0000000..621068e --- /dev/null +++ b/wip/OpenOS/usr/bin/wipprint.lua @@ -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() diff --git a/wip/OpenOS/usr/lib/printwidth.lua b/wip/OpenOS/usr/lib/printwidth.lua new file mode 100644 index 0000000..7dc17a3 --- /dev/null +++ b/wip/OpenOS/usr/lib/printwidth.lua @@ -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}