summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/tex/context/base/l-string.lua
diff options
context:
space:
mode:
Diffstat (limited to 'Master/texmf-dist/tex/context/base/l-string.lua')
-rw-r--r--Master/texmf-dist/tex/context/base/l-string.lua358
1 files changed, 358 insertions, 0 deletions
diff --git a/Master/texmf-dist/tex/context/base/l-string.lua b/Master/texmf-dist/tex/context/base/l-string.lua
new file mode 100644
index 00000000000..6a3bea31c18
--- /dev/null
+++ b/Master/texmf-dist/tex/context/base/l-string.lua
@@ -0,0 +1,358 @@
+-- filename : l-string.lua
+-- comment : split off from luat-lib
+-- author : Hans Hagen, PRAGMA-ADE, Hasselt NL
+-- copyright: PRAGMA ADE / ConTeXt Development Team
+-- license : see context related readme files
+
+if not versions then versions = { } end versions['l-string'] = 1.001
+
+--~ function string.split(str, pat) -- taken from the lua wiki
+--~ local t = {n = 0} -- so this table has a length field, traverse with ipairs then!
+--~ local fpat = "(.-)"..pat
+--~ local last_end = 1
+--~ local s, e, cap = string.find(str, fpat, 1)
+--~ while s ~= nil do
+--~ if s~=1 or cap~="" then
+--~ table.insert(t,cap)
+--~ end
+--~ last_end = e+1
+--~ s, e, cap = string.find(str, fpat, last_end)
+--~ end
+--~ if last_end<=string.len(str) then
+--~ table.insert(t,(string.sub(str,last_end)))
+--~ end
+--~ return t
+--~ end
+
+--~ function string:split(pat) -- taken from the lua wiki but adapted
+--~ local t = { } -- self and colon usage (faster)
+--~ local fpat = "(.-)"..pat
+--~ local last_end = 1
+--~ local s, e, cap = self:find(fpat, 1)
+--~ while s ~= nil do
+--~ if s~=1 or cap~="" then
+--~ t[#t+1] = cap
+--~ end
+--~ last_end = e+1
+--~ s, e, cap = self:find(fpat, last_end)
+--~ end
+--~ if last_end <= #self then
+--~ t[#t+1] = self:sub(last_end)
+--~ end
+--~ return t
+--~ end
+
+--~ a piece of brilliant code by Rici Lake (posted on lua list) -- only names changed
+--~
+--~ function string:splitter(pat)
+--~ local st, g = 1, self:gmatch("()"..pat.."()")
+--~ local function splitter(self)
+--~ if st then
+--~ local s, f = g()
+--~ local rv = self:sub(st, (s or 0)-1)
+--~ st = f
+--~ return rv
+--~ end
+--~ end
+--~ return splitter, self
+--~ end
+
+function string:splitter(pat)
+ -- by Rici Lake (posted on lua list) -- only names changed
+ -- p 79 ref man: () returns position of match
+ local st, g = 1, self:gmatch("()("..pat..")")
+ local function strgetter(self, segs, seps, sep, cap1, ...)
+ st = sep and seps + #sep
+ return self:sub(segs, (seps or 0) - 1), cap1 or sep, ...
+ end
+ local function strsplitter(self)
+ if st then return strgetter(self, st, g()) end
+ end
+ return strsplitter, self
+end
+
+function string:split(separator)
+ local t = {}
+ for k in self:splitter(separator) do t[#t+1] = k end
+ return t
+end
+
+-- faster than a string:split:
+
+function string:splitchr(chr)
+ if #self > 0 then
+ local t = { }
+ for s in string.gmatch(self..chr,"(.-)"..chr) do
+ t[#t+1] = s
+ end
+ return t
+ else
+ return { }
+ end
+end
+
+--~ function string.piecewise(str, pat, fnc) -- variant of split
+--~ local fpat = "(.-)"..pat
+--~ local last_end = 1
+--~ local s, e, cap = string.find(str, fpat, 1)
+--~ while s ~= nil do
+--~ if s~=1 or cap~="" then
+--~ fnc(cap)
+--~ end
+--~ last_end = e+1
+--~ s, e, cap = string.find(str, fpat, last_end)
+--~ end
+--~ if last_end <= #str then
+--~ fnc((string.sub(str,last_end)))
+--~ end
+--~ end
+
+function string.piecewise(str, pat, fnc) -- variant of split
+ for k in string.splitter(str,pat) do fnc(k) end
+end
+
+--~ function string.piecewise(str, pat, fnc) -- variant of split
+--~ for k in str:splitter(pat) do fnc(k) end
+--~ end
+
+--~ do if lpeg then
+
+--~ -- this alternative is 30% faster esp when we cache them
+--~ -- problem: no expressions
+
+--~ splitters = { }
+
+--~ function string:split(separator)
+--~ if #self > 0 then
+--~ local split = splitters[separator]
+--~ if not split then
+--~ -- based on code by Roberto
+--~ local p = lpeg.P(separator)
+--~ local c = lpeg.C((1-p)^0)
+--~ split = lpeg.Ct(c*(p*c)^0)
+--~ splitters[separator] = split
+--~ end
+--~ return split:match(self)
+--~ else
+--~ return { }
+--~ end
+--~ end
+
+--~ string.splitchr = string.split
+
+--~ function string:piecewise(separator,fnc)
+--~ for _,v in pairs(self:split(separator)) do
+--~ fnc(v)
+--~ end
+--~ end
+
+--~ end end
+
+string.chr_to_esc = {
+ ["%"] = "%%",
+ ["."] = "%.",
+ ["+"] = "%+", ["-"] = "%-", ["*"] = "%*",
+ ["^"] = "%^", ["$"] = "%$",
+ ["["] = "%[", ["]"] = "%]",
+ ["("] = "%(", [")"] = "%)",
+ ["{"] = "%{", ["}"] = "%}"
+}
+
+function string:esc() -- variant 2
+ return (self:gsub("(.)",string.chr_to_esc))
+end
+
+function string.unquote(str)
+ return (str:gsub("^([\"\'])(.*)%1$","%2"))
+end
+
+function string.quote(str)
+ return '"' .. str:unquote() .. '"'
+end
+
+function string:count(pattern) -- variant 3
+ local n = 0
+ for _ in self:gmatch(pattern) do
+ n = n + 1
+ end
+ return n
+end
+
+function string:limit(n,sentinel)
+ if #self > n then
+ sentinel = sentinel or " ..."
+ return self:sub(1,(n-#sentinel)) .. sentinel
+ else
+ return self
+ end
+end
+
+function string:strip()
+ return (self:gsub("^%s*(.-)%s*$", "%1"))
+end
+
+--~ function string.strip(str) -- slightly different
+--~ return (string.gsub(string.gsub(str,"^%s*(.-)%s*$","%1"),"%s+"," "))
+--~ end
+
+function string:is_empty()
+ return not self:find("%S")
+end
+
+function string:enhance(pattern,action)
+ local ok, n = true, 0
+ while ok do
+ ok = false
+ self = self:gsub(pattern, function(...)
+ ok, n = true, n + 1
+ return action(...)
+ end)
+ end
+ return self, n
+end
+
+--~ function string:enhance(pattern,action)
+--~ local ok, n = 0, 0
+--~ repeat
+--~ self, ok = self:gsub(pattern, function(...)
+--~ n = n + 1
+--~ return action(...)
+--~ end)
+--~ until ok == 0
+--~ return self, n
+--~ end
+
+--~ function string:to_hex()
+--~ if self then
+--~ return (self:gsub("(.)",function(c)
+--~ return string.format("%02X",c:byte())
+--~ end))
+--~ else
+--~ return ""
+--~ end
+--~ end
+
+--~ function string:from_hex()
+--~ if self then
+--~ return (self:gsub("(..)",function(c)
+--~ return string.char(tonumber(c,16))
+--~ end))
+--~ else
+--~ return ""
+--~ end
+--~ end
+
+string.chr_to_hex = { }
+string.hex_to_chr = { }
+
+for i=0,255 do
+ local c, h = string.char(i), string.format("%02X",i)
+ string.chr_to_hex[c], string.hex_to_chr[h] = h, c
+end
+
+--~ function string:to_hex()
+--~ if self then return (self:gsub("(.)",string.chr_to_hex)) else return "" end
+--~ end
+
+--~ function string:from_hex()
+--~ if self then return (self:gsub("(..)",string.hex_to_chr)) else return "" end
+--~ end
+
+function string:to_hex()
+ return ((self or ""):gsub("(.)",string.chr_to_hex))
+end
+
+function string:from_hex()
+ return ((self or ""):gsub("(..)",string.hex_to_chr))
+end
+
+if not string.characters then
+
+ local function nextchar(str, index)
+ index = index + 1
+ return (index <= #str) and index or nil, str:sub(index,index)
+ end
+ function string:characters()
+ return nextchar, self, 0
+ end
+ local function nextbyte(str, index)
+ index = index + 1
+ return (index <= #str) and index or nil, string.byte(str:sub(index,index))
+ end
+ function string:bytes()
+ return nextbyte, self, 0
+ end
+
+end
+
+--~ function string:padd(n,chr)
+--~ return self .. self.rep(chr or " ",n-#self)
+--~ end
+
+function string:rpadd(n,chr)
+ local m = n-#self
+ if m > 0 then
+ return self .. self.rep(chr or " ",m)
+ else
+ return self
+ end
+end
+
+function string:lpadd(n,chr)
+ local m = n-#self
+ if m > 0 then
+ return self.rep(chr or " ",m) .. self
+ else
+ return self
+ end
+end
+
+string.padd = string.rpadd
+
+function is_number(str)
+ return str:find("^[%-%+]?[%d]-%.?[%d+]$") == 1
+end
+
+--~ print(is_number("1"))
+--~ print(is_number("1.1"))
+--~ print(is_number(".1"))
+--~ print(is_number("-0.1"))
+--~ print(is_number("+0.1"))
+--~ print(is_number("-.1"))
+--~ print(is_number("+.1"))
+
+function string:split_settings() -- no {} handling, see l-aux for lpeg variant
+ if self:find("=") then
+ local t = { }
+ for k,v in self:gmatch("(%a+)=([^%,]*)") do
+ t[k] = v
+ end
+ return t
+ else
+ return nil
+ end
+end
+
+local patterns_escapes = {
+ ["-"] = "%-",
+ ["."] = "%.",
+ ["+"] = "%+",
+ ["*"] = "%*",
+ ["%"] = "%%",
+ ["("] = "%)",
+ [")"] = "%)",
+ ["["] = "%[",
+ ["]"] = "%]",
+}
+
+function string:pattesc()
+ return (self:gsub(".",patterns_escapes))
+end
+
+function string:tohash()
+ local t = { }
+ for s in self:gmatch("([^, ]+)") do -- lpeg
+ t[s] = true
+ end
+ return t
+end