How to use mkdocs as a package to read a Markdown page? #3576
-
Hello Mkdocs community, I manage a Mkdocs website with 1000+ pages and sometimes we need to update the structure of our pages. Typically, we're moving our YAML frontmatter We wrote some scripts with regex and it works fine but it's not the first nor the last time we need to do this and it would be really convenient if we can open and write back the markdown file with mkdocs to be sure that we use the same parser. Is it possible? |
Beta Was this translation helpful? Give feedback.
Replies: 5 comments 18 replies
-
Why don't you just use a hook and run it through |
Beta Was this translation helpful? Give feedback.
-
I believe Myst builds an AST of the source, which would have been great here (I could definitely use such a thing to create auto-migration for mkdocstrings options in Markdown pages). Unfortunately Python-Markdown does not: it converts directly to HTML. But I'll think about it since I'm interested too, and report back if I find something 🙂 |
Beta Was this translation helpful? Give feedback.
-
Okay, I'm tired or loosing memory because I've found a script that I wrote myself 2 years ago using Line 56 in e755aae In a nutshell: from pathlib import Path
from mkdocs.utils.meta import get_data
markdown_filepath = Path("sample_mkdocs_markdown.md")
with markdown_filepath.open(encoding="utf-8-sig", errors="strict") as f:
source = f.read()
page_meta = get_data(source)[1]
[...] |
Beta Was this translation helpful? Give feedback.
-
Until now, I've made it through a script based on python-frontmatter. It works fine even it's not perfect since the output file is written with 0 indentation (despite the Script#! python3 # noqa: E265
"""Script meant to be used as one-shot to convert YAML fonrtmatter 'date' value from
str into date.
See: https://github.com/mkdocs/mkdocs/discussions/3576
"""
# -- IMPORTS --
# standard
import logging
from datetime import date, datetime
from pathlib import Path
# 3rd party
import frontmatter
import yaml
from yaml import SafeDumper
# -- MAIN --
dt_format = "%Y-%m-%d %H:%M"
logging.basicConfig(level=logging.INFO)
# match = re.search(
# r"^---\s*\n.*?date: (\d{4}-\d{2}-\d{2}).*?\n---",
# content,
# re.DOTALL | re.MULTILINE,
# )
for md_filepath in Path("content").glob("**/*.md"):
# read and load content
with md_filepath.open(mode="r", encoding="UTF-8") as in_file:
content = frontmatter.load(in_file)
# manipulate date in YAML frontmatter
if content_date := content.metadata.get("date"):
if type(content_date) == date:
logging.debug(
f"File {md_filepath} has already a proper date defined in YAML "
"frontmatters."
)
continue
elif isinstance(content_date, str):
# parse date from str
try:
content.metadata["date"] = datetime.strptime(
content_date, dt_format
).date()
except ValueError:
logging.error(
f"File {md_filepath} has a date in YAML frontmatters but it does "
f"not comply with expected format ({dt_format}): {content_date}"
)
# write new version
with md_filepath.open(mode="w", encoding="UTF-8") as out_file:
# frontmatter.dump(content, out_file) # not working
out_file.write(frontmatter.dumps(content, sort_keys=False, indent=4))
else:
logging.warning(
f"File {md_filepath} has a date in YAML frontmatters but it's not a "
f"str: {content_date}"
)
continue
logging.info(f"File has no date defined in YAML frontmatters: {md_filepath}") |
Beta Was this translation helpful? Give feedback.
-
FYI it's the same with your script @kamilkrzyskow that I've just tested it. |
Beta Was this translation helpful? Give feedback.
So for the tags example @Guts, I looked up https://stackoverflow.com/questions/25108581/python-yaml-dump-bad-indentation
and made appropriate changes via copy and paste ;)
modify_docs.zip