Read-only mirrors. Development, issues and pull requests are on GitHub.

summaryrefslogtreecommitdiffhomepage
path: root/app/content/locales.ts
blob: 74ba08603ae00bd8afae9eb06483ccaa088f46be (plain)
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";
}