mirror of
https://github.com/lifestorm/wnsrc.git
synced 2025-12-16 21:33:46 +03:00
462 lines
13 KiB
Lua
462 lines
13 KiB
Lua
--[[
|
|
| This file was obtained through the combined efforts
|
|
| of Madbluntz & Plymouth Antiquarian Society.
|
|
|
|
|
| Credits: lifestorm, Gregory Wayne Rossel JR.,
|
|
| Maloy, DrPepper10 @ RIP, Atle!
|
|
|
|
|
| Visit for more: https://plymouth.thetwilightzone.ru/
|
|
--]]
|
|
|
|
|
|
local string = string
|
|
local math = math
|
|
|
|
--[[---------------------------------------------------------
|
|
Name: string.ToTable( string )
|
|
-----------------------------------------------------------]]
|
|
function string.ToTable( input )
|
|
local tbl = {}
|
|
|
|
-- For numbers, as some addons do this..
|
|
local str = tostring( input )
|
|
|
|
for i = 1, #str do
|
|
tbl[i] = string.sub( str, i, i )
|
|
end
|
|
|
|
return tbl
|
|
end
|
|
|
|
--[[---------------------------------------------------------
|
|
Name: string.JavascriptSafe( string )
|
|
Desc: Takes a string and escapes it for insertion in to a JavaScript string
|
|
-----------------------------------------------------------]]
|
|
local javascript_escape_replacements = {
|
|
["\\"] = "\\\\",
|
|
["\0"] = "\\x00" ,
|
|
["\b"] = "\\b" ,
|
|
["\t"] = "\\t" ,
|
|
["\n"] = "\\n" ,
|
|
["\v"] = "\\v" ,
|
|
["\f"] = "\\f" ,
|
|
["\r"] = "\\r" ,
|
|
["\""] = "\\\"",
|
|
["\'"] = "\\\'",
|
|
["`"] = "\\`",
|
|
["$"] = "\\$",
|
|
["{"] = "\\{",
|
|
["}"] = "\\}"
|
|
}
|
|
|
|
function string.JavascriptSafe( str )
|
|
|
|
str = string.gsub( str, ".", javascript_escape_replacements )
|
|
|
|
-- U+2028 and U+2029 are treated as line separators in JavaScript, handle separately as they aren't single-byte
|
|
str = string.gsub( str, "\226\128\168", "\\\226\128\168" )
|
|
str = string.gsub( str, "\226\128\169", "\\\226\128\169" )
|
|
|
|
return str
|
|
|
|
end
|
|
|
|
--[[---------------------------------------------------------
|
|
Name: string.PatternSafe( string )
|
|
Desc: Takes a string and escapes it for insertion in to a Lua pattern
|
|
-----------------------------------------------------------]]
|
|
local pattern_escape_replacements = {
|
|
["("] = "%(",
|
|
[")"] = "%)",
|
|
["."] = "%.",
|
|
["%"] = "%%",
|
|
["+"] = "%+",
|
|
["-"] = "%-",
|
|
["*"] = "%*",
|
|
["?"] = "%?",
|
|
["["] = "%[",
|
|
["]"] = "%]",
|
|
["^"] = "%^",
|
|
["$"] = "%$",
|
|
["\0"] = "%z"
|
|
}
|
|
|
|
function string.PatternSafe( str )
|
|
return ( string.gsub( str, ".", pattern_escape_replacements ) )
|
|
end
|
|
|
|
--[[---------------------------------------------------------
|
|
Name: explode(seperator ,string)
|
|
Desc: Takes a string and turns it into a table
|
|
Usage: string.explode( " ", "Seperate this string")
|
|
-----------------------------------------------------------]]
|
|
local totable = string.ToTable
|
|
local string_sub = string.sub
|
|
local string_find = string.find
|
|
local string_len = string.len
|
|
function string.Explode( separator, str, withpattern )
|
|
if ( separator == "" ) then return totable( str ) end
|
|
if ( withpattern == nil ) then withpattern = false end
|
|
|
|
local ret = {}
|
|
local current_pos = 1
|
|
|
|
for i = 1, string_len( str ) do
|
|
local start_pos, end_pos = string_find( str, separator, current_pos, not withpattern )
|
|
if ( not start_pos ) then break end
|
|
ret[ i ] = string_sub( str, current_pos, start_pos - 1 )
|
|
current_pos = end_pos + 1
|
|
end
|
|
|
|
ret[ #ret + 1 ] = string_sub( str, current_pos )
|
|
|
|
return ret
|
|
end
|
|
|
|
function string.Split( str, delimiter )
|
|
return string.Explode( delimiter, str )
|
|
end
|
|
|
|
--[[---------------------------------------------------------
|
|
Name: Implode( seperator, Table)
|
|
Desc: Takes a table and turns it into a string
|
|
Usage: string.Implode( " ", { "This", "Is", "A", "Table" } )
|
|
-----------------------------------------------------------]]
|
|
function string.Implode( seperator, Table ) return
|
|
table.concat( Table, seperator )
|
|
end
|
|
|
|
--[[---------------------------------------------------------
|
|
Name: GetExtensionFromFilename( path )
|
|
Desc: Returns extension from path
|
|
Usage: string.GetExtensionFromFilename("garrysmod/lua/modules/string.lua")
|
|
-----------------------------------------------------------]]
|
|
function string.GetExtensionFromFilename( path )
|
|
for i = #path, 1, -1 do
|
|
local c = string.sub( path, i, i )
|
|
if ( c == "/" or c == "\\" ) then return nil end
|
|
if ( c == "." ) then return string.sub( path, i + 1 ) end
|
|
end
|
|
|
|
return nil
|
|
end
|
|
|
|
--[[---------------------------------------------------------
|
|
Name: StripExtension( path )
|
|
-----------------------------------------------------------]]
|
|
function string.StripExtension( path )
|
|
for i = #path, 1, -1 do
|
|
local c = string.sub( path, i, i )
|
|
if ( c == "/" or c == "\\" ) then return path end
|
|
if ( c == "." ) then return string.sub( path, 1, i - 1 ) end
|
|
end
|
|
|
|
return path
|
|
end
|
|
|
|
--[[---------------------------------------------------------
|
|
Name: GetPathFromFilename( path )
|
|
Desc: Returns path from filepath
|
|
Usage: string.GetPathFromFilename("garrysmod/lua/modules/string.lua")
|
|
-----------------------------------------------------------]]
|
|
function string.GetPathFromFilename( path )
|
|
for i = #path, 1, -1 do
|
|
local c = string.sub( path, i, i )
|
|
if ( c == "/" or c == "\\" ) then return string.sub( path, 1, i ) end
|
|
end
|
|
|
|
return ""
|
|
end
|
|
|
|
--[[---------------------------------------------------------
|
|
Name: GetFileFromFilename( path )
|
|
Desc: Returns file with extension from path
|
|
Usage: string.GetFileFromFilename("garrysmod/lua/modules/string.lua")
|
|
-----------------------------------------------------------]]
|
|
function string.GetFileFromFilename( path )
|
|
for i = #path, 1, -1 do
|
|
local c = string.sub( path, i, i )
|
|
if ( c == "/" or c == "\\" ) then return string.sub( path, i + 1 ) end
|
|
end
|
|
|
|
return path
|
|
end
|
|
|
|
--[[-----------------------------------------------------------------
|
|
Name: FormattedTime( TimeInSeconds, Format )
|
|
Desc: Given a time in seconds, returns formatted time
|
|
If 'Format' is not specified the function returns a table
|
|
conatining values for hours, mins, secs, ms
|
|
|
|
Examples: string.FormattedTime( 123.456, "%02i:%02i:%02i") ==> "02:03:45"
|
|
string.FormattedTime( 123.456, "%02i:%02i") ==> "02:03"
|
|
string.FormattedTime( 123.456, "%2i:%02i") ==> " 2:03"
|
|
string.FormattedTime( 123.456 ) ==> { h = 0, m = 2, s = 3, ms = 45 }
|
|
-------------------------------------------------------------------]]
|
|
function string.FormattedTime( seconds, format )
|
|
if ( not seconds ) then seconds = 0 end
|
|
local hours = math.floor( seconds / 3600 )
|
|
local minutes = math.floor( ( seconds / 60 ) % 60 )
|
|
local millisecs = ( seconds - math.floor( seconds ) ) * 100
|
|
seconds = math.floor( seconds % 60 )
|
|
|
|
if ( format ) then
|
|
return string.format( format, minutes, seconds, millisecs )
|
|
else
|
|
return { h = hours, m = minutes, s = seconds, ms = millisecs }
|
|
end
|
|
end
|
|
|
|
--[[---------------------------------------------------------
|
|
Name: Old time functions
|
|
-----------------------------------------------------------]]
|
|
function string.ToMinutesSecondsMilliseconds( TimeInSeconds ) return string.FormattedTime( TimeInSeconds, "%02i:%02i:%02i" ) end
|
|
function string.ToMinutesSeconds( TimeInSeconds ) return string.FormattedTime( TimeInSeconds, "%02i:%02i" ) end
|
|
|
|
local function pluralizeString( str, quantity )
|
|
return str .. ( ( quantity ~= 1 ) and "s" or "" )
|
|
end
|
|
|
|
function string.NiceTime( seconds )
|
|
|
|
if ( seconds == nil ) then return "a few seconds" end
|
|
|
|
if ( seconds < 60 ) then
|
|
local t = math.floor( seconds )
|
|
return t .. pluralizeString( " second", t )
|
|
end
|
|
|
|
if ( seconds < 60 * 60 ) then
|
|
local t = math.floor( seconds / 60 )
|
|
return t .. pluralizeString( " minute", t )
|
|
end
|
|
|
|
if ( seconds < 60 * 60 * 24 ) then
|
|
local t = math.floor( seconds / (60 * 60) )
|
|
return t .. pluralizeString( " hour", t )
|
|
end
|
|
|
|
if ( seconds < 60 * 60 * 24 * 7 ) then
|
|
local t = math.floor( seconds / ( 60 * 60 * 24 ) )
|
|
return t .. pluralizeString( " day", t )
|
|
end
|
|
|
|
if ( seconds < 60 * 60 * 24 * 365 ) then
|
|
local t = math.floor( seconds / ( 60 * 60 * 24 * 7 ) )
|
|
return t .. pluralizeString( " week", t )
|
|
end
|
|
|
|
local t = math.floor( seconds / ( 60 * 60 * 24 * 365 ) )
|
|
return t .. pluralizeString( " year", t )
|
|
|
|
end
|
|
|
|
function string.Left( str, num ) return string.sub( str, 1, num ) end
|
|
function string.Right( str, num ) return string.sub( str, -num ) end
|
|
|
|
function string.Replace( str, tofind, toreplace )
|
|
local tbl = string.Explode( tofind, str )
|
|
if ( tbl[ 1 ] ) then return table.concat( tbl, toreplace ) end
|
|
return str
|
|
end
|
|
|
|
--[[---------------------------------------------------------
|
|
Name: Trim( s )
|
|
Desc: Removes leading and trailing spaces from a string.
|
|
Optionally pass char to trim that character from the ends instead of space
|
|
-----------------------------------------------------------]]
|
|
function string.Trim( s, char )
|
|
if ( char ) then char = string.PatternSafe( char ) else char = "%s" end
|
|
return string.match( s, "^" .. char .. "*(.-)" .. char .. "*$" ) or s
|
|
end
|
|
|
|
--[[---------------------------------------------------------
|
|
Name: TrimRight( s )
|
|
Desc: Removes trailing spaces from a string.
|
|
Optionally pass char to trim that character from the ends instead of space
|
|
-----------------------------------------------------------]]
|
|
function string.TrimRight( s, char )
|
|
if ( char ) then char = string.PatternSafe( char ) else char = "%s" end
|
|
return string.match( s, "^(.-)" .. char .. "*$" ) or s
|
|
end
|
|
|
|
--[[---------------------------------------------------------
|
|
Name: TrimLeft( s )
|
|
Desc: Removes leading spaces from a string.
|
|
Optionally pass char to trim that character from the ends instead of space
|
|
-----------------------------------------------------------]]
|
|
function string.TrimLeft( s, char )
|
|
if ( char ) then char = string.PatternSafe( char ) else char = "%s" end
|
|
return string.match( s, "^" .. char .. "*(.+)$" ) or s
|
|
end
|
|
|
|
function string.NiceSize( size )
|
|
|
|
size = tonumber( size )
|
|
|
|
if ( size <= 0 ) then return "0" end
|
|
if ( size < 1000 ) then return size .. " Bytes" end
|
|
if ( size < 1000 * 1000 ) then return math.Round( size / 1000, 2 ) .. " KB" end
|
|
if ( size < 1000 * 1000 * 1000 ) then return math.Round( size / ( 1000 * 1000 ), 2 ) .. " MB" end
|
|
|
|
return math.Round( size / ( 1000 * 1000 * 1000 ), 2 ) .. " GB"
|
|
|
|
end
|
|
|
|
-- Note: These use Lua index numbering, not what you'd expect
|
|
-- ie they start from 1, not 0.
|
|
|
|
function string.SetChar( s, k, v )
|
|
|
|
return string.sub( s, 0, k - 1 ) .. v .. string.sub( s, k + 1 )
|
|
|
|
end
|
|
|
|
function string.GetChar( s, k )
|
|
|
|
return string.sub( s, k, k )
|
|
|
|
end
|
|
|
|
local meta = getmetatable( "" )
|
|
|
|
function meta:__index( key )
|
|
|
|
local val = string[ key ]
|
|
if ( val ~= nil ) then
|
|
return val
|
|
elseif ( tonumber( key ) ) then
|
|
return string.sub( self, key, key )
|
|
end
|
|
|
|
end
|
|
|
|
function string.StartsWith( str, start )
|
|
|
|
return string.sub( str, 1, string.len( start ) ) == start
|
|
|
|
end
|
|
string.StartWith = string.StartsWith
|
|
|
|
function string.EndsWith( str, endStr )
|
|
|
|
return endStr == "" or string.sub( str, -string.len( endStr ) ) == endStr
|
|
|
|
end
|
|
|
|
function string.FromColor( color )
|
|
|
|
return Format( "%i %i %i %i", color.r, color.g, color.b, color.a )
|
|
|
|
end
|
|
|
|
function string.ToColor( str )
|
|
|
|
local r, g, b, a = string.match( str, "(%d+) (%d+) (%d+) (%d+)" )
|
|
|
|
local col = Color( 255, 255, 255, 255 )
|
|
col.r = tonumber( r ) or 255
|
|
col.g = tonumber( g ) or 255
|
|
col.b = tonumber( b ) or 255
|
|
col.a = tonumber( a ) or 255
|
|
|
|
return col
|
|
|
|
end
|
|
|
|
function string.Comma( number, str )
|
|
|
|
if ( str ~= nil and not isstring( str ) ) then
|
|
error( "bad argument #2 to 'string.Comma' (string expected, got " .. type( str ) .. ")" )
|
|
elseif ( str ~= nil and string.match( str, "%d" ) ~= nil ) then
|
|
error( "bad argument #2 to 'string.Comma' (non-numerical values expected, got " .. str .. ")" )
|
|
end
|
|
|
|
local replace = str == nil and "%1,%2" or "%1" .. str .. "%2"
|
|
|
|
if ( isnumber( number ) ) then
|
|
number = string.format( "%f", number )
|
|
number = string.match( number, "^(.-)%.?0*$" ) -- Remove trailing zeros
|
|
end
|
|
|
|
local index = -1
|
|
while index ~= 0 do number, index = string.gsub( number, "^(-?%d+)(%d%d%d)", replace ) end
|
|
|
|
return number
|
|
|
|
end
|
|
|
|
function string.Interpolate( str, lookuptable )
|
|
|
|
return ( string.gsub( str, "{([_%a][_%w]*)}", lookuptable ) )
|
|
|
|
end
|
|
|
|
function string.CardinalToOrdinal( cardinal )
|
|
|
|
local basedigit = cardinal % 10
|
|
|
|
if ( basedigit == 1 ) then
|
|
if ( cardinal % 100 == 11 ) then
|
|
return cardinal .. "th"
|
|
end
|
|
|
|
return cardinal .. "st"
|
|
elseif ( basedigit == 2 ) then
|
|
if ( cardinal % 100 == 12 ) then
|
|
return cardinal .. "th"
|
|
end
|
|
|
|
return cardinal .. "nd"
|
|
elseif ( basedigit == 3 ) then
|
|
if ( cardinal % 100 == 13 ) then
|
|
return cardinal .. "th"
|
|
end
|
|
|
|
return cardinal .. "rd"
|
|
end
|
|
|
|
return cardinal .. "th"
|
|
|
|
end
|
|
|
|
function string.NiceName( name )
|
|
|
|
name = name:Replace( "_", " " )
|
|
|
|
-- Try to split text into words, where words would start with single uppercase character
|
|
local newParts = {}
|
|
for id, str in ipairs( string.Explode( " ", name ) ) do
|
|
local wordStart = 1
|
|
for i = 2, str:len() do
|
|
local c = str[ i ]
|
|
if ( c:upper() == c ) then
|
|
local toAdd = str:sub( wordStart, i - 1 )
|
|
if ( toAdd:upper() == toAdd ) then continue end
|
|
table.insert( newParts, toAdd )
|
|
wordStart = i
|
|
end
|
|
|
|
end
|
|
|
|
table.insert( newParts, str:sub( wordStart, str:len() ) )
|
|
end
|
|
|
|
-- Capitalize
|
|
--[[
|
|
for i, word in ipairs( newParts ) do
|
|
if ( #word == 1 ) then
|
|
newParts[i] = string.upper( word )
|
|
else
|
|
newParts[i] = string.upper( string.sub( word, 1, 1 ) ) .. string.sub( word, 2 )
|
|
end
|
|
end
|
|
|
|
return table.concat( newParts, " " )]]
|
|
|
|
local ret = table.concat( newParts, " " )
|
|
ret = string.upper( string.sub( ret, 1, 1 ) ) .. string.sub( ret, 2 )
|
|
return ret
|
|
|
|
end
|