2020-11-17 02:22:48 +01:00
import * as fs from "fs" ;
import { Utils } from "../Utils" ;
2021-05-19 16:15:12 +02:00
import ScriptUtils from "./ScriptUtils" ;
import { readFileSync , writeFileSync } from "fs" ;
2021-05-19 20:47:41 +02:00
import LayerConfig from "../Customizations/JSON/LayerConfig" ;
import { LayerConfigJson } from "../Customizations/JSON/LayerConfigJson" ;
import * as bookcases from "../assets/layers/public_bookcase/public_bookcase.json"
import LayerOverviewUtils from "./generateLayerOverview" ;
const knownLanguages = [ "en" , "nl" , "de" , "fr" , "es" , "gl" , "ca" ] ;
2021-05-19 16:15:12 +02:00
class TranslationPart {
contents : Map < string , TranslationPart | string > = new Map < string , TranslationPart | string > ( )
2021-05-19 20:47:41 +02:00
add ( language : string , obj : any ) {
2021-05-19 16:15:12 +02:00
for ( const key in obj ) {
const v = obj [ key ]
2021-05-19 20:47:41 +02:00
if ( ! this . contents . has ( key ) ) {
2021-05-19 16:15:12 +02:00
this . contents . set ( key , new TranslationPart ( ) )
}
const subpart = this . contents . get ( key ) as TranslationPart
2021-05-19 20:47:41 +02:00
if ( typeof v === "string" ) {
2021-05-19 16:15:12 +02:00
subpart . contents . set ( language , v )
2021-05-19 20:47:41 +02:00
} else {
2021-05-19 16:15:12 +02:00
subpart . add ( language , v )
}
}
}
2021-05-19 20:47:41 +02:00
addTranslationObject ( translations : any , context? : string ) {
for ( const translationsKey in translations ) {
if ( ! translations . hasOwnProperty ( translationsKey ) ) {
continue ;
}
const v = translations [ translationsKey ]
if ( typeof ( v ) != "string" ) {
console . error ( "Non-string object in translation: " , translations [ translationsKey ] )
throw "Error in an object depicting a translation: a non-string object was found. (" + context + ")\n You probably put some other section accidentally in the translation"
}
this . contents . set ( translationsKey , v )
}
}
isLeaf() {
for ( let key of Array . from ( this . contents . keys ( ) ) ) {
const value = this . contents . get ( key ) ;
if ( typeof value !== "string" ) {
return false ;
}
}
return true ;
}
recursiveAdd ( object : any ) {
const isProbablyTranslationObject = knownLanguages . map ( l = > object . hasOwnProperty ( l ) ) . filter ( x = > x ) . length > 0 ;
if ( isProbablyTranslationObject ) {
this . addTranslationObject ( object )
return ;
}
for ( const key in object ) {
if ( ! object . hasOwnProperty ( key ) ) {
continue ;
}
const v = object [ key ]
if ( v == null ) {
console . warn ( "Got a null value for key " , key )
continue
}
if ( typeof v !== "object" ) {
continue ;
}
if ( ! this . contents . get ( key ) ) {
this . contents . set ( key , new TranslationPart ( ) )
}
( this . contents . get ( key ) as TranslationPart ) . recursiveAdd ( v ) ;
}
}
knownLanguages ( ) : string [ ] {
const languages = [ ]
for ( let key of Array . from ( this . contents . keys ( ) ) ) {
2021-05-19 16:15:12 +02:00
const value = this . contents . get ( key ) ;
2021-05-19 20:47:41 +02:00
if ( typeof value === "string" ) {
languages . push ( key )
} else {
languages . push ( . . . ( value as TranslationPart ) . knownLanguages ( ) )
}
}
return Utils . Dedup ( languages ) ;
}
toJson ( neededLanguage? : string ) : string {
const parts = [ ]
for ( let key of Array . from ( this . contents . keys ( ) ) ) {
let value = this . contents . get ( key ) ;
if ( typeof value === "string" ) {
value = value . replace ( /"/g , "\\\"" )
if ( neededLanguage === undefined ) {
parts . push ( ` \ " ${ key } \ ": \ " ${ value } \ " ` )
} else if ( key === neededLanguage ) {
return ` " ${ value } " `
}
} else {
const sub = ( value as TranslationPart ) . toJson ( neededLanguage )
if ( sub !== "" ) {
parts . push ( ` \ " ${ key } \ ": ${ sub } ` ) ;
}
2021-05-19 16:15:12 +02:00
}
}
2021-05-19 20:47:41 +02:00
if ( parts . length === 0 ) {
return "" ;
}
return ` { ${ parts . join ( "," ) } } ` ;
2021-05-19 16:15:12 +02:00
}
}
2020-11-17 02:22:48 +01:00
function isTranslation ( tr : any ) : boolean {
for ( const key in tr ) {
if ( typeof tr [ key ] !== "string" ) {
return false ;
}
}
return true ;
}
function transformTranslation ( obj : any , depth = 1 ) {
if ( isTranslation ( obj ) ) {
return ` new Translation( ${ JSON . stringify ( obj ) } ) `
}
let values = ""
for ( const key in obj ) {
2021-05-19 20:47:41 +02:00
if ( key === "#" ) {
2021-01-18 02:51:42 +01:00
continue ;
}
2021-05-19 20:47:41 +02:00
if ( key . match ( "^[a-zA-Z0-9_]*$" ) === null ) {
throw "Invalid character in key: " + key
2021-01-18 02:51:42 +01:00
}
2020-11-17 02:22:48 +01:00
values += ( Utils . Times ( ( _ ) = > " " , depth ) ) + key + ": " + transformTranslation ( obj [ key ] , depth + 1 ) + ",\n"
}
return ` { ${ values } } ` ;
}
function genTranslations() {
2021-05-19 16:15:12 +02:00
const translations = JSON . parse ( fs . readFileSync ( "./assets/generated/translations.json" , "utf-8" ) )
2020-11-17 02:22:48 +01:00
const transformed = transformTranslation ( translations ) ;
2021-05-10 23:43:30 +02:00
let module = ` import {Translation} from "../../UI/i18n/Translation" \ n \ nexport default class CompiledTranslations { \ n \ n ` ;
2020-11-17 02:22:48 +01:00
module += " public static t = " + transformed ;
module += "}"
2021-05-10 23:43:30 +02:00
fs . writeFileSync ( "./assets/generated/CompiledTranslations.ts" , module ) ;
2020-11-17 02:22:48 +01:00
}
2021-05-19 16:15:12 +02:00
// Read 'lang/*.json', writes to 'assets/generated/translations.json'
2021-05-19 20:47:41 +02:00
function compileTranslationsFromWeblate() {
2021-05-19 16:15:12 +02:00
const translations = ScriptUtils . readDirRecSync ( "./langs" )
. filter ( path = > path . indexOf ( ".json" ) > 0 )
const allTranslations = new TranslationPart ( )
for ( const translationFile of translations ) {
const contents = JSON . parse ( readFileSync ( translationFile , "utf-8" ) ) ;
let language = translationFile . substring ( translationFile . lastIndexOf ( "/" ) + 1 )
2021-05-19 20:47:41 +02:00
language = language . substring ( 0 , language . length - 5 )
2021-05-19 16:15:12 +02:00
allTranslations . add ( language , contents )
}
2021-05-19 20:47:41 +02:00
writeFileSync ( "./assets/generated/translations.json" , JSON . stringify ( JSON . parse ( allTranslations . toJson ( ) ) , null , " " ) )
2021-05-19 16:15:12 +02:00
}
2021-05-19 20:47:41 +02:00
function generateTranslationFromLayerConfig ( layerConfig : LayerConfigJson ) : TranslationPart {
const tr = new TranslationPart ( ) ;
tr . recursiveAdd ( layerConfig )
return tr ;
}
function generateLayerTranslationsObject() {
const layerFiles = new LayerOverviewUtils ( ) . getLayerFiles ( ) ;
const tr = new TranslationPart ( ) ;
for ( const layerFile of layerFiles ) {
const config : LayerConfigJson = layerFile . parsed ;
const layerTr = generateTranslationFromLayerConfig ( config )
tr . contents . set ( config . id , layerTr )
}
const langs = tr . knownLanguages ( ) ;
for ( const lang of langs ) {
console . log ( "Exporting " , lang )
let json = tr . toJson ( lang )
try {
json = JSON . stringify ( JSON . parse ( json ) , null , " " ) ;
} catch ( e ) {
console . error ( e )
}
writeFileSync ( "langs/layers/" + lang + ".json" , json )
}
}
generateLayerTranslationsObject ( )
2021-05-19 16:15:12 +02:00
compileTranslationsFromWeblate ( ) ;
2020-11-17 02:22:48 +01:00
genTranslations ( )