ontoref-outreach/site/scripts/build/gen-glossary-json.nu
2026-07-17 01:01:30 +01:00

105 lines
4.6 KiB
Text

#!/usr/bin/env nu
# Project the term registry → the glossary the PAGE can read:
# site/public/r/glosario-<lang>.json
#
# The glosses already existed. Every one of them — "NCL — el lenguaje de configuración tipada en
# el que se declara todo esto", "un DAG — grafo dirigido acíclico" — was written in
# .ontoref/ontology/lexicon.ncl for a reader who does not know the word, and then no surface ever
# showed it to one. /acerca-de said NCL and DAG to people who had never met either, and the gate's
# own GlossFirstUse check sat inert with a comment explaining why it could not bite: "the site
# serves no canonical glossary route yet, so failing here would fail on a link nobody can add".
#
# This is that route. Nothing here is authored: the gloss, the preferred form and the learn-more
# href all come from the registry, so the tooltip cannot become the SEVENTH vocabulary — which is
# exactly the failure expediente 6/0 is about.
#
# Usage (from outreach/site):
# nu scripts/build/gen-glossary-json.nu --root ../..
# nu scripts/build/gen-glossary-json.nu --root ../.. --check
def main [
--root: string = "../.."
--out-dir: string = "site/public/r"
--check
] {
let reg = (
^nickel export --format json --import-path $"($root)/.ontoref" $"($root)/.ontoref/ontology/registry.ncl"
| from json
)
mut drift = []
for lang in $reg.languages {
# A term earns a tooltip by HAVING A GLOSS — never by being in the registry. The registry
# governs every word the project writes; the tooltip is for the handful a reader can trip on.
# `drift` needs no tooltip: a Spanish reader gets «deriva» and understands it.
let terms = (
$reg.rules
| where lang == $lang
| where kind == "Term"
| where {|r| ($r.gloss? | default "") != "" }
| each {|r| {
term: $r.instead, # the form the reader actually SEES on the page
gloss: $r.gloss,
href: ($r.gloss_href? | default ""),
} }
| uniq-by term
| sort-by term
)
if ($terms | is-empty) {
# Not a crash: a language may legitimately gloss nothing yet. But say so — a silently empty
# glossary is a tooltip layer that never fires and nobody notices.
print $"glosario [($lang)]: 0 términos con glosa — no se emite"
continue
}
let payload = {
generated_from: ".ontoref/ontology/registry.ncl",
lang: $lang,
terms: $terms,
}
# LA GLOSA ABRE CON LA PALABRA QUE EL LECTOR HA SEÑALADO — Y ESO NO LO COMPROBABA NADIE.
#
# El tooltip sale pegado a la palabra. Si la frase empieza por OTRA, el lector cree que le
# están hablando de otra cosa: pasa el ratón por `FSM` y lee «a state machine —». Las 26
# glosas españolas cumplen la regla («un testigo —», «una gate —», «los modos —») y la cumplen
# por casualidad: se escribieron junto a su `prefer`. En inglés `prefer` es la forma FUENTE, y
# a veces no es la misma palabra que abría la frase española — así entraron `fsm` («a state
# machine» sobre `FSM`) y `red-team` («an adversarial test» sobre `red-team`), las dos en la
# primera tanda de glosas inglesas.
#
# Una convención que solo vive en la cabeza de quien escribe la siguiente entrada no es una
# convención: es una racha. Aquí se ejecuta.
let misaligned = ($terms | where {|t|
let head = ($t.gloss | split row " — " | first | str downcase)
not (($head | str contains ($t.term | str downcase)) or (($t.term | str downcase) | str contains $head))
})
if ($misaligned | is-not-empty) {
print $"glosario [($lang)]: la glosa no abre por la palabra que el lector señala —"
for m in $misaligned { print $" ✗ «($m.term)» → «($m.gloss | split row ' — ' | first)»" }
print " El tooltip se ancla en el término: la frase tiene que empezar por él, o el lector"
print " cree que le hablan de otra cosa. Corrige la glosa en el registro."
exit 1
}
let out = $"($out_dir)/glosario-($lang).json"
let json = ($payload | to json --indent 2)
if $check {
let cur = (if ($out | path exists) { open --raw $out } else { "" })
if $cur != $json { $drift = ($drift | append $out) }
} else {
mkdir $out_dir
$json | save -f $out
print $"glosario → ($out) [($terms | length) términos · ($terms | where href != "" | length) con enlace]"
}
}
if $check {
if ($drift | is-not-empty) {
print $"glossary-check: DRIFT — ($drift | str join ', ') no reproduce desde el registro. Ejecuta `just glossary`."
exit 1
}
print "glossary-check: el glosario servido reproduce desde el registro"
}
}