Subversion Repositories navi

Compare Revisions

Ignore whitespace Rev 295 → Rev 301

/tsimapiak/parse.py
22,6 → 22,7
 
import tsimapiak.dbconnector as dbconnector
import tsimapiak.parsenum as parsenum
import itertools
import re
 
#wordlist = [{"id": 0, "navi": u"tawtute", "infix": u"tawtute", "type": u"n."}] + dbconnector.getnavilist() + [{"id": 0, "navi": u"na'vi", "infix": u"na'vi", "type": u"n."}] # XXX HACK - extra proper nouns
31,24 → 32,29
 
# XXX HACK - These are words that are either not in Eana Eltu, or that get interpreted wrongly for whatever reason. The latter should be removed from this list when the parser gets more sophisticated. The former should also have an entry in the equivalent array in the translator! If it can take infixes, consider adding it to the main wordlist above (see the examples). The order is - original, Na'vi root, 0-pos infix, 1-pos infix, 2-pos infix, prefixes, suffixes. Things that can take affixes should go in the above list instead.
BROKENWORDS = (
(u"sami", u"si", u"", u"am", u"", (()), (()), False),
(u"to", u"to", u"", u"", u"", (()), (()), False),
(u"sami", u"si", u"", u"am", u"", (()), (()), False, "si"), # otherwise parses as sa (tsa-lenited) + mi
#(u"to", u"to", u"", u"", u"", (()), (()), False),
#(u"frato", u"to", u"", u"", u"", [[u"fra"]], (()), False),
(u"soaiä", u"soaia", u"", u"", u"", (()), [[(u"ä", None)]], False),
(u"mengenga", u"ngenga", u"", u"", u"", [[u"me"]], (()), False),
(u"pxengenga", u"ngenga", u"", u"", u"", [[u"pxe"]], (()), False),
(u"kìmä", u"kä", u"", u"ìm", u"", (()), (()), False),
(u"apxay", u"pxay", u"", u"", u"", [[u"a"]], (()), False),
(u"soaiä", u"soaia", u"", u"", u"", (()), [[(u"ä", None)]], False, "soaia"), # does not parse, irregular form
#(u"mengenga", u"ngenga", u"", u"", u"", [[u"me"]], (()), False),
#(u"pxengenga", u"ngenga", u"", u"", u"", [[u"pxe"]], (()), False),
(u"kìmä", u"kä", u"", u"ìm", u"", (()), (()), False, "kä"), # otherwise parses as kìm (spin) + ä (genitive)
(u"apxay", u"pxay", u"", u"", u"", [[(u"a", "a")]], (()), False, "pxay"), # otherwise parses as apxa + -y (genitive)
#(u"akawng", u"kawng", u"", u"", u"", [[u"a"]], (()), False),
#(u"kawnga", u"kawng", u"", u"", u"", (()), [[(u"a", None)]], False),
#(u"kawng", u"kawng", u"", u"", u"", (()), (()), False),
(u"ka", u"ka", u"", u"", u"", (()), (()), False),
(u"uo", u"uo", u"", u"", u"", (()), (()), False),
(u"sìk", u"sìk", u"", u"", u"", (()), (()), False),
(u"sim", u"sim", u"", u"", u"", (()), (()), False), # probably not tsim lenited
(u"tse", u"tse", u"", u"", u"", (()), (()), False),
#(u"ka", u"ka", u"", u"", u"", (()), (()), False),
#(u"uo", u"uo", u"", u"", u"", (()), (()), False),
#(u"sìk", u"sìk", u"", u"", u"", (()), (()), False),
#(u"sim", u"sim", u"", u"", u"", (()), (()), False), # probably not tsim lenited
(u"tse", u"tse", u"", u"", u"", (()), (()), False, "tse"), # otherwise parses as tsa'u abbreviated (special case)
(u"por", u"po", u"", u"", u"", (()), [[("r", None)]], False, "po"), # otherwise parses as lenited pxor which is unlikely
)
 
