zulip/tools/convert-help-center-docs-to...

118 lines
3.7 KiB
Plaintext
Raw Normal View History

#!/usr/bin/env python3
import os
import sys
import django
from django.template import engines
from django.template.backends.jinja2 import Jinja2
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.insert(0, os.path.join(os.path.dirname(__file__), ".."))
from scripts.lib.setup_path import setup_path
setup_path()
os.environ["DJANGO_SETTINGS_MODULE"] = "zproject.settings"
django.setup()
def replace_image_path(markdown_string: str) -> str:
"""
We will point to the existing image folder till
the cutover. After that, we will copy the images
to src folder for help-beta in order to take
advantage of Astro's image optimization.
See https://chat.zulip.org/#narrow/stream/6-frontend/topic/Handling.20images.20in.20help.20center.20starlight.20migration.2E/near/1915130
"""
# We do not replace /static/images directly since there are a few
# instances in the documentation where zulip.com links are
# referenced with that blurb as a part of the url.
result = markdown_string.replace("(/static/images/help-beta", "(../../../../static/images/help")
return result.replace('="/static/images/help-beta', '="../../../../static/images/help')
def escape_curly_braces(markdown_string: str) -> str:
"""
MDX will treat curly braces as a JS expression,
we need to escape it if we don't want it to be
treated as such.
"""
result = markdown_string.replace("{", r"\{")
return result.replace("}", r"\}")
def fix_relative_path(markdown_string: str) -> str:
"""
Since the docs will live at the `help-beta/` url
until we migrate the project completely, we will
replace `help/` with `help-beta/`
"""
return markdown_string.replace("help/", "help-beta/")
def insert_frontmatter(markdown_string: str) -> str:
"""
We use the heading in the first line for the
existing files to extract the document title.
We are not adding a description to the frontmatter
yet.
"""
heading = markdown_string.partition("\n")[0].lstrip("#").strip()
title = f"---\ntitle: {heading}\n---\n"
# Remove the first line since starlight will display the
# `title` as `H1` anyways.
return title + markdown_string.split("\n", 1)[-1]
def convert_string_to_mdx(markdown_string: str) -> str:
result = escape_curly_braces(markdown_string)
result = fix_relative_path(result)
result = replace_image_path(result)
return insert_frontmatter(result)
def convert_file_to_mdx(
markdown_file_path: str,
) -> str:
"""
Given a path to a Markdown file, return the equivalent MDX file.
"""
jinja = engines["Jinja2"]
assert isinstance(jinja, Jinja2)
if markdown_file_path.startswith("/"):
with open(markdown_file_path) as fp:
markdown_string = fp.read()
else:
markdown_string = jinja.env.loader.get_source(jinja.env, markdown_file_path)[0]
return convert_string_to_mdx(markdown_string)
def run() -> None:
input_dir = os.path.join(BASE_DIR, "help")
output_dir = os.path.join(BASE_DIR, "help-beta/src/content/docs")
print("Starting the conversion from MD to MDX...")
converted_count = 0
os.makedirs(output_dir, exist_ok=True)
for name in os.listdir(input_dir):
if os.path.isfile(os.path.join(input_dir, name)):
converted_count += 1
mdx = convert_file_to_mdx(os.path.join(input_dir, name))
with open(
os.path.join(
BASE_DIR,
output_dir,
os.path.basename(name).split(".")[0] + ".mdx",
),
"w",
) as mdx_file:
mdx_file.write(mdx)
print(f"Converted {converted_count} files. Conversion completed.")
run()