Upload 2 files
Browse files- app.py +46 -14
- tag_labels.json +18 -8
app.py
CHANGED
|
@@ -32,8 +32,8 @@ GROUP_ORDER = ["subcategory","gender","number","case","article","proper","degree
|
|
| 32 |
HIDE_CODES = {"subcategory": {"B"}}
|
| 33 |
|
| 34 |
UI = {
|
| 35 |
-
"fo": {"w":"Orð", "t":"Mark", "s":"
|
| 36 |
-
"en": {"w":"Word","t":"Tag", "s":"
|
| 37 |
}
|
| 38 |
|
| 39 |
# Theme color: #89AFA9 (+ close shades)
|
|
@@ -47,6 +47,16 @@ CSS = """
|
|
| 47 |
}
|
| 48 |
.gr-button-primary:hover, button.primary:hover, .primary:hover{ background:var(--primary-600)!important; }
|
| 49 |
a{ color:var(--primary-700)!important; }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 50 |
"""
|
| 51 |
|
| 52 |
def simp_tok(s: str):
|
|
@@ -178,45 +188,66 @@ def group_code(vec: torch.Tensor, group: str) -> str:
|
|
| 178 |
def clean_label(s: str) -> str:
|
| 179 |
s = (s or "").strip()
|
| 180 |
s = re.sub(r"\s+", " ", s)
|
|
|
|
| 181 |
s = s.strip(" -;,:")
|
| 182 |
return s
|
| 183 |
|
| 184 |
def visible_summary(vec: torch.Tensor, lang: str) -> str:
|
| 185 |
"""
|
| 186 |
-
|
| 187 |
-
- ONLY words/labels
|
| 188 |
-
-
|
| 189 |
"""
|
| 190 |
lang = "fo" if lang=="fo" else "en"
|
| 191 |
raw_tag = vector_to_tag(vec)
|
| 192 |
wc = wc_code(vec)
|
| 193 |
|
| 194 |
-
|
| 195 |
-
|
| 196 |
-
# Exact override requested earlier:
|
| 197 |
if raw_tag == "DGd":
|
| 198 |
-
|
|
|
|
|
|
|
| 199 |
|
| 200 |
-
labels = [
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 201 |
|
| 202 |
for g in GROUP_ORDER:
|
| 203 |
c = group_code(vec, g)
|
| 204 |
if not c:
|
| 205 |
continue
|
| 206 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 207 |
lbl = label_for(lang, g, wc, c) or label_for(lang, g, "", c) or ""
|
| 208 |
lbl = clean_label(lbl)
|
| 209 |
if not lbl:
|
| 210 |
continue
|
| 211 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 212 |
if lbl not in labels:
|
| 213 |
labels.append(lbl)
|
| 214 |
|
| 215 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 216 |
|
| 217 |
def meaning_detail(vec: torch.Tensor, lang: str) -> str:
|
| 218 |
"""
|
| 219 |
-
Merking / Meaning:
|
| 220 |
keeps codes + labels (useful for debugging and linguists)
|
| 221 |
"""
|
| 222 |
lang = "fo" if lang=="fo" else "en"
|
|
@@ -263,7 +294,7 @@ CODES_BY_WC = compute_codes_by_wc()
|
|
| 263 |
def build_legend(lang: str) -> str:
|
| 264 |
"""
|
| 265 |
Elaborate overview:
|
| 266 |
-
Under each word class, show the letter codes actually used in the CURRENT CSV,
|
| 267 |
with labels from tag_labels.json (fallback to code if missing).
|
| 268 |
"""
|
| 269 |
lang = "fo" if lang=="fo" else "en"
|
|
@@ -279,6 +310,7 @@ def build_legend(lang: str) -> str:
|
|
| 279 |
if not cs:
|
| 280 |
continue
|
| 281 |
|
|
|
|
| 282 |
if lang=="fo":
|
| 283 |
group_name = {
|
| 284 |
"subcategory":"Undirflokkur",
|
|
@@ -410,7 +442,7 @@ with gr.Blocks(theme=theme, css=CSS, title="BRAGD-markarin") as demo:
|
|
| 410 |
# Under results + can be changed AFTER tagging (no rerun; just re-render)
|
| 411 |
lang = gr.Dropdown(choices=[("Føroyskt","fo"), ("English","en")], value="fo", label="Mál / Language")
|
| 412 |
|
| 413 |
-
with gr.Accordion("
|
| 414 |
out_mean_df = gr.Dataframe(wrap=True, interactive=False, label="")
|
| 415 |
|
| 416 |
with gr.Accordion("Markingaryvirlit / Legend", open=False):
|
|
|
|
| 32 |
HIDE_CODES = {"subcategory": {"B"}}
|
| 33 |
|
| 34 |
UI = {
|
| 35 |
+
"fo": {"w":"Orð", "t":"Mark", "s":"Útgreining", "m":"Merking"},
|
| 36 |
+
"en": {"w":"Word","t":"Tag", "s":"Analysis", "m":"Meaning"},
|
| 37 |
}
|
| 38 |
|
| 39 |
# Theme color: #89AFA9 (+ close shades)
|
|
|
|
| 47 |
}
|
| 48 |
.gr-button-primary:hover, button.primary:hover, .primary:hover{ background:var(--primary-600)!important; }
|
| 49 |
a{ color:var(--primary-700)!important; }
|
| 50 |
+
|
| 51 |
+
/* Dataframe column sizing:
|
| 52 |
+
- word + tag stay on one line
|
| 53 |
+
- analysis can wrap only if needed
|
| 54 |
+
*/
|
| 55 |
+
.gr-dataframe table { table-layout: auto !important; width: 100% !important; }
|
| 56 |
+
.gr-dataframe th, .gr-dataframe td { vertical-align: top; }
|
| 57 |
+
.gr-dataframe th:nth-child(1), .gr-dataframe td:nth-child(1) { white-space: nowrap; width: 1%; }
|
| 58 |
+
.gr-dataframe th:nth-child(2), .gr-dataframe td:nth-child(2) { white-space: nowrap; min-width: 8.5rem; }
|
| 59 |
+
.gr-dataframe th:nth-child(3), .gr-dataframe td:nth-child(3) { white-space: normal; }
|
| 60 |
"""
|
| 61 |
|
| 62 |
def simp_tok(s: str):
|
|
|
|
| 188 |
def clean_label(s: str) -> str:
|
| 189 |
s = (s or "").strip()
|
| 190 |
s = re.sub(r"\s+", " ", s)
|
| 191 |
+
# remove leading punctuation/hyphen artifacts
|
| 192 |
s = s.strip(" -;,:")
|
| 193 |
return s
|
| 194 |
|
| 195 |
def visible_summary(vec: torch.Tensor, lang: str) -> str:
|
| 196 |
"""
|
| 197 |
+
Útgreining / Analysis:
|
| 198 |
+
- ONLY words/labels (no letters, no hyphens like "X –")
|
| 199 |
+
- word + tag columns stay single-line; analysis wraps only if needed (CSS)
|
| 200 |
"""
|
| 201 |
lang = "fo" if lang=="fo" else "en"
|
| 202 |
raw_tag = vector_to_tag(vec)
|
| 203 |
wc = wc_code(vec)
|
| 204 |
|
| 205 |
+
# Special-case: DGd should show ONLY "fyriseting"/"preposition"
|
|
|
|
|
|
|
| 206 |
if raw_tag == "DGd":
|
| 207 |
+
return "fyriseting" if lang == "fo" else "preposition"
|
| 208 |
+
|
| 209 |
+
wc_lbl = clean_label(label_for(lang, "word_class", wc, wc) or wc)
|
| 210 |
|
| 211 |
+
labels = []
|
| 212 |
+
|
| 213 |
+
# For pronouns: don't start with the main word-class label (subcategories already include it)
|
| 214 |
+
if wc != "P":
|
| 215 |
+
if wc_lbl:
|
| 216 |
+
labels.append(wc_lbl)
|
| 217 |
|
| 218 |
for g in GROUP_ORDER:
|
| 219 |
c = group_code(vec, g)
|
| 220 |
if not c:
|
| 221 |
continue
|
| 222 |
|
| 223 |
+
# Hide "stýrir falli" / "stýrir ikki falli" in Útgreining (but keep them in expanded tags)
|
| 224 |
+
if wc == "D" and g == "subcategory" and c in {"G", "N"}:
|
| 225 |
+
continue
|
| 226 |
+
|
| 227 |
lbl = label_for(lang, g, wc, c) or label_for(lang, g, "", c) or ""
|
| 228 |
lbl = clean_label(lbl)
|
| 229 |
if not lbl:
|
| 230 |
continue
|
| 231 |
|
| 232 |
+
# Extra safety in case the exact phrases come from labels
|
| 233 |
+
if lang == "fo" and lbl in {"stýrir falli", "stýrir ikki falli"}:
|
| 234 |
+
continue
|
| 235 |
+
if lang == "en" and lbl.lower() in {"governs case", "does not govern case"}:
|
| 236 |
+
continue
|
| 237 |
+
|
| 238 |
if lbl not in labels:
|
| 239 |
labels.append(lbl)
|
| 240 |
|
| 241 |
+
# If pronoun ended up empty (shouldn't), fall back to word-class label
|
| 242 |
+
if not labels and wc_lbl:
|
| 243 |
+
labels = [wc_lbl]
|
| 244 |
+
|
| 245 |
+
return ", ".join(labels)
|
| 246 |
+
|
| 247 |
|
| 248 |
def meaning_detail(vec: torch.Tensor, lang: str) -> str:
|
| 249 |
"""
|
| 250 |
+
Merking / Meaning (more explicit):
|
| 251 |
keeps codes + labels (useful for debugging and linguists)
|
| 252 |
"""
|
| 253 |
lang = "fo" if lang=="fo" else "en"
|
|
|
|
| 294 |
def build_legend(lang: str) -> str:
|
| 295 |
"""
|
| 296 |
Elaborate overview:
|
| 297 |
+
Under each orðaflokkur / word class, show the letter codes actually used in the CURRENT CSV,
|
| 298 |
with labels from tag_labels.json (fallback to code if missing).
|
| 299 |
"""
|
| 300 |
lang = "fo" if lang=="fo" else "en"
|
|
|
|
| 310 |
if not cs:
|
| 311 |
continue
|
| 312 |
|
| 313 |
+
# group header
|
| 314 |
if lang=="fo":
|
| 315 |
group_name = {
|
| 316 |
"subcategory":"Undirflokkur",
|
|
|
|
| 442 |
# Under results + can be changed AFTER tagging (no rerun; just re-render)
|
| 443 |
lang = gr.Dropdown(choices=[("Føroyskt","fo"), ("English","en")], value="fo", label="Mál / Language")
|
| 444 |
|
| 445 |
+
with gr.Accordion("Útgreinað marking / Expanded tags", open=False):
|
| 446 |
out_mean_df = gr.Dataframe(wrap=True, interactive=False, label="")
|
| 447 |
|
| 448 |
with gr.Accordion("Markingaryvirlit / Legend", open=False):
|
tag_labels.json
CHANGED
|
@@ -150,7 +150,10 @@
|
|
| 150 |
"subcategory": {
|
| 151 |
"D": "demonstrative",
|
| 152 |
"E": "possessive",
|
| 153 |
-
"I": "indefinite"
|
|
|
|
|
|
|
|
|
|
| 154 |
},
|
| 155 |
"gender": {
|
| 156 |
"M": "masculine",
|
|
@@ -179,7 +182,9 @@
|
|
| 179 |
},
|
| 180 |
"subcategory": {
|
| 181 |
"C": "cardinal number",
|
| 182 |
-
"O": "Date and other indeclinable number"
|
|
|
|
|
|
|
| 183 |
},
|
| 184 |
"gender": {
|
| 185 |
"M": "masculine",
|
|
@@ -331,8 +336,8 @@
|
|
| 331 |
"A": "lýsingarorð",
|
| 332 |
"P": "fornavn",
|
| 333 |
"N": "talorð",
|
| 334 |
-
"V": "sagnorð
|
| 335 |
-
"L": "lýsingarháttur",
|
| 336 |
"D": "hjáorð",
|
| 337 |
"C": "sambindingarorð",
|
| 338 |
"F": "útlendskt orð",
|
|
@@ -474,7 +479,10 @@
|
|
| 474 |
"subcategory": {
|
| 475 |
"D": "ávísingarfornavn",
|
| 476 |
"E": "ognarfornavn",
|
| 477 |
-
"I": "óbundið fornavn"
|
|
|
|
|
|
|
|
|
|
| 478 |
},
|
| 479 |
"gender": {
|
| 480 |
"M": "kallkyn",
|
|
@@ -503,7 +511,9 @@
|
|
| 503 |
},
|
| 504 |
"subcategory": {
|
| 505 |
"C": "grundtal",
|
| 506 |
-
"O": "dagfesting og onnur óbendandi tøl"
|
|
|
|
|
|
|
| 507 |
},
|
| 508 |
"gender": {
|
| 509 |
"M": "kallkyn",
|
|
@@ -523,7 +533,7 @@
|
|
| 523 |
},
|
| 524 |
"V": {
|
| 525 |
"word_class": {
|
| 526 |
-
"V": "sagnorð
|
| 527 |
},
|
| 528 |
"mood": {
|
| 529 |
"I": "navnháttur",
|
|
@@ -552,7 +562,7 @@
|
|
| 552 |
},
|
| 553 |
"L": {
|
| 554 |
"word_class": {
|
| 555 |
-
"L": "lýsingarháttur"
|
| 556 |
},
|
| 557 |
"tense": {
|
| 558 |
"P": "nútíð",
|
|
|
|
| 150 |
"subcategory": {
|
| 151 |
"D": "demonstrative",
|
| 152 |
"E": "possessive",
|
| 153 |
+
"I": "indefinite",
|
| 154 |
+
"P": "personal pronoun",
|
| 155 |
+
"Q": "interrogative pronoun",
|
| 156 |
+
"X": "reflexive pronoun"
|
| 157 |
},
|
| 158 |
"gender": {
|
| 159 |
"M": "masculine",
|
|
|
|
| 182 |
},
|
| 183 |
"subcategory": {
|
| 184 |
"C": "cardinal number",
|
| 185 |
+
"O": "Date and other indeclinable number",
|
| 186 |
+
"P": "percentage",
|
| 187 |
+
"R": "number preceding other numeral"
|
| 188 |
},
|
| 189 |
"gender": {
|
| 190 |
"M": "masculine",
|
|
|
|
| 336 |
"A": "lýsingarorð",
|
| 337 |
"P": "fornavn",
|
| 338 |
"N": "talorð",
|
| 339 |
+
"V": "sagnorð",
|
| 340 |
+
"L": "tátíðar lýsingarháttur",
|
| 341 |
"D": "hjáorð",
|
| 342 |
"C": "sambindingarorð",
|
| 343 |
"F": "útlendskt orð",
|
|
|
|
| 479 |
"subcategory": {
|
| 480 |
"D": "ávísingarfornavn",
|
| 481 |
"E": "ognarfornavn",
|
| 482 |
+
"I": "óbundið fornavn",
|
| 483 |
+
"P": "perónsfornavn",
|
| 484 |
+
"Q": "spurnarfornavn",
|
| 485 |
+
"X": "afturbent fornavn"
|
| 486 |
},
|
| 487 |
"gender": {
|
| 488 |
"M": "kallkyn",
|
|
|
|
| 511 |
},
|
| 512 |
"subcategory": {
|
| 513 |
"C": "grundtal",
|
| 514 |
+
"O": "dagfesting og onnur óbendandi tøl",
|
| 515 |
+
"P": "prosent",
|
| 516 |
+
"R": "nummar sum er framman fyri annað nummar"
|
| 517 |
},
|
| 518 |
"gender": {
|
| 519 |
"M": "kallkyn",
|
|
|
|
| 533 |
},
|
| 534 |
"V": {
|
| 535 |
"word_class": {
|
| 536 |
+
"V": "sagnorð"
|
| 537 |
},
|
| 538 |
"mood": {
|
| 539 |
"I": "navnháttur",
|
|
|
|
| 562 |
},
|
| 563 |
"L": {
|
| 564 |
"word_class": {
|
| 565 |
+
"L": "tátíðar lýsingarháttur"
|
| 566 |
},
|
| 567 |
"tense": {
|
| 568 |
"P": "nútíð",
|