Mon, 20 Apr 2020 12:02:54 -0500
Add title
--@module path local path={} local tuple=require("tuple") local lfs=require("lfs") local err=require("err") local config=require("config") local sep=config.dirsep function path.join(p, f) if p=="" then return f else return p..sep..f end end function path.dirbasename(p) local d, b = string.match(p, "^(.*)"..sep.."+([^"..sep.."]+)"..sep.."*$") if not b then return "", p else return d, b end end function path.dirname(p) return tuple.fst(dirbasename(p)) end function path.dirname_slash(p) local dn=dirname(p) if dn=="" then return dn else return dn..sep end end function path.basename(p) return tuple.snd(dirbasename(p)) end function path.rmext(p) return string.gsub(p, "%.[^.]*$", "") end -- would rather do this as an iterator, but can't -- coroutine.yield from gsub handler function path.split(p) local t={} local head="" local s, p2 = string.match(p, "^("..sep.."+)(.*)$") if s then table.insert(t, "/.") -- root p=p2 end string.gsub(p, "([^"..sep.."]+)", --..sep.."+", function(d) table.insert(t, d); end) return t end --[[ function path.parts(p) local s={i=1, t=split(p)} local function g(s) local v=s.t[s.i] s.i=s.i+1 return v end return g, s end function path.makepath(p, head) head=head or "" for d in parts(p) do head=head..d local a=lfs.attributes(head) if not a then local success, e = lfs.mkdir(head) if not success then err.file(head, e) end elseif a.mode~="directory" then err.file(head, "not a directory") end head=head..sep end end ]] function path.simplify(p) local capts={} local start=string.match(p, "^(/)") string.gsub(p, "([^/]+)", function(e) if e==".." and #capts > 1 then capts[#capts]=nil elseif e~="." then table.insert(capts, e) end end) return (start or "")..table.concat(capts, "/") end function path.to_root(p) return string.rep("../",#(path.split(p))-1) end return path