From afe00a261b9007b9d82e07ece180ab9e96d4237a Mon Sep 17 00:00:00 2001 From: Konstantin Nosov Date: Fri, 4 Oct 2024 12:56:08 +0300 Subject: [PATCH] BlogPlugin: handling of generated blog posts --- material/plugins/blog/structure/__init__.py | 72 +++++++++++---------- 1 file changed, 39 insertions(+), 33 deletions(-) diff --git a/material/plugins/blog/structure/__init__.py b/material/plugins/blog/structure/__init__.py index 0285f3a9bcb..17f57728678 100644 --- a/material/plugins/blog/structure/__init__.py +++ b/material/plugins/blog/structure/__init__.py @@ -40,6 +40,7 @@ from .config import PostConfig from .markdown import ExcerptTreeprocessor + # ----------------------------------------------------------------------------- # Classes # ----------------------------------------------------------------------------- @@ -52,40 +53,45 @@ class Post(Page): def __init__(self, file: File, config: MkDocsConfig): super().__init__(None, file, config) - # Resolve path relative to docs directory - docs = os.path.relpath(config.docs_dir) - path = os.path.relpath(file.abs_src_path, docs) + if file.generated_by is None: + # Resolve path relative to docs directory + docs = os.path.relpath(config.docs_dir) + path = os.path.relpath(file.abs_src_path, docs) + file_origin = f" in '{docs}'" + else: + # Path for generated posts + path = file.src_path + file_origin = f" generated by '{file.generated_by}'" # Read contents and metadata immediately - with open(file.abs_src_path, encoding = "utf-8-sig") as f: - self.markdown = f.read() - - # Sadly, MkDocs swallows any exceptions that occur during parsing. - # Since we want to provide the best possible user experience, we - # need to catch errors early and display them nicely. We decided to - # drop support for MkDocs' MultiMarkdown syntax, because it is not - # correctly implemented anyway. When using MultiMarkdown syntax, all - # date formats are returned as strings and list are not properly - # supported. Thus, we just use the relevants parts of `get_data`. - match: Match = YAML_RE.match(self.markdown) - if not match: - raise PluginError( - f"Error reading metadata of post '{path}' in '{docs}':\n" - f"Expected metadata to be defined but found nothing" - ) - - # Extract metadata and parse as YAML - try: - self.meta = yaml.load(match.group(1), SafeLoader) or {} - self.markdown = self.markdown[match.end():].lstrip("\n") - - # The post's metadata could not be parsed because of a syntax error, - # which we display to the author with a nice error message - except Exception as e: - raise PluginError( - f"Error reading metadata of post '{path}' in '{docs}':\n" - f"{e}" - ) + self.markdown = file.content_string + + # Sadly, MkDocs swallows any exceptions that occur during parsing. + # Since we want to provide the best possible user experience, we + # need to catch errors early and display them nicely. We decided to + # drop support for MkDocs' MultiMarkdown syntax, because it is not + # correctly implemented anyway. When using MultiMarkdown syntax, all + # date formats are returned as strings and list are not properly + # supported. Thus, we just use the relevants parts of `get_data`. + match: Match = YAML_RE.match(self.markdown) + if not match: + raise PluginError( + f"Error reading metadata of post '{path}' {file_origin}:\n" + f"Expected metadata to be defined but found nothing" + ) + + # Extract metadata and parse as YAML + try: + self.meta = yaml.load(match.group(1), SafeLoader) or {} + self.markdown = self.markdown[match.end():].lstrip("\n") + + # The post's metadata could not be parsed because of a syntax error, + # which we display to the author with a nice error message + except Exception as e: + raise PluginError( + f"Error reading metadata of post '{path}' {file_origin}:\n" + f"{e}" + ) # Initialize post configuration, but remove all keys that this plugin # doesn't care about, or they will be reported as invalid configuration @@ -103,7 +109,7 @@ def __init__(self, file: File, config: MkDocsConfig): log.warning(w) for k, e in errors: raise PluginError( - f"Error reading metadata '{k}' of post '{path}' in '{docs}':\n" + f"Error reading metadata '{k}' of post '{path}' {file_origin}:\n" f"{e}" )