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
|
if not modules then modules = { } end modules ['l-lpeg'] = {
version = 1.001,
comment = "companion to luat-lib.tex",
author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
copyright = "PRAGMA ADE / ConTeXt Development Team",
license = "see context related readme files"
}
local P, S, Ct, C, Cs, Cc = lpeg.P, lpeg.S, lpeg.Ct, lpeg.C, lpeg.Cs, lpeg.Cc
--~ l-lpeg.lua :
--~ lpeg.digit = lpeg.R('09')^1
--~ lpeg.sign = lpeg.S('+-')^1
--~ lpeg.cardinal = lpeg.P(lpeg.sign^0 * lpeg.digit^1)
--~ lpeg.integer = lpeg.P(lpeg.sign^0 * lpeg.digit^1)
--~ lpeg.float = lpeg.P(lpeg.sign^0 * lpeg.digit^0 * lpeg.P('.') * lpeg.digit^1)
--~ lpeg.number = lpeg.float + lpeg.integer
--~ lpeg.oct = lpeg.P("0") * lpeg.R('07')^1
--~ lpeg.hex = lpeg.P("0x") * (lpeg.R('09') + lpeg.R('AF'))^1
--~ lpeg.uppercase = lpeg.P("AZ")
--~ lpeg.lowercase = lpeg.P("az")
--~ lpeg.eol = lpeg.S('\r\n\f')^1 -- includes formfeed
--~ lpeg.space = lpeg.S(' ')^1
--~ lpeg.nonspace = lpeg.P(1-lpeg.space)^1
--~ lpeg.whitespace = lpeg.S(' \r\n\f\t')^1
--~ lpeg.nonwhitespace = lpeg.P(1-lpeg.whitespace)^1
local hash = { }
function lpeg.anywhere(pattern) --slightly adapted from website
return P { P(pattern) + 1 * lpeg.V(1) }
end
function lpeg.startswith(pattern) --slightly adapted
return P(pattern)
end
function lpeg.splitter(pattern, action)
return (((1-P(pattern))^1)/action+1)^0
end
-- variant:
--~ local parser = lpeg.Ct(lpeg.splitat(newline))
local crlf = P("\r\n")
local cr = P("\r")
local lf = P("\n")
local space = S(" \t\f\v") -- + string.char(0xc2, 0xa0) if we want utf (cf mail roberto)
local newline = crlf + cr + lf
local spacing = space^0 * newline
local empty = spacing * Cc("")
local nonempty = Cs((1-spacing)^1) * spacing^-1
local content = (empty + nonempty)^1
local capture = Ct(content^0)
function string:splitlines()
return capture:match(self)
end
lpeg.linebyline = content -- better make a sublibrary
--~ local p = lpeg.splitat("->",false) print(p:match("oeps->what->more")) -- oeps what more
--~ local p = lpeg.splitat("->",true) print(p:match("oeps->what->more")) -- oeps what->more
--~ local p = lpeg.splitat("->",false) print(p:match("oeps")) -- oeps
--~ local p = lpeg.splitat("->",true) print(p:match("oeps")) -- oeps
local splitters_s, splitters_m = { }, { }
local function splitat(separator,single)
local splitter = (single and splitters_s[separator]) or splitters_m[separator]
if not splitter then
separator = P(separator)
if single then
local other, any = C((1 - separator)^0), P(1)
splitter = other * (separator * C(any^0) + "")
splitters_s[separator] = splitter
else
local other = C((1 - separator)^0)
splitter = other * (separator * other)^0
splitters_m[separator] = splitter
end
end
return splitter
end
lpeg.splitat = splitat
local cache = { }
function string:split(separator)
local c = cache[separator]
if not c then
c = Ct(splitat(separator))
cache[separator] = c
end
return c:match(self)
end
|