summaryrefslogtreecommitdiff
path: root/conglossor.cgi
diff options
context:
space:
mode:
authorubq323 <ubq323@ubq323.website>2024-11-05 21:33:44 +0000
committerubq323 <ubq323@ubq323.website>2024-11-05 21:33:44 +0000
commitea9c0f681c6ec55894b1854b54af8a7569ecbab9 (patch)
tree0adf02dec3725e46624fe96cd3aae4ec7db14205 /conglossor.cgi
parent09826722016c2ae9d8a08212a54e4b80d26dd09c (diff)
conlex.lua -> conglossor.cgi
Diffstat (limited to 'conglossor.cgi')
-rwxr-xr-xconglossor.cgi165
1 files changed, 165 insertions, 0 deletions
diff --git a/conglossor.cgi b/conglossor.cgi
new file mode 100755
index 0000000..bf3ff8c
--- /dev/null
+++ b/conglossor.cgi
@@ -0,0 +1,165 @@
+#!/usr/bin/env lua5.3
+local lpeg = require'lpeg'
+
+local function template(str, args)
+ return (str:gsub("%%(%w+)%%", args))
+end
+
+local function urldecode(s)
+ return s:gsub('+',' ')
+ :gsub('%%(%x%x)',function(x)
+ return string.char(tonumber(x,16))
+ end)
+end
+local function parse_qs(s)
+ local ix = 1
+ local res = {}
+ while true do
+ local _,next_ix,ek,ev = s:find("([^=]+)=([^&]*)&?",ix)
+ if not ek then break end
+ local k,v = urldecode(ek), urldecode(ev)
+ res[k] = v
+ ix = next_ix + 1
+ end
+ return res
+end
+
+local function eprint(...)
+ local s = {}
+ for i = 1, select('#',...) do
+ s[i] = tostring(select(i, ...))
+ end
+ io.stderr:write(table.concat(s, "\t"), "\n")
+end
+
+local document_template
+do
+ local template_file = assert(io.open"template.html")
+ document_template = template_file:read"a"
+ template_file:close()
+end
+
+local function load_dict(filename)
+ local res = {}
+ for line in io.lines(filename) do
+ local word, pos, def = line:match "^(.-)\t(.-)\t(.-)$"
+ if word then
+ res[word] = {pos=pos, def=def, word=word}
+ end
+ end
+ return res
+end
+
+local function format_def(found_word, entry)
+ local defc
+ if entry then
+ defc = template("<b>%word%</b> <i>%pos%</i>. %def%", entry)
+ else
+ defc = "????"
+ end
+ return template(
+ "<word><def>%defc%</def><wi>%wi%</wi></word>",
+ {defc=defc, wi=found_word}
+ )
+end
+
+local glossors = {}
+
+function glossors.sanila(text)
+ local words = load_dict "sanila.tsv"
+
+ local items = {}
+ -- sanila morphology is easy enough
+ for word in text:gmatch("%S+") do
+ local stripped = word:match("^(.-)[.,]*$")
+ local entry = words[stripped]
+ table.insert(items, format_def(word, entry))
+ end
+
+ return table.concat(items, "\n")
+end
+
+glossors["vötgil"] = function(text)
+ local words = load_dict "vötgil.tsv"
+ local function norm(s)
+ return s:lower():gsub("Ð","ð"):gsub("Ö","ö"):gsub("0","ö"):gsub("9","ð")
+ end
+
+ local letter = lpeg.R("az","AZ") + lpeg.S"09" + "ö" + "Ö" + 'ð' + 'Ð'
+ local word = (letter*letter*letter) / function (w)
+ return format_def(w, words[norm(w)])
+ end * lpeg.Cp()
+
+ local i = 1
+ local out = ""
+ while i < #text do
+ local item, ni = lpeg.match(word, text, i)
+ if item then
+ out = out .. item
+ i = ni
+ else
+ out = out .. text:sub(i,i)
+ i = i + 1
+ end
+ end
+ return out
+end
+
+local function engloss(langue, text)
+ local text = glossors[langue](text)
+ return template([[
+ <section>%text%</section>
+ <section id=place></section>
+ <section><a href="%path%">&lt; return</a></section>
+ ]], {text=text,path=os.getenv"SCRIPT_NAME"})
+end
+
+local function enform()
+ local options = {}
+ for k in pairs(glossors) do
+ table.insert(options, template('<option value="%x%" >%x%</option>', {x=k}))
+ end
+ table.sort(options)
+ return template([[
+<section>
+<form>
+ <textarea name=q></textarea>
+ <label for=langue>select con-langue:</label>
+ <select name=langue id=langue>
+ %options%
+ </select>
+ <br><button>perform <i>conglossatio</i></button>
+</form>
+</section>
+]], {
+ options=table.concat(options, "\n"),
+
+ })
+end
+
+local function response(content)
+ print("Content-Type: text/html")
+ print()
+ print(template(document_template, {content=content}))
+end
+
+local function main()
+ local langue, text
+ local qs = os.getenv"QUERY_STRING"
+ if qs then
+ local pqs = parse_qs(qs)
+ langue = pqs.langue
+ text = pqs.q
+ end
+
+ if not text then
+ response(enform())
+ elseif not glossors[langue] then
+ response("unknown langue "..langue)
+ else
+ response(engloss(langue, text))
+ end
+end
+
+main()
+