Tooling: use the same sort as weblate
This commit is contained in:
parent
d02e6bb83f
commit
198a1964fb
1 changed files with 50 additions and 23 deletions
|
@ -6,6 +6,7 @@ import Script from "./Script"
|
||||||
|
|
||||||
const knownLanguages = ["en", "nl", "de", "fr", "es", "gl", "ca"]
|
const knownLanguages = ["en", "nl", "de", "fr", "es", "gl", "ca"]
|
||||||
const ignoreTerms = ["searchTerms"]
|
const ignoreTerms = ["searchTerms"]
|
||||||
|
|
||||||
class TranslationPart {
|
class TranslationPart {
|
||||||
contents: Map<string, TranslationPart | string> = new Map<string, TranslationPart | string>()
|
contents: Map<string, TranslationPart | string> = new Map<string, TranslationPart | string>()
|
||||||
|
|
||||||
|
@ -54,10 +55,10 @@ class TranslationPart {
|
||||||
if (typeof v != "string") {
|
if (typeof v != "string") {
|
||||||
console.error(
|
console.error(
|
||||||
`Non-string object at ${context} in translation while trying to add the translation ` +
|
`Non-string object at ${context} in translation while trying to add the translation ` +
|
||||||
JSON.stringify(v) +
|
JSON.stringify(v) +
|
||||||
` to '` +
|
` to '` +
|
||||||
translationsKey +
|
translationsKey +
|
||||||
"'. The offending object which _should_ be a translation is: ",
|
"'. The offending object which _should_ be a translation is: ",
|
||||||
v,
|
v,
|
||||||
"\n\nThe current object is (only showing en):",
|
"\n\nThe current object is (only showing en):",
|
||||||
this.toJson(),
|
this.toJson(),
|
||||||
|
@ -96,9 +97,9 @@ class TranslationPart {
|
||||||
if (noTranslate !== undefined) {
|
if (noTranslate !== undefined) {
|
||||||
console.log(
|
console.log(
|
||||||
"Ignoring some translations for " +
|
"Ignoring some translations for " +
|
||||||
context +
|
context +
|
||||||
": " +
|
": " +
|
||||||
dontTranslateKeys.join(", ")
|
dontTranslateKeys.join(", ")
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -184,7 +185,7 @@ class TranslationPart {
|
||||||
let value = this.contents.get(key)
|
let value = this.contents.get(key)
|
||||||
|
|
||||||
if (typeof value === "string") {
|
if (typeof value === "string") {
|
||||||
value = value.replace(/"/g, '\\"').replace(/\n/g, "\\n")
|
value = value.replace(/"/g, "\\\"").replace(/\n/g, "\\n")
|
||||||
if (neededLanguage === undefined) {
|
if (neededLanguage === undefined) {
|
||||||
parts.push(`\"${key}\": \"${value}\"`)
|
parts.push(`\"${key}\": \"${value}\"`)
|
||||||
} else if (key === neededLanguage) {
|
} else if (key === neededLanguage) {
|
||||||
|
@ -234,7 +235,7 @@ class TranslationPart {
|
||||||
} else if (!isLeaf) {
|
} else if (!isLeaf) {
|
||||||
errors.push({
|
errors.push({
|
||||||
error: "Mixed node: non-leaf node has translation strings",
|
error: "Mixed node: non-leaf node has translation strings",
|
||||||
path: path,
|
path: path
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -285,7 +286,7 @@ class TranslationPart {
|
||||||
value +
|
value +
|
||||||
"\n" +
|
"\n" +
|
||||||
fixLink,
|
fixLink,
|
||||||
path: path,
|
path: path
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
|
@ -297,7 +298,7 @@ class TranslationPart {
|
||||||
error: `The translation for ${key} does not have the required subpart ${part} (in ${usedByLanguage}).
|
error: `The translation for ${key} does not have the required subpart ${part} (in ${usedByLanguage}).
|
||||||
\tThe full translation is ${value}
|
\tThe full translation is ${value}
|
||||||
\t${fixLink}`,
|
\t${fixLink}`,
|
||||||
path: path,
|
path: path
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -426,22 +427,49 @@ function transformTranslation(
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* const result = sortKeys({"b": 43, "a": 42})
|
* const result = stringifySorted({"b": 43, "a": 42})
|
||||||
* JSON.stringify(result) // => '{"a":42,"b":43}'
|
* result // => '{"a": 42,"b": 43}'
|
||||||
|
*
|
||||||
|
* // Should have correct newlines
|
||||||
|
* const result = stringifySorted({"b": {"x": "y"}, "a": 42}, " ")
|
||||||
|
* result // => '{\n "a": 42,\n "b": {\n "x": "y"\n }\n}'
|
||||||
|
*
|
||||||
|
* // Should sort like weblate does
|
||||||
|
* const result = stringifySorted({"1": "abc", "2": "def", "9": "ghi", "10": "xyz", "11": "uvw"})
|
||||||
|
* result // => '{"1": "abc","10": "xyz","11": "uvw","2": "def","9", "ghi"}'
|
||||||
*/
|
*/
|
||||||
function sortKeys(o: object): object {
|
function stringifySorted(o: object, space: string = undefined, depth = 0): string {
|
||||||
const keys = Object.keys(o)
|
const keys = Object.keys(o)
|
||||||
keys.sort((a, b) => ("" + a < "" + b ? -1 : 1))
|
let obj = "{"
|
||||||
const nw = {}
|
|
||||||
for (const key of keys) {
|
obj += keys.sort().map(key => {
|
||||||
const v = o[key]
|
const v = o[key]
|
||||||
|
let r = ""
|
||||||
|
if (space !== undefined) {
|
||||||
|
r += "\n"
|
||||||
|
for (let i = 0; i <= depth; i++) {
|
||||||
|
r += space
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
r += JSON.stringify("" + key) + ": "
|
||||||
if (typeof v === "object") {
|
if (typeof v === "object") {
|
||||||
nw[key] = sortKeys(v)
|
r += stringifySorted(v, space, depth + 1)
|
||||||
|
} else if (Array.isArray(v)) {
|
||||||
|
r += "[" + v.map(v_ => stringifySorted(v_, space, depth + 1)).join(",") + "]"
|
||||||
} else {
|
} else {
|
||||||
nw[key] = v
|
r += JSON.stringify(v)
|
||||||
|
}
|
||||||
|
return r
|
||||||
|
}).join(",")
|
||||||
|
if (space !== undefined) {
|
||||||
|
obj += "\n"
|
||||||
|
for (let i = 0; i < depth; i++) {
|
||||||
|
obj += space
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nw
|
obj += "}"
|
||||||
|
return obj
|
||||||
}
|
}
|
||||||
|
|
||||||
function removeEmptyString(object: object) {
|
function removeEmptyString(object: object) {
|
||||||
|
@ -464,9 +492,8 @@ function formatFile(path) {
|
||||||
const original = readFileSync(path, "utf8")
|
const original = readFileSync(path, "utf8")
|
||||||
let contents = JSON.parse(original)
|
let contents = JSON.parse(original)
|
||||||
contents = removeEmptyString(contents)
|
contents = removeEmptyString(contents)
|
||||||
contents = sortKeys(contents)
|
contents = stringifySorted(contents, " ")
|
||||||
const endsWithNewline = original.endsWith("\n")
|
writeFileSync(path, contents)
|
||||||
writeFileSync(path, JSON.stringify(contents, null, " ") + (endsWithNewline ? "\n" : ""))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue