-- primitives for saving to file and loading from file Drawing = require 'drawing' function load_from_disk(filename) local infile = io.open(filename) local result = load_from_file(infile) if infile then infile:close() end return result end function load_from_file(infile) local result = {} if infile then local infile_next_line = infile:lines() -- works with both Lua files and LÖVE Files (https://www.love2d.org/wiki/File) while true do local line = infile_next_line() if line == nil then break end if line == '```lines' then -- inflexible with whitespace since these files are always autogenerated table.insert(result, load_drawing(infile_next_line)) else table.insert(result, {mode='text', data=line}) end end end if #result == 0 then table.insert(result, {mode='text', data=''}) end return result end function save_to_disk(lines, filename) local outfile = io.open(filename, 'w') for _,line in ipairs(lines) do if line.mode == 'drawing' then store_drawing(outfile, line) else outfile:write(line.data..'\n') end end outfile:close() end json = require 'json' function load_drawing(infile_next_line) local drawing = {mode='drawing', h=256/2, points={}, shapes={}, pending={}} while true do local line = infile_next_line() assert(line) if line == '```' then break end local shape = json.decode(line) if shape.mode == 'line' or shape.mode == 'manhattan' then shape.p1 = Drawing.insert_point(drawing.points, shape.p1.x, shape.p1.y) shape.p2 = Drawing.insert_point(drawing.points, shape.p2.x, shape.p2.y) elseif shape.mode == 'polygon' or shape.mode == 'rectangle' or shape.mode == 'square' then for i,p in ipairs(shape.vertices) do shape.vertices[i] = Drawing.insert_point(drawing.points, p.x,p.y) end elseif shape.mode == 'circle' or shape.mode == 'arc' then shape.center = Drawing.insert_point(drawing.points, shape.center.x,shape.center.y) else print(shape.mode) assert(false) end table.insert(drawing.shapes, shape) end return drawing end function store_drawing(outfile, drawing) outfile:write('```lines\n') for _,shape in ipairs(drawing.shapes) do if shape.mode == 'freehand' then outfile:write(json.encode(shape)..'\n') elseif shape.mode == 'line' or shape.mode == 'manhattan' then local line = json.encode({mode=shape.mode, p1=drawing.points[shape.p1], p2=drawing.points[shape.p2]}) outfile:write(line..'\n') elseif shape.mode == 'polygon' or shape.mode == 'rectangle' or shape.mode == 'square' then local obj = {mode=shape.mode, vertices={}} for _,p in ipairs(shape.vertices) do table.insert(obj.vertices, drawing.points[p]) end local line = json.encode(obj) outfile:write(line..'\n') elseif shape.mode == 'circle' then outfile:write(json.encode({mode=shape.mode, center=drawing.points[shape.center], radius=shape.radius})..'\n') elseif shape.mode == 'arc' then outfile:write(json.encode({mode=shape.mode, center=drawing.points[shape.center], radius=shape.radius, start_angle=shape.start_angle, end_angle=shape.end_angle})..'\n') else print(shape.mode) assert(false) end end outfile:write('```\n') end