BANNEDNUMBERS = { # words which must not be parsed by the number parser
"pey" # more likely dictionary word pey than lenited pxey 3
}
 
#INFIXES1 = (u"awn", u"eyk", u"us", u"äp", u"")
#INFIXES2 = (u"ìyev", u"iyev", u"ìmìy", u"arm", u"asy", u"ilv", u"ìmv", u"imv", u"ìrm", u"irv", u"ìsy", u"aly", u"ary", u"ìly", u"ìry", u"ìlm", u"alm", u"am", u"ay", u"er", u"ìm", u"iv", u"ìy", u"ol", u"")
#INFIXES3 = (u"äng", u"ats", u"eiy", u"ei", u"uy", u"")
59,12 → 65,13
#prefixesv = ur"(?P<vpr>(?:nì|sä|tì|rä'ä |ke )?)"
 
EXTRAINFIXES = [
{"id": "-1", "navi": "eiy", "gloss": "LAUD.", "position": 2},
{"id": "-2", "navi": "eng", "gloss": "PEJ.", "position": 2},
{"id": "-1", "navi": "eiy", "orig_navi": "ei", "gloss": "LAUD.", "position": 2},
{"id": "-2", "navi": "eng", "orig_navi": "äng", "gloss": "PEJ.", "position": 2},
]
 
EXTRAPOSTFIXES = [
{"id": "-3", "navi": "eyä", "gloss": "GEN."},
{"id": "-3", "navi": "eyä", "orig_navi": "yä", "gloss": "GEN."},
{"id": "-4", "navi": "pxì", "orig_navi": "pxì", "gloss": "FRAC."},
]
 
EXTRAADP = (("to", [x["id"] for x in wordlist if x["navi"] == "to"][0]), ("sì", [x["id"] for x in wordlist if x["navi"] == "sì"][0])) # words that act like adpositions but technically aren't
78,7 → 85,7
if prefix["navi"].startswith(letter):
new_prefix = prefix["navi"].replace(letter, replacement, 1)
if not [x for x in prefixes if x["navi"] == new_prefix]: # always assume a dictionary word over a lenited prefix
extraprefixes.append({"id": prefix["id"], "navi": new_prefix, "gloss": prefix["gloss"] + ".LENTD"})
extraprefixes.append({"id": prefix["id"], "navi": new_prefix, "gloss": prefix["gloss"] + ".LENTD", "orig_navi": prefix["navi"]})
break
 
prefixes = sorted(prefixes + extraprefixes, key=lambda x: len(x["navi"]), reverse=True)
85,6 → 92,42
infixes = sorted(infixes + EXTRAINFIXES, key=lambda x: len(x["navi"]), reverse=True)
postfixes = sorted(postfixes + EXTRAPOSTFIXES, key=lambda x: len(x["navi"]), reverse=True)
 
# Let's lenit the dictionary
extrawords = []
for word in wordlist:
splitword = word["navi"].split(" ")
splitinfix = word["infix"].split(" ")
lenitword = {}
lenitinfix = {}
for i, wor in enumerate(splitword):
for letter, replacement in LENIT:
if wor.startswith(letter):
lenitword[i] = wor.replace(letter, replacement, 1)
lenitinfix[i] = splitinfix[i].replace(letter, replacement, 1)
break
 
s = list(lenitword.keys())
for lenits in itertools.chain.from_iterable(itertools.combinations(s, r) for r in range(1, len(s)+1)):
new_word = ""
new_infix = ""
for i, wor in enumerate(splitword):
if i in lenits:
new_word += lenitword[i]
new_infix += lenitinfix[i]
else:
new_word += wor
new_infix += splitinfix[i]
new_word += " "
new_infix += " "
print(f"Generated lenited {new_word} from {word['navi']}")
new_word = new_word[:-1]
new_infix = new_infix[:-1]
extrawords.append({"id": word["id"], "navi": new_word, "infix": new_infix, "type": word["type"], "lenited": True, "orig_navi": word["navi"]})
 
