Repository: pypa/setuptools

Issue:
[Docs] Replace binary images with SVG
### Summary

According to

> I'd recommend not to add blobs into the repo. Sphinx and any other modern web tool works with SVG just fine. Besides poisoning the Git bare repo size, it can also look ugly when scaled for folks with 200% default browser zoom (I have this, for example) + SVG is more optimized for the network transfer meaning faster page loads.
>
> _Originally posted by @webknjaz in https://github.com/pypa/setuptools/pull/2853#discussion_r743648362_

The best approach is to have all SVG images, and preferably remove binary files from the git repo.

### OS / Environment

_No response_

### Additional Information

There is some discussion in #2853.

According to https://caniuse.com/link-icon-svg, not all the browsers support SVG, however, [a recent article](https://evilmartians.com/chronicles/how-to-favicon-in-2021-six-files-that-fit-most-needs) seems to indicate that Safari does support it, which means that all major desktop browsers are covered.

### Code of Conduct

- [X] I agree to follow the PSF Code of Conduct


Discussion:

Resolving patch:
diff --git a/docs/_ext/_custom_icons.py b/docs/_ext/_custom_icons.py
new file mode 100644
--- /dev/null
+++ b/docs/_ext/_custom_icons.py
@@ -0,0 +1,58 @@
+"""'In-tree' sphinx extension to add icons/favicons to documentation"""
+import os
+from sphinx.util.fileutil import copy_asset_file
+
+
+IMAGES_DIR = "_images"  # same used by .. image:: and .. picture::
+
+
+def _prepare_image(pathto, confdir, outdir, icon_attrs):
+    """Copy icon files to the ``IMAGES_DIR`` and return a modified version of
+    the icon attributes dict replacing ``file`` with the correct ``href``.
+    """
+    icon = icon_attrs.copy()
+    src = os.path.join(confdir, icon.pop("file"))
+    if not os.path.exists(src):
+        raise FileNotFoundError(f"icon {src!r} not found")
+
+    dest = os.path.join(outdir, IMAGES_DIR)
+    copy_asset_file(src, dest)  # already compares if dest exists and is uptodate
+
+    asset_name = os.path.basename(src)
+    icon["href"] = pathto(f"{IMAGES_DIR}/{asset_name}", resource=True)
+    return icon
+
+
+def _link_tag(attrs):
+    return "<link " + " ".join(f'{k}="{v}"' for k, v in attrs.items()) + "/>"
+
+
+def _add_icons(app, _pagename, _templatename, context, doctree):
+    """Add multiple "favicons", not limited to PNG/ICO files"""
+    # https://evilmartians.com/chronicles/how-to-favicon-in-2021-six-files-that-fit-most-needs
+    # https://caniuse.com/link-icon-svg
+    try:
+        pathto = context['pathto']
+    except KeyError as ex:
+        msg = f"{__name__} extension is supposed to be call in HTML contexts"
+        raise ValueError(msg) from ex
+
+    if doctree and "icons" in app.config:
+        icons = [
+            _prepare_image(pathto, app.confdir, app.outdir, icon)
+            for icon in app.config["icons"]
+        ]
+        context["metatags"] += "\n".join(_link_tag(attrs) for attrs in icons)
+
+
+def setup(app):
+    images_dir = os.path.join(app.outdir, IMAGES_DIR)
+    os.makedirs(images_dir, exist_ok=True)
+
+    app.add_config_value("icons", None, "html")
+    app.connect("html-page-context", _add_icons)
+
+    return {
+        'parallel_read_safe': True,
+        'parallel_write_safe': True,
+    }
diff --git a/docs/conf.py b/docs/conf.py
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -1,3 +1,6 @@
+import os
+import sys
+
 extensions = ['sphinx.ext.autodoc', 'jaraco.packaging.sphinx', 'rst.linker']
 
 master_doc = "index"
@@ -101,8 +104,7 @@
 
 # HTML theme
 html_theme = 'furo'
-html_logo = "images/logo.png"
-html_favicon = "images/favicon.ico"
+html_logo = "images/logo.svg"
 
 html_theme_options = {
     "sidebar_hide_name": True,
@@ -172,4 +174,27 @@
 
 extensions += ['jaraco.tidelift']
 
+# Add icons (aka "favicons") to documentation
+sys.path.append(os.path.join(os.path.dirname(__file__), '_ext'))
+extensions += ['_custom_icons']
+
+# List of dicts with <link> HTML attributes
+# as defined in https://developer.mozilla.org/en-US/docs/Web/HTML/Element/link
+# except that ``file`` gets replaced with the correct ``href``
+icons = [
+    {  # "Catch-all" goes first, otherwise some browsers will overwrite
+        "rel": "icon",
+        "type": "image/svg+xml",
+        "file": "images/logo-symbol-only.svg",
+        "sizes": "any"
+    },
+    {  # Version with thicker strokes for better visibility at smaller sizes
+        "rel": "icon",
+        "type": "image/svg+xml",
+        "file": "images/favicon.svg",
+        "sizes": "16x16 24x24 32x32 48x48"
+    },
+    # rel="apple-touch-icon" does not support SVG yet
+]
+
 intersphinx_mapping['pip'] = 'https://pip.pypa.io/en/latest', None


Test patch: