Brian S. Stephan 0d59e64323
static site generator part 1 --- incomplete, but kinda works
Signed-off-by: Brian S. Stephan <bss@incorporeal.org>
2025-03-13 18:33:17 -05:00

73 lines
2.5 KiB
Python

"""Miscellaneous helper functions and whatnot.
SPDX-FileCopyrightText: © 2021 Brian S. Stephan <bss@incorporeal.org>
SPDX-License-Identifier: AGPL-3.0-or-later
"""
import datetime
import logging
import os
import re
import markdown
from markupsafe import Markup
from incorporealcms.config import Config
logger = logging.getLogger(__name__)
def get_meta_str(md, key):
"""Provide the page's (parsed in Markup obj md) metadata for the specified key, or '' if unset."""
return " ".join(md.Meta.get(key)) if md.Meta.get(key) else ""
def init_md():
"""Initialize the Markdown parser.
This used to done at the app level in __init__, but extensions like footnotes apparently
assume the parser to only live for the length of parsing one document, and create double
footnote ref links if the one parser sees the same document multiple times.
"""
# initialize markdown parser from config, but include
# extensions our app depends on, like the meta extension
return markdown.Markdown(extensions=Config.MARKDOWN_EXTENSIONS + ['meta'],
extension_configs=Config.MARKDOWN_EXTENSION_CONFIGS)
def instance_resource_path_to_request_path(path):
"""Reverse a relative disk path to the path that would show up in a URL request."""
return '/' + re.sub(r'.md$', '', re.sub(r'index.md$', '', path))
def parse_md(path: str):
"""Given a file to parse, return file content and other derived data along with the md object.
Args:
path: the path to the file to render
"""
try:
logger.debug("opening path '%s'", path)
with open(path, 'r') as input_file:
mtime = datetime.datetime.fromtimestamp(os.path.getmtime(input_file.name), tz=datetime.timezone.utc)
entry = input_file.read()
logger.debug("path '%s' read", path)
md = init_md()
content = Markup(md.convert(entry))
except OSError:
logger.exception("path '%s' could not be opened!", path)
raise
except ValueError:
logger.exception("error parsing/rendering markdown!")
raise
except TypeError:
logger.exception("error loading/rendering markdown!")
raise
logger.debug("file metadata: %s", md.Meta)
page_name = get_meta_str(md, 'title') if md.Meta.get('title') else path
page_title = f'{page_name} - {Config.TITLE_SUFFIX}' if page_name else Config.TITLE_SUFFIX
logger.debug("title (potentially derived): %s", page_title)
return content, md, page_name, page_title, mtime