#!/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("%word% %pos%. %def%", entry) else defc = "????" end return template( "%defc%%wi%", {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("^(.-)[.,]*$"):lower() 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([[
%text%
< return
]], {text=text,path=os.getenv"SCRIPT_NAME"}) end local function enform() local options = {} for k in pairs(glossors) do table.insert(options, template('', {x=k})) end table.sort(options) return template([[

]], { 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()