File: utils.py

package info (click to toggle)
sphinx-notfound-page 1.0.4-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 920 kB
  • sloc: python: 699; makefile: 15
file content (74 lines) | stat: -rw-r--r-- 3,028 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
import docutils
import re

from sphinx.builders.dirhtml import DirectoryHTMLBuilder


def replace_uris(app, doctree, nodetype, nodeattr):
    """
    Replace ``nodetype`` URIs from ``doctree`` to the proper one.

    If ``nodetype`` is an image (``docutils.nodes.image``), the URL is prefixed
    with ``Builder.imagedir`` and the original image path is added to
    ``Builder.images`` so it's copied using Sphinx's internals before
    finalizing the building.

    :param app: Sphinx Application
    :type app: sphinx.application.Sphinx

    :param doctree: doctree representing the document
    :type doctree: docutils.nodes.document

    :param nodetype: type of node to replace URIs
    :type nodetype: docutils.nodes.Node

    :param nodeattr: node attribute to be replaced
    :type nodeattr: str
    """
    # https://github.com/sphinx-doc/sphinx/blob/2adeb68af1763be46359d5e808dae59d708661b1/sphinx/environment/adapters/toctree.py#L260-L266
    for node in doctree.findall(nodetype):
        uri = olduri = node.attributes.get(nodeattr)  # somepage.html (or ../sompage.html)

        if isinstance(app.builder, DirectoryHTMLBuilder):
            # When the builder is ``DirectoryHTMLBuilder``, refuri will be
            # ``../somepage.html``. In that case, we want to remove the
            # initial ``../`` to make valid links
            if uri.startswith('../'):
                uri = uri.replace('../', '')

        if re.match('^https?://', uri):
            # allow non-local URLs for resources
            continue

        imagedir = ''
        if nodetype is docutils.nodes.image:
            # Prefix the URL with ``Builder.imagedir`` to use the internal's
            # Sphinx image handling if the node is an image
            imagedir = '{imagedir}/'.format(
                imagedir=app.builder.imagedir,
            )

            # The image is copied into ``app.builder.imagedir`` without keeping
            # the directory structure, so we need only the filename for the
            # correct link
            uri = olduri.split('/')[-1]

        uri = '{prefix}{imagedir}{filename}'.format(
            prefix=app.config.notfound_urls_prefix or '/',
            imagedir=imagedir,
            filename=uri,
        )

        node.replace_attr(nodeattr, uri)

        # Force adding the image to the builder so it's copied at ``Builder.copy_image_files``
        # https://github.com/sphinx-doc/sphinx/blob/5ce5c2c3156c53c1f1b758c38150e48080138b15/sphinx/builders/html.py#L721
        # We need to do this at this point because ``Builder.post_process_images``
        # does not add it automatically as the path does not match.
        # https://github.com/sphinx-doc/sphinx/blob/5ce5c2c3156c53c1f1b758c38150e48080138b15/sphinx/builders/__init__.py#L189
        if nodetype is docutils.nodes.image:
            if all([
                    not olduri.startswith('data:'),
                    '://' not in olduri,
            ]):
                app.builder.images[olduri] = olduri.split('/')[-1]