]> BookStack Code Mirror - bookstack/blob - resources/js/services/translations.ts
Vectors: Added command to regenerate for all
[bookstack] / resources / js / services / translations.ts
1 /**
2  *  Translation Manager
3  *  Helps with some of the JavaScript side of translating strings
4  *  in a way which fits with Laravel.
5  */
6 export class Translator {
7
8     /**
9      * Parse the given translation and find the correct plural option
10      * to use. Similar format at Laravel's 'trans_choice' helper.
11      */
12     choice(translation: string, count: number, replacements: Record<string, string> = {}): string {
13         const splitText = translation.split('|');
14         const exactCountRegex = /^{([0-9]+)}/;
15         const rangeRegex = /^\[([0-9]+),([0-9*]+)]/;
16         let result = null;
17
18         for (const t of splitText) {
19             // Parse exact matches
20             const exactMatches = t.match(exactCountRegex);
21             if (exactMatches !== null && Number(exactMatches[1]) === count) {
22                 result = t.replace(exactCountRegex, '').trim();
23                 break;
24             }
25
26             // Parse range matches
27             const rangeMatches = t.match(rangeRegex);
28             if (rangeMatches !== null) {
29                 const rangeStart = Number(rangeMatches[1]);
30                 if (rangeStart <= count && (rangeMatches[2] === '*' || Number(rangeMatches[2]) >= count)) {
31                     result = t.replace(rangeRegex, '').trim();
32                     break;
33                 }
34             }
35         }
36
37         if (result === null && splitText.length > 1) {
38             result = (count === 1) ? splitText[0] : splitText[1];
39         }
40
41         if (result === null) {
42             result = splitText[0];
43         }
44
45         return this.performReplacements(result, replacements);
46     }
47
48     protected performReplacements(string: string, replacements: Record<string, string>): string {
49         const replaceMatches = string.match(/:(\S+)/g);
50         if (replaceMatches === null) {
51             return string;
52         }
53
54         let updatedString = string;
55
56         for (const match of replaceMatches) {
57             const key = match.substring(1);
58             if (typeof replacements[key] === 'undefined') {
59                 continue;
60             }
61             updatedString = updatedString.replace(match, replacements[key]);
62         }
63
64         return updatedString;
65     }
66
67 }