Skip to content

Commit

Permalink
Validate translations (#127)
Browse files Browse the repository at this point in the history
* validate translations
* fix some broken links
* replace 'hoid' with 'wit'
* fix broken links
* update regexp
* fix regexp
* skip links that starts with 'http'
  • Loading branch information
lianzhao authored Nov 13, 2021
1 parent 9ff94aa commit 5e37159
Show file tree
Hide file tree
Showing 17 changed files with 33 additions and 18 deletions.
19 changes: 17 additions & 2 deletions bin/validate-translations.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@ const events = JSON.parse(fs.readFileSync('./src/store/events.json', 'utf8')).ma
const locations = JSON.parse(fs.readFileSync('./src/store/locations.json', 'utf8')).map(l => l.id)
const characters = JSON.parse(fs.readFileSync('./src/store/characters.json', 'utf8')).map(l => l.id)
const misc = JSON.parse(fs.readFileSync('./src/store/misc.json', 'utf8')).map(l => l.id)
const allReference = new Set([
...events.map(name => `events/${name}`),
...locations.map(name => `locations/${name}`),
...characters.map(name => `characters/${name}`),
...misc.map(name => `misc/${name}`)
])

let errors = false

Expand All @@ -22,7 +28,7 @@ if (errors) {
process.exit(1)
}

function checkLang (lang) {
function checkLang(lang) {
console.log(`Validating translations for locale '${lang}'`)

checkLangFiles(lang, 'events', events)
Expand All @@ -31,7 +37,7 @@ function checkLang (lang) {
checkLangFiles(lang, 'misc', misc)
}

function checkLangFiles (lang, type, reference) {
function checkLangFiles(lang, type, reference) {
const dirPath = `./translations/${lang}/${type}`

if (!fs.existsSync(dirPath)) {
Expand All @@ -45,5 +51,14 @@ function checkLangFiles (lang, type, reference) {
console.error(`Found translation for unknown ${type} entry '${entryId}' in locale '${lang}'`)
errors = true
}
const fullPath = `${dirPath}/${entry.name}`
const content = fs.readFileSync(fullPath).toString()
const links = [...content.matchAll(/[^_]\[[^\]]*\]\(([^)]*)\)/g)].flat().filter((_, i) => i % 2 === 1)
links.forEach((link) => {
if (!link.startsWith('http') && !allReference.has(link)) {
console.error(`Found broken link ${link} in file ${fullPath}`)
errors = true
}
})
})
}
2 changes: 1 addition & 1 deletion translations/en/events/dalinar-meets-odium.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
Dalinar and Odium meet and discuss final terms and a date for the contest of champions.

## Details
#[Dalinar](characters/dalinar), #[Szeth](characters/szeth), and the Windrunners return from #[Tukar](tukar) just in time to hear news of #[Urithiru's](locations/urithiru) liberation. After sending a message to #[Navani](characters/navani) and asking to meet with #[Jasnah](characters/jasnah) and the Prime after the impending highstorm, Dalinar goes to his quarters. As he enters, he walks onto a golden field and realizes that #[Odium](characters/odium) has come to speak with him. As Odium tries to provoke Dalinar into revealing the nature of his relationship with Ishar, Dalinar realizes that Odium is frightened of him and attempts to provoke Odium in turn. Odium looks at the terms #[Wit](characters/wit) has written on Dalinar's behalf and angrily detects the worldhopper's hand in them. He tells Dalinar that he is incapable of accepting the terms, now that the Everstorm has changed the situation, then explains that his plan has been to use the Rosharans as hardened warriors to fight for him in the cosmere.
#[Dalinar](characters/dalinar), #[Szeth](characters/szeth), and the Windrunners return from #[Tukar](locations/tukar) just in time to hear news of #[Urithiru's](locations/urithiru) liberation. After sending a message to #[Navani](characters/navani) and asking to meet with #[Jasnah](characters/jasnah) and the Prime after the impending highstorm, Dalinar goes to his quarters. As he enters, he walks onto a golden field and realizes that #[Odium](characters/odium) has come to speak with him. As Odium tries to provoke Dalinar into revealing the nature of his relationship with Ishar, Dalinar realizes that Odium is frightened of him and attempts to provoke Odium in turn. Odium looks at the terms #[Wit](characters/wit) has written on Dalinar's behalf and angrily detects the worldhopper's hand in them. He tells Dalinar that he is incapable of accepting the terms, now that the Everstorm has changed the situation, then explains that his plan has been to use the Rosharans as hardened warriors to fight for him in the cosmere.

Odium expresses interest in making an agreement that day, so he describes his terms: as Dalinar has to give up the idea of Odium restraining the Fused in the event of Dalinar's victory, Odium would give up his designs for Roshar and leave the Rosharan system in the event of his own victory. Dalinar, forewarned by Wit, refuses to make any agreement that will allow Odium to leave the Rosharan system, so they continue to negotiate until they settle on something acceptable, despite Dalinar's horror at the prospect of his failure, to them both: a battle of champions in ten days. Should Dalinar's champion win, Odium will cease all hostilities, return #[Alethkar](locations/alethkar) and #[Herdaz](locations/herdaz) to the coalition, and remain bound to the system. Should Odium's champion win, he will still cease hostilities and remain bound to the system, but he will keep what land he has conquered and will gain Dalinar's soul as a Fused.

Expand Down
2 changes: 1 addition & 1 deletion translations/en/events/diagram-disbands.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
Taravangian meets with the inner circle of the Diagram and the group disbands.

## Details
#[Taravangian](characters/taravangian) gathers his friends to tell them farewell in his chambers at #[Urithiru](locations/urithiru). Later that day, he plans to leave for #[Emul](locations/emul) with #[Dalinar](characters/dalinar) and #[Jasnah](characters/jasnah), while the rest of the #[Diagram](misc/diagram) would go back to #[Kharbranth](locations/kharbranth). In Emul, Taravangian intends to have his armies betray the coalition, fulfiling his part of the agreement with 3[Odium](odium). #[Jah Keved](locations/jah-keved) too will turn against the coalition at that time. He announces to his group that the Diagram has served its purpose and now has to be disbanded. Kharbranth is to distance itself from Taravangian's actions, so that the city may be able to stay out of the war. After his friends leave the room, Taravangian reassures himself that saving a single city was really all he could’ve done, and he throws his copy of the Diagram into the fire.
#[Taravangian](characters/taravangian) gathers his friends to tell them farewell in his chambers at #[Urithiru](locations/urithiru). Later that day, he plans to leave for #[Emul](locations/emul) with #[Dalinar](characters/dalinar) and #[Jasnah](characters/jasnah), while the rest of the #[Diagram](misc/diagram) would go back to #[Kharbranth](locations/kharbranth). In Emul, Taravangian intends to have his armies betray the coalition, fulfiling his part of the agreement with [Odium](characters/odium). #[Jah Keved](locations/jah-keved) too will turn against the coalition at that time. He announces to his group that the Diagram has served its purpose and now has to be disbanded. Kharbranth is to distance itself from Taravangian's actions, so that the city may be able to stay out of the war. After his friends leave the room, Taravangian reassures himself that saving a single city was really all he could’ve done, and he throws his copy of the Diagram into the fire.

## Metadata
| Field | Value |
Expand Down
2 changes: 1 addition & 1 deletion translations/en/events/fourth-bridge-departure.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@
The *Fourth Bridge* departs from the Shattered Plains.

## Details
The *Fourth Bridge* departs from the #[Shattered Plains](locations/shattered-plains) on its maiden voyage. The plan is to take the ship north, out over the #[Steamwater Ocean](locations/steamwater-ocean).
The *Fourth Bridge* departs from the #[Shattered Plains](locations/shattered-plains) on its maiden voyage. The plan is to take the ship north, out over the #[Steamwater Ocean](locations/steamwaterocean).
2 changes: 1 addition & 1 deletion translations/en/events/urithiru-captured.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
Following Taravangian's betrayal, Raboniel leads her forces in an assault on Urithiru. Navani is barely able to establish the Sibling's defenses before the tower is fully captured.

## Details
As #[Taravangian](characters/taravangian) betrays the coalition, Raboniel's forces sneak in through the basements of #[Urithiru](locations/urithiru) in a surprise attack on the tower city. After corrupting a portion of the crystal pillar with Voidlight, the tower's defenses are inverted such that most of the Knights Radiant in the tower are immediately rendered unconscious. Various Fused and and their singer armies assault the city, and #[characters/Venli](venli) watches on as Raboniel attempts to fully corrupt the crystal pillar.
As #[Taravangian](characters/taravangian) betrays the coalition, Raboniel's forces sneak in through the basements of #[Urithiru](locations/urithiru) in a surprise attack on the tower city. After corrupting a portion of the crystal pillar with Voidlight, the tower's defenses are inverted such that most of the Knights Radiant in the tower are immediately rendered unconscious. Various Fused and and their singer armies assault the city, and #[characters/Venli](characters/venli) watches on as Raboniel attempts to fully corrupt the crystal pillar.

#[Navani](characters/navani) is questioning Dabbid when the tower's defenses are disabled. They quickly determine that the city is under attack and send runners to organize the available military leaders as Dabbid helps Navani make contact with the Sibling. Meanwhile, #[Kaladin](characters/kaladin) carries an unconscious Teft to his family's quarters, and decides to lay low after realizing that the tower is defenseless. Working deep into the night, Navani organizes a desperate resistance. The Sibling informs her that they will soon fall to Raboniel's corruption unless Navani is able to activate a backup defense system to protect the crystal pillar. While Teofil leads a suicide mission to attack at the heart of the tower, Navani locates one of the tower's defense nodes and fills it with Stormlight to activate the fabrial. Finally, she destroys the node itself.

Expand Down
2 changes: 1 addition & 1 deletion translations/en/events/warlight-discovered.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
Working with Raboneil, Navani discovers that harmonizing the rhythms of Stormlight and Voidlight allows for the two Lights to be combined into Warlight.

## Details
#[Navani](characters/navani) continues to try to get the Sibling to speak to her, repeatedly apologizing for her failure to realize that they were being spied on. Raboniel enters, and Navani is amazed to hear her reminisce about the shadowdays. She is so tired of the war and is dismissive of Navani’s suggestion of peace because their previous attempts had failed. Navani realizes that Raboniel’s desire to combine the Lights is related to her desire to end the war. They discuss her research progress, including Navani's realization that Stormlight responds to sound. She learns that Raboniel can hear the tone of Light, the same tone that she uses to get the Light to transfer spheres. Raboniel explains that there is a rhythm as well as a tone, and that Towerlight has two rhythms that work in harmony. Navani wonders if the rhythms of Stormlight and Voidlight could harmonize, but Raboniel says that Stormlight is too orderly and Voidlight too chaotic. Navani convinces her to try, Raboniel singing the rhythm and tone of Voidlight, and with some effort, Navani doing the same for Stormlight. Their two rhythms eventually come into harmony, and the two kinds of Light successfully mix and infuse the sphere. Raboniel recognizes the rhythm of the Light as the Rhythm of War and is shocked that the Lights did not destroy each other. Navani asks about her motivations, and Raboniel suggests that the discovery might allow them to kill a god--like how Honor was killed. Navani realizes that #[characters/Gavilar](gavilar) had been looking for a way to kill a god. Even more, she realizes that he had discovered the opposite to Voidlight, and that that is what had been in the sphere that killed her scholars. Raboniel gets ready to leave, thanking Navani for her assistance and telling her that though Navani has earned her gratitude, she is not going to leave #[Urithiru](locations/urithiru).
#[Navani](characters/navani) continues to try to get the Sibling to speak to her, repeatedly apologizing for her failure to realize that they were being spied on. Raboniel enters, and Navani is amazed to hear her reminisce about the shadowdays. She is so tired of the war and is dismissive of Navani’s suggestion of peace because their previous attempts had failed. Navani realizes that Raboniel’s desire to combine the Lights is related to her desire to end the war. They discuss her research progress, including Navani's realization that Stormlight responds to sound. She learns that Raboniel can hear the tone of Light, the same tone that she uses to get the Light to transfer spheres. Raboniel explains that there is a rhythm as well as a tone, and that Towerlight has two rhythms that work in harmony. Navani wonders if the rhythms of Stormlight and Voidlight could harmonize, but Raboniel says that Stormlight is too orderly and Voidlight too chaotic. Navani convinces her to try, Raboniel singing the rhythm and tone of Voidlight, and with some effort, Navani doing the same for Stormlight. Their two rhythms eventually come into harmony, and the two kinds of Light successfully mix and infuse the sphere. Raboniel recognizes the rhythm of the Light as the Rhythm of War and is shocked that the Lights did not destroy each other. Navani asks about her motivations, and Raboniel suggests that the discovery might allow them to kill a god--like how Honor was killed. Navani realizes that #[characters/Gavilar](characters/gavilar) had been looking for a way to kill a god. Even more, she realizes that he had discovered the opposite to Voidlight, and that that is what had been in the sphere that killed her scholars. Raboniel gets ready to leave, thanking Navani for her assistance and telling her that though Navani has earned her gratitude, she is not going to leave #[Urithiru](locations/urithiru).

## Metadata
| Field | Value |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
A la vuelta de Kaladin a Urithiru, el Puente Cuatro empieza a entrenar escuderos Corredores del Viento. La familia de Roca llega a las Llanuras Quebradas.

## Details
Cuando #[Kaladin](characters/kaladin) regresa tras su misión en #[Alezkar](locations/Alethkar), empieza a hacerse cargo de la evolución del creciente número de Corredores del Viento. Varios miembros del Puente Cuatro muestran indicios de ser escuderos de Kaladin, y en el transcurso de las semanas, tanto la mayoría de la cuadrilla como algunos recién llegados, seguirán los pasos para convertirse en escuderos o en Corredores del Viento plenos.
Cuando #[Kaladin](characters/kaladin) regresa tras su misión en #[Alezkar](locations/alethkar), empieza a hacerse cargo de la evolución del creciente número de Corredores del Viento. Varios miembros del Puente Cuatro muestran indicios de ser escuderos de Kaladin, y en el transcurso de las semanas, tanto la mayoría de la cuadrilla como algunos recién llegados, seguirán los pasos para convertirse en escuderos o en Corredores del Viento plenos.

## Metadata
| Field | Value |
Expand Down
2 changes: 1 addition & 1 deletion translations/es-ES/events/everstorm-countdown.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
Renarin empieza a escribir una cuenta atrás para la Tormenta Eterna.

## Details
Dotado de algún tipo de capacidad de predicción incontrolable gracias a su spren de Vigilante de la Verdad corrupto, Glys, #[Renarin](characters/renarin) empieza a escribir glifos que representan una cuenta atrás de la #[Batalla de Narak](events/battle-of-narak) y de la invocación de la Tormenta Eterna.
Dotado de algún tipo de capacidad de predicción incontrolable gracias a su spren de Vigilante de la Verdad corrupto, Glys, #[Renarin](characters/renarin) empieza a escribir glifos que representan una cuenta atrás de la #[Batalla de Narak](events/battle-of-narak-and-the-everstorm) y de la invocación de la Tormenta Eterna.

## Metadata
| Field | Value |
Expand Down
2 changes: 1 addition & 1 deletion translations/es-ES/events/jasnah-arrives.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
Dada por muerta tras el naufragio en costas de las Tierras Heladas, Jasnah sorprende a todo el mundo con su súbita llegada a Urirhitu.

## Details
Después de regresar al Reino Físico, #[Jasnah](characters/jasnah) viajó un tiempo con #[Sagaz](characters/hoid) antes de llegar a las #[Llanuras Quebradas](locations/shattered-plains) en solitario. Sin intención de contactar con su familia tras su regreso, y con asesinos presuntamente interesados todavía en matarla, Jasnah elige mantener su anonimato hasta llegar a salvo a #[Urithiru](locations/urithiru).
Después de regresar al Reino Físico, #[Jasnah](characters/jasnah) viajó un tiempo con #[Sagaz](characters/wit) antes de llegar a las #[Llanuras Quebradas](locations/shattered-plains) en solitario. Sin intención de contactar con su familia tras su regreso, y con asesinos presuntamente interesados todavía en matarla, Jasnah elige mantener su anonimato hasta llegar a salvo a #[Urithiru](locations/urithiru).

## Metadata
| Field | Value |
Expand Down
2 changes: 1 addition & 1 deletion translations/es-ES/events/jasnah-returns-from-shadesmar.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
Jasnah regresa de Shadesmar tras visitar a los altospren y se encuentra conque Sagaz la está esperando.

## Details
Atacada por los Sangre Espectral a bordo del *Placer del Viento*, #[Jasnah](characters/jasnah) se transportó accidentalmente a Shadesmar y se dio cuenta de que volver al Reino Físico de forma inmediata era algo imposible. Allí pasó la mayor parte de su tiempo visitando a los altospren para aprender más sobre el pasado de Roshar. Meses más tarde, Jasnah pudo regresar a algún lugar de las #[Montañas Irreclamadas](locations/unclaimed-hills), donde #[Sagaz](characters/hoid) la estaba esperando.
Atacada por los Sangre Espectral a bordo del *Placer del Viento*, #[Jasnah](characters/jasnah) se transportó accidentalmente a Shadesmar y se dio cuenta de que volver al Reino Físico de forma inmediata era algo imposible. Allí pasó la mayor parte de su tiempo visitando a los altospren para aprender más sobre el pasado de Roshar. Meses más tarde, Jasnah pudo regresar a algún lugar de las #[Montañas Irreclamadas](locations/unclaimed-hills), donde #[Sagaz](characters/wit) la estaba esperando.

## Metadata
| Field | Value |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@
Después de trabajar para hacerse con el liderazgo de la casa Kholin, Gavilar y Dalinar empiezan una campaña para unificar Alezkar bajo una monarquía.

## Details
Una vez al mando de la casa Kholin, #[Dalinar](characters/dalinar) y #[Gavilar](characters/gavilar) trabajan para unificar #[Alezkar](locations/alezkar) bajo una monarquía liderada por Gavilar. Forjaron una alianza con Sadeas y se enzarzaron en guerra contra los altos príncipes que se interpusieron en su camino.
Una vez al mando de la casa Kholin, #[Dalinar](characters/dalinar) y #[Gavilar](characters/gavilar) trabajan para unificar #[Alezkar](locations/alethkar) bajo una monarquía liderada por Gavilar. Forjaron una alianza con Sadeas y se enzarzaron en guerra contra los altos príncipes que se interpusieron en su camino.
2 changes: 1 addition & 1 deletion translations/es-ES/events/state-of-the-world.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ El estado actual del mundo tras la Batalla de la Explanada Thayleña.
> —Cambia esta parte del territorio a un oro ardiente. [...]
> Según los informes recibidos por vinculacaña, casi todos los reinos menores que rodeaban el #[Lagopuro](locations/purelake) estaban conquistados por Iri, que había avanzado en compañía de los Fusionados para tomar unas tierras a las que tenía echado el ojo desde hacía generaciones. Con ello, el enemigo dominaba un total de tres Puertas Juradas. #[Shallan](characters/shallan) pintó esos reinos en el mapa de un vivo color dorado, a petición de Dalinar.
> #[Azir](locations/azir) y sus protectorados los pintó con una pauta de azul y granate, el símbolo que las escribas azishianas habían escogido para la alianza entre sus reinos. [...]
> Shallan siguió tiñendo el territorio de colores según iba pidiéndole Dalinar. #[Marat](locations/marat) y sus tierras circundantes se volvieron doradas, igual que #[Alezkar](locations/alethkar), por desgracia. Los territorios que no se habían definido por un bando, como #[Shinovar](locations/shinovar) y #[Tukar](locations/tikar), las coloreó de verde. El resultado fue una visión depresiva de un continente, con demasiado poco terreno pintado en los tonos de su coalición.
> Shallan siguió tiñendo el territorio de colores según iba pidiéndole Dalinar. #[Marat](locations/marat) y sus tierras circundantes se volvieron doradas, igual que #[Alezkar](locations/alethkar), por desgracia. Los territorios que no se habían definido por un bando, como #[Shinovar](locations/shinovar) y #[Tukar](locations/tukar), las coloreó de verde. El resultado fue una visión depresiva de un continente, con demasiado poco terreno pintado en los tonos de su coalición.
## Metadata
| Field | Value |
Expand Down
Loading

0 comments on commit 5e37159

Please sign in to comment.