test bkp
This commit is contained in:
1 parent
6ccab0347b
commit
954a2fd6d6
18684 files changed
+601012
-190
No files matched your search
@@ -0,0 +1,150 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import functools
|
||||
import logging
|
||||
import os
|
||||
import os.path
|
||||
from typing import IO, TYPE_CHECKING, Any
|
||||
|
||||
import mergedeep # type: ignore
|
||||
import yaml
|
||||
import yaml.constructor
|
||||
import yaml_env_tag # type: ignore
|
||||
|
||||
from mkdocs import exceptions
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from mkdocs.config.defaults import MkDocsConfig
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def _construct_dir_placeholder(
|
||||
config: MkDocsConfig, loader: yaml.BaseLoader, node: yaml.ScalarNode
|
||||
) -> _DirPlaceholder:
|
||||
loader.construct_scalar(node)
|
||||
|
||||
value: str = (node and node.value) or ''
|
||||
prefix, _, suffix = value.partition('/')
|
||||
if prefix.startswith('$'):
|
||||
if prefix == '$config_dir':
|
||||
return ConfigDirPlaceholder(config, suffix)
|
||||
elif prefix == '$docs_dir':
|
||||
return DocsDirPlaceholder(config, suffix)
|
||||
else:
|
||||
raise exceptions.ConfigurationError(
|
||||
f"Unknown prefix {prefix!r} in {node.tag} {node.value!r}"
|
||||
)
|
||||
else:
|
||||
return RelativeDirPlaceholder(config, value)
|
||||
|
||||
|
||||
class _DirPlaceholder(os.PathLike):
|
||||
def __init__(self, config: MkDocsConfig, suffix: str = ''):
|
||||
self.config = config
|
||||
self.suffix = suffix
|
||||
|
||||
def value(self) -> str:
|
||||
raise NotImplementedError
|
||||
|
||||
def __fspath__(self) -> str:
|
||||
"""Can be used as a path."""
|
||||
return os.path.join(self.value(), self.suffix)
|
||||
|
||||
def __str__(self) -> str:
|
||||
"""Can be converted to a string to obtain the current class."""
|
||||
return self.__fspath__()
|
||||
|
||||
|
||||
class ConfigDirPlaceholder(_DirPlaceholder):
|
||||
"""
|
||||
A placeholder object that gets resolved to the directory of the config file when used as a path.
|
||||
|
||||
The suffix can be an additional sub-path that is always appended to this path.
|
||||
|
||||
This is the implementation of the `!relative $config_dir/suffix` tag, but can also be passed programmatically.
|
||||
"""
|
||||
|
||||
def value(self) -> str:
|
||||
return os.path.dirname(self.config.config_file_path)
|
||||
|
||||
|
||||
class DocsDirPlaceholder(_DirPlaceholder):
|
||||
"""
|
||||
A placeholder object that gets resolved to the docs dir when used as a path.
|
||||
|
||||
The suffix can be an additional sub-path that is always appended to this path.
|
||||
|
||||
This is the implementation of the `!relative $docs_dir/suffix` tag, but can also be passed programmatically.
|
||||
"""
|
||||
|
||||
def value(self) -> str:
|
||||
return self.config.docs_dir
|
||||
|
||||
|
||||
class RelativeDirPlaceholder(_DirPlaceholder):
|
||||
"""
|
||||
A placeholder object that gets resolved to the directory of the Markdown file currently being rendered.
|
||||
|
||||
This is the implementation of the `!relative` tag, but can also be passed programmatically.
|
||||
"""
|
||||
|
||||
def __init__(self, config: MkDocsConfig, suffix: str = ''):
|
||||
if suffix:
|
||||
raise exceptions.ConfigurationError(
|
||||
f"'!relative' tag does not expect any value; received {suffix!r}"
|
||||
)
|
||||
super().__init__(config, suffix)
|
||||
|
||||
def value(self) -> str:
|
||||
current_page = self.config._current_page
|
||||
if current_page is None:
|
||||
raise exceptions.ConfigurationError(
|
||||
"The current file is not set for the '!relative' tag. "
|
||||
"It cannot be used in this context; the intended usage is within `markdown_extensions`."
|
||||
)
|
||||
return os.path.dirname(os.path.join(self.config.docs_dir, current_page.file.src_path))
|
||||
|
||||
|
||||
def get_yaml_loader(loader=yaml.Loader, config: MkDocsConfig | None = None):
|
||||
"""Wrap PyYaml's loader so we can extend it to suit our needs."""
|
||||
|
||||
class Loader(loader):
|
||||
"""
|
||||
Define a custom loader derived from the global loader to leave the
|
||||
global loader unaltered.
|
||||
"""
|
||||
|
||||
# Attach Environment Variable constructor.
|
||||
# See https://github.com/waylan/pyyaml-env-tag
|
||||
Loader.add_constructor('!ENV', yaml_env_tag.construct_env_tag)
|
||||
|
||||
if config is not None:
|
||||
Loader.add_constructor('!relative', functools.partial(_construct_dir_placeholder, config))
|
||||
|
||||
return Loader
|
||||
|
||||
|
||||
def yaml_load(source: IO | str, loader: type[yaml.BaseLoader] | None = None) -> dict[str, Any]:
|
||||
"""Return dict of source YAML file using loader, recursively deep merging inherited parent."""
|
||||
loader = loader or get_yaml_loader()
|
||||
try:
|
||||
result = yaml.load(source, Loader=loader)
|
||||
except yaml.YAMLError as e:
|
||||
raise exceptions.ConfigurationError(
|
||||
f"MkDocs encountered an error parsing the configuration file: {e}"
|
||||
)
|
||||
if result is None:
|
||||
return {}
|
||||
if 'INHERIT' in result and not isinstance(source, str):
|
||||
relpath = result.pop('INHERIT')
|
||||
abspath = os.path.normpath(os.path.join(os.path.dirname(source.name), relpath))
|
||||
if not os.path.exists(abspath):
|
||||
raise exceptions.ConfigurationError(
|
||||
f"Inherited config file '{relpath}' does not exist at '{abspath}'."
|
||||
)
|
||||
log.debug(f"Loading inherited configuration file: {abspath}")
|
||||
with open(abspath, 'rb') as fd:
|
||||
parent = yaml_load(fd, loader)
|
||||
result = mergedeep.merge(parent, result)
|
||||
return result
|
||||
Reference in new issue
Block a user