diff options
Diffstat (limited to 'Master/texmf-dist/tex/context/base/m-database.lua')
-rw-r--r-- | Master/texmf-dist/tex/context/base/m-database.lua | 108 |
1 files changed, 108 insertions, 0 deletions
diff --git a/Master/texmf-dist/tex/context/base/m-database.lua b/Master/texmf-dist/tex/context/base/m-database.lua new file mode 100644 index 00000000000..8dde9690e96 --- /dev/null +++ b/Master/texmf-dist/tex/context/base/m-database.lua @@ -0,0 +1,108 @@ +if not modules then modules = { } end modules ['m-database'] = { + version = 1.001, + comment = "companion to m-database.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +local sub, gmatch, format = string.sub, string.gmatch, string.format +local concat = table.concat +local lpegpatterns, lpegmatch, lpegsplitat = lpeg.patterns, lpeg.match, lpeg.splitat +local lpegP, lpegC, lpegS, lpegCt = lpeg.P, lpeg.C, lpeg.S, lpeg.Ct +local sprint, ctxcatcodes = tex.sprint, tex.ctxcatcodes + +local trace_flush = false trackers.register("module.database.flush", function(v) trace_flush = v end) + +local report_database = logs.reporter("database") + +buffers.database = buffers.database or { } + +local separators = { -- not interfaced + tab = lpegpatterns.tab, + tabs = lpegpatterns.tab^1, + comma = lpegpatterns.comma, + space = lpegpatterns.space, + spaces = lpegpatterns.space^1, +} + +local function tracedsprint(c,str) + report_database("snippet: %s",str) + sprint(c,str) +end + +function buffers.database.process(settings) + local data + local sprint = trace_flush and tracedsprint or sprint + if settings.type == "file" then + local filename = resolvers.finders.byscheme("any",settings.database) + data = filename ~= "" and io.loaddata(filename) + data = data and string.splitlines(data) + else + data = buffers.getlines(settings.database) + end + if data and #data > 0 then + local separatorchar, quotechar, commentchar = settings.separator, settings.quotechar, settings.commentchar + local before, after = settings.before or "", settings.after or "" + local first, last = settings.first or "", settings.last or "" + local left, right = settings.left or "", settings.right or "" + local setups = settings.setups or "" + local command = settings.command + separatorchar = (not separatorchar and ",") or separators[separatorchar] or separatorchar + local separator = type(separatorchar) == "string" and lpegS(separatorchar) or separatorchar + local whatever = lpegC((1 - separator)^0) + if quotechar and quotechar ~= "" then + local quotedata = nil + for chr in gmatch(quotechar,".") do + local quotechar = lpegP(chr) + local quoteword = quotechar * lpeg.C((1 - quotechar)^0) * quotechar + if quotedata then + quotedata = quotedata + quoteword + else + quotedata = quoteword + end + end + whatever = quotedata + whatever + end + local checker = commentchar ~= "" and lpeg.S(commentchar) + local splitter = lpegCt(whatever * (separator * whatever)^0) + local found = false + for i=1,#data do + local line = data[i] + if line ~= "" and (not checker or not lpegmatch(checker,line)) then + local result, r = { }, 0 -- we collect as this is nicer in tracing + local list = lpegmatch(splitter,line) + if not found then + if setups ~= "" then + sprint(ctxcatcodes,format("\\begingroup\\setups[%s]",setups)) + end + sprint(ctxcatcodes,before) + found = true + end + r = r + 1 ; result[r] = first + for j=1,#list do + r = r + 1 ; result[r] = left + if command == "" then + r = r + 1 ; result[r] = list[j] + else + r = r + 1 ; result[r] = command + r = r + 1 ; result[r] = "{" + r = r + 1 ; result[r] = list[j] + r = r + 1 ; result[r] = "}" + end + r = r + 1 ; result[r] = right + end + r = r + 1 ; result[r] = last + sprint(ctxcatcodes,concat(result)) + end + end + if found then + sprint(ctxcatcodes,after) + if setups ~= "" then + sprint(ctxcatcodes,"\\endgroup") + end + end + else + -- message + end +end |