1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
|
if not modules then modules = { } end modules ['util-str'] = {
version = 1.001,
comment = "companion to luat-lib.mkiv",
author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
copyright = "PRAGMA ADE / ConTeXt Development Team",
license = "see context related readme files"
}
utilities = utilities or {}
utilities.strings = utilities.strings or { }
local strings = utilities.strings
local gsub, rep = string.gsub, string.rep
local Cs, C, Cp, P, Carg = lpeg.Cs, lpeg.C, lpeg.Cp, lpeg.P, lpeg.Carg
local patterns, lpegmatch = lpeg.patterns, lpeg.match
-- str = " \n \ntest \n test\ntest "
-- print("["..string.gsub(string.collapsecrlf(str),"\n","+").."]")
local rubish = patterns.spaceortab^0 * patterns.newline
local anyrubish = patterns.spaceortab + patterns.newline
local anything = patterns.anything
local stripped = (patterns.spaceortab^1 / "") * patterns.newline
local leading = rubish^0 / ""
local trailing = (anyrubish^1 * patterns.endofstring) / ""
local redundant = rubish^3 / "\n"
local pattern = Cs(leading * (trailing + redundant + stripped + anything)^0)
function strings.collapsecrlf(str)
return lpegmatch(pattern,str)
end
-- The following functions might end up in another namespace.
local repeaters = { } -- watch how we also moved the -1 in depth-1 to the creator
function strings.newrepeater(str,offset)
offset = offset or 0
local s = repeaters[str]
if not s then
s = { }
repeaters[str] = s
end
local t = s[offset]
if t then
return t
end
t = { }
setmetatable(t, {
__index = function(t,k)
if not k then
return ""
end
local n = k + offset
local s = n > 0 and rep(str,n) or ""
t[k] = s
return s
end
} )
s[offset] = t
return t
end
--~ local dashes = strings.newrepeater("--",-1)
--~ print(dashes[2])
--~ print(dashes[3])
--~ print(dashes[1])
local extra, tab, start = 0, 0, 4, 0
local nspaces = strings.newrepeater(" ")
local pattern =
Carg(1) / function(t)
extra, tab, start = 0, t or 7, 1
end
* Cs((
Cp() * patterns.tab / function(position)
local current = (position - start + 1) + extra
local spaces = tab-(current-1) % tab
if spaces > 0 then
extra = extra + spaces - 1
return nspaces[spaces] -- rep(" ",spaces)
else
return ""
end
end
+ patterns.newline * Cp() / function(position)
extra, start = 0, position
end
+ patterns.anything
)^1)
function strings.tabtospace(str,tab)
return lpegmatch(pattern,str,1,tab or 7)
end
--~ local t = {
--~ "1234567123456712345671234567",
--~ "\tb\tc",
--~ "a\tb\tc",
--~ "aa\tbb\tcc",
--~ "aaa\tbbb\tccc",
--~ "aaaa\tbbbb\tcccc",
--~ "aaaaa\tbbbbb\tccccc",
--~ "aaaaaa\tbbbbbb\tcccccc\n aaaaaa\tbbbbbb\tcccccc",
--~ "one\n two\nxxx three\nxx four\nx five\nsix",
--~ }
--~ for k=1,#t do
--~ print(strings.tabtospace(t[k]))
--~ end
function strings.striplong(str) -- strips all leading spaces
str = gsub(str,"^%s*","")
str = gsub(str,"[\n\r]+ *","\n")
return str
end
--~ local template = string.striplong([[
--~ aaaa
--~ bb
--~ cccccc
--~ ]])
function strings.nice(str)
str = gsub(str,"[:%-+_]+"," ") -- maybe more
return str
end
|