1if not modules then modules = { } end modules ['l-string'] = {
2 version = 1.001,
3 comment = "companion to luat-lib.mkiv",
4 author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
5 copyright = "PRAGMA ADE / ConTeXt Development Team",
6 license = "see context related readme files"
7}
8
9local string = string
10local sub, gmatch, format, char, byte, rep, lower = string.sub, string.gmatch, string.format, string.char, string.byte, string.rep, string.lower
11local lpegmatch, patterns = lpeg.match, lpeg.patterns
12local P, S, C, Ct, Cc, Cs = lpeg.P, lpeg.S, lpeg.C, lpeg.Ct, lpeg.Cc, lpeg.Cs
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37local unquoted = patterns.squote * C(patterns.nosquote) * patterns.squote
38 + patterns.dquote * C(patterns.nodquote) * patterns.dquote
39
40function string.unquoted(str)
41 return lpegmatch(unquoted,str) or str
42end
43
44
45
46
47
48
49
50
51function string.quoted(str)
52 return format("%q",str)
53end
54
55function string.count(str,pattern)
56 local n = 0
57 for _ in gmatch(str,pattern) do
58 n = n + 1
59 end
60 return n
61end
62
63function string.limit(str,n,sentinel)
64 if #str > n then
65 sentinel = sentinel or "..."
66 return sub(str,1,(n-#sentinel)) .. sentinel
67 else
68 return str
69 end
70end
71
72local stripper = patterns.stripper
73local fullstripper = patterns.fullstripper
74local collapser = patterns.collapser
75local nospacer = patterns.nospacer
76local longtostring = patterns.longtostring
77
78function string.strip(str)
79 return str and lpegmatch(stripper,str) or ""
80end
81
82function string.fullstrip(str)
83 return str and lpegmatch(fullstripper,str) or ""
84end
85
86function string.collapsespaces(str)
87 return str and lpegmatch(collapser,str) or ""
88end
89
90function string.nospaces(str)
91 return str and lpegmatch(nospacer,str) or ""
92end
93
94function string.longtostring(str)
95 return str and lpegmatch(longtostring,str) or ""
96end
97
98
99
100
101
102local pattern = P(" ")^0 * P(-1)
103
104
105
106function string.is_empty(str)
107 if not str or str == "" then
108 return true
109 else
110 return lpegmatch(pattern,str) and true or false
111 end
112end
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157local anything = patterns.anything
158local moreescapes = Cc("%") * S(".-+%?()[]*$^{}")
159local allescapes = Cc("%") * S(".-+%?()[]*")
160local someescapes = Cc("%") * S(".-+%()[]")
161local matchescapes = Cc(".") * S("*?")
162
163local pattern_m = Cs ( ( moreescapes + anything )^0 )
164local pattern_a = Cs ( ( allescapes + anything )^0 )
165local pattern_b = Cs ( ( someescapes + matchescapes + anything )^0 )
166local pattern_c = Cs ( Cc("^") * ( someescapes + matchescapes + anything )^0 * Cc("$") )
167
168function string.escapedpattern(str,simple)
169 return lpegmatch(simple and pattern_b or pattern_a,str)
170end
171
172function string.topattern(str,lowercase,strict)
173 if str == "" or type(str) ~= "string" then
174 return ".*"
175 elseif strict == "all" then
176 str = lpegmatch(pattern_m,str)
177 elseif strict then
178 str = lpegmatch(pattern_c,str)
179 else
180 str = lpegmatch(pattern_b,str)
181 end
182 if lowercase then
183 return lower(str)
184 else
185 return str
186 end
187end
188
189
190
191
192
193
194
195function string.valid(str,default)
196 return (type(str) == "string" and str ~= "" and str) or default or nil
197end
198
199
200
201string.itself = function(s) return s end
202
203
204
205local pattern_c = Ct( C(1) ^0)
206local pattern_b = Ct((C(1)/byte)^0)
207
208function string.totable(str,bytes)
209 return lpegmatch(bytes and pattern_b or pattern_c,str)
210end
211
212
213
214local replacer = lpeg.replacer("@","%%")
215
216function string.tformat(fmt,...)
217 return format(lpegmatch(replacer,fmt),...)
218end
219
220
221
222string.quote = string.quoted
223string.unquote = string.unquoted
224
225
226
227if not string.bytetable then
228
229 local limit = 5000
230
231 function string.bytetable(str)
232 local n = #str
233 if n > limit then
234 local t = { byte(str,1,limit) }
235 for i=limit+1,n do
236 t[i] = byte(str,i)
237 end
238 return t
239 else
240 return { byte(str,1,n) }
241 end
242 end
243
244end
245 |