diff --git a/mkdocs_static_i18n/config.py b/mkdocs_static_i18n/config.py index 7717a85..0052add 100644 --- a/mkdocs_static_i18n/config.py +++ b/mkdocs_static_i18n/config.py @@ -80,6 +80,13 @@ def validate(self): return failed, warnings +class I18nPoOverridesConfig(Config): + """configure the user overrides which should be read from a po file""" + + po_dir = config_options.Type(str, default="") + override = config_options.Optional(config_options.ListOfItems(config_options.Type(str))) + + class I18nPluginConfig(Config): """ """ @@ -91,6 +98,7 @@ class I18nPluginConfig(Config): languages = config_options.ListOfItems( config_options.SubConfig(I18nPluginLanguage, validate=True) ) + po_overrides = config_options.SubConfig(I18nPoOverridesConfig, validate=True) def validate(self): failed, warnings = super().validate() diff --git a/mkdocs_static_i18n/reconfigure.py b/mkdocs_static_i18n/reconfigure.py index 682fd8f..c7cfdbe 100644 --- a/mkdocs_static_i18n/reconfigure.py +++ b/mkdocs_static_i18n/reconfigure.py @@ -1,9 +1,11 @@ +import os.path from collections import defaultdict from copy import deepcopy from pathlib import Path, PurePath from typing import Union from urllib.parse import urlsplit +from babel.messages import pofile from mkdocs import localization from mkdocs.config.base import LegacyConfig from mkdocs.config.defaults import MkDocsConfig @@ -77,6 +79,32 @@ log.warning("Unable to detect lunr languages from mkdocs distribution") MKDOCS_THEMES = ["mkdocs", "readthedocs"] +# some config overrides are forbidden as they make no sense +FORBIDDEN_CONFIG_OVERRIDES = [ + "dev_addr", + "docs_dir", + "edit_uri_template", + "edit_uri", + "exclude_docs", + "extra_css", + "extra_javascript", + "extra_templates", + "hooks", + "markdown_extensions", + "mdx_configs", + "not_in_nav", + "plugins", + "remote_branch", + "remote_name", + "repo_name", + "repo_url", + "site_dir", + "strict", + "use_directory_urls", + "validation", + "watch", +] + class ExtendedPlugin(BasePlugin[I18nPluginConfig]): def __init__(self, *args, **kwargs): @@ -197,37 +225,63 @@ def apply_user_overrides(self, config: MkDocsConfig): # altered by a previous build config = self.reset_to_original_config(config) - # some config overrides are forbidden as they make no sense - forbidden_config_overrides = [ - "dev_addr", - "docs_dir", - "edit_uri_template", - "edit_uri", - "exclude_docs", - "extra_css", - "extra_javascript", - "extra_templates", - "hooks", - "markdown_extensions", - "mdx_configs", - "not_in_nav", - "plugins", - "remote_branch", - "remote_name", - "repo_name", - "repo_url", - "site_dir", - "strict", - "use_directory_urls", - "validation", - "watch", - ] + overrides = dict() + # read po file if configured and override array is not empty + if self.config.po_overrides is not None and self.config.po_overrides.override: + po_file = os.path.normpath( + os.path.join( + os.path.dirname(config.config_file_path), + self.config.po_overrides.po_dir, + self.current_language + ".po", + ) + ) + if os.path.exists(po_file): + with open(po_file, "r", encoding="utf-8") as fs: + catalog = pofile.read_po(fs) + + for key in self.config.po_overrides.override: + if key in FORBIDDEN_CONFIG_OVERRIDES: + log.warning( + f"Ignoring forbidden '{self.current_language}' po override '{key}'" + ) + continue + # get original value + if config.__contains__(key) and config[key]: + msgid = config[key] + translation = catalog.get(msgid) + if translation is not None: + if translation.string: + overrides[key] = translation.string + else: + log.warning( + f"MsgId '{msgid}' is not translated, discarding override" + ) + else: + log.warning( + f"MsgId '{msgid}' for config '{key}' not found in catalog '{po_file}'" + ) + else: + log.warning( + f"no original value set for config '{key}', cannot look up translation" + ) + else: + log.warning(f"translation catalog '{po_file}' not found") + + # read explicitly configured overrides for lang_key, lang_override in self.current_language_config.items(): - if lang_key in forbidden_config_overrides: + if lang_key in FORBIDDEN_CONFIG_OVERRIDES: log.warning( f"Ignoring forbidden '{self.current_language}' config override '{lang_key}'" ) continue + if lang_override is not None: + if lang_key in overrides: + log.warning( + f"Overwriting override '{lang_key}' from PO file with explicitly configured string '{lang_override}'" + ) + overrides[lang_key] = lang_override + + for lang_key, lang_override in overrides.items(): if lang_key in config.data and lang_override is not None: mkdocs_config_option_type = type(config.data[lang_key]) # support special Theme object overrides