1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
|
// SPDX-FileCopyrightText: 2026 Progmasoft <support@progmasoft.com>
// SPDX-License-Identifier: AGPL-3.0-or-later WITH AdditionRef-Progmasoft-Patent-Grant-1.1
/** The languages the site is published in; the first is served without a prefix. */
export const locales = ["en-US", "de-DE", "ru-RU", "he-IL"] as const;
export type Locale = (typeof locales)[number];
export const defaultLocale: Locale = "en-US";
/** The first path segment of each language; English has none. */
const prefixes: Record<Locale, string> = {
"en-US": "",
"de-DE": "de",
"ru-RU": "ru",
"he-IL": "he",
};
/** The name of each language in its own language, for the language menu. */
export const localeNames: Record<Locale, string> = {
"en-US": "English",
"de-DE": "Deutsch",
"ru-RU": "Русский",
"he-IL": "עברית",
};
export function isLocale(value: unknown): value is Locale {
return locales.some((locale) => locale === value);
}
/**
* The language a route parameter names: none means English, and a segment that is no prefix
* means the route does not exist.
*/
export function localeOfPrefix(segment: string | undefined): Locale | undefined {
if (segment === undefined || segment === "") return defaultLocale;
return locales.find((locale) => prefixes[locale] === segment && segment !== "");
}
/**
* The path of [page] in [locale]. [page] starts with `/` and names the page in English, so
* `/docs/commands` in German is `/de/docs/commands`.
*/
export function localePath(locale: Locale, page: string): string {
const prefix = prefixes[locale];
if (prefix === "") return page;
return page === "/" ? `/${prefix}` : `/${prefix}${page}`;
}
/** The page a localized path shows, written as its English path. */
export function pageOfPath(path: string): string {
const trimmed = path.length > 1 ? path.replace(/\/+$/, "") : path;
for (const locale of locales) {
const prefix = prefixes[locale];
if (prefix === "") continue;
if (trimmed === `/${prefix}`) return "/";
if (trimmed.startsWith(`/${prefix}/`)) return trimmed.slice(prefix.length + 1);
}
return trimmed;
}
/** The direction the text of a language runs in. */
export function textDirection(locale: Locale): "ltr" | "rtl" {
return locale === "he-IL" ? "rtl" : "ltr";
}
|