1if not modules then modules = { } end modules ['util-tbs'] = {
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 tonumber, type, rawget = tonumber, type, rawget
10
11utilities = utilities or {}
12local tablestore = { }
13utilities.tablestore = tablestore
14
15local loaded = { }
16local current = nil
17
18function tablestore.load(namespace,filename)
19 local data = loaded[namespace]
20 if not data then
21 if type(filename) == "table" then
22 data = filename
23 else
24 local fullname = resolvers.findfile(filename)
25 if fullname and fullname ~= "" then
26 if file.suffix(fullname,"json") and utilities.json then
27 data = io.loaddata(fullname)
28 if data then
29 data = utilities.json.tolua(data)
30 else
31
32 end
33 else
34 data = table.load(fullname)
35 end
36 end
37 end
38 if not data then
39 data = { }
40 end
41 loaded[namespace] = data
42 if metapost then
43 metapost.setparameterset(namespace,data)
44 end
45 end
46 current = data
47 return data
48end
49
50function tablestore.loaded(namespace)
51 return (namespace and loaded[namespace]) or current or { }
52end
53
54function tablestore.known(namespace)
55 return namespace and rawget(loaded,namespace) or false
56end
57
58do
59
60 local find, gmatch, formatters = string.find, string.gmatch, string.formatters
61
62 local P, C, Ct, Cc, R = lpeg.P, lpeg.C, lpeg.Ct, lpeg.Cc, lpeg.R
63
64 local separator = P(".")
65 local equal = P("=")
66 local digit = R("09")
67 local lbracket = P("[")
68 local rbracket = P("]")
69 local index = Ct(Cc("index") * lbracket * (digit^1 / tonumber) * rbracket)
70 local test = Ct(Cc("test") * lbracket * C((1-equal)^1) * equal * C((1-rbracket)^1) * rbracket)
71 local entry = Ct(Cc("entry") * C((1-lbracket-separator)^1))
72
73 local specifier = Ct ((entry + (separator + index + test))^1)
74
75 local function field(namespace,name,default)
76 local data = loaded[namespace] or current
77 if data then
78
79 local t = lpeg.match(specifier,name)
80 for i=1,#t do
81 local ti = t[i]
82 local t1 = ti[1]
83 local k = ti[2]
84 if t1 == "test" then
85 local v = ti[3]
86 for j=1,#data do
87 local dj = data[j]
88 if dj[k] == v then
89 data = dj
90 goto OKAY
91 end
92 end
93 return
94 else
95 data = data[k]
96 if not data then
97 return
98 end
99 end
100 ::OKAY::
101 end
102
103
104
105
106
107
108
109
110 return data
111 end
112 end
113
114
115 function length(namespace,name,default)
116 local data = field(namespace,name)
117 return type(data) == "table" and #data or 0
118 end
119
120 function formatted(namespace,name,fmt)
121 local data = field(namespace,name)
122 if data then
123 return formatters[fmt](data)
124 end
125 end
126
127 tablestore.field = field
128 tablestore.length = length
129 tablestore.formatted = formatted
130
131end
132 |