wordlist = sorted(wordlist + extrawords, key=lambda x: len(x["navi"]) * 2 + (0 if x["lenited"] else 1), reverse=True)
 
# TODO add reef Na'vi
 
def parseword(wordin):
tempid = 0
temptype = u""
94,14 → 137,13
if brokenword[1] == word["navi"]:
tempid = word["id"]
temptype = word["type"]
return {"word": {"id": tempid, "navi": brokenword[1], "infix": u"", "type": temptype}, "pref": brokenword[5], "post": brokenword[6], "len": brokenword[7], "inf": (brokenword[2], brokenword[3], brokenword[4]) }
ret = {"word": {"id": 0, "navi": u"[" + wordin[0] + u"]", "infix": u"", "type": u""}}
return {"word": {"id": tempid, "navi": brokenword[1], "infix": u"", "type": temptype, "orig_navi": brokenword[8]}, "pref": brokenword[5], "post": brokenword[6], "len": brokenword[7], "inf": (brokenword[2], brokenword[3], brokenword[4]) }
ret = {"word": {"id": 0, "navi": u"[" + wordin[0] + u"]", "infix": u"", "type": u"", "orig_navi": "[" + wordin[0] + "]"}, "len": False, "pref": [], "post": [], "inf": ["", "", ""]}
for word in wordlist:
word["navi"] = word["navi"].lower()
foundit = True
foundprefs = []
foundposts = []
lenited = False
splitword = word["infix"].split(u" ")
foundins = [u"", u"", u""]
if len(wordin) < len(splitword):
140,14 → 182,6
else:
if splitword[wor] in wordin[wor]:
center = splitword[wor]
if center == u"" and (wordin[wor] == u"paya" or splitword[wor] != u"pxay"): # XXX HACK - workaround to fix pay being lenited pxay. Maybe fixable without hardcoding?
for i in LENIT:
temp = u""
if splitword[wor].startswith(i[0]):
temp = i[1] + splitword[wor][len(i[0]):]
if temp in wordin[wor]:
lenited = True
center = temp
if center == u"":
if splitword[wor].endswith(u"nga"):
temp = splitword[wor][:-3] + u"nge"
196,13 → 230,13
last = u""
while last != pref:
last = pref
for pre in [x["navi"] for x in prefixes]:
for pre in prefixes:
if pref != u"":
if pref.endswith(pre):
if pre in foundprefs[wor]:
if pref.endswith(pre["navi"]):
if pre["navi"] in foundprefs[wor]:
break
foundprefs[wor].append(pre)
pref = pref[:-len(pre)]
foundprefs[wor].append((pre["navi"], pre["orig_navi"])) # only needed here, to handle lenition
pref = pref[:-len(pre["navi"])]
break
if pref != u"":
foundit = False
216,7 → 250,7
if posf.startswith(pos):
if (pos, posid) in foundposts[wor]:
break
if pos != u"ä" or word["navi"] != u"pey": # XXX HACK - fix for peyä. THIS SHOULD NOT BE HERE!
if pos != u"ä" or word["orig_navi"] != u"pey": # XXX HACK - fix for peyä. THIS SHOULD NOT BE HERE!
foundposts[wor].append((pos, posid))
posf = posf[len(pos):]
break
229,16 → 263,17
if foundit == True:
foundword = word
break
ret["pref"] = foundprefs
ret["post"] = foundposts
ret["inf"] = foundins
ret["len"] = lenited
if foundit == True:
ret["pref"] = foundprefs
ret["post"] = foundposts
ret["inf"] = foundins
ret["len"] = word["lenited"]
ret["word"] = foundword
return ret
 
