Repository: hynek/hatch-fancy-pypi-readme

Issue:
Monorepo support for URL replacement
Hi team,

Thanks for producing this module!

Context: PyPI renders the readme of a package, yet it makes no attempt to normalise relative links within it.

Solution: use this package with a regex replacement.

I am working on a monorepo with uv. When I replace a relative link from a package within the monorepo, I need to know which package it is in order to include that in the regex replacement URL, otherwise I can only link to the monorepo itself.

Would it be reasonable to add something similar to [`HFPR_VERSION` substitution](https://github.com/hynek/hatch-fancy-pypi-readme/pull/39) but for the package name, e.g. `HFPR_PACKAGE_NAME`?

Happy to make a PR if you think it's a suitable suggestion.

Hints from issue comments:
@hynek: sure, sounds reasonable!@robbieaverill: Thanks @hynek, I've opened a PR here: https://github.com/hynek/hatch-fancy-pypi-readme/pull/64@hynek: 25.1.0 with this is live: https://pypi.org/project/hatch-fancy-pypi-readme/ 🎉

Solution patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 431f13a..17e0976 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -13,6 +13,12 @@ The **third number** is for emergencies when we need to start branches for older
 
 ## [Unreleased](https://github.com/hynek/hatch-fancy-pypi-readme/compare/24.1.0...HEAD)
 
+### Added
+
+- `$HFPR_PACKAGE_NAME` is now replaced by the package name in the PyPI readme.
+  The version is not available in CLI mode, therefore it's replaced by the dummy value of `your-package`.
+  [#64](https://github.com/hynek/hatch-fancy-pypi-readme/pull/64)
+
 ### Removed
 
 - Support for Python 3.7.
diff --git a/README.md b/README.md
index dd0eb61..04d9db5 100644
--- a/README.md
+++ b/README.md
@@ -243,10 +243,10 @@ Again, please check out our [example configuration][example-config] for a comple
 
 ### Referencing Packaging Metadata
 
-If the final readme contains the string `$HFPR_VERSION`, it is replaced by the current package version.
+If the final readme contains the strings `$HFPR_PACKAGE_NAME` or `$HFPR_VERSION`, they will be replaced by the current package name or version.
 
 When running *hatch-fancy-pypi-readme* in CLI mode (as described in the next section), packaging metadata is not available.
-In that case `$HFPR_VERSION` is hardcoded to `42.0` so you can still test your readme.
+In that case `$HFPR_PACKAGE_NAME` is hardcoded to `your-package`, and `$HFPR_VERSION` to `42.0`, so you can still test your readme.
 
 
 ## CLI Interface
diff --git a/src/hatch_fancy_pypi_readme/_builder.py b/src/hatch_fancy_pypi_readme/_builder.py
index 225da0f..3bb69c9 100644
--- a/src/hatch_fancy_pypi_readme/_builder.py
+++ b/src/hatch_fancy_pypi_readme/_builder.py
@@ -15,6 +15,7 @@ if TYPE_CHECKING:
 def build_text(
     fragments: list[Fragment],
     substitutions: list[Substituter],
+    package_name: str = "",
     version: str = "",
 ) -> str:
     """
@@ -26,4 +27,6 @@ def build_text(
     for sub in substitutions:
         text = sub.substitute(text)
 
-    return text.replace("$HFPR_VERSION", version)
+    return text.replace("$HFPR_PACKAGE_NAME", package_name).replace(
+        "$HFPR_VERSION", version
+    )
diff --git a/src/hatch_fancy_pypi_readme/_cli.py b/src/hatch_fancy_pypi_readme/_cli.py
index e4c3320..23d2299 100644
--- a/src/hatch_fancy_pypi_readme/_cli.py
+++ b/src/hatch_fancy_pypi_readme/_cli.py
@@ -65,7 +65,12 @@ def cli_run(
             + "\n".join(f"- {msg}" for msg in e.errors),
         )
 
-    print(build_text(config.fragments, config.substitutions, "42.0"), file=out)
+    print(
+        build_text(
+            config.fragments, config.substitutions, "your-package", "42.0"
+        ),
+        file=out,
+    )
 
 
 def _fail(msg: str) -> NoReturn:
diff --git a/src/hatch_fancy_pypi_readme/hooks.py b/src/hatch_fancy_pypi_readme/hooks.py
index 97c4ef2..a770b62 100644
--- a/src/hatch_fancy_pypi_readme/hooks.py
+++ b/src/hatch_fancy_pypi_readme/hooks.py
@@ -27,6 +27,7 @@ class FancyReadmeMetadataHook(MetadataHookInterface):
             "text": build_text(
                 config.fragments,
                 config.substitutions,
+                package_name=metadata.get("name", ""),
                 version=metadata.get("version", ""),
             ),
         }


Test patch:
diff --git a/tests/test_builder.py b/tests/test_builder.py
index 205de53..afe3011 100644
--- a/tests/test_builder.py
+++ b/tests/test_builder.py
@@ -11,8 +11,15 @@ class TestBuildText:
         """
         A single text fragment becomes the readme.
         """
-        assert "This is the README for 1.0!" == build_text(
-            [TextFragment("This is the README for $HFPR_VERSION!")], [], "1.0"
+        assert "This is the README for your-package 1.0!" == build_text(
+            [
+                TextFragment(
+                    "This is the README for $HFPR_PACKAGE_NAME $HFPR_VERSION!"
+                )
+            ],
+            [],
+            "your-package",
+            "1.0",
         )
 
     def test_multiple_text_fragment(self):
@@ -26,5 +33,6 @@ class TestBuildText:
                 TextFragment("This is the README!"),
             ],
             [],
+            "your-package",
             "1.0",
         )