wsminify.lua

Run Settings
LanguageLua
Language Version
Run Command
local source = [[ local str = "Lorem ipsum dolor sit amet, consectetur adipiscing elit." local function split(s, delimiter) local t = {} (s..delimiter):gsub("(.-)"..delimiter, function(c) table.insert(t, c) end) return t end for _, s in ipairs(split(str, " ")) do print(s) end ]] local minified = require("wsminify")(source) print(minified) print("---") loadstring(minified)()
--[[ wsminify A whitespace minifier made with boatbomber's Lua(u) lexer Lua Lexer (https://devforum.roblox.com/t/183115) the original Penlight Lexer module: https://github.com/stevedonovan/Penlight Authors: stevedonovan <https://github.com/stevedonovan> ----------- Original Penlight lexer author ryanjmulder <https://github.com/ryanjmulder> ------------- Penlight lexer contributer mpeterv <https://github.com/mpeterv> --------------------- Penlight lexer contributer Tieske <https://github.com/Tieske> ----------------------- Penlight lexer contributer boatbomber <https://github.com/boatbomber> --------------- Roblox port, added builtin token, added patterns for incomplete syntax, bug fixes, behavior changes, token optimization Sleitnick <https://github.com/Sleitnick> ----------------- Roblox optimizations howmanysmall <https://github.com/howmanysmall> ----------- Lua + Roblox optimizations boatbomber <https://github.com/boatbomber> --------------- Added lexer.navigator() for non-sequential reads ]] -- Ported lexer -- Also minified with this, except I had to add an escape on one of the -- patterns (which had ]] and conflicted the multi-line string) local lexer={} local Prefix,Suffix,Cleaner="^[ \t\n\0\a\b\v\f\r]*","[ \t\n\0\a\b\v\f\r]*","[ \t\n\0\a\b\v\f\r]+" local NUMBER_A="0x[%da-fA-F]+" local NUMBER_B="%d+%.?%d*[eE][%+%-]?%d+" local NUMBER_C="%d+[%._]?[%d_eE]*" local OPERATORS="[:;<>/~%*%(%)%-=,{}%.#%^%+%%]+" local BRACKETS="[%[%]]+" local IDEN="[%a_][%w_]*" local STRING_EMPTY="(['\"])%1" local STRING_PLAIN=[=[(['"])[%w%p \t\v\b\f\r\a]-([^%\]%1)]=] local STRING_INCOMP_A="(['\"]).-\n" local STRING_INCOMP_B="(['\"])[^\n]*" local STRING_MULTI="%[(=*)%[.-%]%1%]" local STRING_MULTI_INCOMP="%[=*%[.-.*" local COMMENT_MULTI="%-%-%[(=*)%[.-%]%1%]" local COMMENT_MULTI_INCOMP="%-%-%[=*%[.-.*" local COMMENT_PLAIN="%-%-.-\n" local COMMENT_INCOMP="%-%-.*" local TABLE_EMPTY={} local lua_keyword={["and"]= true ,["break"]= true ,["do"]= true ,["else"]= true ,["elseif"]= true ,["end"]= true ,["false"]= true ,["for"]= true ,["function"]= true ,["if"]= true ,["in"]= true ,["local"]= true ,["nil"]= true ,["not"]= true ,["while"]= true ,["or"]= true ,["repeat"]= true ,["return"]= true ,["then"]= true ,["true"]= true ,["self"]= true ,["until"]= true ,["continue"]= true ,["plugin"]= true ,} local lua_builtin={["assert"]= true ;["collectgarbage"]= true ;["error"]= true ;["getfenv"]= true ;["getmetatable"]= true ;["ipairs"]= true ;["loadstring"]= true ;["newproxy"]= true ;["next"]= true ;["pairs"]= true ;["pcall"]= true ;["print"]= true ;["rawequal"]= true ;["rawget"]= true ;["rawset"]= true ;["select"]= true ;["setfenv"]= true ;["setmetatable"]= true ;["tonumber"]= true ;["tostring"]= true ;["type"]= true ;["unpack"]= true ;["xpcall"]= true ;["_G"]= true ;["_VERSION"]= true ;["bit32"]= true ;["coroutine"]= true ;["debug"]= true ;["math"]= true ;["os"]= true ;["string"]= true ;["table"]= true ;["utf8"]= true ;["delay"]= true ;["elapsedTime"]= true ;["gcinfo"]= true ;["require"]= true ;["settings"]= true ;["spawn"]= true ;["tick"]= true ;["time"]= true ;["typeof"]= true ;["UserSettings"]= true ;["wait"]= true ;["warn"]= true ;["ypcall"]= true ;["Enum"]= true ;["game"]= true ;["shared"]= true ;["script"]= true ;["workspace"]= true ;["Axes"]= true ;["BrickColor"]= true ;["CellId"]= true ;["CFrame"]= true ;["Color3"]= true ;["ColorSequence"]= true ;["ColorSequenceKeypoint"]= true ;["DateTime"]= true ;["DockWidgetPluginGuiInfo"]= true ;["Faces"]= true ;["Instance"]= true ;["NumberRange"]= true ;["NumberSequence"]= true ;["NumberSequenceKeypoint"]= true ;["PathWaypoint"]= true ;["PhysicalProperties"]= true ;["PluginDrag"]= true ;["Random"]= true ;["Ray"]= true ;["Rect"]= true ;["Region3"]= true ;["Region3int16"]= true ;["TweenInfo"]= true ;["UDim"]= true ;["UDim2"]= true ;["Vector2"]= true ;["Vector2int16"]= true ;["Vector3"]= true ;["Vector3int16"]= true ;} local function idump(tok) return coroutine.yield("iden",tok) end local function odump(tok) return coroutine.yield("operator",tok) end local function ndump(tok) return coroutine.yield("number",tok) end local function sdump(tok) return coroutine.yield("string",tok) end local function cdump(tok) return coroutine.yield("comment",tok) end local function lua_vdump(tok) local cleanTok=string.gsub(tok,Cleaner,"") if lua_keyword[cleanTok] then return coroutine.yield("keyword",tok) elseif lua_builtin[cleanTok] then return coroutine.yield("builtin",tok) else return coroutine.yield("iden",tok) end end local lua_matches={{Prefix..IDEN..Suffix,lua_vdump},{Prefix..NUMBER_A..Suffix,ndump},{Prefix..NUMBER_B..Suffix,ndump},{Prefix..NUMBER_C..Suffix,ndump},{Prefix..STRING_EMPTY..Suffix,sdump},{Prefix..STRING_PLAIN..Suffix,sdump},{Prefix..STRING_INCOMP_A..Suffix,sdump},{Prefix..STRING_INCOMP_B..Suffix,sdump},{Prefix..STRING_MULTI..Suffix,sdump},{Prefix..STRING_MULTI_INCOMP..Suffix,sdump},{Prefix..COMMENT_MULTI..Suffix,cdump},{Prefix..COMMENT_MULTI_INCOMP..Suffix,cdump},{Prefix..COMMENT_PLAIN..Suffix,cdump},{Prefix..COMMENT_INCOMP..Suffix,cdump},{Prefix..OPERATORS..Suffix,odump},{Prefix..BRACKETS..Suffix,odump},{"^.",idump}} function lexer.scan(s) local startTime=os.clock()lexer.finished= false local function lex(first_arg) local line_nr=0 local sz=#s local idx=1 local function handle_requests(res) while res do local tp=type(res) if tp=="table" then res=coroutine.yield("","") for _,t in ipairs(res) do res=coroutine.yield(t[1],t[2]) end elseif tp=="string" then local i1,i2=string.find(s,res,idx) if i1 then idx=i2+1res=coroutine.yield("",string.sub(s,i1,i2)) else res=coroutine.yield("","")idx=sz+1 end else res=coroutine.yield(line_nr,idx) end end end handle_requests(first_arg)line_nr=1 while true do if idx>sz then while true do handle_requests(coroutine.yield()) end end for _,m in ipairs(lua_matches) do local findres={} local i1,i2=string.find(s,m[1],idx)findres[1],findres[2]=i1,i2 if i1 then local tok=string.sub(s,i1,i2)idx=i2+1lexer.finished=idx>sz local res=m[2](tok,findres) if string.find(tok,"\n") then local _,newlines=string.gsub(tok,"\n",TABLE_EMPTY)line_nr=line_nr+newlines end handle_requests(res) break end end end end return coroutine.wrap(lex) end -- Transformers local function trim(s) local r, _ = s:gsub("^%s+",""):gsub("%s-$","") return r end local function blank() return "" end local function padend(s) return trim(s).." " end local function pad(s) return " "..trim(s).." " end -- Lookup a token's transformer local transform = { ["string"] = trim; ["operator"] = trim; ["number"] = trim; ["iden"] = trim; ["builtin"] = trim; ["space"] = blank; ["comment"] = blank; ["keyword"] = function(s, previous) s = trim(s) return ( previous == nil -- Beginning of string or (previous[1]~="keyword" and previous[1]~="iden") -- Not a keyword or variable or (previous[2] and previous[2]:sub(previous[2]:len(),-1) == " ") -- Already has a space ) and padend(s) or pad(s) end } return function(s) local minified = "" local previous for token, src in lexer.scan(s) do local transformed = transform[token] and transform[token](src, previous) or src minified = minified..transformed previous = {token, transformed} end return minified end
Editor Settings
Theme
Key bindings
Full width
Lines