summaryrefslogtreecommitdiff
path: root/tex/context/base/strc-syn.lua
diff options
context:
space:
mode:
Diffstat (limited to 'tex/context/base/strc-syn.lua')
-rw-r--r--tex/context/base/strc-syn.lua284
1 files changed, 202 insertions, 82 deletions
diff --git a/tex/context/base/strc-syn.lua b/tex/context/base/strc-syn.lua
index ca4b3ac18..5f3557a69 100644
--- a/tex/context/base/strc-syn.lua
+++ b/tex/context/base/strc-syn.lua
@@ -7,10 +7,13 @@ if not modules then modules = { } end modules ['strc-syn'] = {
}
local next, type = next, type
-local format = string.format
-local allocate = utilities.storage.allocate
--- interface to tex end
+local context = context
+local implement = interfaces.implement
+
+local allocate = utilities.storage.allocate
+
+local sorters = sorters
local structures = structures
local synonyms = structures.synonyms
@@ -19,6 +22,10 @@ local tags = structures.tags
local collected = allocate()
local tobesaved = allocate()
+local firstofsplit = sorters.firstofsplit
+local strip = sorters.strip
+local splitter = sorters.splitters.utf
+
synonyms.collected = collected
synonyms.tobesaved = tobesaved
@@ -37,94 +44,144 @@ job.register('structures.synonyms.collected', tobesaved, initializer, finalizer)
-- todo: allocate becomes metatable
-local function allocate(class)
- local d = tobesaved[class]
- if not d then
- d = {
- metadata = {
- language = 'en',
- sorted = false,
- class = class
- },
- entries = {
- },
- hash = {
- }
+table.setmetatableindex(tobesaved,function(t,k)
+ local v = {
+ metadata = {
+ language = 'en',
+ sorted = false,
+ class = v
+ },
+ entries = {
+ },
+ hash = {
}
- tobesaved[class] = d
- end
- return d
-end
+ }
+ t[k] = v
+ return v
+end)
function synonyms.define(class,kind)
- local data = allocate(class)
+ local data = tobesaved[class]
data.metadata.kind = kind
end
function synonyms.register(class,kind,spec)
- local data = allocate(class)
+ local data = tobesaved[class]
+ local hash = data.hash
+ local definition = spec.definition
+ local tag = definition.tag or ""
data.metadata.kind = kind -- runtime, not saved in format (yet)
- if not data.hash[spec.definition.tag or ""] then
- data.entries[#data.entries+1] = spec
- data.hash[spec.definition.tag or ""] = spec
+ if not hash[tag] then
+ if definition.used == nil then
+ definition.used = false
+ end
+ if definition.shown == nil then
+ definition.shown = false
+ end
+ local entries = data.entries
+ entries[#entries+1] = spec
+ hash[tag] = spec
end
end
function synonyms.registerused(class,tag)
- local data = allocate(class)
- local dht = data.hash[tag]
- if dht then
- dht.definition.used = true
+ local data = tobesaved[class]
+ local okay = data.hash[tag]
+ if okay then
+ local definition = okay.definition
+ definition.used = true
+ definition.list = true
+ end
+end
+
+function synonyms.registershown(class,tag)
+ local data = tobesaved[class]
+ local okay = data.hash[tag]
+ if okay then
+ local definition = okay.definition
+ definition.shown = true
+ definition.list = true
+ end
+end
+
+function synonyms.isused(class,tag)
+ local data = tobesaved[class]
+ local okay = data.hash[tag]
+ return okay and okay.definition.used
+end
+
+function synonyms.isshown(class,tag)
+ local data = tobesaved[class]
+ local okay = data.hash[tag]
+ return okay and okay.definition.shown
+end
+
+function synonyms.resetused(class)
+ for tag, data in next, tobesaved[class].hash do
+ data.definition.used = false
+ end
+end
+
+function synonyms.resetshown(class)
+ for tag, data in next, tobesaved[class].hash do
+ data.definition.shown = false
end
end
function synonyms.synonym(class,tag)
- local data = allocate(class).hash
- local d = data[tag]
- if d then
- local de = d.definition
- de.used = true
- context(de.synonym)
+ local data = tobesaved[class]
+ local okay = data.hash[tag]
+ if okay then
+ local definition = okay.definition
+ definition.used = true
+ definition.list = true
+ context(definition.synonym)
end
end
function synonyms.meaning(class,tag)
- local data = allocate(class).hash
- local d = data[tag]
- if d then
- local de = d.definition
- de.used = true
- context(de.meaning)
+ local data = tobesaved[class]
+ local okay = data.hash[tag]
+ if okay then
+ local definition = okay.definition
+ definition.shown = true
+ definition.list = true
+ context(definition.meaning)
end
end
synonyms.compare = sorters.comparers.basic -- (a,b)
function synonyms.filter(data,options)
- local result = { }
+ local result = { }
local entries = data.entries
- local all = options and options.criterium == interfaces.variables.all
- for i=1,#entries do
- local entry = entries[i]
- if all or entry.definition.used then
- result[#result+1] = entry
+ local all = options and options.criterium == interfaces.variables.all
+ if all then
+ for i=1,#entries do
+ result[i] = entries[i]
+ end
+ else
+ for i=1,#entries do
+ local entry = entries[i]
+ local definition = entry.definition
+ if definition.list then
+ result[#result+1] = entry
+ end
end
end
data.result = result
end
function synonyms.prepare(data)
- local strip = sorters.strip
- local splitter = sorters.splitters.utf
local result = data.result
if result then
for i=1, #result do
- local r = result[i]
- local rd = r.definition
- if rd then
- local rt = rd.tag
- local sortkey = (rt and rt ~= "" and rt) or rd.synonym
- r.split = splitter(strip(sortkey))
+ local entry = result[i]
+ local definition = entry.definition
+ if definition then
+ local tag = definition.tag
+ local key = tag ~= "" and tag or definition.synonym
+ entry.split = splitter(strip(key))
end
end
end
@@ -132,21 +189,31 @@ end
function synonyms.sort(data,options)
sorters.sort(data.result,synonyms.compare)
+ data.metadata.sorted = true
end
-function synonyms.finalize(data,options)
- local result = data.result
- data.metadata.nofsorted = #result
- local split = { }
+function synonyms.finalize(data,options) -- mostly the same as registers so we will generalize it: sorters.split
+ local result = data.result
+ local split = { }
+ local nofsplit = 0
+ local lasttag = nil
+ local lasttag = nil
+ local nofdone = 0
for k=1,#result do
- local v = result[k]
- local entry, tag = sorters.firstofsplit(v)
- local s = split[entry] -- keeps track of change
- if not s then
- s = { tag = tag, data = { } }
- split[entry] = s
+ local entry = result[k]
+ local first, tag = firstofsplit(entry)
+ if tag ~= lasttag then
+ -- if trace_registers then
+ -- report_registers("splitting at %a",tag)
+ -- end
+ done = { }
+ nofdone = 0
+ nofsplit = nofsplit + 1
+ lasttag = tag
+ split[nofsplit] = { tag = tag, data = done }
end
- s.data[#s.data+1] = v
+ nofdone = nofdone + 1
+ done[nofdone] = entry
end
data.result = split
end
@@ -154,33 +221,28 @@ end
-- for now, maybe at some point we will do a multipass or so
-- maybe pass the settings differently
+local ctx_synonymentry = context.synonymentry
+
function synonyms.flush(data,options)
- local kind = data.metadata.kind -- hack, will be done better
- -- context[format("\\start%soutput",kind)]()
local result = data.result
- local sorted = table.sortedkeys(result)
- for k=1,#sorted do
- local letter = sorted[k]
- local sublist = result[letter]
- local data = sublist.data
- -- context[format("\\start%ssection",kind)](sublist.tag)
+ for i=1,#result do
+ local sublist = result[i]
+ local letter = sublist.tag
+ local data = sublist.data
for d=1,#data do
local entry = data[d].definition
- -- context[format("\\%sentry",kind)](d,entry.tag,entry.synonym,entry.meaning or "")
- context("\\%sentry{%s}{%s}{%s}{%s}",kind,d,entry.tag,entry.synonym,entry.meaning or "")
+ ctx_synonymentry(d,entry.tag,entry.synonym,entry.meaning or "")
end
- -- context[format("\\stop%ssection",kind)]()
end
- -- context[format("\\stop%soutput",kind)]()
- data.result = nil
+ data.result = nil
data.metadata.sorted = false
end
function synonyms.analyzed(class,options)
- local data = synonyms.collected[class]
+ local data = collected[class]
if data and data.entries then
options = options or { }
- sorters.setlanguage(options.language)
+ sorters.setlanguage(options.language,options.method)
synonyms.filter(data,options) -- filters entries to result
synonyms.prepare(data,options) -- adds split table parallel to list table
synonyms.sort(data,options) -- sorts entries in result
@@ -192,7 +254,65 @@ end
function synonyms.process(class,options)
if synonyms.analyzed(class,options) then
- synonyms.flush(synonyms.collected[class],options)
+ synonyms.flush(collected[class],options)
end
end
+-- todo: local higher up
+
+implement { name = "registerusedsynonym", actions = synonyms.registerused, arguments = { "string", "string" } }
+implement { name = "registershownsynonym", actions = synonyms.registershown, arguments = { "string", "string" } }
+implement { name = "synonymmeaning", actions = synonyms.meaning, arguments = { "string", "string" } }
+implement { name = "synonymname", actions = synonyms.synonym, arguments = { "string", "string" } }
+implement { name = "resetusedsynonyms", actions = synonyms.resetused, arguments = "string" }
+implement { name = "resetshownsynonyms", actions = synonyms.resetshown, arguments = "string" }
+
+implement {
+ name = "doifelsesynonymused",
+ actions = { synonyms.isused, commands.doifelse },
+ arguments = { "string", "string" }
+}
+
+implement {
+ name = "doifelsesynonymshown",
+ actions = { synonyms.isshown, commands.doifelse },
+ arguments = { "string", "string" }
+}
+
+implement {
+ name = "registersynonym",
+ actions = synonyms.register,
+ arguments = {
+ "string",
+ "string",
+ {
+ { "metadata", {
+ { "catcodes", "integer" },
+ { "coding" },
+ { "xmlroot" }
+ }
+ },
+ {
+ "definition", {
+ { "tag" },
+ { "synonym" },
+ { "meaning" },
+ { "used", "boolean" }
+ }
+ }
+ }
+ }
+}
+
+implement {
+ name = "processsynonyms",
+ actions = synonyms.process,
+ arguments = {
+ "string",
+ {
+ { "criterium" },
+ { "language" },
+ { "method" }
+ }
+ }
+}