File: localization.py

package info (click to toggle)
python-mkdocs 1.4.2%2Bdfsg-2
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 5,640 kB
  • sloc: python: 12,310; javascript: 2,315; perl: 142; sh: 84; makefile: 24; xml: 12
file content (88 lines) | stat: -rw-r--r-- 2,837 bytes parent folder | download
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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
from __future__ import annotations

import logging
import os
from typing import Optional, Sequence

import jinja2
from jinja2.ext import Extension, InternationalizationExtension

from mkdocs.config.base import ValidationError

try:
    from babel.core import Locale, UnknownLocaleError
    from babel.support import NullTranslations, Translations

    has_babel = True
except ImportError:  # pragma: no cover
    from mkdocs.utils.babel_stub import Locale, UnknownLocaleError

    has_babel = False


log = logging.getLogger(__name__)
base_path = os.path.dirname(os.path.abspath(__file__))


class NoBabelExtension(InternationalizationExtension):  # pragma: no cover
    def __init__(self, environment):
        Extension.__init__(self, environment)
        environment.extend(
            install_null_translations=self._install_null,
            newstyle_gettext=False,
        )


def parse_locale(locale) -> Locale:
    try:
        return Locale.parse(locale, sep='_')
    except (ValueError, UnknownLocaleError, TypeError) as e:
        raise ValidationError(f'Invalid value for locale: {str(e)}')


def install_translations(
    env: jinja2.Environment, locale: Locale, theme_dirs: Sequence[str]
) -> None:
    if has_babel:
        env.add_extension('jinja2.ext.i18n')
        translations = _get_merged_translations(theme_dirs, 'locales', locale)
        if translations is not None:
            env.install_gettext_translations(translations)
        else:
            env.install_null_translations()
            if locale.language != 'en':
                log.warning(
                    f"No translations could be found for the locale '{locale}'. "
                    'Defaulting to English.'
                )
    else:  # pragma: no cover
        # no babel installed, add dummy support for trans/endtrans blocks
        env.add_extension(NoBabelExtension)
        env.install_null_translations()


def _get_merged_translations(
    theme_dirs: Sequence[str], locales_dir: str, locale: Locale
) -> Optional[Translations]:
    merged_translations: Optional[Translations] = None

    log.debug(f"Looking for translations for locale '{locale}'")
    if locale.territory:
        locale_str = f"{locale.language}_{locale.territory}"
    else:
        locale_str = locale.language
    for theme_dir in reversed(theme_dirs):
        dirname = os.path.join(theme_dir, locales_dir)
        translations = Translations.load(dirname, [locale_str])

        if type(translations) is NullTranslations:
            log.debug(f"No translations found here: '{dirname}'")
            continue

        log.debug(f"Translations found here: '{dirname}'")
        if merged_translations is None:
            merged_translations = translations
        else:
            merged_translations.merge(translations)

    return merged_translations