Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ test_venv
docs/build
docs/source/generated
docs/source/examples
docs/source/README_processed.md

# reports
reports
Expand Down
2 changes: 1 addition & 1 deletion docs/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,4 @@ help:
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)

clean:
@rm -rf $(BUILDDIR) $(SOURCEDIR)/examples $(SOURCEDIR)/generated
@rm -rf $(BUILDDIR) $(SOURCEDIR)/examples $(SOURCEDIR)/generated $(SOURCEDIR)/README_processed.md
104 changes: 103 additions & 1 deletion docs/source/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
# documentation root, use os.path.abspath to make it absolute, like shown here.

from importlib import metadata
from pathlib import Path

# -- Project information -----------------------------------------------------

Expand Down Expand Up @@ -101,7 +102,108 @@
}

# MyST parser settings
myst_enable_extensions = []
myst_enable_extensions = [
"colon_fence",
]
myst_heading_anchors = 5
myst_all_links_external = True
suppress_warnings = ["myst.header"]


def convert_github_admonitions(text):
"""Convert GitHub-style admonitions to MyST format."""
lines = text.split("\n")
github_to_myst = {
"> [!NOTE]": ":::{note}",
"> [!TIP]": ":::{tip}",
"> [!IMPORTANT]": ":::{important}",
"> [!WARNING]": ":::{warning}",
"> [!CAUTION]": ":::{caution}",
}

converted_lines = []
in_admonition = False

for line in lines:
# Check if this line starts a GitHub admonition
admonition_found = False
for github_style, myst_style in github_to_myst.items():
if line.strip().startswith(github_style):
# Start of admonition
converted_lines.append(myst_style)
in_admonition = True
admonition_found = True
break

if not admonition_found:
if in_admonition:
strip_line = line.strip()
if strip_line.startswith("> "):
# Content of admonition - remove the "> " prefix
content = strip_line[2:]
converted_lines.append(content)
elif strip_line == ">":
# Empty line in admonition
converted_lines.append("")
elif strip_line == "":
# Empty line - could be end of admonition or just spacing
converted_lines.append("")
else:
# End of admonition
converted_lines.append(":::")
converted_lines.append("")
converted_lines.append(line)
in_admonition = False
else:
# Regular line
converted_lines.append(line)

# Close any remaining open admonition
if in_admonition:
converted_lines.append(":::")

return "\n".join(converted_lines)


def preprocess_readme_for_sphinx(app, config): # pylint: disable=unused-argument
"""Preprocess README.md to convert GitHub admonitions before Sphinx build."""
# Calculate paths relative to the docs directory
docs_dir = Path(app.srcdir)
project_root = docs_dir.parent.parent
readme_path = project_root / "README.md"
docs_readme_path = docs_dir / "README_processed.md"

# Remove existing processed README to ensure fresh generation
if docs_readme_path.exists():
docs_readme_path.unlink()
print(f"[sphinx-hook] Removed existing {docs_readme_path}")

# Check if README exists
if not readme_path.exists():
print(f"[sphinx-hook] README.md not found at {readme_path}")
return

# Read original README
try:
with open(readme_path, "r", encoding="utf-8") as f:
content = f.read()

# Convert admonitions
converted_content = convert_github_admonitions(content)

# Write processed README to docs directory
with open(docs_readme_path, "w", encoding="utf-8") as f:
f.write(converted_content)

print(f"[sphinx-hook] Processed README saved to {docs_readme_path}")

except Exception as e:
print(f"[sphinx-hook] Error processing README: {e}")
raise


def setup(app):
"""Setup Sphinx app with custom handlers."""
# Connect the preprocessing function to config-inited event
# This runs after configuration is loaded but before any documents are read
app.connect("config-inited", preprocess_readme_for_sphinx)
2 changes: 1 addition & 1 deletion docs/source/index.rst
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
.. include:: ../../README.md
.. include:: README_processed.md
:parser: myst_parser.sphinx_


Expand Down