diff --git a/.gitignore b/.gitignore index c46b1d71..6611c73a 100644 --- a/.gitignore +++ b/.gitignore @@ -61,6 +61,7 @@ docs/build/ docs/source/examples/ docs/source/api/ docs/source/api_index.rst +docs/source/snippets/admonitions.md sg_execution_times.rst # MkDocs documentation diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 63dc93bf..88f5ecd0 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -296,9 +296,13 @@ make html ``` The local build can be viewed by opening `docs/build/html/index.html` in a browser. -To re-build the documentation after making changes, we recommend removing existing build files first. +To re-build the documentation after making changes, +we recommend removing existing build files first. The following command will remove all generated files in `docs/`, -including the auto-generated API index `source/api_index.rst`, and those in `build/`, `source/api/`, and `source/examples/`. It will then re-build the documentation: +including the auto-generated files `source/api_index.rst` and +`source/snippets/admonitions.md`, as well as all files in + `build/`, `source/api/`, and `source/examples/`. + It will then re-build the documentation: ```sh make clean html diff --git a/README.md b/README.md index 5b1dec34..ab66a9b8 100644 --- a/README.md +++ b/README.md @@ -34,10 +34,19 @@ We aim to support a range of pose estimation packages, along with 2D or 3D track Find out more on our [mission and scope](https://movement.neuroinformatics.dev/community/mission-scope.html) statement and our [roadmap](https://movement.neuroinformatics.dev/community/roadmaps.html). -## Status + + > [!Warning] > 🏗️ The package is currently in early development and the interface is subject to change. Feel free to play around and provide feedback. +> [!Tip] +> If you prefer analysing your data in R, we recommend checking out the +> [animovement](https://www.roald-arboel.com/animovement/) toolbox, which is similar in scope. +> We are working together with its developer +> to gradually converge on common data standards and workflows. + + + ## Join the movement Contributions to movement are absolutely encouraged, whether to fix a bug, develop a new feature, or improve the documentation. diff --git a/docs/Makefile b/docs/Makefile index da95f613..df622291 100644 --- a/docs/Makefile +++ b/docs/Makefile @@ -19,14 +19,20 @@ help: api_index.rst: python make_api_index.py +# Generate the snippets/admonitions.md file +# by converting the admonitions in the repo's README.md to MyST format +admonitions.md: + python convert_admonitions.py + # Remove all generated files clean: rm -rf ./build rm -f ./source/api_index.rst rm -rf ./source/api rm -rf ./source/examples + rm -rf ./source/snippets/admonitions.md # Catch-all target: route all unknown targets to Sphinx using the new # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). -%: Makefile api_index.rst +%: Makefile api_index.rst admonitions.md @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) diff --git a/docs/convert_admonitions.py b/docs/convert_admonitions.py new file mode 100644 index 00000000..dc3dc27c --- /dev/null +++ b/docs/convert_admonitions.py @@ -0,0 +1,87 @@ +"""Convert admonitions GitHub Flavored Markdown (GFM) to MyST Markdown.""" + +import re +from pathlib import Path + +# Valid admonition types supported by both GFM and MyST (case-insensitive) +VALID_TYPES = {"note", "tip", "important", "warning", "caution"} + + +def convert_gfm_admonitions_to_myst_md( + input_path: Path, output_path: Path, exclude: set[str] | None = None +): + """Convert admonitions from GitHub Flavored Markdown to MyST. + + Extracts GitHub Flavored Markdown admonitions from the input file and + writes them to the output file as MyST Markdown admonitions. + The original admonition type and order are preserved. + + Parameters + ---------- + input_path : Path + Path to the input file containing GitHub Flavored Markdown. + output_path : Path + Path to the output file to write the MyST Markdown admonitions. + exclude : set[str], optional + Set of admonition types to exclude from conversion (case-insensitive). + Default is None. + + """ + excluded_types = {s.lower() for s in (exclude or set())} + + # Read the input file + gfm_text = input_path.read_text(encoding="utf-8") + + # Regex pattern to match GFM admonitions + pattern = r"(^> \[!(\w+)\]\n(?:^> .*\n?)*)" + matches = re.finditer(pattern, gfm_text, re.MULTILINE) + + # Process matches and collect converted admonitions + admonitions = [] + for match in matches: + adm_myst = _process_match(match, excluded_types) + if adm_myst: + admonitions.append(adm_myst) + + if admonitions: + # Write all admonitions to a single file + output_path.write_text("\n".join(admonitions) + "\n", encoding="utf-8") + print(f"Admonitions written to {output_path}") + else: + print("No GitHub Markdown admonitions found.") + + +def _process_match(match: re.Match, excluded_types: set[str]) -> str | None: + """Process a regex match and return the converted admonition if valid.""" + # Extract the admonition type + adm_type = match.group(2).lower() + if adm_type not in VALID_TYPES or adm_type in excluded_types: + return None + + # Extract the content lines + full_block = match.group(0) + content = "\n".join( + line[2:].strip() + for line in full_block.split("\n") + if line.startswith("> ") and not line.startswith("> [!") + ).strip() + + # Return the converted admonition + return ":::{" + adm_type + "}\n" + content + "\n" + ":::\n" + + +if __name__ == "__main__": + # Path to the README.md file + # (1 level above the current script) + docs_dir = Path(__file__).resolve().parent + readme_path = docs_dir.parent / "README.md" + + # Path to the output file + # (inside the docs/source/snippets directory) + snippets_dir = docs_dir / "source" / "snippets" + target_path = snippets_dir / "admonitions.md" + + # Call the function + convert_gfm_admonitions_to_myst_md( + readme_path, target_path, exclude={"note"} + ) diff --git a/docs/make.bat b/docs/make.bat index b1e18dd6..1969d4b3 100644 --- a/docs/make.bat +++ b/docs/make.bat @@ -28,14 +28,19 @@ if "%1" == "" goto help :process_targets if "%1" == "clean" ( - @echo Removing auto-generated files under 'docs' and 'src'... + echo Removing auto-generated files... rmdir /S /Q %BUILDDIR% del /Q %SOURCEDIR%\api_index.rst rmdir /S /Q %SOURCEDIR%\api\ rmdir /S /Q %SOURCEDIR%\examples\ + del /Q %SOURCEDIR%\snippets\admonitions.md ) else ( - @echo Generating API index... + echo Generating API index... python make_api_index.py + + echo Converting admonitions... + python convert_admonitions.py + %SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% ) diff --git a/docs/source/index.md b/docs/source/index.md index 629027b9..d37c1849 100644 --- a/docs/source/index.md +++ b/docs/source/index.md @@ -39,7 +39,7 @@ We aim to support a range of pose estimation packages, along with 2D or 3D track Find out more on our [mission and scope](target-mission) statement and our [roadmap](target-roadmaps). -```{include} /snippets/status-warning.md +```{include} /snippets/admonitions.md ``` ## Citation diff --git a/docs/source/snippets/status-warning.md b/docs/source/snippets/status-warning.md deleted file mode 100644 index a9ccbbb7..00000000 --- a/docs/source/snippets/status-warning.md +++ /dev/null @@ -1,4 +0,0 @@ -:::{admonition} Status -:class: warning -The package is currently in early development and the interface is subject to change. Feel free to play around and provide feedback. -:::