def parsesent(sent):
sent = sent.strip().lower().replace(u"’", u"'")
sent = sent.replace("ù", "u") # Basic support for reef Na'vi
sent = re.sub(r"[^\wìä' ]", u"", sent)
sent = re.sub(r"\ +", u" ", sent)
sent = sent.split(u" ")
245,7 → 280,9
ret = []
left = len(sent)
while left:
word = parsenum.parse(sent[len(sent) - left])
word = None
if sent[len(sent) - left] not in BANNEDNUMBERS:
word = parsenum.parse(sent[len(sent) - left])
if word == None:
word = parseword(sent[-left:])
left -= len(word["word"]["navi"].split(" "))
/tsimapiak/parsenum.py
31,6 → 31,15
u"pukap",
u"kinä"]
 
NUMLEN = [u"hew",
u"aw",
u"mune",
u"pey",
u"sìng",
u"mrr",
u"fukap",
u"hinä"]
 
NUMORD = [u"kew",
u"'aw",
u"mu",
40,6 → 49,15
u"pu",
u"ki"]
 
NUMORDLEN = [u"hew",
u"aw",
u"mu",
u"pey",
u"sì",
u"mrr",
u"fu",
u"hi"]
 
REM = [u"aw",
u"mun",
u"pey",
64,19 → 82,31
u"pu",
u"ki"]
 
BASELEN = [u"",
u"me",
u"pe",
u"sì",
u"mrr",
u"fu",
u"hi"]
 
def parse(numin):
if u"mm" in numin:
return None
if (numin == u"") or ((numin[0] == u"a") and (numin[len(numin) - 1] == u"a")):
if (numin == u"") or len(numin) == 1 or ((numin[0] == u"a" and numin[1] != "w") and (numin[len(numin) - 1] == u"a")):
return None
prefs = []
posts = []
outoct = 0
outdec = 0
ret = {"word": {"id": 0, "navi": u"", "infix": u"", "type": u""}, "pref": [prefs], "post": [posts], "inf": [u"", u"", u""], "len": False, "dec": outdec, "oct": outoct}
if numin[0] == u"a":
prefs.append(u"a")
frac = False
ret = {"word": {"id": 0, "navi": u"", "orig_navi": "", "infix": u"", "type": u""}, "pref": [prefs], "post": [posts], "inf": [u"", u"", u""], "len": False, "dec": outdec, "oct": outoct}
if numin[0] == u"a" and len(numin) > 1 and numin[1] != "w":
prefs.append((u"a", "a"))
numin = numin[1:]
elif numin[0:2] == "nì":
prefs.append(("nì", "nì"))
numin = numin[2:]
if numin[len(numin) - 1] == u"a":
posts.append((u"a", None))
numin = numin[:-1]
83,7 → 113,21
if numin[-2:] == u"ve":
posts.append((u"ve", None))
numin = numin[:-2]
if numin[-3:] == u"pxì":
posts.append((u"pxì", None))
numin = numin[:-3]
 
# Special fractions
if numin in ("mawl", "pan", "fan"):
outoct = 2 if numin == "mawl" else 3
outdec = 2 if numin == "mawl" else 3
ret["word"]["navi"] = "1/" + str(outdec)
ret["word"]["orig_navi"] = "mawl" if numin == "mawl" else "pan"
ret["dec"] = outdec
ret["oct"] = outoct
ret["len"] = True if numin == "fan" else False
return ret
 
