]> BookStack Code Mirror - bookstack/blob - resources/js/services/translations.ts
Merge pull request #5627 from BookStackApp/lexical_20250525
[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         replacements = Object.assign({}, {count: String(count)}, replacements);
14         const splitText = translation.split('|');
15         const exactCountRegex = /^{([0-9]+)}/;
16         const rangeRegex = /^\[([0-9]+),([0-9*]+)]/;
17         let result = null;
18
19         for (const t of splitText) {
20             // Parse exact matches
21             const exactMatches = t.match(exactCountRegex);
22             if (exactMatches !== null && Number(exactMatches[1]) === count) {
23                 result = t.replace(exactCountRegex, '').trim();
24                 break;
25             }
26
27             // Parse range matches
28             const rangeMatches = t.match(rangeRegex);
29             if (rangeMatches !== null) {
30                 const rangeStart = Number(rangeMatches[1]);
31                 if (rangeStart <= count && (rangeMatches[2] === '*' || Number(rangeMatches[2]) >= count)) {
32                     result = t.replace(rangeRegex, '').trim();
33                     break;
34                 }
35             }
36         }
37
38         if (result === null && splitText.length > 1) {
39             result = (count === 1) ? splitText[0] : splitText[1];
40         }
41
42         if (result === null) {
43             result = splitText[0];
44         }
45
46         return this.performReplacements(result, replacements);
47     }
48
49     protected performReplacements(string: string, replacements: Record<string, string>): string {
50         const replaceMatches = string.match(/:(\S+)/g);
51         if (replaceMatches === null) {
52             return string;
53         }
54
55         let updatedString = string;
56
57         for (const match of replaceMatches) {
58             const key = match.substring(1);
59             if (typeof replacements[key] === 'undefined') {
60                 continue;
61             }
62             updatedString = updatedString.replace(match, replacements[key]);
63         }
64
65         return updatedString;
66     }
67
68 }
Morty Proxy This is a proxified and sanitized view of the page, visit original site.