#BASE numbers
for n in range(len(NUM)):
if (u"ve", None) in posts:
91,80 → 135,156
outoct = n
outdec = n
ret["word"]["navi"] = str(outdec) + u"."
ret["word"]["orig_navi"] = NUMORD[n]
ret["dec"] = outdec
ret["oct"] = outoct
return ret
if numin == NUMORDLEN[n]:
outoct = n
outdec = n
ret["word"]["navi"] = str(outdec) + u"."
ret["word"]["orig_navi"] = NUMORD[n]
ret["dec"] = outdec
ret["oct"] = outoct
ret["len"] = True
return ret
elif ("pxì", None) in posts and n > 3:
if numin == NUMORD[n]:
outoct = n
outdec = n
ret["word"]["navi"] = "1/" + str(outdec)
ret["word"]["orig_navi"] = NUMORD[n]
ret["dec"] = outdec
ret["oct"] = outoct
return ret
if numin == NUMORDLEN[n]:
outoct = n
outdec = n
ret["word"]["navi"] = "1/" + str(outdec)
ret["word"]["orig_navi"] = NUMORD[n]
ret["dec"] = outdec
ret["oct"] = outoct
ret["len"] = True
return ret
else:
if numin == NUM[n]:
outoct = n
outdec = n
ret["word"]["navi"] = str(outdec)
ret["word"]["orig_navi"] = NUM[n]
ret["dec"] = outdec
ret["oct"] = outoct
return ret
if numin == NUMLEN[n]:
outoct = n
outdec = n
ret["word"]["navi"] = str(outdec)
ret["word"]["orig_navi"] = NUM[n]
ret["dec"] = outdec
ret["oct"] = outoct
ret["len"] = True
return ret
#other numbers
notbase = False
orig_navi = ""
for n in range(len(BASE)):
if numin.startswith(BASE[n] + u"vozazam"):
if numin.startswith(BASE[n] + u"vozaza") or (not notbase and numin.startswith(BASELEN[n] + "vozaza")):
base = BASE[n]
if not numin.startswith(BASE[n]):
base = BASELEN[n]
ret["len"] = True
outoct += (n + 1) * (10 ** 5)
outdec += (n + 1) * (8 ** 5)
if numin[len(BASE[n]) + 6:].startswith(u"mrr") or numin[len(BASE[n]) + 6:].startswith(u"me"):
numin = numin[len(BASE[n]) + 6:]
if numin[len(base) + 6:].startswith(u"mrr") or numin[len(base) + 6:].startswith(u"me") or numin[len(base) + 6:].startswith("mu") or not numin[len(base) + 6:].startswith("m"):
orig_navi += BASE[n] + "vozaza"
numin = numin[len(base) + 6:]
else:
numin = numin[len(BASE[n]) + 7:]
orig_navi += BASE[n] + "vozazam"
numin = numin[len(base) + 7:]
notbase = True
for n in range(len(BASE)):
if numin.startswith(BASE[n] + u"zazam"):
if numin.startswith(BASE[n] + u"zaza") or (not notbase and numin.startswith(BASELEN[n] + "zaza")):
base = BASE[n]
if not numin.startswith(BASE[n]):
base = BASELEN[n]
ret["len"] = True
outoct += (n + 1) * (10 ** 4)
outdec += (n + 1) * (8 ** 4)
if numin[len(BASE[n]) + 4:].startswith(u"mrr") or numin[len(BASE[n]) + 4:].startswith(u"me"):
numin = numin[len(BASE[n]) + 4:]
if numin[len(base) + 4:].startswith(u"mrr") or numin[len(base) + 4:].startswith(u"me") or numin[len(base) + 4:].startswith("mu") or not numin[len(base) + 4:].startswith("m"):
orig_navi += BASE[n] + "zaza"
numin = numin[len(base) + 4:]
else:
numin = numin[len(BASE[n]) + 5:]
orig_navi += BASE[n] + "zazam"
numin = numin[len(base) + 5:]
notbase = True
for n in range(len(BASE)):
if numin.startswith(BASE[n] + u"vozam"):
if numin.startswith(BASE[n] + u"voza") or (not notbase and numin.startswith(BASELEN[n] + "voza")):
base = BASE[n]
if not numin.startswith(BASE[n]):
base = BASELEN[n]
ret["len"] = True
outoct += (n + 1) * (10 ** 3)
outdec += (n + 1) * (8 ** 3)
if numin[len(BASE[n]) + 4:].startswith(u"mrr") or numin[len(BASE[n]) + 4:].startswith(u"me"):
numin = numin[len(BASE[n]) + 4:]
if numin[len(base) + 4:].startswith(u"mrr") or numin[len(base) + 4:].startswith(u"me") or numin[len(base) + 4:].startswith("mu") or not numin[len(base) + 4:].startswith("m"):
orig_navi += BASE[n] + "voza"
numin = numin[len(base) + 4:]
else:
numin = numin[len(BASE[n]) + 5:]
orig_navi += BASE[n] + "vozam"
numin = numin[len(base) + 5:]
notbase = True
for n in range(len(BASE)):
if numin.startswith(BASE[n] + u"zam"):
if numin.startswith(BASE[n] + u"za") or (not notbase and numin.startswith(BASELEN[n] + "za")):
base = BASE[n]
if not numin.startswith(BASE[n]):
base = BASELEN[n]
ret["len"] = True
outoct += (n + 1) * (10 ** 2)
outdec += (n + 1) * (8 ** 2)
if numin[len(BASE[n]) + 2:].startswith(u"mrr") or numin[len(BASE[n]) + 2:].startswith(u"me"):
numin = numin[len(BASE[n]) + 2:]
if numin[len(base) + 2:].startswith(u"mrr") or numin[len(base) + 2:].startswith(u"me") or numin[len(base) + 2:].startswith("mu") or not numin[len(base) + 2:].startswith("m"):
orig_navi += BASE[n] + "za"
numin = numin[len(base) + 2:]
else:
numin = numin[len(BASE[n]) + 3:]
orig_navi += BASE[n] + "zam"
numin = numin[len(base) + 3:]
notbase = True
for n in range(len(BASE)):
if numin.startswith(BASE[n] + u"vol"):
if numin.startswith(BASE[n] + u"vol") or (not notbase and numin.startswith(BASELEN[n] + "vol")):
base = BASE[n]
if not numin.startswith(BASE[n]):
base = BASELEN[n]
ret["len"] = True
outoct += (n + 1) * 10
outdec += (n + 1) * 8
numin = numin[len(BASE[n]) + 3:]
numin = numin[len(base) + 3:]
notbase = True
if numin.startswith(BASE[n] + u"vo"):
orig_navi += BASE[n] + "vol"
if numin.startswith(BASE[n] + u"vo") or (not notbase and numin.startswith(BASELEN[n] + "vo")):
base = BASE[n]
if not numin.startswith(BASE[n]):
base = BASELEN[n]
ret["len"] = True
outoct += (n + 1) * 10
outdec += (n + 1) * 8
numin = numin[len(BASE[n]) + 2:]
numin = numin[len(base) + 2:]
notbase = True
orig_navi += BASE[n] + "vo"
if notbase:
for n in range(len(REM)):
if (u"ve", None) in posts:
if (u"ve", None) in posts or ("pxì", None) in posts:
if numin == REMORD[n]:
orig_navi += numin
outoct += n + 1
outdec += n + 1
numin = u""
else:
if numin == REM[n]:
orig_navi += numin
outoct += n + 1
outdec += n + 1
numin = u""
if numin == u"":
ret["word"]["navi"] = str(outdec) if not (u"ve", None) in posts else str(outdec) + u"."
ret["word"]["navi"] = ("" if not ("pxì", None) in posts else "1/") + str(outdec) + ("" if not (u"ve", None) in posts else ".")
ret["word"]["orig_navi"] = orig_navi
ret["dec"] = outdec
ret["oct"] = outoct
return ret
/tsimapiak/translate.py
56,7 → 56,7
if fix[0] == word["inf"][2]:
word["translated"] += '-' + fix[1]
for temp in word["pref"]:
for navf in temp:
for navf, navf_orig in temp:
for fix in [(x["navi"], x["gloss"]) for x in parse.prefixes]:
if fix[0] == navf:
word["translated"] += '-' + fix[1]
/tsimapiak/dbconnector.py
33,10 → 33,11
WHERE partOfSpeech <> 'num.' AND partOfSpeech <> 'prefix' AND partOfSpeech <> 'affix'
ORDER BY CHAR_LENGTH(navi) DESC""")
for row in cur:
navi = row["navi"].replace("+", "").replace("-", "")
if row["infixes"] and row["infixes"] != "NULL": # yeah seriously
ret.append({"id": row["id"], "navi": row["navi"].replace("+", "").replace("-", ""), "infix": row["infixes"].lower(), "type": row["partOfSpeech"]})
ret.append({"id": row["id"], "navi": navi, "orig_navi": navi, "infix": row["infixes"].lower(), "type": row["partOfSpeech"], "lenited": False})
else:
ret.append({"id": row["id"], "navi": row["navi"].replace("+", "").replace("-", ""), "infix": row["navi"].replace("+", "").replace("-", "").lower(), "type": row["partOfSpeech"]})
ret.append({"id": row["id"], "navi": navi, "orig_navi": navi, "infix": navi.lower(), "type": row["partOfSpeech"], "lenited": False})
cur.close()
db.close()
return ret
52,16 → 53,18
for row in cur:
endfix = False
if row["navi"] and row["navi"][0] == "-":
ret[2].append({"id": row["id"], "navi": row["navi"].replace("-", ""), "gloss": row["shorthand"].upper()})
navi = row["navi"].replace("-", "").lower()
ret[2].append({"id": row["id"], "navi": navi, "orig_navi": navi, "gloss": row["shorthand"].upper()})
endfix = True
if row["navi"] and row["navi"][-1] in ("-", "+"):
ret[0].append({"id": row["id"], "navi": row["navi"].replace("-", "").replace("+", ""), "gloss": row["shorthand"].upper()})
navi = row["navi"].replace("-", "").replace("+", "").lower()
ret[0].append({"id": row["id"], "navi": navi, "orig_navi": navi, "gloss": row["shorthand"].upper()})
endfix = True
if not endfix:
if not row["position"] or row["position"] == "NULL":
if row["position"] is None or row["position"] == "NULL":
# not actually an affix
continue
ret[1].append({"id": row["id"], "navi": row["navi"], "gloss": row["shorthand"].upper(), "position": int(row["position"])})
ret[1].append({"id": row["id"], "navi": row["navi"].lower(), "orig_navi": row["navi"].lower(), "gloss": row["shorthand"].upper(), "position": int(row["position"])})
cur.close()
db.close()
 
/webapp/templates/parse.html
39,13 → 39,13
</tr>
{% for wor in out %}
<tr>
<td rowspan="4">{{ wor["word"]["navi"] }}</td>
<td rowspan="4">{{ wor["word"]["orig_navi"] }}</td>
<td>Infixes:</td>
<td>{{ u", ".join(wor["inf"]) }}</td>
</tr>
<tr>
<td>Prefixes:</td>
<td>{{ u"; ".join(u", ".join(x) for x in wor["pref"]) }}</td>
<td>{{ u"; ".join(u", ".join([y[1] for y in x]) for x in wor["pref"]) }}</td>
</tr>
<tr>
<td>Postfixes:</td>
/webapp/templates/translate.html
55,7 → 55,7
</tr>
{% for wor in out %}
<tr>
<td rowspan="4">{{ wor["word"]["navi"] }}</td>
<td rowspan="4">{{ wor["word"]["orig_navi"] }}</td>
<td rowspan="4">{{ wor["translated"] }}</td>
<td>Infixes:</td>
<td>{{ u", ".join(wor["inf"]) }}</td>
62,7 → 62,7
</tr>
<tr>
<td>Prefixes:</td>
<td>{{ u"; ".join(u", ".join(x) for x in wor["pref"]) }}</td>
<td>{{ u"; ".join(u", ".join([y[1] for y in x]) for x in wor["pref"]) }}</td>
</tr>
<tr>
<td>Postfixes:</td>